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
| |
| struct | event_state_compositor |
| The Event State Compositors. More... | |
| struct | invstate2stringtable |
| Readable descriptions of device states. More... | |
| struct | match_req_args |
| struct | show_peers_context |
| Used in the sip_show_peers functions to pass parameters. More... | |
| struct | sip_reasons |
| Diversion header reasons. More... | |
Defines | |
| #define | SIP_PEDANTIC_DECODE(str) |
Variables | |
| static int | authlimit = DEFAULT_AUTHLIMIT |
| static int | authtimeout = DEFAULT_AUTHTIMEOUT |
| static int | can_parse_xml |
| static unsigned int | chan_idx |
| static const char | config [] = "sip.conf" |
| static int | default_expiry = DEFAULT_DEFAULT_EXPIRY |
| static struct ast_jb_conf | default_jbconf |
| Global jitterbuffer configuration - by default, jb is disabled. | |
| static unsigned int | dumphistory |
| static int | global_authfailureevents |
| static unsigned int | global_autoframing |
| static int | global_callcounter |
| static unsigned int | global_cos_audio |
| static unsigned int | global_cos_sip |
| static unsigned int | global_cos_text |
| static unsigned int | global_cos_video |
| static int | global_dynamic_exclude_static = 0 |
| static struct ast_jb_conf | global_jbconf |
| static int | global_match_auth_username |
| static int | global_max_se |
| static int | global_min_se |
| static int | global_prematuremediafilter |
| static int | global_qualify_gap |
| static int | global_qualify_peers |
| static int | global_qualifyfreq |
| static int | global_reg_retry_403 |
| static int | global_reg_timeout |
| static int | global_regattempts_max |
| static int | global_relaxdtmf |
| static int | global_rtpholdtimeout |
| static int | global_rtpkeepalive |
| static int | global_rtptimeout |
| static char | global_sdpowner [AST_MAX_EXTENSION] |
| static char | global_sdpsession [AST_MAX_EXTENSION] |
| static int | global_shrinkcallerid |
| static enum st_mode | global_st_mode |
| static enum st_refresher_param | global_st_refresher |
| static int | global_store_sip_cause |
| static int | global_t1 |
| static int | global_t1min |
| static int | global_timer_b |
| static unsigned int | global_tos_audio |
| static unsigned int | global_tos_sip |
| static unsigned int | global_tos_text |
| static unsigned int | global_tos_video |
| static char | global_useragent [AST_MAX_EXTENSION] |
| static struct invstate2stringtable | invitestate2string [] |
| Readable descriptions of device states. | |
| static int | max_expiry = DEFAULT_MAX_EXPIRY |
| static int | min_expiry = DEFAULT_MIN_EXPIRY |
| static int | mwi_expiry = DEFAULT_MWI_EXPIRY |
| static const char | notify_config [] = "sip_notify.conf" |
| static unsigned int | recordhistory |
| static struct sip_settings | sip_cfg |
| static struct cfsip_methods | sip_methods [] |
| The core structure to setup dialogs. We parse incoming messages by using structure and then route the messages according to the type. | |
| static struct sip_reasons | sip_reason_table [] |
| Diversion header reasons. | |
| static struct cfsubscription_types | subscription_types [] |
Subscription types that we support. We support
| |
| static int | unauth_sessions = 0 |
DefaultSettings | |
| static char | default_callerid [AST_MAX_EXTENSION] |
| static char | default_engine [256] |
| static char | default_fromdomain [AST_MAX_EXTENSION] |
| static int | default_fromdomainport |
| static char | default_language [MAX_LANGUAGE] |
| static int | default_maxcallbitrate |
| static char | default_mohinterpret [MAX_MUSICCLASS] |
| static char | default_mohsuggest [MAX_MUSICCLASS] |
| static char | default_mwi_from [80] |
| static char | default_notifymime [AST_MAX_EXTENSION] |
| static char | default_parkinglot [AST_MAX_CONTEXT] |
| static struct ast_codec_pref | default_prefs |
| static unsigned int | default_primary_transport |
| static int | default_qualify |
| static unsigned int | default_transports |
| static char | default_vmexten [AST_MAX_EXTENSION] |
Object counters @{ | |
| |
| #define | append_history(p, event, fmt, args...) append_history_full(p, "%-15s " fmt, event, ## args) |
| Append to SIP dialog history. | |
| #define | BOGUS_PEER_MD5SECRET "intentionally_invalid_md5_string" |
| We can recognise the bogus peer by this invalid MD5 hash. | |
| #define | CHECK_AUTH_BUF_INITLEN 256 |
| #define | check_request_transport(peer, tmpl) |
| generic function for determining if a correct transport is being used to contact a peer | |
| #define | CONTAINER_UNLINK(container, obj, tag) |
| Unlink the given object from the container and return TRUE if it was in the container. | |
| #define | DATA_EXPORT_SIP_PEER(MEMBER) |
| #define | FORMAT "%-15.15s %-15.15s %-15.15s %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s %-10.10s\n" |
| #define | FORMAT "%-30.30s %-12.12s %-10.10s %-10.10s\n" |
| #define | FORMAT "%-15.15s %-11.11s %-8.8s %-10.10u%-1.1s %-10.10u (%5.2f%%) %-6.4lf %-10.10u%-1.1s %-10.10u (%5.2f%%) %-6.4lf\n" |
| #define | FORMAT "%-39.39s %-6.6s %-12.12s %8d %-20.20s %-25.25s\n" |
| #define | FORMAT "%-40.40s %-20.20s %-16.16s\n" |
| #define | FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" |
| #define | FORMAT "%-47.47s %-9.9s %-6.6s\n" |
| #define | FORMAT "%-25.25s %-15.15s %-15.15s \n" |
| #define | FORMAT2 "%-15.15s %-15.15s %-15.15s %-15.15s %-7.7s %-15.15s %-10.10s %-10.10s\n" |
| #define | FORMAT2 "%-15.15s %-11.11s %-8.8s %-10.10s %-10.10s ( %%) %-6.6s %-10.10s %-10.10s ( %%) %-6.6s\n" |
| #define | FORMAT2 "%-39.39s %-6.6s %-12.12s %8.8s %-20.20s %-25.25s\n" |
| #define | FORMAT2 "%-47.47s %9.9s %6.6s\n" |
| #define | FORMAT2 "%-25.25s %-15.15s %-15.15s \n" |
| #define | FORMAT3 "%-15.15s %-15.15s %-15.15s %-15.15s %-13.13s %-15.15s %-10.10s %-6.6s\n" |
| #define | FORMAT4 "%-15.15s %-15.15s %-15.15s %-15.15s %-13.13s %-15.15s %-10.10s %-6.6d\n" |
| #define | PEERS_FORMAT2 "%-25.25s %-39.39s %-3.3s %-10.10s %-3.3s %-8s %-10s %s\n" |
| #define | sip_pvt_lock(x) ao2_lock(x) |
| #define | sip_pvt_trylock(x) ao2_trylock(x) |
| #define | sip_pvt_unlock(x) ao2_unlock(x) |
| #define | UNLINK(element, head, prev) |
| enum | match_req_res { SIP_REQ_MATCH, SIP_REQ_NOT_MATCH, SIP_REQ_LOOP_DETECTED } |
| enum | message_integrity { MESSAGE_INVALID, MESSAGE_FRAGMENT, MESSAGE_FRAGMENT_COMPLETE, MESSAGE_COMPLETE } |
Indication of a TCP message's integrity. More... | |
| enum | peer_unlink_flag_t { SIP_PEERS_MARKED, SIP_PEERS_ALL } |
| static struct _map_x_s | allowoverlapstr [] |
| static int | apeerobjs = 0 |
| static char * | app_dtmfmode = "SIPDtmfMode" |
| static char * | app_sipaddheader = "SIPAddHeader" |
| static char * | app_sipremoveheader = "SIPRemoveHeader" |
| static struct sip_auth_container * | authl = NULL |
| Authentication container for realm authentication. | |
| struct ast_sockaddr | bindaddr |
| static struct sip_peer * | bogus_peer |
| A bogus peer, to be used when authentication should fail. | |
| static struct epa_static_data | cc_epa_static_data |
| static struct ast_custom_function | checksipdomain_function |
| static struct ast_cli_entry | cli_sip [] |
| SIP Cli commands definition. | |
| static struct ast_sockaddr | debugaddr |
| static const int | DEFAULT_PUBLISH_EXPIRES = 3600 |
| static struct ast_tls_config | default_tls_cfg |
| Default TLS connection configuration. | |
| static struct ao2_container * | dialogs |
| Here we implement the container for dialogs (sip_pvt), defining generic wrapper functions to ease the transition from the current implementation (a single linked list) to a different container. In addition to a reference to the container, we need functions to lock/unlock the container and individual items, and functions to add/remove references to the individual items. | |
| struct ao2_container * | dialogs_to_destroy |
| static struct _map_x_s | dtmfstr [] |
| mapping between dtmf flags and strings | |
| static int | esc_etag_counter |
| static const int | ESC_MAX_BUCKETS = 37 |
| static struct event_state_compositor | event_state_compositors [] |
| The Event State Compositors. | |
| static struct ast_sockaddr | externaddr |
| our external IP address/port for SIP sessions. externaddr.sin_addr is only set when we know we might be behind a NAT, and this is done using a variety of (mutually exclusive) ways from the config file: | |
| static time_t | externexpire |
| static char | externhost [MAXHOSTNAMELEN] |
| static int | externrefresh = 10 |
| static uint16_t | externtcpport |
| static uint16_t | externtlsport |
| static struct _map_x_s | faxecmodes [] |
| static struct ast_flags | global_flags [3] = {{0}} |
| static unsigned int | global_t38_maxdatagram |
| static const int | HASH_DIALOG_SIZE = 563 |
| static const int | HASH_PEER_SIZE = 563 |
| static struct _map_x_s | insecurestr [] |
| static struct ast_sockaddr | internip |
| our (internal) default address/port to put in SIP/SDP messages internip is initialized picking a suitable address from one of the interfaces, and the same port number we bind to. It is used as the default address/port in SIP messages, and as the default address (but not port) in SDP messages. | |
| static struct io_context * | io |
| static struct ast_ha * | localaddr |
| List of local networks We store "localnet" addresses from the config file into an access list, marked as 'DENY', so the call to ast_apply_ha() will return AST_SENSE_DENY for 'local' addresses, and AST_SENSE_ALLOW for 'non local' (i.e. presumably public) addresses. | |
| static struct ast_sockaddr | media_address |
| static pthread_t | monitor_thread = AST_PTHREADT_NULL |
| This is the thread for the monitor which checks for input on the channels which are not currently in use. | |
| static int | network_change_event_sched_id = -1 |
| static struct ast_event_sub * | network_change_event_subscription |
| static struct ast_config * | notify_types = NULL |
| static int | ourport_tcp |
| static int | ourport_tls |
| static struct ao2_container * | peers |
| The peer list: Users, Peers and Friends. | |
| static struct ao2_container * | peers_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_context * | sched |
| 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_container * | sip_monitor_instances |
| static int | sip_reloading = FALSE |
| static enum channelreloadreason | sip_reloadreason |
| static struct ast_rtp_glue | sip_rtp_glue |
| static struct ast_tcptls_session_args | sip_tcp_desc |
| The TCP server definition. | |
| struct ast_channel_tech | sip_tech |
| Definition of this channel for PBX channel registration. | |
| struct ast_channel_tech | sip_tech_info |
| This version of the sip channel tech has no send_digit_begin callback so that the core knows that the channel does not want DTMF BEGIN frames. The struct is initialized just before registering the channel driver, and is for use with channels using SIP INFO DTMF. | |
| static struct ast_tls_config | sip_tls_cfg |
| Working TLS connection configuration. | |
| static struct ast_tcptls_session_args | sip_tls_desc |
| The TCP/TLS server definition. | |
| static struct ast_udptl_protocol | sip_udptl |
| Interface structure with callbacks used to connect to UDPTL module. | |
| static struct ast_custom_function | sipchaninfo_function |
| Structure to declare a dialplan function: SIPCHANINFO. | |
| static enum sip_debug_e | sipdebug |
| static int | sipdebug_text |
| extra debugging for 'text' related events. At the moment this is set together with sip_debug_console. | |
| static struct ast_custom_function | sippeer_function |
| Structure to declare a dialplan function: SIPPEER. | |
| static int | sipsock = -1 |
| Main socket for UDP SIP communication. | |
| static int * | sipsock_read_id |
| static int | speerobjs = 0 |
| static struct _map_x_s | stmodes [] |
| Report Peer status in character string. | |
| static struct _map_x_s | strefresher_params [] |
| static struct _map_x_s | strefreshers [] |
| static struct ast_subscription_mwi_list | submwil |
| The MWI subscription list. | |
| static struct ao2_container * | threadt |
| The table of TCP threads. | |
| static struct _map_x_s | trust_id_outboundstr [] |
| static char | used_context [AST_MAX_CONTEXT] |
| static const char * | __get_header (const struct sip_request *req, const char *name, int *start) |
| static int | __set_address_from_contact (const char *fullcontact, struct ast_sockaddr *addr, int tcp) |
| int | __sip_ack (struct sip_pvt *p, uint32_t seqno, int resp, int sipmethod) |
| Acknowledges receipt of a packet and stops retransmission called with p locked. | |
| static int | __sip_autodestruct (const void *data) |
| Kill a SIP dialog (called only by the scheduler) The scheduler has a reference to this dialog when p->autokillid != -1, and we are called using that reference. So if the event is not rescheduled, we need to call dialog_unref(). | |
| void | __sip_destroy (struct sip_pvt *p, int lockowner, int lockdialoglist) |
| Execute destruction of SIP dialog structure, release memory. | |
| static int | __sip_do_register (struct sip_registry *r) |
| Register with SIP proxy. | |
| void | __sip_pretend_ack (struct sip_pvt *p) |
| Pretend to ack all packets called with p locked. | |
| static int | __sip_reliable_xmit (struct sip_pvt *p, uint32_t seqno, int resp, struct ast_str *data, int fatal, int sipmethod) |
| int | __sip_semi_ack (struct sip_pvt *p, uint32_t seqno, int resp, int sipmethod) |
| Acks receipt of packet, keep it around (used for provisional responses). | |
| static int | __sip_subscribe_mwi_do (struct sip_subscription_mwi *mwi) |
| Actually setup an MWI subscription or resubscribe. | |
| static int | __sip_xmit (struct sip_pvt *p, struct ast_str *data) |
| static int | __transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
| Base transmit response function. | |
| static char * | _sip_qualify_peer (int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[]) |
| Send qualify message to peer from cli or manager. Mostly for debugging. | |
| static char * | _sip_show_peer (int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[]) |
| Show one peer in detail (main function). | |
| static char * | _sip_show_peers (int fd, int *total, struct mansession *s, const struct message *m, int argc, const char *argv[]) |
| Execute sip show peers command. | |
| static struct sip_peer * | _sip_show_peers_one (int fd, struct mansession *s, struct show_peers_context *cont, struct sip_peer *peer) |
| Emit informations for one peer during sip show peers command. | |
| static void * | _sip_tcp_helper_thread (struct ast_tcptls_session_instance *tcptls_session) |
| SIP TCP thread management function This function reads from the socket, parses the packet into a request. | |
| static void | add_blank (struct sip_request *req) |
| add a blank line if no body | |
| static void | add_cc_call_info_to_response (struct sip_pvt *p, struct sip_request *resp) |
| static void | add_codec_to_sdp (const struct sip_pvt *p, format_t codec, struct ast_str **m_buf, struct ast_str **a_buf, int debug, int *min_packet_size) |
| Add codec offer to SDP offer/answer body in INVITE or 200 OK. | |
| static int | add_content (struct sip_request *req, const char *line) |
| Add content (not header) to SIP message. | |
| static int | add_digit (struct sip_request *req, char digit, unsigned int duration, int mode) |
| Add DTMF INFO tone to sip message Mode = 0 for application/dtmf-relay (Cisco) 1 for application/dtmf. | |
| static void | add_diversion_header (struct sip_request *req, struct sip_pvt *pvt) |
| Add "Diversion" header to outgoing message. | |
| static int | add_header (struct sip_request *req, const char *var, const char *value) |
| Add header to SIP message. | |
| static int | add_header_max_forwards (struct sip_pvt *dialog, struct sip_request *req) |
| Add 'Max-Forwards' header to SIP message. | |
| static void | add_noncodec_to_sdp (const struct sip_pvt *p, int format, struct ast_str **m_buf, struct ast_str **a_buf, int debug) |
| Add RFC 2833 DTMF offer to SDP. | |
| static void | add_peer_mailboxes (struct sip_peer *peer, const char *value) |
| static void | add_peer_mwi_subs (struct sip_peer *peer) |
| static void | add_realm_authentication (struct sip_auth_container **credentials, const char *configuration, int lineno) |
| static void | add_required_respheader (struct sip_request *req) |
| static void | add_route (struct sip_request *req, struct sip_route *route) |
| Add route header into request per learned route. | |
| static int | add_rpid (struct sip_request *req, struct sip_pvt *p) |
| Add Remote-Party-ID header to SIP message. | |
| static enum sip_result | add_sdp (struct sip_request *resp, struct sip_pvt *p, int oldsdp, int add_audio, int add_t38) |
| Add Session Description Protocol message. | |
| static int | add_sip_domain (const char *domain, const enum domain_mode mode, const char *context) |
| Add SIP domain to list of domains we are responsible for. | |
| static int | add_supported_header (struct sip_pvt *pvt, struct sip_request *req) |
| Add "Supported" header to sip message. Since some options may be disabled in the config, the sip_pvt must be inspected to determine what is supported for this dialog. | |
| static void | add_tcodec_to_sdp (const struct sip_pvt *p, int codec, struct ast_str **m_buf, struct ast_str **a_buf, int debug, int *min_packet_size) |
| Add text codec offer to SDP offer/answer body in INVITE or 200 OK. | |
| static int | add_text (struct sip_request *req, const char *text) |
| Add text body to SIP message. | |
| static struct ast_variable * | add_var (const char *buf, struct ast_variable *list) |
| implement the setvar config line | |
| static void | add_vcodec_to_sdp (const struct sip_pvt *p, format_t codec, struct ast_str **m_buf, struct ast_str **a_buf, int debug, int *min_packet_size) |
| Add video codec offer to SDP offer/answer body in INVITE or 200 OK. | |
| static int | add_vidupdate (struct sip_request *req) |
| add XML encoded media control with update | |
| static int | addr_is_multicast (const struct ast_sockaddr *addr) |
| Check if an ip is an multicast IP. addr the address to check. | |
| static const char * | allowoverlap2str (int mode) |
| Convert AllowOverlap setting to printable string. | |
| static void | append_date (struct sip_request *req) |
| Append date to SIP message. | |
| static void | append_history_full (struct sip_pvt *p, const char *fmt,...) |
| Append to SIP dialog history with arg list. | |
| static void | append_history_va (struct sip_pvt *p, const char *fmt, va_list ap) |
| Append to SIP dialog history with arg list. | |
| static int | apply_directmedia_ha (struct sip_pvt *p1, struct sip_pvt *p2, const char *op) |
| AST_DATA_STRUCTURE (sip_peer, DATA_EXPORT_SIP_PEER) | |
| AST_LIST_HEAD_NOLOCK (sip_history_head, sip_history) | |
| AST_LIST_HEAD_STATIC (epa_static_data_list, epa_backend) | |
| static | AST_LIST_HEAD_STATIC (domain_list, domain) |
| AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER,"Session Initiation Protocol (SIP)",.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DRIVER,.nonoptreq="res_crypto,chan_local",) | |
| AST_MUTEX_DEFINE_STATIC (authl_lock) | |
| Global authentication container protection while adjusting the references. | |
| AST_MUTEX_DEFINE_STATIC (sip_reload_lock) | |
| AST_MUTEX_DEFINE_STATIC (monlock) | |
| Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical. | |
| AST_MUTEX_DEFINE_STATIC (netlock) | |
| static void | ast_quiet_chan (struct ast_channel *chan) |
| Turn off generator data XXX Does this function belong in the SIP channel? | |
| static void | ast_sip_ouraddrfor (const struct ast_sockaddr *them, struct ast_sockaddr *us, struct sip_pvt *p) |
| NAT fix - decide which IP address to use for Asterisk server? | |
| static int | ast_sockaddr_resolve_first (struct ast_sockaddr *addr, const char *name, int flag) |
| Return the first entry from ast_sockaddr_resolve filtered by family of binddaddr. | |
| static int | ast_sockaddr_resolve_first_af (struct ast_sockaddr *addr, const char *name, int flag, int family) |
| Return the first entry from ast_sockaddr_resolve filtered by address family. | |
| static int | ast_sockaddr_resolve_first_transport (struct ast_sockaddr *addr, const char *name, int flag, unsigned int transport) |
| Return the first entry from ast_sockaddr_resolve filtered by family of binddaddr. | |
| AST_THREADSTORAGE (check_auth_buf) | |
| AST_THREADSTORAGE_CUSTOM (ts_temp_pvt, temp_pvt_init, temp_pvt_cleanup) | |
| A per-thread temporary pvt structure. | |
| static int | attempt_transfer (struct sip_dual *transferer, struct sip_dual *target) |
| Attempt transfer of SIP call This fix for attended transfers on a local PBX. | |
| static void | auth_headers (enum sip_auth_type code, char **header, char **respheader) |
| return the request and response header for a 401 or 407 code | |
| static int | auto_congest (const void *arg) |
| Scheduled congestion on a call. Only called by the scheduler, must return the reference when done. | |
| static void | build_callid_pvt (struct sip_pvt *pvt) |
| Build SIP Call-ID value for a non-REGISTER transaction. | |
| static void | build_callid_registry (struct sip_registry *reg, const struct ast_sockaddr *ourip, const char *fromdomain) |
| Build SIP Call-ID value for a REGISTER transaction. | |
| static void | build_contact (struct sip_pvt *p) |
| Build contact header - the contact header we send out. | |
| static void | build_localtag_registry (struct sip_registry *reg) |
| Build SIP From tag value for REGISTER. | |
| static struct sip_peer * | build_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime, int devstate_only) |
| Build peer from configuration (file or realtime static/dynamic). | |
| static int | build_reply_digest (struct sip_pvt *p, int method, char *digest, int digest_len) |
| Build reply digest. | |
| static void | build_route (struct sip_pvt *p, struct sip_request *req, int backwards, int resp) |
| Build route list from Record-Route header. | |
| static void | build_via (struct sip_pvt *p) |
| Build a Via header for a request. | |
| static int | cb_extensionstate (char *context, char *exten, int state, void *data) |
| Callback for the devicestate notification (SUBSCRIBE) support subsystem. | |
| static void | cb_extensionstate_destroy (int id, void *data) |
| static void | cc_epa_destructor (void *data) |
| static void | cc_handle_publish_error (struct sip_pvt *pvt, const int resp, struct sip_request *req, struct sip_epa_entry *epa_entry) |
| static void | change_callid_pvt (struct sip_pvt *pvt, const char *callid) |
| static void | change_hold_state (struct sip_pvt *dialog, struct sip_request *req, int holdstate, int sendonly) |
| Change hold state for a call. | |
| static void | change_redirecting_information (struct sip_pvt *p, struct sip_request *req, struct ast_party_redirecting *redirecting, struct ast_set_party_redirecting *update_redirecting, int set_call_forward) |
| update redirecting information for a channel based on headers | |
| static void | change_t38_state (struct sip_pvt *p, int state) |
| Change the T38 state on a SIP dialog. | |
| static enum check_auth_result | check_auth (struct sip_pvt *p, struct sip_request *req, const char *username, const char *secret, const char *md5secret, int sipmethod, const char *uri, enum xmittype reliable, int ignore) |
| Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set). | |
| static enum message_integrity | check_message_integrity (struct ast_str **request, struct ast_str **overflow) |
| Check that a message received over TCP is a full message. | |
| static enum check_auth_result | check_peer_ok (struct sip_pvt *p, char *of, struct sip_request *req, int sipmethod, struct ast_sockaddr *addr, struct sip_peer **authpeer, enum xmittype reliable, char *calleridname, char *uri2) |
| Validate device authentication. | |
| static void | check_pendings (struct sip_pvt *p) |
| Check pending actions on SIP call. | |
| static void | check_rtp_timeout (struct sip_pvt *dialog, time_t t) |
| helper function for the monitoring thread -- seems to be called with the assumption that the dialog is locked | |
| static int | check_sip_domain (const char *domain, char *context, size_t len) |
| check_sip_domain: Check if domain part of uri is local to our server | |
| static int | check_user (struct sip_pvt *p, struct sip_request *req, int sipmethod, const char *uri, enum xmittype reliable, struct ast_sockaddr *addr) |
| Find user If we get a match, this will add a reference pointer to the user object in ASTOBJ, that needs to be unreferenced. | |
| static enum check_auth_result | check_user_full (struct sip_pvt *p, struct sip_request *req, int sipmethod, const char *uri, enum xmittype reliable, struct ast_sockaddr *addr, struct sip_peer **authpeer) |
| Check if matching user or peer is defined Match user on From: user name and peer on IP/port This is used on first invite (not re-invites) and subscribe requests. | |
| static void | check_via (struct sip_pvt *p, const struct sip_request *req) |
| check Via: header for hostname, port and rport request/answer | |
| static attribute_unused void | check_via_response (struct sip_pvt *p, struct sip_request *req) |
| check received= and rport= in a SIP response. If we get a response with received= and/or rport= in the Via: line, use them as 'p->ourip' (see RFC 3581 for rport, and RFC 3261 for received). Using these two fields SIP can produce the correct address and port in the SIP headers without the need for STUN. The address part is also reused for the media sessions. Note that ast_sip_ouraddrfor() still rewrites p->ourip if you specify externaddr/seternaddr/. | |
| static void | cleanup_all_regs (void) |
| static void | cleanup_stale_contexts (char *new, char *old) |
| Destroy disused contexts between reloads Only used in reload_config so the code for regcontext doesn't get ugly. | |
| static void | clear_peer_mailboxes (struct sip_peer *peer) |
| static void | clear_sip_domains (void) |
| Clear our domain list (at reload). | |
| static char * | complete_sip_peer (const char *word, int state, int flags2) |
| Do completion on peer name. | |
| static char * | complete_sip_registered_peer (const char *word, int state, int flags2) |
| Do completion on registered peer name. | |
| static char * | complete_sip_show_history (const char *line, const char *word, int pos, int state) |
| Support routine for 'sip show history' CLI. | |
| static char * | complete_sip_show_peer (const char *line, const char *word, int pos, int state) |
| Support routine for 'sip show peer' CLI. | |
| static char * | complete_sip_show_user (const char *line, const char *word, int pos, int state) |
| Support routine for 'sip show user' CLI. | |
| static char * | complete_sip_unregister (const char *line, const char *word, int pos, int state) |
| Support routine for 'sip unregister' CLI. | |
| static char * | complete_sip_user (const char *word, int state) |
| Do completion on user name. | |
| static char * | complete_sipch (const char *line, const char *word, int pos, int state) |
| Support routine for 'sip show channel' and 'sip show history' CLI This is in charge of generating all strings that match a prefix in the given position. As many functions of this kind, each invokation has O(state) time complexity so be careful in using it. | |
| static char * | complete_sipnotify (const char *line, const char *word, int pos, int state) |
| Support routine for 'sip notify' CLI. | |
| static int | construct_pidf_body (enum sip_cc_publish_state state, char *pidf_body, size_t size, const char *presentity) |
| static int | copy_all_header (struct sip_request *req, const struct sip_request *orig, const char *field) |
| Copy all headers from one request to another. | |
| static int | copy_header (struct sip_request *req, const struct sip_request *orig, const char *field) |
| Copy one header field from one request to another. | |
| static void | copy_request (struct sip_request *dst, const struct sip_request *src) |
| copy SIP request (mostly used to save request for responses) | |
| static void | copy_socket_data (struct sip_socket *to_sock, const struct sip_socket *from_sock) |
| static struct ast_variable * | copy_vars (struct ast_variable *src) |
| duplicate a list of channel variables, | |
| static int | copy_via_headers (struct sip_pvt *p, struct sip_request *req, const struct sip_request *orig, const char *field) |
| Copy SIP VIA Headers from the request to the response. | |
| static int | create_addr (struct sip_pvt *dialog, const char *opeer, struct ast_sockaddr *addr, int newdialog) |
| create address structure from device name Or, if peer not found, find it in the global DNS returns TRUE (-1) on failure, FALSE on success | |
| static int | create_addr_from_peer (struct sip_pvt *dialog, struct sip_peer *peer) |
| Create address structure from peer reference. This function copies data from peer to the dialog, so we don't have to look up the peer again from memory or database during the life time of the dialog. | |
| static struct sip_epa_entry * | create_epa_entry (const char *const event_package, const char *const destination) |
| static struct sip_esc_entry * | create_esc_entry (struct event_state_compositor *esc, struct sip_request *req, const int expires) |
| static void | create_new_sip_etag (struct sip_esc_entry *esc_entry, int is_linked) |
| static int | default_sip_port (enum sip_transport type) |
| The default sip port for the given transport. | |
| static void | deinit_req (struct sip_request *req) |
| Deinitialize SIP response/request. | |
| static void | destroy_association (struct sip_peer *peer) |
| Remove registration data from realtime database or AST/DB when registration expires. | |
| static void | destroy_escs (void) |
| static void | destroy_mailbox (struct sip_mailbox *mailbox) |
| static void | destroy_realm_authentication (void *obj) |
| static int | determine_firstline_parts (struct sip_request *req) |
| Parse first line of incoming SIP request. | |
| static enum sip_publish_type | determine_sip_publish_type (struct sip_request *req, const char *const event, const char *const etag, const char *const expires, int *expires_int) |
| static int | dialog_cmp_cb (void *obj, void *arg, int flags) |
| static int | dialog_dump_func (void *userobj, void *arg, int flags) |
| static int | dialog_find_multiple (void *obj, void *arg, int flags) |
| static int | dialog_hash_cb (const void *obj, const int flags) |
| static int | dialog_initialize_rtp (struct sip_pvt *dialog) |
| Initialize RTP portion of a dialog. | |
| static int | dialog_needdestroy (void *dialogobj, void *arg, int flags) |
| Match dialogs that need to be destroyed. | |
| struct sip_pvt * | dialog_ref_debug (struct sip_pvt *p, char *tag, char *file, int line, const char *func) |
| void | dialog_unlink_all (struct sip_pvt *dialog) |
| Unlink a dialog from the dialogs container, as well as any other places that it may be currently stored. | |
| static int | dialog_unlink_callback (void *obj, void *arg, int flags) |
| struct sip_pvt * | dialog_unref_debug (struct sip_pvt *p, char *tag, char *file, int line, const char *func) |
| static void | disable_dsp_detect (struct sip_pvt *p) |
| static void | display_nat_warning (const char *cat, int reason, struct ast_flags *flags) |
| static int | do_magic_pickup (struct ast_channel *channel, const char *extension, const char *context) |
| static void * | do_monitor (void *data) |
| The SIP monitoring thread. | |
| static int | do_proxy_auth (struct sip_pvt *p, struct sip_request *req, enum sip_auth_type code, int sipmethod, int init) |
| Add authentication on outbound SIP packet. | |
| static int | do_register_auth (struct sip_pvt *p, struct sip_request *req, enum sip_auth_type code) |
| Authenticate for outbound registration. | |
| static void | do_setnat (struct sip_pvt *p) |
| Set nat mode on the various data sockets. | |
| static const char * | domain_mode_to_text (const enum domain_mode mode) |
| Print domain mode to cli. | |
| static const char * | dtmfmode2str (int mode) |
| Convert DTMF mode to printable string. | |
| static void | enable_dsp_detect (struct sip_pvt *p) |
| static int | esc_cmp_fn (void *obj, void *arg, int flags) |
| static void | esc_entry_destructor (void *obj) |
| static int | esc_hash_fn (const void *obj, const int flags) |
| static int | expire_register (const void *data) |
| Expire registration of SIP peer. | |
| static void | extract_host_from_hostport (char **hostport) |
| Terminate a host:port at the ':'. | |
| static void | extract_uri (struct sip_pvt *p, struct sip_request *req) |
| Check Contact: URI of SIP message. | |
| static const char * | faxec2str (int faxec) |
| static int | finalize_content (struct sip_request *req) |
| Add 'Content-Length' header and content to SIP message. | |
| static const char * | find_alias (const char *name, const char *_default) |
| Find compressed SIP alias. | |
| static int | find_by_callid_helper (void *obj, void *arg, int flags) |
| static int | find_by_name (void *obj, void *arg, void *data, int flags) |
| static int | find_by_notify_uri_helper (void *obj, void *arg, int flags) |
| static int | find_by_subscribe_uri_helper (void *obj, void *arg, int flags) |
| static struct sip_pvt * | find_call (struct sip_request *req, struct ast_sockaddr *addr, const int intended_method) |
| find or create a dialog structure for an incoming SIP message. Connect incoming SIP message to current dialog or create new dialog structure Returns a reference to the sip_pvt object, remember to give it back once done. Called by handle_request_do | |
| static int | find_calling_channel (void *obj, void *arg, void *data, int flags) |
| Find the channel that is causing the RINGING update. | |
| const char * | find_closing_quote (const char *start, const char *lim) |
| Locate closing quote in a string, skipping escaped quotes. optionally with a limit on the search. start must be past the first quote. | |
| static struct sip_peer * | find_peer (const char *peer, struct ast_sockaddr *addr, int realtime, int which_objects, int devstate_only, int transport) |
| Locate device by name or ip address. | |
| static struct sip_auth * | find_realm_authentication (struct sip_auth_container *credentials, const char *realm) |
| static int | find_sdp (struct sip_request *req) |
| Determine whether a SIP message contains an SDP in its body. | |
| static struct ast_cc_agent * | find_sip_cc_agent_by_notify_uri (const char *const uri) |
| static struct ast_cc_agent * | find_sip_cc_agent_by_original_callid (struct sip_pvt *pvt) |
| static struct ast_cc_agent * | find_sip_cc_agent_by_subscribe_uri (const char *const uri) |
| static int | find_sip_method (const char *msg) |
| find_sip_method: Find SIP method from header | |
| static int | find_sip_monitor_instance_by_subscription_pvt (void *obj, void *arg, int flags) |
| static int | find_sip_monitor_instance_by_suspension_entry (void *obj, void *arg, int flags) |
| static struct epa_static_data * | find_static_data (const char *const event_package) |
| static struct cfsubscription_types * | find_subscription_type (enum subscriptiontype subtype) |
| Find subscription type in array. | |
| static void | free_old_route (struct sip_route *route) |
| Remove route from route list. | |
| static int | func_check_sipdomain (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
| Dial plan function to check if domain is local. | |
| static int | func_header_read (struct ast_channel *chan, const char *function, char *data, char *buf, size_t len) |
| Read SIP header (dialplan function). | |
| static int | function_sipchaninfo_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
| ${SIPCHANINFO()} Dialplan function - reads sip channel data | |
| static int | function_sippeer (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
| ${SIPPEER()} Dialplan function - reads peer data | |
| static char * | generate_random_string (char *buf, size_t size) |
| Generate 32 byte random string for callid's etc. | |
| static char * | generate_uri (struct sip_pvt *pvt, char *buf, size_t size) |
| static int | get_address_family_filter (unsigned int transport) |
| Helper for dns resolution to filter by address family. | |
| static int | get_also_info (struct sip_pvt *p, struct sip_request *oreq) |
| Call transfer support (old way, deprecated by the IETF). | |
| static char * | get_body (struct sip_request *req, char *name, char delimiter) |
| Get a specific line from the message body. | |
| static char * | get_body_by_line (const char *line, const char *name, int nameLen, char delimiter) |
| Reads one line of SIP message body. | |
| static int | get_cached_mwi (struct sip_peer *peer, int *new, int *old) |
| Get cached MWI info. | |
| static void | get_crypto_attrib (struct sip_srtp *srtp, const char **a_crypto) |
| static enum sip_get_dest_result | get_destination (struct sip_pvt *p, struct sip_request *oreq, int *cc_recall_core_id) |
| Find out who the call is for. | |
| static int | get_domain (const char *str, char *domain, int len) |
| Extract domain from SIP To/From header. | |
| static struct event_state_compositor * | get_esc (const char *const event_package) |
| static struct sip_esc_entry * | get_esc_entry (const char *entity_tag, struct event_state_compositor *esc) |
| static const char * | get_header (const struct sip_request *req, const char *name) |
| Get header from SIP request. | |
| static struct ast_variable * | get_insecure_variable_from_config (struct ast_config *config) |
| static struct ast_variable * | get_insecure_variable_from_sippeers (const char *column, const char *value) |
| static struct ast_variable * | get_insecure_variable_from_sipregs (const char *column, const char *value, struct ast_variable **var) |
| static int | get_ip_and_port_from_sdp (struct sip_request *req, const enum media_type media, struct ast_sockaddr *addr) |
| static int | get_msg_text (char *buf, int len, struct sip_request *req) |
| Get message body from a SIP request. | |
| static const char * | get_name_from_variable (const struct ast_variable *var) |
| static void | get_our_media_address (struct sip_pvt *p, int needvideo, int needtext, struct ast_sockaddr *addr, struct ast_sockaddr *vaddr, struct ast_sockaddr *taddr, struct ast_sockaddr *dest, struct ast_sockaddr *vdest, struct ast_sockaddr *tdest) |
| Set all IP media addresses for this call. | |
| static int | get_pai (struct sip_pvt *p, struct sip_request *req) |
| Parse the parts of the P-Asserted-Identity header on an incoming packet. Returns 1 if a valid header is found and it is different from the current caller id. | |
| static int | get_rdnis (struct sip_pvt *p, struct sip_request *oreq, char **name, char **number, int *reason) |
| Get referring dnis. | |
| static void | get_realm (struct sip_pvt *p, const struct sip_request *req) |
| Choose realm based on From header and then To header or use globaly configured realm. Realm from From/To header should be listed among served domains in config file: domain=... | |
| static int | get_refer_info (struct sip_pvt *transferer, struct sip_request *outgoing_req) |
| Call transfer support (the REFER method) Extracts Refer headers into pvt dialog structure. | |
| static int | get_rpid (struct sip_pvt *p, struct sip_request *oreq) |
| Get name, number and presentation from remote party id header, returns true if a valid header was found and it was different from the current caller id. | |
| static const char * | get_sdp_iterate (int *start, struct sip_request *req, const char *name) |
| Lookup 'name' in the SDP starting at the 'start' line. Returns the matching line, and 'start' is updated with the next line number. | |
| static char | get_sdp_line (int *start, int stop, struct sip_request *req, const char **value) |
| Fetches the next valid SDP line between the 'start' line (inclusive) and the 'stop' line (exclusive). Returns the type ('a', 'c', ...) and matching line in reference 'start' is updated with the next line number. | |
| static struct sip_pvt * | get_sip_pvt_byid_locked (const char *callid, const char *totag, const char *fromtag) |
| Lock dialog lock and find matching pvt lock. | |
| static const char * | get_srv_protocol (enum sip_transport t) |
| Return protocol string for srv dns query. | |
| static const char * | get_srv_service (enum sip_transport t) |
| Return service string for srv dns query. | |
| static const char * | get_transport (enum sip_transport t) |
| Return transport as string. | |
| static const char * | get_transport_list (unsigned int transports) |
| Return configuration of transports for a device. | |
| static const char * | get_transport_pvt (struct sip_pvt *p) |
| Return transport of dialog. | |
| static int | get_transport_str2enum (const char *transport) |
| Return int representing a bit field of transport types found in const char *transport. | |
| static const char * | gettag (const struct sip_request *req, const char *header, char *tagbuf, int tagbufsize) |
| Get tag from packet. | |
| static int | handle_cc_notify (struct sip_pvt *pvt, struct sip_request *req) |
| static int | handle_cc_subscribe (struct sip_pvt *p, struct sip_request *req) |
| static int | handle_common_options (struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v) |
| Handle flag-type options common to configuration of devices - peers. | |
| static int | handle_incoming (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, int *recount, int *nounlock) |
| Handle incoming SIP requests (methods). | |
| static int | handle_invite_replaces (struct sip_pvt *p, struct sip_request *req, int debug, uint32_t seqno, struct ast_sockaddr *addr, int *nounlock) |
| Handle the transfer part of INVITE with a replaces: header, meaning a target pickup or an attended transfer. Used only once. XXX 'ignore' is unused. | |
| static int | handle_request_bye (struct sip_pvt *p, struct sip_request *req) |
| Handle incoming BYE request. | |
| static int | handle_request_cancel (struct sip_pvt *p, struct sip_request *req) |
| Handle incoming CANCEL request. | |
| static int | handle_request_do (struct sip_request *req, struct ast_sockaddr *addr) |
| Handle incoming SIP message - request or response. | |
| static void | handle_request_info (struct sip_pvt *p, struct sip_request *req) |
| Receive SIP INFO Message. | |
| static int | handle_request_invite (struct sip_pvt *p, struct sip_request *req, int debug, uint32_t seqno, struct ast_sockaddr *addr, int *recount, const char *e, int *nounlock) |
| Handle incoming INVITE request. | |
| static int | handle_request_invite_st (struct sip_pvt *p, struct sip_request *req, const char *required, int reinvite) |
| static int | handle_request_message (struct sip_pvt *p, struct sip_request *req) |
| Handle incoming MESSAGE request. | |
| static int | handle_request_notify (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, uint32_t seqno, const char *e) |
| Handle incoming notifications. | |
| static int | handle_request_options (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, const char *e) |
| Handle incoming OPTIONS request An OPTIONS request should be answered like an INVITE from the same UA, including SDP. | |
| static int | handle_request_publish (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, const uint32_t seqno, const char *uri) |
| static int | handle_request_refer (struct sip_pvt *p, struct sip_request *req, int debug, uint32_t seqno, int *nounlock) |
| static int | handle_request_register (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, const char *e) |
| Handle incoming REGISTER request. | |
| static int | handle_request_subscribe (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, uint32_t seqno, const char *e) |
| Handle incoming SUBSCRIBE request. | |
| static int | handle_request_update (struct sip_pvt *p, struct sip_request *req) |
| bare-bones support for SIP UPDATE | |
| static void | handle_response (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno) |
| Handle SIP response in dialogue. | |
| static void | handle_response_info (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno) |
| static void | handle_response_invite (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno) |
| Handle SIP response to INVITE dialogue. | |
| static void | handle_response_message (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno) |
| static void | handle_response_notify (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno) |
| static void | handle_response_peerpoke (struct sip_pvt *p, int resp, struct sip_request *req) |
| Handle qualification responses (OPTIONS). | |
| static void | handle_response_publish (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno) |
| static void | handle_response_refer (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno) |
| static int | handle_response_register (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno) |
| Handle responses on REGISTER to services. | |
| static void | handle_response_subscribe (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno) |
| static void | handle_response_update (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno) |
| Handle authentication challenge for SIP UPDATE. | |
| static int | handle_sip_publish_initial (struct sip_pvt *p, struct sip_request *req, struct event_state_compositor *esc, const int expires) |
| static int | handle_sip_publish_modify (struct sip_pvt *p, struct sip_request *req, struct event_state_compositor *esc, const char *const etag, const int expires) |
| static int | handle_sip_publish_refresh (struct sip_pvt *p, struct sip_request *req, struct event_state_compositor *esc, const char *const etag, const int expires) |
| static int | handle_sip_publish_remove (struct sip_pvt *p, struct sip_request *req, struct event_state_compositor *esc, const char *const etag) |
| static int | handle_t38_options (struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v, unsigned int *maxdatagram) |
| Handle T.38 configuration options common to users and peers. | |
| const char * | hangup_cause2sip (int cause) |
| Convert Asterisk hangup causes to SIP codes. | |
| int | hangup_sip2cause (int cause) |
| Convert SIP hangup causes to Asterisk hangup causes. | |
| static int | init_req (struct sip_request *req, int sipmethod, const char *recip) |
| Initialize SIP request. | |
| static int | init_resp (struct sip_request *resp, const char *msg) |
| Initialize SIP response, based on SIP request. | |
| static int | initialize_escs (void) |
| static void | initialize_initreq (struct sip_pvt *p, struct sip_request *req) |
| Initialize the initital request packet in the pvt structure. This packet is used for creating replies and future requests in a dialog. | |
| static int | initialize_udptl (struct sip_pvt *p) |
| static void | initreqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod, const char *const explicit_uri) |
| Initiate new SIP request to peer/user. | |
| static const char * | insecure2str (int mode) |
| Convert Insecure setting to printable string. | |
| static int | interpret_t38_parameters (struct sip_pvt *p, const struct ast_control_t38_parameters *parameters) |
| Helper function which updates T.38 capability information and triggers a reinvite. | |
| static int | is_method_allowed (unsigned int *allowed_methods, enum sipmethod method) |
| Check if method is allowed for a device or a dialog. | |
| static void | list_route (struct sip_route *route) |
| List all routes - mostly for debugging. | |
| static int | load_module (void) |
| PBX load module - initialization. | |
| static int | local_attended_transfer (struct sip_pvt *transferer, struct sip_dual *current, struct sip_request *req, uint32_t seqno, int *nounlock) |
| Find all call legs and bridge transferee with target called from handle_request_refer. | |
| static void | lws2sws (struct ast_str *data) |
| Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled. | |
| static void | make_our_tag (struct sip_pvt *pvt) |
| Make our SIP dialog tag. | |
| static int | manager_show_registry (struct mansession *s, const struct message *m) |
| Show SIP registrations in the manager API. | |
| static int | manager_sip_qualify_peer (struct mansession *s, const struct message *m) |
| Qualify SIP peers in the manager API. | |
| static int | manager_sip_show_peer (struct mansession *s, const struct message *m) |
| Show SIP peers in the manager API. | |
| static int | manager_sip_show_peers (struct mansession *s, const struct message *m) |
| Show SIP peers in the manager API. | |
| static int | manager_sipnotify (struct mansession *s, const struct message *m) |
| static int | map_s_x (const struct _map_x_s *table, const char *s, int errorvalue) |
| map from a string to an integer value, case insensitive. If no match is found, return errorvalue. | |
| static const char * | map_x_s (const struct _map_x_s *table, int x, const char *errorstring) |
| map from an integer value to a string. If no match is found, return errorstring | |
| static void | mark_method_allowed (unsigned int *allowed_methods, enum sipmethod method) |
| static void | mark_method_unallowed (unsigned int *allowed_methods, enum sipmethod method) |
| static void | mark_parsed_methods (unsigned int *methods, char *methods_str) |
| static int | match_and_cleanup_peer_sched (void *peerobj, void *arg, int flags) |
| static enum match_req_res | match_req_to_dialog (struct sip_pvt *sip_pvt_ptr, struct match_req_args *arg) |
| static int | method_match (enum sipmethod id, const char *name) |
| returns true if 'name' (with optional trailing whitespace) matches the sip method 'id'. Strictly speaking, SIP methods are case SENSITIVE, but we do a case-insensitive comparison to be more tolerant. following Jon Postel's rule: Be gentle in what you accept, strict with what you send | |
| static void | mwi_event_cb (const struct ast_event *event, void *userdata) |
| Receive MWI events that we have subscribed to. | |
| static void | network_change_event_cb (const struct ast_event *, void *) |
| static int | network_change_event_sched_cb (const void *data) |
| static void | network_change_event_subscribe (void) |
| static void | network_change_event_unsubscribe (void) |
| static struct sip_proxy * | obproxy_get (struct sip_pvt *dialog, struct sip_peer *peer) |
| Get default outbound proxy or global proxy. | |
| static void | on_dns_update_mwi (struct ast_sockaddr *old, struct ast_sockaddr *new, void *data) |
| static void | on_dns_update_peer (struct ast_sockaddr *old, struct ast_sockaddr *new, void *data) |
| static void | on_dns_update_registry (struct ast_sockaddr *old, struct ast_sockaddr *new, void *data) |
| static unsigned int | parse_allowed_methods (struct sip_request *req) |
| parse the Allow header to see what methods the endpoint we are communicating with allows. | |
| static void | parse_copy (struct sip_request *dst, const struct sip_request *src) |
| Copy SIP request, parse it. | |
| static int | parse_minse (const char *p_hdrval, int *const p_interval) |
| Session-Timers: Function for parsing Min-SE header. | |
| static void | parse_moved_contact (struct sip_pvt *p, struct sip_request *req, char **name, char **number, int set_call_forward) |
| Parse 302 Moved temporalily response. | |
| static int | parse_ok_contact (struct sip_pvt *pvt, struct sip_request *req) |
| Save contact header for 200 OK on INVITE. | |
| static enum parse_register_result | parse_register_contact (struct sip_pvt *pvt, struct sip_peer *peer, struct sip_request *req) |
| Parse contact header and save registration (peer registration). | |
| static int | parse_request (struct sip_request *req) |
| Parse a SIP message. | |
| static int | parse_session_expires (const char *p_hdrval, int *const p_interval, enum st_refresher_param *const p_ref) |
| Session-Timers: Function for parsing Session-Expires header. | |
| static int | parse_uri_legacy_check (char *uri, const char *scheme, char **user, char **pass, char **hostport, char **transport) |
| parse uri in a way that allows semicolon stripping if legacy mode is enabled | |
| static int | peer_cmp_cb (void *obj, void *arg, int flags) |
| static int | peer_dump_func (void *userobj, void *arg, int flags) |
| static int | peer_hash_cb (const void *obj, const int flags) |
| static int | peer_ipcmp_cb (void *obj, void *arg, int flags) |
| static int | peer_iphash_cb (const void *obj, const int flags) |
| static void | peer_mailboxes_to_str (struct ast_str **mailbox_str, struct sip_peer *peer) |
| list peer mailboxes to CLI | |
| static int | peer_markall_func (void *device, void *arg, int flags) |
| static void | peer_sched_cleanup (struct sip_peer *peer) |
| static int | peer_status (struct sip_peer *peer, char *status, int statuslen) |
| int | peercomparefunc (const void *a, const void *b) |
| static int | peers_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root) |
| unsigned int | port_str2int (const char *pt, unsigned int standard) |
| converts ascii port to int representation. If no pt buffer is provided or the pt has errors when being converted to an int value, the port provided as the standard is used. | |
| static void | print_codec_to_cli (int fd, struct ast_codec_pref *pref) |
| Print codec list from preference to CLI/manager. | |
| static void | print_group (int fd, ast_group_t group, int crlf) |
| Print call group and pickup group. | |
| static void | proc_422_rsp (struct sip_pvt *p, struct sip_request *rsp) |
| Handle 422 response to INVITE with session-timer requested. | |
| static int | proc_session_timer (const void *vp) |
| Session-Timers: Process session refresh timeout event. | |
| static int | process_crypto (struct sip_pvt *p, struct ast_rtp_instance *rtp, struct sip_srtp **srtp, const char *a) |
| static int | process_sdp (struct sip_pvt *p, struct sip_request *req, int t38action) |
| Process SIP SDP offer, select formats and activate media channels If offer is rejected, we will not change any properties of the call Return 0 on success, a negative value on errors. Must be called after find_sdp(). | |
| static int | process_sdp_a_audio (const char *a, struct sip_pvt *p, struct ast_rtp_codecs *newaudiortp, int *last_rtpmap_codec) |
| static int | process_sdp_a_image (const char *a, struct sip_pvt *p) |
| static int | process_sdp_a_sendonly (const char *a, int *sendonly) |
| static int | process_sdp_a_text (const char *a, struct sip_pvt *p, struct ast_rtp_codecs *newtextrtp, char *red_fmtp, int *red_num_gen, int *red_data_pt, int *last_rtpmap_codec) |
| static int | process_sdp_a_video (const char *a, struct sip_pvt *p, struct ast_rtp_codecs *newvideortp, int *last_rtpmap_codec) |
| static int | process_sdp_c (const char *c, struct ast_sockaddr *addr) |
| static int | process_sdp_o (const char *o, struct sip_pvt *p) |
| static int | process_via (struct sip_pvt *p, const struct sip_request *req) |
| Process the Via header according to RFC 3261 section 18.2.2. | |
| static struct sip_proxy * | proxy_from_config (const char *proxy, int sipconf_lineno, struct sip_proxy *dest) |
| Parse proxy string and return an ao2_alloc'd proxy. If dest is non-NULL, no allocation is performed and dest is used instead. On error NULL is returned. | |
| static int | proxy_update (struct sip_proxy *proxy) |
| static int | publish_expire (const void *data) |
| static void | pvt_set_needdestroy (struct sip_pvt *pvt, const char *reason) |
| static int | read_raw_content_length (const char *message) |
| Get the content length from an unparsed SIP message. | |
| static struct sip_peer * | realtime_peer (const char *newpeername, struct ast_sockaddr *addr, int devstate_only, int which_objects) |
| realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf Checks the "sipregs" realtime family from extconfig.conf if it's configured. This returns a pointer to a peer and because we use build_peer, we can rest assured that the refcount is bumped. | |
| static int | realtime_peer_by_addr (const char **name, struct ast_sockaddr *addr, const char *ipaddr, struct ast_variable **var, struct ast_variable **varregs) |
| static int | realtime_peer_by_name (const char *const *name, struct ast_sockaddr *addr, const char *ipaddr, struct ast_variable **var, struct ast_variable **varregs) |
| static struct ast_variable * | realtime_peer_get_sippeer_helper (const char **name, struct ast_variable **varregs) |
| static void | realtime_update_peer (const char *peername, struct ast_sockaddr *addr, const char *defaultuser, const char *fullcontact, const char *useragent, int expirey, unsigned short deprecated_username, int lastms) |
| Update peer object in realtime storage If the Asterisk system name is set in asterisk.conf, we will use that name and store that in the "regserver" field in the sippeers table to facilitate multi-server setups. | |
| static void | receive_message (struct sip_pvt *p, struct sip_request *req) |
| Receive SIP MESSAGE method messages. | |
| static struct sip_peer * | ref_peer (struct sip_peer *peer, char *tag) |
| static void | ref_proxy (struct sip_pvt *pvt, struct sip_proxy *proxy) |
| maintain proper refcounts for a sip_pvt's outboundproxy | |
| static const char * | referstatus2str (enum referstatus rstatus) |
| Convert transfer status to string. | |
| static void | reg_source_db (struct sip_peer *peer) |
| Get registration details from Asterisk DB. | |
| static void | register_peer_exten (struct sip_peer *peer, int onoff) |
| Automatically add peer extension to dial plan. | |
| static enum check_auth_result | register_verify (struct sip_pvt *p, struct ast_sockaddr *addr, struct sip_request *req, const char *uri) |
Verify registration of user
| |
| static struct sip_registry * | registry_addref (struct sip_registry *reg, char *tag) |
| Add object reference to SIP registry. | |
| static void * | registry_unref (struct sip_registry *reg, char *tag) |
| static const char * | regstate2str (enum sipregistrystate regstate) |
| Convert registration state status to string. | |
| static int | reinvite_timeout (const void *data) |
| static int | reload (void) |
| Part of Asterisk module interface. | |
| static int | reload_config (enum channelreloadreason reason) |
| Re-read SIP.conf config file. | |
| static char * | remove_uri_parameters (char *uri) |
| static int | reply_digest (struct sip_pvt *p, struct sip_request *req, char *header, int sipmethod, char *digest, int digest_len) |
| reply to authentication for outbound registrations | |
| static int | reqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod, uint32_t seqno, int newbranch) |
| Initialize a SIP request message (not the initial one in a dialog). | |
| static int | resp_needs_contact (const char *msg, enum sipmethod method) |
| Test if this response needs a contact header. | |
| static int | respprep (struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req) |
| Prepare SIP response packet. | |
| static int | restart_monitor (void) |
| Start the channel monitor thread. | |
| static void | restart_session_timer (struct sip_pvt *p) |
| Session-Timers: Restart session timer. | |
| static int | retrans_pkt (const void *data) |
| Retransmit SIP message if no answer (Called from scheduler). | |
| static int | send_provisional_keepalive (const void *data) |
| static int | send_provisional_keepalive_full (struct sip_pvt *pvt, int with_sdp) |
| static int | send_provisional_keepalive_with_sdp (const void *data) |
| static int | send_request (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno) |
| static int | send_response (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno) |
| Transmit response on SIP request. | |
| static enum ast_cc_service_type | service_string_to_service_type (const char *const service_string) |
| static int | set_address_from_contact (struct sip_pvt *pvt) |
| Change the other partys IP address based on given contact. | |
| static void | set_destination (struct sip_pvt *p, char *uri) |
| Set destination from SIP URI. | |
| static void | set_insecure_flags (struct ast_flags *flags, const char *value, int lineno) |
| Parse insecure= setting in sip.conf and set flags according to setting. | |
| static void | set_nonce_randdata (struct sip_pvt *p, int forceupdate) |
| builds the sip_pvt's randdata field which is used for the nonce challenge. When forceupdate is not set, the nonce is only updated if the current one is stale. In this case, a stalenonce is one which has already received a response, if a nonce has not received a response it is not always necessary or beneficial to create a new one. | |
| static void | set_peer_defaults (struct sip_peer *peer) |
| Set peer defaults before configuring specific configurations. | |
| static unsigned int | set_pvt_allowed_methods (struct sip_pvt *pvt, struct sip_request *req) |
| static void | set_socket_transport (struct sip_socket *socket, int transport) |
| static void | set_t38_capabilities (struct sip_pvt *p) |
| Set the global T38 capabilities on a SIP dialog structure. | |
| static int | setup_srtp (struct sip_srtp **srtp) |
| static int | show_channels_cb (void *__cur, void *__arg, int flags) |
| callback for show channel|subscription | |
| static int | show_chanstats_cb (void *__cur, void *__arg, int flags) |
| Callback for show_chanstats. | |
| static int | sip_addheader (struct ast_channel *chan, const char *data) |
| Add a SIP header to an outbound INVITE. | |
| struct sip_pvt * | sip_alloc (ast_string_field callid, struct ast_sockaddr *addr, int useglobal_nat, const int intended_method, struct sip_request *req) |
| Allocate sip_pvt structure, set defaults and link in the container. Returns a reference to the object so whoever uses it later must remember to release the reference. | |
| static void | sip_alreadygone (struct sip_pvt *dialog) |
| Encapsulate setting of SIP_ALREADYGONE to be able to trace it with debugging. | |
| static int | sip_answer (struct ast_channel *ast) |
| sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface | |
| static int | sip_call (struct ast_channel *ast, char *dest, int timeout) |
| Initiate SIP call from PBX used from the dial() application. | |
| int | sip_cancel_destroy (struct sip_pvt *p) |
| Cancel destruction of SIP dialog. Be careful as this also absorbs the reference - if you call it from within the scheduler, this might be the last reference. | |
| static void | sip_cc_agent_destructor (struct ast_cc_agent *agent) |
| static int | sip_cc_agent_init (struct ast_cc_agent *agent, struct ast_channel *chan) |
| static int | sip_cc_agent_recall (struct ast_cc_agent *agent) |
| static void | sip_cc_agent_respond (struct ast_cc_agent *agent, enum ast_cc_agent_response_reason reason) |
| static int | sip_cc_agent_start_monitoring (struct ast_cc_agent *agent) |
| static int | sip_cc_agent_start_offer_timer (struct ast_cc_agent *agent) |
| static int | sip_cc_agent_status_request (struct ast_cc_agent *agent) |
| static int | sip_cc_agent_stop_offer_timer (struct ast_cc_agent *agent) |
| static int | sip_cc_monitor_cancel_available_timer (struct ast_cc_monitor *monitor, int *sched_id) |
| static void | sip_cc_monitor_destructor (void *private_data) |
| static int | sip_cc_monitor_request_cc (struct ast_cc_monitor *monitor, int *available_timer_id) |
| static int | sip_cc_monitor_suspend (struct ast_cc_monitor *monitor) |
| static int | sip_cc_monitor_unsuspend (struct ast_cc_monitor *monitor) |
| static int | sip_check_authtimeout (time_t start) |
| Check if the authtimeout has expired. | |
| static char * | sip_cli_notify (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Cli command to send SIP notify to peer. | |
| static int | sip_debug_test_addr (const struct ast_sockaddr *addr) |
| See if we pass debug IP filter. | |
| static int | sip_debug_test_pvt (struct sip_pvt *p) |
| Test PVT for debugging output. | |
| struct sip_pvt * | sip_destroy (struct sip_pvt *p) |
| Destroy SIP call structure. Make it return NULL so the caller can do things like foo = sip_destroy(foo); and reduce the chance of bugs due to dangling pointers. | |
| static void | sip_destroy_fn (void *p) |
| static void | sip_destroy_peer (struct sip_peer *peer) |
| Destroy peer object from memory. | |
| static void | sip_destroy_peer_fn (void *peer) |
| static int | sip_devicestate (void *data) |
| Part of PBX channel interface. | |
| static char * | sip_do_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Turn on SIP debugging (CLI command). | |
| static char * | sip_do_debug_ip (int fd, const char *arg) |
| Enable SIP Debugging for a single IP. | |
| static char * | sip_do_debug_peer (int fd, const char *arg) |
| Turn on SIP debugging for a given peer. | |
| static int | sip_do_reload (enum channelreloadreason reason) |
| Reload module. | |
| static int | sip_dtmfmode (struct ast_channel *chan, const char *data) |
| Set the DTMFmode for an outbound SIP call (application). | |
| static void | sip_dump_history (struct sip_pvt *dialog) |
| Dump SIP history to debug log file at end of lifespan for SIP dialog. | |
| static int | sip_epa_register (const struct epa_static_data *static_data) |
| static void | sip_epa_unregister_all (void) |
| static int | sip_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
| sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links | |
| static const char * | sip_get_callid (struct ast_channel *chan) |
| Deliver SIP call ID for the call. | |
| static int | sip_get_cc_information (struct sip_request *req, char *subscribe_uri, size_t size, enum ast_cc_service_type *service) |
| static format_t | sip_get_codec (struct ast_channel *chan) |
| static enum ast_rtp_glue_result | sip_get_rtp_peer (struct ast_channel *chan, struct ast_rtp_instance **instance) |
| static enum ast_rtp_glue_result | sip_get_trtp_peer (struct ast_channel *chan, struct ast_rtp_instance **instance) |
| static struct ast_udptl * | sip_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_channel * | sip_new (struct sip_pvt *i, int state, const char *title, const char *linkedid) |
| Initiate a call in the SIP channel. | |
| static int | sip_notify_allocate (struct sip_pvt *p) |
| Allocate SIP refer structure. | |
| static int | sip_offer_timer_expire (const void *data) |
| static int | sip_park (struct ast_channel *chan1, struct ast_channel *chan2, struct sip_request *req, uint32_t seqno, const char *park_exten, const char *park_context) |
| static void * | sip_park_thread (void *stuff) |
| Park SIP call support function Starts in a new thread, then parks the call XXX Should we add a wait period after streaming audio and before hangup?? Sometimes the audio can't be heard before hangup. | |
| static void | sip_peer_hold (struct sip_pvt *p, int hold) |
| Change onhold state of a peer using a pvt structure. | |
| static int | sip_pickup (struct ast_channel *chan) |
| Pickup a call using the subsystem in features.c This is executed in a separate thread. | |
| static void * | sip_pickup_thread (void *stuff) |
| SIP pickup support function Starts in a new thread, then pickup the call. | |
| static void | sip_poke_all_peers (void) |
| Send a poke to all known peers. | |
| static int | sip_poke_noanswer (const void *data) |
| React to lack of answer to Qualify poke. | |
| static int | sip_poke_peer (struct sip_peer *peer, int force) |
| Check availability of peer, also keep NAT open. | |
| static int | sip_poke_peer_s (const void *data) |
| Poke peer (send qualify to check if peer is alive and well). | |
| static int | sip_prepare_socket (struct sip_pvt *p) |
| static char * | sip_prune_realtime (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Remove temporary realtime objects from memory (CLI). | |
| static struct ast_channel * | sip_pvt_lock_full (struct sip_pvt *pvt) |
| static char * | sip_qualify_peer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Send an OPTIONS packet to a SIP peer. | |
| static int | sip_queryoption (struct ast_channel *chan, int option, void *data, int *datalen) |
| Query an option on a SIP dialog. | |
| static void | sip_queue_hangup_cause (struct sip_pvt *p, int cause) |
| static struct ast_frame * | sip_read (struct ast_channel *ast) |
| Read SIP RTP from channel. | |
| static struct ast_sockaddr * | sip_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_channel * | sip_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_frame * | sip_rtp_read (struct ast_channel *ast, struct sip_pvt *p, int *faxdetect) |
| Read RTP from network. | |
| static const char * | sip_sanitized_host (const char *host) |
| void | sip_scheddestroy (struct sip_pvt *p, int ms) |
| Schedule destruction of SIP dialog. | |
| void | sip_scheddestroy_final (struct sip_pvt *p, int ms) |
| Schedule final destruction of SIP dialog. This can not be canceled. This function is used to keep a dialog around for a period of time in order to properly respond to any retransmits. | |
| static void | sip_send_all_mwi_subscriptions (void) |
| Send all MWI subscriptions. | |
| static void | sip_send_all_registers (void) |
| Send all known registrations. | |
| static int | sip_send_mwi_to_peer (struct sip_peer *peer, int cache_only) |
| Send message waiting indication to alert peer that they've got voicemail. | |
| static int | sip_senddigit_begin (struct ast_channel *ast, char digit) |
| static int | sip_senddigit_end (struct ast_channel *ast, char digit, unsigned int duration) |
| Send DTMF character on SIP channel within one call, we're able to transmit in many methods simultaneously. | |
| static int | sip_sendhtml (struct ast_channel *chan, int subclass, const char *data, int datalen) |
| Send message with Access-URL header, if this is an HTML URL only! | |
| static int | sip_sendtext (struct ast_channel *ast, const char *text) |
| static char * | sip_set_history (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Enable/Disable SIP History logging (CLI). | |
| static void | sip_set_redirstr (struct sip_pvt *p, char *reason) |
| Translate referring cause. | |
| static int | sip_set_rtp_peer (struct ast_channel *chan, struct ast_rtp_instance *instance, struct ast_rtp_instance *vinstance, struct ast_rtp_instance *tinstance, format_t codecs, int nat_active) |
| static int | sip_set_udptl_peer (struct ast_channel *chan, struct ast_udptl *udptl) |
| static int | sip_setoption (struct ast_channel *chan, int option, void *data, int datalen) |
| Set an option on a SIP dialog. | |
| static char * | sip_show_channel (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Show details of one active dialog. | |
| static char * | sip_show_channels (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| CLI for show channels or subscriptions. This is a new-style CLI handler so a single function contains the prototype for the function, the 'generator' to produce multiple entries in case it is required, and the actual handler for the command. | |
| static char * | sip_show_channelstats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| SIP show channelstats CLI (main function). | |
| static char * | sip_show_domains (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| CLI command to list local domains. | |
| static char * | sip_show_history (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Show history details of one dialog. | |
| static char * | sip_show_inuse (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| CLI Command to show calls within limits set by call_limit. | |
| static char * | sip_show_mwi (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | sip_show_objects (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| List all allocated SIP Objects (realtime or static). | |
| static char * | sip_show_peer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Show one peer in detail. | |
| static char * | sip_show_peers (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| CLI Show Peers command. | |
| static char * | sip_show_registry (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Show SIP Registry (registrations with other SIP proxies. | |
| static char * | sip_show_sched (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | sip_show_settings (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| List global settings for the SIP channel. | |
| static char * | sip_show_tcp (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Show active TCP connections. | |
| static char * | sip_show_user (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Show one user in detail. | |
| static char * | sip_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| CLI Command 'SIP Show Users'. | |
| static int | sip_sipredirect (struct sip_pvt *p, const char *dest) |
| Transfer call before connect with a 302 redirect. | |
| static struct sip_st_dlg * | sip_st_alloc (struct sip_pvt *const p) |
| Allocate Session-Timers struct w/in dialog. | |
| static int | sip_standard_port (enum sip_transport type, int port) |
| Returns the port to use for this socket. | |
| static int | sip_subscribe_mwi (const char *value, int lineno) |
| Parse mwi=> line in sip.conf and add to list. | |
| static void | sip_subscribe_mwi_destroy (struct sip_subscription_mwi *mwi) |
| Destroy MWI subscription object. | |
| static int | sip_subscribe_mwi_do (const void *data) |
| Send a subscription or resubscription for MWI. | |
| static int | sip_t38_abort (const void *data) |
| Called to deny a T38 reinvite if the core does not respond to our request. | |
| static struct ast_tcptls_session_instance * | sip_tcp_locate (struct ast_sockaddr *s) |
| Find thread for TCP/TLS session (based on IP/Port. | |
| static void * | sip_tcp_worker_fn (void *data) |
| SIP TCP connection handler. | |
| static void | sip_tcptls_client_args_destructor (void *obj) |
| static int | sip_tcptls_read (struct sip_request *req, struct ast_tcptls_session_instance *tcptls_session, int authenticated, time_t start) |
| Read SIP request or response from a TCP/TLS connection. | |
| static int | sip_tcptls_write (struct ast_tcptls_session_instance *tcptls_session, const void *buf, size_t len) |
| used to indicate to a tcptls thread that data is ready to be written | |
| static struct sip_threadinfo * | sip_threadinfo_create (struct ast_tcptls_session_instance *tcptls_session, int transport) |
| creates a sip_threadinfo object and links it into the threadt table. | |
| static void | sip_threadinfo_destructor (void *obj) |
| static int | sip_transfer (struct ast_channel *ast, const char *dest) |
| Transfer SIP call. | |
| static char * | sip_unregister (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Unregister (force expiration) a SIP peer in the registry via CLI. | |
| static void | sip_unregister_tests (void) |
| SIP test registration. | |
| static int | sip_write (struct ast_channel *ast, struct ast_frame *frame) |
| Send frame to media channel (rtp). | |
| static int | sipsock_read (int *id, int fd, short events, void *ignore) |
| Read data from SIP UDP socket. | |
| static int | sockaddr_is_null_or_any (const struct ast_sockaddr *addr) |
| static enum st_mode | st_get_mode (struct sip_pvt *p, int no_cached) |
| Get the session-timer mode. | |
| static enum st_refresher | st_get_refresher (struct sip_pvt *p) |
| Get the entity (UAC or UAS) that's acting as the session-timer refresher. | |
| static int | st_get_se (struct sip_pvt *p, int max) |
| Get Max or Min SE (session timer expiry). | |
| static void | start_session_timer (struct sip_pvt *p) |
| Session-Timers: Start session timer. | |
| static void | state_notify_build_xml (int state, int full, const char *exten, const char *context, struct ast_str **tmp, struct sip_pvt *p, int subscribed, const char *mfrom, const char *mto) |
| Builds XML portion of NOTIFY messages for presence or dialog updates. | |
| static const char * | stmode2str (enum st_mode m) |
| static void | stop_media_flows (struct sip_pvt *p) |
| Immediately stop RTP, VRTP and UDPTL as applicable. | |
| static void | stop_session_timer (struct sip_pvt *p) |
| Session-Timers: Stop session timer. | |
| static int | str2dtmfmode (const char *str) |
| maps a string to dtmfmode, returns -1 on error | |
| static enum st_mode | str2stmode (const char *s) |
| static enum st_refresher | str2strefresherparam (const char *s) |
| static const char * | strefresher2str (enum st_refresher r) |
| static const char * | strefresherparam2str (enum st_refresher r) |
| static const char * | subscription_type2str (enum subscriptiontype subtype) |
| Show subscription type in string format. | |
| static unsigned int | t38_get_rate (enum ast_control_t38_rate rate) |
| Get Max T.38 Transmission rate from T38 capabilities. | |
| static void | tcptls_packet_destructor (void *obj) |
| static struct sip_peer * | temp_peer (const char *name) |
| Create temporary peer (used in autocreatepeer mode). | |
| static void | temp_pvt_cleanup (void *) |
| static int | temp_pvt_init (void *) |
| static char * | terminate_uri (char *uri) |
| static int | threadinfo_locate_cb (void *obj, void *arg, int flags) |
| static int | threadt_cmp_cb (void *obj, void *arg, int flags) |
| static int | threadt_hash_cb (const void *obj, const int flags) |
| static char * | transfermode2str (enum transfermodes mode) |
| Convert transfer mode to text string. | |
| static int | transmit_cc_notify (struct ast_cc_agent *agent, struct sip_pvt *subscription, enum sip_cc_notify_state state) |
| static void | transmit_fake_auth_response (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable) |
| Send a fake 401 Unauthorized response when the administrator wants to hide the names of local devices from fishers. | |
| static int | transmit_info_with_aoc (struct sip_pvt *p, struct ast_aoc_decoded *decoded) |
| Send SIP INFO advice of charge message. | |
| static int | transmit_info_with_digit (struct sip_pvt *p, const char digit, unsigned int duration) |
| Send SIP INFO dtmf message, see Cisco documentation on cisco.com. | |
| static int | transmit_info_with_vidupdate (struct sip_pvt *p) |
| Send SIP INFO with video update request. | |
| static int | transmit_invite (struct sip_pvt *p, int sipmethod, int sdp, int init, const char *const explicit_uri) |
| Build REFER/INVITE/OPTIONS/SUBSCRIBE message and transmit it. | |
| static int | transmit_message_with_text (struct sip_pvt *p, const char *text) |
| Transmit text with SIP MESSAGE method. | |
| static int | transmit_notify_with_mwi (struct sip_pvt *p, int newmsgs, int oldmsgs, const char *vmexten) |
| Notify user of messages waiting in voicemail (RFC3842). | |
| static int | transmit_notify_with_sipfrag (struct sip_pvt *p, int cseq, char *message, int terminate) |
| Notify a transferring party of the status of transfer (RFC3515). | |
| static int | transmit_provisional_response (struct sip_pvt *p, const char *msg, const struct sip_request *req, int with_sdp) |
| static int | transmit_publish (struct sip_epa_entry *epa_entry, enum sip_publish_type publish_type, const char *const explicit_uri) |
| static int | transmit_refer (struct sip_pvt *p, const char *dest) |
| Transmit SIP REFER message (initiated by the transfer() dialplan application. | |
| static int | transmit_register (struct sip_registry *r, int sipmethod, const char *auth, const char *authheader) |
| Transmit register to SIP proxy or UA auth = NULL on the initial registration (from sip_reregister()). | |
| static int | transmit_reinvite_with_sdp (struct sip_pvt *p, int t38version, int oldsdp) |
| Transmit reinvite with SDP. | |
| static int | transmit_request (struct sip_pvt *p, int sipmethod, uint32_t seqno, enum xmittype reliable, int newbranch) |
| Transmit generic SIP request returns XMIT_ERROR if transmit failed with a critical error (don't retry). | |
| static int | transmit_request_with_auth (struct sip_pvt *p, int sipmethod, uint32_t seqno, enum xmittype reliable, int newbranch) |
| Transmit SIP request, auth added. | |
| static int | transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
| Transmit response, no retransmits. | |
| static int | transmit_response_reliable (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
| Transmit response, Make sure you get an ACK This is only used for responses to INVITEs, where we need to make sure we get an ACK. | |
| static int | transmit_response_using_temp (ast_string_field callid, struct ast_sockaddr *addr, int useglobal_nat, const int intended_method, const struct sip_request *req, const char *msg) |
| Transmit response, no retransmits, using a temporary pvt structure. | |
| static int | transmit_response_with_allow (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
| Append Accept header, content length before transmitting response. | |
| static int | transmit_response_with_auth (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *randdata, enum xmittype reliable, const char *header, int stale) |
| Respond with authorization request. | |
| static int | transmit_response_with_date (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
| Append date and content length before transmitting response. | |
| static int | transmit_response_with_minexpires (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
| Append Min-Expires header, content length before transmitting response. | |
| static int | transmit_response_with_minse (struct sip_pvt *p, const char *msg, const struct sip_request *req, int minse_int) |
| Transmit 422 response with Min-SE header (Session-Timers). | |
| static int | transmit_response_with_retry_after (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *seconds) |
| Append Retry-After header field when transmitting response. | |
| static int | transmit_response_with_sdp (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable, int oldsdp, int rpid) |
| Used for 200 OK and 183 early media. | |
| static int | transmit_response_with_sip_etag (struct sip_pvt *p, const char *msg, const struct sip_request *req, struct sip_esc_entry *esc_entry, int need_new_etag) |
| static int | transmit_response_with_t38_sdp (struct sip_pvt *p, char *msg, struct sip_request *req, int retrans) |
| Used for 200 OK and 183 early media. | |
| static int | transmit_response_with_unsupported (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *unsupported) |
| Transmit response, no retransmits. | |
| static int | transmit_state_notify (struct sip_pvt *p, int state, int full, int timeout) |
| Used in the SUBSCRIBE notification subsystem (RFC3265). | |
| static const char * | transport2str (enum sip_transport transport) |
| static const char * | trust_id_outbound2str (int mode) |
| static void | try_suggested_sip_codec (struct sip_pvt *p) |
| Try setting codec suggested by the SIP_CODEC channel variable. | |
| static void | unlink_all_peers_from_tables (void) |
| static void | unlink_marked_peers_from_tables (void) |
| static void | unlink_peer_from_tables (struct sip_peer *peer) |
| static void | unlink_peers_from_tables (peer_unlink_flag_t flag) |
| static int | unload_module (void) |
| PBX unload module API. | |
| static void * | unref_peer (struct sip_peer *peer, char *tag) |
| static int | update_call_counter (struct sip_pvt *fup, int event) |
| update_call_counter: Handle call_limit for SIP devices Setting a call-limit will cause calls above the limit not to be accepted. | |
| static void | update_connectedline (struct sip_pvt *p, const void *data, size_t datalen) |
| Notify peer that the connected line has changed. | |
| static void | update_peer (struct sip_peer *p, int expire) |
| Update peer data in database (if used). | |
| static void | update_peer_lastmsgssent (struct sip_peer *peer, int value, int locked) |
| static void | update_provisional_keepalive (struct sip_pvt *pvt, int with_sdp) |
| static void | update_redirecting (struct sip_pvt *p, const void *data, size_t datalen) |
| Send a provisional response indicating that a call was redirected. | |
Implementation of Session Initiation Protocol.
See Also:
Implementation of RFC 3261 - without S/MIME, and experimental TCP and TLS support Configuration file sip.conf
********** IMPORTANT *
******** General TODO:s
Better support of forking
VIA branch tag transaction checking
Transaction support
******** Wishlist: Improvements
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"
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
Definition in file chan_sip.c.
| #define append_history | ( | p, | |||
| event, | |||||
| fmt, | |||||
| args... | ) | append_history_full(p, "%-15s " fmt, event, ## args) |
Append to SIP dialog history.
Definition at line 2219 of file chan_sip.c.
Referenced by __sip_autodestruct(), __sip_reliable_xmit(), auto_congest(), build_reply_digest(), cb_extensionstate(), change_hold_state(), check_auth(), do_register_auth(), handle_invite_replaces(), handle_request_bye(), handle_request_do(), handle_request_invite(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response(), handle_response_invite(), local_attended_transfer(), obproxy_get(), pvt_set_needdestroy(), retrans_pkt(), send_request(), send_response(), sip_cancel_destroy(), sip_fixup(), sip_hangup(), sip_new(), sip_park_thread(), sip_reregister(), sip_scheddestroy(), sip_set_rtp_peer(), transmit_register(), transmit_reinvite_with_sdp(), transmit_response_with_auth(), and update_connectedline().
| #define BOGUS_PEER_MD5SECRET "intentionally_invalid_md5_string" |
We can recognise the bogus peer by this invalid MD5 hash.
Definition at line 1105 of file chan_sip.c.
Referenced by check_auth(), load_module(), and sip_reload().
| #define CHECK_AUTH_BUF_INITLEN 256 |
Definition at line 14831 of file chan_sip.c.
Referenced by check_auth(), and transmit_fake_auth_response().
| #define check_request_transport | ( | peer, | |||
| tmpl | ) |
generic function for determining if a correct transport is being used to contact a peer
this is done as a macro so that the "tmpl" var can be passed either a sip_request or a sip_peer
Definition at line 2302 of file chan_sip.c.
Referenced by create_addr_from_peer(), and register_verify().
| #define CONTAINER_UNLINK | ( | container, | |||
| obj, | |||||
| tag | ) |
Unlink the given object from the container and return TRUE if it was in the container.
Definition at line 7876 of file chan_sip.c.
Referenced by change_callid_pvt().
| #define DATA_EXPORT_SIP_PEER | ( | MEMBER | ) |
Definition at line 31622 of file chan_sip.c.
| #define FORMAT "%-15.15s %-15.15s %-15.15s %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s %-10.10s\n" |
Definition at line 18979 of file chan_sip.c.
| #define FORMAT "%-30.30s %-12.12s %-10.10s %-10.10s\n" |
Definition at line 18979 of file chan_sip.c.
| #define FORMAT "%-15.15s %-11.11s %-8.8s %-10.10u%-1.1s %-10.10u (%5.2f%%) %-6.4lf %-10.10u%-1.1s %-10.10u (%5.2f%%) %-6.4lf\n" |
Definition at line 18979 of file chan_sip.c.
| #define FORMAT "%-39.39s %-6.6s %-12.12s %8d %-20.20s %-25.25s\n" |
Definition at line 18979 of file chan_sip.c.
| #define FORMAT "%-40.40s %-20.20s %-16.16s\n" |
Definition at line 18979 of file chan_sip.c.
| #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" |
Definition at line 18979 of file chan_sip.c.
| #define FORMAT "%-47.47s %-9.9s %-6.6s\n" |
Definition at line 18979 of file chan_sip.c.
| #define FORMAT "%-25.25s %-15.15s %-15.15s \n" |
Definition at line 18979 of file chan_sip.c.
| #define FORMAT2 "%-15.15s %-15.15s %-15.15s %-15.15s %-7.7s %-15.15s %-10.10s %-10.10s\n" |
Definition at line 18978 of file chan_sip.c.
| #define FORMAT2 "%-15.15s %-11.11s %-8.8s %-10.10s %-10.10s ( %%) %-6.6s %-10.10s %-10.10s ( %%) %-6.6s\n" |
Definition at line 18978 of file chan_sip.c.
| #define FORMAT2 "%-39.39s %-6.6s %-12.12s %8.8s %-20.20s %-25.25s\n" |
Definition at line 18978 of file chan_sip.c.
| #define FORMAT2 "%-47.47s %9.9s %6.6s\n" |
Definition at line 18978 of file chan_sip.c.
| #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" |
Definition at line 18978 of file chan_sip.c.
| #define FORMAT3 "%-15.15s %-15.15s %-15.15s %-15.15s %-13.13s %-15.15s %-10.10s %-6.6s\n" |
Definition at line 18977 of file chan_sip.c.
Referenced by sip_show_channels().
| #define FORMAT4 "%-15.15s %-15.15s %-15.15s %-15.15s %-13.13s %-15.15s %-10.10s %-6.6d\n" |
Definition at line 18976 of file chan_sip.c.
Referenced by show_channels_cb().
| #define PEERS_FORMAT2 "%-25.25s %-39.39s %-3.3s %-10.10s %-3.3s %-8s %-10s %s\n" |
Definition at line 17287 of file chan_sip.c.
Referenced by _sip_show_peers(), and _sip_show_peers_one().
| #define SIP_PEDANTIC_DECODE | ( | str | ) |
if (sip_cfg.pedanticsipchecking && !ast_strlen_zero(str)) { \ ast_uri_decode(str); \ } \
Definition at line 690 of file chan_sip.c.
Referenced by check_user_full(), get_also_info(), get_destination(), get_refer_info(), and register_verify().
| #define sip_pvt_lock | ( | x | ) | ao2_lock(x) |
Definition at line 1091 of file chan_sip.c.
Referenced by __sip_ack(), __sip_autodestruct(), auto_congest(), cb_extensionstate(), complete_sipch(), find_call(), get_sip_pvt_byid_locked(), handle_incoming(), handle_invite_replaces(), handle_request_bye(), handle_request_invite(), handle_request_refer(), handle_request_subscribe(), local_attended_transfer(), parse_register_contact(), proc_session_timer(), register_verify(), retrans_pkt(), show_channels_cb(), show_chanstats_cb(), sip_answer(), sip_call(), sip_cc_agent_destructor(), sip_cc_agent_init(), sip_cc_agent_recall(), sip_cc_agent_respond(), sip_cc_monitor_request_cc(), sip_dtmfmode(), sip_fixup(), sip_get_rtp_peer(), sip_get_trtp_peer(), sip_get_udptl_peer(), sip_get_vrtp_peer(), sip_hangup(), sip_indicate(), sip_monitor_instance_destructor(), sip_new(), sip_pvt_lock_full(), sip_queryoption(), sip_read(), sip_reg_timeout(), sip_reinvite_retry(), sip_request_call(), sip_send_mwi_to_peer(), sip_senddigit_begin(), sip_senddigit_end(), sip_set_rtp_peer(), sip_set_udptl_peer(), sip_setoption(), sip_show_channel(), sip_show_history(), sip_t38_abort(), sip_transfer(), sip_write(), transmit_publish(), and update_call_counter().
| #define sip_pvt_trylock | ( | x | ) | ao2_trylock(x) |
Definition at line 1092 of file chan_sip.c.
Referenced by dialog_needdestroy(), sip_get_rtp_peer(), sip_get_trtp_peer(), sip_get_udptl_peer(), sip_get_vrtp_peer(), and sip_hangup().
| #define sip_pvt_unlock | ( | x | ) | ao2_unlock(x) |
Definition at line 1093 of file chan_sip.c.
Referenced by __sip_ack(), __sip_autodestruct(), auto_congest(), cb_extensionstate(), complete_sipch(), dialog_needdestroy(), dialog_unlink_all(), find_call(), get_sip_pvt_byid_locked(), handle_incoming(), handle_invite_replaces(), handle_request_bye(), handle_request_do(), handle_request_invite(), handle_request_refer(), handle_request_subscribe(), local_attended_transfer(), parse_register_contact(), proc_session_timer(), register_verify(), retrans_pkt(), send_provisional_keepalive_full(), show_channels_cb(), show_chanstats_cb(), sip_answer(), sip_call(), sip_cc_agent_destructor(), sip_cc_agent_init(), sip_cc_agent_recall(), sip_cc_agent_respond(), sip_cc_monitor_request_cc(), sip_dtmfmode(), sip_fixup(), sip_get_rtp_peer(), sip_get_trtp_peer(), sip_get_udptl_peer(), sip_get_vrtp_peer(), sip_hangup(), sip_indicate(), sip_monitor_instance_destructor(), sip_new(), sip_pvt_lock_full(), sip_queryoption(), sip_queue_hangup_cause(), sip_read(), sip_reg_timeout(), sip_reinvite_retry(), sip_request_call(), sip_send_mwi_to_peer(), sip_senddigit_begin(), sip_senddigit_end(), sip_set_rtp_peer(), sip_set_udptl_peer(), sip_setoption(), sip_show_channel(), sip_show_history(), sip_t38_abort(), sip_transfer(), sip_write(), transmit_publish(), and update_call_counter().
| #define UNLINK | ( | element, | |||
| head, | |||||
| prev | ) |
some list management macros.
Definition at line 1196 of file chan_sip.c.
Referenced by __sip_ack(), handle_request_cancel(), and retrans_pkt().
| enum match_req_res |
Definition at line 8173 of file chan_sip.c.
08173 { 08174 SIP_REQ_MATCH, 08175 SIP_REQ_NOT_MATCH, 08176 SIP_REQ_LOOP_DETECTED, 08177 };
| enum message_integrity |
Indication of a TCP message's integrity.
| MESSAGE_INVALID |
The message has an error in it with regards to its Content-Length header |
| MESSAGE_FRAGMENT |
The message is incomplete |
| MESSAGE_FRAGMENT_COMPLETE |
The data contains a complete message plus a fragment of another. |
| MESSAGE_COMPLETE |
The message is complete |
Definition at line 2504 of file chan_sip.c.
02504 { 02505 /*! 02506 * The message has an error in it with 02507 * regards to its Content-Length header 02508 */ 02509 MESSAGE_INVALID, 02510 /*! 02511 * The message is incomplete 02512 */ 02513 MESSAGE_FRAGMENT, 02514 /*! 02515 * The data contains a complete message 02516 * plus a fragment of another. 02517 */ 02518 MESSAGE_FRAGMENT_COMPLETE, 02519 /*! 02520 * The message is complete 02521 */ 02522 MESSAGE_COMPLETE, 02523 };
| enum peer_unlink_flag_t |
Definition at line 3004 of file chan_sip.c.
03004 { 03005 SIP_PEERS_MARKED, 03006 SIP_PEERS_ALL, 03007 } peer_unlink_flag_t;
| static const char * __get_header | ( | const struct sip_request * | req, | |
| const char * | name, | |||
| int * | start | |||
| ) | [static] |
Definition at line 7644 of file chan_sip.c.
References ast_skip_blanks(), find_alias(), len(), match(), and sip_cfg.
Referenced by build_route(), copy_all_header(), copy_via_headers(), func_header_read(), get_header(), handle_incoming(), handle_request_subscribe(), handle_response_register(), and parse_register_contact().
07645 { 07646 /* 07647 * Technically you can place arbitrary whitespace both before and after the ':' in 07648 * a header, although RFC3261 clearly says you shouldn't before, and place just 07649 * one afterwards. If you shouldn't do it, what absolute idiot decided it was 07650 * a good idea to say you can do it, and if you can do it, why in the hell would. 07651 * you say you shouldn't. 07652 * Anyways, pedanticsipchecking controls whether we allow spaces before ':', 07653 * and we always allow spaces after that for compatibility. 07654 */ 07655 const char *sname = find_alias(name, NULL); 07656 int x, len = strlen(name), slen = (sname ? 1 : 0); 07657 for (x = *start; x < req->headers; x++) { 07658 const char *header = REQ_OFFSET_TO_STR(req, header[x]); 07659 int smatch = 0, match = !strncasecmp(header, name, len); 07660 if (slen) { 07661 smatch = !strncasecmp(header, sname, slen); 07662 } 07663 if (match || smatch) { 07664 /* skip name */ 07665 const char *r = header + (match ? len : slen ); 07666 if (sip_cfg.pedanticsipchecking) { 07667 r = ast_skip_blanks(r); 07668 } 07669 07670 if (*r == ':') { 07671 *start = x+1; 07672 return ast_skip_blanks(r+1); 07673 } 07674 } 07675 } 07676 07677 /* Don't return NULL, so get_header is always a valid pointer */ 07678 return ""; 07679 }
| static int __set_address_from_contact | ( | const char * | fullcontact, | |
| struct ast_sockaddr * | addr, | |||
| int | tcp | |||
| ) | [static] |
Definition at line 14393 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_sockaddr_port, ast_sockaddr_resolve_first_transport(), ast_sockaddr_set_port, ast_strlen_zero(), get_transport_str2enum(), LOG_WARNING, and parse_uri_legacy_check().
Referenced by build_peer(), and set_address_from_contact().
14394 { 14395 char *hostport, *transport; 14396 char contact_buf[256]; 14397 char *contact; 14398 14399 /* Work on a copy */ 14400 ast_copy_string(contact_buf, fullcontact, sizeof(contact_buf)); 14401 contact = contact_buf; 14402 14403 /* 14404 * We have only the part in <brackets> here so we just need to parse a SIP URI. 14405 * 14406 * Note: The outbound proxy could be using UDP between the proxy and Asterisk. 14407 * We still need to be able to send to the remote agent through the proxy. 14408 */ 14409 14410 if (parse_uri_legacy_check(contact, "sip:,sips:", &contact, NULL, &hostport, 14411 &transport)) { 14412 ast_log(LOG_WARNING, "Invalid contact uri %s (missing sip: or sips:), attempting to use anyway\n", fullcontact); 14413 } 14414 14415 /* XXX This could block for a long time XXX */ 14416 /* We should only do this if it's a name, not an IP */ 14417 /* \todo - if there's no PORT number in contact - we are required to check NAPTR/SRV records 14418 to find transport, port address and hostname. If there's a port number, we have to 14419 assume that the hostport part is a host name and only look for an A/AAAA record in DNS. 14420 */ 14421 14422 /* If we took in an invalid URI, hostport may not have been initialized */ 14423 /* ast_sockaddr_resolve requires an initialized hostport string. */ 14424 if (ast_strlen_zero(hostport)) { 14425 ast_log(LOG_WARNING, "Invalid URI: parse_uri failed to acquire hostport\n"); 14426 return -1; 14427 } 14428 14429 if (ast_sockaddr_resolve_first_transport(addr, hostport, 0, get_transport_str2enum(transport))) { 14430 ast_log(LOG_WARNING, "Invalid host name in Contact: (can't " 14431 "resolve in DNS) : '%s'\n", hostport); 14432 return -1; 14433 } 14434 14435 /* set port */ 14436 if (!ast_sockaddr_port(addr)) { 14437 ast_sockaddr_set_port(addr, 14438 (get_transport_str2enum(transport) == 14439 SIP_TRANSPORT_TLS || 14440 !strncasecmp(fullcontact, "sips", 4)) ? 14441 STANDARD_TLS_PORT : STANDARD_SIP_PORT); 14442 } 14443 14444 return 0; 14445 }
| int __sip_ack | ( | struct sip_pvt * | p, | |
| uint32_t | seqno, | |||
| int | resp, | |||
| int | sipmethod | |||
| ) |
Acknowledges receipt of a packet and stops retransmission called with p locked.
Definition at line 4158 of file chan_sip.c.
References ast_debug, ast_free, ast_sched_del(), FALSE, ref_proxy(), sip_pvt_lock, sip_pvt_unlock, TRUE, and UNLINK.
Referenced by __sip_pretend_ack(), handle_incoming(), handle_request_invite(), handle_request_publish(), and handle_response().
04159 { 04160 struct sip_pkt *cur, *prev = NULL; 04161 const char *msg = "Not Found"; /* used only for debugging */ 04162 int res = FALSE; 04163 04164 /* If we have an outbound proxy for this dialog, then delete it now since 04165 the rest of the requests in this dialog needs to follow the routing. 04166 If obforcing is set, we will keep the outbound proxy during the whole 04167 dialog, regardless of what the SIP rfc says 04168 */ 04169 if (p->outboundproxy && !p->outboundproxy->force){ 04170 ref_proxy(p, NULL); 04171 } 04172 04173 for (cur = p->packets; cur; prev = cur, cur = cur->next) { 04174 if (cur->seqno != seqno || cur->is_resp != resp) { 04175 continue; 04176 } 04177 if (cur->is_resp || cur->method == sipmethod) { 04178 res = TRUE; 04179 msg = "Found"; 04180 if (!resp && (seqno == p->pendinginvite)) { 04181 ast_debug(1, "Acked pending invite %u\n", p->pendinginvite); 04182 p->pendinginvite = 0; 04183 } 04184 if (cur->retransid > -1) { 04185 if (sipdebug) 04186 ast_debug(4, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid); 04187 } 04188 /* This odd section is designed to thwart a 04189 * race condition in the packet scheduler. There are 04190 * two conditions under which deleting the packet from the 04191 * scheduler can fail. 04192 * 04193 * 1. The packet has been removed from the scheduler because retransmission 04194 * is being attempted. The problem is that if the packet is currently attempting 04195 * retransmission and we are at this point in the code, then that MUST mean 04196 * that retrans_pkt is waiting on p's lock. Therefore we will relinquish the 04197 * lock temporarily to allow retransmission. 04198 * 04199 * 2. The packet has reached its maximum number of retransmissions and has 04200 * been permanently removed from the packet scheduler. If this is the case, then 04201 * the packet's retransid will be set to -1. The atomicity of the setting and checking 04202 * of the retransid to -1 is ensured since in both cases p's lock is held. 04203 */ 04204 while (cur->retransid > -1 && ast_sched_del(sched, cur->retransid)) { 04205 sip_pvt_unlock(p); 04206 usleep(1); 04207 sip_pvt_lock(p); 04208 } 04209 UNLINK(cur, p->packets, prev); 04210 dialog_unref(cur->owner, "unref pkt cur->owner dialog from sip ack before freeing pkt"); 04211 if (cur->data) { 04212 ast_free(cur->data); 04213 } 04214 ast_free(cur); 04215 break; 04216 } 04217 } 04218 ast_debug(1, "Stopping retransmission on '%s' of %s %u: Match %s\n", 04219 p->callid, resp ? "Response" : "Request", seqno, msg); 04220 return res; 04221 }
| static int __sip_autodestruct | ( | const void * | data | ) | [static] |
Kill a SIP dialog (called only by the scheduler) The scheduler has a reference to this dialog when p->autokillid != -1, and we are called using that reference. So if the event is not rescheduled, we need to call dialog_unref().
Definition at line 4021 of file chan_sip.c.
References __sip_pretend_ack(), append_history, AST_CAUSE_PROTOCOL_ERROR, ast_channel_unlock, ast_channel_unref, ast_debug, AST_EXTENSION_DEACTIVATED, ast_log(), ast_queue_hangup_with_cause(), dialog_unlink_all(), LOG_WARNING, method_match(), NONE, pvt_set_needdestroy(), sip_methods, sip_pvt_lock, sip_pvt_lock_full(), sip_pvt_unlock, sip_scheddestroy(), stop_media_flows(), cfsip_methods::text, transmit_request_with_auth(), transmit_state_notify(), and TRUE.
Referenced by sip_scheddestroy(), and sip_show_sched().
04022 { 04023 struct sip_pvt *p = (struct sip_pvt *)data; 04024 struct ast_channel *owner; 04025 04026 /* If this is a subscription, tell the phone that we got a timeout */ 04027 if (p->subscribed && p->subscribed != MWI_NOTIFICATION && p->subscribed != CALL_COMPLETION) { 04028 transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE); /* Send last notification */ 04029 p->subscribed = NONE; 04030 append_history(p, "Subscribestatus", "timeout"); 04031 ast_debug(3, "Re-scheduled destruction of SIP subscription %s\n", p->callid ? p->callid : "<unknown>"); 04032 return 10000; /* Reschedule this destruction so that we know that it's gone */ 04033 } 04034 04035 /* If there are packets still waiting for delivery, delay the destruction */ 04036 if (p->packets) { 04037 if (!p->needdestroy) { 04038 char method_str[31]; 04039 ast_debug(3, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>"); 04040 append_history(p, "ReliableXmit", "timeout"); 04041 if (sscanf(p->lastmsg, "Tx: %30s", method_str) == 1 || sscanf(p->lastmsg, "Rx: %30s", method_str) == 1) { 04042 if (p->ongoing_reinvite || method_match(SIP_CANCEL, method_str) || method_match(SIP_BYE, method_str)) { 04043 pvt_set_needdestroy(p, "autodestruct"); 04044 } 04045 } 04046 return 10000; 04047 } else { 04048 /* They've had their chance to respond. Time to bail */ 04049 __sip_pretend_ack(p); 04050 } 04051 } 04052 04053 /* Reset schedule ID */ 04054 p->autokillid = -1; 04055 04056 /* 04057 * Lock both the pvt and the channel safely so that we can queue up a frame. 04058 */ 04059 owner = sip_pvt_lock_full(p); 04060 if (owner) { 04061 ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner %s in place (Method: %s). Rescheduling destruction for 10000 ms\n", p->callid, owner->name, sip_methods[p->method].text); 04062 ast_queue_hangup_with_cause(owner, AST_CAUSE_PROTOCOL_ERROR); 04063 ast_channel_unlock(owner); 04064 ast_channel_unref(owner); 04065 sip_pvt_unlock(p); 04066 return 10000; 04067 } else if (p->refer && !p->alreadygone) { 04068 ast_debug(3, "Finally hanging up channel after transfer: %s\n", p->callid); 04069 stop_media_flows(p); 04070 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 04071 append_history(p, "ReferBYE", "Sending BYE on transferer call leg %s", p->callid); 04072 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 04073 } else { 04074 append_history(p, "AutoDestroy", "%s", p->callid); 04075 ast_debug(3, "Auto destroying SIP dialog '%s'\n", p->callid); 04076 sip_pvt_unlock(p); 04077 dialog_unlink_all(p); /* once it's unlinked and unrefd everywhere, it'll be freed automagically */ 04078 sip_pvt_lock(p); 04079 /* dialog_unref(p, "unref dialog-- no other matching conditions"); -- unlink all now should finish off the dialog's references and free it. */ 04080 /* sip_destroy(p); */ /* Go ahead and destroy dialog. All attempts to recover is done */ 04081 /* sip_destroy also absorbs the reference */ 04082 } 04083 04084 sip_pvt_unlock(p); 04085 04086 dialog_unref(p, "The ref to a dialog passed to this sched callback is going out of scope; unref it."); 04087 04088 return 0; 04089 }
| void __sip_destroy | ( | struct sip_pvt * | p, | |
| int | lockowner, | |||
| int | lockdialoglist | |||
| ) |
Execute destruction of SIP dialog structure, release memory.
Definition at line 5968 of file chan_sip.c.
References ao2_ref, ao2_t_ref, ast_cc_config_params_destroy(), ast_channel_lock, ast_channel_unlock, ast_debug, ast_free, ast_free_ha(), AST_LIST_REMOVE_HEAD, ast_rtp_instance_destroy(), AST_SOFTHANGUP_DEV, ast_string_field_free_memory, ast_test_flag, ast_udptl_destroy(), ast_variables_destroy(), ast_verbose, deinit_req(), free_old_route(), registry_unref(), sip_debug_test_pvt(), sip_dump_history(), sip_methods, sip_srtp_destroy(), stop_session_timer(), cfsip_methods::text, unref_peer(), and update_call_counter().
Referenced by sip_destroy().
05969 { 05970 struct sip_request *req; 05971 05972 /* Destroy Session-Timers if allocated */ 05973 if (p->stimer) { 05974 p->stimer->quit_flag = 1; 05975 stop_session_timer(p); 05976 ast_free(p->stimer); 05977 p->stimer = NULL; 05978 } 05979 05980 if (sip_debug_test_pvt(p)) 05981 ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 05982 05983 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 05984 update_call_counter(p, DEC_CALL_LIMIT); 05985 ast_debug(2, "This call did not properly clean up call limits. Call ID %s\n", p->callid); 05986 } 05987 05988 /* Unlink us from the owner if we have one */ 05989 if (p->owner) { 05990 if (lockowner) 05991 ast_channel_lock(p->owner); 05992 ast_debug(1, "Detaching from %s\n", p->owner->name); 05993 p->owner->tech_pvt = NULL; 05994 /* Make sure that the channel knows its backend is going away */ 05995 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 05996 if (lockowner) 05997 ast_channel_unlock(p->owner); 05998 /* Give the channel a chance to react before deallocation */ 05999 usleep(1); 06000 } 06001 06002 /* Remove link from peer to subscription of MWI */ 06003 if (p->relatedpeer && p->relatedpeer->mwipvt == p) 06004 p->relatedpeer->mwipvt = dialog_unref(p->relatedpeer->mwipvt, "delete ->relatedpeer->mwipvt"); 06005 if (p->relatedpeer && p->relatedpeer->call == p) 06006 p->relatedpeer->call = dialog_unref(p->relatedpeer->call, "unset the relatedpeer->call field in tandem with relatedpeer field itself"); 06007 06008 if (p->relatedpeer) 06009 p->relatedpeer = unref_peer(p->relatedpeer,"unsetting a dialog relatedpeer field in sip_destroy"); 06010 06011 if (p->registry) { 06012 if (p->registry->call == p) 06013 p->registry->call = dialog_unref(p->registry->call, "nulling out the registry's call dialog field in unlink_all"); 06014 p->registry = registry_unref(p->registry, "delete p->registry"); 06015 } 06016 06017 if (p->mwi) { 06018 p->mwi->call = NULL; 06019 p->mwi = NULL; 06020 } 06021 06022 if (dumphistory) 06023 sip_dump_history(p); 06024 06025 if (p->options) { 06026 if (p->options->outboundproxy) { 06027 ao2_ref(p->options->outboundproxy, -1); 06028 } 06029 ast_free(p->options); 06030 p->options = NULL; 06031 } 06032 06033 if (p->notify) { 06034 ast_variables_destroy(p->notify->headers); 06035 ast_free(p->notify->content); 06036 ast_free(p->notify); 06037 p->notify = NULL; 06038 } 06039 if (p->rtp) { 06040 ast_rtp_instance_destroy(p->rtp); 06041 p->rtp = NULL; 06042 } 06043 if (p->vrtp) { 06044 ast_rtp_instance_destroy(p->vrtp); 06045 p->vrtp = NULL; 06046 } 06047 if (p->trtp) { 06048 ast_rtp_instance_destroy(p->trtp); 06049 p->trtp = NULL; 06050 } 06051 if (p->udptl) { 06052 ast_udptl_destroy(p->udptl); 06053 p->udptl = NULL; 06054 } 06055 if (p->refer) { 06056 if (p->refer->refer_call) { 06057 p->refer->refer_call = dialog_unref(p->refer->refer_call, "unref dialog p->refer->refer_call"); 06058 } 06059 ast_free(p->refer); 06060 p->refer = NULL; 06061 } 06062 if (p->route) { 06063 free_old_route(p->route); 06064 p->route = NULL; 06065 } 06066 deinit_req(&p->initreq); 06067 06068 /* Clear history */ 06069 if (p->history) { 06070 struct sip_history *hist; 06071 while ( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) { 06072 ast_free(hist); 06073 p->history_entries--; 06074 } 06075 ast_free(p->history); 06076 p->history = NULL; 06077 } 06078 06079 while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) { 06080 ast_free(req); 06081 } 06082 06083 if (p->chanvars) { 06084 ast_variables_destroy(p->chanvars); 06085 p->chanvars = NULL; 06086 } 06087 06088 if (p->srtp) { 06089 sip_srtp_destroy(p->srtp); 06090 p->srtp = NULL; 06091 } 06092 06093 if (p->vsrtp) { 06094 sip_srtp_destroy(p->vsrtp); 06095 p->vsrtp = NULL; 06096 } 06097 06098 if (p->tsrtp) { 06099 sip_srtp_destroy(p->tsrtp); 06100 p->tsrtp = NULL; 06101 } 06102 06103 if (p->directmediaha) { 06104 ast_free_ha(p->directmediaha); 06105 p->directmediaha = NULL; 06106 } 06107 06108 ast_string_field_free_memory(p); 06109 06110 ast_cc_config_params_destroy(p->cc_params); 06111 p->cc_params = NULL; 06112 06113 if (p->epa_entry) { 06114 ao2_ref(p->epa_entry, -1); 06115 p->epa_entry = NULL; 06116 } 06117 06118 if (p->socket.tcptls_session) { 06119 ao2_ref(p->socket.tcptls_session, -1); 06120 p->socket.tcptls_session = NULL; 06121 } 06122 06123 if (p->peerauth) { 06124 ao2_t_ref(p->peerauth, -1, "Removing active peer authentication"); 06125 p->peerauth = NULL; 06126 } 06127 }
| static int __sip_do_register | ( | struct sip_registry * | r | ) | [static] |
Register with SIP proxy.
Definition at line 13598 of file chan_sip.c.
References transmit_register().
Referenced by sip_reregister().
13599 { 13600 int res; 13601 13602 res = transmit_register(r, SIP_REGISTER, NULL, NULL); 13603 return res; 13604 }
| void __sip_pretend_ack | ( | struct sip_pvt * | p | ) |
Pretend to ack all packets called with p locked.
Definition at line 4225 of file chan_sip.c.
References __sip_ack(), ast_log(), ast_str_buffer(), find_sip_method(), LOG_WARNING, sip_methods, and cfsip_methods::text.
Referenced by __sip_autodestruct(), handle_request_bye(), handle_request_cancel(), and sip_reg_timeout().
04226 { 04227 struct sip_pkt *cur = NULL; 04228 04229 while (p->packets) { 04230 int method; 04231 if (cur == p->packets) { 04232 ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text); 04233 return; 04234 } 04235 cur = p->packets; 04236 method = (cur->method) ? cur->method : find_sip_method(ast_str_buffer(cur->data)); 04237 __sip_ack(p, cur->seqno, cur->is_resp, method); 04238 } 04239 }
| static enum sip_result __sip_reliable_xmit | ( | struct sip_pvt * | p, | |
| uint32_t | seqno, | |||
| int | resp, | |||
| struct ast_str * | data, | |||
| int | fatal, | |||
| int | sipmethod | |||
| ) | [static] |
Definition at line 3930 of file chan_sip.c.
References __sip_xmit(), append_history, ast_calloc, ast_debug, ast_free, ast_log(), AST_PTHREADT_NULL, AST_SCHED_DEL, AST_SCHED_REPLACE_VARIABLE, ast_str_buffer(), ast_str_create(), ast_str_set(), ast_str_strlen(), ast_tvnow(), DEFAULT_RETRANS, LOG_ERROR, and retrans_pkt().
Referenced by send_request(), and send_response().
03931 { 03932 struct sip_pkt *pkt = NULL; 03933 int siptimer_a = DEFAULT_RETRANS; 03934 int xmitres = 0; 03935 unsigned respid; 03936 03937 if (sipmethod == SIP_INVITE) { 03938 /* Note this is a pending invite */ 03939 p->pendinginvite = seqno; 03940 } 03941 03942 /* If the transport is something reliable (TCP or TLS) then don't really send this reliably */ 03943 /* I removed the code from retrans_pkt that does the same thing so it doesn't get loaded into the scheduler */ 03944 /*! \todo According to the RFC some packets need to be retransmitted even if its TCP, so this needs to get revisited */ 03945 if (!(p->socket.type & SIP_TRANSPORT_UDP)) { 03946 xmitres = __sip_xmit(p, data); /* Send packet */ 03947 if (xmitres == XMIT_ERROR) { /* Serious network trouble, no need to try again */ 03948 append_history(p, "XmitErr", "%s", fatal ? "(Critical)" : "(Non-critical)"); 03949 return AST_FAILURE; 03950 } else { 03951 return AST_SUCCESS; 03952 } 03953 } 03954 03955 if (!(pkt = ast_calloc(1, sizeof(*pkt)))) { 03956 return AST_FAILURE; 03957 } 03958 /* copy data, add a terminator and save length */ 03959 if (!(pkt->data = ast_str_create(ast_str_strlen(data)))) { 03960 ast_free(pkt); 03961 return AST_FAILURE; 03962 } 03963 ast_str_set(&pkt->data, 0, "%s%s", ast_str_buffer(data), "\0"); 03964 /* copy other parameters from the caller */ 03965 pkt->method = sipmethod; 03966 pkt->seqno = seqno; 03967 pkt->is_resp = resp; 03968 pkt->is_fatal = fatal; 03969 pkt->owner = dialog_ref(p, "__sip_reliable_xmit: setting pkt->owner"); 03970 pkt->next = p->packets; 03971 p->packets = pkt; /* Add it to the queue */ 03972 if (resp) { 03973 /* Parse out the response code */ 03974 if (sscanf(ast_str_buffer(pkt->data), "SIP/2.0 %30u", &respid) == 1) { 03975 pkt->response_code = respid; 03976 } 03977 } 03978 pkt->timer_t1 = p->timer_t1; /* Set SIP timer T1 */ 03979 pkt->retransid = -1; 03980 if (pkt->timer_t1) { 03981 siptimer_a = pkt->timer_t1; 03982 } 03983 03984 pkt->time_sent = ast_tvnow(); /* time packet was sent */ 03985 pkt->retrans_stop_time = 64 * (pkt->timer_t1 ? pkt->timer_t1 : DEFAULT_TIMER_T1); /* time in ms after pkt->time_sent to stop retransmission */ 03986 03987 /* Schedule retransmission */ 03988 AST_SCHED_REPLACE_VARIABLE(pkt->retransid, sched, siptimer_a, retrans_pkt, pkt, 1); 03989 if (sipdebug) { 03990 ast_debug(4, "*** SIP TIMER: Initializing retransmit timer on packet: Id #%d\n", pkt->retransid); 03991 } 03992 03993 xmitres = __sip_xmit(pkt->owner, pkt->data); /* Send packet */ 03994 03995 if (xmitres == XMIT_ERROR) { /* Serious network trouble, no need to try again */ 03996 append_history(pkt->owner, "XmitErr", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)"); 03997 ast_log(LOG_ERROR, "Serious Network Trouble; __sip_xmit returns error for pkt data\n"); 03998 AST_SCHED_DEL(sched, pkt->retransid); 03999 p->packets = pkt->next; 04000 pkt->owner = dialog_unref(pkt->owner,"pkt is being freed, its dialog ref is dead now"); 04001 ast_free(pkt->data); 04002 ast_free(pkt); 04003 return AST_FAILURE; 04004 } else { 04005 /* This is odd, but since the retrans timer starts at 500ms and the do_monitor thread 04006 * only wakes up every 1000ms by default, we have to poke the thread here to make 04007 * sure it successfully detects this must be retransmitted in less time than 04008 * it usually sleeps for. Otherwise it might not retransmit this packet for 1000ms. */ 04009 if (monitor_thread != AST_PTHREADT_NULL) { 04010 pthread_kill(monitor_thread, SIGURG); 04011 } 04012 return AST_SUCCESS; 04013 } 04014 }
| int __sip_semi_ack | ( | struct sip_pvt * | p, | |
| uint32_t | seqno, | |||
| int | resp, | |||
| int | sipmethod | |||
| ) |
Acks receipt of packet, keep it around (used for provisional responses).
Definition at line 4242 of file chan_sip.c.
References ast_debug, AST_SCHED_DEL, ast_str_buffer(), FALSE, method_match(), sip_methods, cfsip_methods::text, and TRUE.
Referenced by handle_response(), and sip_hangup().
04243 { 04244 struct sip_pkt *cur; 04245 int res = FALSE; 04246 04247 for (cur = p->packets; cur; cur = cur->next) { 04248 if (cur->seqno == seqno && cur->is_resp == resp && 04249 (cur->is_resp || method_match(sipmethod, ast_str_buffer(cur->data)))) { 04250 /* this is our baby */ 04251 if (cur->retransid > -1) { 04252 if (sipdebug) 04253 ast_debug(4, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text); 04254 } 04255 AST_SCHED_DEL(sched, cur->retransid); 04256 res = TRUE; 04257 break; 04258 } 04259 } 04260 ast_debug(1, "(Provisional) Stopping retransmission (but retaining packet) on '%s' %s %u: %s\n", p->callid, resp ? "Response" : "Request", seqno, res == -1 ? "Not Found" : "Found"); 04261 return res; 04262 }
| static int __sip_subscribe_mwi_do | ( | struct sip_subscription_mwi * | mwi | ) | [static] |
Actually setup an MWI subscription or resubscribe.
Definition at line 12862 of file chan_sip.c.
References ast_dnsmgr_lookup_cb(), ast_set_flag, ast_sip_ouraddrfor(), ast_sockaddr_port, ast_sockaddr_set_port, ast_string_field_set, ast_strlen_zero(), ASTOBJ_REF, ASTOBJ_UNREF, build_contact(), build_via(), change_callid_pvt(), create_addr(), dialog_unlink_all(), get_address_family_filter(), get_srv_protocol(), get_srv_service(), MAXHOSTNAMELEN, obproxy_get(), on_dns_update_mwi(), ref_proxy(), set_socket_transport(), sip_alloc(), sip_cfg, sip_subscribe_mwi_destroy(), and transmit_invite().
Referenced by sip_subscribe_mwi_do().
12863 { 12864 /* If we have no DNS manager let's do a lookup */ 12865 if (!mwi->dnsmgr) { 12866 char transport[MAXHOSTNAMELEN]; 12867 struct sip_subscription_mwi *saved; 12868 snprintf(transport, sizeof(transport), "_%s._%s", get_srv_service(mwi->transport), get_srv_protocol(mwi->transport)); 12869 12870 mwi->us.ss.ss_family = get_address_family_filter(mwi->transport); /* Filter address family */ 12871 saved = ASTOBJ_REF(mwi); 12872 ast_dnsmgr_lookup_cb(mwi->hostname, &mwi->us, &mwi->dnsmgr, sip_cfg.srvlookup ? transport : NULL, on_dns_update_mwi, saved); 12873 if (!mwi->dnsmgr) { 12874 ASTOBJ_UNREF(saved, sip_subscribe_mwi_destroy); /* dnsmgr disabled, remove reference */ 12875 } 12876 } 12877 12878 /* If we already have a subscription up simply send a resubscription */ 12879 if (mwi->call) { 12880 transmit_invite(mwi->call, SIP_SUBSCRIBE, 0, 0, NULL); 12881 return 0; 12882 } 12883 12884 /* Create a dialog that we will use for the subscription */ 12885 if (!(mwi->call = sip_alloc(NULL, NULL, 0, SIP_SUBSCRIBE, NULL))) { 12886 return -1; 12887 } 12888 12889 ref_proxy(mwi->call, obproxy_get(mwi->call, NULL)); 12890 12891 if (!ast_sockaddr_port(&mwi->us) && mwi->portno) { 12892 ast_sockaddr_set_port(&mwi->us, mwi->portno); 12893 } 12894 12895 /* Setup the destination of our subscription */ 12896 if (create_addr(mwi->call, mwi->hostname, &mwi->us, 0)) { 12897 dialog_unlink_all(mwi->call); 12898 mwi->call = dialog_unref(mwi->call, "unref dialog after unlink_all"); 12899 return 0; 12900 } 12901 12902 mwi->call->expiry = mwi_expiry; 12903 12904 if (!mwi->dnsmgr && mwi->portno) { 12905 ast_sockaddr_set_port(&mwi->call->sa, mwi->portno); 12906 ast_sockaddr_set_port(&mwi->call->recv, mwi->portno); 12907 } else { 12908 mwi->portno = ast_sockaddr_port(&mwi->call->sa); 12909 } 12910 12911 /* Set various other information */ 12912 if (!ast_strlen_zero(mwi->authuser)) { 12913 ast_string_field_set(mwi->call, peername, mwi->authuser); 12914 ast_string_field_set(mwi->call, authname, mwi->authuser); 12915 ast_string_field_set(mwi->call, fromuser, mwi->authuser); 12916 } else { 12917 ast_string_field_set(mwi->call, peername, mwi->username); 12918 ast_string_field_set(mwi->call, authname, mwi->username); 12919 ast_string_field_set(mwi->call, fromuser, mwi->username); 12920 } 12921 ast_string_field_set(mwi->call, username, mwi->username); 12922 if (!ast_strlen_zero(mwi->secret)) { 12923 ast_string_field_set(mwi->call, peersecret, mwi->secret); 12924 } 12925 set_socket_transport(&mwi->call->socket, mwi->transport); 12926 mwi->call->socket.port = htons(mwi->portno); 12927 ast_sip_ouraddrfor(&mwi->call->sa, &mwi->call->ourip, mwi->call); 12928 build_contact(mwi->call); 12929 build_via(mwi->call); 12930 12931 /* Change the dialog callid. */ 12932 change_callid_pvt(mwi->call, NULL); 12933 12934 ast_set_flag(&mwi->call->flags[0], SIP_OUTGOING); 12935 12936 /* Associate the call with us */ 12937 mwi->call->mwi = ASTOBJ_REF(mwi); 12938 12939 mwi->call->subscribed = MWI_NOTIFICATION; 12940 12941 /* Actually send the packet */ 12942 transmit_invite(mwi->call, SIP_SUBSCRIBE, 0, 2, NULL); 12943 12944 return 0; 12945 }
| static int __sip_xmit | ( | struct sip_pvt * | p, | |
| struct ast_str * | data | |||
| ) | [static] |
Definition at line 3530 of file chan_sip.c.
References ast_debug, ast_log(), ast_sendto(), ast_sockaddr_stringify(), ast_str_buffer(), ast_str_strlen(), errno, get_transport_pvt(), LOG_WARNING, sip_prepare_socket(), sip_real_dst(), and sip_tcptls_write().
Referenced by __sip_reliable_xmit(), retrans_pkt(), send_request(), and send_response().
03531 { 03532 int res = 0; 03533 const struct ast_sockaddr *dst = sip_real_dst(p); 03534 03535 ast_debug(2, "Trying to put '%.11s' onto %s socket destined for %s\n", ast_str_buffer(data), get_transport_pvt(p), ast_sockaddr_stringify(dst)); 03536 03537 if (sip_prepare_socket(p) < 0) { 03538 return XMIT_ERROR; 03539 } 03540 03541 if (p->socket.type == SIP_TRANSPORT_UDP) { 03542 res = ast_sendto(p->socket.fd, ast_str_buffer(data), ast_str_strlen(data), 0, dst); 03543 } else if (p->socket.tcptls_session) { 03544 res = sip_tcptls_write(p->socket.tcptls_session, ast_str_buffer(data), ast_str_strlen(data)); 03545 } else { 03546 ast_debug(2, "Socket type is TCP but no tcptls_session is present to write to\n"); 03547 return XMIT_ERROR; 03548 } 03549 03550 if (res == -1) { 03551 switch (errno) { 03552 case EBADF: /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */ 03553 case EHOSTUNREACH: /* Host can't be reached */ 03554 case ENETDOWN: /* Interface down */ 03555 case ENETUNREACH: /* Network failure */ 03556 case ECONNREFUSED: /* ICMP port unreachable */ 03557 res = XMIT_ERROR; /* Don't bother with trying to transmit again */ 03558 } 03559 } 03560 if (res != ast_str_strlen(data)) { 03561 ast_log(LOG_WARNING, "sip_xmit of %p (len %zu) to %s returned %d: %s\n", data, ast_str_strlen(data), ast_sockaddr_stringify(dst), res, strerror(errno)); 03562 } 03563 03564 return res; 03565 }
| static int __transmit_response | ( | struct sip_pvt * | p, | |
| const char * | msg, | |||
| const struct sip_request * | req, | |||
| enum xmittype | reliable | |||
| ) | [static] |
Base transmit response function.
Definition at line 10843 of file chan_sip.c.
References add_cc_call_info_to_response(), add_diversion_header(), add_header(), add_rpid(), ast_cause2str(), ast_clear_flag, ast_log(), ast_test_flag, get_header(), hangup_sip2cause(), LOG_WARNING, respprep(), and send_response().
Referenced by transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), and transmit_response_using_temp().
10844 { 10845 struct sip_request resp; 10846 uint32_t seqno = 0; 10847 10848 if (reliable && (sscanf(get_header(req, "CSeq"), "%30u ", &seqno) != 1)) { 10849 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 10850 return -1; 10851 } 10852 respprep(&resp, p, msg, req); 10853 10854 if (ast_test_flag(&p->flags[0], SIP_SENDRPID) 10855 && ast_test_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND) 10856 && (!strncmp(msg, "180", 3) || !strncmp(msg, "183", 3))) { 10857 ast_clear_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND); 10858 add_rpid(&resp, p); 10859 } 10860 if (ast_test_flag(&p->flags[0], SIP_OFFER_CC)) { 10861 add_cc_call_info_to_response(p, &resp); 10862 } 10863 10864 /* If we are sending a 302 Redirect we can add a diversion header if the redirect information is set */ 10865 if (!strncmp(msg, "302", 3)) { 10866 add_diversion_header(&resp, p); 10867 } 10868 10869 /* If we are cancelling an incoming invite for some reason, add information 10870 about the reason why we are doing this in clear text */ 10871 if (p->method == SIP_INVITE && msg[0] != '1') { 10872 char buf[20]; 10873 10874 if (ast_test_flag(&p->flags[1], SIP_PAGE2_Q850_REASON)) { 10875 int hangupcause = 0; 10876 10877 if (p->owner && p->owner->hangupcause) { 10878 hangupcause = p->owner->hangupcause; 10879 } else if (p->hangupcause) { 10880 hangupcause = p->hangupcause; 10881 } else { 10882 int respcode; 10883 if (sscanf(msg, "%30d ", &respcode)) 10884 hangupcause = hangup_sip2cause(respcode); 10885 } 10886 10887 if (hangupcause) { 10888 sprintf(buf, "Q.850;cause=%i", hangupcause & 0x7f); 10889 add_header(&resp, "Reason", buf); 10890 } 10891 } 10892 10893 if (p->owner && p->owner->hangupcause) { 10894 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 10895 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 10896 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 10897 } 10898 } 10899 return send_response(p, &resp, reliable, seqno); 10900 }
| static char * _sip_qualify_peer | ( | int | type, | |
| int | fd, | |||
| struct mansession * | s, | |||
| const struct message * | m, | |||
| int | argc, | |||
| const char * | argv[] | |||
| ) | [static] |
Send qualify message to peer from cli or manager. Mostly for debugging.
Definition at line 17975 of file chan_sip.c.
References ast_cli(), astman_send_error(), CLI_SHOWUSAGE, CLI_SUCCESS, FALSE, find_peer(), sip_poke_peer(), TRUE, and unref_peer().
Referenced by manager_sip_qualify_peer(), and sip_qualify_peer().
17976 { 17977 struct sip_peer *peer; 17978 int load_realtime; 17979 17980 if (argc < 4) 17981 return CLI_SHOWUSAGE; 17982 17983 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 17984 if ((peer = find_peer(argv[3], NULL, load_realtime, FINDPEERS, FALSE, 0))) { 17985 sip_poke_peer(peer, 1); 17986 unref_peer(peer, "qualify: done with peer"); 17987 } else if (type == 0) { 17988 ast_cli(fd, "Peer '%s' not found\n", argv[3]); 17989 } else { 17990 astman_send_error(s, m, "Peer not found"); 17991 } 17992 return CLI_SUCCESS; 17993 }
| static char * _sip_show_peer | ( | int | type, | |
| int | fd, | |||
| struct mansession * | s, | |||
| const struct message * | m, | |||
| int | argc, | |||
| const char * | argv[] | |||
| ) | [static] |
Show one peer in detail (main function).
Definition at line 18060 of file chan_sip.c.
References allowoverlap2str(), ao2_lock, ao2_t_ref, ao2_unlock, ARRAY_LEN, ast_callerid_merge(), ast_cdr_flags2str(), ast_check_realtime(), ast_cli(), AST_CLI_YESNO, ast_codec_pref_index(), ast_describe_caller_presentation(), ast_getformatname(), ast_getformatname_multiple(), AST_LIST_TRAVERSE, ast_print_group(), ast_sched_when(), ast_sockaddr_port, ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_str_alloca, ast_str_buffer(), ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), astman_send_error(), CLI_SHOWUSAGE, CLI_SUCCESS, dtmfmode2str(), FALSE, faxec2str(), find_peer(), get_transport(), get_transport_list(), insecure2str(), ast_variable::name, ast_variable::next, peer_mailboxes_to_str(), peer_status(), print_codec_to_cli(), print_group(), S_OR, sip_cfg, status, stmode2str(), strefresherparam2str(), text, transfermode2str(), TRUE, trust_id_outbound2str(), unref_peer(), and ast_variable::value.
Referenced by manager_sip_show_peer(), and sip_show_peer().
18061 { 18062 char status[30] = ""; 18063 char cbuf[256]; 18064 struct sip_peer *peer; 18065 char codec_buf[512]; 18066 struct ast_codec_pref *pref; 18067 struct ast_variable *v; 18068 int x = 0, load_realtime; 18069 format_t codec = 0; 18070 int realtimepeers; 18071 18072 realtimepeers = ast_check_realtime("sippeers"); 18073 18074 if (argc < 4) 18075 return CLI_SHOWUSAGE; 18076 18077 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 18078 peer = find_peer(argv[3], NULL, load_realtime, FINDPEERS, FALSE, 0); 18079 18080 if (s) { /* Manager */ 18081 if (peer) { 18082 const char *id = astman_get_header(m, "ActionID"); 18083 18084 astman_append(s, "Response: Success\r\n"); 18085 if (!ast_strlen_zero(id)) 18086 astman_append(s, "ActionID: %s\r\n", id); 18087 } else { 18088 snprintf (cbuf, sizeof(cbuf), "Peer %s not found.", argv[3]); 18089 astman_send_error(s, m, cbuf); 18090 return CLI_SUCCESS; 18091 } 18092 } 18093 if (peer && type==0 ) { /* Normal listing */ 18094 struct ast_str *mailbox_str = ast_str_alloca(512); 18095 struct sip_auth_container *credentials; 18096 18097 ao2_lock(peer); 18098 credentials = peer->auth; 18099 if (credentials) { 18100 ao2_t_ref(credentials, +1, "Ref peer auth for show"); 18101 } 18102 ao2_unlock(peer); 18103 18104 ast_cli(fd, "\n\n"); 18105 ast_cli(fd, " * Name : %s\n", peer->name); 18106 if (realtimepeers) { /* Realtime is enabled */ 18107 ast_cli(fd, " Realtime peer: %s\n", peer->is_realtime ? "Yes, cached" : "No"); 18108 } 18109 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 18110 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>"); 18111 ast_cli(fd, " Remote Secret: %s\n", ast_strlen_zero(peer->remotesecret)?"<Not set>":"<Set>"); 18112 if (credentials) { 18113 struct sip_auth *auth; 18114 18115 AST_LIST_TRAVERSE(&credentials->list, auth, node) { 18116 ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s %s\n", 18117 auth->realm, 18118 auth->username, 18119 !ast_strlen_zero(auth->secret) 18120 ? "<Secret set>" 18121 : (!ast_strlen_zero(auth->md5secret) 18122 ? "<MD5secret set>" : "<Not set>")); 18123 } 18124 ao2_t_ref(credentials, -1, "Unref peer auth for show"); 18125 } 18126 ast_cli(fd, " Context : %s\n", peer->context); 18127 ast_cli(fd, " Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") ); 18128 ast_cli(fd, " Language : %s\n", peer->language); 18129 if (!ast_strlen_zero(peer->accountcode)) 18130 ast_cli(fd, " Accountcode : %s\n", peer->accountcode); 18131 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(peer->amaflags)); 18132 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(peer->allowtransfer)); 18133 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres)); 18134 if (!ast_strlen_zero(peer->fromuser)) 18135 ast_cli(fd, " FromUser : %s\n", peer->fromuser); 18136 if (!ast_strlen_zero(peer->fromdomain)) 18137 ast_cli(fd, " FromDomain : %s Port %d\n", peer->fromdomain, (peer->fromdomainport) ? peer->fromdomainport : STANDARD_SIP_PORT); 18138 ast_cli(fd, " Callgroup : "); 18139 print_group(fd, peer->callgroup, 0); 18140 ast_cli(fd, " Pickupgroup : "); 18141 print_group(fd, peer->pickupgroup, 0); 18142 peer_mailboxes_to_str(&mailbox_str, peer); 18143 ast_cli(fd, " MOH Suggest : %s\n", peer->mohsuggest); 18144 ast_cli(fd, " Mailbox : %s\n", ast_str_buffer(mailbox_str)); 18145 ast_cli(fd, " VM Extension : %s\n", peer->vmexten); 18146 ast_cli(fd, " LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff); 18147 ast_cli(fd, " Call limit : %d\n", peer->call_limit); 18148 ast_cli(fd, " Max forwards : %d\n", peer->maxforwards); 18149 if (peer->busy_level) 18150 ast_cli(fd, " Busy level : %d\n", peer->busy_level); 18151 ast_cli(fd, " Dynamic : %s\n", AST_CLI_YESNO(peer->host_dynamic)); 18152 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 18153 ast_cli(fd, " MaxCallBR : %d kbps\n", peer->maxcallbitrate); 18154 ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, peer->expire)); 18155 ast_cli(fd, " Insecure : %s\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE))); 18156 ast_cli(fd, " Force rport : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT))); 18157 ast_cli(fd, " ACL : %s\n", AST_CLI_YESNO(peer->ha != NULL)); 18158 ast_cli(fd, " DirectMedACL : %s\n", AST_CLI_YESNO(peer->directmediaha != NULL)); 18159 ast_cli(fd, " T.38 support : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT))); 18160 ast_cli(fd, " T.38 EC mode : %s\n", faxec2str(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT))); 18161 ast_cli(fd, " T.38 MaxDtgrm: %u\n", peer->t38_maxdatagram); 18162 ast_cli(fd, " DirectMedia : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_DIRECT_MEDIA))); 18163 ast_cli(fd, " PromiscRedir : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR))); 18164 ast_cli(fd, " User=Phone : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_USEREQPHONE))); 18165 ast_cli(fd, " Video Support: %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT) || ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS))); 18166 ast_cli(fd, " Text Support : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT))); 18167 ast_cli(fd, " Ign SDP ver : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_IGNORESDPVERSION))); 18168 ast_cli(fd, " Trust RPID : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_TRUSTRPID))); 18169 ast_cli(fd, " Send RPID : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_SENDRPID))); 18170 ast_cli(fd, " TrustIDOutbnd: %s\n", trust_id_outbound2str(ast_test_flag(&peer->flags[1], SIP_PAGE2_TRUST_ID_OUTBOUND))); 18171 ast_cli(fd, " Subscriptions: %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))); 18172 ast_cli(fd, " Overlap dial : %s\n", allowoverlap2str(ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP))); 18173 if (peer->outboundproxy) 18174 ast_cli(fd, " Outb. proxy : %s %s\n", ast_strlen_zero(peer->outboundproxy->name) ? "<not set>" : peer->outboundproxy->name, 18175 peer->outboundproxy->force ? "(forced)" : ""); 18176 18177 /* - is enumerated */ 18178 ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 18179 ast_cli(fd, " Timer T1 : %d\n", peer->timer_t1); 18180 ast_cli(fd, " Timer B : %d\n", peer->timer_b); 18181 ast_cli(fd, " ToHost : %s\n", peer->tohost); 18182 ast_cli(fd, " Addr->IP : %s\n", ast_sockaddr_stringify(&peer->addr)); 18183 ast_cli(fd, " Defaddr->IP : %s\n", ast_sockaddr_stringify(&peer->defaddr)); 18184 ast_cli(fd, " Prim.Transp. : %s\n", get_transport(peer->socket.type)); 18185 ast_cli(fd, " Allowed.Trsp : %s\n", get_transport_list(peer->transports)); 18186 if (!ast_strlen_zero(sip_cfg.regcontext)) 18187 ast_cli(fd, " Reg. exten : %s\n", peer->regexten); 18188 ast_cli(fd, " Def. Username: %s\n", peer->username); 18189 ast_cli(fd, " SIP Options : "); 18190 if (peer->sipoptions) { 18191 int lastoption = -1; 18192 for (x = 0 ; x < ARRAY_LEN(sip_options); x++) { 18193 if (sip_options[x].id != lastoption) { 18194 if (peer->sipoptions & sip_options[x].id) 18195 ast_cli(fd, "%s ", sip_options[x].text); 18196 lastoption = x; 18197 } 18198 } 18199 } else 18200 ast_cli(fd, "(none)"); 18201 18202 ast_cli(fd, "\n"); 18203 ast_cli(fd, " Codecs : "); 18204 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 18205 ast_cli(fd, "%s\n", codec_buf); 18206 ast_cli(fd, " Codec Order : ("); 18207 print_codec_to_cli(fd, &peer->prefs); 18208 ast_cli(fd, ")\n"); 18209 18210 ast_cli(fd, " Auto-Framing : %s\n", AST_CLI_YESNO(peer->autoframing)); 18211 ast_cli(fd, " Status : "); 18212 peer_status(peer, status, sizeof(status)); 18213 ast_cli(fd, "%s\n", status); 18214 ast_cli(fd, " Useragent : %s\n", peer->useragent); 18215 ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); 18216 ast_cli(fd, " Qualify Freq : %d ms\n", peer->qualifyfreq); 18217 if (peer->chanvars) { 18218 ast_cli(fd, " Variables :\n"); 18219 for (v = peer->chanvars ; v ; v = v->next) 18220 ast_cli(fd, " %s = %s\n", v->name, v->value); 18221 } 18222 18223 ast_cli(fd, " Sess-Timers : %s\n", stmode2str(peer->stimer.st_mode_oper)); 18224 ast_cli(fd, " Sess-Refresh : %s\n", strefresherparam2str(peer->stimer.st_ref)); 18225 ast_cli(fd, " Sess-Expires : %d secs\n", peer->stimer.st_max_se); 18226 ast_cli(fd, " Min-Sess : %d secs\n", peer->stimer.st_min_se); 18227 ast_cli(fd, " RTP Engine : %s\n", peer->engine); 18228 ast_cli(fd, " Parkinglot : %s\n", peer->parkinglot); 18229 ast_cli(fd, " Use Reason : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_Q850_REASON))); 18230 ast_cli(fd, " Encryption : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_USE_SRTP))); 18231 ast_cli(fd, "\n"); 18232 peer = unref_peer(peer, "sip_show_peer: unref_peer: done with peer ptr"); 18233 } else if (peer && type == 1) { /* manager listing */ 18234 char buffer[256]; 18235 struct ast_str *mailbox_str = ast_str_alloca(512); 18236 astman_append(s, "Channeltype: SIP\r\n"); 18237 astman_append(s, "ObjectName: %s\r\n", peer->name); 18238 astman_append(s, "ChanObjectType: peer\r\n"); 18239 astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y"); 18240 astman_append(s, "RemoteSecretExist: %s\r\n", ast_strlen_zero(peer->remotesecret)?"N":"Y"); 18241 astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y"); 18242 astman_append(s, "Context: %s\r\n", peer->context); 18243 astman_append(s, "Language: %s\r\n", peer->language); 18244 if (!ast_strlen_zero(peer->accountcode)) 18245 astman_append(s, "Accountcode: %s\r\n", peer->accountcode); 18246 astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags)); 18247 astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres)); 18248 if (!ast_strlen_zero(peer->fromuser)) 18249 astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser); 18250 if (!ast_strlen_zero(peer->fromdomain)) 18251 astman_append(s, "SIP-FromDomain: %s\r\nSip-FromDomain-Port: %d\r\n", peer->fromdomain, (peer->fromdomainport) ? peer->fromdomainport : STANDARD_SIP_PORT); 18252 astman_append(s, "Callgroup: "); 18253 astman_append(s, "%s\r\n", ast_print_group(buffer, sizeof(buffer), peer->callgroup)); 18254 astman_append(s, "Pickupgroup: "); 18255 astman_append(s, "%s\r\n", ast_print_group(buffer, sizeof(buffer), peer->pickupgroup)); 18256 astman_append(s, "MOHSuggest: %s\r\n", peer->mohsuggest); 18257 peer_mailboxes_to_str(&mailbox_str, peer); 18258 astman_append(s, "VoiceMailbox: %s\r\n", ast_str_buffer(mailbox_str)); 18259 astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer)); 18260 astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent); 18261 astman_append(s, "Maxforwards: %d\r\n", peer->maxforwards); 18262 astman_append(s, "Call-limit: %d\r\n", peer->call_limit); 18263 astman_append(s, "Busy-level: %d\r\n", peer->busy_level); 18264 astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate); 18265 astman_append(s, "Dynamic: %s\r\n", peer->host_dynamic?"Y":"N"); 18266 astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); 18267 astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched, peer->expire)); 18268 astman_append(s, "SIP-AuthInsecure: %s\r\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE))); 18269 astman_append(s, "SIP-Forcerport: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT)?"Y":"N")); 18270 astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N")); 18271 astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_DIRECT_MEDIA)?"Y":"N")); 18272 astman_append(s, "SIP-DirectMedia: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_DIRECT_MEDIA)?"Y":"N")); 18273 astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N")); 18274 astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N")); 18275 astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N")); 18276 astman_append(s, "SIP-TextSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT)?"Y":"N")); 18277 astman_append(s, "SIP-T.38Support: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT)?"Y":"N")); 18278 astman_append(s, "SIP-T.38EC: %s\r\n", faxec2str(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT))); 18279 astman_append(s, "SIP-T.38MaxDtgrm: %u\r\n", peer->t38_maxdatagram); 18280 astman_append(s, "SIP-Sess-Timers: %s\r\n", stmode2str(peer->stimer.st_mode_oper)); 18281 astman_append(s, "SIP-Sess-Refresh: %s\r\n", strefresherparam2str(peer->stimer.st_ref)); 18282 astman_append(s, "SIP-Sess-Expires: %d\r\n", peer->stimer.st_max_se); 18283 astman_append(s, "SIP-Sess-Min: %d\r\n", peer->stimer.st_min_se); 18284 astman_append(s, "SIP-RTP-Engine: %s\r\n", peer->engine); 18285 astman_append(s, "SIP-Encryption: %s\r\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_USE_SRTP) ? "Y" : "N"); 18286 18287 /* - is enumerated */ 18288 astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 18289 astman_append(s, "ToHost: %s\r\n", peer->tohost); 18290 astman_append(s, "Address-IP: %s\r\nAddress-Port: %d\r\n", ast_sockaddr_stringify_addr(&peer->addr), ast_sockaddr_port(&peer->addr)); 18291 astman_append(s, "Default-addr-IP: %s\r\nDefault-addr-port: %d\r\n", ast_sockaddr_stringify_addr(&peer->defaddr), ast_sockaddr_port(&peer->defaddr)); 18292 astman_append(s, "Default-Username: %s\r\n", peer->username); 18293 if (!ast_strlen_zero(sip_cfg.regcontext)) 18294 astman_append(s, "RegExtension: %s\r\n", peer->regexten); 18295 astman_append(s, "Codecs: "); 18296 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 18297 astman_append(s, "%s\r\n", codec_buf); 18298 astman_append(s, "CodecOrder: "); 18299 pref = &peer->prefs; 18300 for(x = 0; x < 64 ; x++) { 18301 codec = ast_codec_pref_index(pref, x); 18302 if (!codec) 18303 break; 18304 astman_append(s, "%s", ast_getformatname(codec)); 18305 if (x < 63 && ast_codec_pref_index(pref, x+1)) 18306 astman_append(s, ","); 18307 } 18308 18309 astman_append(s, "\r\n"); 18310 astman_append(s, "Status: "); 18311 peer_status(peer, status, sizeof(status)); 18312 astman_append(s, "%s\r\n", status); 18313 astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent); 18314 astman_append(s, "Reg-Contact: %s\r\n", peer->fullcontact); 18315 astman_append(s, "QualifyFreq: %d ms\r\n", peer->qualifyfreq); 18316 astman_append(s, "Parkinglot: %s\r\n", peer->parkinglot); 18317 if (peer->chanvars) { 18318 for (v = peer->chanvars ; v ; v = v->next) { 18319 astman_append(s, "ChanVariable: %s=%s\r\n", v->name, v->value); 18320 } 18321 } 18322 astman_append(s, "SIP-Use-Reason-Header: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_Q850_REASON)) ? "Y" : "N"); 18323 18324 peer = unref_peer(peer, "sip_show_peer: unref_peer: done with peer"); 18325 18326 } else { 18327 ast_cli(fd, "Peer %s not found.\n", argv[3]); 18328 ast_cli(fd, "\n"); 18329 } 18330 18331 return CLI_SUCCESS; 18332 }
| static char * _sip_show_peers | ( | int | fd, | |
| int * | total, | |||
| struct mansession * | s, | |||
| const struct message * | m, | |||
| int | argc, | |||
| const char * | argv[] | |||
| ) | [static] |
Execute sip show peers command.
Definition at line 17302 of file chan_sip.c.
References _sip_show_peers_one(), ao2_callback, ao2_container_count(), ao2_iterator_destroy(), ao2_lock, ao2_t_iterator_next, ao2_unlock, ast_calloc, ast_check_realtime(), ast_cli(), ast_free, ast_log(), AST_LOG_ERROR, ast_strlen_zero(), astman_get_header(), CLI_FAILURE, CLI_SHOWUSAGE, CLI_SUCCESS, FALSE, show_peers_context::havepattern, id, show_peers_context::idtext, OBJ_MULTIPLE, peercomparefunc(), PEERS_FORMAT2, show_peers_context::peers_mon_offline, show_peers_context::peers_mon_online, show_peers_context::peers_unmon_offline, show_peers_context::peers_unmon_online, show_peers_context::realtimepeers, show_peers_context::regexbuf, TRUE, and unref_peer().
Referenced by manager_sip_show_peers(), and sip_show_peers().
17303 { 17304 struct show_peers_context cont = { 17305 .havepattern = FALSE, 17306 .idtext = "", 17307 17308 .peers_mon_online = 0, 17309 .peers_mon_offline = 0, 17310 .peers_unmon_online = 0, 17311 .peers_unmon_offline = 0, 17312 }; 17313 struct sip_peer *peer; 17314 struct ao2_iterator* it_peers; 17315 17316 int total_peers = 0; 17317 const char *id; 17318 struct sip_peer **peerarray; 17319 int k; 17320 17321 cont.realtimepeers = ast_check_realtime("sippeers"); 17322 17323 if (s) { /* Manager - get ActionID */ 17324 id = astman_get_header(m, "ActionID"); 17325 if (!ast_strlen_zero(id)) { 17326 snprintf(cont.idtext, sizeof(cont.idtext), "ActionID: %s\r\n", id); 17327 } 17328 } 17329 17330 switch (argc) { 17331 case 5: 17332 if (!strcasecmp(argv[3], "like")) { 17333 if (regcomp(&cont.regexbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 17334 return CLI_SHOWUSAGE; 17335 cont.havepattern = TRUE; 17336 } else 17337 return CLI_SHOWUSAGE; 17338 case 3: 17339 break; 17340 default: 17341 return CLI_SHOWUSAGE; 17342 } 17343 17344 if (!s) { 17345 /* Normal list */ 17346 ast_cli(fd, PEERS_FORMAT2, "Name/username", "Host", "Dyn", "Forcerport", "ACL", "Port", "Status", (cont.realtimepeers ? "Realtime" : "")); 17347 } 17348 17349 ao2_lock(peers); 17350 if (!(it_peers = ao2_callback(peers, OBJ_MULTIPLE, NULL, NULL))) { 17351 ast_log(AST_LOG_ERROR, "Unable to create iterator for peers container for sip show peers\n"); 17352 ao2_unlock(peers); 17353 return CLI_FAILURE; 17354 } 17355 if (!(peerarray = ast_calloc(sizeof(struct sip_peer *), ao2_container_count(peers)))) { 17356 ast_log(AST_LOG_ERROR, "Unable to allocate peer array for sip show peers\n"); 17357 ao2_iterator_destroy(it_peers); 17358 ao2_unlock(peers); 17359 return CLI_FAILURE; 17360 } 17361 ao2_unlock(peers); 17362 17363 while ((peer = ao2_t_iterator_next(it_peers, "iterate thru peers table"))) { 17364 ao2_lock(peer); 17365 17366 if (!(peer->type & SIP_TYPE_PEER)) { 17367 ao2_unlock(peer); 17368 unref_peer(peer, "unref peer because it's actually a user"); 17369 continue; 17370 } 17371 17372 if (cont.havepattern && regexec(&cont.regexbuf, peer->name, 0, NULL, 0)) { 17373 ao2_unlock(peer); 17374 unref_peer(peer, "toss iterator peer ptr before continue"); 17375 continue; 17376 } 17377 17378 peerarray[total_peers++] = peer; 17379 ao2_unlock(peer); 17380 } 17381 ao2_iterator_destroy(it_peers); 17382 17383 qsort(peerarray, total_peers, sizeof(struct sip_peer *), peercomparefunc); 17384 17385 for(k = 0; k < total_peers; k++) { 17386 peerarray[k] = _sip_show_peers_one(fd, s, &cont, peerarray[k]); 17387 } 17388 17389 if (!s) { 17390 ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n", 17391 total_peers, cont.peers_mon_online, cont.peers_mon_offline, cont.peers_unmon_online, cont.peers_unmon_offline); 17392 } 17393 17394 if (cont.havepattern) { 17395 regfree(&cont.regexbuf); 17396 } 17397 17398 if (total) { 17399 *total = total_peers; 17400 } 17401 17402 ast_free(peerarray); 17403 17404 return CLI_SUCCESS; 17405 }
| static struct sip_peer * _sip_show_peers_one | ( | int | fd, | |
| struct mansession * | s, | |||
| struct show_peers_context * | cont, | |||
| struct sip_peer * | peer | |||
| ) | [static, read] |
Emit informations for one peer during sip show peers command.
Definition at line 17408 of file chan_sip.c.
References ao2_lock, ao2_unlock, ast_cli(), ast_copy_string(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_sockaddr_stringify_port(), ast_strdupa, ast_strlen_zero(), ast_test_flag, astman_append(), show_peers_context::havepattern, show_peers_context::idtext, name, peer_status(), PEERS_FORMAT2, show_peers_context::peers_mon_offline, show_peers_context::peers_mon_online, show_peers_context::peers_unmon_offline, show_peers_context::peers_unmon_online, show_peers_context::realtimepeers, show_peers_context::regexbuf, status, and unref_peer().
Referenced by _sip_show_peers().
17409 { 17410 /* _sip_show_peers_one() is separated from _sip_show_peers() to properly free the ast_strdupa 17411 * (this is executed in a loop in _sip_show_peers() ) 17412 */ 17413 17414 char name[256]; 17415 char status[20] = ""; 17416 char pstatus; 17417 17418 /* 17419 * tmp_port and tmp_host store copies of ast_sockaddr_stringify strings since the 17420 * string pointers for that function aren't valid between subsequent calls to 17421 * ast_sockaddr_stringify functions 17422 */ 17423 char *tmp_port; 17424 char *tmp_host; 17425 17426 tmp_port = ast_sockaddr_isnull(&peer->addr) ? 17427 "0" : ast_strdupa(ast_sockaddr_stringify_port(&peer->addr)); 17428 17429 tmp_host = ast_sockaddr_isnull(&peer->addr) ? 17430 "(Unspecified)" : ast_strdupa(ast_sockaddr_stringify_addr(&peer->addr)); 17431 17432 ao2_lock(peer); 17433 if (cont->havepattern && regexec(&cont->regexbuf, peer->name, 0, NULL, 0)) { 17434 ao2_unlock(peer); 17435 return unref_peer(peer, "toss iterator peer ptr no match"); 17436 } 17437 17438 if (!ast_strlen_zero(peer->username) && !s) { 17439 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 17440 } else { 17441 ast_copy_string(name, peer->name, sizeof(name)); 17442 } 17443 17444 pstatus = peer_status(peer, status, sizeof(status)); 17445 if (pstatus == 1) { 17446 cont->peers_mon_online++; 17447 } else if (pstatus == 0) { 17448 cont->peers_mon_offline++; 17449 } else { 17450 if (ast_sockaddr_isnull(&peer->addr) || 17451 !ast_sockaddr_port(&peer->addr)) { 17452 cont->peers_unmon_offline++; 17453 } else { 17454 cont->peers_unmon_online++; 17455 } 17456 } 17457 17458 if (!s) { /* Normal CLI list */ 17459 ast_cli(fd, PEERS_FORMAT2, name, 17460 tmp_host, 17461 peer->host_dynamic ? " D " : " ", /* Dynamic or not? */ 17462 ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? " N " : " ", /* NAT=yes? */ 17463 peer->ha ? " A " : " ", /* permit/deny */ 17464 tmp_port, status, 17465 cont->realtimepeers ? (peer->is_realtime ? "Cached RT":"") : ""); 17466 } else { /* Manager format */ 17467 /* The names here need to be the same as other channels */ 17468 astman_append(s, 17469 "Event: PeerEntry\r\n%s" 17470 "Channeltype: SIP\r\n" 17471 "ObjectName: %s\r\n" 17472 "ChanObjectType: peer\r\n" /* "peer" or "user" */ 17473 "IPaddress: %s\r\n" 17474 "IPport: %s\r\n" 17475 "Dynamic: %s\r\n" 17476 "Forcerport: %s\r\n" 17477 "VideoSupport: %s\r\n" 17478 "TextSupport: %s\r\n" 17479 "ACL: %s\r\n" 17480 "Status: %s\r\n" 17481 "RealtimeDevice: %s\r\n\r\n", 17482 cont->idtext, 17483 peer->name, 17484 ast_sockaddr_isnull(&peer->addr) ? "-none-" : tmp_host, 17485 ast_sockaddr_isnull(&peer->addr) ? "0" : tmp_port, 17486 peer->host_dynamic ? "yes" : "no", /* Dynamic or not? */ 17487 ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? "yes" : "no", /* NAT=yes? */ 17488 ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */ 17489 ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT) ? "yes" : "no", /* TEXTSUPPORT=yes? */ 17490 peer->ha ? "yes" : "no", /* permit/deny */ 17491 status, 17492 cont->realtimepeers ? (peer->is_realtime ? "yes":"no") : "no"); 17493 } 17494 ao2_unlock(peer); 17495 17496 return unref_peer(peer, "toss iterator peer ptr"); 17497 }
| static void * _sip_tcp_helper_thread | ( | struct ast_tcptls_session_instance * | tcptls_session | ) | [static] |
SIP TCP thread management function This function reads from the socket, parses the packet into a request.
Definition at line 2728 of file chan_sip.c.
References ao2_lock, ao2_ref, ao2_t_find, ao2_t_ref, ao2_t_unlink, ao2_unlock, ast_atomic_fetchadd_int(), ast_debug, AST_LIST_REMOVE_HEAD, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_poll, ast_str_buffer(), ast_str_create(), ast_str_reset(), ast_str_strlen(), ast_tcptls_client_start(), ast_tcptls_close_session_file(), ast_tcptls_server_write(), ast_tcptls_stream_set_exclusive_input(), ast_tcptls_stream_set_timeout_disable(), ast_tcptls_stream_set_timeout_sequence(), ast_tvnow(), cleanup(), ast_tcptls_session_instance::client, deinit_req(), errno, ast_tcptls_session_instance::fd, handle_request_do(), ast_tcptls_session_instance::lock, LOG_ERROR, LOG_WARNING, OBJ_POINTER, ast_tcptls_session_instance::overflow_buf, ast_tcptls_session_instance::parent, ast_tcptls_session_instance::remote_address, set_socket_transport(), sip_check_authtimeout(), sip_tcptls_read(), sip_threadinfo_create(), ast_tcptls_session_instance::ssl, and ast_tcptls_session_instance::stream_cookie.
Referenced by sip_tcp_worker_fn().
02729 { 02730 int res, timeout = -1, authenticated = 0, flags; 02731 time_t start; 02732 struct sip_request req = { 0, } , reqcpy = { 0, }; 02733 struct sip_threadinfo *me = NULL; 02734 char buf[1024] = ""; 02735 struct pollfd fds[2] = { { 0 }, { 0 }, }; 02736 struct ast_tcptls_session_args *ca = NULL; 02737 02738 /* If this is a server session, then the connection has already been 02739 * setup. Check if the authlimit has been reached and if not create the 02740 * threadinfo object so we can access this thread for writing. 02741 * 02742 * if this is a client connection more work must be done. 02743 * 1. We own the parent session args for a client connection. This pointer needs 02744 * to be held on to so we can decrement it's ref count on thread destruction. 02745 * 2. The threadinfo object was created before this thread was launched, however 02746 * it must be found within the threadt table. 02747 * 3. Last, the tcptls_session must be started. 02748 */ 02749 if (!tcptls_session->client) { 02750 if (ast_atomic_fetchadd_int(&unauth_sessions, +1) >= authlimit) { 02751 /* unauth_sessions is decremented in the cleanup code */ 02752 goto cleanup; 02753 } 02754 02755 if ((flags = fcntl(tcptls_session->fd, F_GETFL)) == -1) { 02756 ast_log(LOG_ERROR, "error setting socket to non blocking mode, fcntl() failed: %s\n", strerror(errno)); 02757 goto cleanup; 02758 } 02759 02760 flags |= O_NONBLOCK; 02761 if (fcntl(tcptls_session->fd, F_SETFL, flags) == -1) { 02762 ast_log(LOG_ERROR, "error setting socket to non blocking mode, fcntl() failed: %s\n", strerror(errno)); 02763 goto cleanup; 02764 } 02765 02766 if (!(me = sip_threadinfo_create(tcptls_session, tcptls_session->ssl ? SIP_TRANSPORT_TLS : SIP_TRANSPORT_TCP))) { 02767 goto cleanup; 02768 } 02769 ao2_t_ref(me, +1, "Adding threadinfo ref for tcp_helper_thread"); 02770 } else { 02771 struct sip_threadinfo tmp = { 02772 .tcptls_session = tcptls_session, 02773 }; 02774 02775 if ((!(ca = tcptls_session->parent)) || 02776 (!(me = ao2_t_find(threadt, &tmp, OBJ_POINTER, "ao2_find, getting sip_threadinfo in tcp helper thread"))) || 02777 (!(tcptls_session = ast_tcptls_client_start(tcptls_session)))) { 02778 goto cleanup; 02779 } 02780 } 02781 02782 flags = 1; 02783 if (setsockopt(tcptls_session->fd, SOL_SOCKET, SO_KEEPALIVE, &flags, sizeof(flags))) { 02784 ast_log(LOG_ERROR, "error enabling TCP keep-alives on sip socket: %s\n", strerror(errno)); 02785 goto cleanup; 02786 } 02787 02788 me->threadid = pthread_self(); 02789 ast_debug(2, "Starting thread for %s server\n", tcptls_session->ssl ? "TLS" : "TCP"); 02790 02791 /* set up pollfd to watch for reads on both the socket and the alert_pipe */ 02792 fds[0].fd = tcptls_session->fd; 02793 fds[1].fd = me->alert_pipe[0]; 02794 fds[0].events = fds[1].events = POLLIN | POLLPRI; 02795 02796 if (!(req.data = ast_str_create(SIP_MIN_PACKET))) { 02797 goto cleanup; 02798 } 02799 if (!(reqcpy.data = ast_str_create(SIP_MIN_PACKET))) { 02800 goto cleanup; 02801 } 02802 02803 if(time(&start) == -1) { 02804 ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno)); 02805 goto cleanup; 02806 } 02807 02808 /* 02809 * We cannot let the stream exclusively wait for data to arrive. 02810 * We have to wake up the task to send outgoing messages. 02811 */ 02812 ast_tcptls_stream_set_exclusive_input(tcptls_session->stream_cookie, 0); 02813 02814 ast_tcptls_stream_set_timeout_sequence(tcptls_session->stream_cookie, ast_tvnow(), 02815 tcptls_session->client ? -1 : (authtimeout * 1000)); 02816 02817 for (;;) { 02818 struct ast_str *str_save; 02819 02820 if (!tcptls_session->client && req.authenticated && !authenticated) { 02821 authenticated = 1; 02822 ast_tcptls_stream_set_timeout_disable(tcptls_session->stream_cookie); 02823 ast_atomic_fetchadd_int(&unauth_sessions, -1); 02824 } 02825 02826 /* calculate the timeout for unauthenticated server sessions */ 02827 if (!tcptls_session->client && !authenticated ) { 02828 if ((timeout = sip_check_authtimeout(start)) < 0) { 02829 goto cleanup; 02830 } 02831 02832 if (timeout == 0) { 02833 ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "TLS": "TCP"); 02834 goto cleanup; 02835 } 02836 } else { 02837 timeout = -1; 02838 } 02839 02840 if (ast_str_strlen(tcptls_session->overflow_buf) == 0) { 02841 res = ast_poll(fds, 2, timeout); /* polls for both socket and alert_pipe */ 02842 if (res < 0) { 02843 ast_debug(2, "SIP %s server :: ast_wait_for_input returned %d\n", tcptls_session->ssl ? "TLS": "TCP", res); 02844 goto cleanup; 02845 } else if (res == 0) { 02846 /* timeout */ 02847 ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "TLS": "TCP"); 02848 goto cleanup; 02849 } 02850 } 02851 02852 /* 02853 * handle the socket event, check for both reads from the socket fd or TCP overflow buffer, 02854 * and writes from alert_pipe fd. 02855 */ 02856 if (fds[0].revents || (ast_str_strlen(tcptls_session->overflow_buf) > 0)) { /* there is data on the socket to be read */ 02857 fds[0].revents = 0; 02858 02859 /* clear request structure */ 02860 str_save = req.data; 02861 memset(&req, 0, sizeof(req)); 02862 req.data = str_save; 02863 ast_str_reset(req.data); 02864 02865 str_save = reqcpy.data; 02866 memset(&reqcpy, 0, sizeof(reqcpy)); 02867 reqcpy.data = str_save; 02868 ast_str_reset(reqcpy.data); 02869 02870 memset(buf, 0, sizeof(buf)); 02871 02872 if (tcptls_session->ssl) { 02873 set_socket_transport(&req.socket, SIP_TRANSPORT_TLS); 02874 req.socket.port = htons(ourport_tls); 02875 } else { 02876 set_socket_transport(&req.socket, SIP_TRANSPORT_TCP); 02877 req.socket.port = htons(ourport_tcp); 02878 } 02879 req.socket.fd = tcptls_session->fd; 02880 02881 res = sip_tcptls_read(&req, tcptls_session, authenticated, start); 02882 if (res < 0) { 02883 goto cleanup; 02884 } 02885 02886 req.socket.tcptls_session = tcptls_session; 02887 handle_request_do(&req, &tcptls_session->remote_address); 02888 } 02889 02890 if (fds[1].revents) { /* alert_pipe indicates there is data in the send queue to be sent */ 02891 enum sip_tcptls_alert alert; 02892 struct tcptls_packet *packet; 02893 02894 fds[1].revents = 0; 02895 02896 if (read(me->alert_pipe[0], &alert, sizeof(alert)) == -1) { 02897 ast_log(LOG_ERROR, "read() failed: %s\n", strerror(errno)); 02898 continue; 02899 } 02900 02901 switch (alert) { 02902 case TCPTLS_ALERT_STOP: 02903 goto cleanup; 02904 case TCPTLS_ALERT_DATA: 02905 ao2_lock(me); 02906 if (!(packet = AST_LIST_REMOVE_HEAD(&me->packet_q, entry))) { 02907 ast_log(LOG_WARNING, "TCPTLS thread alert_pipe indicated packet should be sent, but frame_q is empty\n"); 02908 } 02909 ao2_unlock(me); 02910 02911 if (packet) { 02912 if (ast_tcptls_server_write(tcptls_session, ast_str_buffer(packet->data), packet->len) == -1) { 02913 ast_log(LOG_WARNING, "Failure to write to tcp/tls socket\n"); 02914 } 02915 ao2_t_ref(packet, -1, "tcptls packet sent, this is no longer needed"); 02916 } 02917 break; 02918 default: 02919 ast_log(LOG_ERROR, "Unknown tcptls thread alert '%u'\n", alert); 02920 } 02921 } 02922 } 02923 02924 ast_debug(2, "Shutting down thread for %s server\n", tcptls_session->ssl ? "TLS" : "TCP"); 02925 02926 cleanup: 02927 if (tcptls_session && !tcptls_session->client && !authenticated) { 02928 ast_atomic_fetchadd_int(&unauth_sessions, -1); 02929 } 02930 02931 if (me) { 02932 ao2_t_unlink(threadt, me, "Removing tcptls helper thread, thread is closing"); 02933 ao2_t_ref(me, -1, "Removing tcp_helper_threads threadinfo ref"); 02934 } 02935 deinit_req(&reqcpy); 02936 deinit_req(&req); 02937 02938 /* if client, we own the parent session arguments and must decrement ref */ 02939 if (ca) { 02940 ao2_t_ref(ca, -1, "closing tcptls thread, getting rid of client tcptls_session arguments"); 02941 } 02942 02943 if (tcptls_session) { 02944 ast_mutex_lock(&tcptls_session->lock); 02945 ast_tcptls_close_session_file(tcptls_session); 02946 tcptls_session->parent = NULL; 02947 ast_mutex_unlock(&tcptls_session->lock); 02948 02949 ao2_ref(tcptls_session, -1); 02950 tcptls_session = NULL; 02951 } 02952 return NULL; 02953 }
| static void add_blank | ( | struct sip_request * | req | ) | [static] |
add a blank line if no body
Definition at line 4273 of file chan_sip.c.
References ast_str_append().
Referenced by send_request(), and send_response().
04274 { 04275 if (!req->lines) { 04276 /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */ 04277 ast_str_append(&req->data, 0, "\r\n"); 04278 } 04279 }
| static void add_cc_call_info_to_response | ( | struct sip_pvt * | p, | |
| struct sip_request * | resp | |||
| ) | [static] |
Definition at line 12134 of file chan_sip.c.
References add_header(), ao2_ref, ast_copy_string(), ast_log(), ast_str_alloca, ast_str_buffer(), ast_str_set(), ast_strlen_zero(), find_sip_cc_agent_by_original_callid(), generate_uri(), LOG_WARNING, and ast_cc_agent::private_data.
Referenced by __transmit_response(), and transmit_response_with_sdp().
12135 { 12136 char uri[SIPBUFSIZE]; 12137 struct ast_str *header = ast_str_alloca(SIPBUFSIZE); 12138 struct ast_cc_agent *agent = find_sip_cc_agent_by_original_callid(p); 12139 struct sip_cc_agent_pvt *agent_pvt; 12140 12141 if (!agent) { 12142 /* Um, what? How could the SIP_OFFER_CC flag be set but there not be an 12143 * agent? Oh well, we'll just warn and return without adding the header. 12144 */ 12145 ast_log(LOG_WARNING, "Can't find SIP CC agent for call '%s' even though OFFER_CC flag was set?\n", p->callid); 12146 return; 12147 } 12148 12149 agent_pvt = agent->private_data; 12150 12151 if (!ast_strlen_zero(agent_pvt->subscribe_uri)) { 12152 ast_copy_string(uri, agent_pvt->subscribe_uri, sizeof(uri)); 12153 } else { 12154 generate_uri(p, uri, sizeof(uri)); 12155 ast_copy_string(agent_pvt->subscribe_uri, uri, sizeof(agent_pvt->subscribe_uri)); 12156 } 12157 /* XXX Hardcode "NR" as the m reason for now. This should perhaps be changed 12158 * to be more accurate. This parameter has no bearing on the actual operation 12159 * of the feature; it's just there for informational purposes. 12160 */ 12161 ast_str_set(&header, 0, "<%s>;purpose=call-completion;m=%s", uri, "NR"); 12162 add_header(resp, "Call-Info", ast_str_buffer(header)); 12163 ao2_ref(agent, -1); 12164 }
| static void add_codec_to_sdp | ( | const struct sip_pvt * | p, | |
| format_t | codec, | |||
| struct ast_str ** | m_buf, | |||
| struct ast_str ** | a_buf, | |||
| int | debug, | |||
| int * | min_packet_size | |||
| ) | [static] |
Add codec offer to SDP offer/answer body in INVITE or 200 OK.
Definition at line 11385 of file chan_sip.c.
References ast_codec_pref_getsize(), AST_FORMAT_G719, AST_FORMAT_G723_1, AST_FORMAT_G729A, AST_FORMAT_ILBC, AST_FORMAT_SIREN14, AST_FORMAT_SIREN7, ast_getformatname(), ast_rtp_codecs_payload_code(), ast_rtp_instance_get_codecs(), ast_rtp_lookup_mime_subtype2(), ast_rtp_lookup_sample_rate2(), AST_RTP_OPT_G726_NONSTANDARD, ast_str_append(), ast_test_flag, ast_verbose, ast_format_list::cur_ms, and ast_rtp_codecs::pref.
Referenced by add_sdp().
11388 { 11389 int rtp_code; 11390 struct ast_format_list fmt; 11391 11392 11393 if (debug) 11394 ast_verbose("Adding codec 0x%" PRIx64 " (%s) to SDP\n", (uint64_t)codec, ast_getformatname(codec)); 11395 if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->rtp), 1, codec)) == -1) 11396 return; 11397 11398 if (p->rtp) { 11399 struct ast_codec_pref *pref = &ast_rtp_instance_get_codecs(p->rtp)->pref; 11400 fmt = ast_codec_pref_getsize(pref, codec); 11401 } else /* I don't see how you couldn't have p->rtp, but good to check for and error out if not there like earlier code */ 11402 return; 11403 ast_str_append(m_buf, 0, " %d", rtp_code); 11404 ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%u\r\n", rtp_code, 11405 ast_rtp_lookup_mime_subtype2(1, codec, 11406 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0), 11407 ast_rtp_lookup_sample_rate2(1, codec)); 11408 11409 switch (codec) { 11410 case AST_FORMAT_G729A: 11411 /* Indicate that we don't support VAD (G.729 annex B) */ 11412 ast_str_append(a_buf, 0, "a=fmtp:%d annexb=no\r\n", rtp_code); 11413 break; 11414 case AST_FORMAT_G723_1: 11415 /* Indicate that we don't support VAD (G.723.1 annex A) */ 11416 ast_str_append(a_buf, 0, "a=fmtp:%d annexa=no\r\n", rtp_code); 11417 break; 11418 case AST_FORMAT_ILBC: 11419 /* Add information about us using only 20/30 ms packetization */ 11420 ast_str_append(a_buf, 0, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms); 11421 break; 11422 case AST_FORMAT_SIREN7: 11423 /* Indicate that we only expect 32Kbps */ 11424 ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=32000\r\n", rtp_code); 11425 break; 11426 case AST_FORMAT_SIREN14: 11427 /* Indicate that we only expect 48Kbps */ 11428 ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=48000\r\n", rtp_code); 11429 break; 11430 case AST_FORMAT_G719: 11431 /* Indicate that we only expect 64Kbps */ 11432 ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=64000\r\n", rtp_code); 11433 break; 11434 } 11435 11436 if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size)) 11437 *min_packet_size = fmt.cur_ms; 11438 11439 /* Our first codec packetization processed cannot be zero */ 11440 if ((*min_packet_size)==0 && fmt.cur_ms) 11441 *min_packet_size = fmt.cur_ms; 11442 }
| static int add_content | ( | struct sip_request * | req, | |
| const char * | line | |||
| ) | [static] |
Add content (not header) to SIP message.
Definition at line 10276 of file chan_sip.c.
References ast_log(), ast_str_append(), and LOG_WARNING.
Referenced by add_digit(), add_sdp(), add_text(), add_vidupdate(), transmit_cc_notify(), transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), and transmit_state_notify().
10277 { 10278 if (req->lines) { 10279 ast_log(LOG_WARNING, "Can't add more content when the content has been finalized\n"); 10280 return -1; 10281 } 10282 10283 ast_str_append(&req->content, 0, "%s", line); 10284 return 0; 10285 }
| static int add_digit | ( | struct sip_request * | req, | |
| char | digit, | |||
| unsigned int | duration, | |||
| int | mode | |||
| ) | [static] |
Add DTMF INFO tone to sip message Mode = 0 for application/dtmf-relay (Cisco) 1 for application/dtmf.
Definition at line 11214 of file chan_sip.c.
References add_content(), and add_header().
Referenced by transmit_info_with_digit().
11215 { 11216 char tmp[256]; 11217 int event; 11218 if (mode) { 11219 /* Application/dtmf short version used by some implementations */ 11220 if ('0' <= digit && digit <= '9') { 11221 event = digit - '0'; 11222 } else if (digit == '*') { 11223 event = 10; 11224 } else if (digit == '#') { 11225 event = 11; 11226 } else if ('A' <= digit && digit <= 'D') { 11227 event = 12 + digit - 'A'; 11228 } else if ('a' <= digit && digit <= 'd') { 11229 event = 12 + digit - 'a'; 11230 } else { 11231 /* Unknown digit */ 11232 event = 0; 11233 } 11234 snprintf(tmp, sizeof(tmp), "%d\r\n", event); 11235 add_header(req, "Content-Type", "application/dtmf"); 11236 add_content(req, tmp); 11237 } else { 11238 /* Application/dtmf-relay as documented by Cisco */ 11239 snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration); 11240 add_header(req, "Content-Type", "application/dtmf-relay"); 11241 add_content(req, tmp); 11242 } 11243 return 0; 11244 }
| static void add_diversion_header | ( | struct sip_request * | req, | |
| struct sip_pvt * | pvt | |||
| ) | [static] |
Add "Diversion" header to outgoing message.
We need to add a Diversion header if the owner channel of this dialog has redirecting information associated with it.
| req | The request/response to which we will add the header | |
| pvt | The sip_pvt which represents the call-leg |
Definition at line 12529 of file chan_sip.c.
References add_header(), ast_escape_quoted(), ast_sockaddr_stringify_host_remote(), ast_strlen_zero(), and sip_reason_code_to_str().
Referenced by __transmit_response(), transmit_invite(), and update_redirecting().
12530 { 12531 const char *diverting_number; 12532 const char *diverting_name; 12533 const char *reason; 12534 char header_text[256]; 12535 12536 if (!pvt->owner) { 12537 return; 12538 } 12539 12540 diverting_number = pvt->owner->redirecting.from.number.str; 12541 if (!pvt->owner->redirecting.from.number.valid 12542 || ast_strlen_zero(diverting_number)) { 12543 return; 12544 } 12545 12546 reason = sip_reason_code_to_str(pvt->owner->redirecting.reason); 12547 12548 /* We at least have a number to place in the Diversion header, which is enough */ 12549 diverting_name = pvt->owner->redirecting.from.name.str; 12550 if (!pvt->owner->redirecting.from.name.valid 12551 || ast_strlen_zero(diverting_name)) { 12552 snprintf(header_text, sizeof(header_text), "<sip:%s@%s>;reason=%s", diverting_number, 12553 ast_sockaddr_stringify_host_remote(&pvt->ourip), reason); 12554 } else { 12555 char diverting_name_buf[128]; 12556 12557 ast_escape_quoted(diverting_name, diverting_name_buf, sizeof(diverting_name_buf)); 12558 snprintf(header_text, sizeof(header_text), "\"%s\" <sip:%s@%s>;reason=%s", 12559 diverting_name_buf, diverting_number, 12560 ast_sockaddr_stringify_host_remote(&pvt->ourip), reason); 12561 } 12562 12563 add_header(req, "Diversion", header_text); 12564 }
| static int add_header | ( | struct sip_request * | req, | |
| const char * | var, | |||
| const char * | value | |||
| ) | [static] |
Add header to SIP message.
Definition at line 10218 of file chan_sip.c.
References ast_log(), ast_str_append(), ast_str_strlen(), find_alias(), LOG_WARNING, and sip_cfg.
Referenced by __transmit_response(), add_cc_call_info_to_response(), add_digit(), add_diversion_header(), add_header_max_forwards(), add_required_respheader(), add_route(), add_rpid(), add_sdp(), add_supported_header(), add_text(), add_vidupdate(), append_date(), copy_all_header(), copy_header(), copy_via_headers(), finalize_content(), initreqprep(), reqprep(), respprep(), transmit_cc_notify(), transmit_info_with_aoc(), transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_register(), transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), transmit_response_with_allow(), transmit_response_with_auth(), transmit_response_with_minexpires(), transmit_response_with_minse(), transmit_response_with_retry_after(), transmit_response_with_sip_etag(), transmit_response_with_unsupported(), transmit_state_notify(), and update_connectedline().
10219 { 10220 if (req->headers == SIP_MAX_HEADERS) { 10221 ast_log(LOG_WARNING, "Out of SIP header space\n"); 10222 return -1; 10223 } 10224 10225 if (req->lines) { 10226 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 10227 return -1; 10228 } 10229 10230 if (sip_cfg.compactheaders) { 10231 var = find_alias(var, var); 10232 } 10233 10234 ast_str_append(&req->data, 0, "%s: %s\r\n", var, value); 10235 req->header[req->headers] = ast_str_strlen(req->data); 10236 10237 req->headers++; 10238 10239 return 0; 10240 }
| static int add_header_max_forwards | ( | struct sip_pvt * | dialog, | |
| struct sip_request * | req | |||
| ) | [static] |
Add 'Max-Forwards' header to SIP message.
Definition at line 10246 of file chan_sip.c.
References add_header().
Referenced by initreqprep(), reqprep(), and transmit_register().
10247 { 10248 char clen[10]; 10249 10250 snprintf(clen, sizeof(clen), "%d", dialog->maxforwards); 10251 10252 return add_header(req, "Max-Forwards", clen); 10253 }
| static void add_noncodec_to_sdp | ( | const struct sip_pvt * | p, | |
| int | format, | |||
| struct ast_str ** | m_buf, | |||
| struct ast_str ** | a_buf, | |||
| int | debug | |||
| ) | [static] |
Add RFC 2833 DTMF offer to SDP.
Definition at line 11523 of file chan_sip.c.
References ast_rtp_codecs_payload_code(), AST_RTP_DTMF, ast_rtp_instance_get_codecs(), ast_rtp_lookup_mime_subtype2(), ast_rtp_lookup_sample_rate2(), ast_str_append(), and ast_verbose.
Referenced by add_sdp().
11526 { 11527 int rtp_code; 11528 11529 if (debug) 11530 ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", (unsigned)format, ast_rtp_lookup_mime_subtype2(0, format, 0)); 11531 if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->rtp), 0, format)) == -1) 11532 return; 11533 11534 ast_str_append(m_buf, 0, " %d", rtp_code); 11535 ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%u\r\n", rtp_code, 11536 ast_rtp_lookup_mime_subtype2(0, format, 0), 11537 ast_rtp_lookup_sample_rate2(0, format)); 11538 if (format == AST_RTP_DTMF) /* Indicate we support DTMF and FLASH... */ 11539 ast_str_append(a_buf, 0, "a=fmtp:%d 0-16\r\n", rtp_code); 11540 }
| static void add_peer_mailboxes | ( | struct sip_peer * | peer, | |
| const char * | value | |||
| ) | [static] |
Definition at line 28014 of file chan_sip.c.
References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_strdupa, ast_strip(), ast_strlen_zero(), context, mailbox, mbox(), and S_OR.
Referenced by build_peer().
28015 { 28016 char *next, *mbox, *context; 28017 28018 next = ast_strdupa(value); 28019 28020 while ((mbox = context = strsep(&next, ","))) { 28021 struct sip_mailbox *mailbox; 28022 int duplicate = 0; 28023 /* remove leading/trailing whitespace from mailbox string */ 28024 mbox = ast_strip(mbox); 28025 strsep(&context, "@"); 28026 28027 if (ast_strlen_zero(mbox)) { 28028 continue; 28029 } 28030 28031 /* Check whether the mailbox is already in the list */ 28032 AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { 28033 if (!strcmp(mailbox->mailbox, mbox) && !strcmp(S_OR(mailbox->context, ""), S_OR(context, ""))) { 28034 duplicate = 1; 28035 break; 28036 } 28037 } 28038 if (duplicate) { 28039 continue; 28040 } 28041 28042 if (!(mailbox = ast_calloc(1, sizeof(*mailbox) + strlen(mbox) + strlen(S_OR(context, ""))))) { 28043 continue; 28044 } 28045 28046 if (!ast_strlen_zero(context)) { 28047 mailbox->context = mailbox->mailbox + strlen(mbox) + 1; 28048 strcpy(mailbox->context, context); /* SAFE */ 28049 } 28050 strcpy(mailbox->mailbox, mbox); /* SAFE */ 28051 28052 AST_LIST_INSERT_TAIL(&peer->mailboxes, mailbox, entry); 28053 } 28054 }
| static void add_peer_mwi_subs | ( | struct sip_peer * | peer | ) | [static] |
Definition at line 25268 of file chan_sip.c.
References AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, ast_event_subscribe(), ast_event_unsubscribe(), AST_LIST_TRAVERSE, mailbox, mwi_event_cb(), and S_OR.
Referenced by build_peer(), and handle_request_subscribe().
25269 { 25270 struct sip_mailbox *mailbox; 25271 25272 AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { 25273 if (mailbox->event_sub) { 25274 ast_event_unsubscribe(mailbox->event_sub); 25275 } 25276 25277 mailbox->event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "SIP mbox event", peer, 25278 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox->mailbox, 25279 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, S_OR(mailbox->context, "default"), 25280 AST_EVENT_IE_END); 25281 } 25282 }
| static void add_realm_authentication | ( | struct sip_auth_container ** | credentials, | |
| const char * | configuration, | |||
| int | lineno | |||
| ) | [static] |
Definition at line 27814 of file chan_sip.c.
References ao2_t_alloc, ast_calloc, ast_copy_string(), ast_debug, AST_LIST_INSERT_TAIL, ast_log(), ast_strdupa, ast_strlen_zero(), ast_verb, destroy_realm_authentication(), LOG_WARNING, and secret.
Referenced by build_peer(), and reload_config().
27815 { 27816 char *authcopy; 27817 char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; 27818 struct sip_auth *auth; 27819 27820 if (ast_strlen_zero(configuration)) { 27821 /* Nothing to add */ 27822 return; 27823 } 27824 27825 ast_debug(1, "Auth config :: %s\n", configuration); 27826 27827 authcopy = ast_strdupa(configuration); 27828 username = authcopy; 27829 27830 /* split user[:secret] and relm */ 27831 realm = strrchr(username, '@'); 27832 if (realm) 27833 *realm++ = '\0'; 27834 if (ast_strlen_zero(username) || ast_strlen_zero(realm)) { 27835 ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno); 27836 return; 27837 } 27838 27839 /* parse username at ':' for secret, or '#" for md5secret */ 27840 if ((secret = strchr(username, ':'))) { 27841 *secret++ = '\0'; 27842 } else if ((md5secret = strchr(username, '#'))) { 27843 *md5secret++ = '\0'; 27844 } 27845 27846 /* Create the continer if needed. */ 27847 if (!*credentials) { 27848 *credentials = ao2_t_alloc(sizeof(**credentials), destroy_realm_authentication, 27849 "Create realm auth container."); 27850 if (!*credentials) { 27851 /* Failed to create the credentials container. */ 27852 return; 27853 } 27854 } 27855 27856 /* Create the authentication credential entry. */ 27857 auth = ast_calloc(1, sizeof(*auth)); 27858 if (!auth) { 27859 return; 27860 } 27861 ast_copy_string(auth->realm, realm, sizeof(auth->realm)); 27862 ast_copy_string(auth->username, username, sizeof(auth->username)); 27863 if (secret) 27864 ast_copy_string(auth->secret, secret, sizeof(auth->secret)); 27865 if (md5secret) 27866 ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret)); 27867 27868 /* Add credential to container list. */ 27869 AST_LIST_INSERT_TAIL(&(*credentials)->list, auth, node); 27870 27871 ast_verb(3, "Added authentication for realm %s\n", realm); 27872 }
| static void add_required_respheader | ( | struct sip_request * | req | ) | [static] |
Definition at line 4351 of file chan_sip.c.
References add_header(), ARRAY_LEN, ast_free, ast_str_append(), ast_str_buffer(), ast_str_create(), ast_str_strlen(), str, and text.
Referenced by transmit_response_with_sdp().
04352 { 04353 struct ast_str *str; 04354 int i; 04355 04356 if (!req->reqsipoptions) { 04357 return; 04358 } 04359 04360 str = ast_str_create(32); 04361 04362 for (i = 0; i < ARRAY_LEN(sip_options); ++i) { 04363 if (!(req->reqsipoptions & sip_options[i].id)) { 04364 continue; 04365 } 04366 if (ast_str_strlen(str) > 0) { 04367 ast_str_append(&str, 0, ", "); 04368 } 04369 ast_str_append(&str, 0, "%s", sip_options[i].text); 04370 } 04371 04372 if (ast_str_strlen(str) > 0) { 04373 add_header(req, "Require", ast_str_buffer(str)); 04374 } 04375 04376 ast_free(str); 04377 }
| static void add_route | ( | struct sip_request * | req, | |
| struct sip_route * | route | |||
| ) | [static] |
Add route header into request per learned route.
Definition at line 10387 of file chan_sip.c.
References add_header(), and ast_copy_string().
Referenced by initreqprep(), and reqprep().
10388 { 10389 char r[SIPBUFSIZE*2], *p; 10390 int n, rem = sizeof(r); 10391 10392 if (!route) 10393 return; 10394 10395 p = r; 10396 for (;route ; route = route->next) { 10397 n = strlen(route->hop); 10398 if (rem < n+3) /* we need room for ",<route>" */ 10399 break; 10400 if (p != r) { /* add a separator after fist route */ 10401 *p++ = ','; 10402 --rem; 10403 } 10404 *p++ = '<'; 10405 ast_copy_string(p, route->hop, rem); /* cannot fail */ 10406 p += n; 10407 *p++ = '>'; 10408 rem -= (n+2); 10409 } 10410 *p = '\0'; 10411 add_header(req, "Route", r); 10412 }
| static int add_rpid | ( | struct sip_request * | req, | |
| struct sip_pvt * | p | |||
| ) | [static] |
Add Remote-Party-ID header to SIP message.
Definition at line 11250 of file chan_sip.c.
References add_header(), ast_escape_quoted(), ast_party_id_presentation(), AST_PRES_ALLOWED, AST_PRES_ALLOWED_NETWORK_NUMBER, AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, AST_PRES_PROHIB_NETWORK_NUMBER, AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, AST_PRES_RESTRICTION, ast_sockaddr_stringify_host_remote(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_set(), ast_strlen_zero(), ast_test_flag, ast_uri_encode(), and S_COR.
Referenced by __transmit_response(), transmit_invite(), transmit_reinvite_with_sdp(), transmit_response_with_sdp(), and update_connectedline().
11251 { 11252 struct ast_str *tmp = ast_str_alloca(256); 11253 char tmp2[256]; 11254 char lid_name_buf[128]; 11255 char *lid_num; 11256 char *lid_name; 11257 int lid_pres; 11258 const char *fromdomain; 11259 const char *privacy = NULL; 11260 const char *screen = NULL; 11261 const char *anonymous_string = "\"Anonymous\" <sip:anonymous@anonymous.invalid>"; 11262 11263 if (!ast_test_flag(&p->flags[0], SIP_SENDRPID)) { 11264 return 0; 11265 } 11266 11267 if (!p->owner) { 11268 return 0; 11269 } 11270 lid_num = S_COR(p->owner->connected.id.number.valid, 11271 p->owner->connected.id.number.str, 11272 NULL); 11273 if (!lid_num) { 11274 return 0; 11275 } 11276 lid_name = S_COR(p->owner->connected.id.name.valid, 11277 p->owner->connected.id.name.str, 11278 NULL); 11279 if (!lid_name) { 11280 lid_name = lid_num; 11281 } 11282 ast_escape_quoted(lid_name, lid_name_buf, sizeof(lid_name_buf)); 11283 lid_pres = ast_party_id_presentation(&p->owner->connected.id); 11284 11285 if (((lid_pres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) && 11286 (ast_test_flag(&p->flags[1], SIP_PAGE2_TRUST_ID_OUTBOUND) == SIP_PAGE2_TRUST_ID_OUTBOUND_NO)) { 11287 /* If pres is not allowed and we don't trust the peer, we don't apply an RPID header */ 11288 return 0; 11289 } 11290 11291 fromdomain = p->fromdomain; 11292 if (!fromdomain || 11293 ((ast_test_flag(&p->flags[1], SIP_PAGE2_TRUST_ID_OUTBOUND) == SIP_PAGE2_TRUST_ID_OUTBOUND_YES) && 11294 !strcmp("anonymous.invalid", fromdomain))) { 11295 /* If the fromdomain is NULL or if it was set to anonymous.invalid due to privacy settings and we trust the peer, 11296 * use the host IP address */ 11297 fromdomain = ast_sockaddr_stringify_host_remote(&p->ourip); 11298 } 11299 11300 lid_num = ast_uri_encode(lid_num, tmp2, sizeof(tmp2), 0); 11301 11302 if (ast_test_flag(&p->flags[0], SIP_SENDRPID_PAI)) { 11303 if (ast_test_flag(&p->flags[1], SIP_PAGE2_TRUST_ID_OUTBOUND) != SIP_PAGE2_TRUST_ID_OUTBOUND_LEGACY) { 11304 /* trust_id_outbound = yes - Always give full information even if it's private, but append a privacy header 11305 * When private data is included */ 11306 ast_str_set(&tmp, -1, "\"%s\" <sip:%s@%s>", lid_name_buf, lid_num, fromdomain); 11307 if ((lid_pres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) { 11308 add_header(req, "Privacy", "id"); 11309 } 11310 } else { 11311 /* trust_id_outbound = legacy - behave in a non RFC-3325 compliant manner and send anonymized data when 11312 * when handling private data. */ 11313 if ((lid_pres & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED) { 11314 ast_str_set(&tmp, -1, "\"%s\" <sip:%s@%s>", lid_name_buf, lid_num, fromdomain); 11315 } else { 11316 ast_str_set(&tmp, -1, "%s", anonymous_string); 11317 } 11318 } 11319 add_header(req, "P-Asserted-Identity", ast_str_buffer(tmp)); 11320 } else { 11321 ast_str_set(&tmp, -1, "\"%s\" <sip:%s@%s>;party=%s", lid_name_buf, lid_num, fromdomain, p->outgoing_call ? "calling" : "called"); 11322 11323 switch (lid_pres) { 11324 case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 11325 case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 11326 privacy = "off"; 11327 screen = "no"; 11328 break; 11329 case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 11330 case AST_PRES_ALLOWED_NETWORK_NUMBER: 11331 privacy = "off"; 11332 screen = "yes"; 11333 break; 11334 case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 11335 case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 11336 privacy = "full"; 11337 screen = "no"; 11338 break; 11339 case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 11340 case AST_PRES_PROHIB_NETWORK_NUMBER: 11341 privacy = "full"; 11342 screen = "yes"; 11343 break; 11344 case AST_PRES_NUMBER_NOT_AVAILABLE: 11345 break; 11346 default: 11347 if ((lid_pres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) { 11348 privacy = "full"; 11349 } 11350 else 11351 privacy = "off"; 11352 screen = "no"; 11353 break; 11354 } 11355 11356 if (!ast_strlen_zero(privacy) && !ast_strlen_zero(screen)) { 11357 ast_str_append(&tmp, -1, ";privacy=%s;screen=%s", privacy, screen); 11358 } 11359 11360 add_header(req, "Remote-Party-ID", ast_str_buffer(tmp)); 11361 } 11362 return 0; 11363 }
| static enum sip_result add_sdp | ( | struct sip_request * | resp, | |
| struct sip_pvt * | p, | |||
| int | oldsdp, | |||
| int | add_audio, | |||
| int | add_t38 | |||
| ) | [static] |
Add Session Description Protocol message.
If oldsdp is TRUE, then the SDP version number is not incremented. This mechanism is used in Session-Timers where RE-INVITEs are used for refreshing SIP sessions without modifying the media session in any way.
Definition at line 11661 of file chan_sip.c.
References add_codec_to_sdp(), add_content(), add_header(), add_noncodec_to_sdp(), add_tcodec_to_sdp(), add_vcodec_to_sdp(), ast_codec_pref_index(), ast_debug, AST_FORMAT_AUDIO_MASK, AST_FORMAT_TEXT_MASK, AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_log(), ast_random(), AST_RTP_MAX, ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_is_ipv4_mapped(), ast_sockaddr_is_ipv6(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_sockaddr_stringify_addr_remote(), ast_sockaddr_stringify_port(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_size(), ast_str_strlen(), ast_strlen_zero(), AST_T38_RATE_MANAGEMENT_LOCAL_TCF, AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF, ast_test_flag, ast_udptl_get_error_correction_scheme(), ast_udptl_get_local_max_datagram(), ast_udptl_get_us(), ast_verbose, capability, FALSE, get_crypto_attrib(), get_our_media_address(), LOG_WARNING, sip_debug_test_pvt(), t38_get_rate(), TRUE, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_REDUNDANCY, and version.
Referenced by transmit_invite(), transmit_reinvite_with_sdp(), transmit_response_with_sdp(), transmit_response_with_t38_sdp(), and update_connectedline().
11662 { 11663 format_t alreadysent = 0; 11664 int doing_directmedia = FALSE; 11665 11666 struct ast_sockaddr addr = { {0,} }; 11667 struct ast_sockaddr vaddr = { {0,} }; 11668 struct ast_sockaddr taddr = { {0,} }; 11669 struct ast_sockaddr udptladdr = { {0,} }; 11670 struct ast_sockaddr dest = { {0,} }; 11671 struct ast_sockaddr vdest = { {0,} }; 11672 struct ast_sockaddr tdest = { {0,} }; 11673 struct ast_sockaddr udptldest = { {0,} }; 11674 11675 /* SDP fields */ 11676 char *version = "v=0\r\n"; /* Protocol version */ 11677 char subject[256]; /* Subject of the session */ 11678 char owner[256]; /* Session owner/creator */ 11679 char connection[256]; /* Connection data */ 11680 char *session_time = "t=0 0\r\n"; /* Time the session is active */ 11681 char bandwidth[256] = ""; /* Max bitrate */ 11682 char *hold = ""; 11683 struct ast_str *m_audio = ast_str_alloca(256); /* Media declaration line for audio */ 11684 struct ast_str *m_video = ast_str_alloca(256); /* Media declaration line for video */ 11685 struct ast_str *m_text = ast_str_alloca(256); /* Media declaration line for text */ 11686 struct ast_str *m_modem = ast_str_alloca(256); /* Media declaration line for modem */ 11687 struct ast_str *a_audio = ast_str_alloca(1024); /* Attributes for audio */ 11688 struct ast_str *a_video = ast_str_alloca(1024); /* Attributes for video */ 11689 struct ast_str *a_text = ast_str_alloca(1024); /* Attributes for text */ 11690 struct ast_str *a_modem = ast_str_alloca(1024); /* Attributes for modem */ 11691 const char *a_crypto = NULL; 11692 const char *v_a_crypto = NULL; 11693 const char *t_a_crypto = NULL; 11694 11695 format_t x; 11696 format_t capability = 0; 11697 int needaudio = FALSE; 11698 int needvideo = FALSE; 11699 int needtext = FALSE; 11700 int debug = sip_debug_test_pvt(p); 11701 int min_audio_packet_size = 0; 11702 int min_video_packet_size = 0; 11703 int min_text_packet_size = 0; 11704 11705 char codecbuf[SIPBUFSIZE]; 11706 char buf[SIPBUFSIZE]; 11707 char dummy_answer[256]; 11708 11709 /* Set the SDP session name */ 11710 snprintf(subject, sizeof(subject), "s=%s\r\n", ast_strlen_zero(global_sdpsession) ? "-" : global_sdpsession); 11711 11712 if (!p->rtp) { 11713 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 11714 return AST_FAILURE; 11715 } 11716 /* XXX We should not change properties in the SIP dialog until 11717 we have acceptance of the offer if this is a re-invite */ 11718 11719 /* Set RTP Session ID and version */ 11720 if (!p->sessionid) { 11721 p->sessionid = (int)ast_random(); 11722 p->sessionversion = p->sessionid; 11723 } else { 11724 if (oldsdp == FALSE) 11725 p->sessionversion++; 11726 } 11727 11728 if (add_audio) { 11729 doing_directmedia = (!ast_sockaddr_isnull(&p->redirip) && p->redircodecs) ? TRUE : FALSE; 11730 /* Check if we need video in this call */ 11731 if ((p->jointcapability & AST_FORMAT_VIDEO_MASK) && !p->novideo) { 11732 if (doing_directmedia && !(p->jointcapability & AST_FORMAT_VIDEO_MASK & p->redircodecs)) { 11733 ast_debug(2, "This call needs video offers, but caller probably did not offer it!\n"); 11734 } else if (p->vrtp) { 11735 needvideo = TRUE; 11736 ast_debug(2, "This call needs video offers!\n"); 11737 } else { 11738 ast_debug(2, "This call needs video offers, but there's no video support enabled!\n"); 11739 } 11740 } 11741 /* Check if we need text in this call */ 11742 if ((p->jointcapability & AST_FORMAT_TEXT_MASK) && !p->notext) { 11743 if (sipdebug_text) 11744 ast_verbose("We think we can do text\n"); 11745 if (p->trtp) { 11746 if (sipdebug_text) { 11747 ast_verbose("And we have a text rtp object\n"); 11748 } 11749 needtext = TRUE; 11750 ast_debug(2, "This call needs text offers! \n"); 11751 } else { 11752 ast_debug(2, "This call needs text offers, but there's no text support enabled ! \n"); 11753 } 11754 } 11755 } 11756 11757 get_our_media_address(p, needvideo, needtext, &addr, &vaddr, &taddr, &dest, &vdest, &tdest); 11758 11759 snprintf(owner, sizeof(owner), "o=%s %d %d IN %s %s\r\n", 11760 ast_strlen_zero(global_sdpowner) ? "-" : global_sdpowner, 11761 p->sessionid, p->sessionversion, 11762 (ast_sockaddr_is_ipv6(&dest) && !ast_sockaddr_is_ipv4_mapped(&dest)) ? 11763 "IP6" : "IP4", 11764 ast_sockaddr_stringify_addr_remote(&dest)); 11765 11766 snprintf(connection, sizeof(connection), "c=IN %s %s\r\n", 11767 (ast_sockaddr_is_ipv6(&dest) && !ast_sockaddr_is_ipv4_mapped(&dest)) ? 11768 "IP6" : "IP4", 11769 ast_sockaddr_stringify_addr_remote(&dest)); 11770 11771 if (add_audio) { 11772 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR) { 11773 hold = "a=recvonly\r\n"; 11774 doing_directmedia = FALSE; 11775 } else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE) { 11776 hold = "a=inactive\r\n"; 11777 doing_directmedia = FALSE; 11778 } else { 11779 hold = "a=sendrecv\r\n"; 11780 } 11781 11782 capability = p->jointcapability; 11783 11784 /* XXX note, Video and Text are negated - 'true' means 'no' */ 11785 ast_debug(1, "** Our capability: %s Video flag: %s Text flag: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), capability), 11786 p->novideo ? "True" : "False", p->notext ? "True" : "False"); 11787 ast_debug(1, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec)); 11788 11789 if (doing_directmedia) { 11790 capability &= p->redircodecs; 11791 ast_debug(1, "** Our native-bridge filtered capablity: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), capability)); 11792 } 11793 11794 /* Check if we need audio */ 11795 if (capability & AST_FORMAT_AUDIO_MASK) 11796 needaudio = TRUE; 11797 11798 if (debug) { 11799 ast_verbose("Audio is at %s\n", ast_sockaddr_stringify_port(&addr)); 11800 } 11801 11802 /* Ok, we need video. Let's add what we need for video and set codecs. 11803 Video is handled differently than audio since we can not transcode. */ 11804 if (needvideo) { 11805 get_crypto_attrib(p->vsrtp, &v_a_crypto); 11806 ast_str_append(&m_video, 0, "m=video %d RTP/%s", ast_sockaddr_port(&vdest), 11807 v_a_crypto ? "SAVP" : "AVP"); 11808 11809 /* Build max bitrate string */ 11810 if (p->maxcallbitrate) 11811 snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate); 11812 if (debug) { 11813 ast_verbose("Video is at %s\n", ast_sockaddr_stringify(&vdest)); 11814 } 11815 } 11816 11817 /* Ok, we need text. Let's add what we need for text and set codecs. 11818 Text is handled differently than audio since we can not transcode. */ 11819 if (needtext) { 11820 if (sipdebug_text) 11821 ast_verbose("Lets set up the text sdp\n"); 11822 get_crypto_attrib(p->tsrtp, &t_a_crypto); 11823 ast_str_append(&m_text, 0, "m=text %d RTP/%s", ast_sockaddr_port(&tdest), 11824 t_a_crypto ? "SAVP" : "AVP"); 11825 if (debug) { /* XXX should I use tdest below ? */ 11826 ast_verbose("Text is at %s\n", ast_sockaddr_stringify(&taddr)); 11827 } 11828 } 11829 11830 /* Start building generic SDP headers */ 11831 11832 /* We break with the "recommendation" and send our IP, in order that our 11833 peer doesn't have to ast_gethostbyname() us */ 11834 11835 get_crypto_attrib(p->srtp, &a_crypto); 11836 ast_str_append(&m_audio, 0, "m=audio %d RTP/%s", ast_sockaddr_port(&dest), 11837 a_crypto ? "SAVP" : "AVP"); 11838 11839 /* Now, start adding audio codecs. These are added in this order: 11840 - First what was requested by the calling channel 11841 - Then preferences in order from sip.conf device config for this peer/user 11842 - Then other codecs in capabilities, including video 11843 */ 11844 11845 /* Prefer the audio codec we were requested to use, first, no matter what 11846 Note that p->prefcodec can include video codecs, so mask them out 11847 */ 11848 if ((capability & p->prefcodec) & AST_FORMAT_AUDIO_MASK) { 11849 format_t codec = p->prefcodec & AST_FORMAT_AUDIO_MASK; 11850 11851 add_codec_to_sdp(p, codec, &m_audio, &a_audio, debug, &min_audio_packet_size); 11852 alreadysent |= codec; 11853 } 11854 11855 /* Start by sending our preferred audio/video codecs */ 11856 for (x = 0; x < 64; x++) { 11857 format_t codec; 11858 11859 if (!(codec = ast_codec_pref_index(&p->prefs, x))) 11860 break; 11861 11862 if (!(capability & codec)) 11863 continue; 11864 11865 if (alreadysent & codec) 11866 continue; 11867 11868 add_codec_to_sdp(p, codec, &m_audio, &a_audio, debug, &min_audio_packet_size); 11869 alreadysent |= codec; 11870 } 11871 11872 /* Now send any other common audio and video codecs, and non-codec formats: */ 11873 for (x = 1ULL; x <= (needtext ? AST_FORMAT_TEXT_MASK : (needvideo ? AST_FORMAT_VIDEO_MASK : AST_FORMAT_AUDIO_MASK)); x <<= 1) { 11874 if (!(capability & x)) /* Codec not requested */ 11875 continue; 11876 11877 if (alreadysent & x) /* Already added to SDP */ 11878 continue; 11879 11880 if (x & AST_FORMAT_AUDIO_MASK) 11881 add_codec_to_sdp(p, x, &m_audio, &a_audio, debug, &min_audio_packet_size); 11882 else if (x & AST_FORMAT_VIDEO_MASK) 11883 add_vcodec_to_sdp(p, x, &m_video, &a_video, debug, &min_video_packet_size); 11884 else if (x & AST_FORMAT_TEXT_MASK) 11885 add_tcodec_to_sdp(p, x, &m_text, &a_text, debug, &min_text_packet_size); 11886 } 11887 11888 /* Now add DTMF RFC2833 telephony-event as a codec */ 11889 for (x = 1LL; x <= AST_RTP_MAX; x <<= 1) { 11890 if (!(p->jointnoncodeccapability & x)) 11891 continue; 11892 11893 add_noncodec_to_sdp(p, x, &m_audio, &a_audio, debug); 11894 } 11895 11896 ast_debug(3, "-- Done with adding codecs to SDP\n"); 11897 11898 if (!p->owner || p->owner->timingfd == -1) { 11899 ast_str_append(&a_audio, 0, "a=silenceSupp:off - - - -\r\n"); 11900 } 11901 11902 if (min_audio_packet_size) 11903 ast_str_append(&a_audio, 0, "a=ptime:%d\r\n", min_audio_packet_size); 11904 11905 /* XXX don't think you can have ptime for video */ 11906 if (min_video_packet_size) 11907 ast_str_append(&a_video, 0, "a=ptime:%d\r\n", min_video_packet_size); 11908 11909 /* XXX don't think you can have ptime for text */ 11910 if (min_text_packet_size) 11911 ast_str_append(&a_text, 0, "a=ptime:%d\r\n", min_text_packet_size); 11912 11913 if (ast_str_size(m_audio) - ast_str_strlen(m_audio) < 2 || ast_str_size(m_video) - ast_str_strlen(m_video) < 2 || 11914 ast_str_size(m_text) - ast_str_strlen(m_text) < 2 || ast_str_size(a_text) - ast_str_strlen(a_text) < 2 || 11915 ast_str_size(a_audio) - ast_str_strlen(a_audio) < 2 || ast_str_size(a_video) - ast_str_strlen(a_video) < 2) 11916 ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n"); 11917 } 11918 11919 if (add_t38) { 11920 /* Our T.38 end is */ 11921 ast_udptl_get_us(p->udptl, &udptladdr); 11922 11923 /* We don't use directmedia for T.38, so keep the destination the same as our IP address. */ 11924 ast_sockaddr_copy(&udptldest, &p->ourip); 11925 ast_sockaddr_set_port(&udptldest, ast_sockaddr_port(&udptladdr)); 11926 11927 if (debug) { 11928 ast_debug(1, "T.38 UDPTL is at %s port %d\n", ast_sockaddr_stringify_addr(&p->ourip), ast_sockaddr_port(&udptladdr)); 11929 } 11930 11931 /* We break with the "recommendation" and send our IP, in order that our 11932 peer doesn't have to ast_gethostbyname() us */ 11933 11934 ast_str_append(&m_modem, 0, "m=image %d udptl t38\r\n", ast_sockaddr_port(&udptldest)); 11935 11936 if (ast_sockaddr_cmp(&udptldest, &dest)) { 11937 ast_str_append(&m_modem, 0, "c=IN %s %s\r\n", 11938 (ast_sockaddr_is_ipv6(&udptldest) && !ast_sockaddr_is_ipv4_mapped(&udptldest)) ? 11939 "IP6" : "IP4", ast_sockaddr_stringify_addr_remote(&udptldest)); 11940 } 11941 11942 ast_str_append(&a_modem, 0, "a=T38FaxVersion:%u\r\n", p->t38.our_parms.version); 11943 ast_str_append(&a_modem, 0, "a=T38MaxBitRate:%u\r\n", t38_get_rate(p->t38.our_parms.rate)); 11944 if (p->t38.our_parms.fill_bit_removal) { 11945 ast_str_append(&a_modem, 0, "a=T38FaxFillBitRemoval\r\n"); 11946 } 11947 if (p->t38.our_parms.transcoding_mmr) { 11948 ast_str_append(&a_modem, 0, "a=T38FaxTranscodingMMR\r\n"); 11949 } 11950 if (p->t38.our_parms.transcoding_jbig) { 11951 ast_str_append(&a_modem, 0, "a=T38FaxTranscodingJBIG\r\n"); 11952 } 11953 switch (p->t38.our_parms.rate_management) { 11954 case AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF: 11955 ast_str_append(&a_modem, 0, "a=T38FaxRateManagement:transferredTCF\r\n"); 11956 break; 11957 case AST_T38_RATE_MANAGEMENT_LOCAL_TCF: 11958 ast_str_append(&a_modem, 0, "a=T38FaxRateManagement:localTCF\r\n"); 11959 break; 11960 } 11961 ast_str_append(&a_modem, 0, "a=T38FaxMaxDatagram:%u\r\n", ast_udptl_get_local_max_datagram(p->udptl)); 11962 switch (ast_udptl_get_error_correction_scheme(p->udptl)) { 11963 case UDPTL_ERROR_CORRECTION_NONE: 11964 break; 11965 case UDPTL_ERROR_CORRECTION_FEC: 11966 ast_str_append(&a_modem, 0, "a=T38FaxUdpEC:t38UDPFEC\r\n"); 11967 break; 11968 case UDPTL_ERROR_CORRECTION_REDUNDANCY: 11969 ast_str_append(&a_modem, 0, "a=T38FaxUdpEC:t38UDPRedundancy\r\n"); 11970 break; 11971 } 11972 } 11973 11974 if (needaudio) 11975 ast_str_append(&m_audio, 0, "\r\n"); 11976 if (needvideo) 11977 ast_str_append(&m_video, 0, "\r\n"); 11978 if (needtext) 11979 ast_str_append(&m_text, 0, "\r\n"); 11980 11981 add_header(resp, "Content-Type", "application/sdp"); 11982 add_content(resp, version); 11983 add_content(resp, owner); 11984 add_content(resp, subject); 11985 add_content(resp, connection); 11986 /* only if video response is appropriate */ 11987 if (needvideo) { 11988 add_content(resp, bandwidth); 11989 } 11990 add_content(resp, session_time); 11991 /* if this is a response to an invite, order our offers properly */ 11992 if (p->offered_media[SDP_AUDIO].order_offered || 11993 p->offered_media[SDP_VIDEO].order_offered || 11994 p->offered_media[SDP_TEXT].order_offered || 11995 p->offered_media[SDP_IMAGE].order_offered) { 11996 int i; 11997 /* we have up to 3 streams as limited by process_sdp */ 11998 for (i = 1; i <= 3; i++) { 11999 if (p->offered_media[SDP_AUDIO].order_offered == i) { 12000 if (needaudio) { 12001 add_content(resp, ast_str_buffer(m_audio)); 12002 add_content(resp, ast_str_buffer(a_audio)); 12003 add_content(resp, hold); 12004 if (a_crypto) { 12005 add_content(resp, a_crypto); 12006 } 12007 } else { 12008 snprintf(dummy_answer, sizeof(dummy_answer), "m=audio 0 RTP/AVP %s\r\n", p->offered_media[SDP_AUDIO].codecs); 12009 add_content(resp, dummy_answer); 12010 } 12011 } else if (p->offered_media[SDP_VIDEO].order_offered == i) { 12012 if (needvideo) { /* only if video response is appropriate */ 12013 add_content(resp, ast_str_buffer(m_video)); 12014 add_content(resp, ast_str_buffer(a_video)); 12015 add_content(resp, hold); /* Repeat hold for the video stream */ 12016 if (v_a_crypto) { 12017 add_content(resp, v_a_crypto); 12018 } 12019 } else { 12020 snprintf(dummy_answer, sizeof(dummy_answer), "m=video 0 RTP/AVP %s\r\n", p->offered_media[SDP_VIDEO].codecs); 12021 add_content(resp, dummy_answer); 12022 } 12023 } else if (p->offered_media[SDP_TEXT].order_offered == i) { 12024 if (needtext) { /* only if text response is appropriate */ 12025 add_content(resp, ast_str_buffer(m_text)); 12026 add_content(resp, ast_str_buffer(a_text)); 12027 add_content(resp, hold); /* Repeat hold for the text stream */ 12028 if (t_a_crypto) { 12029 add_content(resp, t_a_crypto); 12030 } 12031 } else { 12032 snprintf(dummy_answer, sizeof(dummy_answer), "m=text 0 RTP/AVP %s\r\n", p->offered_media[SDP_TEXT].codecs); 12033 add_content(resp, dummy_answer); 12034 } 12035 } else if (p->offered_media[SDP_IMAGE].order_offered == i) { 12036 if (add_t38) { 12037 add_content(resp, ast_str_buffer(m_modem)); 12038 add_content(resp, ast_str_buffer(a_modem)); 12039 } else { 12040 add_content(resp, "m=image 0 udptl t38\r\n"); 12041 } 12042 } 12043 } 12044 } else { 12045 /* generate new SDP from scratch, no offers */ 12046 if (needaudio) { 12047 add_content(resp, ast_str_buffer(m_audio)); 12048 add_content(resp, ast_str_buffer(a_audio)); 12049 add_content(resp, hold); 12050 if (a_crypto) { 12051 add_content(resp, a_crypto); 12052 } 12053 } 12054 if (needvideo) { /* only if video response is appropriate */ 12055 add_content(resp, ast_str_buffer(m_video)); 12056 add_content(resp, ast_str_buffer(a_video)); 12057 add_content(resp, hold); /* Repeat hold for the video stream */ 12058 if (v_a_crypto) { 12059 add_content(resp, v_a_crypto); 12060 } 12061 } 12062 if (needtext) { /* only if text response is appropriate */ 12063 add_content(resp, ast_str_buffer(m_text)); 12064 add_content(resp, ast_str_buffer(a_text)); 12065 add_content(resp, hold); /* Repeat hold for the text stream */ 12066 if (t_a_crypto) { 12067 add_content(resp, t_a_crypto); 12068 } 12069 } 12070 if (add_t38) { 12071 add_content(resp, ast_str_buffer(m_modem)); 12072 add_content(resp, ast_str_buffer(a_modem)); 12073 } 12074 } 12075 12076 /* Update lastrtprx when we send our SDP */ 12077 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 12078 12079 ast_debug(3, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, capability)); 12080 12081 return AST_SUCCESS; 12082 }
| static int add_sip_domain | ( | const char * | domain, | |
| const enum domain_mode | mode, | |||
| const char * | context | |||
| ) | [static] |
Add SIP domain to list of domains we are responsible for.
Definition at line 27723 of file chan_sip.c.
References ast_calloc, ast_copy_string(), ast_debug, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strlen_zero(), and LOG_WARNING.
Referenced by reload_config().
27724 { 27725 struct domain *d; 27726 27727 if (ast_strlen_zero(domain)) { 27728 ast_log(LOG_WARNING, "Zero length domain.\n"); 27729 return 1; 27730 } 27731 27732 if (!(d = ast_calloc(1, sizeof(*d)))) 27733 return 0; 27734 27735 ast_copy_string(d->domain, domain, sizeof(d->domain)); 27736 27737 if (!ast_strlen_zero(context)) 27738 ast_copy_string(d->context, context, sizeof(d->context)); 27739 27740 d->mode = mode; 27741 27742 AST_LIST_LOCK(&domain_list); 27743 AST_LIST_INSERT_TAIL(&domain_list, d, list); 27744 AST_LIST_UNLOCK(&domain_list); 27745 27746 if (sipdebug) 27747 ast_debug(1, "Added local SIP domain '%s'\n", domain); 27748 27749 return 1; 27750 }
| static int add_supported_header | ( | struct sip_pvt * | pvt, | |
| struct sip_request * | req | |||
| ) | [static] |
Add "Supported" header to sip message. Since some options may be disabled in the config, the sip_pvt must be inspected to determine what is supported for this dialog.
Definition at line 10206 of file chan_sip.c.
References add_header(), and st_get_mode().
Referenced by respprep(), transmit_invite(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_reinvite_with_sdp(), and update_connectedline().
10207 { 10208 int res; 10209 if (st_get_mode(pvt, 0) != SESSION_TIMER_MODE_REFUSE) { 10210 res = add_header(req, "Supported", "replaces, timer"); 10211 } else { 10212 res = add_header(req, "Supported", "replaces"); 10213 } 10214 return res; 10215 }
| static void add_tcodec_to_sdp | ( | const struct sip_pvt * | p, | |
| int | codec, | |||
| struct ast_str ** | m_buf, | |||
| struct ast_str ** | a_buf, | |||
| int | debug, | |||
| int * | min_packet_size | |||
| ) | [static] |
Add text codec offer to SDP offer/answer body in INVITE or 200 OK.
Definition at line 11469 of file chan_sip.c.
References AST_FORMAT_T140, AST_FORMAT_T140RED, ast_getformatname(), ast_rtp_codecs_payload_code(), ast_rtp_instance_get_codecs(), ast_rtp_lookup_mime_subtype2(), ast_rtp_lookup_sample_rate2(), ast_str_append(), and ast_verbose.
Referenced by add_sdp().
11472 { 11473 int rtp_code; 11474 11475 if (!p->trtp) 11476 return; 11477 11478 if (debug) 11479 ast_verbose("Adding text codec 0x%x (%s) to SDP\n", (unsigned)codec, ast_getformatname(codec)); 11480 11481 if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->trtp), 1, codec)) == -1) 11482 return; 11483 11484 ast_str_append(m_buf, 0, " %d", rtp_code); 11485 ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%u\r\n", rtp_code, 11486 ast_rtp_lookup_mime_subtype2(1, codec, 0), 11487 ast_rtp_lookup_sample_rate2(1, codec)); 11488 /* Add fmtp code here */ 11489 11490 if (codec == AST_FORMAT_T140RED) { 11491 int t140code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->trtp), 1, AST_FORMAT_T140); 11492 ast_str_append(a_buf, 0, "a=fmtp:%d %d/%d/%d\r\n", rtp_code, 11493 t140code, 11494 t140code, 11495 t140code); 11496 11497 } 11498 }
| static int add_text | ( | struct sip_request * | req, | |
| const char * | text | |||
| ) | [static] |
Add text body to SIP message.
Definition at line 11202 of file chan_sip.c.
References add_content(), and add_header().
Referenced by transmit_message_with_text().
11203 { 11204 /* XXX Convert \n's to \r\n's XXX */ 11205 add_header(req, "Content-Type", "text/plain;charset=UTF-8"); 11206 add_content(req, text); 11207 return 0; 11208 }
| static struct ast_variable* add_var | ( | const char * | buf, | |
| struct ast_variable * | list | |||
| ) | [static, read] |
implement the setvar config line
Definition at line 27903 of file chan_sip.c.
References ast_strdupa, ast_variable_new(), and ast_variable::next.
Referenced by build_peer().
27904 { 27905 struct ast_variable *tmpvar = NULL; 27906 char *varname = ast_strdupa(buf), *varval = NULL; 27907 27908 if ((varval = strchr(varname, '='))) { 27909 *varval++ = '\0'; 27910 if ((tmpvar = ast_variable_new(varname, varval, ""))) { 27911 tmpvar->next = list; 27912 list = tmpvar; 27913 } 27914 } 27915 return list; 27916 }
| static void add_vcodec_to_sdp | ( | const struct sip_pvt * | p, | |
| format_t | codec, | |||
| struct ast_str ** | m_buf, | |||
| struct ast_str ** | a_buf, | |||
| int | debug, | |||
| int * | min_packet_size | |||
| ) | [static] |
Add video codec offer to SDP offer/answer body in INVITE or 200 OK.
Definition at line 11446 of file chan_sip.c.
References ast_getformatname(), ast_rtp_codecs_payload_code(), ast_rtp_instance_get_codecs(), ast_rtp_lookup_mime_subtype2(), ast_rtp_lookup_sample_rate2(), ast_str_append(), and ast_verbose.
Referenced by add_sdp().
11449 { 11450 int rtp_code; 11451 11452 if (!p->vrtp) 11453 return; 11454 11455 if (debug) 11456 ast_verbose("Adding video codec 0x%" PRIx64 " (%s) to SDP\n", (uint64_t)codec, ast_getformatname(codec)); 11457 11458 if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->vrtp), 1, codec)) == -1) 11459 return; 11460 11461 ast_str_append(m_buf, 0, " %d", rtp_code); 11462 ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%u\r\n", rtp_code, 11463 ast_rtp_lookup_mime_subtype2(1, codec, 0), 11464 ast_rtp_lookup_sample_rate2(1, codec)); 11465 /* Add fmtp code here */ 11466 }
| static int add_vidupdate | ( | struct sip_request * | req | ) | [static] |
add XML encoded media control with update
Definition at line 11367 of file chan_sip.c.
References add_content(), and add_header().
Referenced by transmit_info_with_vidupdate().
11368 { 11369 const char *xml_is_a_huge_waste_of_space = 11370 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" 11371 " <media_control>\r\n" 11372 " <vc_primitive>\r\n" 11373 " <to_encoder>\r\n" 11374 " <picture_fast_update>\r\n" 11375 " </picture_fast_update>\r\n" 11376 " </to_encoder>\r\n" 11377 " </vc_primitive>\r\n" 11378 " </media_control>\r\n"; 11379 add_header(req, "Content-Type", "application/media_control+xml"); 11380 add_content(req, xml_is_a_huge_waste_of_space); 11381 return 0; 11382 }
| static int addr_is_multicast | ( | const struct ast_sockaddr * | addr | ) | [static] |
Check if an ip is an multicast IP. addr the address to check.
This function checks if an address is in the 224.0.0.0/4 network block.
Definition at line 8108 of file chan_sip.c.
References ast_sockaddr_ipv4().
Referenced by process_via().
08109 { 08110 return ((ast_sockaddr_ipv4(addr) & 0xf0000000) == 0xe0000000); 08111 }
| static const char * allowoverlap2str | ( | int | mode | ) | [static] |
Convert AllowOverlap setting to printable string.
Definition at line 17602 of file chan_sip.c.
References map_x_s().
Referenced by _sip_show_peer(), and sip_show_settings().
17603 { 17604 return map_x_s(allowoverlapstr, mode, "<error>"); 17605 }
| static void append_date | ( | struct sip_request * | req | ) | [static] |
Append date to SIP message.
Definition at line 11025 of file chan_sip.c.
References add_header().
Referenced by transmit_invite(), transmit_response_with_date(), transmit_response_with_minse(), and transmit_response_with_unsupported().
11026 { 11027 char tmpdat[256]; 11028 struct tm tm; 11029 time_t t = time(NULL); 11030 11031 gmtime_r(&t, &tm); 11032 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm); 11033 add_header(req, "Date", tmpdat); 11034 }
| static void append_history_full | ( | struct sip_pvt * | p, | |
| const char * | fmt, | |||
| ... | ||||
| ) | [static] |
Append to SIP dialog history with arg list.
Definition at line 3719 of file chan_sip.c.
References append_history_va().
03720 { 03721 va_list ap; 03722 03723 if (!p) { 03724 return; 03725 } 03726 03727 if (!p->do_history && !recordhistory && !dumphistory) { 03728 return; 03729 } 03730 03731 va_start(ap, fmt); 03732 append_history_va(p, fmt, ap); 03733 va_end(ap); 03734 03735 return; 03736 }
| static void append_history_va | ( | struct sip_pvt * | p, | |
| const char * | fmt, | |||
| va_list | ap | |||
| ) | [static] |
Append to SIP dialog history with arg list.
Definition at line 3691 of file chan_sip.c.
References ast_calloc, ast_free, AST_LIST_INSERT_TAIL, and AST_LIST_REMOVE_HEAD.
Referenced by append_history_full().
03692 { 03693 char buf[80], *c = buf; /* max history length */ 03694 struct sip_history *hist; 03695 int l; 03696 03697 vsnprintf(buf, sizeof(buf), fmt, ap); 03698 strsep(&c, "\r\n"); /* Trim up everything after \r or \n */ 03699 l = strlen(buf) + 1; 03700 if (!(hist = ast_calloc(1, sizeof(*hist) + l))) { 03701 return; 03702 } 03703 if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) { 03704 ast_free(hist); 03705 return; 03706 } 03707 memcpy(hist->event, buf, l); 03708 if (p->history_entries == MAX_HISTORY_ENTRIES) { 03709 struct sip_history *oldest; 03710 oldest = AST_LIST_REMOVE_HEAD(p->history, list); 03711 p->history_entries--; 03712 ast_free(oldest); 03713 } 03714 AST_LIST_INSERT_TAIL(p->history, hist, list); 03715 p->history_entries++; 03716 }
| static int apply_directmedia_ha | ( | struct sip_pvt * | p1, | |
| struct sip_pvt * | p2, | |||
| const char * | op | |||
| ) | [static] |
Definition at line 29842 of file chan_sip.c.
References ast_apply_ha(), ast_debug, ast_rtp_instance_get_local_address(), ast_rtp_instance_get_remote_address(), AST_SENSE_ALLOW, AST_SENSE_DENY, ast_sockaddr_stringify(), and ast_strdupa.
Referenced by sip_get_rtp_peer(), sip_get_trtp_peer(), sip_get_udptl_peer(), and sip_get_vrtp_peer().
29843 { 29844 struct ast_sockaddr us = { { 0, }, }, them = { { 0, }, }; 29845 int res = AST_SENSE_ALLOW; 29846 29847 ast_rtp_instance_get_remote_address(p1->rtp, &them); 29848 ast_rtp_instance_get_local_address(p1->rtp, &us); 29849 29850 /* If p2 is a guest call, there will be no peer. If there is no peer, there 29851 * is no directmediaha, so go ahead and allow it */ 29852 if (!p2->relatedpeer) { 29853 return res; 29854 } 29855 29856 if ((res = ast_apply_ha(p2->relatedpeer->directmediaha, &them)) == AST_SENSE_DENY) { 29857 const char *us_addr = ast_strdupa(ast_sockaddr_stringify(&us)); 29858 const char *them_addr = ast_strdupa(ast_sockaddr_stringify(&them)); 29859 29860 ast_debug(3, "Reinvite %s to %s denied by directmedia ACL on %s\n", 29861 op, them_addr, us_addr); 29862 } 29863 29864 return res; 29865 }
| AST_DATA_STRUCTURE | ( | sip_peer | , | |
| DATA_EXPORT_SIP_PEER | ||||
| ) |
| AST_LIST_HEAD_NOLOCK | ( | sip_history_head | , | |
| sip_history | ||||
| ) |
history list, entry in sip_pvt
| AST_LIST_HEAD_STATIC | ( | epa_static_data_list | , | |
| epa_backend | ||||
| ) |
| static AST_LIST_HEAD_STATIC | ( | domain_list | , | |
| domain | ||||
| ) | [static] |
The SIP domain list
| AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
| AST_MODFLAG_LOAD_ORDER | , | |||
| "Session Initiation Protocol (SIP)" | , | |||
| . | load = load_module, |
|||
| . | unload = unload_module, |
|||
| . | reload = reload, |
|||
| . | load_pri = AST_MODPRI_CHANNEL_DRIVER, |
|||
| . | nonoptreq = "res_crypto,chan_local" | |||
| ) |
| AST_MUTEX_DEFINE_STATIC | ( | authl_lock | ) |
Global authentication container protection while adjusting the references.
| AST_MUTEX_DEFINE_STATIC | ( | sip_reload_lock | ) |
| AST_MUTEX_DEFINE_STATIC | ( | monlock | ) |
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.
| AST_MUTEX_DEFINE_STATIC | ( | netlock | ) |
| static void ast_quiet_chan | ( | struct ast_channel * | chan | ) | [static] |
Turn off generator data XXX Does this function belong in the SIP channel?
Definition at line 22339 of file chan_sip.c.
References ast_channel::_state, ast_deactivate_generator(), AST_FLAG_MOH, ast_moh_stop(), AST_STATE_UP, ast_test_flag, and ast_channel::generatordata.
Referenced by attempt_transfer(), and handle_invite_replaces().
22340 { 22341 if (chan && chan->_state == AST_STATE_UP) { 22342 if (ast_test_flag(chan, AST_FLAG_MOH)) 22343 ast_moh_stop(chan); 22344 else if (chan->generatordata) 22345 ast_deactivate_generator(chan); 22346 } 22347 }
| static void ast_sip_ouraddrfor | ( | const struct ast_sockaddr * | them, | |
| struct ast_sockaddr * | us, | |||
| struct sip_pvt * | p | |||
| ) | [static] |
NAT fix - decide which IP address to use for Asterisk server?
Using the localaddr structure built up with localnet statements in sip.conf apply it to their address to see if we need to substitute our externaddr or can get away with our internal bindaddr 'us' is always overwritten.
Definition at line 3587 of file chan_sip.c.
References ast_apply_ha(), ast_debug, ast_log(), ast_ouraddrfor(), AST_SENSE_ALLOW, ast_sockaddr_copy(), ast_sockaddr_is_any(), ast_sockaddr_is_ipv6(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_resolve_first(), ast_sockaddr_set_port, ast_sockaddr_stringify(), bindaddr, externaddr, get_transport(), internip, ast_tcptls_session_args::local_address, LOG_NOTICE, LOG_WARNING, and sip_cfg.
Referenced by __sip_subscribe_mwi_do(), sip_alloc(), sip_cc_monitor_request_cc(), sip_cli_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_publish(), transmit_register(), and transmit_response_using_temp().
03588 { 03589 struct ast_sockaddr theirs; 03590 03591 /* Set want_remap to non-zero if we want to remap 'us' to an externally 03592 * reachable IP address and port. This is done if: 03593 * 1. we have a localaddr list (containing 'internal' addresses marked 03594 * as 'deny', so ast_apply_ha() will return AST_SENSE_DENY on them, 03595 * and AST_SENSE_ALLOW on 'external' ones); 03596 * 2. externaddr is set, so we know what to use as the 03597 * externally visible address; 03598 * 3. the remote address, 'them', is external; 03599 * 4. the address returned by ast_ouraddrfor() is 'internal' (AST_SENSE_DENY 03600 * when passed to ast_apply_ha() so it does need to be remapped. 03601 * This fourth condition is checked later. 03602 */ 03603 int want_remap = 0; 03604 03605 ast_sockaddr_copy(us, &internip); /* starting guess for the internal address */ 03606 /* now ask the system what would it use to talk to 'them' */ 03607 ast_ouraddrfor(them, us); 03608 ast_sockaddr_copy(&theirs, them); 03609 03610 if (ast_sockaddr_is_ipv6(&theirs)) { 03611 if (localaddr && !ast_sockaddr_isnull(&externaddr) && !ast_sockaddr_is_any(&bindaddr)) { 03612 ast_log(LOG_WARNING, "Address remapping activated in sip.conf " 03613 "but we're using IPv6, which doesn't need it. Please " 03614 "remove \"localnet\" and/or \"externaddr\" settings.\n"); 03615 } 03616 } else { 03617 want_remap = localaddr && 03618 !ast_sockaddr_isnull(&externaddr) && 03619 ast_apply_ha(localaddr, &theirs) == AST_SENSE_ALLOW ; 03620 } 03621 03622 if (want_remap && 03623 (!sip_cfg.matchexternaddrlocally || !ast_apply_ha(localaddr, us)) ) { 03624 /* if we used externhost, see if it is time to refresh the info */ 03625 if (externexpire && time(NULL) >= externexpire) { 03626 if (ast_sockaddr_resolve_first(&externaddr, externhost, 0)) { 03627 ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost); 03628 } 03629 externexpire = time(NULL) + externrefresh; 03630 } 03631 if (!ast_sockaddr_isnull(&externaddr)) { 03632 ast_sockaddr_copy(us, &externaddr); 03633 switch (p->socket.type) { 03634 case SIP_TRANSPORT_TCP: 03635 if (!externtcpport && ast_sockaddr_port(&externaddr)) { 03636 /* for consistency, default to the externaddr port */ 03637 externtcpport = ast_sockaddr_port(&externaddr); 03638 } 03639 ast_sockaddr_set_port(us, externtcpport); 03640 break; 03641 case SIP_TRANSPORT_TLS: 03642 ast_sockaddr_set_port(us, externtlsport); 03643 break; 03644 case SIP_TRANSPORT_UDP: 03645 if (!ast_sockaddr_port(&externaddr)) { 03646 ast_sockaddr_set_port(us, ast_sockaddr_port(&bindaddr)); 03647 } 03648 break; 03649 default: 03650 break; 03651 } 03652 } 03653 ast_debug(1, "Target address %s is not local, substituting externaddr\n", 03654 ast_sockaddr_stringify(them)); 03655 } else { 03656 /* no remapping, but we bind to a specific address, so use it. */ 03657 switch (p->socket.type) { 03658 case SIP_TRANSPORT_TCP: 03659 if (!ast_sockaddr_is_any(&sip_tcp_desc.local_address)) { 03660 ast_sockaddr_copy(us, 03661 &sip_tcp_desc.local_address); 03662 } else { 03663 ast_sockaddr_set_port(us, 03664 ast_sockaddr_port(&sip_tcp_desc.local_address)); 03665 } 03666 break; 03667 case SIP_TRANSPORT_TLS: 03668 if (!ast_sockaddr_is_any(&sip_tls_desc.local_address)) { 03669 ast_sockaddr_copy(us, 03670 &sip_tls_desc.local_address); 03671 } else { 03672 ast_sockaddr_set_port(us, 03673 ast_sockaddr_port(&sip_tls_desc.local_address)); 03674 } 03675 break; 03676 case SIP_TRANSPORT_UDP: 03677 /* fall through on purpose */ 03678 default: 03679 if (!ast_sockaddr_is_any(&bindaddr)) { 03680 ast_sockaddr_copy(us, &bindaddr); 03681 } 03682 if (!ast_sockaddr_port(us)) { 03683 ast_sockaddr_set_port(us, ast_sockaddr_port(&bindaddr)); 03684 } 03685 } 03686 } 03687 ast_debug(3, "Setting SIP_TRANSPORT_%s with address %s\n", get_transport(p->socket.type), ast_sockaddr_stringify(us)); 03688 }
| static int ast_sockaddr_resolve_first | ( | struct ast_sockaddr * | addr, | |
| const char * | name, | |||
| int | flag | |||
| ) | [static] |
Return the first entry from ast_sockaddr_resolve filtered by family of binddaddr.
Using this function probably means you have a faulty design.
Definition at line 30680 of file chan_sip.c.
References ast_sockaddr_resolve_first_af(), and get_address_family_filter().
Referenced by ast_sip_ouraddrfor(), check_via(), and reload_config().
30682 { 30683 return ast_sockaddr_resolve_first_af(addr, name, flag, get_address_family_filter(SIP_TRANSPORT_UDP)); 30684 }
| static int ast_sockaddr_resolve_first_af | ( | struct ast_sockaddr * | addr, | |
| const char * | name, | |||
| int | flag, | |||
| int | family | |||
| ) | [static] |
Return the first entry from ast_sockaddr_resolve filtered by address family.
Using this function probably means you have a faulty design.
Definition at line 30656 of file chan_sip.c.
References ast_debug, ast_free, ast_sockaddr_copy(), and ast_sockaddr_resolve().
Referenced by ast_sockaddr_resolve_first(), ast_sockaddr_resolve_first_transport(), get_ip_and_port_from_sdp(), process_sdp_c(), and sip_do_debug_ip().
30658 { 30659 struct ast_sockaddr *addrs; 30660 int addrs_cnt; 30661 30662 addrs_cnt = ast_sockaddr_resolve(&addrs, name, flag, family); 30663 if (addrs_cnt <= 0) { 30664 return 1; 30665 } 30666 if (addrs_cnt > 1) { 30667 ast_debug(1, "Multiple addresses, using the first one only\n"); 30668 } 30669 30670 ast_sockaddr_copy(addr, &addrs[0]); 30671 30672 ast_free(addrs); 30673 return 0; 30674 }
| static int ast_sockaddr_resolve_first_transport | ( | struct ast_sockaddr * | addr, | |
| const char * | name, | |||
| int | flag, | |||
| unsigned int | transport | |||
| ) | [static] |
Return the first entry from ast_sockaddr_resolve filtered by family of binddaddr.
Using this function probably means you have a faulty design.
Definition at line 30690 of file chan_sip.c.
References ast_sockaddr_resolve_first_af(), and get_address_family_filter().
Referenced by __set_address_from_contact(), create_addr(), parse_register_contact(), process_via(), and set_destination().
30692 { 30693 return ast_sockaddr_resolve_first_af(addr, name, flag, get_address_family_filter(transport)); 30694 }
| AST_THREADSTORAGE | ( | check_auth_buf | ) |
| AST_THREADSTORAGE_CUSTOM | ( | ts_temp_pvt | , | |
| temp_pvt_init | , | |||
| temp_pvt_cleanup | ||||
| ) |
A per-thread temporary pvt structure.
| static int attempt_transfer | ( | struct sip_dual * | transferer, | |
| struct sip_dual * | target | |||
| ) | [static] |
Attempt transfer of SIP call This fix for attended transfers on a local PBX.
Definition at line 22351 of file chan_sip.c.
References ast_channel_masquerade(), ast_debug, ast_log(), ast_quiet_chan(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), ast_state2str(), LOG_NOTICE, and LOG_WARNING.
Referenced by local_attended_transfer().
22352 { 22353 int res = 0; 22354 struct ast_channel *peera = NULL, 22355 *peerb = NULL, 22356 *peerc = NULL, 22357 *peerd = NULL; 22358 22359 22360 /* We will try to connect the transferee with the target and hangup 22361 all channels to the transferer */ 22362 ast_debug(4, "Sip transfer:--------------------\n"); 22363 if (transferer->chan1) 22364 ast_debug(4, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state)); 22365 else 22366 ast_debug(4, "-- No transferer first channel - odd??? \n"); 22367 if (target->chan1) 22368 ast_debug(4, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state)); 22369 else 22370 ast_debug(4, "-- No target first channel ---\n"); 22371 if (transferer->chan2) 22372 ast_debug(4, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state)); 22373 else 22374 ast_debug(4, "-- No bridged call to transferee\n"); 22375 if (target->chan2) 22376 ast_debug(4, "-- Bridged call to transfer target: %s State %s\n", target->chan2 ? target->chan2->name : "<none>", target->chan2 ? ast_state2str(target->chan2->_state) : "(none)"); 22377 else 22378 ast_debug(4, "-- No target second channel ---\n"); 22379 ast_debug(4, "-- END Sip transfer:--------------------\n"); 22380 if (transferer->chan2) { /* We have a bridge on the transferer's channel */ 22381 peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */ 22382 peerb = target->chan1; /* Transferer - PBX -> target channel - This will get lost in masq */ 22383 peerc = transferer->chan2; /* Asterisk to Transferee */ 22384 peerd = target->chan2; /* Asterisk to Target */ 22385 ast_debug(3, "SIP transfer: Four channels to handle\n"); 22386 } else if (target->chan2) { /* Transferer has no bridge (IVR), but transferee */ 22387 peera = target->chan1; /* Transferer to PBX -> target channel */ 22388 peerb = transferer->chan1; /* Transferer to IVR*/ 22389 peerc = target->chan2; /* Asterisk to Target */ 22390 peerd = transferer->chan2; /* Nothing */ 22391 ast_debug(3, "SIP transfer: Three channels to handle\n"); 22392 } 22393 22394 if (peera && peerb && peerc && (peerb != peerc)) { 22395 ast_quiet_chan(peera); /* Stop generators */ 22396 /* no need to quiet peerb since it should be hungup after the 22397 transfer and the masquerade needs to be able to see if MOH is 22398 playing on it */ 22399 ast_quiet_chan(peerc); 22400 if (peerd) 22401 ast_quiet_chan(peerd); 22402 22403 ast_debug(4, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name); 22404 if (ast_channel_masquerade(peerb, peerc)) { 22405 ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); 22406 res = -1; 22407 } else 22408 ast_debug(4, "SIP transfer: Succeeded to masquerade channels.\n"); 22409 return res; 22410 } else { 22411 ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n"); 22412 if (transferer->chan1) 22413 ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV); 22414 if (target->chan1) 22415 ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV); 22416 return -1; 22417 } 22418 return 0; 22419 }
| static void auth_headers | ( | enum sip_auth_type | code, | |
| char ** | header, | |||
| char ** | respheader | |||
| ) | [static] |
return the request and response header for a 401 or 407 code
Definition at line 14135 of file chan_sip.c.
References ast_verbose.
Referenced by check_auth(), do_proxy_auth(), do_register_auth(), and transmit_request_with_auth().
14136 { 14137 if (code == WWW_AUTH) { /* 401 */ 14138 *header = "WWW-Authenticate"; 14139 *respheader = "Authorization"; 14140 } else if (code == PROXY_AUTH) { /* 407 */ 14141 *header = "Proxy-Authenticate"; 14142 *respheader = "Proxy-Authorization"; 14143 } else { 14144 ast_verbose("-- wrong response code %u\n", code); 14145 *header = *respheader = "Invalid"; 14146 } 14147 }
| static int auto_congest | ( | const void * | arg | ) | [static] |
Scheduled congestion on a call. Only called by the scheduler, must return the reference when done.
Definition at line 5738 of file chan_sip.c.
References append_history, ast_channel_trylock, ast_channel_unlock, AST_CONTROL_CONGESTION, ast_queue_control(), sip_pvt_lock, sip_pvt_unlock, and sip_scheddestroy().
Referenced by sip_call(), and sip_show_sched().
05739 { 05740 struct sip_pvt *p = (struct sip_pvt *)arg; 05741 05742 sip_pvt_lock(p); 05743 p->initid = -1; /* event gone, will not be rescheduled */ 05744 if (p->owner) { 05745 /* XXX fails on possible deadlock */ 05746 if (!ast_channel_trylock(p->owner)) { 05747 append_history(p, "Cong", "Auto-congesting (timer)"); 05748 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 05749 ast_channel_unlock(p->owner); 05750 } 05751 05752 /* Give the channel a chance to act before we proceed with destruction */ 05753 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 05754 } 05755 sip_pvt_unlock(p); 05756 dialog_unref(p, "unreffing arg passed into auto_congest callback (p->initid)"); 05757 return 0; 05758 }
| static void build_callid_pvt | ( | struct sip_pvt * | pvt | ) | [static] |
Build SIP Call-ID value for a non-REGISTER transaction.
Definition at line 7867 of file chan_sip.c.
References ast_sockaddr_stringify_remote(), ast_string_field_build, generate_random_string(), and S_OR.
Referenced by change_callid_pvt(), and sip_alloc().
07868 { 07869 char buf[33]; 07870 const char *host = S_OR(pvt->fromdomain, ast_sockaddr_stringify_remote(&pvt->ourip)); 07871 07872 ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 07873 }
| static void build_callid_registry | ( | struct sip_registry * | reg, | |
| const struct ast_sockaddr * | ourip, | |||
| const char * | fromdomain | |||
| ) | [static] |
Build SIP Call-ID value for a REGISTER transaction.
Definition at line 7922 of file chan_sip.c.
References ast_sockaddr_stringify_host_remote(), ast_string_field_build, generate_random_string(), and S_OR.
Referenced by transmit_register().
07923 { 07924 char buf[33]; 07925 07926 const char *host = S_OR(fromdomain, ast_sockaddr_stringify_host_remote(ourip)); 07927 07928 ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 07929 }
| static void build_contact | ( | struct sip_pvt * | p | ) | [static] |
Build contact header - the contact header we send out.
Definition at line 12329 of file chan_sip.c.
References ast_sockaddr_stringify_remote(), ast_string_field_build, ast_strlen_zero(), ast_uri_encode(), and get_transport().
Referenced by __sip_subscribe_mwi_do(), check_user_full(), handle_request_invite(), handle_request_options(), handle_request_subscribe(), initreqprep(), register_verify(), and transmit_register().
12330 { 12331 char tmp[SIPBUFSIZE]; 12332 char *user = ast_uri_encode(p->exten, tmp, sizeof(tmp), 0); 12333 12334 if (p->socket.type == SIP_TRANSPORT_UDP) { 12335 ast_string_field_build(p, our_contact, "<sip:%s%s%s>", user, 12336 ast_strlen_zero(user) ? "" : "@", ast_sockaddr_stringify_remote(&p->ourip)); 12337 } else { 12338 ast_string_field_build(p, our_contact, "<sip:%s%s%s;transport=%s>", user, 12339 ast_strlen_zero(user) ? "" : "@", ast_sockaddr_stringify_remote(&p->ourip), 12340 get_transport(p->socket.type)); 12341 } 12342 }
| static void build_localtag_registry | ( | struct sip_registry * | reg | ) | [static] |
Build SIP From tag value for REGISTER.
Definition at line 7932 of file chan_sip.c.
References ast_random(), and ast_string_field_build.
Referenced by transmit_register().
07933 { 07934 ast_string_field_build(reg, localtag, "as%08lx", (unsigned long)ast_random()); 07935 }
| static struct sip_peer * build_peer | ( | const char * | name, | |
| struct ast_variable * | v, | |||
| struct ast_variable * | alt, | |||
| int | realtime, | |||
| int | devstate_only | |||
| ) | [static, read] |
Build peer from configuration (file or realtime static/dynamic).
< The first transport listed should be default outbound
Definition at line 28057 of file chan_sip.c.
References __set_address_from_contact(), accountcode, add_peer_mailboxes(), add_peer_mwi_subs(), add_realm_authentication(), add_var(), ao2_lock, ao2_t_alloc, ao2_t_find, ao2_t_ref, ao2_t_unlink, ao2_unlock, ast_append_ha(), ast_asprintf, ast_atomic_fetchadd_int(), ast_callerid_split(), AST_CC_AGENT_NATIVE, AST_CC_AGENT_NEVER, ast_cc_config_params_init, ast_cc_is_config_param(), ast_cc_set_param(), ast_cdr_amaflags2int(), ast_copy_flags, ast_copy_string(), ast_debug, ast_dnsmgr_lookup_cb(), ast_dnsmgr_refresh(), ast_free, ast_free_ha(), ast_get_cc_agent_policy(), ast_get_group(), ast_get_ip(), ast_get_time_t(), AST_LIST_EMPTY, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), ast_parse_allow_disallow(), ast_parse_caller_presentation(), AST_SCHED_DEL_UNREF, ast_set2_flag, ast_set_cc_agent_policy(), ast_set_flag, ast_skip_blanks(), ast_sockaddr_isnull(), ast_sockaddr_parse(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_setnull(), ast_sockaddr_stringify_addr(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_set(), ast_str_strlen(), ast_strdupa, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variables_destroy(), cid_name, cid_num, context, DEFAULT_MAXMS, destroy_association(), destroy_mailbox(), ast_tls_config::enabled, FALSE, ast_flags::flags, format, get_address_family_filter(), get_srv_protocol(), get_srv_service(), handle_common_options(), handle_t38_options(), language, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, mailbox, mark_parsed_methods(), MAXHOSTNAMELEN, mohinterpret, mohsuggest, ast_variable::name, ast_variable::next, OBJ_POINTER, OBJ_UNLINK, on_dns_update_peer(), parkinglot, PARSE_PORT_FORBID, port_str2int(), proxy_from_config(), ref_peer(), reg_source_db(), secret, set_peer_defaults(), set_socket_transport(), sip_cfg, sip_destroy_peer_fn(), sip_poke_peer(), sip_register(), sip_send_mwi_to_peer(), srvlookup, str2stmode(), str2strefresherparam(), TRUE, unref_peer(), and ast_variable::value.
Referenced by realtime_peer(), and reload_config().
28058 { 28059 struct sip_peer *peer = NULL; 28060 struct ast_ha *oldha = NULL; 28061 struct ast_ha *olddirectmediaha = NULL; 28062 int found = 0; 28063 int firstpass = 1; 28064 uint16_t port = 0; 28065 int format = 0; /* Ama flags */ 28066 int timerb_set = 0, timert1_set = 0; 28067 time_t regseconds = 0; 28068 struct ast_flags peerflags[3] = {{(0)}}; 28069 struct ast_flags mask[3] = {{(0)}}; 28070 char callback[256] = ""; 28071 struct sip_peer tmp_peer; 28072 const char *srvlookup = NULL; 28073 static int deprecation_warning = 1; 28074 int alt_fullcontact = alt ? 1 : 0, headercount = 0; 28075 struct ast_str *fullcontact = ast_str_alloca(512); 28076 28077 if (!realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 28078 /* Note we do NOT use find_peer here, to avoid realtime recursion */ 28079 /* We also use a case-sensitive comparison (unlike find_peer) so 28080 that case changes made to the peer name will be properly handled 28081 during reload 28082 */ 28083 ast_copy_string(tmp_peer.name, name, sizeof(tmp_peer.name)); 28084 peer = ao2_t_find(peers, &tmp_peer, OBJ_POINTER | OBJ_UNLINK, "find and unlink peer from peers table"); 28085 } 28086 28087 if (peer) { 28088 /* Already in the list, remove it and it will be added back (or FREE'd) */ 28089 found++; 28090 /* we've unlinked the peer from the peers container but not unlinked from the peers_by_ip container yet 28091 this leads to a wrong refcounter and the peer object is never destroyed */ 28092 if (!ast_sockaddr_isnull(&peer->addr)) { 28093 ao2_t_unlink(peers_by_ip, peer, "ao2_unlink peer from peers_by_ip table"); 28094 } 28095 if (!(peer->the_mark)) 28096 firstpass = 0; 28097 } else { 28098 if (!(peer = ao2_t_alloc(sizeof(*peer), sip_destroy_peer_fn, "allocate a peer struct"))) 28099 return NULL; 28100 28101 if (ast_string_field_init(peer, 512)) { 28102 ao2_t_ref(peer, -1, "failed to string_field_init, drop peer"); 28103 return NULL; 28104 } 28105 28106 if (!(peer->cc_params = ast_cc_config_params_init())) { 28107 ao2_t_ref(peer, -1, "failed to allocate cc_params for peer"); 28108 return NULL; 28109 } 28110 28111 if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 28112 ast_atomic_fetchadd_int(&rpeerobjs, 1); 28113 ast_debug(3, "-REALTIME- peer built. Name: %s. Peer objects: %d\n", name, rpeerobjs); 28114 } else 28115 ast_atomic_fetchadd_int(&speerobjs, 1); 28116 } 28117 28118 /* Note that our peer HAS had its reference count increased */ 28119 if (firstpass) { 28120 peer->lastmsgssent = -1; 28121 oldha = peer->ha; 28122 peer->ha = NULL; 28123 olddirectmediaha = peer->directmediaha; 28124 peer->directmediaha = NULL; 28125 set_peer_defaults(peer); /* Set peer defaults */ 28126 peer->type = 0; 28127 } 28128 28129 /* in case the case of the peer name has changed, update the name */ 28130 ast_copy_string(peer->name, name, sizeof(peer->name)); 28131 28132 /* If we have channel variables, remove them (reload) */ 28133 if (peer->chanvars) { 28134 ast_variables_destroy(peer->chanvars); 28135 peer->chanvars = NULL; 28136 /* XXX should unregister ? */ 28137 } 28138 28139 if (found) 28140 peer->portinuri = 0; 28141 28142 /* If we have realm authentication information, remove them (reload) */ 28143 ao2_lock(peer); 28144 if (peer->auth) { 28145 ao2_t_ref(peer->auth, -1, "Removing old peer authentication"); 28146 peer->auth = NULL; 28147 } 28148 ao2_unlock(peer); 28149 28150 /* clear the transport information. We will detect if a default value is required after parsing the config */ 28151 peer->default_outbound_transport = 0; 28152 peer->transports = 0; 28153 28154 if (!devstate_only) { 28155 struct sip_mailbox *mailbox; 28156 AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { 28157 mailbox->delme = 1; 28158 } 28159 } 28160 28161 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 28162 if (!devstate_only) { 28163 if (handle_common_options(&peerflags[0], &mask[0], v)) { 28164 continue; 28165 } 28166 if (handle_t38_options(&peerflags[0], &mask[0], v, &peer->t38_maxdatagram)) { 28167 continue; 28168 } 28169 if (!strcasecmp(v->name, "transport")) { 28170 char *val = ast_strdupa(v->value); 28171 char *trans; 28172 28173 peer->transports = peer->default_outbound_transport = 0; 28174 while ((trans = strsep(&val, ","))) { 28175 trans = ast_skip_blanks(trans); 28176 28177 if (!strncasecmp(trans, "udp", 3)) { 28178 peer->transports |= SIP_TRANSPORT_UDP; 28179 } else if (sip_cfg.tcp_enabled && !strncasecmp(trans, "tcp", 3)) { 28180 peer->transports |= SIP_TRANSPORT_TCP; 28181 } else if (default_tls_cfg.enabled && !strncasecmp(trans, "tls", 3)) { 28182 peer->transports |= SIP_TRANSPORT_TLS; 28183 } else if (!strncasecmp(trans, "tcp", 3) || !strncasecmp(trans, "tls", 3)) { 28184 ast_log(LOG_WARNING, "'%.3s' is not a valid transport type when %.3senable=no. If no other is specified, the defaults from general will be used.\n", trans, trans); 28185 } else { 28186 ast_log(LOG_NOTICE, "'%s' is not a valid transport type. if no other is specified, the defaults from general will be used.\n", trans); 28187 } 28188 28189 if (!peer->default_outbound_transport) { /*!< The first transport listed should be default outbound */ 28190 peer->default_outbound_transport = peer->transports; 28191 } 28192 } 28193 } else if (realtime && !strcasecmp(v->name, "regseconds")) { 28194 ast_get_time_t(v->value, ®seconds, 0, NULL); 28195 } else if (realtime && !strcasecmp(v->name, "name")) { 28196 ast_copy_string(peer->name, v->value, sizeof(peer->name)); 28197 } else if (realtime && !strcasecmp(v->name, "useragent")) { 28198 ast_string_field_set(peer, useragent, v->value); 28199 } else if (!strcasecmp(v->name, "type")) { 28200 if (!strcasecmp(v->value, "peer")) { 28201 peer->type |= SIP_TYPE_PEER; 28202 } else if (!strcasecmp(v->value, "user")) { 28203 peer->type |= SIP_TYPE_USER; 28204 } else if (!strcasecmp(v->value, "friend")) { 28205 peer->type = SIP_TYPE_USER | SIP_TYPE_PEER; 28206 } 28207 } else if (!strcasecmp(v->name, "remotesecret")) { 28208 ast_string_field_set(peer, remotesecret, v->value); 28209 } else if (!strcasecmp(v->name, "secret")) { 28210 ast_string_field_set(peer, secret, v->value); 28211 } else if (!strcasecmp(v->name, "md5secret")) { 28212 ast_string_field_set(peer, md5secret, v->value); 28213 } else if (!strcasecmp(v->name, "auth")) { 28214 add_realm_authentication(&peer->auth, v->value, v->lineno); 28215 } else if (!strcasecmp(v->name, "callerid")) { 28216 char cid_name[80] = { '\0' }, cid_num[80] = { '\0' }; 28217 28218 ast_callerid_split(v->value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num)); 28219 ast_string_field_set(peer, cid_name, cid_name); 28220 ast_string_field_set(peer, cid_num, cid_num); 28221 } else if (!strcasecmp(v->name, "mwi_from")) { 28222 ast_string_field_set(peer, mwi_from, v->value); 28223 } else if (!strcasecmp(v->name, "fullname")) { 28224 ast_string_field_set(peer, cid_name, v->value); 28225 } else if (!strcasecmp(v->name, "trunkname")) { 28226 /* This is actually for a trunk, so we don't want to override callerid */ 28227 ast_string_field_set(peer, cid_name, ""); 28228 } else if (!strcasecmp(v->name, "cid_number")) { 28229 ast_string_field_set(peer, cid_num, v->value); 28230 } else if (!strcasecmp(v->name, "cid_tag")) { 28231 ast_string_field_set(peer, cid_tag, v->value); 28232 } else if (!strcasecmp(v->name, "context")) { 28233 ast_string_field_set(peer, context, v->value); 28234 ast_set_flag(&peer->flags[1], SIP_PAGE2_HAVEPEERCONTEXT); 28235 } else if (!strcasecmp(v->name, "subscribecontext")) { 28236 ast_string_field_set(peer, subscribecontext, v->value); 28237 } else if (!strcasecmp(v->name, "fromdomain")) { 28238 char *fromdomainport; 28239 ast_string_field_set(peer, fromdomain, v->value); 28240 if ((fromdomainport = strchr(peer->fromdomain, ':'))) { 28241 *fromdomainport++ = '\0'; 28242 if (!(peer->fromdomainport = port_str2int(fromdomainport, 0))) { 28243 ast_log(LOG_NOTICE, "'%s' is not a valid port number for fromdomain.\n",fromdomainport); 28244 } 28245 } else { 28246 peer->fromdomainport = STANDARD_SIP_PORT; 28247 } 28248 } else if (!strcasecmp(v->name, "usereqphone")) { 28249 ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE); 28250 } else if (!strcasecmp(v->name, "fromuser")) { 28251 ast_string_field_set(peer, fromuser, v->value); 28252 } else if (!strcasecmp(v->name, "outboundproxy")) { 28253 struct sip_proxy *proxy; 28254 if (ast_strlen_zero(v->value)) { 28255 ast_log(LOG_WARNING, "no value given for outbound proxy on line %d of sip.conf\n", v->lineno); 28256 continue; 28257 } 28258 proxy = proxy_from_config(v->value, v->lineno, peer->outboundproxy); 28259 if (!proxy) { 28260 ast_log(LOG_WARNING, "failure parsing the outbound proxy on line %d of sip.conf.\n", v->lineno); 28261 continue; 28262 } 28263 peer->outboundproxy = proxy; 28264 } else if (!strcasecmp(v->name, "host")) { 28265 if (!strcasecmp(v->value, "dynamic")) { 28266 /* They'll register with us */ 28267 if ((!found && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) || !peer->host_dynamic) { 28268 /* Initialize stuff if this is a new peer, or if it used to 28269 * not be dynamic before the reload. */ 28270 ast_sockaddr_setnull(&peer->addr); 28271 } 28272 peer->host_dynamic = TRUE; 28273 } else { 28274 /* Non-dynamic. Make sure we become that way if we're not */ 28275 AST_SCHED_DEL_UNREF(sched, peer->expire, 28276 unref_peer(peer, "removing register expire ref")); 28277 peer->host_dynamic = FALSE; 28278 srvlookup = v->value; 28279 } 28280 } else if (!strcasecmp(v->name, "defaultip")) { 28281 if (!ast_strlen_zero(v->value) && ast_get_ip(&peer->defaddr, v->value)) { 28282 unref_peer(peer, "unref_peer: from build_peer defaultip"); 28283 return NULL; 28284 } 28285 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 28286 int ha_error = 0; 28287 if (!ast_strlen_zero(v->value)) { 28288 peer->ha = ast_append_ha(v->name, v->value, peer->ha, &ha_error); 28289 } 28290 if (ha_error) { 28291 ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value); 28292 } 28293 } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) { 28294 int ha_error = 0; 28295 if (!ast_strlen_zero(v->value)) { 28296 peer->contactha = ast_append_ha(v->name + 7, v->value, peer->contactha, &ha_error); 28297 } 28298 if (ha_error) { 28299 ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value); 28300 } 28301 } else if (!strcasecmp(v->name, "directmediapermit") || !strcasecmp(v->name, "directmediadeny")) { 28302 int ha_error = 0; 28303 peer->directmediaha = ast_append_ha(v->name + 11, v->value, peer->directmediaha, &ha_error); 28304 if (ha_error) { 28305 ast_log(LOG_ERROR, "Bad directmedia ACL entry in configuration line %d : %s\n", v->lineno, v->value); 28306 } 28307 } else if (!strcasecmp(v->name, "port")) { 28308 peer->portinuri = 1; 28309 if (!(port = port_str2int(v->value, 0))) { 28310 if (realtime) { 28311 /* If stored as integer, could be 0 for some DBs (notably MySQL) */ 28312 peer->portinuri = 0; 28313 } else { 28314 ast_log(LOG_WARNING, "Invalid peer port configuration at line %d : %s\n", v->lineno, v->value); 28315 } 28316 } 28317 } else if (!strcasecmp(v->name, "callingpres")) { 28318 peer->callingpres = ast_parse_caller_presentation(v->value); 28319 if (peer->callingpres == -1) { 28320 peer->callingpres = atoi(v->value); 28321 } 28322 } else if (!strcasecmp(v->name, "username") || !strcmp(v->name, "defaultuser")) { /* "username" is deprecated */ 28323 ast_string_field_set(peer, username, v->value); 28324 if (!strcasecmp(v->name, "username")) { 28325 if (deprecation_warning) { 28326 ast_log(LOG_NOTICE, "The 'username' field for sip peers has been deprecated in favor of the term 'defaultuser'\n"); 28327 deprecation_warning = 0; 28328 } 28329 peer->deprecated_username = 1; 28330 } 28331 } else if (!strcasecmp(v->name, "language")) { 28332 ast_string_field_set(peer, language, v->value); 28333 } else if (!strcasecmp(v->name, "regexten")) { 28334 ast_string_field_set(peer, regexten, v->value); 28335 } else if (!strcasecmp(v->name, "callbackextension")) { 28336 ast_copy_string(callback, v->value, sizeof(callback)); 28337 } else if (!strcasecmp(v->name, "amaflags")) { 28338 format = ast_cdr_amaflags2int(v->value); 28339 if (format < 0) { 28340 ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno); 28341 } else { 28342 peer->amaflags = format; 28343 } 28344 } else if (!strcasecmp(v->name, "maxforwards")) { 28345 if (sscanf(v->value, "%30d", &peer->maxforwards) != 1 28346 || peer->maxforwards < 1 || 255 < peer->maxforwards) { 28347 ast_log(LOG_WARNING, "'%s' is not a valid maxforwards value at line %d. Using default.\n", v->value, v->lineno); 28348 peer->maxforwards = sip_cfg.default_max_forwards; 28349 } 28350 } else if (!strcasecmp(v->name, "accountcode")) { 28351 ast_string_field_set(peer, accountcode, v->value); 28352 } else if (!strcasecmp(v->name, "mohinterpret")) { 28353 ast_string_field_set(peer, mohinterpret, v->value); 28354 } else if (!strcasecmp(v->name, "mohsuggest")) { 28355 ast_string_field_set(peer, mohsuggest, v->value); 28356 } else if (!strcasecmp(v->name, "parkinglot")) { 28357 ast_string_field_set(peer, parkinglot, v->value); 28358 } else if (!strcasecmp(v->name, "rtp_engine")) { 28359 ast_string_field_set(peer, engine, v->value); 28360 } else if (!strcasecmp(v->name, "mailbox")) { 28361 add_peer_mailboxes(peer, v->value); 28362 } else if (!strcasecmp(v->name, "hasvoicemail")) { 28363 /* People expect that if 'hasvoicemail' is set, that the mailbox will 28364 * be also set, even if not explicitly specified. */ 28365 if (ast_true(v->value) && AST_LIST_EMPTY(&peer->mailboxes)) { 28366 add_peer_mailboxes(peer, name); 28367 } 28368 } else if (!strcasecmp(v->name, "subscribemwi")) { 28369 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY); 28370 } else if (!strcasecmp(v->name, "vmexten")) { 28371 ast_string_field_set(peer, vmexten, v->value); 28372 } else if (!strcasecmp(v->name, "callgroup")) { 28373 peer->callgroup = ast_get_group(v->value); 28374 } else if (!strcasecmp(v->name, "allowtransfer")) { 28375 peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 28376 } else if (!strcasecmp(v->name, "pickupgroup")) { 28377 peer->pickupgroup = ast_get_group(v->value); 28378 } else if (!strcasecmp(v->name, "allow")) { 28379 int error = ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, TRUE); 28380 if (error) { 28381 ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value); 28382 } 28383 } else if (!strcasecmp(v->name, "disallow")) { 28384 int error = ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, FALSE); 28385 if (error) { 28386 ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value); 28387 } 28388 } else if (!strcasecmp(v->name, "preferred_codec_only")) { 28389 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_PREFERRED_CODEC); 28390 } else if (!strcasecmp(v->name, "autoframing")) { 28391 peer->autoframing = ast_true(v->value); 28392 } else if (!strcasecmp(v->name, "rtptimeout")) { 28393 if ((sscanf(v->value, "%30d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) { 28394 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 28395 peer->rtptimeout = global_rtptimeout; 28396 } 28397 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 28398 if ((sscanf(v->value, "%30d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) { 28399 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 28400 peer->rtpholdtimeout = global_rtpholdtimeout; 28401 } 28402 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 28403 if ((sscanf(v->value, "%30d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) { 28404 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 28405 peer->rtpkeepalive = global_rtpkeepalive; 28406 } 28407 } else if (!strcasecmp(v->name, "timert1")) { 28408 if ((sscanf(v->value, "%30d", &peer->timer_t1) != 1) || (peer->timer_t1 < 200) || (peer->timer_t1 < global_t1min)) { 28409 ast_log(LOG_WARNING, "'%s' is not a valid T1 time at line %d. Using default.\n", v->value, v->lineno); 28410 peer->timer_t1 = global_t1min; 28411 } 28412 timert1_set = 1; 28413 } else if (!strcasecmp(v->name, "timerb")) { 28414 if ((sscanf(v->value, "%30d", &peer->timer_b) != 1) || (peer->timer_b < 200)) { 28415 ast_log(LOG_WARNING, "'%s' is not a valid Timer B time at line %d. Using default.\n", v->value, v->lineno); 28416 peer->timer_b = global_timer_b; 28417 } 28418 timerb_set = 1; 28419 } else if (!strcasecmp(v->name, "setvar")) { 28420 peer->chanvars = add_var(v->value, peer->chanvars); 28421 } else if (!strcasecmp(v->name, "header")) { 28422 char tmp[4096]; 28423 snprintf(tmp, sizeof(tmp), "__SIPADDHEADERpre%2d=%s", ++headercount, v->value); 28424 peer->chanvars = add_var(tmp, peer->chanvars); 28425 } else if (!strcasecmp(v->name, "qualifyfreq")) { 28426 int i; 28427 if (sscanf(v->value, "%30d", &i) == 1) { 28428 peer->qualifyfreq = i * 1000; 28429 } else { 28430 ast_log(LOG_WARNING, "Invalid qualifyfreq number '%s' at line %d of %s\n", v->value, v->lineno, config); 28431 peer->qualifyfreq = global_qualifyfreq; 28432 } 28433 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 28434 peer->maxcallbitrate = atoi(v->value); 28435 if (peer->maxcallbitrate < 0) { 28436 peer->maxcallbitrate = default_maxcallbitrate; 28437 } 28438 } else if (!strcasecmp(v->name, "session-timers")) { 28439 int i = (int) str2stmode(v->value); 28440 if (i < 0) { 28441 ast_log(LOG_WARNING, "Invalid session-timers '%s' at line %d of %s\n", v->value, v->lineno, config); 28442 peer->stimer.st_mode_oper = global_st_mode; 28443 } else { 28444 peer->stimer.st_mode_oper = i; 28445 } 28446 } else if (!strcasecmp(v->name, "session-expires")) { 28447 if (sscanf(v->value, "%30d", &peer->stimer.st_max_se) != 1) { 28448 ast_log(LOG_WARNING, "Invalid session-expires '%s' at line %d of %s\n", v->value, v->lineno, config); 28449 peer->stimer.st_max_se = global_max_se; 28450 } 28451 } else if (!strcasecmp(v->name, "session-minse")) { 28452 if (sscanf(v->value, "%30d", &peer->stimer.st_min_se) != 1) { 28453 ast_log(LOG_WARNING, "Invalid session-minse '%s' at line %d of %s\n", v->value, v->lineno, config); 28454 peer->stimer.st_min_se = global_min_se; 28455 } 28456 if (peer->stimer.st_min_se < DEFAULT_MIN_SE) { 28457 ast_log(LOG_WARNING, "session-minse '%s' at line %d of %s is not allowed to be < %d secs\n", v->value, v->lineno, config, DEFAULT_MIN_SE); 28458 peer->stimer.st_min_se = global_min_se; 28459 } 28460 } else if (!strcasecmp(v->name, "session-refresher")) { 28461 int i = (int) str2strefresherparam(v->value); 28462 if (i < 0) { 28463 ast_log(LOG_WARNING, "Invalid session-refresher '%s' at line %d of %s\n", v->value, v->lineno, config); 28464 peer->stimer.st_ref = global_st_refresher; 28465 } else { 28466 peer->stimer.st_ref = i; 28467 } 28468 } else if (!strcasecmp(v->name, "disallowed_methods")) { 28469 char *disallow = ast_strdupa(v->value); 28470 mark_parsed_methods(&peer->disallowed_methods, disallow); 28471 } else if (!strcasecmp(v->name, "unsolicited_mailbox")) { 28472 ast_string_field_set(peer, unsolicited_mailbox, v->value); 28473 } else if (!strcasecmp(v->name, "use_q850_reason")) { 28474 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_Q850_REASON); 28475 } else if (!strcasecmp(v->name, "encryption")) { 28476 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_USE_SRTP); 28477 } else if (!strcasecmp(v->name, "snom_aoc_enabled")) { 28478 ast_set2_flag(&peer->flags[2], ast_true(v->value), SIP_PAGE3_SNOM_AOC); 28479 } 28480 } 28481 28482 /* These apply to devstate lookups */ 28483 if (realtime && !strcasecmp(v->name, "lastms")) { 28484 sscanf(v->value, "%30d", &peer->lastms); 28485 } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) { 28486 ast_sockaddr_parse(&peer->addr, v->value, PARSE_PORT_FORBID); 28487 } else if (realtime && !strcasecmp(v->name, "fullcontact")) { 28488 if (alt_fullcontact && !alt) { 28489 /* Reset, because the alternate also has a fullcontact and we 28490 * do NOT want the field value to be doubled. It might be 28491 * tempting to skip this, but the first table might not have 28492 * fullcontact and since we're here, we know that the alternate 28493 * absolutely does. */ 28494 alt_fullcontact = 0; 28495 ast_str_reset(fullcontact); 28496 } 28497 /* Reconstruct field, because realtime separates our value at the ';' */ 28498 if (ast_str_strlen(fullcontact) > 0) { 28499 ast_str_append(&fullcontact, 0, ";%s", v->value); 28500 } else { 28501 ast_str_set(&fullcontact, 0, "%s", v->value); 28502 } 28503 } else if (!strcasecmp(v->name, "qualify")) { 28504 if (!strcasecmp(v->value, "no")) { 28505 peer->maxms = 0; 28506 } else if (!strcasecmp(v->value, "yes")) { 28507 peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS; 28508 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) { 28509 ast_log(LOG_WARNING, "Qualification of peer '%s' should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", peer->name, v->lineno); 28510 peer->maxms = 0; 28511 } 28512 if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && peer->maxms > 0) { 28513 /* This would otherwise cause a network storm, where the 28514 * qualify response refreshes the peer from the database, 28515 * which in turn causes another qualify to be sent, ad 28516 * infinitum. */ 28517 ast_log(LOG_WARNING, "Qualify is incompatible with dynamic uncached realtime. Please either turn rtcachefriends on or turn qualify off on peer '%s'\n", peer->name); 28518 peer->maxms = 0; 28519 } 28520 } else if (!strcasecmp(v->name, "callcounter")) { 28521 peer->call_limit = ast_true(v->value) ? INT_MAX : 0; 28522 } else if (!strcasecmp(v->name, "call-limit")) { 28523 peer->call_limit = atoi(v->value); 28524 if (peer->call_limit < 0) { 28525 peer->call_limit = 0; 28526 } 28527 } else if (!strcasecmp(v->name, "busylevel")) { 28528 peer->busy_level = atoi(v->value); 28529 if (peer->busy_level < 0) { 28530 peer->busy_level = 0; 28531 } 28532 } else if (ast_cc_is_config_param(v->name)) { 28533 ast_cc_set_param(peer->cc_params, v->name, v->value); 28534 } 28535 } 28536 28537 if (!devstate_only) { 28538 struct sip_mailbox *mailbox; 28539 AST_LIST_TRAVERSE_SAFE_BEGIN(&peer->mailboxes, mailbox, entry) { 28540 if (mailbox->delme) { 28541 AST_LIST_REMOVE_CURRENT(entry); 28542 destroy_mailbox(mailbox); 28543 } 28544 } 28545 AST_LIST_TRAVERSE_SAFE_END; 28546 } 28547 28548 if (!can_parse_xml && (ast_get_cc_agent_policy(peer->cc_params) == AST_CC_AGENT_NATIVE)) { 28549 ast_log(LOG_WARNING, "Peer %s has a cc_agent_policy of 'native' but required libxml2 dependency is not installed. Changing policy to 'never'\n", peer->name); 28550 ast_set_cc_agent_policy(peer->cc_params, AST_CC_AGENT_NEVER); 28551 } 28552 28553 /* Note that Timer B is dependent upon T1 and MUST NOT be lower 28554 * than T1 * 64, according to RFC 3261, Section 17.1.1.2 */ 28555 if (peer->timer_b < peer->timer_t1 * 64) { 28556 if (timerb_set && timert1_set) { 28557 ast_log(LOG_WARNING, "Timer B has been set lower than recommended for peer %s (%d < 64 * Timer-T1=%d)\n", peer->name, peer->timer_b, peer->timer_t1); 28558 } else if (timerb_set) { 28559 if ((peer->timer_t1 = peer->timer_b / 64) < global_t1min) { 28560 ast_log(LOG_WARNING, "Timer B has been set lower than recommended (%d < 64 * timert1=%d). (RFC 3261, 17.1.1.2)\n", peer->timer_b, peer->timer_t1); 28561 peer->timer_t1 = global_t1min; 28562 peer->timer_b = peer->timer_t1 * 64; 28563 } 28564 peer->timer_t1 = peer->timer_b / 64; 28565 } else { 28566 peer->timer_b = peer->timer_t1 * 64; 28567 } 28568 } 28569 28570 if (!peer->default_outbound_transport) { 28571 /* Set default set of transports */ 28572 peer->transports = default_transports; 28573 /* Set default primary transport */ 28574 peer->default_outbound_transport = default_primary_transport; 28575 } 28576 28577 /* The default transport type set during build_peer should only replace the socket.type when... 28578 * 1. Registration is not present and the socket.type and default transport types are different. 28579 * 2. The socket.type is not an acceptable transport type after rebuilding peer. 28580 * 3. The socket.type is not set yet. */ 28581 if (((peer->socket.type != peer->default_outbound_transport) && (peer->expire == -1)) || 28582 !(peer->socket.type & peer->transports) || !(peer->socket.type)) { 28583 28584 set_socket_transport(&peer->socket, peer->default_outbound_transport); 28585 } 28586 28587 ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags); 28588 ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags); 28589 ast_copy_flags(&peer->flags[2], &peerflags[2], mask[2].flags); 28590 28591 if (ast_str_strlen(fullcontact)) { 28592 ast_string_field_set(peer, fullcontact, ast_str_buffer(fullcontact)); 28593 peer->rt_fromcontact = TRUE; 28594 /* We have a hostname in the fullcontact, but if we don't have an 28595 * address listed on the entry (or if it's 'dynamic'), then we need to 28596 * parse the entry to obtain the IP address, so a dynamic host can be 28597 * contacted immediately after reload (as opposed to waiting for it to 28598 * register once again). But if we have an address for this peer and NAT was 28599 * specified, use that address instead. */ 28600 /* XXX May need to revisit the final argument; does the realtime DB store whether 28601 * the original contact was over TLS or not? XXX */ 28602 if (!ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) || ast_sockaddr_isnull(&peer->addr)) { 28603 __set_address_from_contact(ast_str_buffer(fullcontact), &peer->addr, 0); 28604 } 28605 } 28606 28607 if (srvlookup && peer->dnsmgr == NULL) { 28608 char transport[MAXHOSTNAMELEN]; 28609 char _srvlookup[MAXHOSTNAMELEN]; 28610 char *params; 28611 28612 ast_copy_string(_srvlookup, srvlookup, sizeof(_srvlookup)); 28613 if ((params = strchr(_srvlookup, ';'))) { 28614 *params++ = '\0'; 28615 } 28616 28617 snprintf(transport, sizeof(transport), "_%s._%s", get_srv_service(peer->socket.type), get_srv_protocol(peer->socket.type)); 28618 28619 peer->addr.ss.ss_family = get_address_family_filter(peer->socket.type); /* Filter address family */ 28620 if (ast_dnsmgr_lookup_cb(_srvlookup, &peer->addr, &peer->dnsmgr, sip_cfg.srvlookup && !peer->portinuri ? transport : NULL, 28621 on_dns_update_peer, ref_peer(peer, "Store peer on dnsmgr"))) { 28622 ast_log(LOG_ERROR, "srvlookup failed for host: %s, on peer %s, removing peer\n", _srvlookup, peer->name); 28623 unref_peer(peer, "dnsmgr lookup failed, getting rid of peer dnsmgr ref"); 28624 unref_peer(peer, "getting rid of a peer pointer"); 28625 return NULL; 28626 } 28627 if (!peer->dnsmgr) { 28628 /* dnsmgr refresh disabeld, release reference */ 28629 unref_peer(peer, "dnsmgr disabled, unref peer"); 28630 } 28631 28632 ast_string_field_set(peer, tohost, srvlookup); 28633 28634 if (global_dynamic_exclude_static && !ast_sockaddr_isnull(&peer->addr)) { 28635 int ha_error = 0; 28636 sip_cfg.contact_ha = ast_append_ha("deny", ast_sockaddr_stringify_addr(&peer->addr), 28637 sip_cfg.contact_ha, &ha_error); 28638 if (ha_error) { 28639 ast_log(LOG_ERROR, "Bad or unresolved host/IP entry in configuration for peer %s, cannot add to contact ACL\n", peer->name); 28640 } 28641 } 28642 } else if (peer->dnsmgr && !peer->host_dynamic) { 28643 /* force a refresh here on reload if dnsmgr already exists and host is set. */ 28644 ast_dnsmgr_refresh(peer->dnsmgr); 28645 } 28646 28647 if (port && !realtime && peer->host_dynamic) { 28648 ast_sockaddr_set_port(&peer->defaddr, port); 28649 } else if (port) { 28650 ast_sockaddr_set_port(&peer->addr, port); 28651 } 28652 28653 if (ast_sockaddr_port(&peer->addr) == 0) { 28654 ast_sockaddr_set_port(&peer->addr, 28655 (peer->socket.type & SIP_TRANSPORT_TLS) ? 28656 STANDARD_TLS_PORT : STANDARD_SIP_PORT); 28657 } 28658 if (ast_sockaddr_port(&peer->defaddr) == 0) { 28659 ast_sockaddr_set_port(&peer->defaddr, 28660 (peer->socket.type & SIP_TRANSPORT_TLS) ? 28661 STANDARD_TLS_PORT : STANDARD_SIP_PORT); 28662 } 28663 if (!peer->socket.port) { 28664 peer->socket.port = htons(((peer->socket.type & SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT)); 28665 } 28666 28667 if (realtime) { 28668 int enablepoke = 1; 28669 28670 if (!sip_cfg.ignore_regexpire && peer->host_dynamic) { 28671 time_t nowtime = time(NULL); 28672 28673 if ((nowtime - regseconds) > 0) { 28674 destroy_association(peer); 28675 memset(&peer->addr, 0, sizeof(peer->addr)); 28676 peer->lastms = -1; 28677 enablepoke = 0; 28678 ast_debug(1, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 28679 } 28680 } 28681 28682 /* Startup regular pokes */ 28683 if (!devstate_only && enablepoke) { 28684 ref_peer(peer, "schedule qualify"); 28685 sip_poke_peer(peer, 0); 28686 } 28687 } 28688 28689 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) { 28690 sip_cfg.allowsubscribe = TRUE; /* No global ban any more */ 28691 } 28692 /* If read-only RT backend, then refresh from local DB cache */ 28693 if (peer->host_dynamic && (!peer->is_realtime || !sip_cfg.peer_rtupdate)) { 28694 reg_source_db(peer); 28695 } 28696 28697 /* If they didn't request that MWI is sent *only* on subscribe, go ahead and 28698 * subscribe to it now. */ 28699 if (!devstate_only && !ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) && 28700 !AST_LIST_EMPTY(&peer->mailboxes)) { 28701 add_peer_mwi_subs(peer); 28702 /* Send MWI from the event cache only. This is so we can send initial 28703 * MWI if app_voicemail got loaded before chan_sip. If it is the other 28704 * way, then we will get events when app_voicemail gets loaded. */ 28705 sip_send_mwi_to_peer(peer, 1); 28706 } 28707 28708 peer->the_mark = 0; 28709 28710 ast_free_ha(oldha); 28711 ast_free_ha(olddirectmediaha); 28712 if (!ast_strlen_zero(callback)) { /* build string from peer info */ 28713 char *reg_string; 28714 if (ast_asprintf(®_string, "%s?%s:%s@%s/%s", peer->name, peer->username, !ast_strlen_zero(peer->remotesecret) ? peer->remotesecret : peer->secret, peer->tohost, callback) >= 0) { 28715 sip_register(reg_string, 0); /* XXX TODO: count in registry_count */ 28716 ast_free(reg_string); 28717 } 28718 } 28719 return peer; 28720 }
| static int build_reply_digest | ( | struct sip_pvt * | p, | |
| int | method, | |||
| char * | digest, | |||
| int | digest_len | |||
| ) | [static] |
Build reply digest.
Definition at line 19922 of file chan_sip.c.
References ao2_lock, ao2_t_ref, ao2_unlock, append_history, ast_copy_string(), ast_debug, ast_md5_hash(), ast_mutex_lock, ast_mutex_unlock, ast_random(), ast_sockaddr_stringify_host_remote(), ast_strlen_zero(), find_realm_authentication(), secret, sip_methods, and text.
Referenced by reply_digest(), transmit_register(), and transmit_request_with_auth().
19923 { 19924 char a1[256]; 19925 char a2[256]; 19926 char a1_hash[256]; 19927 char a2_hash[256]; 19928 char resp[256]; 19929 char resp_hash[256]; 19930 char uri[256]; 19931 char opaque[256] = ""; 19932 char cnonce[80]; 19933 const char *username; 19934 const char *secret; 19935 const char *md5secret; 19936 struct sip_auth *auth; /* Realm authentication credential */ 19937 struct sip_auth_container *credentials; 19938 19939 if (!ast_strlen_zero(p->domain)) 19940 snprintf(uri, sizeof(uri), "%s:%s", p->socket.type == SIP_TRANSPORT_TLS ? "sips" : "sip", p->domain); 19941 else if (!ast_strlen_zero(p->uri)) 19942 ast_copy_string(uri, p->uri, sizeof(uri)); 19943 else 19944 snprintf(uri, sizeof(uri), "%s:%s@%s", p->socket.type == SIP_TRANSPORT_TLS ? "sips" : "sip", p->username, ast_sockaddr_stringify_host_remote(&p->sa)); 19945 19946 snprintf(cnonce, sizeof(cnonce), "%08lx", (unsigned long)ast_random()); 19947 19948 /* Check if we have peer credentials */ 19949 ao2_lock(p); 19950 credentials = p->peerauth; 19951 if (credentials) { 19952 ao2_t_ref(credentials, +1, "Ref peer auth for digest"); 19953 } 19954 ao2_unlock(p); 19955 auth = find_realm_authentication(credentials, p->realm); 19956 if (!auth) { 19957 /* If not, check global credentials */ 19958 if (credentials) { 19959 ao2_t_ref(credentials, -1, "Unref peer auth for digest"); 19960 } 19961 ast_mutex_lock(&authl_lock); 19962 credentials = authl; 19963 if (credentials) { 19964 ao2_t_ref(credentials, +1, "Ref global auth for digest"); 19965 } 19966 ast_mutex_unlock(&authl_lock); 19967 auth = find_realm_authentication(credentials, p->realm); 19968 } 19969 19970 if (auth) { 19971 ast_debug(3, "use realm [%s] from peer [%s][%s]\n", auth->username, p->peername, p->username); 19972 username = auth->username; 19973 secret = auth->secret; 19974 md5secret = auth->md5secret; 19975 if (sipdebug) 19976 ast_debug(1, "Using realm %s authentication for call %s\n", p->realm, p->callid); 19977 } else { 19978 /* No authentication, use peer or register= config */ 19979 username = p->authname; 19980 secret = p->relatedpeer 19981 && !ast_strlen_zero(p->relatedpeer->remotesecret) 19982 ? p->relatedpeer->remotesecret : p->peersecret; 19983 md5secret = p->peermd5secret; 19984 } 19985 if (ast_strlen_zero(username)) { 19986 /* We have no authentication */ 19987 if (credentials) { 19988 ao2_t_ref(credentials, -1, "Unref auth for digest"); 19989 } 19990 return -1; 19991 } 19992 19993 /* Calculate SIP digest response */ 19994 snprintf(a1, sizeof(a1), "%s:%s:%s", username, p->realm, secret); 19995 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[method].text, uri); 19996 if (!ast_strlen_zero(md5secret)) 19997 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 19998 else 19999 ast_md5_hash(a1_hash, a1); 20000 ast_md5_hash(a2_hash, a2); 20001 20002 p->noncecount++; 20003 if (!ast_strlen_zero(p->qop)) 20004 snprintf(resp, sizeof(resp), "%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, (unsigned)p->noncecount, cnonce, "auth", a2_hash); 20005 else 20006 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, p->nonce, a2_hash); 20007 ast_md5_hash(resp_hash, resp); 20008 20009 /* only include the opaque string if it's set */ 20010 if (!ast_strlen_zero(p->opaque)) { 20011 snprintf(opaque, sizeof(opaque), ", opaque=\"%s\"", p->opaque); 20012 } 20013 20014 /* XXX We hard code our qop to "auth" for now. XXX */ 20015 if (!ast_strlen_zero(p->qop)) 20016 snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\"%s, qop=auth, cnonce=\"%s\", nc=%08x", username, p->realm, uri, p->nonce, resp_hash, opaque, cnonce, (unsigned)p->noncecount); 20017 else 20018 snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\"%s", username, p->realm, uri, p->nonce, resp_hash, opaque); 20019 20020 append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount); 20021 20022 if (credentials) { 20023 ao2_t_ref(credentials, -1, "Unref auth for digest"); 20024 } 20025 return 0; 20026 }
| static void build_route | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| int | backwards, | |||
| int | resp | |||
| ) | [static] |
Build route list from Record-Route header.
| resp | the SIP response code or 0 for a request |
Definition at line 14698 of file chan_sip.c.
References __get_header(), ast_copy_string(), ast_debug, ast_malloc, ast_strdupa, ast_strlen_zero(), free_old_route(), get_header(), get_in_brackets(), get_in_brackets_const(), len(), list_route(), and sip_debug_test_pvt().
Referenced by handle_request_invite(), handle_request_subscribe(), and handle_response_invite().
14699 { 14700 struct sip_route *thishop, *head, *tail; 14701 int start = 0; 14702 int len; 14703 const char *rr, *c; 14704 14705 /* Once a persistent route is set, don't fool with it */ 14706 if (p->route && p->route_persistent) { 14707 ast_debug(1, "build_route: Retaining previous route: <%s>\n", p->route->hop); 14708 return; 14709 } 14710 14711 if (p->route) { 14712 free_old_route(p->route); 14713 p->route = NULL; 14714 } 14715 14716 /* We only want to create the route set the first time this is called except 14717 it is called from a provisional response.*/ 14718 if ((resp < 100) || (resp > 199)) { 14719 p->route_persistent = 1; 14720 } 14721 14722 /* Build a tailq, then assign it to p->route when done. 14723 * If backwards, we add entries from the head so they end up 14724 * in reverse order. However, we do need to maintain a correct 14725 * tail pointer because the contact is always at the end. 14726 */ 14727 head = NULL; 14728 tail = head; 14729 /* 1st we pass through all the hops in any Record-Route headers */ 14730 for (;;) { 14731 /* Each Record-Route header */ 14732 int len = 0; 14733 const char *uri; 14734 rr = __get_header(req, "Record-Route", &start); 14735 if (*rr == '\0') { 14736 break; 14737 } 14738 while (!get_in_brackets_const(rr, &uri, &len)) { 14739 len++; 14740 rr = strchr(rr, ','); 14741 if(rr >= uri && rr < (uri + len)) { 14742 /* comma inside brackets*/ 14743 const char *next_br = strchr(rr, '<'); 14744 if (next_br && next_br < (uri + len)) { 14745 rr++; 14746 continue; 14747 } 14748 continue; 14749 } 14750 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 14751 ast_copy_string(thishop->hop, uri, len); 14752 ast_debug(2, "build_route: Record-Route hop: <%s>\n", thishop->hop); 14753 /* Link in */ 14754 if (backwards) { 14755 /* Link in at head so they end up in reverse order */ 14756 thishop->next = head; 14757 head = thishop; 14758 /* If this was the first then it'll be the tail */ 14759 if (!tail) { 14760 tail = thishop; 14761 } 14762 } else { 14763 thishop->next = NULL; 14764 /* Link in at the end */ 14765 if (tail) { 14766 tail->next = thishop; 14767 } else { 14768 head = thishop; 14769 } 14770 tail = thishop; 14771 } 14772 } 14773 rr = strchr(uri + len, ','); 14774 if (rr == NULL) { 14775 /* No more field-values, we're done with this header */ 14776 break; 14777 } 14778 /* Advance past comma */ 14779 rr++; 14780 } 14781 } 14782 14783 /* Only append the contact if we are dealing with a strict router */ 14784 if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop, ";lr") == NULL) ) { 14785 /* 2nd append the Contact: if there is one */ 14786 /* Can be multiple Contact headers, comma separated values - we just take the first */ 14787 char *contact = ast_strdupa(get_header(req, "Contact")); 14788 if (!ast_strlen_zero(contact)) { 14789 ast_debug(2, "build_route: Contact hop: %s\n", contact); 14790 /* Look for <: delimited address */ 14791 c = get_in_brackets(contact); 14792 len = strlen(c) + 1; 14793 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 14794 /* ast_calloc is not needed because all fields are initialized in this block */ 14795 ast_copy_string(thishop->hop, c, len); 14796 thishop->next = NULL; 14797 /* Goes at the end */ 14798 if (tail) { 14799 tail->next = thishop; 14800 } else { 14801 head = thishop; 14802 } 14803 } 14804 } 14805 } 14806 14807 /* Store as new route */ 14808 p->route = head; 14809 14810 /* For debugging dump what we ended up with */ 14811 if (sip_debug_test_pvt(p)) { 14812 list_route(p->route); 14813 } 14814 }
| static void build_via | ( | struct sip_pvt * | p | ) | [static] |
Build a Via header for a request.
Definition at line 3568 of file chan_sip.c.
References ast_sockaddr_stringify_remote(), ast_test_flag, and get_transport_pvt().
Referenced by __sip_subscribe_mwi_do(), reqprep(), sip_alloc(), sip_cli_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_invite(), transmit_register(), and transmit_response_using_temp().
03569 { 03570 /* Work around buggy UNIDEN UIP200 firmware */ 03571 const char *rport = (ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT) || ast_test_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT)) ? ";rport" : ""; 03572 03573 /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ 03574 snprintf(p->via, sizeof(p->via), "SIP/2.0/%s %s;branch=z9hG4bK%08x%s", 03575 get_transport_pvt(p), 03576 ast_sockaddr_stringify_remote(&p->ourip), 03577 (unsigned)p->branch, rport); 03578 }
| static int cb_extensionstate | ( | char * | context, | |
| char * | exten, | |||
| int | state, | |||
| void * | data | |||
| ) | [static] |
Callback for the devicestate notification (SUBSCRIBE) support subsystem.
Definition at line 15096 of file chan_sip.c.
References append_history, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_REMOVED, ast_extension_state2str(), ast_set_flag, ast_test_flag, ast_verb, FALSE, NONE, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), and transmit_state_notify().
Referenced by dialog_unlink_all(), handle_request_subscribe(), and handle_response_notify().
15097 { 15098 struct sip_pvt *p = data; 15099 15100 sip_pvt_lock(p); 15101 15102 switch(state) { 15103 case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ 15104 case AST_EXTENSION_REMOVED: /* Extension is gone */ 15105 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); /* Delete subscription in 32 secs */ 15106 ast_verb(2, "Extension state: Watcher for hint %s %s. Notify User %s\n", exten, state == AST_EXTENSION_DEACTIVATED ? "deactivated" : "removed", p->username); 15107 p->subscribed = NONE; 15108 append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated"); 15109 break; 15110 default: /* Tell user */ 15111 p->laststate = state; 15112 break; 15113 } 15114 if (p->subscribed != NONE) { /* Only send state NOTIFY if we know the format */ 15115 if (!p->pendinginvite) { 15116 transmit_state_notify(p, state, 1, FALSE); 15117 } else { 15118 /* We already have a NOTIFY sent that is not answered. Queue the state up. 15119 if many state changes happen meanwhile, we will only send a notification of the last one */ 15120 ast_set_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 15121 } 15122 } 15123 ast_verb(2, "Extension Changed %s[%s] new state %s for Notify User %s %s\n", exten, context, ast_extension_state2str(state), p->username, 15124 ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE) ? "(queued)" : ""); 15125 15126 sip_pvt_unlock(p); 15127 15128 return 0; 15129 }
| static void cb_extensionstate_destroy | ( | int | id, | |
| void * | data | |||
| ) | [static] |
Definition at line 15086 of file chan_sip.c.
Referenced by handle_request_subscribe().
| static void cc_epa_destructor | ( | void * | data | ) | [static] |
Definition at line 880 of file chan_sip.c.
References ast_free.
00881 { 00882 struct sip_epa_entry *epa_entry = data; 00883 struct cc_epa_entry *cc_entry = epa_entry->instance_data; 00884 ast_free(cc_entry); 00885 }
| static void cc_handle_publish_error | ( | struct sip_pvt * | pvt, | |
| const int | resp, | |||
| struct sip_request * | req, | |||
| struct sip_epa_entry * | epa_entry | |||
| ) | [static] |
Definition at line 20555 of file chan_sip.c.
References ao2_callback, ao2_ref, ast_cc_monitor_failed(), ast_log(), ast_strlen_zero(), FALSE, find_sip_monitor_instance_by_suspension_entry(), get_header(), LOG_WARNING, and transmit_invite().
20556 { 20557 struct cc_epa_entry *cc_entry = epa_entry->instance_data; 20558 struct sip_monitor_instance *monitor_instance = ao2_callback(sip_monitor_instances, 0, 20559 find_sip_monitor_instance_by_suspension_entry, epa_entry); 20560 const char *min_expires; 20561 20562 if (!monitor_instance) { 20563 ast_log(LOG_WARNING, "Can't find monitor_instance corresponding to epa_entry %p.\n", epa_entry); 20564 return; 20565 } 20566 20567 if (resp != 423) { 20568 ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->device_name, 20569 "Received error response to our PUBLISH"); 20570 ao2_ref(monitor_instance, -1); 20571 return; 20572 } 20573 20574 /* Allrighty, the other end doesn't like our Expires value. They think it's 20575 * too small, so let's see if they've provided a more sensible value. If they 20576 * haven't, then we'll just double our Expires value and see if they like that 20577 * instead. 20578 * 20579 * XXX Ideally this logic could be placed into its own function so that SUBSCRIBE, 20580 * PUBLISH, and REGISTER could all benefit from the same shared code. 20581 */ 20582 min_expires = get_header(req, "Min-Expires"); 20583 if (ast_strlen_zero(min_expires)) { 20584 pvt->expiry *= 2; 20585 if (pvt->expiry < 0) { 20586 /* You dork! You overflowed! */ 20587 ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->device_name, 20588 "PUBLISH expiry overflowed"); 20589 ao2_ref(monitor_instance, -1); 20590 return; 20591 } 20592 } else if (sscanf(min_expires, "%d", &pvt->expiry) != 1) { 20593 ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->device_name, 20594 "Min-Expires has non-numeric value"); 20595 ao2_ref(monitor_instance, -1); 20596 return; 20597 } 20598 /* At this point, we have most certainly changed pvt->expiry, so try transmitting 20599 * again 20600 */ 20601 transmit_invite(pvt, SIP_PUBLISH, FALSE, 0, NULL); 20602 ao2_ref(monitor_instance, -1); 20603 }
| static void change_callid_pvt | ( | struct sip_pvt * | pvt, | |
| const char * | callid | |||
| ) | [static] |
Definition at line 7898 of file chan_sip.c.
References ao2_lock, ao2_t_link, ao2_unlock, ast_debug, ast_strdupa, ast_string_field_set, build_callid_pvt(), and CONTAINER_UNLINK.
Referenced by __sip_subscribe_mwi_do(), create_addr_from_peer(), sip_cli_notify(), sip_poke_peer(), sip_request_call(), and sip_send_mwi_to_peer().
07899 { 07900 int in_dialog_container; 07901 char *oldid = ast_strdupa(pvt->callid); 07902 07903 ao2_lock(dialogs); 07904 in_dialog_container = CONTAINER_UNLINK(dialogs, pvt, 07905 "About to change the callid -- remove the old name"); 07906 if (callid) { 07907 ast_string_field_set(pvt, callid, callid); 07908 } else { 07909 build_callid_pvt(pvt); 07910 } 07911 if (in_dialog_container) { 07912 ao2_t_link(dialogs, pvt, "New dialog callid -- inserted back into table"); 07913 } 07914 ao2_unlock(dialogs); 07915 07916 if (strcmp(oldid, pvt->callid)) { 07917 ast_debug(1, "SIP call-id changed from '%s' to '%s'\n", oldid, pvt->callid); 07918 } 07919 }
| static void change_hold_state | ( | struct sip_pvt * | dialog, | |
| struct sip_request * | req, | |||
| int | holdstate, | |||
| int | sendonly | |||
| ) | [static] |
Change hold state for a call.
Definition at line 8987 of file chan_sip.c.
References append_history, ast_clear_flag, ast_set_flag, ast_str_buffer(), ast_test_flag, EVENT_FLAG_CALL, manager_event, sip_cfg, and sip_peer_hold().
Referenced by handle_request_invite(), and process_sdp().
08988 { 08989 if (sip_cfg.notifyhold && (!holdstate || !ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD))) 08990 sip_peer_hold(dialog, holdstate); 08991 if (sip_cfg.callevents) 08992 manager_event(EVENT_FLAG_CALL, "Hold", 08993 "Status: %s\r\n" 08994 "Channel: %s\r\n" 08995 "Uniqueid: %s\r\n", 08996 holdstate ? "On" : "Off", 08997 dialog->owner->name, 08998 dialog->owner->uniqueid); 08999 append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", ast_str_buffer(req->data)); 09000 if (!holdstate) { /* Put off remote hold */ 09001 ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */ 09002 return; 09003 } 09004 /* No address for RTP, we're on hold */ 09005 09006 /* Ensure hold flags are cleared so that overlapping flags do not conflict */ 09007 ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD); 09008 09009 if (sendonly == 1) /* One directional hold (sendonly/recvonly) */ 09010 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR); 09011 else if (sendonly == 2) /* Inactive stream */ 09012 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE); 09013 else 09014 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE); 09015 return; 09016 }
| static void change_redirecting_information | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| struct ast_party_redirecting * | redirecting, | |||
| struct ast_set_party_redirecting * | update_redirecting, | |||
| int | set_call_forward | |||
| ) | [static] |
update redirecting information for a channel based on headers
Definition at line 20284 of file chan_sip.c.
References ast_debug, ast_free, AST_REDIRECTING_REASON_UNCONDITIONAL, ast_strdup, ast_strlen_zero(), ast_party_redirecting::from, ast_set_party_redirecting::from, get_header(), get_name_and_number(), get_rdnis(), ast_party_id::name, ast_set_party_id::name, ast_party_id::number, ast_set_party_id::number, parse_moved_contact(), ast_party_redirecting::reason, ast_party_name::str, ast_party_number::str, ast_party_id::tag, ast_set_party_redirecting::to, ast_party_redirecting::to, ast_party_name::valid, and ast_party_number::valid.
Referenced by handle_request_invite(), handle_response(), and handle_response_invite().
20287 { 20288 char *redirecting_from_name = NULL; 20289 char *redirecting_from_number = NULL; 20290 char *redirecting_to_name = NULL; 20291 char *redirecting_to_number = NULL; 20292 int reason = AST_REDIRECTING_REASON_UNCONDITIONAL; 20293 int is_response = req->method == SIP_RESPONSE; 20294 int res = 0; 20295 20296 res = get_rdnis(p, req, &redirecting_from_name, &redirecting_from_number, &reason); 20297 if (res == -1) { 20298 if (is_response) { 20299 get_name_and_number(get_header(req, "TO"), &redirecting_from_name, &redirecting_from_number); 20300 } else { 20301 return; 20302 } 20303 } 20304 20305 /* At this point, all redirecting "from" info should be filled in appropriately 20306 * on to the "to" info 20307 */ 20308 20309 if (is_response) { 20310 parse_moved_contact(p, req, &redirecting_to_name, &redirecting_to_number, set_call_forward); 20311 } else { 20312 get_name_and_number(get_header(req, "TO"), &redirecting_to_name, &redirecting_to_number); 20313 } 20314 20315 if (!ast_strlen_zero(redirecting_from_number)) { 20316 ast_debug(3, "Got redirecting from number %s\n", redirecting_from_number); 20317 update_redirecting->from.number = 1; 20318 redirecting->from.number.valid = 1; 20319 ast_free(redirecting->from.number.str); 20320 redirecting->from.number.str = redirecting_from_number; 20321 } 20322 if (!ast_strlen_zero(redirecting_from_name)) { 20323 ast_debug(3, "Got redirecting from name %s\n", redirecting_from_name); 20324 update_redirecting->from.name = 1; 20325 redirecting->from.name.valid = 1; 20326 ast_free(redirecting->from.name.str); 20327 redirecting->from.name.str = redirecting_from_name; 20328 } 20329 if (!ast_strlen_zero(p->cid_tag)) { 20330 ast_free(redirecting->from.tag); 20331 redirecting->from.tag = ast_strdup(p->cid_tag); 20332 ast_free(redirecting->to.tag); 20333 redirecting->to.tag = ast_strdup(p->cid_tag); 20334 } 20335 if (!ast_strlen_zero(redirecting_to_number)) { 20336 ast_debug(3, "Got redirecting to number %s\n", redirecting_to_number); 20337 update_redirecting->to.number = 1; 20338 redirecting->to.number.valid = 1; 20339 ast_free(redirecting->to.number.str); 20340 redirecting->to.number.str = redirecting_to_number; 20341 } 20342 if (!ast_strlen_zero(redirecting_to_name)) { 20343 ast_debug(3, "Got redirecting to name %s\n", redirecting_from_number); 20344 update_redirecting->to.name = 1; 20345 redirecting->to.name.valid = 1; 20346 ast_free(redirecting->to.name.str); 20347 redirecting->to.name.str = redirecting_to_name; 20348 } 20349 redirecting->reason = reason; 20350 }
| static void change_t38_state | ( | struct sip_pvt * | p, | |
| int | state | |||
| ) | [static] |
Change the T38 state on a SIP dialog.
Definition at line 5341 of file chan_sip.c.
References AST_CONTROL_T38_PARAMETERS, ast_debug, ast_queue_control_data(), AST_T38_NEGOTIATED, AST_T38_REFUSED, AST_T38_REQUEST_NEGOTIATE, AST_T38_TERMINATED, ast_udptl_get_far_max_ifp(), ast_udptl_set_tag(), ast_control_t38_parameters::max_ifp, and ast_control_t38_parameters::request_response.
Referenced by handle_response_invite(), interpret_t38_parameters(), process_sdp(), and sip_t38_abort().
05342 { 05343 int old = p->t38.state; 05344 struct ast_channel *chan = p->owner; 05345 struct ast_control_t38_parameters parameters = { .request_response = 0 }; 05346 05347 /* Don't bother changing if we are already in the state wanted */ 05348 if (old == state) 05349 return; 05350 05351 p->t38.state = state; 05352 ast_debug(2, "T38 state changed to %u on channel %s\n", p->t38.state, chan ? chan->name : "<none>"); 05353 05354 /* If no channel was provided we can't send off a control frame */ 05355 if (!chan) 05356 return; 05357 05358 /* Given the state requested and old state determine what control frame we want to queue up */ 05359 switch (state) { 05360 case T38_PEER_REINVITE: 05361 parameters = p->t38.their_parms; 05362 parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl); 05363 parameters.request_response = AST_T38_REQUEST_NEGOTIATE; 05364 ast_udptl_set_tag(p->udptl, "%s", chan->name); 05365 break; 05366 case T38_ENABLED: 05367 parameters = p->t38.their_parms; 05368 parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl); 05369 parameters.request_response = AST_T38_NEGOTIATED; 05370 ast_udptl_set_tag(p->udptl, "%s", chan->name); 05371 break; 05372 case T38_DISABLED: 05373 if (old == T38_ENABLED) { 05374 parameters.request_response = AST_T38_TERMINATED; 05375 } else if (old == T38_LOCAL_REINVITE) { 05376 parameters.request_response = AST_T38_REFUSED; 05377 } 05378 break; 05379 case T38_LOCAL_REINVITE: 05380 /* wait until we get a peer response before responding to local reinvite */ 05381 break; 05382 } 05383 05384 /* Woot we got a message, create a control frame and send it on! */ 05385 if (parameters.request_response) 05386 ast_queue_control_data(chan, AST_CONTROL_T38_PARAMETERS, ¶meters, sizeof(parameters)); 05387 }
| static enum check_auth_result check_auth | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| const char * | username, | |||
| const char * | secret, | |||
| const char * | md5secret, | |||
| int | sipmethod, | |||
| const char * | uri, | |||
| enum xmittype | reliable, | |||
| int | ignore | |||
| ) | [static] |
Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set).
XXX
XXX
Definition at line 14838 of file chan_sip.c.
References append_history, ast_copy_string(), AST_DYNSTR_BUILD_FAILED, ast_log(), ast_md5_hash(), ast_skip_blanks(), ast_str_set(), ast_str_thread_get(), ast_strlen_zero(), auth_headers(), BOGUS_PEER_MD5SECRET, CHECK_AUTH_BUF_INITLEN, FALSE, get_header(), LOG_NOTICE, LOG_WARNING, S_OR, set_nonce_randdata(), sip_methods, sip_scheddestroy(), text, transmit_response_with_auth(), and TRUE.
Referenced by check_peer_ok(), and register_verify().
14841 { 14842 const char *response; 14843 char *reqheader, *respheader; 14844 const char *authtoken; 14845 char a1_hash[256]; 14846 char resp_hash[256]=""; 14847 char *c; 14848 int is_bogus_peer = 0; 14849 int wrongnonce = FALSE; 14850 int good_response; 14851 const char *usednonce = p->randdata; 14852 struct ast_str *buf; 14853 int res; 14854 14855 /* table of recognised keywords, and their value in the digest */ 14856 enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST }; 14857 struct x { 14858 const char *key; 14859 const char *s; 14860 } *i, keys[] = { 14861 [K_RESP] = { "response=", "" }, 14862 [K_URI] = { "uri=", "" }, 14863 [K_USER] = { "username=", "" }, 14864 [K_NONCE] = { "nonce=", "" }, 14865 [K_LAST] = { NULL, NULL} 14866 }; 14867 14868 /* Always OK if no secret */ 14869 if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret)) 14870 return AUTH_SUCCESSFUL; 14871 14872 /* Always auth with WWW-auth since we're NOT a proxy */ 14873 /* Using proxy-auth in a B2BUA may block proxy authorization in the same transaction */ 14874 response = "401 Unauthorized"; 14875 14876 /* 14877 * Note the apparent swap of arguments below, compared to other 14878 * usages of auth_headers(). 14879 */ 14880 auth_headers(WWW_AUTH, &respheader, &reqheader); 14881 14882 authtoken = get_header(req, reqheader); 14883 if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 14884 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 14885 information */ 14886 if (!reliable) { 14887 /* Resend message if this was NOT a reliable delivery. Otherwise the 14888 retransmission should get it */ 14889 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 14890 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 14891 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14892 } 14893 return AUTH_CHALLENGE_SENT; 14894 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 14895 /* We have no auth, so issue challenge and request authentication */ 14896 set_nonce_randdata(p, 1); /* Create nonce for challenge */ 14897 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 14898 /* Schedule auto destroy in 32 seconds */ 14899 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14900 return AUTH_CHALLENGE_SENT; 14901 } 14902 14903 /* --- We have auth, so check it */ 14904 14905 /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting 14906 an example in the spec of just what it is you're doing a hash on. */ 14907 14908 if (!(buf = ast_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) { 14909 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 14910 } 14911 14912 /* Make a copy of the response and parse it */ 14913 res = ast_str_set(&buf, 0, "%s", authtoken); 14914 14915 if (res == AST_DYNSTR_BUILD_FAILED) { 14916 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 14917 } 14918 14919 c = buf->str; 14920 14921 while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */ 14922 for (i = keys; i->key != NULL; i++) { 14923 const char *separator = ","; /* default */ 14924 14925 if (strncasecmp(c, i->key, strlen(i->key)) != 0) { 14926 continue; 14927 } 14928 /* Found. Skip keyword, take text in quotes or up to the separator. */ 14929 c += strlen(i->key); 14930 if (*c == '"') { /* in quotes. Skip first and look for last */ 14931 c++; 14932 separator = "\""; 14933 } 14934 i->s = c; 14935 strsep(&c, separator); 14936 break; 14937 } 14938 if (i->key == NULL) { /* not found, jump after space or comma */ 14939 strsep(&c, " ,"); 14940 } 14941 } 14942 14943 /* We cannot rely on the bogus_peer having a bad md5 value. Someone could 14944 * use it to construct valid auth. */ 14945 if (md5secret && strcmp(md5secret, BOGUS_PEER_MD5SECRET) == 0) { 14946 is_bogus_peer = 1; 14947 } 14948 14949 /* Verify that digest username matches the username we auth as */ 14950 if (strcmp(username, keys[K_USER].s) && !is_bogus_peer) { 14951 ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n", 14952 username, keys[K_USER].s); 14953 /* Oops, we're trying something here */ 14954 return AUTH_USERNAME_MISMATCH; 14955 } 14956 14957 /* Verify nonce from request matches our nonce, and the nonce has not already been responded to. 14958 * If this check fails, send 401 with new nonce */ 14959 if (strcasecmp(p->randdata, keys[K_NONCE].s) || p->stalenonce) { /* XXX it was 'n'casecmp ? */ 14960 wrongnonce = TRUE; 14961 usednonce = keys[K_NONCE].s; 14962 } else { 14963 p->stalenonce = 1; /* now, since the nonce has a response, mark it as stale so it can't be sent or responded to again */ 14964 } 14965 14966 if (!ast_strlen_zero(md5secret)) { 14967 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 14968 } else { 14969 char a1[256]; 14970 14971 snprintf(a1, sizeof(a1), "%s:%s:%s", username, p->realm, secret); 14972 ast_md5_hash(a1_hash, a1); 14973 } 14974 14975 /* compute the expected response to compare with what we received */ 14976 { 14977 char a2[256]; 14978 char a2_hash[256]; 14979 char resp[256]; 14980 14981 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, 14982 S_OR(keys[K_URI].s, uri)); 14983 ast_md5_hash(a2_hash, a2); 14984 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash); 14985 ast_md5_hash(resp_hash, resp); 14986 } 14987 14988 good_response = keys[K_RESP].s && 14989 !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash)) && 14990 !is_bogus_peer; /* lastly, check that the peer isn't the fake peer */ 14991 if (wrongnonce) { 14992 if (good_response) { 14993 if (sipdebug) 14994 ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "From")); 14995 /* We got working auth token, based on stale nonce . */ 14996 set_nonce_randdata(p, 0); 14997 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE); 14998 } else { 14999 /* Everything was wrong, so give the device one more try with a new challenge */ 15000 if (!req->ignore) { 15001 if (sipdebug) { 15002 ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To")); 15003 } 15004 set_nonce_randdata(p, 1); 15005 } else { 15006 if (sipdebug) { 15007 ast_log(LOG_NOTICE, "Duplicate authentication received from '%s'\n", get_header(req, "To")); 15008 } 15009 } 15010 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 15011 } 15012 15013 /* Schedule auto destroy in 32 seconds */ 15014 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15015 return AUTH_CHALLENGE_SENT; 15016 } 15017 if (good_response) { 15018 append_history(p, "AuthOK", "Auth challenge successful for %s", username); 15019 return AUTH_SUCCESSFUL; 15020 } 15021 15022 /* Ok, we have a bad username/secret pair */ 15023 /* Tell the UAS not to re-send this authentication data, because 15024 it will continue to fail 15025 */ 15026 15027 return AUTH_SECRET_FAILED; 15028 }
| static enum message_integrity check_message_integrity | ( | struct ast_str ** | request, | |
| struct ast_str ** | overflow | |||
| ) | [static] |
Check that a message received over TCP is a full message.
This will take the information read in and then determine if 1) The message is a full SIP request 2) The message is a partial SIP request 3) The message contains a full SIP request along with another partial request
| data | The unparsed incoming SIP message. | |
| request | The resulting request with extra fragments removed. | |
| overflow | If the message contains more than a full request, this is the remainder of the message |
Definition at line 2592 of file chan_sip.c.
References ast_str_append(), ast_str_buffer(), ast_str_strlen(), ast_str_truncate(), MESSAGE_COMPLETE, MESSAGE_FRAGMENT, MESSAGE_FRAGMENT_COMPLETE, MESSAGE_INVALID, and read_raw_content_length().
Referenced by sip_tcptls_read().
02593 { 02594 char *message = ast_str_buffer(*request); 02595 char *body; 02596 int content_length; 02597 int message_len = ast_str_strlen(*request); 02598 int body_len; 02599 02600 /* Important pieces to search for in a SIP request are \r\n\r\n. This 02601 * marks either 02602 * 1) The division between the headers and body 02603 * 2) The end of the SIP request 02604 */ 02605 body = strstr(message, "\r\n\r\n"); 02606 if (!body) { 02607 /* This is clearly a partial message since we haven't reached an end 02608 * yet. 02609 */ 02610 return MESSAGE_FRAGMENT; 02611 } 02612 body += sizeof("\r\n\r\n") - 1; 02613 body_len = message_len - (body - message); 02614 02615 body[-1] = '\0'; 02616 content_length = read_raw_content_length(message); 02617 body[-1] = '\n'; 02618 02619 if (content_length < 0) { 02620 return MESSAGE_INVALID; 02621 } else if (content_length == 0) { 02622 /* We've definitely received an entire message. We need 02623 * to check if there's also a fragment of another message 02624 * in addition. 02625 */ 02626 if (body_len == 0) { 02627 return MESSAGE_COMPLETE; 02628 } else { 02629 ast_str_append(overflow, 0, "%s", body); 02630 ast_str_truncate(*request, message_len - body_len); 02631 return MESSAGE_FRAGMENT_COMPLETE; 02632 } 02633 } 02634 /* Positive content length. Let's see what sort of 02635 * message body we're dealing with. 02636 */ 02637 if (body_len < content_length) { 02638 /* We don't have the full message body yet */ 02639 return MESSAGE_FRAGMENT; 02640 } else if (body_len > content_length) { 02641 /* We have the full message plus a fragment of a further 02642 * message 02643 */ 02644 ast_str_append(overflow, 0, "%s", body + content_length); 02645 ast_str_truncate(*request, message_len - (body_len - content_length)); 02646 return MESSAGE_FRAGMENT_COMPLETE; 02647 } else { 02648 /* Yay! Full message with no extra content */ 02649 return MESSAGE_COMPLETE; 02650 } 02651 }
| static enum check_auth_result check_peer_ok | ( | struct sip_pvt * | p, | |
| char * | of, | |||
| struct sip_request * | req, | |||
| int | sipmethod, | |||
| struct ast_sockaddr * | addr, | |||
| struct sip_peer ** | authpeer, | |||
| enum xmittype | reliable, | |||
| char * | calleridname, | |||
| char * | uri2 | |||
| ) | [static] |
Validate device authentication.
Definition at line 16510 of file chan_sip.c.
References accountcode, ao2_t_ref, ast_apply_ha(), ast_cc_copy_config_params(), ast_copy_flags, ast_debug, ast_is_shrinkable_phonenumber(), ast_rtp_codecs_packetization_set(), AST_RTP_DTMF, ast_rtp_instance_get_codecs(), ast_set_flag, ast_shrink_phone_number(), ast_sockaddr_stringify(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_variables_destroy(), ast_verbose, check_auth(), cid_name, cid_num, context, copy_vars(), dialog_initialize_rtp(), do_setnat(), FALSE, find_peer(), get_rpid(), language, mohinterpret, mohsuggest, parkinglot, ref_peer(), set_pvt_allowed_methods(), set_t38_capabilities(), sip_cfg, sip_debug_test_addr(), TRUE, and unref_peer().
Referenced by check_user_full().
16514 { 16515 enum check_auth_result res; 16516 int debug = sip_debug_test_addr(addr); 16517 struct sip_peer *peer; 16518 16519 if (sipmethod == SIP_SUBSCRIBE) { 16520 /* For subscribes, match on device name only; for other methods, 16521 * match on IP address-port of the incoming request. 16522 */ 16523 peer = find_peer(of, NULL, TRUE, FINDALLDEVICES, FALSE, 0); 16524 } else { 16525 /* First find devices based on username (avoid all type=peer's) */ 16526 peer = find_peer(of, NULL, TRUE, FINDUSERS, FALSE, 0); 16527 16528 /* Then find devices based on IP */ 16529 if (!peer) { 16530 peer = find_peer(NULL, &p->recv, TRUE, FINDPEERS, FALSE, p->socket.type); 16531 } 16532 } 16533 16534 if (!peer) { 16535 if (debug) { 16536 ast_verbose("No matching peer for '%s' from '%s'\n", 16537 of, ast_sockaddr_stringify(&p->recv)); 16538 } 16539 16540 /* If you don't mind, we can return 404s for devices that do 16541 * not exist: username disclosure. If we allow guests, there 16542 * is no way around that. */ 16543 if (sip_cfg.allowguest || !sip_cfg.alwaysauthreject) { 16544 return AUTH_DONT_KNOW; 16545 } 16546 16547 /* If you do mind, we use a peer that will never authenticate. 16548 * This ensures that we follow the same code path as regular 16549 * auth: less chance for username disclosure. */ 16550 peer = bogus_peer; 16551 ref_peer(peer, "ref_peer: check_peer_ok: must ref bogus_peer so unreffing it does not fail"); 16552 } 16553 16554 if (!ast_apply_ha(peer->ha, addr)) { 16555 ast_debug(2, "Found peer '%s' for '%s', but fails host access\n", peer->name, of); 16556 unref_peer(peer, "unref_peer: check_peer_ok: from find_peer call, early return of AUTH_ACL_FAILED"); 16557 return AUTH_ACL_FAILED; 16558 } 16559 if (debug && peer != bogus_peer) { 16560 ast_verbose("Found peer '%s' for '%s' from %s\n", 16561 peer->name, of, ast_sockaddr_stringify(&p->recv)); 16562 } 16563 16564 /* XXX what about p->prefs = peer->prefs; ? */ 16565 /* Set Frame packetization */ 16566 if (p->rtp) { 16567 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &peer->prefs); 16568 p->autoframing = peer->autoframing; 16569 } 16570 16571 /* Take the peer */ 16572 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 16573 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 16574 ast_copy_flags(&p->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY); 16575 16576 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) && p->udptl) { 16577 p->t38_maxdatagram = peer->t38_maxdatagram; 16578 set_t38_capabilities(p); 16579 } 16580 16581 /* Copy SIP extensions profile to peer */ 16582 /* XXX is this correct before a successful auth ? */ 16583 if (p->sipoptions) 16584 peer->sipoptions = p->sipoptions; 16585 16586 do_setnat(p); 16587 16588 ast_string_field_set(p, peersecret, peer->secret); 16589 ast_string_field_set(p, peermd5secret, peer->md5secret); 16590 ast_string_field_set(p, subscribecontext, peer->subscribecontext); 16591 ast_string_field_set(p, mohinterpret, peer->mohinterpret); 16592 ast_string_field_set(p, mohsuggest, peer->mohsuggest); 16593 if (!ast_strlen_zero(peer->parkinglot)) { 16594 ast_string_field_set(p, parkinglot, peer->parkinglot); 16595 } 16596 ast_string_field_set(p, engine, peer->engine); 16597 p->disallowed_methods = peer->disallowed_methods; 16598 set_pvt_allowed_methods(p, req); 16599 ast_cc_copy_config_params(p->cc_params, peer->cc_params); 16600 if (peer->callingpres) /* Peer calling pres setting will override RPID */ 16601 p->callingpres = peer->callingpres; 16602 if (peer->maxms && peer->lastms) 16603 p->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 16604 else 16605 p->timer_t1 = peer->timer_t1; 16606 16607 /* Set timer B to control transaction timeouts */ 16608 if (peer->timer_b) 16609 p->timer_b = peer->timer_b; 16610 else 16611 p->timer_b = 64 * p->timer_t1; 16612 16613 p->allowtransfer = peer->allowtransfer; 16614 16615 if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) { 16616 /* Pretend there is no required authentication */ 16617 ast_string_field_set(p, peersecret, NULL); 16618 ast_string_field_set(p, peermd5secret, NULL); 16619 } 16620 if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, req->ignore))) { 16621 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 16622 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 16623 ast_copy_flags(&p->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY); 16624 /* If we have a call limit, set flag */ 16625 if (peer->call_limit) 16626 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 16627 ast_string_field_set(p, peername, peer->name); 16628 ast_string_field_set(p, authname, peer->name); 16629 16630 if (sipmethod == SIP_INVITE) { 16631 /* destroy old channel vars and copy in new ones. */ 16632 ast_variables_destroy(p->chanvars); 16633 p->chanvars = copy_vars(peer->chanvars); 16634 } 16635 16636 if (authpeer) { 16637 ao2_t_ref(peer, 1, "copy pointer into (*authpeer)"); 16638 (*authpeer) = peer; /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */ 16639 } 16640 16641 if (!ast_strlen_zero(peer->username)) { 16642 ast_string_field_set(p, username, peer->username); 16643 /* Use the default username for authentication on outbound calls */ 16644 /* XXX this takes the name from the caller... can we override ? */ 16645 ast_string_field_set(p, authname, peer->username); 16646 } 16647 if (!get_rpid(p, req)) { 16648 if (!ast_strlen_zero(peer->cid_num)) { 16649 char *tmp = ast_strdupa(peer->cid_num); 16650 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) 16651 ast_shrink_phone_number(tmp); 16652 ast_string_field_set(p, cid_num, tmp); 16653 } 16654 if (!ast_strlen_zero(peer->cid_name)) 16655 ast_string_field_set(p, cid_name, peer->cid_name); 16656 if (peer->callingpres) 16657 p->callingpres = peer->callingpres; 16658 } 16659 if (!ast_strlen_zero(peer->cid_tag)) { 16660 ast_string_field_set(p, cid_tag, peer->cid_tag); 16661 } 16662 ast_string_field_set(p, fullcontact, peer->fullcontact); 16663 16664 if (!ast_strlen_zero(peer->context)) { 16665 ast_string_field_set(p, context, peer->context); 16666 } 16667 if (!ast_strlen_zero(peer->mwi_from)) { 16668 ast_string_field_set(p, mwi_from, peer->mwi_from); 16669 } 16670 16671 ast_string_field_set(p, peersecret, peer->secret); 16672 ast_string_field_set(p, peermd5secret, peer->md5secret); 16673 ast_string_field_set(p, language, peer->language); 16674 ast_string_field_set(p, accountcode, peer->accountcode); 16675 p->amaflags = peer->amaflags; 16676 p->callgroup = peer->callgroup; 16677 p->pickupgroup = peer->pickupgroup; 16678 p->capability = peer->capability; 16679 p->prefs = peer->prefs; 16680 p->jointcapability = peer->capability; 16681 if (peer->maxforwards > 0) { 16682 p->maxforwards = peer->maxforwards; 16683 } 16684 if (p->peercapability) 16685 p->jointcapability &= p->peercapability; 16686 p->maxcallbitrate = peer->maxcallbitrate; 16687 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 16688 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 16689 p->noncodeccapability |= AST_RTP_DTMF; 16690 else 16691 p->noncodeccapability &= ~AST_RTP_DTMF; 16692 p->jointnoncodeccapability = p->noncodeccapability; 16693 p->rtptimeout = peer->rtptimeout; 16694 p->rtpholdtimeout = peer->rtpholdtimeout; 16695 p->rtpkeepalive = peer->rtpkeepalive; 16696 if (!dialog_initialize_rtp(p)) { 16697 if (p->rtp) { 16698 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &peer->prefs); 16699 p->autoframing = peer->autoframing; 16700 } 16701 } else { 16702 res = AUTH_RTP_FAILED; 16703 } 16704 } 16705 unref_peer(peer, "check_peer_ok: unref_peer: tossing temp ptr to peer from find_peer"); 16706 return res; 16707 }
| static void check_pendings | ( | struct sip_pvt * | p | ) | [static] |
Check pending actions on SIP call.
Definition at line 20470 of file chan_sip.c.
References ast_clear_flag, ast_debug, AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), ast_test_flag, FALSE, sip_scheddestroy(), transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), and TRUE.
Referenced by handle_incoming(), handle_response_invite(), reinvite_timeout(), and sip_reinvite_retry().
20471 { 20472 if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 20473 if (p->reinviteid > -1) { 20474 /* Outstanding p->reinviteid timeout, so wait... */ 20475 return; 20476 } else if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) { 20477 /* if we can't BYE, then this is really a pending CANCEL */ 20478 p->invitestate = INV_CANCELLED; 20479 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 20480 /* If the cancel occurred on an initial invite, cancel the pending BYE */ 20481 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) { 20482 ast_clear_flag(&p->flags[0], SIP_PENDINGBYE); 20483 } 20484 /* Actually don't destroy us yet, wait for the 487 on our original 20485 INVITE, but do set an autodestruct just in case we never get it. */ 20486 } else { 20487 /* We have a pending outbound invite, don't send something 20488 * new in-transaction, unless it is a pending reinvite, then 20489 * by the time we are called here, we should probably just hang up. */ 20490 if (p->pendinginvite && !p->ongoing_reinvite) 20491 return; 20492 20493 if (p->owner) { 20494 ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV); 20495 } 20496 /* Perhaps there is an SD change INVITE outstanding */ 20497 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE); 20498 ast_clear_flag(&p->flags[0], SIP_PENDINGBYE); 20499 } 20500 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 20501 } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) { 20502 /* if we can't REINVITE, hold it for later */ 20503 if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) { 20504 ast_debug(2, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid); 20505 } else { 20506 ast_debug(2, "Sending pending reinvite on '%s'\n", p->callid); 20507 /* Didn't get to reinvite yet, so do it now */ 20508 transmit_reinvite_with_sdp(p, (p->t38.state == T38_LOCAL_REINVITE ? TRUE : FALSE), FALSE); 20509 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 20510 } 20511 } 20512 }
| static void check_rtp_timeout | ( | struct sip_pvt * | dialog, | |
| time_t | t | |||
| ) | [static] |
helper function for the monitoring thread -- seems to be called with the assumption that the dialog is locked
Do we need to move the lastrtptx to the RTP structure to have one for audio and one for video? It really does belong to the RTP structure.
Definition at line 26543 of file chan_sip.c.
References ast_channel_trylock, ast_channel_unlock, ast_log(), ast_rtp_instance_get_hold_timeout(), ast_rtp_instance_get_keepalive(), ast_rtp_instance_get_timeout(), ast_rtp_instance_sendcng(), ast_rtp_instance_set_hold_timeout(), ast_rtp_instance_set_timeout(), ast_sockaddr_isnull(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, ast_test_flag, and LOG_NOTICE.
Referenced by dialog_needdestroy().
26544 { 26545 /* If we have no RTP or no active owner, no need to check timers */ 26546 if (!dialog->rtp || !dialog->owner) 26547 return; 26548 /* If the call is not in UP state or redirected outside Asterisk, no need to check timers */ 26549 26550 if (dialog->owner->_state != AST_STATE_UP || !ast_sockaddr_isnull(&dialog->redirip)) 26551 return; 26552 26553 /* If the call is involved in a T38 fax session do not check RTP timeout */ 26554 if (dialog->t38.state == T38_ENABLED) 26555 return; 26556 26557 /* If we have no timers set, return now */ 26558 if (!ast_rtp_instance_get_keepalive(dialog->rtp) && !ast_rtp_instance_get_timeout(dialog->rtp) && !ast_rtp_instance_get_hold_timeout(dialog->rtp)) { 26559 return; 26560 } 26561 26562 /* Check AUDIO RTP keepalives */ 26563 if (dialog->lastrtptx && ast_rtp_instance_get_keepalive(dialog->rtp) && 26564 (t > dialog->lastrtptx + ast_rtp_instance_get_keepalive(dialog->rtp))) { 26565 /* Need to send an empty RTP packet */ 26566 dialog->lastrtptx = time(NULL); 26567 ast_rtp_instance_sendcng(dialog->rtp, 0); 26568 } 26569 26570 /*! \todo Check video RTP keepalives 26571 26572 Do we need to move the lastrtptx to the RTP structure to have one for audio and one 26573 for video? It really does belong to the RTP structure. 26574 */ 26575 26576 /* Check AUDIO RTP timers */ 26577 if (dialog->lastrtprx && (ast_rtp_instance_get_timeout(dialog->rtp) || ast_rtp_instance_get_hold_timeout(dialog->rtp)) && (t > dialog->lastrtprx + ast_rtp_instance_get_timeout(dialog->rtp))) { 26578 if (!ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD) || (ast_rtp_instance_get_hold_timeout(dialog->rtp) && (t > dialog->lastrtprx + ast_rtp_instance_get_hold_timeout(dialog->rtp)))) { 26579 /* Needs a hangup */ 26580 if (ast_rtp_instance_get_timeout(dialog->rtp)) { 26581 if (!dialog->owner || ast_channel_trylock(dialog->owner)) { 26582 /* 26583 * Don't block, just try again later. 26584 * If there was no owner, the call is dead already. 26585 */ 26586 return; 26587 } 26588 ast_log(LOG_NOTICE, "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", 26589 dialog->owner->name, (long) (t - dialog->lastrtprx)); 26590 /* Issue a softhangup */ 26591 ast_softhangup_nolock(dialog->owner, AST_SOFTHANGUP_DEV); 26592 ast_channel_unlock(dialog->owner); 26593 /* forget the timeouts for this call, since a hangup 26594 has already been requested and we don't want to 26595 repeatedly request hangups 26596 */ 26597 ast_rtp_instance_set_timeout(dialog->rtp, 0); 26598 ast_rtp_instance_set_hold_timeout(dialog->rtp, 0); 26599 if (dialog->vrtp) { 26600 ast_rtp_instance_set_timeout(dialog->vrtp, 0); 26601 ast_rtp_instance_set_hold_timeout(dialog->vrtp, 0); 26602 } 26603 } 26604 } 26605 } 26606 }
| static int check_sip_domain | ( | const char * | domain, | |
| char * | context, | |||
| size_t | len | |||
| ) | [static] |
check_sip_domain: Check if domain part of uri is local to our server
Definition at line 27753 of file chan_sip.c.
References ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_strlen_zero().
Referenced by func_check_sipdomain(), get_destination(), get_realm(), handle_request_refer(), and register_verify().
27754 { 27755 struct domain *d; 27756 int result = 0; 27757 27758 AST_LIST_LOCK(&domain_list); 27759 AST_LIST_TRAVERSE(&domain_list, d, list) { 27760 if (strcasecmp(d->domain, domain)) { 27761 continue; 27762 } 27763 27764 if (len && !ast_strlen_zero(d->context)) 27765 ast_copy_string(context, d->context, len); 27766 27767 result = 1; 27768 break; 27769 } 27770 AST_LIST_UNLOCK(&domain_list); 27771 27772 return result; 27773 }
| static int check_user | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| int | sipmethod, | |||
| const char * | uri, | |||
| enum xmittype | reliable, | |||
| struct ast_sockaddr * | addr | |||
| ) | [static] |
Find user If we get a match, this will add a reference pointer to the user object in ASTOBJ, that needs to be unreferenced.
Definition at line 16846 of file chan_sip.c.
References check_user_full().
Referenced by handle_request_options(), and handle_request_publish().
16847 { 16848 return check_user_full(p, req, sipmethod, uri, reliable, addr, NULL); 16849 }
| static enum check_auth_result check_user_full | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| int | sipmethod, | |||
| const char * | uri, | |||
| enum xmittype | reliable, | |||
| struct ast_sockaddr * | addr, | |||
| struct sip_peer ** | authpeer | |||
| ) | [static] |
Check if matching user or peer is defined Match user on From: user name and peer on IP/port This is used on first invite (not re-invites) and subscribe requests.
Definition at line 16715 of file chan_sip.c.
References ast_free, ast_is_shrinkable_phonenumber(), ast_log(), ast_set_flag, ast_shrink_phone_number(), ast_strdup, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, build_contact(), check_peer_ok(), cid_name, cid_num, dialog_initialize_rtp(), exten, extract_host_from_hostport(), get_calleridname(), get_header(), get_in_brackets(), get_rpid(), LOG_ERROR, LOG_NOTICE, name, parse_uri_legacy_check(), RAII_VAR, sip_cfg, SIP_PEDANTIC_DECODE, and terminate_uri().
Referenced by check_user(), handle_request_invite(), and handle_request_subscribe().
16718 { 16719 char *of, *name, *unused_password, *domain; 16720 RAII_VAR(char *, ofbuf, NULL, ast_free); /* beware, everyone starts pointing to this */ 16721 RAII_VAR(char *, namebuf, NULL, ast_free); 16722 enum check_auth_result res = AUTH_DONT_KNOW; 16723 char calleridname[256]; 16724 char *uri2 = ast_strdupa(uri); 16725 16726 terminate_uri(uri2); /* trim extra stuff */ 16727 16728 ofbuf = ast_strdup(get_header(req, "From")); 16729 /* XXX here tries to map the username for invite things */ 16730 16731 /* strip the display-name portion off the beginning of the FROM header. */ 16732 if (!(of = (char *) get_calleridname(ofbuf, calleridname, sizeof(calleridname)))) { 16733 ast_log(LOG_ERROR, "FROM header can not be parsed\n"); 16734 return res; 16735 } 16736 16737 if (calleridname[0]) { 16738 ast_string_field_set(p, cid_name, calleridname); 16739 } 16740 16741 if (ast_strlen_zero(p->exten)) { 16742 char *t = uri2; 16743 if (!strncasecmp(t, "sip:", 4)) 16744 t+= 4; 16745 else if (!strncasecmp(t, "sips:", 5)) 16746 t += 5; 16747 ast_string_field_set(p, exten, t); 16748 t = strchr(p->exten, '@'); 16749 if (t) 16750 *t = '\0'; 16751 16752 if (ast_strlen_zero(p->our_contact)) 16753 build_contact(p); 16754 } 16755 16756 of = get_in_brackets(of); 16757 16758 /* save the URI part of the From header */ 16759 ast_string_field_set(p, from, of); 16760 16761 if (parse_uri_legacy_check(of, "sip:,sips:", &name, &unused_password, &domain, NULL)) { 16762 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 16763 } 16764 16765 SIP_PEDANTIC_DECODE(name); 16766 SIP_PEDANTIC_DECODE(domain); 16767 16768 extract_host_from_hostport(&domain); 16769 16770 if (ast_strlen_zero(domain)) { 16771 /* <sip:name@[EMPTY]>, never good */ 16772 ast_log(LOG_ERROR, "Empty domain name in FROM header\n"); 16773 return res; 16774 } 16775 16776 if (ast_strlen_zero(name)) { 16777 /* <sip:[EMPTY][@]hostport>. Asterisk 1.4 and 1.6 have always 16778 * treated that as a username, so we continue the tradition: 16779 * uri is now <sip:host@hostport>. */ 16780 name = domain; 16781 } else { 16782 /* Non-empty name, try to get caller id from it */ 16783 char *tmp = ast_strdupa(name); 16784 /* We need to be able to handle from-headers looking like 16785 <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43> 16786 */ 16787 tmp = strsep(&tmp, ";"); 16788 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) { 16789 ast_shrink_phone_number(tmp); 16790 } 16791 ast_string_field_set(p, cid_num, tmp); 16792 } 16793 16794 if (global_match_auth_username) { 16795 /* 16796 * XXX This is experimental code to grab the search key from the 16797 * Auth header's username instead of the 'From' name, if available. 16798 * Do not enable this block unless you understand the side effects (if any!) 16799 * Note, the search for "username" should be done in a more robust way. 16800 * Note2, at the moment we check both fields, though maybe we should 16801 * pick one or another depending on the request ? XXX 16802 */ 16803 const char *hdr = get_header(req, "Authorization"); 16804 if (ast_strlen_zero(hdr)) { 16805 hdr = get_header(req, "Proxy-Authorization"); 16806 } 16807 16808 if (!ast_strlen_zero(hdr) && (hdr = strstr(hdr, "username=\""))) { 16809 namebuf = name = ast_strdup(hdr + strlen("username=\"")); 16810 name = strsep(&name, "\""); 16811 } 16812 } 16813 16814 res = check_peer_ok(p, name, req, sipmethod, addr, 16815 authpeer, reliable, calleridname, uri2); 16816 if (res != AUTH_DONT_KNOW) { 16817 return res; 16818 } 16819 16820 /* Finally, apply the guest policy */ 16821 if (sip_cfg.allowguest) { 16822 /* Ignore check_return warning from Coverity for get_rpid below. */ 16823 get_rpid(p, req); 16824 p->rtptimeout = global_rtptimeout; 16825 p->rtpholdtimeout = global_rtpholdtimeout; 16826 p->rtpkeepalive = global_rtpkeepalive; 16827 if (!dialog_initialize_rtp(p)) { 16828 res = AUTH_SUCCESSFUL; 16829 } else { 16830 res = AUTH_RTP_FAILED; 16831 } 16832 } else { 16833 res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */ 16834 } 16835 16836 if (ast_test_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT)) { 16837 ast_set_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT); 16838 } 16839 16840 return res; 16841 }
| static void check_via | ( | struct sip_pvt * | p, | |
| const struct sip_request * | req | |||
| ) | [static] |
check Via: header for hostname, port and rport request/answer
Definition at line 16445 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_set_flag, ast_skip_blanks(), ast_sockaddr_port, ast_sockaddr_resolve_first(), ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_verbose, get_header(), LOG_WARNING, sip_debug_test_pvt(), sip_nat_mode(), and sip_real_dst().
Referenced by handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_register(), and handle_request_subscribe().
16446 { 16447 char via[512]; 16448 char *c, *maddr; 16449 struct ast_sockaddr tmp = { { 0, } }; 16450 uint16_t port; 16451 16452 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 16453 16454 /* Work on the leftmost value of the topmost Via header */ 16455 c = strchr(via, ','); 16456 if (c) 16457 *c = '\0'; 16458 16459 /* Check for rport */ 16460 c = strstr(via, ";rport"); 16461 if (c && (c[6] != '=')) { /* rport query, not answer */ 16462 ast_set_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT); 16463 ast_set_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT); 16464 } 16465 16466 /* Check for maddr */ 16467 maddr = strstr(via, "maddr="); 16468 if (maddr) { 16469 maddr += 6; 16470 c = maddr + strspn(maddr, "abcdefghijklmnopqrstuvwxyz" 16471 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.:[]"); 16472 *c = '\0'; 16473 } 16474 16475 c = strchr(via, ';'); 16476 if (c) 16477 *c = '\0'; 16478 16479 c = strchr(via, ' '); 16480 if (c) { 16481 *c = '\0'; 16482 c = ast_skip_blanks(c+1); 16483 if (strcasecmp(via, "SIP/2.0/UDP") && strcasecmp(via, "SIP/2.0/TCP") && strcasecmp(via, "SIP/2.0/TLS")) { 16484 ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via); 16485 return; 16486 } 16487 16488 if (maddr && ast_sockaddr_resolve_first(&p->sa, maddr, 0)) { 16489 p->sa = p->recv; 16490 } 16491 16492 if (ast_sockaddr_resolve_first(&tmp, c, 0)) { 16493 ast_log(LOG_WARNING, "Could not resolve socket address for '%s'\n", c); 16494 port = STANDARD_SIP_PORT; 16495 } else if (!(port = ast_sockaddr_port(&tmp))) { 16496 port = STANDARD_SIP_PORT; 16497 } 16498 16499 ast_sockaddr_set_port(&p->sa, port); 16500 16501 if (sip_debug_test_pvt(p)) { 16502 ast_verbose("Sending to %s (%s)\n", 16503 ast_sockaddr_stringify(sip_real_dst(p)), 16504 sip_nat_mode(p)); 16505 } 16506 } 16507 }
| static attribute_unused void check_via_response | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
check received= and rport= in a SIP response. If we get a response with received= and/or rport= in the Via: line, use them as 'p->ourip' (see RFC 3581 for rport, and RFC 3261 for received). Using these two fields SIP can produce the correct address and port in the SIP headers without the need for STUN. The address part is also reused for the media sessions. Note that ast_sip_ouraddrfor() still rewrites p->ourip if you specify externaddr/seternaddr/.
Definition at line 16415 of file chan_sip.c.
References ast_copy_string(), ast_parse_arg(), ast_sockaddr_set_port, get_header(), and PARSE_ADDR.
16416 { 16417 char via[256]; 16418 char *cur, *opts; 16419 16420 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 16421 16422 /* Work on the leftmost value of the topmost Via header */ 16423 opts = strchr(via, ','); 16424 if (opts) 16425 *opts = '\0'; 16426 16427 /* parse all relevant options */ 16428 opts = strchr(via, ';'); 16429 if (!opts) 16430 return; /* no options to parse */ 16431 *opts++ = '\0'; 16432 while ( (cur = strsep(&opts, ";")) ) { 16433 if (!strncmp(cur, "rport=", 6)) { 16434 int port = strtol(cur+6, NULL, 10); 16435 /* XXX add error checking */ 16436 ast_sockaddr_set_port(&p->ourip, port); 16437 } else if (!strncmp(cur, "received=", 9)) { 16438 if (ast_parse_arg(cur + 9, PARSE_ADDR, &p->ourip)) 16439 ; /* XXX add error checking */ 16440 } 16441 } 16442 }
| static void cleanup_all_regs | ( | void | ) | [static] |
Definition at line 28741 of file chan_sip.c.
References ast_debug, ast_dnsmgr_release(), AST_SCHED_DEL_UNREF, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, dialog_unlink_all(), registry_unref(), and regl.
Referenced by reload_config(), and unload_module().
28742 { 28743 /* First, destroy all outstanding registry calls */ 28744 /* This is needed, since otherwise active registry entries will not be destroyed */ 28745 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { /* regl is locked */ 28746 ASTOBJ_WRLOCK(iterator); /* now regl is locked, and the object is also locked */ 28747 if (iterator->call) { 28748 ast_debug(3, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname); 28749 /* This will also remove references to the registry */ 28750 dialog_unlink_all(iterator->call); 28751 iterator->call = dialog_unref(iterator->call, "remove iterator->call from registry traversal"); 28752 } 28753 if (iterator->expire > -1) { 28754 AST_SCHED_DEL_UNREF(sched, iterator->expire, registry_unref(iterator, "reg ptr unref from reload config")); 28755 } 28756 if (iterator->timeout > -1) { 28757 AST_SCHED_DEL_UNREF(sched, iterator->timeout, registry_unref(iterator, "reg ptr unref from reload config")); 28758 } 28759 if (iterator->dnsmgr) { 28760 ast_dnsmgr_release(iterator->dnsmgr); 28761 iterator->dnsmgr = NULL; 28762 registry_unref(iterator, "reg ptr unref from dnsmgr"); 28763 } 28764 ASTOBJ_UNLOCK(iterator); 28765 } while(0)); 28766 }
| static void cleanup_stale_contexts | ( | char * | new, | |
| char * | old | |||
| ) | [static] |
Destroy disused contexts between reloads Only used in reload_config so the code for regcontext doesn't get ugly.
Definition at line 17622 of file chan_sip.c.
References ast_context_destroy(), ast_context_find(), ast_copy_string(), and AST_MAX_CONTEXT.
Referenced by reload_config().
17623 { 17624 char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT]; 17625 17626 while ((oldcontext = strsep(&old, "&"))) { 17627 stalecontext = '\0'; 17628 ast_copy_string(newlist, new, sizeof(newlist)); 17629 stringp = newlist; 17630 while ((newcontext = strsep(&stringp, "&"))) { 17631 if (!strcmp(newcontext, oldcontext)) { 17632 /* This is not the context you're looking for */ 17633 stalecontext = '\0'; 17634 break; 17635 } else if (strcmp(newcontext, oldcontext)) { 17636 stalecontext = oldcontext; 17637 } 17638 17639 } 17640 if (stalecontext) 17641 ast_context_destroy(ast_context_find(stalecontext), "SIP"); 17642 } 17643 }
| static void clear_peer_mailboxes | ( | struct sip_peer * | peer | ) | [static] |
Destroy all peer-related mailbox subscriptions
Definition at line 4814 of file chan_sip.c.
References AST_LIST_REMOVE_HEAD, destroy_mailbox(), and mailbox.
Referenced by set_peer_defaults(), and sip_destroy_peer().
04815 { 04816 struct sip_mailbox *mailbox; 04817 04818 while ((mailbox = AST_LIST_REMOVE_HEAD(&peer->mailboxes, entry))) 04819 destroy_mailbox(mailbox); 04820 }
| static void clear_sip_domains | ( | void | ) | [static] |
Clear our domain list (at reload).
Definition at line 27776 of file chan_sip.c.
References ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, and AST_LIST_UNLOCK.
Referenced by reload_config(), and unload_module().
27777 { 27778 struct domain *d; 27779 27780 AST_LIST_LOCK(&domain_list); 27781 while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list))) 27782 ast_free(d); 27783 AST_LIST_UNLOCK(&domain_list); 27784 }
| static char * complete_sip_peer | ( | const char * | word, | |
| int | state, | |||
| int | flags2 | |||
| ) | [static] |
Do completion on peer name.
Definition at line 19106 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ast_strdup, ast_test_flag, and unref_peer().
Referenced by complete_sip_show_peer(), complete_sipnotify(), sip_do_debug(), and sip_prune_realtime().
19107 { 19108 char *result = NULL; 19109 int wordlen = strlen(word); 19110 int which = 0; 19111 struct ao2_iterator i = ao2_iterator_init(peers, 0); 19112 struct sip_peer *peer; 19113 19114 while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) { 19115 /* locking of the object is not required because only the name and flags are being compared */ 19116 if (!strncasecmp(word, peer->name, wordlen) && 19117 (!flags2 || ast_test_flag(&peer->flags[1], flags2)) && 19118 ++which > state) 19119 result = ast_strdup(peer->name); 19120 unref_peer(peer, "toss iterator peer ptr before break"); 19121 if (result) { 19122 break; 19123 } 19124 } 19125 ao2_iterator_destroy(&i); 19126 return result; 19127 }
| static char * complete_sip_registered_peer | ( | const char * | word, | |
| int | state, | |||
| int | flags2 | |||
| ) | [static] |
Do completion on registered peer name.
Definition at line 19130 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ast_strdup, ast_test_flag, and unref_peer().
Referenced by complete_sip_unregister().
19131 { 19132 char *result = NULL; 19133 int wordlen = strlen(word); 19134 int which = 0; 19135 struct ao2_iterator i; 19136 struct sip_peer *peer; 19137 19138 i = ao2_iterator_init(peers, 0); 19139 while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) { 19140 if (!strncasecmp(word, peer->name, wordlen) && 19141 (!flags2 || ast_test_flag(&peer->flags[1], flags2)) && 19142 ++which > state && peer->expire > 0) 19143 result = ast_strdup(peer->name); 19144 if (result) { 19145 unref_peer(peer, "toss iterator peer ptr before break"); 19146 break; 19147 } 19148 unref_peer(peer, "toss iterator peer ptr"); 19149 } 19150 ao2_iterator_destroy(&i); 19151 return result; 19152 }
| static char * complete_sip_show_history | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Support routine for 'sip show history' CLI.
Definition at line 19155 of file chan_sip.c.
References complete_sipch().
Referenced by sip_show_history().
19156 { 19157 if (pos == 3) 19158 return complete_sipch(line, word, pos, state); 19159 19160 return NULL; 19161 }
| static char * complete_sip_show_peer | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Support routine for 'sip show peer' CLI.
Definition at line 19164 of file chan_sip.c.
References complete_sip_peer().
Referenced by sip_qualify_peer(), and sip_show_peer().
19165 { 19166 if (pos == 3) { 19167 return complete_sip_peer(word, state, 0); 19168 } 19169 19170 return NULL; 19171 }
| static char* complete_sip_show_user | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Support routine for 'sip show user' CLI.
Definition at line 18365 of file chan_sip.c.
References complete_sip_user().
Referenced by sip_show_user().
18366 { 18367 if (pos == 3) 18368 return complete_sip_user(word, state); 18369 18370 return NULL; 18371 }
| static char * complete_sip_unregister | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Support routine for 'sip unregister' CLI.
Definition at line 19174 of file chan_sip.c.
References complete_sip_registered_peer().
Referenced by sip_unregister().
19175 { 19176 if (pos == 2) 19177 return complete_sip_registered_peer(word, state, 0); 19178 19179 return NULL; 19180 }
| static char* complete_sip_user | ( | const char * | word, | |
| int | state | |||
| ) | [static] |
Do completion on user name.
Definition at line 18335 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_iterator_next, ao2_unlock, ast_strdup, and unref_peer().
Referenced by complete_sip_show_user().
18336 { 18337 char *result = NULL; 18338 int wordlen = strlen(word); 18339 int which = 0; 18340 struct ao2_iterator user_iter; 18341 struct sip_peer *user; 18342 18343 user_iter = ao2_iterator_init(peers, 0); 18344 while ((user = ao2_t_iterator_next(&user_iter, "iterate thru peers table"))) { 18345 ao2_lock(user); 18346 if (!(user->type & SIP_TYPE_USER)) { 18347 ao2_unlock(user); 18348 unref_peer(user, "complete sip user"); 18349 continue; 18350 } 18351 /* locking of the object is not required because only the name and flags are being compared */ 18352 if (!strncasecmp(word, user->name, wordlen) && ++which > state) { 18353 result = ast_strdup(user->name); 18354 } 18355 ao2_unlock(user); 18356 unref_peer(user, "complete sip user"); 18357 if (result) { 18358 break; 18359 } 18360 } 18361 ao2_iterator_destroy(&user_iter); 18362 return result; 18363 }
| static char* complete_sipch | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Support routine for 'sip show channel' and 'sip show history' CLI This is in charge of generating all strings that match a prefix in the given position. As many functions of this kind, each invokation has O(state) time complexity so be careful in using it.
Definition at line 19076 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ast_strdup, sip_pvt_lock, and sip_pvt_unlock.
Referenced by complete_sip_show_history(), and sip_show_channel().
19077 { 19078 int which=0; 19079 struct sip_pvt *cur; 19080 char *c = NULL; 19081 int wordlen = strlen(word); 19082 struct ao2_iterator i; 19083 19084 if (pos != 3) { 19085 return NULL; 19086 } 19087 19088 i = ao2_iterator_init(dialogs, 0); 19089 while ((cur = ao2_t_iterator_next(&i, "iterate thru dialogs"))) { 19090 sip_pvt_lock(cur); 19091 if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) { 19092 c = ast_strdup(cur->callid); 19093 sip_pvt_unlock(cur); 19094 dialog_unref(cur, "drop ref in iterator loop break"); 19095 break; 19096 } 19097 sip_pvt_unlock(cur); 19098 dialog_unref(cur, "drop ref in iterator loop"); 19099 } 19100 ao2_iterator_destroy(&i); 19101 return c; 19102 }
| static char * complete_sipnotify | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Support routine for 'sip notify' CLI.
Definition at line 19183 of file chan_sip.c.
References ast_category_browse(), ast_strdup, and complete_sip_peer().
Referenced by sip_cli_notify().
19184 { 19185 char *c = NULL; 19186 19187 if (pos == 2) { 19188 int which = 0; 19189 char *cat = NULL; 19190 int wordlen = strlen(word); 19191 19192 /* do completion for notify type */ 19193 19194 if (!notify_types) 19195 return NULL; 19196 19197 while ( (cat = ast_category_browse(notify_types, cat)) ) { 19198 if (!strncasecmp(word, cat, wordlen) && ++which > state) { 19199 c = ast_strdup(cat); 19200 break; 19201 } 19202 } 19203 return c; 19204 } 19205 19206 if (pos > 2) 19207 return complete_sip_peer(word, state, 0); 19208 19209 return NULL; 19210 }
| static int construct_pidf_body | ( | enum sip_cc_publish_state | state, | |
| char * | pidf_body, | |||
| size_t | size, | |||
| const char * | presentity | |||
| ) | [static] |
Definition at line 1950 of file chan_sip.c.
References ast_copy_string(), ast_str_alloca, ast_str_append(), ast_str_buffer(), and generate_random_string().
Referenced by handle_cc_notify(), sip_cc_monitor_suspend(), and sip_cc_monitor_unsuspend().
01951 { 01952 struct ast_str *body = ast_str_alloca(size); 01953 char tuple_id[32]; 01954 01955 generate_random_string(tuple_id, sizeof(tuple_id)); 01956 01957 /* We'll make this a bare-bones pidf body. In state_notify_build_xml, the PIDF 01958 * body gets a lot more extra junk that isn't necessary, so we'll leave it out here. 01959 */ 01960 ast_str_append(&body, 0, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); 01961 /* XXX The entity attribute is currently set to the peer name associated with the 01962 * dialog. This is because we currently only call this function for call-completion 01963 * PUBLISH bodies. In such cases, the entity is completely disregarded. For other 01964 * event packages, it may be crucial to have a proper URI as the presentity so this 01965 * should be revisited as support is expanded. 01966 */ 01967 ast_str_append(&body, 0, "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" entity=\"%s\">\n", presentity); 01968 ast_str_append(&body, 0, "<tuple id=\"%s\">\n", tuple_id); 01969 ast_str_append(&body, 0, "<status><basic>%s</basic></status>\n", state == CC_OPEN ? "open" : "closed"); 01970 ast_str_append(&body, 0, "</tuple>\n"); 01971 ast_str_append(&body, 0, "</presence>\n"); 01972 ast_copy_string(pidf_body, ast_str_buffer(body), size); 01973 return 0; 01974 }
| static int copy_all_header | ( | struct sip_request * | req, | |
| const struct sip_request * | orig, | |||
| const char * | field | |||
| ) | [static] |
Copy all headers from one request to another.
Definition at line 10299 of file chan_sip.c.
References __get_header(), add_header(), and ast_strlen_zero().
Referenced by respprep().
10300 { 10301 int start = 0; 10302 int copied = 0; 10303 for (;;) { 10304 const char *tmp = __get_header(orig, field, &start); 10305 10306 if (ast_strlen_zero(tmp)) 10307 break; 10308 /* Add what we're responding to */ 10309 add_header(req, field, tmp); 10310 copied++; 10311 } 10312 return copied ? 0 : -1; 10313 }
| static int copy_header | ( | struct sip_request * | req, | |
| const struct sip_request * | orig, | |||
| const char * | field | |||
| ) | [static] |
Copy one header field from one request to another.
Definition at line 10288 of file chan_sip.c.
References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE.
Referenced by reqprep(), and respprep().
10289 { 10290 const char *tmp = get_header(orig, field); 10291 10292 if (!ast_strlen_zero(tmp)) /* Add what we're responding to */ 10293 return add_header(req, field, tmp); 10294 ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field); 10295 return -1; 10296 }
| static void copy_request | ( | struct sip_request * | dst, | |
| const struct sip_request * | src | |||
| ) | [static] |
copy SIP request (mostly used to save request for responses)
Definition at line 12105 of file chan_sip.c.
References ast_str_copy_string(), ast_str_create(), and ast_str_strlen().
Referenced by handle_request_bye(), handle_request_invite(), handle_request_options(), handle_request_register(), handle_request_subscribe(), initialize_initreq(), parse_copy(), and sip_park().
12106 { 12107 /* XXX this function can encounter memory allocation errors, perhaps it 12108 * should return a value */ 12109 12110 struct ast_str *duplicate = dst->data; 12111 struct ast_str *duplicate_content = dst->content; 12112 12113 /* copy the entire request then restore the original data and content 12114 * members from the dst request */ 12115 *dst = *src; 12116 dst->data = duplicate; 12117 dst->content = duplicate_content; 12118 12119 /* copy the data into the dst request */ 12120 if (!dst->data && !(dst->data = ast_str_create(ast_str_strlen(src->data) + 1))) { 12121 return; 12122 } 12123 ast_str_copy_string(&dst->data, src->data); 12124 12125 /* copy the content into the dst request (if it exists) */ 12126 if (src->content) { 12127 if (!dst->content && !(dst->content = ast_str_create(ast_str_strlen(src->content) + 1))) { 12128 return; 12129 } 12130 ast_str_copy_string(&dst->content, src->content); 12131 } 12132 }
| static void copy_socket_data | ( | struct sip_socket * | to_sock, | |
| const struct sip_socket * | from_sock | |||
| ) | [static] |
Definition at line 5403 of file chan_sip.c.
References ao2_ref.
Referenced by create_addr_from_peer(), handle_request_do(), parse_register_contact(), sip_poke_peer(), and transmit_response_using_temp().
| static struct ast_variable * copy_vars | ( | struct ast_variable * | src | ) | [static, read] |
duplicate a list of channel variables,
Definition at line 2329 of file chan_sip.c.
References ast_variable_new(), and ast_variable::next.
Referenced by check_peer_ok(), and create_addr_from_peer().
02330 { 02331 struct ast_variable *res = NULL, *tmp, *v = NULL; 02332 02333 for (v = src ; v ; v = v->next) { 02334 if ((tmp = ast_variable_new(v->name, v->value, v->file))) { 02335 tmp->next = res; 02336 res = tmp; 02337 } 02338 } 02339 return res; 02340 }
| static int copy_via_headers | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| const struct sip_request * | orig, | |||
| const char * | field | |||
| ) | [static] |
Copy SIP VIA Headers from the request to the response.
We always add ;received=<ip address> to the topmost via header.
Definition at line 10323 of file chan_sip.c.
References __get_header(), add_header(), ast_copy_string(), ast_log(), ast_sockaddr_port, ast_sockaddr_stringify_addr_remote(), ast_strlen_zero(), ast_test_flag, and LOG_NOTICE.
Referenced by respprep().
10324 { 10325 int copied = 0; 10326 int start = 0; 10327 10328 for (;;) { 10329 char new[512]; 10330 const char *oh = __get_header(orig, field, &start); 10331 10332 if (ast_strlen_zero(oh)) 10333 break; 10334 10335 if (!copied) { /* Only check for empty rport in topmost via header */ 10336 char leftmost[512], *others, *rport; 10337 10338 /* Only work on leftmost value */ 10339 ast_copy_string(leftmost, oh, sizeof(leftmost)); 10340 others = strchr(leftmost, ','); 10341 if (others) 10342 *others++ = '\0'; 10343 10344 /* Find ;rport; (empty request) */ 10345 rport = strstr(leftmost, ";rport"); 10346 if (rport && *(rport+6) == '=') 10347 rport = NULL; /* We already have a parameter to rport */ 10348 10349 if (((ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT)) || (rport && ast_test_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT)))) { 10350 /* We need to add received port - rport */ 10351 char *end; 10352 10353 rport = strstr(leftmost, ";rport"); 10354 10355 if (rport) { 10356 end = strchr(rport + 1, ';'); 10357 if (end) 10358 memmove(rport, end, strlen(end) + 1); 10359 else 10360 *rport = '\0'; 10361 } 10362 10363 /* Add rport to first VIA header if requested */ 10364 snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s", 10365 leftmost, ast_sockaddr_stringify_addr_remote(&p->recv), 10366 ast_sockaddr_port(&p->recv), 10367 others ? "," : "", others ? others : ""); 10368 } else { 10369 /* We should *always* add a received to the topmost via */ 10370 snprintf(new, sizeof(new), "%s;received=%s%s%s", 10371 leftmost, ast_sockaddr_stringify_addr_remote(&p->recv), 10372 others ? "," : "", others ? others : ""); 10373 } 10374 oh = new; /* the header to copy */ 10375 } /* else add the following via headers untouched */ 10376 add_header(req, field, oh); 10377 copied++; 10378 } 10379 if (!copied) { 10380 ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field); 10381 return -1; 10382 } 10383 return 0; 10384 }
| static int create_addr | ( | struct sip_pvt * | dialog, | |
| const char * | opeer, | |||
| struct ast_sockaddr * | addr, | |||
| int | newdialog | |||
| ) | [static] |
create address structure from device name Or, if peer not found, find it in the global DNS returns TRUE (-1) on failure, FALSE on success
Definition at line 5633 of file chan_sip.c.
References AST_APP_ARG, ast_check_digits(), AST_DECLARE_APP_ARGS, ast_get_srv(), ast_log(), AST_NONSTANDARD_RAW_ARGS, ast_sockaddr_copy(), ast_sockaddr_port, ast_sockaddr_resolve_first_transport(), ast_sockaddr_set_port, ast_strdupa, ast_string_field_set, bindaddr, create_addr_from_peer(), default_sip_port(), dialog_initialize_rtp(), FALSE, find_peer(), get_srv_protocol(), get_srv_service(), LOG_WARNING, MAXHOSTNAMELEN, obproxy_get(), ref_peer(), ref_proxy(), service, set_socket_transport(), sip_cfg, TRUE, and unref_peer().
Referenced by __sip_subscribe_mwi_do(), manager_sipnotify(), sip_cc_monitor_request_cc(), sip_cli_notify(), sip_request_call(), transmit_publish(), and transmit_register().
05634 { 05635 struct sip_peer *peer; 05636 char *peername, *peername2, *hostn; 05637 char host[MAXHOSTNAMELEN]; 05638 char service[MAXHOSTNAMELEN]; 05639 int srv_ret = 0; 05640 int tportno; 05641 05642 AST_DECLARE_APP_ARGS(hostport, 05643 AST_APP_ARG(host); 05644 AST_APP_ARG(port); 05645 ); 05646 05647 peername = ast_strdupa(opeer); 05648 peername2 = ast_strdupa(opeer); 05649 AST_NONSTANDARD_RAW_ARGS(hostport, peername2, ':'); 05650 05651 if (hostport.port) 05652 dialog->portinuri = 1; 05653 05654 dialog->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */ 05655 dialog->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */ 05656 peer = find_peer(peername, NULL, TRUE, FINDPEERS, FALSE, 0); 05657 05658 if (peer) { 05659 int res; 05660 if (newdialog) { 05661 set_socket_transport(&dialog->socket, 0); 05662 } 05663 res = create_addr_from_peer(dialog, peer); 05664 dialog->relatedpeer = ref_peer(peer, "create_addr: setting dialog's relatedpeer pointer"); 05665 unref_peer(peer, "create_addr: unref peer from find_peer hashtab lookup"); 05666 return res; 05667 } else if (ast_check_digits(peername)) { 05668 /* Although an IPv4 hostname *could* be represented as a 32-bit integer, it is uncommon and 05669 * it makes dialing SIP/${EXTEN} for a peer that isn't defined resolve to an IP that is 05670 * almost certainly not intended. It is much better to just reject purely numeric hostnames */ 05671 ast_log(LOG_WARNING, "Purely numeric hostname (%s), and not a peer--rejecting!\n", peername); 05672 return -1; 05673 } else { 05674 dialog->rtptimeout = global_rtptimeout; 05675 dialog->rtpholdtimeout = global_rtpholdtimeout; 05676 dialog->rtpkeepalive = global_rtpkeepalive; 05677 if (dialog_initialize_rtp(dialog)) { 05678 return -1; 05679 } 05680 } 05681 05682 ast_string_field_set(dialog, tohost, hostport.host); 05683 dialog->allowed_methods &= ~sip_cfg.disallowed_methods; 05684 05685 /* Get the outbound proxy information */ 05686 ref_proxy(dialog, obproxy_get(dialog, NULL)); 05687 05688 if (addr) { 05689 /* This address should be updated using dnsmgr */ 05690 ast_sockaddr_copy(&dialog->sa, addr); 05691 } else { 05692 05693 /* Let's see if we can find the host in DNS. First try DNS SRV records, 05694 then hostname lookup */ 05695 /*! \todo Fix this function. When we ask for SRV, we should check all transports 05696 In the future, we should first check NAPTR to find out transport preference 05697 */ 05698 hostn = peername; 05699 /* Section 4.2 of RFC 3263 specifies that if a port number is specified, then 05700 * an A record lookup should be used instead of SRV. 05701 */ 05702 if (!hostport.port && sip_cfg.srvlookup) { 05703 snprintf(service, sizeof(service), "_%s._%s.%s", 05704 get_srv_service(dialog->socket.type), 05705 get_srv_protocol(dialog->socket.type), peername); 05706 if ((srv_ret = ast_get_srv(NULL, host, sizeof(host), &tportno, 05707 service)) > 0) { 05708 hostn = host; 05709 } 05710 } 05711 05712 if (ast_sockaddr_resolve_first_transport(&dialog->sa, hostn, 0, dialog->socket.type ? dialog->socket.type : SIP_TRANSPORT_UDP)) { 05713 ast_log(LOG_WARNING, "No such host: %s\n", peername); 05714 return -1; 05715 } 05716 05717 if (srv_ret > 0) { 05718 ast_sockaddr_set_port(&dialog->sa, tportno); 05719 } 05720 } 05721 05722 if (!dialog->socket.type) 05723 set_socket_transport(&dialog->socket, SIP_TRANSPORT_UDP); 05724 if (!dialog->socket.port) { 05725 dialog->socket.port = htons(ast_sockaddr_port(&bindaddr)); 05726 } 05727 05728 if (!ast_sockaddr_port(&dialog->sa)) { 05729 ast_sockaddr_set_port(&dialog->sa, default_sip_port(dialog->socket.type)); 05730 } 05731 ast_sockaddr_copy(&dialog->recv, &dialog->sa); 05732 return 0; 05733 }
| static int create_addr_from_peer | ( | struct sip_pvt * | dialog, | |
| struct sip_peer * | peer | |||
| ) | [static] |
Create address structure from peer reference. This function copies data from peer to the dialog, so we don't have to look up the peer again from memory or database during the life time of the dialog.
Definition at line 5478 of file chan_sip.c.
References accountcode, ao2_lock, ao2_t_ref, ao2_unlock, ast_alloca, ast_cc_copy_config_params(), ast_copy_flags, ast_duplicate_ha_list(), ast_rtp_codecs_packetization_set(), AST_RTP_DTMF, ast_rtp_instance_get_codecs(), ast_rtp_instance_set_prop(), AST_RTP_PROPERTY_DTMF, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_set_flag, ast_sockaddr_isnull(), ast_sockaddr_stringify_host_remote(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, change_callid_pvt(), check_request_transport, cid_name, cid_num, context, copy_socket_data(), copy_vars(), dialog_initialize_rtp(), language, mohinterpret, mohsuggest, obproxy_get(), parkinglot, and ref_proxy().
Referenced by create_addr(), and sip_send_mwi_to_peer().
05479 { 05480 struct sip_auth_container *credentials; 05481 05482 /* this checks that the dialog is contacting the peer on a valid 05483 * transport type based on the peers transport configuration, 05484 * otherwise, this function bails out */ 05485 if (dialog->socket.type && check_request_transport(peer, dialog)) 05486 return -1; 05487 copy_socket_data(&dialog->socket, &peer->socket); 05488 05489 if (!(ast_sockaddr_isnull(&peer->addr) && ast_sockaddr_isnull(&peer->defaddr)) && 05490 (!peer->maxms || ((peer->lastms >= 0) && (peer->lastms <= peer->maxms)))) { 05491 dialog->sa = ast_sockaddr_isnull(&peer->addr) ? peer->defaddr : peer->addr; 05492 dialog->recv = dialog->sa; 05493 } else 05494 return -1; 05495 05496 /* XXX TODO: get flags directly from peer only as they are needed using dialog->relatedpeer */ 05497 ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 05498 ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 05499 ast_copy_flags(&dialog->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY); 05500 dialog->capability = peer->capability; 05501 dialog->prefs = peer->prefs; 05502 dialog->amaflags = peer->amaflags; 05503 05504 ast_string_field_set(dialog, engine, peer->engine); 05505 05506 dialog->rtptimeout = peer->rtptimeout; 05507 dialog->rtpholdtimeout = peer->rtpholdtimeout; 05508 dialog->rtpkeepalive = peer->rtpkeepalive; 05509 if (dialog_initialize_rtp(dialog)) { 05510 return -1; 05511 } 05512 05513 if (dialog->rtp) { /* Audio */ 05514 ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 05515 ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 05516 /* Set Frame packetization */ 05517 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(dialog->rtp), dialog->rtp, &dialog->prefs); 05518 dialog->autoframing = peer->autoframing; 05519 } 05520 05521 /* XXX TODO: get fields directly from peer only as they are needed using dialog->relatedpeer */ 05522 ast_string_field_set(dialog, peername, peer->name); 05523 ast_string_field_set(dialog, authname, peer->username); 05524 ast_string_field_set(dialog, username, peer->username); 05525 ast_string_field_set(dialog, peersecret, peer->secret); 05526 ast_string_field_set(dialog, peermd5secret, peer->md5secret); 05527 ast_string_field_set(dialog, mohsuggest, peer->mohsuggest); 05528 ast_string_field_set(dialog, mohinterpret, peer->mohinterpret); 05529 ast_string_field_set(dialog, tohost, peer->tohost); 05530 ast_string_field_set(dialog, fullcontact, peer->fullcontact); 05531 ast_string_field_set(dialog, accountcode, peer->accountcode); 05532 ast_string_field_set(dialog, context, peer->context); 05533 ast_string_field_set(dialog, cid_num, peer->cid_num); 05534 ast_string_field_set(dialog, cid_name, peer->cid_name); 05535 ast_string_field_set(dialog, cid_tag, peer->cid_tag); 05536 ast_string_field_set(dialog, mwi_from, peer->mwi_from); 05537 if (!ast_strlen_zero(peer->parkinglot)) { 05538 ast_string_field_set(dialog, parkinglot, peer->parkinglot); 05539 } 05540 ast_string_field_set(dialog, engine, peer->engine); 05541 ref_proxy(dialog, obproxy_get(dialog, peer)); 05542 dialog->callgroup = peer->callgroup; 05543 dialog->pickupgroup = peer->pickupgroup; 05544 dialog->allowtransfer = peer->allowtransfer; 05545 dialog->jointnoncodeccapability = dialog->noncodeccapability; 05546 05547 /* Update dialog authorization credentials */ 05548 ao2_lock(peer); 05549 credentials = peer->auth; 05550 if (credentials) { 05551 ao2_t_ref(credentials, +1, "Ref peer auth for dialog"); 05552 } 05553 ao2_unlock(peer); 05554 ao2_lock(dialog); 05555 if (dialog->peerauth) { 05556 ao2_t_ref(dialog->peerauth, -1, "Unref old dialog peer auth"); 05557 } 05558 dialog->peerauth = credentials; 05559 ao2_unlock(dialog); 05560 05561 dialog->maxcallbitrate = peer->maxcallbitrate; 05562 dialog->disallowed_methods = peer->disallowed_methods; 05563 ast_cc_copy_config_params(dialog->cc_params, peer->cc_params); 05564 if (ast_strlen_zero(dialog->tohost)) 05565 ast_string_field_set(dialog, tohost, ast_sockaddr_stringify_host_remote(&dialog->sa)); 05566 if (!ast_strlen_zero(peer->fromdomain)) { 05567 ast_string_field_set(dialog, fromdomain, peer->fromdomain); 05568 if (!dialog->initreq.headers) { 05569 char *new_callid; 05570 char *tmpcall = ast_strdupa(dialog->callid); 05571 /* this sure looks to me like we are going to change the callid on this dialog!! */ 05572 new_callid = strchr(tmpcall, '@'); 05573 if (new_callid) { 05574 int callid_size; 05575 05576 *new_callid = '\0'; 05577 05578 /* Change the dialog callid. */ 05579 callid_size = strlen(tmpcall) + strlen(peer->fromdomain) + 2; 05580 new_callid = ast_alloca(callid_size); 05581 snprintf(new_callid, callid_size, "%s@%s", tmpcall, peer->fromdomain); 05582 change_callid_pvt(dialog, new_callid); 05583 } 05584 } 05585 } 05586 if (!ast_strlen_zero(peer->fromuser)) 05587 ast_string_field_set(dialog, fromuser, peer->fromuser); 05588 if (!ast_strlen_zero(peer->language)) 05589 ast_string_field_set(dialog, language, peer->language); 05590 /* Set timer T1 to RTT for this peer (if known by qualify=) */ 05591 /* Minimum is settable or default to 100 ms */ 05592 /* If there is a maxms and lastms from a qualify use that over a manual T1 05593 value. Otherwise, use the peer's T1 value. */ 05594 if (peer->maxms && peer->lastms) 05595 dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 05596 else 05597 dialog->timer_t1 = peer->timer_t1; 05598 05599 /* Set timer B to control transaction timeouts, the peer setting is the default and overrides 05600 the known timer */ 05601 if (peer->timer_b) 05602 dialog->timer_b = peer->timer_b; 05603 else 05604 dialog->timer_b = 64 * dialog->timer_t1; 05605 05606 if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 05607 (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 05608 dialog->noncodeccapability |= AST_RTP_DTMF; 05609 else 05610 dialog->noncodeccapability &= ~AST_RTP_DTMF; 05611 dialog->directmediaha = ast_duplicate_ha_list(peer->directmediaha); 05612 if (peer->call_limit) 05613 ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT); 05614 if (!dialog->portinuri) 05615 dialog->portinuri = peer->portinuri; 05616 dialog->chanvars = copy_vars(peer->chanvars); 05617 if (peer->fromdomainport) 05618 dialog->fromdomainport = peer->fromdomainport; 05619 dialog->callingpres = peer->callingpres; 05620 05621 return 0; 05622 }
| static struct sip_epa_entry* create_epa_entry | ( | const char *const | event_package, | |
| const char *const | destination | |||
| ) | [static, read] |
Definition at line 908 of file chan_sip.c.
References ao2_t_alloc, ast_copy_string(), and find_static_data().
Referenced by sip_cc_monitor_suspend().
00909 { 00910 struct sip_epa_entry *epa_entry; 00911 const struct epa_static_data *static_data; 00912 00913 if (!(static_data = find_static_data(event_package))) { 00914 return NULL; 00915 } 00916 00917 if (!(epa_entry = ao2_t_alloc(sizeof(*epa_entry), static_data->destructor, "Allocate new EPA entry"))) { 00918 return NULL; 00919 } 00920 00921 epa_entry->static_data = static_data; 00922 ast_copy_string(epa_entry->destination, destination, sizeof(epa_entry->destination)); 00923 return epa_entry; 00924 }
| static struct sip_esc_entry* create_esc_entry | ( | struct event_state_compositor * | esc, | |
| struct sip_request * | req, | |||
| const int | expires | |||
| ) | [static, read] |
Definition at line 1034 of file chan_sip.c.
References ao2_alloc, ao2_ref, ast_sched_add(), create_new_sip_etag(), esc_entry_destructor(), event_state_compositor::name, and publish_expire().
Referenced by handle_sip_publish_initial().
01035 { 01036 struct sip_esc_entry *esc_entry; 01037 int expires_ms; 01038 01039 if (!(esc_entry = ao2_alloc(sizeof(*esc_entry), esc_entry_destructor))) { 01040 return NULL; 01041 } 01042 01043 esc_entry->event = esc->name; 01044 01045 expires_ms = expires * 1000; 01046 /* Bump refcount for scheduler */ 01047 ao2_ref(esc_entry, +1); 01048 esc_entry->sched_id = ast_sched_add(sched, expires_ms, publish_expire, esc_entry); 01049 01050 /* Note: This links the esc_entry into the ESC properly */ 01051 create_new_sip_etag(esc_entry, 0); 01052 01053 return esc_entry; 01054 }
| static void create_new_sip_etag | ( | struct sip_esc_entry * | esc_entry, | |
| int | is_linked | |||
| ) | [static] |
Definition at line 1021 of file chan_sip.c.
References ao2_link, ao2_unlink, ast_assert, ast_atomic_fetchadd_int(), event_state_compositor::compositor, and get_esc().
Referenced by create_esc_entry(), and transmit_response_with_sip_etag().
01022 { 01023 int new_etag = ast_atomic_fetchadd_int(&esc_etag_counter, +1); 01024 struct event_state_compositor *esc = get_esc(esc_entry->event); 01025 01026 ast_assert(esc != NULL); 01027 if (is_linked) { 01028 ao2_unlink(esc->compositor, esc_entry); 01029 } 01030 snprintf(esc_entry->entity_tag, sizeof(esc_entry->entity_tag), "%d", new_etag); 01031 ao2_link(esc->compositor, esc_entry); 01032 }
| static int default_sip_port | ( | enum sip_transport | type | ) | [inline, static] |
The default sip port for the given transport.
Definition at line 5625 of file chan_sip.c.
Referenced by create_addr(), on_dns_update_peer(), and parse_register_contact().
05626 { 05627 return type == SIP_TRANSPORT_TLS ? STANDARD_TLS_PORT : STANDARD_SIP_PORT; 05628 }
| static void deinit_req | ( | struct sip_request * | req | ) | [static] |
Deinitialize SIP response/request.
Definition at line 10540 of file chan_sip.c.
References ast_free.
Referenced by __sip_destroy(), _sip_tcp_helper_thread(), send_request(), send_response(), sip_park(), sip_park_thread(), and sipsock_read().
| static void destroy_association | ( | struct sip_peer * | peer | ) | [static] |
Remove registration data from realtime database or AST/DB when registration expires.
Definition at line 14187 of file chan_sip.c.
References ast_check_realtime(), ast_db_del(), ast_update_realtime(), SENTINEL, and sip_cfg.
Referenced by build_peer(), and expire_register().
14188 { 14189 int realtimeregs = ast_check_realtime("sipregs"); 14190 char *tablename = (realtimeregs) ? "sipregs" : "sippeers"; 14191 14192 if (!sip_cfg.ignore_regexpire) { 14193 if (peer->rt_fromcontact && sip_cfg.peer_rtupdate) { 14194 ast_update_realtime(tablename, "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "regserver", "", "useragent", "", "lastms", "0", SENTINEL); 14195 } else { 14196 ast_db_del("SIP/Registry", peer->name); 14197 ast_db_del("SIP/PeerMethods", peer->name); 14198 } 14199 } 14200 }
| static void destroy_escs | ( | void | ) | [static] |
Definition at line 1068 of file chan_sip.c.
References ao2_ref, ARRAY_LEN, and event_state_compositors.
Referenced by unload_module().
01069 { 01070 int i; 01071 for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) { 01072 ao2_ref(event_state_compositors[i].compositor, -1); 01073 } 01074 }
| static void destroy_mailbox | ( | struct sip_mailbox * | mailbox | ) | [static] |
Destroy mailbox subscriptions
Definition at line 4806 of file chan_sip.c.
References ast_event_unsubscribe(), and ast_free.
Referenced by build_peer(), and clear_peer_mailboxes().
04807 { 04808 if (mailbox->event_sub) 04809 ast_event_unsubscribe(mailbox->event_sub); 04810 ast_free(mailbox); 04811 }
| static void destroy_realm_authentication | ( | void * | obj | ) | [static] |
Definition at line 27794 of file chan_sip.c.
References ast_free, and AST_LIST_REMOVE_HEAD.
Referenced by add_realm_authentication().
27795 { 27796 struct sip_auth_container *credentials = obj; 27797 struct sip_auth *auth; 27798 27799 while ((auth = AST_LIST_REMOVE_HEAD(&credentials->list, node))) { 27800 ast_free(auth); 27801 } 27802 }
| static int determine_firstline_parts | ( | struct sip_request * | req | ) | [static] |
Parse first line of incoming SIP request.
Definition at line 12205 of file chan_sip.c.
References ast_debug, ast_skip_blanks(), ast_skip_nonblanks(), and ast_trim_blanks().
Referenced by parse_request().
12206 { 12207 char *e = ast_skip_blanks(req->data->str); /* there shouldn't be any */ 12208 char *local_rlPart1; 12209 12210 if (!*e) 12211 return -1; 12212 req->rlPart1 = e - req->data->str; /* method or protocol */ 12213 local_rlPart1 = e; 12214 e = ast_skip_nonblanks(e); 12215 if (*e) 12216 *e++ = '\0'; 12217 /* Get URI or status code */ 12218 e = ast_skip_blanks(e); 12219 if ( !*e ) 12220 return -1; 12221 ast_trim_blanks(e); 12222 12223 if (!strcasecmp(local_rlPart1, "SIP/2.0") ) { /* We have a response */ 12224 if (strlen(e) < 3) /* status code is 3 digits */ 12225 return -1; 12226 req->rlPart2 = e - req->data->str; 12227 } else { /* We have a request */ 12228 if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */ 12229 ast_debug(3, "Oops. Bogus uri in <> %s\n", e); 12230 e++; 12231 if (!*e) 12232 return -1; 12233 } 12234 req->rlPart2 = e - req->data->str; /* URI */ 12235 e = ast_skip_nonblanks(e); 12236 if (*e) 12237 *e++ = '\0'; 12238 e = ast_skip_blanks(e); 12239 if (strcasecmp(e, "SIP/2.0") ) { 12240 ast_debug(3, "Skipping packet - Bad request protocol %s\n", e); 12241 return -1; 12242 } 12243 } 12244 return 1; 12245 }
| static enum sip_publish_type determine_sip_publish_type | ( | struct sip_request * | req, | |
| const char *const | event, | |||
| const char *const | etag, | |||
| const char *const | expires, | |||
| int * | expires_int | |||
| ) | [static] |
Definition at line 24760 of file chan_sip.c.
References ast_assert, and ast_strlen_zero().
Referenced by handle_request_publish().
24761 { 24762 int etag_present = !ast_strlen_zero(etag); 24763 int body_present = req->lines > 0; 24764 24765 ast_assert(expires_int != NULL); 24766 24767 if (ast_strlen_zero(expires)) { 24768 /* Section 6, item 4, second bullet point of RFC 3903 says to 24769 * use a locally-configured default expiration if none is provided 24770 * in the request 24771 */ 24772 *expires_int = DEFAULT_PUBLISH_EXPIRES; 24773 } else if (sscanf(expires, "%30d", expires_int) != 1) { 24774 return SIP_PUBLISH_UNKNOWN; 24775 } 24776 24777 if (*expires_int == 0) { 24778 return SIP_PUBLISH_REMOVE; 24779 } else if (!etag_present && body_present) { 24780 return SIP_PUBLISH_INITIAL; 24781 } else if (etag_present && !body_present) { 24782 return SIP_PUBLISH_REFRESH; 24783 } else if (etag_present && body_present) { 24784 return SIP_PUBLISH_MODIFY; 24785 } 24786 24787 return SIP_PUBLISH_UNKNOWN; 24788 }
| static int dialog_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 30820 of file chan_sip.c.
References CMP_MATCH, and CMP_STOP.
Referenced by load_module().
| static int dialog_dump_func | ( | void * | userobj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 17511 of file chan_sip.c.
References ao2_t_ref, ast_cli(), and ast_cli_args::fd.
Referenced by sip_show_objects().
17512 { 17513 struct sip_pvt *pvt = userobj; 17514 int refc = ao2_t_ref(userobj, 0, ""); 17515 struct ast_cli_args *a = (struct ast_cli_args *) arg; 17516 17517 ast_cli(a->fd, "name: %s\ntype: dialog\nobjflags: %d\nrefcount: %d\n\n", 17518 pvt->callid, 0, refc); 17519 return 0; 17520 }
| static int dialog_find_multiple | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 30810 of file chan_sip.c.
References CMP_MATCH.
Referenced by find_call().
30811 { 30812 struct sip_pvt *pvt = obj, *pvt2 = arg; 30813 30814 return !strcasecmp(pvt->callid, pvt2->callid) ? CMP_MATCH : 0; 30815 }
| static int dialog_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 30800 of file chan_sip.c.
References ast_str_case_hash().
Referenced by load_module().
30801 { 30802 const struct sip_pvt *pvt = obj; 30803 30804 return ast_str_case_hash(pvt->callid); 30805 }
| static int dialog_initialize_rtp | ( | struct sip_pvt * | dialog | ) | [static] |
Initialize RTP portion of a dialog.
Definition at line 5420 of file chan_sip.c.
References AST_FORMAT_VIDEO_MASK, ast_rtp_instance_new(), ast_rtp_instance_set_hold_timeout(), ast_rtp_instance_set_keepalive(), ast_rtp_instance_set_prop(), ast_rtp_instance_set_qos(), ast_rtp_instance_set_timeout(), AST_RTP_PROPERTY_DTMF, AST_RTP_PROPERTY_DTMF_COMPENSATE, AST_RTP_PROPERTY_RTCP, ast_sockaddr_copy(), ast_test_flag, bindaddr, do_setnat(), cfsip_methods::need_rtp, and sip_methods.
Referenced by check_peer_ok(), check_user_full(), create_addr(), and create_addr_from_peer().
05421 { 05422 struct ast_sockaddr bindaddr_tmp; 05423 05424 if (!sip_methods[dialog->method].need_rtp) { 05425 return 0; 05426 } 05427 05428 ast_sockaddr_copy(&bindaddr_tmp, &bindaddr); 05429 if (!(dialog->rtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) { 05430 return -1; 05431 } 05432 05433 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS) || 05434 (ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) && (dialog->capability & AST_FORMAT_VIDEO_MASK))) { 05435 if (!(dialog->vrtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) { 05436 return -1; 05437 } 05438 ast_rtp_instance_set_timeout(dialog->vrtp, dialog->rtptimeout); 05439 ast_rtp_instance_set_hold_timeout(dialog->vrtp, dialog->rtpholdtimeout); 05440 ast_rtp_instance_set_keepalive(dialog->vrtp, dialog->rtpkeepalive); 05441 05442 ast_rtp_instance_set_prop(dialog->vrtp, AST_RTP_PROPERTY_RTCP, 1); 05443 ast_rtp_instance_set_qos(dialog->vrtp, global_tos_video, global_cos_video, "SIP VIDEO"); 05444 } 05445 05446 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_TEXTSUPPORT)) { 05447 if (!(dialog->trtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) { 05448 return -1; 05449 } 05450 /* Do not timeout text as its not constant*/ 05451 ast_rtp_instance_set_keepalive(dialog->trtp, dialog->rtpkeepalive); 05452 05453 ast_rtp_instance_set_prop(dialog->trtp, AST_RTP_PROPERTY_RTCP, 1); 05454 } 05455 05456 ast_rtp_instance_set_timeout(dialog->rtp, dialog->rtptimeout); 05457 ast_rtp_instance_set_hold_timeout(dialog->rtp, dialog->rtpholdtimeout); 05458 ast_rtp_instance_set_keepalive(dialog->rtp, dialog->rtpkeepalive); 05459 05460 ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_RTCP, 1); 05461 ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 05462 ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 05463 05464 ast_rtp_instance_set_qos(dialog->rtp, global_tos_audio, global_cos_audio, "SIP RTP"); 05465 05466 do_setnat(dialog); 05467 05468 return 0; 05469 }
| static int dialog_needdestroy | ( | void * | dialogobj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Match dialogs that need to be destroyed.
This is used with ao2_callback to unlink/delete all dialogs that are marked needdestroy.
Definition at line 17655 of file chan_sip.c.
References ao2_t_link, ast_debug, ast_rtp_instance_get_bridged(), check_rtp_timeout(), sip_methods, sip_pvt_trylock, sip_pvt_unlock, and cfsip_methods::text.
Referenced by do_monitor().
17656 { 17657 struct sip_pvt *dialog = dialogobj; 17658 time_t *t = arg; 17659 17660 if (sip_pvt_trylock(dialog)) { 17661 /* Don't block the monitor thread. This function is called often enough 17662 * that we can wait for the next time around. */ 17663 return 0; 17664 } 17665 17666 /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */ 17667 check_rtp_timeout(dialog, *t); 17668 17669 /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */ 17670 if (dialog->rtp && ast_rtp_instance_get_bridged(dialog->rtp)) { 17671 ast_debug(2, "Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text); 17672 sip_pvt_unlock(dialog); 17673 return 0; 17674 } 17675 17676 if (dialog->vrtp && ast_rtp_instance_get_bridged(dialog->vrtp)) { 17677 ast_debug(2, "Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text); 17678 sip_pvt_unlock(dialog); 17679 return 0; 17680 } 17681 17682 /* If we have sessions that needs to be destroyed, do it now */ 17683 /* Check if we have outstanding requests not responsed to or an active call 17684 - if that's the case, wait with destruction */ 17685 if (dialog->needdestroy && !dialog->packets && !dialog->owner) { 17686 /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */ 17687 if (dialog->rtp && ast_rtp_instance_get_bridged(dialog->rtp)) { 17688 ast_debug(2, "Bridge still active. Delaying destruction of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text); 17689 sip_pvt_unlock(dialog); 17690 return 0; 17691 } 17692 17693 if (dialog->vrtp && ast_rtp_instance_get_bridged(dialog->vrtp)) { 17694 ast_debug(2, "Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text); 17695 sip_pvt_unlock(dialog); 17696 return 0; 17697 } 17698 17699 sip_pvt_unlock(dialog); 17700 17701 /* This dialog needs to be destroyed. */ 17702 ao2_t_link(dialogs_to_destroy, dialog, "Link dialog for destruction"); 17703 return 0; 17704 } 17705 17706 sip_pvt_unlock(dialog); 17707 17708 return 0; 17709 }
| struct sip_pvt* dialog_ref_debug | ( | struct sip_pvt * | p, | |
| char * | tag, | |||
| char * | file, | |||
| int | line, | |||
| const char * | func | |||
| ) | [read] |
Definition at line 2221 of file chan_sip.c.
References __ao2_ref_debug(), ao2_ref, ast_log(), and LOG_ERROR.
02222 { 02223 if (p) 02224 #ifdef REF_DEBUG 02225 __ao2_ref_debug(p, 1, tag, file, line, func); 02226 #else 02227 ao2_ref(p, 1); 02228 #endif 02229 else 02230 ast_log(LOG_ERROR, "Attempt to Ref a null pointer\n"); 02231 return p; 02232 }
| void dialog_unlink_all | ( | struct sip_pvt * | dialog | ) |
Unlink a dialog from the dialogs container, as well as any other places that it may be currently stored.
Definition at line 3089 of file chan_sip.c.
References ao2_t_unlink, ast_channel_unlock, ast_channel_unref, ast_debug, ast_extension_state_del(), ast_free, AST_SCHED_DEL, AST_SCHED_DEL_UNREF, cb_extensionstate(), registry_unref(), sip_pvt_lock_full(), sip_pvt_unlock, stop_session_timer(), and ast_channel::tech_pvt.
Referenced by __sip_autodestruct(), __sip_subscribe_mwi_do(), cleanup_all_regs(), dialog_unlink_callback(), handle_request_subscribe(), manager_sipnotify(), sip_cli_notify(), sip_destroy_peer(), sip_poke_noanswer(), sip_poke_peer(), sip_registry_destroy(), sip_request_call(), sip_send_mwi_to_peer(), transmit_publish(), transmit_register(), and unload_module().
03090 { 03091 struct sip_pkt *cp; 03092 struct ast_channel *owner; 03093 03094 dialog_ref(dialog, "Let's bump the count in the unlink so it doesn't accidentally become dead before we are done"); 03095 03096 ao2_t_unlink(dialogs, dialog, "unlinking dialog via ao2_unlink"); 03097 03098 /* Unlink us from the owner (channel) if we have one */ 03099 owner = sip_pvt_lock_full(dialog); 03100 if (owner) { 03101 ast_debug(1, "Detaching from channel %s\n", owner->name); 03102 owner->tech_pvt = dialog_unref(owner->tech_pvt, "resetting channel dialog ptr in unlink_all"); 03103 ast_channel_unlock(owner); 03104 ast_channel_unref(owner); 03105 dialog->owner = NULL; 03106 } 03107 sip_pvt_unlock(dialog); 03108 03109 if (dialog->registry) { 03110 if (dialog->registry->call == dialog) { 03111 dialog->registry->call = dialog_unref(dialog->registry->call, "nulling out the registry's call dialog field in unlink_all"); 03112 } 03113 dialog->registry = registry_unref(dialog->registry, "delete dialog->registry"); 03114 } 03115 if (dialog->stateid != -1) { 03116 ast_extension_state_del(dialog->stateid, cb_extensionstate); 03117 dialog->stateid = -1; 03118 } 03119 /* Remove link from peer to subscription of MWI */ 03120 if (dialog->relatedpeer && dialog->relatedpeer->mwipvt == dialog) { 03121 dialog->relatedpeer->mwipvt = dialog_unref(dialog->relatedpeer->mwipvt, "delete ->relatedpeer->mwipvt"); 03122 } 03123 if (dialog->relatedpeer && dialog->relatedpeer->call == dialog) { 03124 dialog->relatedpeer->call = dialog_unref(dialog->relatedpeer->call, "unset the relatedpeer->call field in tandem with relatedpeer field itself"); 03125 } 03126 03127 /* remove all current packets in this dialog */ 03128 while((cp = dialog->packets)) { 03129 dialog->packets = dialog->packets->next; 03130 AST_SCHED_DEL(sched, cp->retransid); 03131 dialog_unref(cp->owner, "remove all current packets in this dialog, and the pointer to the dialog too as part of __sip_destroy"); 03132 if (cp->data) { 03133 ast_free(cp->data); 03134 } 03135 ast_free(cp); 03136 } 03137 03138 AST_SCHED_DEL_UNREF(sched, dialog->waitid, dialog_unref(dialog, "when you delete the waitid sched, you should dec the refcount for the stored dialog ptr")); 03139 03140 AST_SCHED_DEL_UNREF(sched, dialog->initid, dialog_unref(dialog, "when you delete the initid sched, you should dec the refcount for the stored dialog ptr")); 03141 03142 if (dialog->autokillid > -1) { 03143 AST_SCHED_DEL_UNREF(sched, dialog->autokillid, dialog_unref(dialog, "when you delete the autokillid sched, you should dec the refcount for the stored dialog ptr")); 03144 } 03145 03146 if (dialog->request_queue_sched_id > -1) { 03147 AST_SCHED_DEL_UNREF(sched, dialog->request_queue_sched_id, dialog_unref(dialog, "when you delete the request_queue_sched_id sched, you should dec the refcount for the stored dialog ptr")); 03148 } 03149 03150 AST_SCHED_DEL_UNREF(sched, dialog->provisional_keepalive_sched_id, dialog_unref(dialog, "when you delete the provisional_keepalive_sched_id, you should dec the refcount for the stored dialog ptr")); 03151 03152 if (dialog->t38id > -1) { 03153 AST_SCHED_DEL_UNREF(sched, dialog->t38id, dialog_unref(dialog, "when you delete the t38id sched, you should dec the refcount for the stored dialog ptr")); 03154 } 03155 03156 if (dialog->stimer) { 03157 stop_session_timer(dialog); 03158 } 03159 03160 dialog_unref(dialog, "Let's unbump the count in the unlink so the poor pvt can disappear if it is time"); 03161 }
| static int dialog_unlink_callback | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 17721 of file chan_sip.c.
References CMP_MATCH, and dialog_unlink_all().
Referenced by do_monitor().
17722 { 17723 struct sip_pvt *dialog = obj; 17724 17725 dialog_unlink_all(dialog); 17726 17727 return CMP_MATCH; 17728 }
| struct sip_pvt* dialog_unref_debug | ( | struct sip_pvt * | p, | |
| char * | tag, | |||
| char * | file, | |||
| int | line, | |||
| const char * | func | |||
| ) | [read] |
Definition at line 2234 of file chan_sip.c.
References __ao2_ref_debug(), and ao2_ref.
02235 { 02236 if (p) 02237 #ifdef REF_DEBUG 02238 __ao2_ref_debug(p, -1, tag, file, line, func); 02239 #else 02240 ao2_ref(p, -1); 02241 #endif 02242 return NULL; 02243 }
| static void disable_dsp_detect | ( | struct sip_pvt * | p | ) | [static] |
Definition at line 4489 of file chan_sip.c.
References ast_dsp_free().
Referenced by sip_dtmfmode(), sip_hangup(), and sip_setoption().
04490 { 04491 if (p->dsp) { 04492 ast_dsp_free(p->dsp); 04493 p->dsp = NULL; 04494 } 04495 }
| static void display_nat_warning | ( | const char * | cat, | |
| int | reason, | |||
| struct ast_flags * | flags | |||
| ) | [static] |
Definition at line 28729 of file chan_sip.c.
References AST_CLI_YESNO, ast_log(), ast_test_flag, CHANNEL_MODULE_LOAD, and LOG_WARNING.
Referenced by reload_config().
28729 { 28730 int global_nat, specific_nat; 28731 28732 if (reason == CHANNEL_MODULE_LOAD && (specific_nat = ast_test_flag(&flags[0], SIP_NAT_FORCE_RPORT)) != (global_nat = ast_test_flag(&global_flags[0], SIP_NAT_FORCE_RPORT))) { 28733 ast_log(LOG_WARNING, "!!! PLEASE NOTE: Setting 'nat' for a peer/user that differs from the global setting can make\n"); 28734 ast_log(LOG_WARNING, "!!! the name of that peer/user discoverable by an attacker. Replies for non-existent peers/users\n"); 28735 ast_log(LOG_WARNING, "!!! will be sent to a different port than replies for an existing peer/user. If at all possible,\n"); 28736 ast_log(LOG_WARNING, "!!! use the global 'nat' setting and do not set 'nat' per peer/user.\n"); 28737 ast_log(LOG_WARNING, "!!! (config category='%s' global force_rport='%s' peer/user force_rport='%s')\n", cat, AST_CLI_YESNO(global_nat), AST_CLI_YESNO(specific_nat)); 28738 } 28739 }
| static int do_magic_pickup | ( | struct ast_channel * | channel, | |
| const char * | extension, | |||
| const char * | context | |||
| ) | [static] |
Definition at line 22887 of file chan_sip.c.
References ast_debug, ast_log(), AST_MAX_CONTEXT, AST_MAX_EXTENSION, ast_str_alloca, ast_str_buffer(), ast_str_set(), LOG_ERROR, pbx_exec(), pbx_findapp(), sip_cfg, and str.
Referenced by handle_request_invite().
22888 { 22889 struct ast_str *str = ast_str_alloca(AST_MAX_EXTENSION + AST_MAX_CONTEXT + 2); 22890 struct ast_app *pickup = pbx_findapp("Pickup"); 22891 22892 if (!pickup) { 22893 ast_log(LOG_ERROR, "Unable to perform pickup: Application 'Pickup' not loaded (app_directed_pickup.so).\n"); 22894 return -1; 22895 } 22896 22897 ast_str_set(&str, 0, "%s@%s", extension, sip_cfg.notifycid == IGNORE_CONTEXT ? "PICKUPMARK" : context); 22898 22899 ast_debug(2, "About to call Pickup(%s)\n", ast_str_buffer(str)); 22900 22901 /* There is no point in capturing the return value since pickup_exec 22902 doesn't return anything meaningful unless the passed data is an empty 22903 string (which in our case it will not be) */ 22904 pbx_exec(channel, pickup, ast_str_buffer(str)); 22905 22906 return 0; 22907 }
| static void * do_monitor | ( | void * | data | ) | [static] |
The SIP monitoring thread.
Definition at line 26612 of file chan_sip.c.
References ao2_container_count(), ao2_t_callback, ast_debug, ast_io_add(), ast_io_change(), AST_IO_IN, ast_io_remove(), ast_io_wait(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_sched_runq(), ast_sched_wait(), ast_verb, dialog_needdestroy(), dialog_unlink_callback(), FALSE, LOG_WARNING, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, sip_do_reload(), and sipsock_read().
Referenced by restart_monitor().
26613 { 26614 int res; 26615 time_t t; 26616 int reloading; 26617 26618 /* Add an I/O event to our SIP UDP socket */ 26619 if (sipsock > -1) 26620 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 26621 26622 /* From here on out, we die whenever asked */ 26623 for(;;) { 26624 /* Check for a reload request */ 26625 ast_mutex_lock(&sip_reload_lock); 26626 reloading = sip_reloading; 26627 sip_reloading = FALSE; 26628 ast_mutex_unlock(&sip_reload_lock); 26629 if (reloading) { 26630 ast_verb(1, "Reloading SIP\n"); 26631 sip_do_reload(sip_reloadreason); 26632 26633 /* Change the I/O fd of our UDP socket */ 26634 if (sipsock > -1) { 26635 if (sipsock_read_id) 26636 sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL); 26637 else 26638 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 26639 } else if (sipsock_read_id) { 26640 ast_io_remove(io, sipsock_read_id); 26641 sipsock_read_id = NULL; 26642 } 26643 } 26644 26645 /* Check for dialogs needing to be killed */ 26646 t = time(NULL); 26647 /* don't scan the dialogs list if it hasn't been a reasonable period 26648 of time since the last time we did it (when MWI is being sent, we can 26649 get back to this point every millisecond or less) 26650 */ 26651 /* 26652 * We cannot hold the dialogs container lock when we destroy a 26653 * dialog because of potential deadlocks. Instead we link the 26654 * doomed dialog into dialogs_to_destroy and then iterate over 26655 * that container destroying the dialogs. 26656 */ 26657 ao2_t_callback(dialogs, OBJ_NODATA | OBJ_MULTIPLE, dialog_needdestroy, &t, 26658 "callback to monitor dialog status"); 26659 if (ao2_container_count(dialogs_to_destroy)) { 26660 /* Now destroy the found dialogs that need to be destroyed. */ 26661 ao2_t_callback(dialogs_to_destroy, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, 26662 dialog_unlink_callback, NULL, "callback to dialog_unlink_all"); 26663 } 26664 26665 /* XXX TODO The scheduler usage in this module does not have sufficient 26666 * synchronization being done between running the scheduler and places 26667 * scheduling tasks. As it is written, any scheduled item may not run 26668 * any sooner than about 1 second, regardless of whether a sooner time 26669 * was asked for. */ 26670 26671 pthread_testcancel(); 26672 /* Wait for sched or io */ 26673 res = ast_sched_wait(sched); 26674 if ((res < 0) || (res > 1000)) 26675 res = 1000; 26676 res = ast_io_wait(io, res); 26677 if (res > 20) 26678 ast_debug(1, "chan_sip: ast_io_wait ran %d all at once\n", res); 26679 ast_mutex_lock(&monlock); 26680 res = ast_sched_runq(sched); 26681 if (res >= 20) 26682 ast_debug(1, "chan_sip: ast_sched_runq ran %d all at once\n", res); 26683 if (global_store_sip_cause && res >= 100) 26684 ast_log(LOG_WARNING, "scheduler delays detected, setting 'storesipcause' to 'no' in %s will improve performance\n", config); 26685 ast_mutex_unlock(&monlock); 26686 } 26687 26688 /* Never reached */ 26689 return NULL; 26690 }
| static int do_proxy_auth | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| enum sip_auth_type | code, | |||
| int | sipmethod, | |||
| int | init | |||
| ) | [static] |
Add authentication on outbound SIP packet.
Definition at line 19822 of file chan_sip.c.
References ast_calloc, ast_debug, auth_headers(), reply_digest(), sip_methods, cfsip_methods::text, and transmit_invite().
Referenced by handle_response(), handle_response_invite(), handle_response_notify(), handle_response_publish(), handle_response_refer(), handle_response_subscribe(), and handle_response_update().
19823 { 19824 char *header, *respheader; 19825 char digest[1024]; 19826 19827 if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options)))) 19828 return -2; 19829 19830 p->authtries++; 19831 auth_headers(code, &header, &respheader); 19832 ast_debug(2, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text); 19833 memset(digest, 0, sizeof(digest)); 19834 if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) { 19835 /* No way to authenticate */ 19836 return -1; 19837 } 19838 /* Now we have a reply digest */ 19839 p->options->auth = digest; 19840 p->options->authheader = respheader; 19841 return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init, NULL); 19842 }
| static int do_register_auth | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| enum sip_auth_type | code | |||
| ) | [static] |
Authenticate for outbound registration.
Definition at line 19798 of file chan_sip.c.
References append_history, ast_verbose, auth_headers(), reply_digest(), sip_debug_test_pvt(), and transmit_register().
Referenced by handle_response_register().
19799 { 19800 char *header, *respheader; 19801 char digest[1024]; 19802 19803 p->authtries++; 19804 auth_headers(code, &header, &respheader); 19805 memset(digest, 0, sizeof(digest)); 19806 if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) { 19807 /* There's nothing to use for authentication */ 19808 /* No digest challenge in request */ 19809 if (sip_debug_test_pvt(p) && p->registry) 19810 ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); 19811 /* No old challenge */ 19812 return -1; 19813 } 19814 if (p->do_history) 19815 append_history(p, "RegistryAuth", "Try: %d", p->authtries); 19816 if (sip_debug_test_pvt(p) && p->registry) 19817 ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); 19818 return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 19819 }
| static void do_setnat | ( | struct sip_pvt * | p | ) | [static] |
Set nat mode on the various data sockets.
Definition at line 5314 of file chan_sip.c.
References ast_debug, ast_rtp_instance_set_prop(), AST_RTP_PROPERTY_NAT, ast_test_flag, and ast_udptl_setnat().
Referenced by check_peer_ok(), dialog_initialize_rtp(), sip_alloc(), and transmit_response_using_temp().
05315 { 05316 const char *mode; 05317 int natflags; 05318 05319 natflags = ast_test_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP); 05320 mode = natflags ? "On" : "Off"; 05321 05322 if (p->rtp) { 05323 ast_debug(1, "Setting NAT on RTP to %s\n", mode); 05324 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_NAT, natflags); 05325 } 05326 if (p->vrtp) { 05327 ast_debug(1, "Setting NAT on VRTP to %s\n", mode); 05328 ast_rtp_instance_set_prop(p->vrtp, AST_RTP_PROPERTY_NAT, natflags); 05329 } 05330 if (p->udptl) { 05331 ast_debug(1, "Setting NAT on UDPTL to %s\n", mode); 05332 ast_udptl_setnat(p->udptl, natflags); 05333 } 05334 if (p->trtp) { 05335 ast_debug(1, "Setting NAT on TRTP to %s\n", mode); 05336 ast_rtp_instance_set_prop(p->trtp, AST_RTP_PROPERTY_NAT, natflags); 05337 } 05338 }
| static const char * domain_mode_to_text | ( | const enum domain_mode | mode | ) | [static] |
Print domain mode to cli.
Definition at line 17890 of file chan_sip.c.
Referenced by sip_show_domains().
| static const char * dtmfmode2str | ( | int | mode | ) | [static] |
Convert DTMF mode to printable string.
Definition at line 17569 of file chan_sip.c.
References map_x_s().
Referenced by _sip_show_peer(), sip_show_channel(), and sip_show_settings().
| static void enable_dsp_detect | ( | struct sip_pvt * | p | ) | [static] |
Definition at line 4455 of file chan_sip.c.
References ast_dsp_new(), ast_dsp_set_digitmode(), ast_dsp_set_features(), AST_RTP_DTMF_MODE_INBAND, ast_rtp_instance_dtmf_mode_set(), ast_test_flag, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_RELAXDTMF, DSP_FEATURE_DIGIT_DETECT, and DSP_FEATURE_FAX_DETECT.
Referenced by sip_dtmfmode(), sip_new(), and sip_setoption().
04456 { 04457 int features = 0; 04458 04459 if (p->dsp) { 04460 return; 04461 } 04462 04463 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || 04464 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) { 04465 if (p->rtp) { 04466 ast_rtp_instance_dtmf_mode_set(p->rtp, AST_RTP_DTMF_MODE_INBAND); 04467 } 04468 features |= DSP_FEATURE_DIGIT_DETECT; 04469 } 04470 04471 if (ast_test_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_CNG)) { 04472 features |= DSP_FEATURE_FAX_DETECT; 04473 } 04474 04475 if (!features) { 04476 return; 04477 } 04478 04479 if (!(p->dsp = ast_dsp_new())) { 04480 return; 04481 } 04482 04483 ast_dsp_set_features(p->dsp, features); 04484 if (global_relaxdtmf) { 04485 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); 04486 } 04487 }
| static int esc_cmp_fn | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 980 of file chan_sip.c.
References CMP_MATCH, and CMP_STOP.
Referenced by initialize_escs().
| static void esc_entry_destructor | ( | void * | obj | ) | [static] |
Definition at line 966 of file chan_sip.c.
References AST_SCHED_DEL.
Referenced by create_esc_entry().
00967 { 00968 struct sip_esc_entry *esc_entry = obj; 00969 if (esc_entry->sched_id > -1) { 00970 AST_SCHED_DEL(sched, esc_entry->sched_id); 00971 } 00972 }
| static int esc_hash_fn | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 974 of file chan_sip.c.
References ast_str_hash().
Referenced by initialize_escs().
00975 { 00976 const struct sip_esc_entry *entry = obj; 00977 return ast_str_hash(entry->entity_tag); 00978 }
| static int expire_register | ( | const void * | data | ) | [static] |
Expire registration of SIP peer.
Definition at line 14216 of file chan_sip.c.
References ao2_ref, ao2_t_unlink, ast_debug, AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_sockaddr_isnull(), ast_test_flag, destroy_association(), EVENT_FLAG_SYSTEM, FALSE, manager_event, register_peer_exten(), set_socket_transport(), unlink_peer_from_tables(), and unref_peer().
Referenced by parse_register_contact(), realtime_peer(), reg_source_db(), sip_show_sched(), and sip_unregister().
14217 { 14218 struct sip_peer *peer = (struct sip_peer *)data; 14219 14220 if (!peer) { /* Hmmm. We have no peer. Weird. */ 14221 return 0; 14222 } 14223 14224 peer->expire = -1; 14225 peer->portinuri = 0; 14226 14227 destroy_association(peer); /* remove registration data from storage */ 14228 set_socket_transport(&peer->socket, peer->default_outbound_transport); 14229 14230 if (peer->socket.tcptls_session) { 14231 ao2_ref(peer->socket.tcptls_session, -1); 14232 peer->socket.tcptls_session = NULL; 14233 } 14234 14235 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 14236 register_peer_exten(peer, FALSE); /* Remove regexten */ 14237 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", peer->name); 14238 14239 /* Do we need to release this peer from memory? 14240 Only for realtime peers and autocreated peers 14241 */ 14242 if (peer->is_realtime) { 14243 ast_debug(3, "-REALTIME- peer expired registration. Name: %s. Realtime peer objects now %d\n", peer->name, rpeerobjs); 14244 } 14245 14246 if (peer->selfdestruct || 14247 ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 14248 unlink_peer_from_tables(peer); 14249 } else if (!ast_sockaddr_isnull(&peer->addr)) { 14250 /* If we aren't self-destructing a temp_peer, we still need to unlink the peer 14251 * from the peers_by_ip table, otherwise we end up with multiple copies hanging 14252 * around each time a registration expires and the peer re-registers. */ 14253 ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table"); 14254 } 14255 14256 /* Only clear the addr after we check for destruction. The addr must remain 14257 * in order to unlink from the peers_by_ip container correctly */ 14258 memset(&peer->addr, 0, sizeof(peer->addr)); 14259 14260 unref_peer(peer, "removing peer ref for expire_register"); 14261 14262 return 0; 14263 }
| static void extract_host_from_hostport | ( | char ** | hostport | ) | [static] |
Terminate a host:port at the ':'.
| hostport | The address of the hostport string |
Definition at line 15251 of file chan_sip.c.
References ast_sockaddr_split_hostport(), and PARSE_PORT_IGNORE.
Referenced by check_user_full(), get_destination(), and register_verify().
15252 { 15253 char *dont_care; 15254 ast_sockaddr_split_hostport(*hostport, hostport, &dont_care, PARSE_PORT_IGNORE); 15255 }
| static void extract_uri | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Check Contact: URI of SIP message.
Definition at line 12313 of file chan_sip.c.
References ast_copy_string(), ast_string_field_set, ast_strlen_zero(), get_header(), get_in_brackets(), and remove_uri_parameters().
Referenced by handle_incoming(), and handle_request_invite().
12314 { 12315 char stripped[SIPBUFSIZE]; 12316 char *c; 12317 12318 ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped)); 12319 c = get_in_brackets(stripped); 12320 /* Cut the URI at the at sign after the @, not in the username part */ 12321 c = remove_uri_parameters(c); 12322 if (!ast_strlen_zero(c)) { 12323 ast_string_field_set(p, uri, c); 12324 } 12325 12326 }
| static const char* faxec2str | ( | int | faxec | ) | [static] |
Definition at line 18054 of file chan_sip.c.
References map_x_s().
Referenced by _sip_show_peer(), and sip_show_settings().
18055 { 18056 return map_x_s(faxecmodes, faxec, "Unknown"); 18057 }
| static int finalize_content | ( | struct sip_request * | req | ) | [static] |
Add 'Content-Length' header and content to SIP message.
Definition at line 10256 of file chan_sip.c.
References add_header(), ast_log(), ast_str_append(), ast_str_buffer(), ast_str_strlen(), and LOG_WARNING.
Referenced by send_request(), and send_response().
10257 { 10258 char clen[10]; 10259 10260 if (req->lines) { 10261 ast_log(LOG_WARNING, "finalize_content() called on a message that has already been finalized\n"); 10262 return -1; 10263 } 10264 10265 snprintf(clen, sizeof(clen), "%zu", ast_str_strlen(req->content)); 10266 add_header(req, "Content-Length", clen); 10267 10268 if (ast_str_strlen(req->content)) { 10269 ast_str_append(&req->data, 0, "\r\n%s", ast_str_buffer(req->content)); 10270 } 10271 req->lines = ast_str_strlen(req->content) ? 1 : 0; 10272 return 0; 10273 }
| static const char * find_alias | ( | const char * | name, | |
| const char * | _default | |||
| ) | [static] |
Find compressed SIP alias.
Structure for conversion between compressed SIP and "normal" SIP
Definition at line 7606 of file chan_sip.c.
References aliases, and ARRAY_LEN.
Referenced by __get_header(), and add_header().
07607 { 07608 /*! \brief Structure for conversion between compressed SIP and "normal" SIP */ 07609 static const struct cfalias { 07610 char * const fullname; 07611 char * const shortname; 07612 } aliases[] = { 07613 { "Content-Type", "c" }, 07614 { "Content-Encoding", "e" }, 07615 { "From", "f" }, 07616 { "Call-ID", "i" }, 07617 { "Contact", "m" }, 07618 { "Content-Length", "l" }, 07619 { "Subject", "s" }, 07620 { "To", "t" }, 07621 { "Supported", "k" }, 07622 { "Refer-To", "r" }, 07623 { "Referred-By", "b" }, 07624 { "Allow-Events", "u" }, 07625 { "Event", "o" }, 07626 { "Via", "v" }, 07627 { "Accept-Contact", "a" }, 07628 { "Reject-Contact", "j" }, 07629 { "Request-Disposition", "d" }, 07630 { "Session-Expires", "x" }, 07631 { "Identity", "y" }, 07632 { "Identity-Info", "n" }, 07633 }; 07634 int x; 07635 07636 for (x = 0; x < ARRAY_LEN(aliases); x++) { 07637 if (!strcasecmp(aliases[x].fullname, name)) 07638 return aliases[x].shortname; 07639 } 07640 07641 return _default; 07642 }
| static int find_by_callid_helper | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1684 of file chan_sip.c.
References CMP_MATCH, CMP_STOP, and ast_cc_agent::private_data.
Referenced by find_sip_cc_agent_by_original_callid().
01685 { 01686 struct ast_cc_agent *agent = obj; 01687 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01688 struct sip_pvt *call_pvt = arg; 01689 01690 return !strcmp(agent_pvt->original_callid, call_pvt->callid) ? CMP_MATCH | CMP_STOP : 0; 01691 }
| static int find_by_name | ( | void * | obj, | |
| void * | arg, | |||
| void * | data, | |||
| int | flags | |||
| ) | [static] |
Definition at line 5225 of file chan_sip.c.
References CMP_MATCH, CMP_STOP, and match().
Referenced by find_peer().
05226 { 05227 struct sip_peer *search = obj, *match = arg; 05228 int *which_objects = data; 05229 05230 /* Usernames in SIP uri's are case sensitive. Domains are not */ 05231 if (strcmp(search->name, match->name)) { 05232 return 0; 05233 } 05234 05235 switch (*which_objects) { 05236 case FINDUSERS: 05237 if (!(search->type & SIP_TYPE_USER)) { 05238 return 0; 05239 } 05240 break; 05241 case FINDPEERS: 05242 if (!(search->type & SIP_TYPE_PEER)) { 05243 return 0; 05244 } 05245 break; 05246 case FINDALLDEVICES: 05247 break; 05248 } 05249 05250 return CMP_MATCH | CMP_STOP; 05251 }
| static int find_by_notify_uri_helper | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1654 of file chan_sip.c.
References CMP_MATCH, CMP_STOP, ast_cc_agent::private_data, and sip_uri_cmp().
Referenced by find_sip_cc_agent_by_notify_uri().
01655 { 01656 struct ast_cc_agent *agent = obj; 01657 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01658 const char *uri = arg; 01659 01660 return !sip_uri_cmp(agent_pvt->notify_uri, uri) ? CMP_MATCH | CMP_STOP : 0; 01661 }
| static int find_by_subscribe_uri_helper | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1669 of file chan_sip.c.
References CMP_MATCH, CMP_STOP, ast_cc_agent::private_data, and sip_uri_cmp().
Referenced by find_sip_cc_agent_by_subscribe_uri().
01670 { 01671 struct ast_cc_agent *agent = obj; 01672 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01673 const char *uri = arg; 01674 01675 return !sip_uri_cmp(agent_pvt->subscribe_uri, uri) ? CMP_MATCH | CMP_STOP : 0; 01676 }
| static struct sip_pvt * find_call | ( | struct sip_request * | req, | |
| struct ast_sockaddr * | addr, | |||
| const int | intended_method | |||
| ) | [static, read] |
find or create a dialog structure for an incoming SIP message. Connect incoming SIP message to current dialog or create new dialog structure Returns a reference to the sip_pvt object, remember to give it back once done. Called by handle_request_do
Definition at line 8382 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_next, ao2_t_callback, ao2_t_find, args, ast_debug, ast_strlen_zero(), match_req_args::authentication_present, match_req_args::callid, dialog_find_multiple(), free_via(), match_req_args::fromtag, get_header(), gettag(), match_req_to_dialog(), match_req_args::method, OBJ_MULTIPLE, OBJ_POINTER, parse_via(), match_req_args::ruri, match_req_args::seqno, sip_alloc(), sip_cfg, sip_methods, sip_pvt_lock, sip_pvt_unlock, SIP_REQ_LOOP_DETECTED, SIP_REQ_MATCH, SIP_REQ_NOT_MATCH, cfsip_methods::text, match_req_args::totag, transmit_response_using_temp(), match_req_args::viabranch, and match_req_args::viasentby.
Referenced by handle_request_do().
08383 { 08384 char totag[128]; 08385 char fromtag[128]; 08386 const char *callid = get_header(req, "Call-ID"); 08387 const char *from = get_header(req, "From"); 08388 const char *to = get_header(req, "To"); 08389 const char *cseq = get_header(req, "Cseq"); 08390 struct sip_pvt *sip_pvt_ptr; 08391 uint32_t seqno; 08392 /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */ 08393 /* get_header always returns non-NULL so we must use ast_strlen_zero() */ 08394 if (ast_strlen_zero(callid) || ast_strlen_zero(to) || 08395 ast_strlen_zero(from) || ast_strlen_zero(cseq) || 08396 (sscanf(cseq, "%30u", &seqno) != 1)) { 08397 08398 /* RFC 3261 section 24.4.1. Send a 400 Bad Request if the request is malformed. */ 08399 if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) { 08400 transmit_response_using_temp(callid, addr, 1, intended_method, 08401 req, "400 Bad Request"); 08402 } 08403 return NULL; /* Invalid packet */ 08404 } 08405 08406 if (sip_cfg.pedanticsipchecking) { 08407 /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy 08408 we need more to identify a branch - so we have to check branch, from 08409 and to tags to identify a call leg. 08410 For Asterisk to behave correctly, you need to turn on pedanticsipchecking 08411 in sip.conf 08412 */ 08413 if (gettag(req, "To", totag, sizeof(totag))) 08414 req->has_to_tag = 1; /* Used in handle_request/response */ 08415 gettag(req, "From", fromtag, sizeof(fromtag)); 08416 08417 ast_debug(5, "= Looking for Call ID: %s (Checking %s) --From tag %s --To-tag %s \n", callid, req->method==SIP_RESPONSE ? "To" : "From", fromtag, totag); 08418 08419 /* All messages must always have From: tag */ 08420 if (ast_strlen_zero(fromtag)) { 08421 ast_debug(5, "%s request has no from tag, dropping callid: %s from: %s\n", sip_methods[req->method].text , callid, from ); 08422 return NULL; 08423 } 08424 /* reject requests that must always have a To: tag */ 08425 if (ast_strlen_zero(totag) && (req->method == SIP_ACK || req->method == SIP_BYE || req->method == SIP_INFO )) { 08426 ast_debug(5, "%s must have a to tag. dropping callid: %s from: %s\n", sip_methods[req->method].text , callid, from ); 08427 return NULL; 08428 } 08429 } 08430 08431 if (!sip_cfg.pedanticsipchecking) { 08432 struct sip_pvt tmp_dialog = { 08433 .callid = callid, 08434 }; 08435 sip_pvt_ptr = ao2_t_find(dialogs, &tmp_dialog, OBJ_POINTER, "ao2_find in dialogs"); 08436 if (sip_pvt_ptr) { /* well, if we don't find it-- what IS in there? */ 08437 /* Found the call */ 08438 return sip_pvt_ptr; 08439 } 08440 } else { /* in pedantic mode! -- do the fancy search */ 08441 struct sip_pvt tmp_dialog = { 08442 .callid = callid, 08443 }; 08444 struct match_req_args args = { 0, }; 08445 int found; 08446 struct ao2_iterator *iterator = ao2_t_callback(dialogs, 08447 OBJ_POINTER | OBJ_MULTIPLE, 08448 dialog_find_multiple, 08449 &tmp_dialog, 08450 "pedantic ao2_find in dialogs"); 08451 struct sip_via *via = NULL; 08452 08453 args.method = req->method; 08454 args.callid = NULL; /* we already matched this. */ 08455 args.totag = totag; 08456 args.fromtag = fromtag; 08457 args.seqno = seqno; 08458 08459 /* If this is a Request, set the Via and Authorization header arguments */ 08460 if (req->method != SIP_RESPONSE) { 08461 args.ruri = REQ_OFFSET_TO_STR(req, rlPart2); 08462 via = parse_via(get_header(req, "Via")); 08463 if (via) { 08464 args.viasentby = via->sent_by; 08465 args.viabranch = via->branch; 08466 } 08467 if (!ast_strlen_zero(get_header(req, "Authorization")) || 08468 !ast_strlen_zero(get_header(req, "Proxy-Authorization"))) { 08469 args.authentication_present = 1; 08470 } 08471 } 08472 08473 /* Iterate a list of dialogs already matched by Call-id */ 08474 while (iterator && (sip_pvt_ptr = ao2_iterator_next(iterator))) { 08475 sip_pvt_lock(sip_pvt_ptr); 08476 found = match_req_to_dialog(sip_pvt_ptr, &args); 08477 sip_pvt_unlock(sip_pvt_ptr); 08478 08479 switch (found) { 08480 case SIP_REQ_MATCH: 08481 ao2_iterator_destroy(iterator); 08482 free_via(via); 08483 return sip_pvt_ptr; /* return pvt with ref */ 08484 case SIP_REQ_LOOP_DETECTED: 08485 /* This is likely a forked Request that somehow resulted in us receiving multiple parts of the fork. 08486 * RFC 3261 section 8.2.2.2, Indicate that we want to merge requests by sending a 482 response. */ 08487 transmit_response_using_temp(callid, addr, 1, intended_method, req, "482 (Loop Detected)"); 08488 dialog_unref(sip_pvt_ptr, "pvt did not match incoming SIP msg, unref from search."); 08489 ao2_iterator_destroy(iterator); 08490 free_via(via); 08491 return NULL; 08492 case SIP_REQ_NOT_MATCH: 08493 default: 08494 dialog_unref(sip_pvt_ptr, "pvt did not match incoming SIP msg, unref from search"); 08495 break; 08496 } 08497 } 08498 if (iterator) { 08499 ao2_iterator_destroy(iterator); 08500 } 08501 08502 free_via(via); 08503 } /* end of pedantic mode Request/Reponse to Dialog matching */ 08504 08505 /* See if the method is capable of creating a dialog */ 08506 if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) { 08507 struct sip_pvt *p = NULL; 08508 08509 if (intended_method == SIP_REFER) { 08510 /* We do support REFER, but not outside of a dialog yet */ 08511 transmit_response_using_temp(callid, addr, 1, intended_method, req, "603 Declined (no dialog)"); 08512 08513 /* Ok, time to create a new SIP dialog object, a pvt */ 08514 } else if (!(p = sip_alloc(callid, addr, 1, intended_method, req))) { 08515 /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not 08516 getting a dialog from sip_alloc. 08517 08518 Without a dialog we can't retransmit and handle ACKs and all that, but at least 08519 send an error message. 08520 08521 Sorry, we apologize for the inconvienience 08522 */ 08523 transmit_response_using_temp(callid, addr, 1, intended_method, req, "500 Server internal error"); 08524 ast_debug(4, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n"); 08525 } 08526 return p; /* can be NULL */ 08527 } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) { 08528 /* A method we do not support, let's take it on the volley */ 08529 transmit_response_using_temp(callid, addr, 1, intended_method, req, "501 Method Not Implemented"); 08530 ast_debug(2, "Got a request with unsupported SIP method.\n"); 08531 } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) { 08532 /* This is a request outside of a dialog that we don't know about */ 08533 transmit_response_using_temp(callid, addr, 1, intended_method, req, "481 Call leg/transaction does not exist"); 08534 ast_debug(2, "That's odd... Got a request in unknown dialog. Callid %s\n", callid ? callid : "<unknown>"); 08535 } 08536 /* We do not respond to responses for dialogs that we don't know about, we just drop 08537 the session quickly */ 08538 if (intended_method == SIP_RESPONSE) 08539 ast_debug(2, "That's odd... Got a response on a call we don't know about. Callid %s\n", callid ? callid : "<unknown>"); 08540 08541 return NULL; 08542 }
| static int find_calling_channel | ( | void * | obj, | |
| void * | arg, | |||
| void * | data, | |||
| int | flags | |||
| ) | [static] |
Find the channel that is causing the RINGING update.
Definition at line 12948 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, CMP_MATCH, CMP_STOP, ast_channel::context, ast_channel::exten, ast_channel::macroexten, ast_channel::pbx, and sip_cfg.
Referenced by state_notify_build_xml().
12949 { 12950 struct ast_channel *c = obj; 12951 struct sip_pvt *p = data; 12952 int res; 12953 12954 ast_channel_lock(c); 12955 12956 res = (c->pbx && 12957 (!strcasecmp(c->macroexten, p->exten) || !strcasecmp(c->exten, p->exten)) && 12958 (sip_cfg.notifycid == IGNORE_CONTEXT || !strcasecmp(c->context, p->context))); 12959 12960 ast_channel_unlock(c); 12961 12962 return res ? CMP_MATCH | CMP_STOP : 0; 12963 }
| const char* find_closing_quote | ( | const char * | start, | |
| const char * | lim | |||
| ) |
Locate closing quote in a string, skipping escaped quotes. optionally with a limit on the search. start must be past the first quote.
Definition at line 4630 of file chan_sip.c.
Referenced by get_comma(), get_in_brackets_const(), get_in_brackets_full(), and parse_moved_contact().
| 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.
| 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.
Definition at line 5266 of file chan_sip.c.
References ao2_t_callback_data, ao2_t_find, ast_copy_string(), ast_set_flag, ast_sockaddr_copy(), find_by_name(), OBJ_POINTER, realtime_peer(), and unref_peer().
Referenced by _sip_qualify_peer(), _sip_show_peer(), check_peer_ok(), create_addr(), function_sippeer(), handle_request_notify(), register_verify(), sip_devicestate(), sip_do_debug_peer(), sip_show_user(), sip_unregister(), and transmit_register().
05267 { 05268 struct sip_peer *p = NULL; 05269 struct sip_peer tmp_peer; 05270 05271 if (peer) { 05272 ast_copy_string(tmp_peer.name, peer, sizeof(tmp_peer.name)); 05273 p = ao2_t_callback_data(peers, OBJ_POINTER, find_by_name, &tmp_peer, &which_objects, "ao2_find in peers table"); 05274 } else if (addr) { /* search by addr? */ 05275 ast_sockaddr_copy(&tmp_peer.addr, addr); 05276 tmp_peer.flags[0].flags = 0; 05277 tmp_peer.transports = transport; 05278 p = ao2_t_find(peers_by_ip, &tmp_peer, OBJ_POINTER, "ao2_find in peers_by_ip table"); /* WAS: p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp); */ 05279 if (!p) { 05280 ast_set_flag(&tmp_peer.flags[0], SIP_INSECURE_PORT); 05281 p = ao2_t_find(peers_by_ip, &tmp_peer, OBJ_POINTER, "ao2_find in peers_by_ip table 2"); /* WAS: p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp); */ 05282 if (p) { 05283 return p; 05284 } 05285 } 05286 } 05287 05288 if (!p && (realtime || devstate_only)) { 05289 p = realtime_peer(peer, addr, devstate_only, which_objects); 05290 if (p) { 05291 switch (which_objects) { 05292 case FINDUSERS: 05293 if (!(p->type & SIP_TYPE_USER)) { 05294 unref_peer(p, "Wrong type of realtime SIP endpoint"); 05295 return NULL; 05296 } 05297 break; 05298 case FINDPEERS: 05299 if (!(p->type & SIP_TYPE_PEER)) { 05300 unref_peer(p, "Wrong type of realtime SIP endpoint"); 05301 return NULL; 05302 } 05303 break; 05304 case FINDALLDEVICES: 05305 break; 05306 } 05307 } 05308 } 05309 05310 return p; 05311 }
| static struct sip_auth * find_realm_authentication | ( | struct sip_auth_container * | credentials, | |
| const char * | realm | |||
| ) | [static, read] |
Definition at line 27883 of file chan_sip.c.
References AST_LIST_TRAVERSE.
Referenced by build_reply_digest().
27884 { 27885 struct sip_auth *auth; 27886 27887 if (credentials) { 27888 AST_LIST_TRAVERSE(&credentials->list, auth, node) { 27889 if (!strcasecmp(auth->realm, realm)) { 27890 break; 27891 } 27892 } 27893 } else { 27894 auth = NULL; 27895 } 27896 27897 return auth; 27898 }
| static int find_sdp | ( | struct sip_request * | req | ) | [static] |
Determine whether a SIP message contains an SDP in its body.
| req | the SIP request to process |
Also updates req->sdp_start and req->sdp_count to indicate where the SDP lives in the message body.
Definition at line 8894 of file chan_sip.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), FALSE, get_header(), LOG_WARNING, and TRUE.
Referenced by handle_incoming(), handle_request_invite(), handle_response(), and handle_response_invite().
08895 { 08896 const char *content_type; 08897 const char *content_length; 08898 const char *search; 08899 char *boundary; 08900 unsigned int x; 08901 int boundaryisquoted = FALSE; 08902 int found_application_sdp = FALSE; 08903 int found_end_of_headers = FALSE; 08904 08905 content_length = get_header(req, "Content-Length"); 08906 08907 if (!ast_strlen_zero(content_length)) { 08908 if (sscanf(content_length, "%30u", &x) != 1) { 08909 ast_log(LOG_WARNING, "Invalid Content-Length: %s\n", content_length); 08910 return 0; 08911 } 08912 08913 /* Content-Length of zero means there can't possibly be an 08914 SDP here, even if the Content-Type says there is */ 08915 if (x == 0) 08916 return 0; 08917 } 08918 08919 content_type = get_header(req, "Content-Type"); 08920 08921 /* if the body contains only SDP, this is easy */ 08922 if (!strncasecmp(content_type, "application/sdp", 15)) { 08923 req->sdp_start = 0; 08924 req->sdp_count = req->lines; 08925 return req->lines ? 1 : 0; 08926 } 08927 08928 /* if it's not multipart/mixed, there cannot be an SDP */ 08929 if (strncasecmp(content_type, "multipart/mixed", 15)) 08930 return 0; 08931 08932 /* if there is no boundary marker, it's invalid */ 08933 if ((search = strcasestr(content_type, ";boundary="))) 08934 search += 10; 08935 else if ((search = strcasestr(content_type, "; boundary="))) 08936 search += 11; 08937 else 08938 return 0; 08939 08940 if (ast_strlen_zero(search)) 08941 return 0; 08942 08943 /* If the boundary is quoted with ", remove quote */ 08944 if (*search == '\"') { 08945 search++; 08946 boundaryisquoted = TRUE; 08947 } 08948 08949 /* make a duplicate of the string, with two extra characters 08950 at the beginning */ 08951 boundary = ast_strdupa(search - 2); 08952 boundary[0] = boundary[1] = '-'; 08953 /* Remove final quote */ 08954 if (boundaryisquoted) 08955 boundary[strlen(boundary) - 1] = '\0'; 08956 08957 /* search for the boundary marker, the empty line delimiting headers from 08958 sdp part and the end boundry if it exists */ 08959 08960 for (x = 0; x < (req->lines); x++) { 08961 const char *line = REQ_OFFSET_TO_STR(req, line[x]); 08962 if (!strncasecmp(line, boundary, strlen(boundary))){ 08963 if (found_application_sdp && found_end_of_headers) { 08964 req->sdp_count = (x - 1) - req->sdp_start; 08965 return 1; 08966 } 08967 found_application_sdp = FALSE; 08968 } 08969 if (!strcasecmp(line, "Content-Type: application/sdp")) 08970 found_application_sdp = TRUE; 08971 08972 if (ast_strlen_zero(line)) { 08973 if (found_application_sdp && !found_end_of_headers){ 08974 req->sdp_start = x; 08975 found_end_of_headers = TRUE; 08976 } 08977 } 08978 } 08979 if (found_application_sdp && found_end_of_headers) { 08980 req->sdp_count = x - req->sdp_start; 08981 return TRUE; 08982 } 08983 return FALSE; 08984 }
| static struct ast_cc_agent* find_sip_cc_agent_by_notify_uri | ( | const char *const | uri | ) | [static, read] |
Definition at line 1663 of file chan_sip.c.
References ast_cc_agent_callback(), and find_by_notify_uri_helper().
Referenced by get_destination().
01664 { 01665 struct ast_cc_agent *agent = ast_cc_agent_callback(0, find_by_notify_uri_helper, (char *)uri, "SIP"); 01666 return agent; 01667 }
| static struct ast_cc_agent* find_sip_cc_agent_by_original_callid | ( | struct sip_pvt * | pvt | ) | [static, read] |
Definition at line 1693 of file chan_sip.c.
References ast_cc_agent_callback(), and find_by_callid_helper().
Referenced by add_cc_call_info_to_response().
01694 { 01695 struct ast_cc_agent *agent = ast_cc_agent_callback(0, find_by_callid_helper, pvt, "SIP"); 01696 return agent; 01697 }
| static struct ast_cc_agent* find_sip_cc_agent_by_subscribe_uri | ( | const char *const | uri | ) | [static, read] |
Definition at line 1678 of file chan_sip.c.
References ast_cc_agent_callback(), and find_by_subscribe_uri_helper().
Referenced by handle_cc_subscribe().
01679 { 01680 struct ast_cc_agent *agent = ast_cc_agent_callback(0, find_by_subscribe_uri_helper, (char *)uri, "SIP"); 01681 return agent; 01682 }
| static int find_sip_method | ( | const char * | msg | ) | [static] |
find_sip_method: Find SIP method from header
Definition at line 3356 of file chan_sip.c.
References ARRAY_LEN, ast_strlen_zero(), cfsip_methods::id, method_match(), and sip_methods.
Referenced by __sip_pretend_ack(), handle_request_do(), handle_response(), mark_parsed_methods(), and sip_hangup().
03357 { 03358 int i, res = 0; 03359 03360 if (ast_strlen_zero(msg)) { 03361 return 0; 03362 } 03363 for (i = 1; i < ARRAY_LEN(sip_methods) && !res; i++) { 03364 if (method_match(i, msg)) { 03365 res = sip_methods[i].id; 03366 } 03367 } 03368 return res; 03369 }
| static int find_sip_monitor_instance_by_subscription_pvt | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1891 of file chan_sip.c.
References CMP_MATCH, and CMP_STOP.
Referenced by handle_cc_notify(), and handle_response_subscribe().
| static int find_sip_monitor_instance_by_suspension_entry | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1897 of file chan_sip.c.
References CMP_MATCH, and CMP_STOP.
Referenced by cc_handle_publish_error().
| static struct epa_static_data* find_static_data | ( | const char *const | event_package | ) | [static, read] |
Definition at line 894 of file chan_sip.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, and AST_LIST_UNLOCK.
Referenced by create_epa_entry().
00895 { 00896 const struct epa_backend *backend = NULL; 00897 00898 AST_LIST_LOCK(&epa_static_data_list); 00899 AST_LIST_TRAVERSE(&epa_static_data_list, backend, next) { 00900 if (!strcmp(backend->static_data->name, event_package)) { 00901 break; 00902 } 00903 } 00904 AST_LIST_UNLOCK(&epa_static_data_list); 00905 return backend ? backend->static_data : NULL; 00906 }
| static struct cfsubscription_types * find_subscription_type | ( | enum subscriptiontype | subtype | ) | [static, read] |
Find subscription type in array.
Definition at line 18957 of file chan_sip.c.
References ARRAY_LEN, subscription_types, and type.
Referenced by transmit_state_notify().
18958 { 18959 int i; 18960 18961 for (i = 1; i < ARRAY_LEN(subscription_types); i++) { 18962 if (subscription_types[i].type == subtype) { 18963 return &subscription_types[i]; 18964 } 18965 } 18966 return &subscription_types[0]; 18967 }
| static void free_old_route | ( | struct sip_route * | route | ) | [static] |
Remove route from route list.
Definition at line 14674 of file chan_sip.c.
References ast_free.
Referenced by __sip_destroy(), and build_route().
14675 { 14676 struct sip_route *next; 14677 14678 while (route) { 14679 next = route->next; 14680 ast_free(route); 14681 route = next; 14682 } 14683 }
| static int func_check_sipdomain | ( | struct ast_channel * | chan, | |
| const char * | cmd, | |||
| char * | data, | |||
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
Dial plan function to check if domain is local.
Definition at line 20093 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_strlen_zero(), check_sip_domain(), and LOG_WARNING.
20094 { 20095 if (ast_strlen_zero(data)) { 20096 ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n"); 20097 return -1; 20098 } 20099 if (check_sip_domain(data, NULL, 0)) 20100 ast_copy_string(buf, data, len); 20101 else 20102 buf[0] = '\0'; 20103 return 0; 20104 }
| static int func_header_read | ( | struct ast_channel * | chan, | |
| const char * | function, | |||
| char * | data, | |||
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
Read SIP header (dialplan function).
Definition at line 20029 of file chan_sip.c.
References __get_header(), args, AST_APP_ARG, ast_channel_lock, ast_channel_unlock, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_strlen_zero(), LOG_WARNING, ast_channel::tech, and ast_channel::tech_pvt.
20030 { 20031 struct sip_pvt *p; 20032 const char *content = NULL; 20033 AST_DECLARE_APP_ARGS(args, 20034 AST_APP_ARG(header); 20035 AST_APP_ARG(number); 20036 ); 20037 int i, number, start = 0; 20038 20039 if (!chan) { 20040 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function); 20041 return -1; 20042 } 20043 20044 if (ast_strlen_zero(data)) { 20045 ast_log(LOG_WARNING, "This function requires a header name.\n"); 20046 return -1; 20047 } 20048 20049 ast_channel_lock(chan); 20050 if (!IS_SIP_TECH(chan->tech)) { 20051 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 20052 ast_channel_unlock(chan); 20053 return -1; 20054 } 20055 20056 AST_STANDARD_APP_ARGS(args, data); 20057 if (!args.number) { 20058 number = 1; 20059 } else { 20060 sscanf(args.number, "%30d", &number); 20061 if (number < 1) 20062 number = 1; 20063 } 20064 20065 p = chan->tech_pvt; 20066 20067 /* If there is no private structure, this channel is no longer alive */ 20068 if (!p) { 20069 ast_channel_unlock(chan); 20070 return -1; 20071 } 20072 20073 for (i = 0; i < number; i++) 20074 content = __get_header(&p->initreq, args.header, &start); 20075 20076 if (ast_strlen_zero(content)) { 20077 ast_channel_unlock(chan); 20078 return -1; 20079 } 20080 20081 ast_copy_string(buf, content, len); 20082 ast_channel_unlock(chan); 20083 20084 return 0; 20085 }
| static int function_sipchaninfo_read | ( | struct ast_channel * | chan, | |
| const char * | cmd, | |||
| char * | data, | |||
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
${SIPCHANINFO()} Dialplan function - reads sip channel data
Definition at line 20211 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_log(), ast_sockaddr_stringify_addr(), LOG_WARNING, ast_channel::tech, and ast_channel::tech_pvt.
20212 { 20213 struct sip_pvt *p; 20214 static int deprecated = 0; 20215 20216 *buf = 0; 20217 20218 if (!chan) { 20219 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd); 20220 return -1; 20221 } 20222 20223 if (!data) { 20224 ast_log(LOG_WARNING, "This function requires a parameter name.\n"); 20225 return -1; 20226 } 20227 20228 ast_channel_lock(chan); 20229 if (!IS_SIP_TECH(chan->tech)) { 20230 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 20231 ast_channel_unlock(chan); 20232 return -1; 20233 } 20234 20235 if (deprecated++ % 20 == 0) { 20236 /* Deprecated in 1.6.1 */ 20237 ast_log(LOG_WARNING, "SIPCHANINFO() is deprecated. Please transition to using CHANNEL().\n"); 20238 } 20239 20240 p = chan->tech_pvt; 20241 20242 /* If there is no private structure, this channel is no longer alive */ 20243 if (!p) { 20244 ast_channel_unlock(chan); 20245 return -1; 20246 } 20247 20248 if (!strcasecmp(data, "peerip")) { 20249 ast_copy_string(buf, ast_sockaddr_stringify_addr(&p->sa), len); 20250 } else if (!strcasecmp(data, "recvip")) { 20251 ast_copy_string(buf, ast_sockaddr_stringify_addr(&p->recv), len); 20252 } else if (!strcasecmp(data, "from")) { 20253 ast_copy_string(buf, p->from, len); 20254 } else if (!strcasecmp(data, "uri")) { 20255 ast_copy_string(buf, p->uri, len); 20256 } else if (!strcasecmp(data, "useragent")) { 20257 ast_copy_string(buf, p->useragent, len); 20258 } else if (!strcasecmp(data, "peername")) { 20259 ast_copy_string(buf, p->peername, len); 20260 } else if (!strcasecmp(data, "t38passthrough")) { 20261 if (p->t38.state == T38_DISABLED) { 20262 ast_copy_string(buf, "0", len); 20263 } else { /* T38 is offered or enabled in this call */ 20264 ast_copy_string(buf, "1", len); 20265 } 20266 } else { 20267 ast_channel_unlock(chan); 20268 return -1; 20269 } 20270 ast_channel_unlock(chan); 20271 20272 return 0; 20273 }
| static int function_sippeer | ( | struct ast_channel * | chan, | |
| const char * | cmd, | |||
| char * | data, | |||
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
${SIPPEER()} Dialplan function - reads peer data
Definition at line 20112 of file chan_sip.c.
References ast_codec_pref_index(), ast_copy_string(), ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_print_group(), ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_str_alloca, ast_str_buffer(), ast_test_flag, chanvar, FALSE, find_peer(), LOG_WARNING, ast_variable::name, ast_variable::next, peer_mailboxes_to_str(), peer_status(), TRUE, unref_peer(), and ast_variable::value.
20113 { 20114 struct sip_peer *peer; 20115 char *colname; 20116 20117 if ((colname = strchr(data, ':'))) { /*! \todo Will be deprecated after 1.4 */ 20118 static int deprecation_warning = 0; 20119 *colname++ = '\0'; 20120 if (deprecation_warning++ % 10 == 0) 20121 ast_log(LOG_WARNING, "SIPPEER(): usage of ':' to separate arguments is deprecated. Please use ',' instead.\n"); 20122 } else if ((colname = strchr(data, ','))) 20123 *colname++ = '\0'; 20124 else 20125 colname = "ip"; 20126 20127 if (!(peer = find_peer(data, NULL, TRUE, FINDPEERS, FALSE, 0))) 20128 return -1; 20129 20130 if (!strcasecmp(colname, "ip")) { 20131 ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len); 20132 } else if (!strcasecmp(colname, "port")) { 20133 snprintf(buf, len, "%d", ast_sockaddr_port(&peer->addr)); 20134 } else if (!strcasecmp(colname, "status")) { 20135 peer_status(peer, buf, len); 20136 } else if (!strcasecmp(colname, "language")) { 20137 ast_copy_string(buf, peer->language, len); 20138 } else if (!strcasecmp(colname, "regexten")) { 20139 ast_copy_string(buf, peer->regexten, len); 20140 } else if (!strcasecmp(colname, "limit")) { 20141 snprintf(buf, len, "%d", peer->call_limit); 20142 } else if (!strcasecmp(colname, "busylevel")) { 20143 snprintf(buf, len, "%d", peer->busy_level); 20144 } else if (!strcasecmp(colname, "curcalls")) { 20145 snprintf(buf, len, "%d", peer->inUse); 20146 } else if (!strcasecmp(colname, "maxforwards")) { 20147 snprintf(buf, len, "%d", peer->maxforwards); 20148 } else if (!strcasecmp(colname, "accountcode")) { 20149 ast_copy_string(buf, peer->accountcode, len); 20150 } else if (!strcasecmp(colname, "callgroup")) { 20151 ast_print_group(buf, len, peer->callgroup); 20152 } else if (!strcasecmp(colname, "pickupgroup")) { 20153 ast_print_group(buf, len, peer->pickupgroup); 20154 } else if (!strcasecmp(colname, "useragent")) { 20155 ast_copy_string(buf, peer->useragent, len); 20156 } else if (!strcasecmp(colname, "mailbox")) { 20157 struct ast_str *mailbox_str = ast_str_alloca(512); 20158 peer_mailboxes_to_str(&mailbox_str, peer); 20159 ast_copy_string(buf, ast_str_buffer(mailbox_str), len); 20160 } else if (!strcasecmp(colname, "context")) { 20161 ast_copy_string(buf, peer->context, len); 20162 } else if (!strcasecmp(colname, "expire")) { 20163 snprintf(buf, len, "%d", peer->expire); 20164 } else if (!strcasecmp(colname, "dynamic")) { 20165 ast_copy_string(buf, peer->host_dynamic ? "yes" : "no", len); 20166 } else if (!strcasecmp(colname, "callerid_name")) { 20167 ast_copy_string(buf, peer->cid_name, len); 20168 } else if (!strcasecmp(colname, "callerid_num")) { 20169 ast_copy_string(buf, peer->cid_num, len); 20170 } else if (!strcasecmp(colname, "codecs")) { 20171 ast_getformatname_multiple(buf, len -1, peer->capability); 20172 } else if (!strcasecmp(colname, "encryption")) { 20173 snprintf(buf, len, "%u", ast_test_flag(&peer->flags[1], SIP_PAGE2_USE_SRTP)); 20174 } else if (!strncasecmp(colname, "chanvar[", 8)) { 20175 char *chanvar=colname + 8; 20176 struct ast_variable *v; 20177 20178 chanvar = strsep(&chanvar, "]"); 20179 for (v = peer->chanvars ; v ; v = v->next) { 20180 if (!strcasecmp(v->name, chanvar)) { 20181 ast_copy_string(buf, v->value, len); 20182 } 20183 } 20184 } else if (!strncasecmp(colname, "codec[", 6)) { 20185 char *codecnum; 20186 format_t codec = 0; 20187 20188 codecnum = colname + 6; /* move past the '[' */ 20189 codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */ 20190 if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) { 20191 ast_copy_string(buf, ast_getformatname(codec), len); 20192 } else { 20193 buf[0] = '\0'; 20194 } 20195 } else { 20196 buf[0] = '\0'; 20197 } 20198 20199 unref_peer(peer, "unref_peer from function_sippeer, just before return"); 20200 20201 return 0; 20202 }
| static char * generate_random_string | ( | char * | buf, | |
| size_t | size | |||
| ) | [static] |
Generate 32 byte random string for callid's etc.
Definition at line 7835 of file chan_sip.c.
References ast_random().
Referenced by build_callid_pvt(), build_callid_registry(), construct_pidf_body(), and generate_uri().
07836 { 07837 long val[4]; 07838 int x; 07839 07840 for (x=0; x<4; x++) 07841 val[x] = ast_random(); 07842 snprintf(buf, size, "%08lx%08lx%08lx%08lx", (unsigned long)val[0], (unsigned long)val[1], (unsigned long)val[2], (unsigned long)val[3]); 07843 07844 return buf; 07845 }
| static char* generate_uri | ( | struct sip_pvt * | pvt, | |
| char * | buf, | |||
| size_t | size | |||
| ) | [static] |
Definition at line 7847 of file chan_sip.c.
References ast_copy_string(), ast_sockaddr_stringify_remote(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_set(), and generate_random_string().
Referenced by add_cc_call_info_to_response(), and transmit_cc_notify().
07848 { 07849 struct ast_str *uri = ast_str_alloca(size); 07850 ast_str_set(&uri, 0, "%s", pvt->socket.type == SIP_TRANSPORT_TLS ? "sips:" : "sip:"); 07851 /* Here would be a great place to generate a UUID, but for now we'll 07852 * use the handy random string generation function we already have 07853 */ 07854 ast_str_append(&uri, 0, "%s", generate_random_string(buf, size)); 07855 ast_str_append(&uri, 0, "@%s", ast_sockaddr_stringify_remote(&pvt->ourip)); 07856 ast_copy_string(buf, ast_str_buffer(uri), size); 07857 return buf; 07858 }
| int get_address_family_filter | ( | unsigned int | transport | ) | [static] |
Helper for dns resolution to filter by address family.
Definition at line 26261 of file chan_sip.c.
References ast_sockaddr_is_any(), ast_sockaddr_is_ipv6(), bindaddr, ast_tcptls_session_args::local_address, and ast_sockaddr::ss.
Referenced by __sip_subscribe_mwi_do(), ast_sockaddr_resolve_first(), ast_sockaddr_resolve_first_transport(), build_peer(), proxy_update(), realtime_peer_by_name(), and transmit_register().
26262 { 26263 const struct ast_sockaddr *addr = NULL; 26264 26265 if ((transport == SIP_TRANSPORT_UDP) || !transport) { 26266 addr = &bindaddr; 26267 } 26268 else if (transport == SIP_TRANSPORT_TCP) { 26269 addr = &sip_tcp_desc.local_address; 26270 } 26271 else if (transport == SIP_TRANSPORT_TLS) { 26272 addr = &sip_tls_desc.local_address; 26273 } 26274 26275 if (ast_sockaddr_is_ipv6(addr) && ast_sockaddr_is_any(addr)) { 26276 return 0; 26277 } 26278 26279 return addr->ss.ss_family; 26280 }
| static int get_also_info | ( | struct sip_pvt * | p, | |
| struct sip_request * | oreq | |||
| ) | [static] |
Call transfer support (old way, deprecated by the IETF).
Definition at line 16347 of file chan_sip.c.
References ast_canmatch_extension(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_log(), ast_string_field_set, ast_strlen_zero(), ast_verbose, context, get_header(), get_in_brackets(), LOG_WARNING, parse_uri_legacy_check(), pbx_builtin_getvar_helper(), S_OR, sip_cfg, sip_debug_test_pvt(), SIP_PEDANTIC_DECODE, and sip_refer_allocate().
Referenced by handle_request_bye().
16348 { 16349 char tmp[256] = "", *c, *a; 16350 struct sip_request *req = oreq ? oreq : &p->initreq; 16351 struct sip_refer *referdata = NULL; 16352 const char *transfer_context = NULL; 16353 16354 if (!p->refer && !sip_refer_allocate(p)) 16355 return -1; 16356 16357 referdata = p->refer; 16358 16359 ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp)); 16360 c = get_in_brackets(tmp); 16361 16362 if (parse_uri_legacy_check(c, "sip:,sips:", &c, NULL, &a, NULL)) { 16363 ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c); 16364 return -1; 16365 } 16366 16367 SIP_PEDANTIC_DECODE(c); 16368 SIP_PEDANTIC_DECODE(a); 16369 16370 if (!ast_strlen_zero(a)) { 16371 ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain)); 16372 } 16373 16374 if (sip_debug_test_pvt(p)) 16375 ast_verbose("Looking for %s in %s\n", c, p->context); 16376 16377 /* Determine transfer context */ 16378 if (p->owner) { 16379 /* By default, use the context in the channel sending the REFER */ 16380 transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT"); 16381 if (ast_strlen_zero(transfer_context)) { 16382 transfer_context = p->owner->macrocontext; 16383 } 16384 } 16385 if (ast_strlen_zero(transfer_context)) { 16386 transfer_context = S_OR(p->context, sip_cfg.default_context); 16387 } 16388 16389 if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) { 16390 /* This is a blind transfer */ 16391 ast_debug(1, "SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context); 16392 ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to)); 16393 ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by)); 16394 ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact)); 16395 /* Set new context */ 16396 ast_string_field_set(p, context, transfer_context); 16397 return 0; 16398 } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) { 16399 return 1; 16400 } 16401 16402 return -1; 16403 }
| static char* get_body | ( | struct sip_request * | req, | |
| char * | name, | |||
| char | delimiter | |||
| ) | [static] |
Get a specific line from the message body.
Definition at line 7590 of file chan_sip.c.
References get_body_by_line(), and len().
Referenced by handle_cc_notify(), handle_request_info(), and handle_request_notify().
07591 { 07592 int x; 07593 int len = strlen(name); 07594 char *r; 07595 07596 for (x = 0; x < req->lines; x++) { 07597 r = get_body_by_line(REQ_OFFSET_TO_STR(req, line[x]), name, len, delimiter); 07598 if (r[0] != '\0') 07599 return r; 07600 } 07601 07602 return ""; 07603 }
| static char* get_body_by_line | ( | const char * | line, | |
| const char * | name, | |||
| int | nameLen, | |||
| char | delimiter | |||
| ) | [static] |
Reads one line of SIP message body.
Definition at line 7535 of file chan_sip.c.
References ast_skip_blanks().
Referenced by get_body(), and get_sdp_iterate().
07536 { 07537 if (!strncasecmp(line, name, nameLen) && line[nameLen] == delimiter) 07538 return ast_skip_blanks(line + nameLen + 1); 07539 07540 return ""; 07541 }
| static int get_cached_mwi | ( | struct sip_peer * | peer, | |
| int * | new, | |||
| int * | old | |||
| ) | [static] |
Get cached MWI info.
Definition at line 26416 of file chan_sip.c.
References ast_event_destroy(), ast_event_get_cached(), ast_event_get_ie_uint(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, AST_LIST_TRAVERSE, mailbox, and S_OR.
Referenced by sip_send_mwi_to_peer().
26417 { 26418 struct sip_mailbox *mailbox; 26419 int in_cache; 26420 26421 in_cache = 0; 26422 AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { 26423 struct ast_event *event; 26424 event = ast_event_get_cached(AST_EVENT_MWI, 26425 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox->mailbox, 26426 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, S_OR(mailbox->context, "default"), 26427 AST_EVENT_IE_END); 26428 if (!event) 26429 continue; 26430 *new += ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS); 26431 *old += ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS); 26432 ast_event_destroy(event); 26433 in_cache = 1; 26434 } 26435 26436 return in_cache; 26437 }
| static void get_crypto_attrib | ( | struct sip_srtp * | srtp, | |
| const char ** | a_crypto | |||
| ) | [static] |
Definition at line 11638 of file chan_sip.c.
References ast_log(), LOG_WARNING, sdp_crypto_attrib(), sdp_crypto_offer(), and sdp_crypto_setup().
Referenced by add_sdp().
11639 { 11640 /* Set encryption properties */ 11641 if (srtp) { 11642 if (!srtp->crypto) { 11643 srtp->crypto = sdp_crypto_setup(); 11644 } 11645 if (srtp->crypto && (sdp_crypto_offer(srtp->crypto) >= 0)) { 11646 *a_crypto = sdp_crypto_attrib(srtp->crypto); 11647 } 11648 11649 if (!*a_crypto) { 11650 ast_log(LOG_WARNING, "No SRTP key management enabled\n"); 11651 } 11652 } 11653 }
| static enum sip_get_dest_result get_destination | ( | struct sip_pvt * | p, | |
| struct sip_request * | oreq, | |||
| int * | cc_recall_core_id | |||
| ) | [static] |
Find out who the call is for.
We use the request uri as a destination. This code assumes authentication has been done, so that the device (peer/user) context is already set.
Definition at line 15891 of file chan_sip.c.
References ao2_ref, ast_canmatch_extension(), ast_cc_agent_recalling(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_free, ast_get_hint(), AST_LIST_EMPTY, ast_log(), AST_MAX_EXTENSION, ast_pickup_ext(), ast_strdup, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_verbose, check_sip_domain(), context, ast_cc_agent::core_id, ast_cc_agent::device_name, exten, extract_host_from_hostport(), find_sip_cc_agent_by_notify_uri(), get_header(), get_in_brackets(), LOG_WARNING, parse_uri_legacy_check(), ast_cc_agent::private_data, RAII_VAR, S_OR, sip_cfg, sip_debug_test_pvt(), sip_methods, SIP_PEDANTIC_DECODE, and cfsip_methods::text.
Referenced by handle_request_invite(), handle_request_options(), and handle_request_subscribe().
15892 { 15893 char tmp[256] = "", *uri, *unused_password, *domain; 15894 RAII_VAR(char *, tmpf, NULL, ast_free); 15895 char *from = NULL; 15896 struct sip_request *req; 15897 char *decoded_uri; 15898 15899 req = oreq; 15900 if (!req) { 15901 req = &p->initreq; 15902 } 15903 15904 /* Find the request URI */ 15905 if (req->rlPart2) 15906 ast_copy_string(tmp, REQ_OFFSET_TO_STR(req, rlPart2), sizeof(tmp)); 15907 15908 uri = ast_strdupa(get_in_brackets(tmp)); 15909 15910 if (parse_uri_legacy_check(uri, "sip:,sips:", &uri, &unused_password, &domain, NULL)) { 15911 ast_log(LOG_WARNING, "Not a SIP header (%s)?\n", uri); 15912 return SIP_GET_DEST_INVALID_URI; 15913 } 15914 15915 SIP_PEDANTIC_DECODE(domain); 15916 SIP_PEDANTIC_DECODE(uri); 15917 15918 extract_host_from_hostport(&domain); 15919 15920 if (ast_strlen_zero(uri)) { 15921 /* 15922 * Either there really was no extension found or the request 15923 * URI had encoded nulls that made the string "empty". Use "s" 15924 * as the extension. 15925 */ 15926 uri = "s"; 15927 } 15928 15929 ast_string_field_set(p, domain, domain); 15930 15931 /* Now find the From: caller ID and name */ 15932 /* XXX Why is this done in get_destination? Isn't it already done? 15933 Needs to be checked 15934 */ 15935 tmpf = ast_strdup(get_header(req, "From")); 15936 if (!ast_strlen_zero(tmpf)) { 15937 from = get_in_brackets(tmpf); 15938 if (parse_uri_legacy_check(from, "sip:,sips:", &from, NULL, &domain, NULL)) { 15939 ast_log(LOG_WARNING, "Not a SIP header (%s)?\n", from); 15940 return SIP_GET_DEST_INVALID_URI; 15941 } 15942 15943 SIP_PEDANTIC_DECODE(from); 15944 SIP_PEDANTIC_DECODE(domain); 15945 15946 extract_host_from_hostport(&domain); 15947 15948 ast_string_field_set(p, fromdomain, domain); 15949 } 15950 15951 if (!AST_LIST_EMPTY(&domain_list)) { 15952 char domain_context[AST_MAX_EXTENSION]; 15953 15954 domain_context[0] = '\0'; 15955 if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) { 15956 if (!sip_cfg.allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) { 15957 ast_debug(1, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain); 15958 return SIP_GET_DEST_REFUSED; 15959 } 15960 } 15961 /* If we don't have a peer (i.e. we're a guest call), 15962 * overwrite the original context */ 15963 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_HAVEPEERCONTEXT) && !ast_strlen_zero(domain_context)) { 15964 ast_string_field_set(p, context, domain_context); 15965 } 15966 } 15967 15968 /* If the request coming in is a subscription and subscribecontext has been specified use it */ 15969 if (req->method == SIP_SUBSCRIBE && !ast_strlen_zero(p->subscribecontext)) { 15970 ast_string_field_set(p, context, p->subscribecontext); 15971 } 15972 15973 if (sip_debug_test_pvt(p)) { 15974 ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain); 15975 } 15976 15977 /* Since extensions.conf can have unescaped characters, try matching a 15978 * decoded uri in addition to the non-decoded uri. */ 15979 decoded_uri = ast_strdupa(uri); 15980 ast_uri_decode(decoded_uri); 15981 15982 /* If this is a subscription we actually just need to see if a hint exists for the extension */ 15983 if (req->method == SIP_SUBSCRIBE) { 15984 char hint[AST_MAX_EXTENSION]; 15985 int which = 0; 15986 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, uri) || 15987 (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, decoded_uri) && (which = 1))) { 15988 if (!oreq) { 15989 ast_string_field_set(p, exten, which ? decoded_uri : uri); 15990 } 15991 return SIP_GET_DEST_EXTEN_FOUND; 15992 } else { 15993 return SIP_GET_DEST_EXTEN_NOT_FOUND; 15994 } 15995 } else { 15996 struct ast_cc_agent *agent; 15997 /* Check the dialplan for the username part of the request URI, 15998 the domain will be stored in the SIPDOMAIN variable 15999 Return 0 if we have a matching extension */ 16000 if (ast_exists_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from))) { 16001 if (!oreq) { 16002 ast_string_field_set(p, exten, uri); 16003 } 16004 return SIP_GET_DEST_EXTEN_FOUND; 16005 } 16006 if (ast_exists_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from)) 16007 || !strcmp(decoded_uri, ast_pickup_ext())) { 16008 if (!oreq) { 16009 ast_string_field_set(p, exten, decoded_uri); 16010 } 16011 return SIP_GET_DEST_EXTEN_FOUND; 16012 } 16013 if ((agent = find_sip_cc_agent_by_notify_uri(tmp))) { 16014 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 16015 /* This is a CC recall. We can set p's extension to the exten from 16016 * the original INVITE 16017 */ 16018 ast_string_field_set(p, exten, agent_pvt->original_exten); 16019 /* And we need to let the CC core know that the caller is attempting 16020 * his recall 16021 */ 16022 ast_cc_agent_recalling(agent->core_id, "SIP caller %s is attempting recall", 16023 agent->device_name); 16024 if (cc_recall_core_id) { 16025 *cc_recall_core_id = agent->core_id; 16026 } 16027 ao2_ref(agent, -1); 16028 return SIP_GET_DEST_EXTEN_FOUND; 16029 } 16030 } 16031 16032 if (ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) 16033 && (ast_canmatch_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from)) 16034 || ast_canmatch_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from)) 16035 || !strncmp(decoded_uri, ast_pickup_ext(), strlen(decoded_uri)))) { 16036 /* Overlap dialing is enabled and we need more digits to match an extension. */ 16037 return SIP_GET_DEST_EXTEN_MATCHMORE; 16038 } 16039 16040 return SIP_GET_DEST_EXTEN_NOT_FOUND; 16041 }
| static int get_domain | ( | const char * | str, | |
| char * | domain, | |||
| int | len | |||
| ) | [static] |
Extract domain from SIP To/From header.
Definition at line 11104 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_strlen_zero(), get_in_brackets(), and LOG_WARNING.
Referenced by get_realm().
11105 { 11106 char tmpf[256]; 11107 char *a, *from; 11108 11109 *domain = '\0'; 11110 ast_copy_string(tmpf, str, sizeof(tmpf)); 11111 from = get_in_brackets(tmpf); 11112 if (!ast_strlen_zero(from)) { 11113 if (strncasecmp(from, "sip:", 4)) { 11114 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from); 11115 return -1; 11116 } 11117 from += 4; 11118 } else 11119 from = NULL; 11120 11121 if (from) { 11122 int bracket = 0; 11123 11124 /* Strip any params or options from user */ 11125 if ((a = strchr(from, ';'))) 11126 *a = '\0'; 11127 /* Strip port from domain if present */ 11128 for (a = from; *a != '\0'; ++a) { 11129 if (*a == ':' && bracket == 0) { 11130 *a = '\0'; 11131 break; 11132 } else if (*a == '[') { 11133 ++bracket; 11134 } else if (*a == ']') { 11135 --bracket; 11136 } 11137 } 11138 if ((a = strchr(from, '@'))) { 11139 *a = '\0'; 11140 ast_copy_string(domain, a + 1, len); 11141 } else 11142 ast_copy_string(domain, from, len); 11143 } 11144 11145 return ast_strlen_zero(domain); 11146 }
| static struct event_state_compositor* get_esc | ( | const char *const | event_package | ) | [static, read] |
Definition at line 988 of file chan_sip.c.
References ARRAY_LEN, event_state_compositors, and name.
Referenced by create_new_sip_etag(), handle_request_publish(), and publish_expire().
00988 { 00989 int i; 00990 for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) { 00991 if (!strcasecmp(event_package, event_state_compositors[i].name)) { 00992 return &event_state_compositors[i]; 00993 } 00994 } 00995 return NULL; 00996 }
| static struct sip_esc_entry* get_esc_entry | ( | const char * | entity_tag, | |
| struct event_state_compositor * | esc | |||
| ) | [static, read] |
Definition at line 998 of file chan_sip.c.
References ao2_find, ast_copy_string(), event_state_compositor::compositor, and OBJ_POINTER.
Referenced by handle_sip_publish_modify(), handle_sip_publish_refresh(), and handle_sip_publish_remove().
00998 { 00999 struct sip_esc_entry *entry; 01000 struct sip_esc_entry finder; 01001 01002 ast_copy_string(finder.entity_tag, entity_tag, sizeof(finder.entity_tag)); 01003 01004 entry = ao2_find(esc->compositor, &finder, OBJ_POINTER); 01005 01006 return entry; 01007 }
| static const char * get_header | ( | const struct sip_request * | req, | |
| const char * | name | |||
| ) | [static] |
Get header from SIP request.
Definition at line 7684 of file chan_sip.c.
References __get_header().
Referenced by __transmit_response(), build_route(), cc_handle_publish_error(), change_redirecting_information(), check_auth(), check_user_full(), check_via(), check_via_response(), copy_header(), extract_uri(), find_call(), find_sdp(), get_also_info(), get_destination(), get_pai(), get_rdnis(), get_realm(), get_refer_info(), get_rpid(), gettag(), handle_cc_notify(), handle_cc_subscribe(), handle_incoming(), handle_request_bye(), handle_request_do(), handle_request_info(), handle_request_invite(), handle_request_invite_st(), handle_request_notify(), handle_request_options(), handle_request_publish(), handle_request_register(), handle_request_subscribe(), handle_request_update(), handle_response(), handle_response_invite(), handle_response_notify(), handle_response_publish(), handle_response_refer(), handle_response_register(), handle_response_subscribe(), handle_response_update(), parse_allowed_methods(), parse_moved_contact(), parse_ok_contact(), parse_register_contact(), proc_422_rsp(), process_via(), receive_message(), register_verify(), reply_digest(), reqprep(), respprep(), send_request(), send_response(), sip_alloc(), sip_get_cc_information(), sip_sipredirect(), transmit_fake_auth_response(), transmit_refer(), transmit_response_with_auth(), transmit_response_with_sdp(), transmit_response_with_t38_sdp(), and transmit_state_notify().
07685 { 07686 int start = 0; 07687 return __get_header(req, name, &start); 07688 }
| static struct ast_variable * get_insecure_variable_from_config | ( | struct ast_config * | config | ) | [static, read] |
Definition at line 4895 of file chan_sip.c.
References ast_category_browse(), ast_category_root(), ast_test_flag, ast_variable_retrieve(), set_insecure_flags(), and var.
Referenced by get_insecure_variable_from_sippeers().
04896 { 04897 struct ast_variable *var = NULL; 04898 struct ast_flags flags = {0}; 04899 char *cat = NULL; 04900 const char *insecure; 04901 while ((cat = ast_category_browse(cfg, cat))) { 04902 insecure = ast_variable_retrieve(cfg, cat, "insecure"); 04903 set_insecure_flags(&flags, insecure, -1); 04904 if (ast_test_flag(&flags, SIP_INSECURE_PORT)) { 04905 var = ast_category_root(cfg, cat); 04906 break; 04907 } 04908 } 04909 return var; 04910 }
| static struct ast_variable* get_insecure_variable_from_sippeers | ( | const char * | column, | |
| const char * | value | |||
| ) | [static, read] |
Definition at line 4912 of file chan_sip.c.
References ast_config_destroy(), ast_load_realtime_multientry(), ast_variables_dup(), get_insecure_variable_from_config(), SENTINEL, and var.
Referenced by realtime_peer_by_addr().
04913 { 04914 struct ast_config *peerlist; 04915 struct ast_variable *var = NULL; 04916 if ((peerlist = ast_load_realtime_multientry("sippeers", column, value, "insecure LIKE", "%port%", SENTINEL))) { 04917 if ((var = get_insecure_variable_from_config(peerlist))) { 04918 /* Must clone, because var will get freed along with 04919 * peerlist. */ 04920 var = ast_variables_dup(var); 04921 } 04922 ast_config_destroy(peerlist); 04923 } 04924 return var; 04925 }
| static struct ast_variable* get_insecure_variable_from_sipregs | ( | const char * | column, | |
| const char * | value, | |||
| struct ast_variable ** | var | |||
| ) | [static, read] |
Definition at line 4932 of file chan_sip.c.
References ast_category_browse(), ast_category_root(), ast_config_destroy(), ast_load_realtime_multientry(), ast_test_flag, ast_variable_retrieve(), ast_variables_destroy(), ast_variables_dup(), SENTINEL, and set_insecure_flags().
Referenced by realtime_peer_by_addr().
04933 { 04934 struct ast_variable *varregs = NULL; 04935 struct ast_config *regs, *peers; 04936 char *regscat; 04937 const char *regname; 04938 04939 if (!(regs = ast_load_realtime_multientry("sipregs", column, value, SENTINEL))) { 04940 return NULL; 04941 } 04942 04943 /* Load *all* peers that are probably insecure=port */ 04944 if (!(peers = ast_load_realtime_multientry("sippeers", "insecure LIKE", "%port%", SENTINEL))) { 04945 ast_config_destroy(regs); 04946 return NULL; 04947 } 04948 04949 /* Loop over the sipregs that match IP address and attempt to find an 04950 * insecure=port match to it in sippeers. */ 04951 regscat = NULL; 04952 while ((regscat = ast_category_browse(regs, regscat)) && (regname = ast_variable_retrieve(regs, regscat, "name"))) { 04953 char *peerscat; 04954 const char *peername; 04955 04956 peerscat = NULL; 04957 while ((peerscat = ast_category_browse(peers, peerscat)) && (peername = ast_variable_retrieve(peers, peerscat, "name"))) { 04958 if (!strcasecmp(regname, peername)) { 04959 /* Ensure that it really is insecure=port and 04960 * not something else. */ 04961 const char *insecure = ast_variable_retrieve(peers, peerscat, "insecure"); 04962 struct ast_flags flags = {0}; 04963 set_insecure_flags(&flags, insecure, -1); 04964 if (ast_test_flag(&flags, SIP_INSECURE_PORT)) { 04965 /* ENOMEM checks till the bitter end. */ 04966 if ((varregs = ast_variables_dup(ast_category_root(regs, regscat)))) { 04967 if (!(*var = ast_variables_dup(ast_category_root(peers, peerscat)))) { 04968 ast_variables_destroy(varregs); 04969 varregs = NULL; 04970 } 04971 } 04972 goto done; 04973 } 04974 } 04975 } 04976 } 04977 04978 done: 04979 ast_config_destroy(regs); 04980 ast_config_destroy(peers); 04981 return varregs; 04982 }
| static int get_ip_and_port_from_sdp | ( | struct sip_request * | req, | |
| const enum media_type | media, | |||
| struct ast_sockaddr * | addr | |||
| ) | [static] |
Definition at line 9019 of file chan_sip.c.
References ast_log(), ast_sockaddr_resolve_first_af(), ast_strlen_zero(), get_sdp_iterate(), len(), and LOG_WARNING.
Referenced by handle_request_invite().
09020 { 09021 const char *m; 09022 const char *c; 09023 int miterator = req->sdp_start; 09024 int citerator = req->sdp_start; 09025 unsigned int x = 0; 09026 unsigned int numberofports; 09027 int len; 09028 int af; 09029 char proto[4], host[258] = ""; /*Initialize to empty so we will know if we have any input */ 09030 09031 c = get_sdp_iterate(&citerator, req, "c"); 09032 if (sscanf(c, "IN %3s %256s", proto, host) != 2) { 09033 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 09034 /* Continue since there may be a valid host in a c= line specific to the audio stream */ 09035 } 09036 /* We only want the m and c lines for audio */ 09037 for (m = get_sdp_iterate(&miterator, req, "m"); !ast_strlen_zero(m); m = get_sdp_iterate(&miterator, req, "m")) { 09038 if ((media == SDP_AUDIO && ((sscanf(m, "audio %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 09039 (sscanf(m, "audio %30u RTP/AVP %n", &x, &len) == 1 && len > 0))) || 09040 (media == SDP_VIDEO && ((sscanf(m, "video %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 09041 (sscanf(m, "video %30u RTP/AVP %n", &x, &len) == 1 && len > 0)))) { 09042 /* See if there's a c= line for this media stream. 09043 * XXX There is no guarantee that we'll be grabbing the c= line for this 09044 * particular media stream here. However, this is the same logic used in process_sdp. 09045 */ 09046 c = get_sdp_iterate(&citerator, req, "c"); 09047 if (!ast_strlen_zero(c)) { 09048 sscanf(c, "IN %3s %256s", proto, host); 09049 } 09050 break; 09051 } 09052 } 09053 09054 if (!strcmp("IP4", proto)) { 09055 af = AF_INET; 09056 } else if (!strcmp("IP6", proto)) { 09057 af = AF_INET6; 09058 } else { 09059 ast_log(LOG_WARNING, "Unknown protocol '%s'.\n", proto); 09060 return -1; 09061 } 09062 09063 if (ast_strlen_zero(host) || x == 0) { 09064 ast_log(LOG_WARNING, "Failed to read an alternate host or port in SDP. Expect %s problems\n", media == SDP_AUDIO ? "audio" : "video"); 09065 return -1; 09066 } 09067 09068 if (ast_sockaddr_resolve_first_af(addr, host, 0, af)) { 09069 ast_log(LOG_WARNING, "Could not look up IP address of alternate hostname. Expect %s problems\n", media == SDP_AUDIO? "audio" : "video"); 09070 return -1; 09071 } 09072 09073 return 0; 09074 }
| static int get_msg_text | ( | char * | buf, | |
| int | len, | |||
| struct sip_request * | req | |||
| ) | [static] |
Get message body from a SIP request.
| buf | Destination buffer | |
| len | Destination buffer size | |
| req | The SIP request |
When parsing the request originally, the lines are split by LF or CRLF. This function adds a single LF after every line.
Definition at line 16859 of file chan_sip.c.
Referenced by handle_request_info(), handle_request_notify(), and receive_message().
16860 { 16861 int x; 16862 int linelen; 16863 16864 buf[0] = '\0'; 16865 --len; /* reserve strncat null */ 16866 for (x = 0; len && x < req->lines; ++x) { 16867 const char *line = REQ_OFFSET_TO_STR(req, line[x]); 16868 strncat(buf, line, len); /* safe */ 16869 linelen = strlen(buf); 16870 buf += linelen; 16871 len -= linelen; 16872 if (len) { 16873 strcat(buf, "\n"); /* safe */ 16874 ++buf; 16875 --len; 16876 } 16877 } 16878 return 0; 16879 }
| static const char * get_name_from_variable | ( | const struct ast_variable * | var | ) | [static] |
Definition at line 4984 of file chan_sip.c.
References ast_strlen_zero(), ast_variable::name, ast_variable::next, and ast_variable::value.
Referenced by realtime_peer_by_addr(), and realtime_peer_get_sippeer_helper().
04985 { 04986 /* Don't expect this to return non-NULL. Both NULL and empty 04987 * values can cause the option to get removed from the variable 04988 * list. This is called on ast_variables gotten from both 04989 * ast_load_realtime and ast_load_realtime_multientry. 04990 * - ast_load_realtime removes options with empty values 04991 * - ast_load_realtime_multientry does not! 04992 * For consistent behaviour, we check for the empty name and 04993 * return NULL instead. */ 04994 const struct ast_variable *tmp; 04995 for (tmp = var; tmp; tmp = tmp->next) { 04996 if (!strcasecmp(tmp->name, "name")) { 04997 if (!ast_strlen_zero(tmp->value)) { 04998 return tmp->value; 04999 } 05000 break; 05001 } 05002 } 05003 return NULL; 05004 }
| static void get_our_media_address | ( | struct sip_pvt * | p, | |
| int | needvideo, | |||
| int | needtext, | |||
| struct ast_sockaddr * | addr, | |||
| struct ast_sockaddr * | vaddr, | |||
| struct ast_sockaddr * | taddr, | |||
| struct ast_sockaddr * | dest, | |||
| struct ast_sockaddr * | vdest, | |||
| struct ast_sockaddr * | tdest | |||
| ) | [static] |
Set all IP media addresses for this call.
Definition at line 11545 of file chan_sip.c.
References ast_rtp_instance_get_local_address(), ast_sockaddr_cmp_addr(), ast_sockaddr_copy(), ast_sockaddr_is_any(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_set_port, and media_address.
Referenced by add_sdp().
11549 { 11550 int use_externip = 0; 11551 11552 /* First, get our address */ 11553 ast_rtp_instance_get_local_address(p->rtp, addr); 11554 if (p->vrtp) { 11555 ast_rtp_instance_get_local_address(p->vrtp, vaddr); 11556 } 11557 if (p->trtp) { 11558 ast_rtp_instance_get_local_address(p->trtp, taddr); 11559 } 11560 11561 /* If our real IP differs from the local address returned by the RTP engine, use it. */ 11562 /* The premise is that if we are already using that IP to communicate with the client, */ 11563 /* we should be using it for RTP too. */ 11564 use_externip = ast_sockaddr_cmp_addr(&p->ourip, addr); 11565 11566 /* Now, try to figure out where we want them to send data */ 11567 /* Is this a re-invite to move the media out, then use the original offer from caller */ 11568 if (!ast_sockaddr_isnull(&p->redirip)) { /* If we have a redirection IP, use it */ 11569 ast_sockaddr_copy(dest, &p->redirip); 11570 } else { 11571 /* 11572 * Audio Destination IP: 11573 * 11574 * 1. Specifically configured media address. 11575 * 2. Local address as specified by the RTP engine. 11576 * 3. The local IP as defined by chan_sip. 11577 * 11578 * Audio Destination Port: 11579 * 11580 * 1. Provided by the RTP engine. 11581 */ 11582 ast_sockaddr_copy(dest, 11583 !ast_sockaddr_isnull(&media_address) ? &media_address : 11584 !ast_sockaddr_is_any(addr) && !use_externip ? addr : 11585 &p->ourip); 11586 ast_sockaddr_set_port(dest, ast_sockaddr_port(addr)); 11587 } 11588 11589 if (needvideo) { 11590 /* Determine video destination */ 11591 if (!ast_sockaddr_isnull(&p->vredirip)) { 11592 ast_sockaddr_copy(vdest, &p->vredirip); 11593 } else { 11594 /* 11595 * Video Destination IP: 11596 * 11597 * 1. Specifically configured media address. 11598 * 2. Local address as specified by the RTP engine. 11599 * 3. The local IP as defined by chan_sip. 11600 * 11601 * Video Destination Port: 11602 * 11603 * 1. Provided by the RTP engine. 11604 */ 11605 ast_sockaddr_copy(vdest, 11606 !ast_sockaddr_isnull(&media_address) ? &media_address : 11607 !ast_sockaddr_is_any(vaddr) && !use_externip ? vaddr : 11608 &p->ourip); 11609 ast_sockaddr_set_port(vdest, ast_sockaddr_port(vaddr)); 11610 } 11611 } 11612 11613 if (needtext) { 11614 /* Determine text destination */ 11615 if (!ast_sockaddr_isnull(&p->tredirip)) { 11616 ast_sockaddr_copy(tdest, &p->tredirip); 11617 } else { 11618 /* 11619 * Text Destination IP: 11620 * 11621 * 1. Specifically configured media address. 11622 * 2. Local address as specified by the RTP engine. 11623 * 3. The local IP as defined by chan_sip. 11624 * 11625 * Text Destination Port: 11626 * 11627 * 1. Provided by the RTP engine. 11628 */ 11629 ast_sockaddr_copy(tdest, 11630 !ast_sockaddr_isnull(&media_address) ? &media_address : 11631 !ast_sockaddr_is_any(taddr) && !use_externip ? taddr : 11632 &p->ourip); 11633 ast_sockaddr_set_port(tdest, ast_sockaddr_port(taddr)); 11634 } 11635 } 11636 }
| static int get_pai | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Parse the parts of the P-Asserted-Identity header on an incoming packet. Returns 1 if a valid header is found and it is different from the current caller id.
Definition at line 15598 of file chan_sip.c.
References ast_copy_string(), ast_free, ast_is_shrinkable_phonenumber(), AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, ast_set_callerid(), ast_shrink_phone_number(), ast_string_field_set, ast_strlen_zero(), cid_name, cid_num, get_header(), get_in_brackets(), and get_name_and_number().
Referenced by get_rpid().
15599 { 15600 char pai[256]; 15601 char privacy[64]; 15602 char *cid_num = NULL; 15603 char *cid_name = NULL; 15604 char emptyname[1] = ""; 15605 int callingpres = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 15606 char *uri = NULL; 15607 int is_anonymous = 0, do_update = 1, no_name = 0; 15608 15609 ast_copy_string(pai, get_header(req, "P-Asserted-Identity"), sizeof(pai)); 15610 15611 if (ast_strlen_zero(pai)) { 15612 return 0; 15613 } 15614 15615 /* use the reqresp_parser function get_name_and_number*/ 15616 if (get_name_and_number(pai, &cid_name, &cid_num)) { 15617 return 0; 15618 } 15619 15620 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(cid_num)) { 15621 ast_shrink_phone_number(cid_num); 15622 } 15623 15624 uri = get_in_brackets(pai); 15625 if (!strncasecmp(uri, "sip:anonymous@anonymous.invalid", 31)) { 15626 callingpres = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 15627 /*XXX Assume no change in cid_num. Perhaps it should be 15628 * blanked? 15629 */ 15630 ast_free(cid_num); 15631 is_anonymous = 1; 15632 cid_num = (char *)p->cid_num; 15633 } 15634 15635 ast_copy_string(privacy, get_header(req, "Privacy"), sizeof(privacy)); 15636 if (!ast_strlen_zero(privacy) && !strncmp(privacy, "id", 2)) { 15637 callingpres = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 15638 } 15639 if (!cid_name) { 15640 no_name = 1; 15641 cid_name = (char *)emptyname; 15642 } 15643 /* Only return true if the supplied caller id is different */ 15644 if (!strcasecmp(p->cid_num, cid_num) && !strcasecmp(p->cid_name, cid_name) && p->callingpres == callingpres) { 15645 do_update = 0; 15646 } else { 15647 15648 ast_string_field_set(p, cid_num, cid_num); 15649 ast_string_field_set(p, cid_name, cid_name); 15650 p->callingpres = callingpres; 15651 15652 if (p->owner) { 15653 ast_set_callerid(p->owner, cid_num, cid_name, NULL); 15654 p->owner->caller.id.name.presentation = callingpres; 15655 p->owner->caller.id.number.presentation = callingpres; 15656 } 15657 } 15658 15659 /* get_name_and_number allocates memory for cid_num and cid_name so we have to free it */ 15660 if (!is_anonymous) { 15661 ast_free(cid_num); 15662 } 15663 if (!no_name) { 15664 ast_free(cid_name); 15665 } 15666 15667 return do_update; 15668 }
| static int get_rdnis | ( | struct sip_pvt * | p, | |
| struct sip_request * | oreq, | |||
| char ** | name, | |||
| char ** | number, | |||
| int * | reason | |||
| ) | [static] |
Get referring dnis.
Definition at line 15791 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_strdup, ast_strip_quoted(), ast_strlen_zero(), ast_verbose, exten, get_header(), get_in_brackets(), LOG_WARNING, pbx_builtin_setvar_helper(), S_OR, sip_debug_test_pvt(), sip_reason_str_to_code(), and sip_set_redirstr().
Referenced by change_redirecting_information().
15792 { 15793 char tmp[256], *exten, *rexten, *rdomain, *rname = NULL; 15794 char *params, *reason_param = NULL; 15795 struct sip_request *req; 15796 15797 req = oreq ? oreq : &p->initreq; 15798 15799 ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp)); 15800 if (ast_strlen_zero(tmp)) 15801 return -1; 15802 15803 if ((params = strchr(tmp, '>'))) { 15804 params = strchr(params, ';'); 15805 } 15806 15807 exten = get_in_brackets(tmp); 15808 if (!strncasecmp(exten, "sip:", 4)) { 15809 exten += 4; 15810 } else if (!strncasecmp(exten, "sips:", 5)) { 15811 exten += 5; 15812 } else { 15813 ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", exten); 15814 return -1; 15815 } 15816 15817 /* Get diversion-reason param if present */ 15818 if (params) { 15819 *params = '\0'; /* Cut off parameters */ 15820 params++; 15821 while (*params == ';' || *params == ' ') 15822 params++; 15823 /* Check if we have a reason parameter */ 15824 if ((reason_param = strcasestr(params, "reason="))) { 15825 char *end; 15826 reason_param+=7; 15827 if ((end = strchr(reason_param, ';'))) { 15828 *end = '\0'; 15829 } 15830 /* Remove enclosing double-quotes */ 15831 if (*reason_param == '"') 15832 reason_param = ast_strip_quoted(reason_param, "\"", "\""); 15833 if (!ast_strlen_zero(reason_param)) { 15834 sip_set_redirstr(p, reason_param); 15835 if (p->owner) { 15836 pbx_builtin_setvar_helper(p->owner, "__PRIREDIRECTREASON", p->redircause); 15837 pbx_builtin_setvar_helper(p->owner, "__SIPREDIRECTREASON", reason_param); 15838 } 15839 } 15840 } 15841 } 15842 15843 rdomain = exten; 15844 rexten = strsep(&rdomain, "@"); /* trim anything after @ */ 15845 if (p->owner) 15846 pbx_builtin_setvar_helper(p->owner, "__SIPRDNISDOMAIN", rdomain); 15847 15848 if (sip_debug_test_pvt(p)) 15849 ast_verbose("RDNIS for this call is %s (reason %s)\n", exten, S_OR(reason_param, "")); 15850 15851 /*ast_string_field_set(p, rdnis, rexten);*/ 15852 15853 if (*tmp == '\"') { 15854 char *end_quote; 15855 rname = tmp + 1; 15856 end_quote = strchr(rname, '\"'); 15857 if (end_quote) { 15858 *end_quote = '\0'; 15859 } 15860 } 15861 15862 if (number) { 15863 *number = ast_strdup(rexten); 15864 } 15865 15866 if (name && rname) { 15867 *name = ast_strdup(rname); 15868 } 15869 15870 if (reason && !ast_strlen_zero(reason_param)) { 15871 *reason = sip_reason_str_to_code(reason_param); 15872 } 15873 15874 return 0; 15875 }
| static void get_realm | ( | struct sip_pvt * | p, | |
| const struct sip_request * | req | |||
| ) | [static] |
Choose realm based on From header and then To header or use globaly configured realm. Realm from From/To header should be listed among served domains in config file: domain=...
Definition at line 11152 of file chan_sip.c.
References AST_LIST_EMPTY, ast_string_field_set, ast_strlen_zero(), check_sip_domain(), get_domain(), get_header(), MAXHOSTNAMELEN, and sip_cfg.
Referenced by transmit_response_with_auth().
11153 { 11154 char domain[MAXHOSTNAMELEN]; 11155 11156 if (!ast_strlen_zero(p->realm)) 11157 return; 11158 11159 if (sip_cfg.domainsasrealm && 11160 !AST_LIST_EMPTY(&domain_list)) 11161 { 11162 /* Check From header first */ 11163 if (!get_domain(get_header(req, "From"), domain, sizeof(domain))) { 11164 if (check_sip_domain(domain, NULL, 0)) { 11165 ast_string_field_set(p, realm, domain); 11166 return; 11167 } 11168 } 11169 /* Check To header */ 11170 if (!get_domain(get_header(req, "To"), domain, sizeof(domain))) { 11171 if (check_sip_domain(domain, NULL, 0)) { 11172 ast_string_field_set(p, realm, domain); 11173 return; 11174 } 11175 } 11176 } 11177 11178 /* Use default realm from config file */ 11179 ast_string_field_set(p, realm, sip_cfg.realm); 11180 }
| static int get_refer_info | ( | struct sip_pvt * | transferer, | |
| struct sip_request * | outgoing_req | |||
| ) | [static] |
Call transfer support (the REFER method) Extracts Refer headers into pvt dialog structure.
Definition at line 16138 of file chan_sip.c.
References ast_bridged_channel(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_uri_decode(), ast_verbose, ast_channel::context, get_header(), get_in_brackets(), LOG_WARNING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), S_OR, sip_cfg, sip_debug_test_pvt(), and SIP_PEDANTIC_DECODE.
Referenced by handle_request_refer().
16139 { 16140 16141 const char *p_referred_by = NULL; 16142 char *h_refer_to = NULL; 16143 char *h_referred_by = NULL; 16144 char *refer_to; 16145 const char *p_refer_to; 16146 char *referred_by_uri = NULL; 16147 char *ptr; 16148 struct sip_request *req = NULL; 16149 const char *transfer_context = NULL; 16150 struct sip_refer *referdata; 16151 16152 16153 req = outgoing_req; 16154 referdata = transferer->refer; 16155 16156 if (!req) { 16157 req = &transferer->initreq; 16158 } 16159 16160 p_refer_to = get_header(req, "Refer-To"); 16161 if (ast_strlen_zero(p_refer_to)) { 16162 ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n"); 16163 return -2; /* Syntax error */ 16164 } 16165 h_refer_to = ast_strdupa(p_refer_to); 16166 refer_to = get_in_brackets(h_refer_to); 16167 if (!strncasecmp(refer_to, "sip:", 4)) { 16168 refer_to += 4; /* Skip sip: */ 16169 } else if (!strncasecmp(refer_to, "sips:", 5)) { 16170 refer_to += 5; 16171 } else { 16172 ast_log(LOG_WARNING, "Can't transfer to non-sip: URI. (Refer-to: %s)?\n", refer_to); 16173 return -3; 16174 } 16175 16176 /* Get referred by header if it exists */ 16177 p_referred_by = get_header(req, "Referred-By"); 16178 16179 /* Give useful transfer information to the dialplan */ 16180 if (transferer->owner) { 16181 struct ast_channel *peer = ast_bridged_channel(transferer->owner); 16182 if (peer) { 16183 pbx_builtin_setvar_helper(peer, "SIPREFERRINGCONTEXT", transferer->context); 16184 pbx_builtin_setvar_helper(peer, "SIPREFERREDBYHDR", p_referred_by); 16185 } 16186 } 16187 16188 if (!ast_strlen_zero(p_referred_by)) { 16189 char *lessthan; 16190 h_referred_by = ast_strdupa(p_referred_by); 16191 16192 /* Store referrer's caller ID name */ 16193 ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name)); 16194 if ((lessthan = strchr(referdata->referred_by_name, '<'))) { 16195 *(lessthan - 1) = '\0'; /* Space */ 16196 } 16197 16198 referred_by_uri = get_in_brackets(h_referred_by); 16199 16200 if (!strncasecmp(referred_by_uri, "sip:", 4)) { 16201 referred_by_uri += 4; /* Skip sip: */ 16202 } else if (!strncasecmp(referred_by_uri, "sips:", 5)) { 16203 referred_by_uri += 5; /* Skip sips: */ 16204 } else { 16205 ast_log(LOG_WARNING, "Huh? Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri); 16206 referred_by_uri = NULL; 16207 } 16208 } 16209 16210 /* Check for arguments in the refer_to header */ 16211 if ((ptr = strcasestr(refer_to, "replaces="))) { 16212 char *to = NULL, *from = NULL; 16213 16214 /* This is an attended transfer */ 16215 referdata->attendedtransfer = 1; 16216 ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid)); 16217 ast_uri_decode(referdata->replaces_callid); 16218 if ((ptr = strchr(referdata->replaces_callid, ';'))) /* Find options */ { 16219 *ptr++ = '\0'; 16220 } 16221 16222 if (ptr) { 16223 /* Find the different tags before we destroy the string */ 16224 to = strcasestr(ptr, "to-tag="); 16225 from = strcasestr(ptr, "from-tag="); 16226 } 16227 16228 /* Grab the to header */ 16229 if (to) { 16230 ptr = to + 7; 16231 if ((to = strchr(ptr, '&'))) { 16232 *to = '\0'; 16233 } 16234 if ((to = strchr(ptr, ';'))) { 16235 *to = '\0'; 16236 } 16237 ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag)); 16238 } 16239 16240 if (from) { 16241 ptr = from + 9; 16242 if ((to = strchr(ptr, '&'))) { 16243 *to = '\0'; 16244 } 16245 if ((to = strchr(ptr, ';'))) { 16246 *to = '\0'; 16247 } 16248 ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag)); 16249 } 16250 16251 if (!strcmp(referdata->replaces_callid, transferer->callid) && 16252 (!sip_cfg.pedanticsipchecking || 16253 (!strcmp(referdata->replaces_callid_fromtag, transferer->theirtag) && 16254 !strcmp(referdata->replaces_callid_totag, transferer->tag)))) { 16255 ast_log(LOG_WARNING, "Got an attempt to replace own Call-ID on %s\n", transferer->callid); 16256 return -4; 16257 } 16258 16259 if (!sip_cfg.pedanticsipchecking) { 16260 ast_debug(2, "Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid ); 16261 } else { 16262 ast_debug(2, "Attended transfer: Will use Replace-Call-ID : %s F-tag: %s T-tag: %s\n", referdata->replaces_callid, referdata->replaces_callid_fromtag ? referdata->replaces_callid_fromtag : "<none>", referdata->replaces_callid_totag ? referdata->replaces_callid_totag : "<none>" ); 16263 } 16264 } 16265 16266 if ((ptr = strchr(refer_to, '@'))) { /* Separate domain */ 16267 char *urioption = NULL, *domain; 16268 int bracket = 0; 16269 *ptr++ = '\0'; 16270 16271 if ((urioption = strchr(ptr, ';'))) { /* Separate urioptions */ 16272 *urioption++ = '\0'; 16273 } 16274 16275 domain = ptr; 16276 16277 /* Remove :port */ 16278 for (; *ptr != '\0'; ++ptr) { 16279 if (*ptr == ':' && bracket == 0) { 16280 *ptr = '\0'; 16281 break; 16282 } else if (*ptr == '[') { 16283 ++bracket; 16284 } else if (*ptr == ']') { 16285 --bracket; 16286 } 16287 } 16288 16289 SIP_PEDANTIC_DECODE(domain); 16290 SIP_PEDANTIC_DECODE(urioption); 16291 16292 /* Save the domain for the dial plan */ 16293 ast_copy_string(referdata->refer_to_domain, domain, sizeof(referdata->refer_to_domain)); 16294 if (urioption) { 16295 ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption)); 16296 } 16297 } 16298 16299 if ((ptr = strchr(refer_to, ';'))) /* Remove options */ 16300 *ptr = '\0'; 16301 16302 SIP_PEDANTIC_DECODE(refer_to); 16303 ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to)); 16304 16305 if (referred_by_uri) { 16306 if ((ptr = strchr(referred_by_uri, ';'))) /* Remove options */ 16307 *ptr = '\0'; 16308 SIP_PEDANTIC_DECODE(referred_by_uri); 16309 ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by)); 16310 } else { 16311 referdata->referred_by[0] = '\0'; 16312 } 16313 16314 /* Determine transfer context */ 16315 if (transferer->owner) { 16316 /* By default, use the context in the channel sending the REFER */ 16317 transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT"); 16318 if (ast_strlen_zero(transfer_context)) { 16319 transfer_context = transferer->owner->macrocontext; 16320 } 16321 } 16322 if (ast_strlen_zero(transfer_context)) { 16323 transfer_context = S_OR(transferer->context, sip_cfg.default_context); 16324 } 16325 16326 ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context)); 16327 16328 /* Either an existing extension or the parking extension */ 16329 if (referdata->attendedtransfer || ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) { 16330 if (sip_debug_test_pvt(transferer)) { 16331 ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri); 16332 } 16333 /* We are ready to transfer to the extension */ 16334 return 0; 16335 } 16336 if (sip_debug_test_pvt(transferer)) 16337 ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context); 16338 16339 /* Failure, we can't find this extension */ 16340 return -1; 16341 }
| static int get_rpid | ( | struct sip_pvt * | p, | |
| struct sip_request * | oreq | |||
| ) | [static] |
Get name, number and presentation from remote party id header, returns true if a valid header was found and it was different from the current caller id.
Definition at line 15674 of file chan_sip.c.
References ast_copy_string(), ast_is_shrinkable_phonenumber(), AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, ast_set_callerid(), ast_shrink_phone_number(), ast_skip_blanks(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, cid_name, cid_num, get_header(), and get_pai().
Referenced by check_peer_ok(), check_user_full(), handle_request_invite(), handle_request_update(), and handle_response_invite().
15675 { 15676 char tmp[256]; 15677 struct sip_request *req; 15678 char *cid_num = ""; 15679 char *cid_name = ""; 15680 int callingpres = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 15681 char *privacy = ""; 15682 char *screen = ""; 15683 char *start, *end; 15684 15685 if (!ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) 15686 return 0; 15687 req = oreq; 15688 if (!req) 15689 req = &p->initreq; 15690 ast_copy_string(tmp, get_header(req, "Remote-Party-ID"), sizeof(tmp)); 15691 if (ast_strlen_zero(tmp)) { 15692 return get_pai(p, req); 15693 } 15694 15695 /* 15696 * RPID is not: 15697 * rpid = (name-addr / addr-spec) *(SEMI rpi-token) 15698 * But it is: 15699 * rpid = [display-name] LAQUOT addr-spec RAQUOT *(SEMI rpi-token) 15700 * Ergo, calling parse_name_andor_addr() on it wouldn't be 15701 * correct because that would allow addr-spec style too. 15702 */ 15703 start = tmp; 15704 /* Quoted (note that we're not dealing with escapes properly) */ 15705 if (*start == '"') { 15706 *start++ = '\0'; 15707 end = strchr(start, '"'); 15708 if (!end) 15709 return 0; 15710 *end++ = '\0'; 15711 cid_name = start; 15712 start = ast_skip_blanks(end); 15713 /* Unquoted */ 15714 } else { 15715 cid_name = start; 15716 start = end = strchr(start, '<'); 15717 if (!start) { 15718 return 0; 15719 } 15720 /* trim blanks if there are any. the mandatory NUL is done below */ 15721 while (--end >= cid_name && *end < 33) { 15722 *end = '\0'; 15723 } 15724 } 15725 15726 if (*start != '<') 15727 return 0; 15728 *start++ = '\0'; 15729 end = strchr(start, '@'); 15730 if (!end) 15731 return 0; 15732 *end++ = '\0'; 15733 if (strncasecmp(start, "sip:", 4)) 15734 return 0; 15735 cid_num = start + 4; 15736 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(cid_num)) 15737 ast_shrink_phone_number(cid_num); 15738 start = end; 15739 15740 end = strchr(start, '>'); 15741 if (!end) 15742 return 0; 15743 *end++ = '\0'; 15744 if (*end) { 15745 start = end; 15746 if (*start != ';') 15747 return 0; 15748 *start++ = '\0'; 15749 while (!ast_strlen_zero(start)) { 15750 end = strchr(start, ';'); 15751 if (end) 15752 *end++ = '\0'; 15753 if (!strncasecmp(start, "privacy=", 8)) 15754 privacy = start + 8; 15755 else if (!strncasecmp(start, "screen=", 7)) 15756 screen = start + 7; 15757 start = end; 15758 } 15759 15760 if (!strcasecmp(privacy, "full")) { 15761 if (!strcasecmp(screen, "yes")) 15762 callingpres = AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN; 15763 else if (!strcasecmp(screen, "no")) 15764 callingpres = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 15765 } else { 15766 if (!strcasecmp(screen, "yes")) 15767 callingpres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 15768 else if (!strcasecmp(screen, "no")) 15769 callingpres = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 15770 } 15771 } 15772 15773 /* Only return true if the supplied caller id is different */ 15774 if (!strcasecmp(p->cid_num, cid_num) && !strcasecmp(p->cid_name, cid_name) && p->callingpres == callingpres) 15775 return 0; 15776 15777 ast_string_field_set(p, cid_num, cid_num); 15778 ast_string_field_set(p, cid_name, cid_name); 15779 p->callingpres = callingpres; 15780 15781 if (p->owner) { 15782 ast_set_callerid(p->owner, cid_num, cid_name, NULL); 15783 p->owner->caller.id.name.presentation = callingpres; 15784 p->owner->caller.id.number.presentation = callingpres; 15785 } 15786 15787 return 1; 15788 }
| static const char * get_sdp_iterate | ( | int * | start, | |
| struct sip_request * | req, | |||
| const char * | name | |||
| ) | [static] |
Lookup 'name' in the SDP starting at the 'start' line. Returns the matching line, and 'start' is updated with the next line number.
Definition at line 7547 of file chan_sip.c.
References get_body_by_line(), and len().
Referenced by get_ip_and_port_from_sdp(), and process_sdp().
07548 { 07549 int len = strlen(name); 07550 07551 while (*start < (req->sdp_start + req->sdp_count)) { 07552 const char *r = get_body_by_line(REQ_OFFSET_TO_STR(req, line[(*start)++]), name, len, '='); 07553 if (r[0] != '\0') 07554 return r; 07555 } 07556 07557 /* if the line was not found, ensure that *start points past the SDP */ 07558 (*start)++; 07559 07560 return ""; 07561 }
| static char get_sdp_line | ( | int * | start, | |
| int | stop, | |||
| struct sip_request * | req, | |||
| const char ** | value | |||
| ) | [static] |
Fetches the next valid SDP line between the 'start' line (inclusive) and the 'stop' line (exclusive). Returns the type ('a', 'c', ...) and matching line in reference 'start' is updated with the next line number.
Definition at line 7568 of file chan_sip.c.
References ast_skip_blanks(), and type.
Referenced by process_sdp().
07569 { 07570 char type = '\0'; 07571 const char *line = NULL; 07572 07573 if (stop > (req->sdp_start + req->sdp_count)) { 07574 stop = req->sdp_start + req->sdp_count; 07575 } 07576 07577 while (*start < stop) { 07578 line = REQ_OFFSET_TO_STR(req, line[(*start)++]); 07579 if (line[1] == '=') { 07580 type = line[0]; 07581 *value = ast_skip_blanks(line + 2); 07582 break; 07583 } 07584 } 07585 07586 return type; 07587 }
| static struct sip_pvt * get_sip_pvt_byid_locked | ( | const char * | callid, | |
| const char * | totag, | |||
| const char * | fromtag | |||
| ) | [static, read] |
Lock dialog lock and find matching pvt lock.
Definition at line 16046 of file chan_sip.c.
References ao2_t_find, ast_channel_trylock, ast_debug, ast_strlen_zero(), ast_test_flag, OBJ_POINTER, sip_cfg, sip_pvt_lock, sip_pvt_unlock, and TRUE.
Referenced by handle_request_invite(), and local_attended_transfer().
16047 { 16048 struct sip_pvt *sip_pvt_ptr; 16049 struct sip_pvt tmp_dialog = { 16050 .callid = callid, 16051 }; 16052 16053 if (totag) { 16054 ast_debug(4, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>"); 16055 } 16056 16057 /* Search dialogs and find the match */ 16058 16059 sip_pvt_ptr = ao2_t_find(dialogs, &tmp_dialog, OBJ_POINTER, "ao2_find of dialog in dialogs table"); 16060 if (sip_pvt_ptr) { 16061 /* Go ahead and lock it (and its owner) before returning */ 16062 sip_pvt_lock(sip_pvt_ptr); 16063 if (sip_cfg.pedanticsipchecking) { 16064 unsigned char frommismatch = 0, tomismatch = 0; 16065 16066 if (ast_strlen_zero(fromtag)) { 16067 sip_pvt_unlock(sip_pvt_ptr); 16068 ast_debug(4, "Matched %s call for callid=%s - no from tag specified, pedantic check fails\n", 16069 sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid); 16070 return NULL; 16071 } 16072 16073 if (ast_strlen_zero(totag)) { 16074 sip_pvt_unlock(sip_pvt_ptr); 16075 ast_debug(4, "Matched %s call for callid=%s - no to tag specified, pedantic check fails\n", 16076 sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid); 16077 return NULL; 16078 } 16079 /* RFC 3891 16080 * > 3. User Agent Server Behavior: Receiving a Replaces Header 16081 * > The Replaces header contains information used to match an existing 16082 * > SIP dialog (call-id, to-tag, and from-tag). Upon receiving an INVITE 16083 * > with a Replaces header, the User Agent (UA) attempts to match this 16084 * > information with a confirmed or early dialog. The User Agent Server 16085 * > (UAS) matches the to-tag and from-tag parameters as if they were tags 16086 * > present in an incoming request. In other words, the to-tag parameter 16087 * > is compared to the local tag, and the from-tag parameter is compared 16088 * > to the remote tag. 16089 * 16090 * Thus, the totag is always compared to the local tag, regardless if 16091 * this our call is an incoming or outgoing call. 16092 */ 16093 frommismatch = !!strcmp(fromtag, sip_pvt_ptr->theirtag); 16094 tomismatch = !!strcmp(totag, sip_pvt_ptr->tag); 16095 16096 /* Don't check from if the dialog is not established, due to multi forking the from 16097 * can change when the call is not answered yet. 16098 */ 16099 if ((frommismatch && ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) || tomismatch) { 16100 sip_pvt_unlock(sip_pvt_ptr); 16101 if (frommismatch) { 16102 ast_debug(4, "Matched %s call for callid=%s - pedantic from tag check fails; their tag is %s our tag is %s\n", 16103 sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid, 16104 fromtag, sip_pvt_ptr->theirtag); 16105 } 16106 if (tomismatch) { 16107 ast_debug(4, "Matched %s call for callid=%s - pedantic to tag check fails; their tag is %s our tag is %s\n", 16108 sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid, 16109 totag, sip_pvt_ptr->tag); 16110 } 16111 return NULL; 16112 } 16113 } 16114 16115 if (totag) 16116 ast_debug(4, "Matched %s call - their tag is %s Our tag is %s\n", 16117 sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", 16118 sip_pvt_ptr->theirtag, sip_pvt_ptr->tag); 16119 16120 /* deadlock avoidance... */ 16121 while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) { 16122 sip_pvt_unlock(sip_pvt_ptr); 16123 usleep(1); 16124 sip_pvt_lock(sip_pvt_ptr); 16125 } 16126 } 16127 16128 return sip_pvt_ptr; 16129 }
| static const char* get_srv_protocol | ( | enum sip_transport | t | ) | [inline, static] |
Return protocol string for srv dns query.
Definition at line 3478 of file chan_sip.c.
Referenced by __sip_subscribe_mwi_do(), build_peer(), create_addr(), and transmit_register().
| static const char* get_srv_service | ( | enum sip_transport | t | ) | [inline, static] |
Return service string for srv dns query.
Definition at line 3492 of file chan_sip.c.
Referenced by __sip_subscribe_mwi_do(), build_peer(), create_addr(), and transmit_register().
| static const char* get_transport | ( | enum sip_transport | t | ) | [inline, static] |
Return transport as string.
Definition at line 3463 of file chan_sip.c.
Referenced by _sip_show_peer(), ast_sip_ouraddrfor(), build_contact(), get_transport_pvt(), handle_request_do(), parse_moved_contact(), sip_show_settings(), sip_show_tcp(), and transmit_notify_with_mwi().
| static const char* get_transport_list | ( | unsigned int | transports | ) | [inline, static] |
Return configuration of transports for a device.
Definition at line 3442 of file chan_sip.c.
Referenced by _sip_show_peer(), peers_data_provider_get(), and sip_show_settings().
03442 { 03443 switch (transports) { 03444 case SIP_TRANSPORT_UDP: 03445 return "UDP"; 03446 case SIP_TRANSPORT_TCP: 03447 return "TCP"; 03448 case SIP_TRANSPORT_TLS: 03449 return "TLS"; 03450 case SIP_TRANSPORT_UDP | SIP_TRANSPORT_TCP: 03451 return "TCP,UDP"; 03452 case SIP_TRANSPORT_UDP | SIP_TRANSPORT_TLS: 03453 return "TLS,UDP"; 03454 case SIP_TRANSPORT_TCP | SIP_TRANSPORT_TLS: 03455 return "TLS,TCP"; 03456 default: 03457 return transports ? 03458 "TLS,TCP,UDP" : "UNKNOWN"; 03459 } 03460 }
| static const char* get_transport_pvt | ( | struct sip_pvt * | p | ) | [inline, static] |
Return transport of dialog.
Definition at line 3510 of file chan_sip.c.
References get_transport(), and set_socket_transport().
Referenced by __sip_xmit(), and build_via().
03511 { 03512 if (p->outboundproxy && p->outboundproxy->transport) { 03513 set_socket_transport(&p->socket, p->outboundproxy->transport); 03514 } 03515 03516 return get_transport(p->socket.type); 03517 }
| static int get_transport_str2enum | ( | const char * | transport | ) | [static] |
Return int representing a bit field of transport types found in const char *transport.
Definition at line 3420 of file chan_sip.c.
References ast_strlen_zero().
Referenced by __set_address_from_contact(), and parse_register_contact().
03421 { 03422 int res = 0; 03423 03424 if (ast_strlen_zero(transport)) { 03425 return res; 03426 } 03427 03428 if (!strcasecmp(transport, "udp")) { 03429 res |= SIP_TRANSPORT_UDP; 03430 } 03431 if (!strcasecmp(transport, "tcp")) { 03432 res |= SIP_TRANSPORT_TCP; 03433 } 03434 if (!strcasecmp(transport, "tls")) { 03435 res |= SIP_TRANSPORT_TLS; 03436 } 03437 03438 return res; 03439 }
| static const char * gettag | ( | const struct sip_request * | req, | |
| const char * | header, | |||
| char * | tagbuf, | |||
| int | tagbufsize | |||
| ) | [static] |
Get tag from packet.
Definition at line 22426 of file chan_sip.c.
References ast_copy_string(), and get_header().
Referenced by find_call(), handle_incoming(), handle_request_subscribe(), and handle_response().
22427 { 22428 const char *thetag; 22429 22430 if (!tagbuf) 22431 return NULL; 22432 tagbuf[0] = '\0'; /* reset the buffer */ 22433 thetag = get_header(req, header); 22434 thetag = strcasestr(thetag, ";tag="); 22435 if (thetag) { 22436 thetag += 5; 22437 ast_copy_string(tagbuf, thetag, tagbufsize); 22438 return strsep(&tagbuf, ";"); 22439 } 22440 return NULL; 22441 }
| static int handle_cc_notify | ( | struct sip_pvt * | pvt, | |
| struct sip_request * | req | |||
| ) | [static] |
Definition at line 22443 of file chan_sip.c.
References ao2_callback, ao2_ref, ast_cc_monitor_callee_available(), ast_cc_monitor_request_acked(), ast_string_field_set, ast_strlen_zero(), construct_pidf_body(), find_sip_monitor_instance_by_subscription_pvt(), get_body(), get_header(), get_in_brackets(), status, transmit_publish(), and transmit_response().
Referenced by handle_request_notify().
22444 { 22445 struct sip_monitor_instance *monitor_instance = ao2_callback(sip_monitor_instances, 0, 22446 find_sip_monitor_instance_by_subscription_pvt, pvt); 22447 const char *status = get_body(req, "cc-state", ':'); 22448 struct cc_epa_entry *cc_entry; 22449 char *uri; 22450 22451 if (!monitor_instance) { 22452 transmit_response(pvt, "400 Bad Request", req); 22453 return -1; 22454 } 22455 22456 if (ast_strlen_zero(status)) { 22457 ao2_ref(monitor_instance, -1); 22458 transmit_response(pvt, "400 Bad Request", req); 22459 return -1; 22460 } 22461 22462 if (!strcmp(status, "queued")) { 22463 /* We've been told that we're queued. This is the endpoint's way of telling 22464 * us that it has accepted our CC request. We need to alert the core of this 22465 * development 22466 */ 22467 ast_cc_monitor_request_acked(monitor_instance->core_id, "SIP endpoint %s accepted request", monitor_instance->device_name); 22468 transmit_response(pvt, "200 OK", req); 22469 ao2_ref(monitor_instance, -1); 22470 return 0; 22471 } 22472 22473 /* It's open! Yay! */ 22474 uri = get_body(req, "cc-URI", ':'); 22475 if (ast_strlen_zero(uri)) { 22476 uri = get_in_brackets((char *)get_header(req, "From")); 22477 } 22478 22479 ast_string_field_set(monitor_instance, notify_uri, uri); 22480 if (monitor_instance->suspension_entry) { 22481 cc_entry = monitor_instance->suspension_entry->instance_data; 22482 if (cc_entry->current_state == CC_CLOSED) { 22483 /* If we've created a suspension entry and the current state is closed, then that means 22484 * we got a notice from the CC core earlier to suspend monitoring, but because this particular 22485 * call leg had not yet notified us that it was ready for recall, it meant that we 22486 * could not yet send a PUBLISH. Now, however, we can. 22487 */ 22488 construct_pidf_body(CC_CLOSED, monitor_instance->suspension_entry->body, 22489 sizeof(monitor_instance->suspension_entry->body), monitor_instance->peername); 22490 transmit_publish(monitor_instance->suspension_entry, SIP_PUBLISH_INITIAL, monitor_instance->notify_uri); 22491 } else { 22492 ast_cc_monitor_callee_available(monitor_instance->core_id, "SIP monitored callee has become available"); 22493 } 22494 } else { 22495 ast_cc_monitor_callee_available(monitor_instance->core_id, "SIP monitored callee has become available"); 22496 } 22497 ao2_ref(monitor_instance, -1); 22498 transmit_response(pvt, "200 OK", req); 22499 22500 return 0; 22501 }
| static int handle_cc_subscribe | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Definition at line 25284 of file chan_sip.c.
References ao2_ref, ast_cc_agent_accept_request(), ast_cc_failed(), ast_log(), ast_strlen_zero(), ast_cc_agent::core_id, ast_cc_agent::device_name, find_sip_cc_agent_by_subscribe_uri(), get_header(), LOG_WARNING, ast_cc_agent::private_data, and transmit_response().
Referenced by handle_request_subscribe().
25285 { 25286 const char *uri = REQ_OFFSET_TO_STR(req, rlPart2); 25287 char *param_separator; 25288 struct ast_cc_agent *agent; 25289 struct sip_cc_agent_pvt *agent_pvt; 25290 const char *expires_str = get_header(req, "Expires"); 25291 int expires = -1; /* Just need it to be non-zero */ 25292 25293 if (!ast_strlen_zero(expires_str)) { 25294 sscanf(expires_str, "%d", &expires); 25295 } 25296 25297 if ((param_separator = strchr(uri, ';'))) { 25298 *param_separator = '\0'; 25299 } 25300 25301 p->subscribed = CALL_COMPLETION; 25302 25303 if (!(agent = find_sip_cc_agent_by_subscribe_uri(uri))) { 25304 if (!expires) { 25305 /* Typically, if a 0 Expires reaches us and we can't find 25306 * the corresponding agent, it means that the CC transaction 25307 * has completed and so the calling side is just trying to 25308 * clean up its subscription. We'll just respond with a 25309 * 200 OK and be done with it 25310 */ 25311 transmit_response(p, "200 OK", req); 25312 return 0; 25313 } 25314 ast_log(LOG_WARNING, "Invalid URI '%s' in CC subscribe\n", uri); 25315 transmit_response(p, "404 Not Found", req); 25316 return -1; 25317 } 25318 25319 agent_pvt = agent->private_data; 25320 25321 if (!expires) { 25322 /* We got sent a SUBSCRIBE and found an agent. This means that CC 25323 * is being canceled. 25324 */ 25325 ast_cc_failed(agent->core_id, "CC is being canceled by %s", agent->device_name); 25326 transmit_response(p, "200 OK", req); 25327 ao2_ref(agent, -1); 25328 return 0; 25329 } 25330 25331 agent_pvt->subscribe_pvt = dialog_ref(p, "SIP CC agent gains reference to subscription dialog"); 25332 ast_cc_agent_accept_request(agent->core_id, "SIP caller %s has requested CC via SUBSCRIBE", 25333 agent->device_name); 25334 25335 /* We don't send a response here. That is done in the agent's ack callback or in the 25336 * agent destructor, should a failure occur before we have responded 25337 */ 25338 ao2_ref(agent, -1); 25339 return 0; 25340 }
| static int handle_common_options | ( | struct ast_flags * | flags, | |
| struct ast_flags * | mask, | |||
| struct ast_variable * | v | |||
| ) | [static] |
Handle flag-type options common to configuration of devices - peers.
| flags | array of two struct ast_flags | |
| mask | array of two struct ast_flags | |
| v | linked list of config variables to process |
Definition at line 27556 of file chan_sip.c.
References ast_clear_flag, ast_copy_string(), ast_false(), ast_log(), ast_set2_flag, ast_set_flag, ast_strdupa, ast_true(), ast_variable::lineno, LOG_WARNING, ast_variable::name, set_insecure_flags(), ast_variable::value, and word.
Referenced by build_peer(), and reload_config().
27557 { 27558 int res = 1; 27559 27560 if (!strcasecmp(v->name, "trustrpid")) { 27561 ast_set_flag(&mask[0], SIP_TRUSTRPID); 27562 ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID); 27563 } else if (!strcasecmp(v->name, "sendrpid")) { 27564 ast_set_flag(&mask[0], SIP_SENDRPID); 27565 if (!strcasecmp(v->value, "pai")) { 27566 ast_set_flag(&flags[0], SIP_SENDRPID_PAI); 27567 } else if (!strcasecmp(v->value, "rpid")) { 27568 ast_set_flag(&flags[0], SIP_SENDRPID_RPID); 27569 } else if (ast_true(v->value)) { 27570 ast_set_flag(&flags[0], SIP_SENDRPID_RPID); 27571 } 27572 } else if (!strcasecmp(v->name, "rpid_update")) { 27573 ast_set_flag(&mask[1], SIP_PAGE2_RPID_UPDATE); 27574 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RPID_UPDATE); 27575 } else if (!strcasecmp(v->name, "rpid_immediate")) { 27576 ast_set_flag(&mask[1], SIP_PAGE2_RPID_IMMEDIATE); 27577 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RPID_IMMEDIATE); 27578 } else if (!strcasecmp(v->name, "trust_id_outbound")) { 27579 ast_set_flag(&mask[1], SIP_PAGE2_TRUST_ID_OUTBOUND); 27580 ast_clear_flag(&flags[1], SIP_PAGE2_TRUST_ID_OUTBOUND); 27581 if (!strcasecmp(v->value, "legacy")) { 27582 ast_set_flag(&flags[1], SIP_PAGE2_TRUST_ID_OUTBOUND_LEGACY); 27583 } else if (ast_true(v->value)) { 27584 ast_set_flag(&flags[1], SIP_PAGE2_TRUST_ID_OUTBOUND_YES); 27585 } else if (ast_false(v->value)) { 27586 ast_set_flag(&flags[1], SIP_PAGE2_TRUST_ID_OUTBOUND_NO); 27587 } else { 27588 ast_log(LOG_WARNING, "Unknown trust_id_outbound mode '%s' on line %d, using legacy\n", v->value, v->lineno); 27589 ast_set_flag(&flags[1], SIP_PAGE2_TRUST_ID_OUTBOUND_LEGACY); 27590 } 27591 } else if (!strcasecmp(v->name, "g726nonstandard")) { 27592 ast_set_flag(&mask[0], SIP_G726_NONSTANDARD); 27593 ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD); 27594 } else if (!strcasecmp(v->name, "useclientcode")) { 27595 ast_set_flag(&mask[0], SIP_USECLIENTCODE); 27596 ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE); 27597 } else if (!strcasecmp(v->name, "dtmfmode")) { 27598 ast_set_flag(&mask[0], SIP_DTMF); 27599 ast_clear_flag(&flags[0], SIP_DTMF); 27600 if (!strcasecmp(v->value, "inband")) 27601 ast_set_flag(&flags[0], SIP_DTMF_INBAND); 27602 else if (!strcasecmp(v->value, "rfc2833")) 27603 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 27604 else if (!strcasecmp(v->value, "info")) 27605 ast_set_flag(&flags[0], SIP_DTMF_INFO); 27606 else if (!strcasecmp(v->value, "shortinfo")) 27607 ast_set_flag(&flags[0], SIP_DTMF_SHORTINFO); 27608 else if (!strcasecmp(v->value, "auto")) 27609 ast_set_flag(&flags[0], SIP_DTMF_AUTO); 27610 else { 27611 ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno); 27612 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 27613 } 27614 } else if (!strcasecmp(v->name, "nat")) { 27615 ast_set_flag(&mask[0], SIP_NAT_FORCE_RPORT); 27616 ast_set_flag(&mask[1], SIP_PAGE2_SYMMETRICRTP); 27617 if (!strcasecmp(v->value, "yes")) { 27618 ast_set_flag(&flags[0], SIP_NAT_FORCE_RPORT); 27619 ast_set_flag(&flags[1], SIP_PAGE2_SYMMETRICRTP); 27620 } else if (!strcasecmp(v->value, "force_rport")) { 27621 ast_set_flag(&flags[0], SIP_NAT_FORCE_RPORT); 27622 } else if (!strcasecmp(v->value, "comedia")) { 27623 ast_set_flag(&flags[1], SIP_PAGE2_SYMMETRICRTP); 27624 } 27625 } else if (!strcasecmp(v->name, "directmedia") || !strcasecmp(v->name, "canreinvite")) { 27626 ast_set_flag(&mask[0], SIP_REINVITE); 27627 ast_clear_flag(&flags[0], SIP_REINVITE); 27628 if (ast_true(v->value)) { 27629 ast_set_flag(&flags[0], SIP_DIRECT_MEDIA | SIP_DIRECT_MEDIA_NAT); 27630 } else if (!ast_false(v->value)) { 27631 char buf[64]; 27632 char *word, *next = buf; 27633 27634 ast_copy_string(buf, v->value, sizeof(buf)); 27635 while ((word = strsep(&next, ","))) { 27636 if (!strcasecmp(word, "update")) { 27637 ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_DIRECT_MEDIA); 27638 } else if (!strcasecmp(word, "nonat")) { 27639 ast_set_flag(&flags[0], SIP_DIRECT_MEDIA); 27640 ast_clear_flag(&flags[0], SIP_DIRECT_MEDIA_NAT); 27641 } else if (!strcasecmp(word, "outgoing")) { 27642 ast_set_flag(&flags[0], SIP_DIRECT_MEDIA); 27643 ast_set_flag(&mask[2], SIP_PAGE3_DIRECT_MEDIA_OUTGOING); 27644 ast_set_flag(&flags[2], SIP_PAGE3_DIRECT_MEDIA_OUTGOING); 27645 } else { 27646 ast_log(LOG_WARNING, "Unknown directmedia mode '%s' on line %d\n", v->value, v->lineno); 27647 } 27648 } 27649 } 27650 } else if (!strcasecmp(v->name, "insecure")) { 27651 ast_set_flag(&mask[0], SIP_INSECURE); 27652 ast_clear_flag(&flags[0], SIP_INSECURE); 27653 set_insecure_flags(&flags[0], v->value, v->lineno); 27654 } else if (!strcasecmp(v->name, "progressinband")) { 27655 ast_set_flag(&mask[0], SIP_PROG_INBAND); 27656 ast_clear_flag(&flags[0], SIP_PROG_INBAND); 27657 if (ast_true(v->value)) 27658 ast_set_flag(&flags[0], SIP_PROG_INBAND_YES); 27659 else if (strcasecmp(v->value, "never")) 27660 ast_set_flag(&flags[0], SIP_PROG_INBAND_NO); 27661 } else if (!strcasecmp(v->name, "promiscredir")) { 27662 ast_set_flag(&mask[0], SIP_PROMISCREDIR); 27663 ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR); 27664 } else if (!strcasecmp(v->name, "videosupport")) { 27665 if (!strcasecmp(v->value, "always")) { 27666 ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS); 27667 ast_set_flag(&flags[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS); 27668 } else { 27669 ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT); 27670 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT); 27671 } 27672 } else if (!strcasecmp(v->name, "textsupport")) { 27673 ast_set_flag(&mask[1], SIP_PAGE2_TEXTSUPPORT); 27674 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_TEXTSUPPORT); 27675 res = 1; 27676 } else if (!strcasecmp(v->name, "allowoverlap")) { 27677 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP); 27678 ast_clear_flag(&flags[1], SIP_PAGE2_ALLOWOVERLAP); 27679 if (ast_true(v->value)) { 27680 ast_set_flag(&flags[1], SIP_PAGE2_ALLOWOVERLAP_YES); 27681 } else if (!strcasecmp(v->value, "dtmf")){ 27682 ast_set_flag(&flags[1], SIP_PAGE2_ALLOWOVERLAP_DTMF); 27683 } 27684 } else if (!strcasecmp(v->name, "allowsubscribe")) { 27685 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE); 27686 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE); 27687 } else if (!strcasecmp(v->name, "ignoresdpversion")) { 27688 ast_set_flag(&mask[1], SIP_PAGE2_IGNORESDPVERSION); 27689 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_IGNORESDPVERSION); 27690 } else if (!strcasecmp(v->name, "faxdetect")) { 27691 ast_set_flag(&mask[1], SIP_PAGE2_FAX_DETECT); 27692 if (ast_true(v->value)) { 27693 ast_set_flag(&flags[1], SIP_PAGE2_FAX_DETECT_BOTH); 27694 } else if (ast_false(v->value)) { 27695 ast_clear_flag(&flags[1], SIP_PAGE2_FAX_DETECT_BOTH); 27696 } else { 27697 char *buf = ast_strdupa(v->value); 27698 char *word, *next = buf; 27699 27700 while ((word = strsep(&next, ","))) { 27701 if (!strcasecmp(word, "cng")) { 27702 ast_set_flag(&flags[1], SIP_PAGE2_FAX_DETECT_CNG); 27703 } else if (!strcasecmp(word, "t38")) { 27704 ast_set_flag(&flags[1], SIP_PAGE2_FAX_DETECT_T38); 27705 } else { 27706 ast_log(LOG_WARNING, "Unknown faxdetect mode '%s' on line %d.\n", word, v->lineno); 27707 } 27708 } 27709 } 27710 } else if (!strcasecmp(v->name, "rfc2833compensate")) { 27711 ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE); 27712 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE); 27713 } else if (!strcasecmp(v->name, "buggymwi")) { 27714 ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI); 27715 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI); 27716 } else 27717 res = 0; 27718 27719 return res; 27720 }
| static int handle_incoming | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| struct ast_sockaddr * | addr, | |||
| int * | recount, | |||
| int * | nounlock | |||
| ) | [static] |
Handle incoming SIP requests (methods).
Definition at line 25796 of file chan_sip.c.
References __get_header(), __sip_ack(), ast_channel_ref, ast_channel_unlock, ast_channel_unref, AST_CONTROL_SRCCHANGE, ast_debug, ast_log(), ast_queue_control(), ast_random(), ast_skip_blanks(), ast_sockaddr_stringify(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose, check_pendings(), extract_uri(), find_sdp(), get_header(), gettag(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_message(), handle_request_notify(), handle_request_options(), handle_request_publish(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_request_update(), handle_response(), cfsip_methods::id, len(), LOG_ERROR, LOG_NOTICE, LOG_WARNING, pbx_builtin_setvar_helper(), process_sdp(), pvt_set_needdestroy(), sip_cfg, sip_debug_test_pvt(), sip_methods, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), cfsip_methods::text, transmit_response(), transmit_response_reliable(), transmit_response_with_allow(), and transmit_response_with_retry_after().
Referenced by handle_request_do().
25797 { 25798 /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things 25799 relatively static */ 25800 const char *cmd; 25801 const char *cseq; 25802 const char *useragent; 25803 const char *via; 25804 const char *callid; 25805 int via_pos = 0; 25806 uint32_t seqno; 25807 int len; 25808 int respid; 25809 int res = 0; 25810 int debug = sip_debug_test_pvt(p); 25811 const char *e; 25812 int error = 0; 25813 int oldmethod = p->method; 25814 int acked = 0; 25815 25816 /* RFC 3261 - 8.1.1 A valid SIP request must contain To, From, CSeq, Call-ID and Via. 25817 * 8.2.6.2 Response must have To, From, Call-ID CSeq, and Via related to the request, 25818 * so we can check to make sure these fields exist for all requests and responses */ 25819 cseq = get_header(req, "Cseq"); 25820 cmd = REQ_OFFSET_TO_STR(req, header[0]); 25821 /* Save the via_pos so we can check later that responses only have 1 Via header */ 25822 via = __get_header(req, "Via", &via_pos); 25823 /* This must exist already because we've called find_call by now */ 25824 callid = get_header(req, "Call-ID"); 25825 25826 /* Must have Cseq */ 25827 if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq) || ast_strlen_zero(via)) { 25828 ast_log(LOG_ERROR, "Dropping this SIP message with Call-ID '%s', it's incomplete.\n", callid); 25829 error = 1; 25830 } 25831 if (!error && sscanf(cseq, "%30u%n", &seqno, &len) != 1) { 25832 ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd); 25833 error = 1; 25834 } 25835 if (error) { 25836 if (!p->initreq.headers) { /* New call */ 25837 pvt_set_needdestroy(p, "no headers"); 25838 } 25839 return -1; 25840 } 25841 /* Get the command XXX */ 25842 25843 cmd = REQ_OFFSET_TO_STR(req, rlPart1); 25844 e = ast_skip_blanks(REQ_OFFSET_TO_STR(req, rlPart2)); 25845 25846 /* Save useragent of the client */ 25847 useragent = get_header(req, "User-Agent"); 25848 if (!ast_strlen_zero(useragent)) 25849 ast_string_field_set(p, useragent, useragent); 25850 25851 /* Find out SIP method for incoming request */ 25852 if (req->method == SIP_RESPONSE) { /* Response to our request */ 25853 /* ignore means "don't do anything with it" but still have to 25854 * respond appropriately. 25855 * But in this case this is a response already, so we really 25856 * have nothing to do with this message, and even setting the 25857 * ignore flag is pointless. 25858 */ 25859 if (ast_strlen_zero(e)) { 25860 return 0; 25861 } 25862 if (sscanf(e, "%30d %n", &respid, &len) != 1) { 25863 ast_log(LOG_WARNING, "Invalid response: '%s'\n", e); 25864 return 0; 25865 } 25866 if (respid <= 0) { 25867 ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid); 25868 return 0; 25869 } 25870 /* RFC 3261 - 8.1.3.3 If more than one Via header field value is present in a reponse 25871 * the UAC SHOULD discard the message. This is not perfect, as it will not catch multiple 25872 * headers joined with a comma. Fixing that would pretty much involve writing a new parser */ 25873 if (!ast_strlen_zero(__get_header(req, "via", &via_pos))) { 25874 ast_log(LOG_WARNING, "Misrouted SIP response '%s' with Call-ID '%s', too many vias\n", e, callid); 25875 return 0; 25876 } 25877 if (p->ocseq && (p->ocseq < seqno)) { 25878 ast_debug(1, "Ignoring out of order response %u (expecting %u)\n", seqno, p->ocseq); 25879 return -1; 25880 } else { 25881 char causevar[256], causeval[256]; 25882 25883 if ((respid == 200) || ((respid >= 300) && (respid <= 399))) { 25884 extract_uri(p, req); 25885 } 25886 25887 handle_response(p, respid, e + len, req, seqno); 25888 25889 if (global_store_sip_cause && p->owner) { 25890 struct ast_channel *owner = p->owner; 25891 25892 snprintf(causevar, sizeof(causevar), "MASTER_CHANNEL(HASH(SIP_CAUSE,%s))", owner->name); 25893 snprintf(causeval, sizeof(causeval), "SIP %s", REQ_OFFSET_TO_STR(req, rlPart2)); 25894 25895 ast_channel_ref(owner); 25896 sip_pvt_unlock(p); 25897 ast_channel_unlock(owner); 25898 *nounlock = 1; 25899 pbx_builtin_setvar_helper(owner, causevar, causeval); 25900 ast_channel_unref(owner); 25901 sip_pvt_lock(p); 25902 } 25903 } 25904 return 0; 25905 } 25906 25907 /* New SIP request coming in 25908 (could be new request in existing SIP dialog as well...) 25909 */ 25910 25911 p->method = req->method; /* Find out which SIP method they are using */ 25912 ast_debug(4, "**** Received %s (%u) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 25913 25914 if (p->icseq && (p->icseq > seqno) ) { 25915 if (p->pendinginvite && seqno == p->pendinginvite && (req->method == SIP_ACK || req->method == SIP_CANCEL)) { 25916 ast_debug(2, "Got CANCEL or ACK on INVITE with transactions in between.\n"); 25917 } else { 25918 ast_debug(1, "Ignoring too old SIP packet packet %u (expecting >= %u)\n", seqno, p->icseq); 25919 if (req->method == SIP_INVITE) { 25920 unsigned int ran = (ast_random() % 10) + 1; 25921 char seconds[4]; 25922 snprintf(seconds, sizeof(seconds), "%u", ran); 25923 transmit_response_with_retry_after(p, "500 Server error", req, seconds); /* respond according to RFC 3261 14.2 with Retry-After betwewn 0 and 10 */ 25924 } else if (req->method != SIP_ACK) { 25925 transmit_response(p, "500 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */ 25926 } 25927 return -1; 25928 } 25929 } else if (p->icseq && 25930 p->icseq == seqno && 25931 req->method != SIP_ACK && 25932 (p->method != SIP_CANCEL || p->alreadygone)) { 25933 /* ignore means "don't do anything with it" but still have to 25934 respond appropriately. We do this if we receive a repeat of 25935 the last sequence number */ 25936 req->ignore = 1; 25937 ast_debug(3, "Ignoring SIP message because of retransmit (%s Seqno %u, ours %u)\n", sip_methods[p->method].text, p->icseq, seqno); 25938 } 25939 25940 /* RFC 3261 section 9. "CANCEL has no effect on a request to which a UAS has 25941 * already given a final response." */ 25942 if (!p->pendinginvite && (req->method == SIP_CANCEL)) { 25943 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 25944 return res; 25945 } 25946 25947 if (seqno >= p->icseq) 25948 /* Next should follow monotonically (but not necessarily 25949 incrementally -- thanks again to the genius authors of SIP -- 25950 increasing */ 25951 p->icseq = seqno; 25952 25953 /* Find their tag if we haven't got it */ 25954 if (ast_strlen_zero(p->theirtag)) { 25955 char tag[128]; 25956 25957 gettag(req, "From", tag, sizeof(tag)); 25958 ast_string_field_set(p, theirtag, tag); 25959 } 25960 snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd); 25961 25962 if (sip_cfg.pedanticsipchecking) { 25963 /* If this is a request packet without a from tag, it's not 25964 correct according to RFC 3261 */ 25965 /* Check if this a new request in a new dialog with a totag already attached to it, 25966 RFC 3261 - section 12.2 - and we don't want to mess with recovery */ 25967 if (!p->initreq.headers && req->has_to_tag) { 25968 /* If this is a first request and it got a to-tag, it is not for us */ 25969 if (!req->ignore && req->method == SIP_INVITE) { 25970 /* Just because we think this is a dialog-starting INVITE with a to-tag 25971 * doesn't mean it actually is. It could be a reinvite for an established, but 25972 * unknown dialog. In such a case, we need to change our tag to the 25973 * incoming INVITE's to-tag so that they will recognize the 481 we send and 25974 * so that we will properly match their incoming ACK. 25975 */ 25976 char totag[128]; 25977 gettag(req, "To", totag, sizeof(totag)); 25978 ast_string_field_set(p, tag, totag); 25979 p->pendinginvite = p->icseq; 25980 transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req); 25981 /* Will cease to exist after ACK */ 25982 return res; 25983 } else if (req->method != SIP_ACK) { 25984 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 25985 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 25986 return res; 25987 } 25988 /* Otherwise, this is an ACK. It will always have a to-tag */ 25989 } 25990 } 25991 25992 if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY || p->method == SIP_PUBLISH)) { 25993 transmit_response(p, "400 Bad request", req); 25994 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 25995 return -1; 25996 } 25997 25998 /* Handle various incoming SIP methods in requests */ 25999 switch (p->method) { 26000 case SIP_OPTIONS: 26001 res = handle_request_options(p, req, addr, e); 26002 break; 26003 case SIP_INVITE: 26004 res = handle_request_invite(p, req, debug, seqno, addr, recount, e, nounlock); 26005 break; 26006 case SIP_REFER: 26007 res = handle_request_refer(p, req, debug, seqno, nounlock); 26008 break; 26009 case SIP_CANCEL: 26010 res = handle_request_cancel(p, req); 26011 break; 26012 case SIP_BYE: 26013 res = handle_request_bye(p, req); 26014 break; 26015 case SIP_MESSAGE: 26016 res = handle_request_message(p, req); 26017 break; 26018 case SIP_PUBLISH: 26019 res = handle_request_publish(p, req, addr, seqno, e); 26020 break; 26021 case SIP_SUBSCRIBE: 26022 res = handle_request_subscribe(p, req, addr, seqno, e); 26023 break; 26024 case SIP_REGISTER: 26025 res = handle_request_register(p, req, addr, e); 26026 break; 26027 case SIP_INFO: 26028 if (req->debug) 26029 ast_verbose("Receiving INFO!\n"); 26030 if (!req->ignore) 26031 handle_request_info(p, req); 26032 else /* if ignoring, transmit response */ 26033 transmit_response(p, "200 OK", req); 26034 break; 26035 case SIP_NOTIFY: 26036 res = handle_request_notify(p, req, addr, seqno, e); 26037 break; 26038 case SIP_UPDATE: 26039 res = handle_request_update(p, req); 26040 break; 26041 case SIP_ACK: 26042 /* Make sure we don't ignore this */ 26043 if (seqno == p->pendinginvite) { 26044 p->invitestate = INV_TERMINATED; 26045 p->pendinginvite = 0; 26046 acked = __sip_ack(p, seqno, 1 /* response */, 0); 26047 if (p->owner && find_sdp(req)) { 26048 if (process_sdp(p, req, SDP_T38_NONE)) { 26049 return -1; 26050 } 26051 if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) { 26052 ast_queue_control(p->owner, AST_CONTROL_SRCCHANGE); 26053 } 26054 } 26055 check_pendings(p); 26056 } else if (p->glareinvite == seqno) { 26057 /* handle ack for the 491 pending sent for glareinvite */ 26058 p->glareinvite = 0; 26059 acked = __sip_ack(p, seqno, 1, 0); 26060 } 26061 if (!acked) { 26062 /* Got an ACK that did not match anything. Ignore 26063 * silently and restore previous method */ 26064 p->method = oldmethod; 26065 } 26066 if (!p->lastinvite && ast_strlen_zero(p->randdata)) { 26067 pvt_set_needdestroy(p, "unmatched ACK"); 26068 } 26069 break; 26070 default: 26071 transmit_response_with_allow(p, "501 Method Not Implemented", req, 0); 26072 ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 26073 cmd, ast_sockaddr_stringify(&p->sa)); 26074 /* If this is some new method, and we don't have a call, destroy it now */ 26075 if (!p->initreq.headers) { 26076 pvt_set_needdestroy(p, "unimplemented method"); 26077 } 26078 break; 26079 } 26080 return res; 26081 }
| static int handle_invite_replaces | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| int | debug, | |||
| uint32_t | seqno, | |||
| struct ast_sockaddr * | addr, | |||
| int * | nounlock | |||
| ) | [static] |
Handle the transfer part of INVITE with a replaces: header, meaning a target pickup or an attended transfer. Used only once. XXX 'ignore' is unused.
Definition at line 22756 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), AST_CAUSE_SWITCH_CONGESTION, AST_CEL_ANSWER, AST_CEL_PICKUP, ast_cel_report_event(), ast_channel_lock, ast_channel_masquerade(), ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_debug, ast_do_masquerade(), ast_hangup(), ast_log(), ast_quiet_chan(), ast_set_flag, ast_setstate(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, FALSE, ast_channel::hangupcause, LOG_ERROR, LOG_NOTICE, LOG_WARNING, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), ast_channel::tech_pvt, transmit_response(), transmit_response_reliable(), and transmit_response_with_sdp().
Referenced by handle_request_invite().
22757 { 22758 int earlyreplace = 0; 22759 int oneleggedreplace = 0; /* Call with no bridge, propably IVR or voice message */ 22760 struct ast_channel *c = p->owner; /* Our incoming call */ 22761 struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */ 22762 struct ast_channel *targetcall; /* The bridge to the take-over target */ 22763 22764 /* Check if we're in ring state */ 22765 if (replacecall->_state == AST_STATE_RING) 22766 earlyreplace = 1; 22767 22768 /* Check if we have a bridge */ 22769 if (!(targetcall = ast_bridged_channel(replacecall))) { 22770 /* We have no bridge */ 22771 if (!earlyreplace) { 22772 ast_debug(2, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name); 22773 oneleggedreplace = 1; 22774 } 22775 } 22776 if (targetcall && targetcall->_state == AST_STATE_RINGING) 22777 ast_debug(4, "SIP transfer: Target channel is in ringing state\n"); 22778 22779 if (targetcall) 22780 ast_debug(4, "SIP transfer: Invite Replace incoming channel should bridge to channel %s while hanging up channel %s\n", targetcall->name, replacecall->name); 22781 else 22782 ast_debug(4, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name); 22783 22784 if (req->ignore) { 22785 ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n"); 22786 /* We should answer something here. If we are here, the 22787 call we are replacing exists, so an accepted 22788 can't harm */ 22789 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE, FALSE, FALSE); 22790 /* Do something more clever here */ 22791 if (c) { 22792 *nounlock = 1; 22793 ast_channel_unlock(c); 22794 } 22795 ast_channel_unlock(replacecall); 22796 sip_pvt_unlock(p->refer->refer_call); 22797 return 1; 22798 } 22799 if (!c) { 22800 /* What to do if no channel ??? */ 22801 ast_log(LOG_ERROR, "Unable to create new channel. Invite/replace failed.\n"); 22802 transmit_response_reliable(p, "503 Service Unavailable", req); 22803 append_history(p, "Xfer", "INVITE/Replace Failed. No new channel."); 22804 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22805 ast_channel_unlock(replacecall); 22806 sip_pvt_unlock(p->refer->refer_call); 22807 return 1; 22808 } 22809 append_history(p, "Xfer", "INVITE/Replace received"); 22810 /* We have three channels to play with 22811 channel c: New incoming call 22812 targetcall: Call from PBX to target 22813 p->refer->refer_call: SIP pvt dialog from transferer to pbx. 22814 replacecall: The owner of the previous 22815 We need to masq C into refer_call to connect to 22816 targetcall; 22817 If we are talking to internal audio stream, target call is null. 22818 */ 22819 22820 /* Fake call progress */ 22821 transmit_response(p, "100 Trying", req); 22822 ast_setstate(c, AST_STATE_RING); 22823 22824 /* Masquerade the new call into the referred call to connect to target call 22825 Targetcall is not touched by the masq */ 22826 22827 /* Answer the incoming call and set channel to UP state */ 22828 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE, FALSE, FALSE); 22829 22830 /* Is this a call pickup? */ 22831 if (earlyreplace || oneleggedreplace) { 22832 /* Report pickup event, in this order: PICKUP, CHAN_UP, ANSWER */ 22833 ast_cel_report_event(replacecall, AST_CEL_PICKUP, NULL, NULL, c); 22834 ast_setstate(c, AST_STATE_UP); 22835 ast_cel_report_event(c, AST_CEL_ANSWER, NULL, NULL, NULL); 22836 } else { 22837 ast_setstate(c, AST_STATE_UP); 22838 } 22839 22840 /* Stop music on hold and other generators */ 22841 ast_quiet_chan(replacecall); 22842 ast_quiet_chan(targetcall); 22843 ast_debug(4, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name); 22844 22845 /* Make sure that the masq does not free our PVT for the old call */ 22846 if (! earlyreplace && ! oneleggedreplace ) 22847 ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 22848 22849 /* Prepare the masquerade - if this does not happen, we will be gone */ 22850 if(ast_channel_masquerade(replacecall, c)) 22851 ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n"); 22852 else 22853 ast_debug(4, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name); 22854 22855 /* C should now be in place of replacecall. all channel locks and pvt locks should be removed 22856 * before issuing the masq. Since we are unlocking both the pvt (p) and its owner channel (c) 22857 * it is possible for channel c to be destroyed on us. To prevent this, we must give c a reference 22858 * before any unlocking takes place and remove it only once we are completely done with it */ 22859 ast_channel_ref(c); 22860 ast_channel_unlock(replacecall); 22861 ast_channel_unlock(c); 22862 sip_pvt_unlock(p->refer->refer_call); 22863 sip_pvt_unlock(p); 22864 if (ast_do_masquerade(replacecall)) { 22865 ast_log(LOG_WARNING, "Failed to perform masquerade with INVITE replaces\n"); 22866 } 22867 if (earlyreplace || oneleggedreplace ) { 22868 ast_channel_lock(c); 22869 c->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 22870 ast_channel_unlock(c); 22871 } 22872 22873 /* The call should be down with no ast_channel, so hang it up */ 22874 c->tech_pvt = dialog_unref(c->tech_pvt, "unref dialog c->tech_pvt"); 22875 22876 /* c and c's tech pvt must be unlocked at this point for ast_hangup */ 22877 ast_hangup(c); 22878 /* this indicates to handle_request_do that the owner channel has already been unlocked */ 22879 *nounlock = 1; 22880 /* lock PVT structure again after hangup */ 22881 sip_pvt_lock(p); 22882 ast_channel_unref(c); 22883 return 0; 22884 }
| static int handle_request_bye | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Handle incoming BYE request.
Definition at line 24599 of file chan_sip.c.
References __sip_pretend_ack(), append_history, ARRAY_LEN, ast_async_goto(), ast_bridged_channel(), AST_CAUSE_PROTOCOL_ERROR, ast_channel_lock, ast_channel_trylock, ast_channel_unlock, ast_clear_flag, AST_CONTROL_UNHOLD, ast_debug, ast_log(), AST_MAX_USER_FIELD, ast_queue_control(), ast_queue_hangup(), ast_queue_hangup_with_cause(), ast_rtp_instance_get_quality(), ast_rtp_instance_set_stats_vars(), AST_RTP_INSTANCE_STAT_FIELD_QUALITY, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_JITTER, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_LOSS, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_RTT, ast_sockaddr_stringify(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, check_via(), ast_channel::context, context, copy_request(), get_also_info(), get_header(), LOG_NOTICE, LOG_WARNING, parse_sip_options(), pbx_builtin_setvar_helper(), quality, sip_alreadygone(), sip_cfg, sip_methods, sip_pvt_lock, sip_pvt_unlock, sip_queue_hangup_cause(), sip_scheddestroy_final(), stop_media_flows(), stop_session_timer(), ast_channel::tech, ast_channel::tech_pvt, cfsip_methods::text, transmit_response(), transmit_response_reliable(), and transmit_response_with_unsupported().
Referenced by handle_incoming().
24600 { 24601 struct ast_channel *c=NULL; 24602 int res; 24603 struct ast_channel *bridged_to; 24604 const char *required; 24605 24606 /* If we have an INCOMING invite that we haven't answered, terminate that transaction */ 24607 if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !req->ignore) { 24608 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 24609 } 24610 24611 __sip_pretend_ack(p); 24612 24613 p->invitestate = INV_TERMINATED; 24614 24615 copy_request(&p->initreq, req); 24616 if (sipdebug) 24617 ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid); 24618 check_via(p, req); 24619 sip_alreadygone(p); 24620 24621 /* Get RTCP quality before end of call */ 24622 if (p->do_history || p->owner) { 24623 char quality_buf[AST_MAX_USER_FIELD], *quality; 24624 struct ast_channel *bridge = p->owner ? ast_bridged_channel(p->owner) : NULL; 24625 24626 /* We need to get the lock on bridge because ast_rtp_instance_set_stats_vars will attempt 24627 * to lock the bridge. This may get hairy... 24628 */ 24629 while (bridge && ast_channel_trylock(bridge)) { 24630 ast_channel_unlock(p->owner); 24631 do { 24632 /* Can't use DEADLOCK_AVOIDANCE since p is an ao2 object */ 24633 sip_pvt_unlock(p); 24634 usleep(1); 24635 sip_pvt_lock(p); 24636 } while (p->owner && ast_channel_trylock(p->owner)); 24637 bridge = p->owner ? ast_bridged_channel(p->owner) : NULL; 24638 } 24639 24640 24641 if (p->rtp && (quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) { 24642 if (p->do_history) { 24643 append_history(p, "RTCPaudio", "Quality:%s", quality); 24644 24645 if ((quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_JITTER, quality_buf, sizeof(quality_buf)))) { 24646 append_history(p, "RTCPaudioJitter", "Quality:%s", quality); 24647 } 24648 if ((quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_LOSS, quality_buf, sizeof(quality_buf)))) { 24649 append_history(p, "RTCPaudioLoss", "Quality:%s", quality); 24650 } 24651 if ((quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_RTT, quality_buf, sizeof(quality_buf)))) { 24652 append_history(p, "RTCPaudioRTT", "Quality:%s", quality); 24653 } 24654 } 24655 24656 if (p->owner) { 24657 ast_rtp_instance_set_stats_vars(p->owner, p->rtp); 24658 } 24659 24660 } 24661 24662 if (bridge) { 24663 struct sip_pvt *q = bridge->tech_pvt; 24664 24665 if (IS_SIP_TECH(bridge->tech) && q && q->rtp) { 24666 ast_rtp_instance_set_stats_vars(bridge, q->rtp); 24667 } 24668 ast_channel_unlock(bridge); 24669 } 24670 24671 if (p->vrtp && (quality = ast_rtp_instance_get_quality(p->vrtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) { 24672 if (p->do_history) { 24673 append_history(p, "RTCPvideo", "Quality:%s", quality); 24674 } 24675 if (p->owner) { 24676 pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", quality); 24677 } 24678 } 24679 if (p->trtp && (quality = ast_rtp_instance_get_quality(p->trtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) { 24680 if (p->do_history) { 24681 append_history(p, "RTCPtext", "Quality:%s", quality); 24682 } 24683 if (p->owner) { 24684 pbx_builtin_setvar_helper(p->owner, "RTPTEXTQOS", quality); 24685 } 24686 } 24687 } 24688 24689 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 24690 if (p->stimer) { 24691 stop_session_timer(p); /* Stop Session-Timer */ 24692 } 24693 24694 if (!ast_strlen_zero(get_header(req, "Also"))) { 24695 ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n", 24696 ast_sockaddr_stringify(&p->recv)); 24697 if (ast_strlen_zero(p->context)) 24698 ast_string_field_set(p, context, sip_cfg.default_context); 24699 res = get_also_info(p, req); 24700 if (!res) { 24701 c = p->owner; 24702 if (c) { 24703 bridged_to = ast_bridged_channel(c); 24704 if (bridged_to) { 24705 /* Don't actually hangup here... */ 24706 ast_queue_control(c, AST_CONTROL_UNHOLD); 24707 ast_channel_unlock(c); /* async_goto can do a masquerade, no locks can be held during a masq */ 24708 ast_async_goto(bridged_to, p->context, p->refer->refer_to, 1); 24709 ast_channel_lock(c); 24710 } else 24711 ast_queue_hangup(p->owner); 24712 } 24713 } else { 24714 ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_sockaddr_stringify(&p->recv)); 24715 if (p->owner) 24716 ast_queue_hangup_with_cause(p->owner, AST_CAUSE_PROTOCOL_ERROR); 24717 } 24718 } else if (p->owner) { 24719 sip_queue_hangup_cause(p, 0); 24720 sip_scheddestroy_final(p, DEFAULT_TRANS_TIMEOUT); 24721 ast_debug(3, "Received bye, issuing owner hangup\n"); 24722 } else { 24723 sip_scheddestroy_final(p, DEFAULT_TRANS_TIMEOUT); 24724 ast_debug(3, "Received bye, no owner, selfdestruct soon.\n"); 24725 } 24726 ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 24727 24728 /* Find out what they require */ 24729 required = get_header(req, "Require"); 24730 if (!ast_strlen_zero(required)) { 24731 char unsupported[256] = { 0, }; 24732 parse_sip_options(required, unsupported, ARRAY_LEN(unsupported)); 24733 /* If there are any options required that we do not support, 24734 * then send a 420 with only those unsupported options listed */ 24735 if (!ast_strlen_zero(unsupported)) { 24736 transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, unsupported); 24737 ast_log(LOG_WARNING, "Received SIP BYE with unsupported required extension: required:%s unsupported:%s\n", required, unsupported); 24738 } else { 24739 transmit_response(p, "200 OK", req); 24740 } 24741 } else { 24742 transmit_response(p, "200 OK", req); 24743 } 24744 24745 return 1; 24746 }
| static int handle_request_cancel | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Handle incoming CANCEL request.
Definition at line 24531 of file chan_sip.c.
References __sip_pretend_ack(), ast_debug, ast_free, AST_SCHED_DEL, AST_STATE_UP, ast_str_strlen(), ast_test_flag, check_via(), sip_alreadygone(), sip_queue_hangup_cause(), sip_scheddestroy(), stop_media_flows(), transmit_response(), transmit_response_reliable(), UNLINK, and update_call_counter().
Referenced by handle_incoming().
24532 { 24533 24534 check_via(p, req); 24535 sip_alreadygone(p); 24536 24537 if (p->owner && p->owner->_state == AST_STATE_UP) { 24538 /* This call is up, cancel is ignored, we need a bye */ 24539 transmit_response(p, "200 OK", req); 24540 ast_debug(1, "Got CANCEL on an answered call. Ignoring... \n"); 24541 return 0; 24542 } 24543 24544 /* At this point, we could have cancelled the invite at the same time 24545 as the other side sends a CANCEL. Our final reply with error code 24546 might not have been received by the other side before the CANCEL 24547 was sent, so let's just give up retransmissions and waiting for 24548 ACK on our error code. The call is hanging up any way. */ 24549 if (p->invitestate == INV_TERMINATED || p->invitestate == INV_COMPLETED) { 24550 __sip_pretend_ack(p); 24551 } 24552 if (p->invitestate != INV_TERMINATED) 24553 p->invitestate = INV_CANCELLED; 24554 24555 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 24556 update_call_counter(p, DEC_CALL_LIMIT); 24557 24558 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 24559 if (p->owner) { 24560 sip_queue_hangup_cause(p, 0); 24561 } else { 24562 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 24563 } 24564 if (ast_str_strlen(p->initreq.data) > 0) { 24565 struct sip_pkt *pkt, *prev_pkt; 24566 /* If the CANCEL we are receiving is a retransmission, and we already have scheduled 24567 * a reliable 487, then we don't want to schedule another one on top of the previous 24568 * one. 24569 * 24570 * As odd as this may sound, we can't rely on the previously-transmitted "reliable" 24571 * response in this situation. What if we've sent all of our reliable responses 24572 * already and now all of a sudden, we get this second CANCEL? 24573 * 24574 * The only way to do this correctly is to cancel our previously-scheduled reliably- 24575 * transmitted response and send a new one in its place. 24576 */ 24577 for (pkt = p->packets, prev_pkt = NULL; pkt; prev_pkt = pkt, pkt = pkt->next) { 24578 if (pkt->seqno == p->lastinvite && pkt->response_code == 487) { 24579 AST_SCHED_DEL(sched, pkt->retransid); 24580 UNLINK(pkt, p->packets, prev_pkt); 24581 dialog_unref(pkt->owner, "unref packet->owner from dialog"); 24582 if (pkt->data) { 24583 ast_free(pkt->data); 24584 } 24585 ast_free(pkt); 24586 break; 24587 } 24588 } 24589 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 24590 transmit_response(p, "200 OK", req); 24591 return 1; 24592 } else { 24593 transmit_response(p, "481 Call Leg Does Not Exist", req); 24594 return 0; 24595 } 24596 }
| static int handle_request_do | ( | struct sip_request * | req, | |
| struct ast_sockaddr * | addr | |||
| ) | [static] |
Handle incoming SIP message - request or response.
This is used for all transports (udp, tcp and tcp/tls)
Definition at line 26133 of file chan_sip.c.
References ao2_t_ref, append_history, ast_channel_unlock, ast_channel_unref, ast_debug, ast_mutex_lock, ast_mutex_unlock, ast_sockaddr_copy(), ast_sockaddr_stringify(), ast_str_buffer(), ast_str_reset(), ast_str_strlen(), ast_update_use_count(), ast_verbose, copy_socket_data(), find_call(), find_sip_method(), get_header(), get_transport(), handle_incoming(), lws2sws(), parse_request(), sip_cfg, sip_debug_test_addr(), sip_pvt_lock_full(), and sip_pvt_unlock.
Referenced by _sip_tcp_helper_thread(), and sipsock_read().
26134 { 26135 struct sip_pvt *p; 26136 struct ast_channel *owner_chan_ref = NULL; 26137 int recount = 0; 26138 int nounlock = 0; 26139 26140 if (sip_debug_test_addr(addr)) /* Set the debug flag early on packet level */ 26141 req->debug = 1; 26142 if (sip_cfg.pedanticsipchecking) 26143 lws2sws(req->data); /* Fix multiline headers */ 26144 if (req->debug) { 26145 ast_verbose("\n<--- SIP read from %s:%s --->\n%s\n<------------->\n", 26146 get_transport(req->socket.type), ast_sockaddr_stringify(addr), ast_str_buffer(req->data)); 26147 } 26148 26149 if (parse_request(req) == -1) { /* Bad packet, can't parse */ 26150 ast_str_reset(req->data); /* nulling this out is NOT a good idea here. */ 26151 return 1; 26152 } 26153 req->method = find_sip_method(REQ_OFFSET_TO_STR(req, rlPart1)); 26154 26155 if (req->debug) 26156 ast_verbose("--- (%d headers %d lines)%s ---\n", req->headers, req->lines, (req->headers + req->lines == 0) ? " Nat keepalive" : ""); 26157 26158 if (req->headers < 2) { /* Must have at least two headers */ 26159 ast_str_reset(req->data); /* nulling this out is NOT a good idea here. */ 26160 return 1; 26161 } 26162 26163 /* Process request, with netlock held, and with usual deadlock avoidance */ 26164 ast_mutex_lock(&netlock); 26165 26166 /* Find the active SIP dialog or create a new one */ 26167 p = find_call(req, addr, req->method); /* returns p with a reference only. _NOT_ locked*/ 26168 if (p == NULL) { 26169 ast_debug(1, "Invalid SIP message - rejected , no callid, len %zu\n", ast_str_strlen(req->data)); 26170 ast_mutex_unlock(&netlock); 26171 return 1; 26172 } 26173 26174 /* Lock both the pvt and the owner if owner is present. This will 26175 * not fail. */ 26176 owner_chan_ref = sip_pvt_lock_full(p); 26177 26178 copy_socket_data(&p->socket, &req->socket); 26179 26180 ast_sockaddr_copy(&p->recv, addr); 26181 26182 /* if we have an owner, then this request has been authenticated */ 26183 if (p->owner) { 26184 req->authenticated = 1; 26185 } 26186 26187 if (p->do_history) /* This is a request or response, note what it was for */ 26188 append_history(p, "Rx", "%s / %s / %s", ast_str_buffer(req->data), get_header(req, "CSeq"), REQ_OFFSET_TO_STR(req, rlPart2)); 26189 26190 if (handle_incoming(p, req, addr, &recount, &nounlock) == -1) { 26191 /* Request failed */ 26192 ast_debug(1, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 26193 } 26194 26195 if (recount) { 26196 ast_update_use_count(); 26197 } 26198 26199 if (p->owner && !nounlock) { 26200 ast_channel_unlock(p->owner); 26201 } 26202 if (owner_chan_ref) { 26203 ast_channel_unref(owner_chan_ref); 26204 } 26205 sip_pvt_unlock(p); 26206 ao2_t_ref(p, -1, "throw away dialog ptr from find_call at end of routine"); /* p is gone after the return */ 26207 ast_mutex_unlock(&netlock); 26208 26209 return 1; 26210 }
| static void handle_request_info | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Receive SIP INFO Message.
Definition at line 19438 of file chan_sip.c.
References ast_bridged_channel(), ast_cdr_setuserfield(), AST_CONTROL_FLASH, AST_CONTROL_VIDUPDATE, ast_copy_string(), ast_debug, ast_find_call_feature(), AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_log(), AST_LOG_WARNING, ast_queue_control(), ast_queue_frame(), ast_rdlock_call_features(), ast_strlen_zero(), ast_test_flag, ast_unlock_call_features(), ast_verbose, ast_channel::cdr, ast_call_feature::exten, f, get_body(), get_header(), get_msg_text(), ast_frame_subclass::integer, ast_frame::len, LOG_WARNING, sip_scheddestroy(), ast_frame::subclass, and transmit_response().
Referenced by handle_incoming().
19439 { 19440 char buf[1024] = ""; 19441 unsigned int event; 19442 const char *c = get_header(req, "Content-Type"); 19443 19444 /* Need to check the media/type */ 19445 if (!strcasecmp(c, "application/dtmf-relay") || 19446 !strcasecmp(c, "application/vnd.nortelnetworks.digits") || 19447 !strcasecmp(c, "application/dtmf")) { 19448 unsigned int duration = 0; 19449 19450 if (!p->owner) { /* not a PBX call */ 19451 transmit_response(p, "481 Call leg/transaction does not exist", req); 19452 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 19453 return; 19454 } 19455 19456 /* If dtmf-relay or vnd.nortelnetworks.digits, parse the signal and duration; 19457 * otherwise use the body as the signal */ 19458 if (strcasecmp(c, "application/dtmf")) { 19459 const char *msg_body; 19460 19461 if ( ast_strlen_zero(msg_body = get_body(req, "Signal", '=')) 19462 && ast_strlen_zero(msg_body = get_body(req, "d", '='))) { 19463 ast_log(LOG_WARNING, "Unable to retrieve DTMF signal for INFO message on " 19464 "call %s\n", p->callid); 19465 transmit_response(p, "200 OK", req); 19466 return; 19467 } 19468 ast_copy_string(buf, msg_body, sizeof(buf)); 19469 19470 if (!ast_strlen_zero((msg_body = get_body(req, "Duration", '=')))) { 19471 sscanf(msg_body, "%30u", &duration); 19472 } 19473 } else { 19474 /* Type is application/dtmf, simply use what's in the message body */ 19475 get_msg_text(buf, sizeof(buf), req); 19476 } 19477 19478 /* An empty message body requires us to send a 200 OK */ 19479 if (ast_strlen_zero(buf)) { 19480 transmit_response(p, "200 OK", req); 19481 return; 19482 } 19483 19484 if (!duration) { 19485 duration = 100; /* 100 ms */ 19486 } 19487 19488 if (buf[0] == '*') { 19489 event = 10; 19490 } else if (buf[0] == '#') { 19491 event = 11; 19492 } else if (buf[0] == '!') { 19493 event = 16; 19494 } else if ('A' <= buf[0] && buf[0] <= 'D') { 19495 event = 12 + buf[0] - 'A'; 19496 } else if ('a' <= buf[0] && buf[0] <= 'd') { 19497 event = 12 + buf[0] - 'a'; 19498 } else if ((sscanf(buf, "%30u", &event) != 1) || event > 16) { 19499 ast_log(AST_LOG_WARNING, "Unable to convert DTMF event signal code to a valid " 19500 "value for INFO message on call %s\n", p->callid); 19501 transmit_response(p, "200 OK", req); 19502 return; 19503 } 19504 19505 if (event == 16) { 19506 /* send a FLASH event */ 19507 struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_FLASH, } }; 19508 ast_queue_frame(p->owner, &f); 19509 if (sipdebug) { 19510 ast_verbose("* DTMF-relay event received: FLASH\n"); 19511 } 19512 } else { 19513 /* send a DTMF event */ 19514 struct ast_frame f = { AST_FRAME_DTMF, }; 19515 if (event < 10) { 19516 f.subclass.integer = '0' + event; 19517 } else if (event == 10) { 19518 f.subclass.integer = '*'; 19519 } else if (event == 11) { 19520 f.subclass.integer = '#'; 19521 } else { 19522 f.subclass.integer = 'A' + (event - 12); 19523 } 19524 f.len = duration; 19525 ast_queue_frame(p->owner, &f); 19526 if (sipdebug) { 19527 ast_verbose("* DTMF-relay event received: %c\n", (int) f.subclass.integer); 19528 } 19529 } 19530 transmit_response(p, "200 OK", req); 19531 return; 19532 } else if (!strcasecmp(c, "application/media_control+xml")) { 19533 /* Eh, we'll just assume it's a fast picture update for now */ 19534 if (p->owner) 19535 ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE); 19536 transmit_response(p, "200 OK", req); 19537 return; 19538 } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) { 19539 /* Client code (from SNOM phone) */ 19540 if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) { 19541 if (p->owner && p->owner->cdr) 19542 ast_cdr_setuserfield(p->owner, c); 19543 if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr) 19544 ast_cdr_setuserfield(ast_bridged_channel(p->owner), c); 19545 transmit_response(p, "200 OK", req); 19546 } else { 19547 transmit_response(p, "403 Forbidden", req); 19548 } 19549 return; 19550 } else if (!ast_strlen_zero(c = get_header(req, "Record"))) { 19551 /* INFO messages generated by some phones to start/stop recording 19552 on phone calls. 19553 OEJ: I think this should be something that is enabled/disabled 19554 per device. I don't want incoming callers to record calls in my 19555 pbx. 19556 */ 19557 19558 struct ast_call_feature *feat; 19559 int j; 19560 struct ast_frame f = { AST_FRAME_DTMF, }; 19561 19562 if (!p->owner) { /* not a PBX call */ 19563 transmit_response(p, "481 Call leg/transaction does not exist", req); 19564 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 19565 return; 19566 } 19567 19568 /* first, get the feature string, if it exists */ 19569 ast_rdlock_call_features(); 19570 feat = ast_find_call_feature("automon"); 19571 if (!feat || ast_strlen_zero(feat->exten)) { 19572 ast_log(LOG_WARNING, "Recording requested, but no One Touch Monitor registered. (See features.conf)\n"); 19573 /* 403 means that we don't support this feature, so don't request it again */ 19574 transmit_response(p, "403 Forbidden", req); 19575 ast_unlock_call_features(); 19576 return; 19577 } 19578 /* Send the feature code to the PBX as DTMF, just like the handset had sent it */ 19579 f.len = 100; 19580 for (j=0; j < strlen(feat->exten); j++) { 19581 f.subclass.integer = feat->exten[j]; 19582 ast_queue_frame(p->owner, &f); 19583 if (sipdebug) 19584 ast_verbose("* DTMF-relay event faked: %c\n", f.subclass.integer); 19585 } 19586 ast_unlock_call_features(); 19587 19588 ast_debug(1, "Got a Request to Record the channel, state %s\n", c); 19589 transmit_response(p, "200 OK", req); 19590 return; 19591 } else if (ast_strlen_zero(c = get_header(req, "Content-Length")) || !strcasecmp(c, "0")) { 19592 /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */ 19593 transmit_response(p, "200 OK", req); 19594 return; 19595 } 19596 19597 /* Other type of INFO message, not really understood by Asterisk */ 19598 /* if (get_msg_text(buf, sizeof(buf), req)) { */ 19599 19600 ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf); 19601 transmit_response(p, "415 Unsupported media type", req); 19602 return; 19603 }
| static int handle_request_invite | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| int | debug, | |||
| uint32_t | seqno, | |||
| struct ast_sockaddr * | addr, | |||
| int * | recount, | |||
| const char * | e, | |||
| int * | nounlock | |||
| ) | [static] |
Handle incoming INVITE request.
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.
Definition at line 23122 of file chan_sip.c.
References __sip_ack(), ast_channel::_state, append_history, ARRAY_LEN, AST_CAUSE_FAILURE, ast_cc_agent_set_interfaces_chanvar(), ast_channel_queue_connected_line_update(), ast_channel_set_redirecting(), ast_channel_unlock, ast_clear_flag, AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, AST_CONTROL_BUSY, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, ast_copy_string(), ast_debug, ast_hangup(), ast_log(), AST_MAX_CONTEXT, AST_MAX_EXTENSION, ast_null_frame, ast_party_connected_line_init(), ast_party_redirecting_free(), ast_party_redirecting_init(), AST_PBX_CALL_LIMIT, AST_PBX_FAILED, ast_pbx_start(), AST_PBX_SUCCESS, ast_pickup_ext(), ast_queue_control(), ast_queue_frame(), ast_rtp_instance_set_alt_remote_address(), ast_rtp_instance_set_prop(), AST_RTP_PROPERTY_DTMF, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_sched_add(), AST_SCHED_DEL_UNREF, ast_set_flag, ast_setstate(), ast_setup_cc_recall_datastore(), ast_skip_blanks(), ast_sockaddr_stringify(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_verbose, build_contact(), build_route(), change_hold_state(), change_redirecting_information(), check_user_full(), check_via(), connected, context, copy_request(), do_magic_pickup(), ast_channel::exten, exten, extract_uri(), FALSE, find_sdp(), get_destination(), get_header(), get_ip_and_port_from_sdp(), get_rpid(), get_sip_pvt_byid_locked(), handle_invite_replaces(), handle_request_invite_st(), ast_channel::hangupcause, ast_party_connected_line::id, ast_set_party_connected_line::id, LOG_NOTICE, LOG_WARNING, make_our_tag(), ast_party_id::name, ast_set_party_id::name, ast_party_id::number, ast_set_party_id::number, parse_ok_contact(), parse_sip_options(), ast_party_name::presentation, ast_party_number::presentation, process_sdp(), ref_peer(), restart_session_timer(), S_OR, set_pvt_allowed_methods(), sip_alreadygone(), sip_cancel_destroy(), sip_cfg, sip_methods, sip_new(), sip_pickup(), sip_pvt_lock, sip_pvt_unlock, sip_refer_allocate(), sip_scheddestroy(), sip_t38_abort(), sip_uri_cmp(), ast_party_connected_line::source, ast_party_name::str, ast_party_number::str, ast_party_id::tag, cfsip_methods::text, transmit_provisional_response(), transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), transmit_response_with_t38_sdp(), transmit_response_with_unsupported(), TRUE, unref_peer(), update_call_counter(), update_redirecting(), ast_party_name::valid, and ast_party_number::valid.
Referenced by handle_incoming().
23123 { 23124 int res = 1; 23125 int gotdest; 23126 const char *p_replaces; 23127 char *replace_id = NULL; 23128 int refer_locked = 0; 23129 const char *required; 23130 unsigned int required_profile = 0; 23131 struct ast_channel *c = NULL; /* New channel */ 23132 struct sip_peer *authpeer = NULL; /* Matching Peer */ 23133 int reinvite = 0; 23134 struct ast_party_redirecting redirecting; 23135 struct ast_set_party_redirecting update_redirecting; 23136 23137 struct { 23138 char exten[AST_MAX_EXTENSION]; 23139 char context[AST_MAX_CONTEXT]; 23140 } pickup = { 23141 .exten = "", 23142 }; 23143 23144 /* Find out what they support */ 23145 if (!p->sipoptions) { 23146 const char *supported = get_header(req, "Supported"); 23147 if (!ast_strlen_zero(supported)) { 23148 p->sipoptions = parse_sip_options(supported, NULL, 0); 23149 } 23150 } 23151 23152 /* Find out what they require */ 23153 required = get_header(req, "Require"); 23154 if (!ast_strlen_zero(required)) { 23155 char unsupported[256] = { 0, }; 23156 required_profile = parse_sip_options(required, unsupported, ARRAY_LEN(unsupported)); 23157 23158 /* If there are any options required that we do not support, 23159 * then send a 420 with only those unsupported options listed */ 23160 if (!ast_strlen_zero(unsupported)) { 23161 transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, unsupported); 23162 ast_log(LOG_WARNING, "Received SIP INVITE with unsupported required extension: required:%s unsupported:%s\n", required, unsupported); 23163 p->invitestate = INV_COMPLETED; 23164 if (!p->lastinvite) 23165 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23166 res = -1; 23167 goto request_invite_cleanup; 23168 } 23169 } 23170 23171 /* The option tags may be present in Supported: or Require: headers. 23172 Include the Require: option tags for further processing as well */ 23173 p->sipoptions |= required_profile; 23174 p->reqsipoptions = required_profile; 23175 23176 /* Check if this is a loop */ 23177 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->invitestate != INV_TERMINATED && p->invitestate != INV_CONFIRMED) && p->owner->_state != AST_STATE_UP) { 23178 /* This is a call to ourself. Send ourselves an error code and stop 23179 processing immediately, as SIP really has no good mechanism for 23180 being able to call yourself */ 23181 /* If pedantic is on, we need to check the tags. If they're different, this is 23182 in fact a forked call through a SIP proxy somewhere. */ 23183 int different; 23184 const char *initial_rlPart2 = REQ_OFFSET_TO_STR(&p->initreq, rlPart2); 23185 const char *this_rlPart2 = REQ_OFFSET_TO_STR(req, rlPart2); 23186 if (sip_cfg.pedanticsipchecking) 23187 different = sip_uri_cmp(initial_rlPart2, this_rlPart2); 23188 else 23189 different = strcmp(initial_rlPart2, this_rlPart2); 23190 if (!different) { 23191 transmit_response(p, "482 Loop Detected", req); 23192 p->invitestate = INV_COMPLETED; 23193 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23194 res = 0; 23195 goto request_invite_cleanup; 23196 } else { 23197 /*! This is a spiral. What we need to do is to just change the outgoing INVITE 23198 * so that it now routes to the new Request URI. Since we created the INVITE ourselves 23199 * that should be all we need to do. 23200 * 23201 * \todo XXX This needs to be reviewed. YOu don't change the request URI really, you route the packet 23202 * correctly instead... 23203 */ 23204 char *uri = ast_strdupa(this_rlPart2); 23205 char *at = strchr(uri, '@'); 23206 char *peerorhost; 23207 ast_debug(2, "Potential spiral detected. Original RURI was %s, new RURI is %s\n", initial_rlPart2, this_rlPart2); 23208 transmit_response(p, "100 Trying", req); 23209 if (at) { 23210 *at = '\0'; 23211 } 23212 /* Parse out "sip:" */ 23213 if ((peerorhost = strchr(uri, ':'))) { 23214 *peerorhost++ = '\0'; 23215 } 23216 ast_string_field_set(p, theirtag, NULL); 23217 /* Treat this as if there were a call forward instead... 23218 */ 23219 ast_string_field_set(p->owner, call_forward, peerorhost); 23220 ast_queue_control(p->owner, AST_CONTROL_BUSY); 23221 res = 0; 23222 goto request_invite_cleanup; 23223 } 23224 } 23225 23226 if (!req->ignore && p->pendinginvite) { 23227 if (!ast_test_flag(&p->flags[0], SIP_OUTGOING) && (p->invitestate == INV_COMPLETED || p->invitestate == INV_TERMINATED)) { 23228 /* What do these circumstances mean? We have received an INVITE for an "incoming" dialog for which we 23229 * have sent a final response. We have not yet received an ACK, though (which is why p->pendinginvite is non-zero). 23230 * We also know that the INVITE is not a retransmission, because otherwise the "ignore" flag would be set. 23231 * This means that either we are receiving a reinvite for a terminated dialog, or we are receiving an INVITE with 23232 * credentials based on one we challenged earlier. 23233 * 23234 * The action to take in either case is to treat the INVITE as though it contains an implicit ACK for the previous 23235 * transaction. Calling __sip_ack will take care of this by clearing the p->pendinginvite and removing the response 23236 * from the previous transaction from the list of outstanding packets. 23237 */ 23238 __sip_ack(p, p->pendinginvite, 1, 0); 23239 } else { 23240 /* We already have a pending invite. Sorry. You are on hold. */ 23241 p->glareinvite = seqno; 23242 if (p->rtp && find_sdp(req)) { 23243 struct ast_sockaddr addr; 23244 if (get_ip_and_port_from_sdp(req, SDP_AUDIO, &addr)) { 23245 ast_log(LOG_WARNING, "Failed to set an alternate media source on glared reinvite. Audio may not work properly on this call.\n"); 23246 } else { 23247 ast_rtp_instance_set_alt_remote_address(p->rtp, &addr); 23248 } 23249 if (p->vrtp) { 23250 if (get_ip_and_port_from_sdp(req, SDP_VIDEO, &addr)) { 23251 ast_log(LOG_WARNING, "Failed to set an alternate media source on glared reinvite. Video may not work properly on this call.\n"); 23252 } else { 23253 ast_rtp_instance_set_alt_remote_address(p->vrtp, &addr); 23254 } 23255 } 23256 } 23257 transmit_response_reliable(p, "491 Request Pending", req); 23258 check_via(p, req); 23259 ast_debug(1, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid); 23260 /* Don't destroy dialog here */ 23261 res = 0; 23262 goto request_invite_cleanup; 23263 } 23264 } 23265 23266 p_replaces = get_header(req, "Replaces"); 23267 if (!ast_strlen_zero(p_replaces)) { 23268 /* We have a replaces header */ 23269 char *ptr; 23270 char *fromtag = NULL; 23271 char *totag = NULL; 23272 char *start, *to; 23273 int error = 0; 23274 23275 if (p->owner) { 23276 ast_debug(3, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid); 23277 transmit_response_reliable(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 23278 check_via(p, req); 23279 copy_request(&p->initreq, req); 23280 /* Do not destroy existing call */ 23281 res = -1; 23282 goto request_invite_cleanup; 23283 } 23284 23285 if (sipdebug) 23286 ast_debug(3, "INVITE part of call transfer. Replaces [%s]\n", p_replaces); 23287 /* Create a buffer we can manipulate */ 23288 replace_id = ast_strdupa(p_replaces); 23289 ast_uri_decode(replace_id); 23290 23291 if (!p->refer && !sip_refer_allocate(p)) { 23292 transmit_response_reliable(p, "500 Server Internal Error", req); 23293 append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory."); 23294 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23295 p->invitestate = INV_COMPLETED; 23296 check_via(p, req); 23297 copy_request(&p->initreq, req); 23298 res = -1; 23299 goto request_invite_cleanup; 23300 } 23301 23302 /* Todo: (When we find phones that support this) 23303 if the replaces header contains ";early-only" 23304 we can only replace the call in early 23305 stage, not after it's up. 23306 23307 If it's not in early mode, 486 Busy. 23308 */ 23309 23310 /* Skip leading whitespace */ 23311 replace_id = ast_skip_blanks(replace_id); 23312 23313 start = replace_id; 23314 while ( (ptr = strsep(&start, ";")) ) { 23315 ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */ 23316 if ( (to = strcasestr(ptr, "to-tag=") ) ) 23317 totag = to + 7; /* skip the keyword */ 23318 else if ( (to = strcasestr(ptr, "from-tag=") ) ) { 23319 fromtag = to + 9; /* skip the keyword */ 23320 fromtag = strsep(&fromtag, "&"); /* trim what ? */ 23321 } 23322 } 23323 23324 if (sipdebug) 23325 ast_debug(4, "Invite/replaces: Will use Replace-Call-ID : %s Fromtag: %s Totag: %s\n", 23326 replace_id, 23327 fromtag ? fromtag : "<no from tag>", 23328 totag ? totag : "<no to tag>"); 23329 23330 /* Try to find call that we are replacing. 23331 If we have a Replaces header, we need to cancel that call if we succeed with this call. 23332 First we cheat a little and look for a magic call-id from phones that support 23333 dialog-info+xml so we can do technology independent pickup... */ 23334 if (strncmp(replace_id, "pickup-", 7) == 0) { 23335 struct sip_pvt *subscription = NULL; 23336 replace_id += 7; /* Worst case we are looking at \0 */ 23337 23338 if ((subscription = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) { 23339 ast_log(LOG_NOTICE, "Unable to find subscription with call-id: %s\n", replace_id); 23340 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replaces)", req); 23341 error = 1; 23342 } else { 23343 ast_log(LOG_NOTICE, "Trying to pick up %s@%s\n", subscription->exten, subscription->context); 23344 ast_copy_string(pickup.exten, subscription->exten, sizeof(pickup.exten)); 23345 ast_copy_string(pickup.context, subscription->context, sizeof(pickup.context)); 23346 sip_pvt_unlock(subscription); 23347 if (subscription->owner) { 23348 ast_channel_unlock(subscription->owner); 23349 } 23350 subscription = dialog_unref(subscription, "unref dialog subscription"); 23351 } 23352 } 23353 23354 /* This locks both refer_call pvt and refer_call pvt's owner!!!*/ 23355 if (!error && ast_strlen_zero(pickup.exten) && (p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) { 23356 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id); 23357 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replaces)", req); 23358 error = 1; 23359 } else { 23360 refer_locked = 1; 23361 } 23362 23363 /* The matched call is the call from the transferer to Asterisk . 23364 We want to bridge the bridged part of the call to the 23365 incoming invite, thus taking over the refered call */ 23366 23367 if (p->refer->refer_call == p) { 23368 ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid); 23369 transmit_response_reliable(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 23370 error = 1; 23371 } 23372 23373 if (!error && ast_strlen_zero(pickup.exten) && !p->refer->refer_call->owner) { 23374 /* Oops, someting wrong anyway, no owner, no call */ 23375 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id); 23376 /* Check for better return code */ 23377 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replace)", req); 23378 error = 1; 23379 } 23380 23381 if (!error && ast_strlen_zero(pickup.exten) && p->refer->refer_call->owner->_state != AST_STATE_RINGING && p->refer->refer_call->owner->_state != AST_STATE_RING && p->refer->refer_call->owner->_state != AST_STATE_UP) { 23382 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id); 23383 transmit_response_reliable(p, "603 Declined (Replaces)", req); 23384 error = 1; 23385 } 23386 23387 if (error) { /* Give up this dialog */ 23388 append_history(p, "Xfer", "INVITE/Replace Failed."); 23389 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23390 sip_pvt_unlock(p); 23391 if (p->refer->refer_call) { 23392 sip_pvt_unlock(p->refer->refer_call); 23393 if (p->refer->refer_call->owner) { 23394 ast_channel_unlock(p->refer->refer_call->owner); 23395 } 23396 p->refer->refer_call = dialog_unref(p->refer->refer_call, "unref dialog p->refer->refer_call"); 23397 } 23398 refer_locked = 0; 23399 p->invitestate = INV_COMPLETED; 23400 check_via(p, req); 23401 copy_request(&p->initreq, req); 23402 res = -1; 23403 goto request_invite_cleanup; 23404 } 23405 } 23406 23407 /* Check if this is an INVITE that sets up a new dialog or 23408 a re-invite in an existing dialog */ 23409 23410 if (!req->ignore) { 23411 int newcall = (p->initreq.headers ? TRUE : FALSE); 23412 23413 if (sip_cancel_destroy(p)) 23414 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 23415 /* This also counts as a pending invite */ 23416 p->pendinginvite = seqno; 23417 check_via(p, req); 23418 23419 copy_request(&p->initreq, req); /* Save this INVITE as the transaction basis */ 23420 if (sipdebug) 23421 ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid); 23422 if (!p->owner) { /* Not a re-invite */ 23423 if (debug) 23424 ast_verbose("Using INVITE request as basis request - %s\n", p->callid); 23425 if (newcall) 23426 append_history(p, "Invite", "New call: %s", p->callid); 23427 parse_ok_contact(p, req); 23428 } else { /* Re-invite on existing call */ 23429 ast_clear_flag(&p->flags[0], SIP_OUTGOING); /* This is now an inbound dialog */ 23430 if (get_rpid(p, req)) { 23431 struct ast_party_connected_line connected; 23432 struct ast_set_party_connected_line update_connected; 23433 23434 ast_party_connected_line_init(&connected); 23435 memset(&update_connected, 0, sizeof(update_connected)); 23436 23437 update_connected.id.number = 1; 23438 connected.id.number.valid = 1; 23439 connected.id.number.str = (char *) p->cid_num; 23440 connected.id.number.presentation = p->callingpres; 23441 23442 update_connected.id.name = 1; 23443 connected.id.name.valid = 1; 23444 connected.id.name.str = (char *) p->cid_name; 23445 connected.id.name.presentation = p->callingpres; 23446 23447 connected.id.tag = (char *) p->cid_tag; 23448 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER; 23449 ast_channel_queue_connected_line_update(p->owner, &connected, 23450 &update_connected); 23451 } 23452 /* Handle SDP here if we already have an owner */ 23453 if (find_sdp(req)) { 23454 if (process_sdp(p, req, SDP_T38_INITIATE)) { 23455 if (!ast_strlen_zero(get_header(req, "Content-Encoding"))) { 23456 /* Asterisk does not yet support any Content-Encoding methods. Always 23457 * attempt to process the sdp, but return a 415 if a Content-Encoding header 23458 * was present after processing failed. */ 23459 transmit_response_reliable(p, "415 Unsupported Media type", req); 23460 } else { 23461 transmit_response_reliable(p, "488 Not acceptable here", req); 23462 } 23463 if (!p->lastinvite) 23464 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23465 res = -1; 23466 goto request_invite_cleanup; 23467 } 23468 ast_queue_control(p->owner, AST_CONTROL_SRCUPDATE); 23469 } else { 23470 p->jointcapability = p->capability; 23471 ast_debug(1, "Hm.... No sdp for the moment\n"); 23472 /* Some devices signal they want to be put off hold by sending a re-invite 23473 *without* an SDP, which is supposed to mean "Go back to your state" 23474 and since they put os on remote hold, we go back to off hold */ 23475 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 23476 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 23477 /* Activate a re-invite */ 23478 ast_queue_frame(p->owner, &ast_null_frame); 23479 change_hold_state(p, req, FALSE, 0); 23480 } 23481 } 23482 if (p->do_history) /* This is a response, note what it was for */ 23483 append_history(p, "ReInv", "Re-invite received"); 23484 } 23485 } else if (debug) 23486 ast_verbose("Ignoring this INVITE request\n"); 23487 23488 if (!p->lastinvite && !req->ignore && !p->owner) { 23489 /* This is a new invite */ 23490 /* Handle authentication if this is our first invite */ 23491 int cc_recall_core_id = -1; 23492 set_pvt_allowed_methods(p, req); 23493 res = check_user_full(p, req, SIP_INVITE, e, XMIT_RELIABLE, addr, &authpeer); 23494 if (res == AUTH_CHALLENGE_SENT) { 23495 p->invitestate = INV_COMPLETED; /* Needs to restart in another INVITE transaction */ 23496 res = 0; 23497 goto request_invite_cleanup; 23498 } 23499 if (res < 0) { /* Something failed in authentication */ 23500 ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From")); 23501 transmit_response_reliable(p, "403 Forbidden", req); 23502 p->invitestate = INV_COMPLETED; 23503 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23504 res = 0; 23505 goto request_invite_cleanup; 23506 } 23507 23508 /* Successful authentication and peer matching so record the peer related to this pvt (for easy access to peer settings) */ 23509 if (p->relatedpeer) { 23510 p->relatedpeer = unref_peer(p->relatedpeer,"unsetting the relatedpeer field in the dialog, before it is set to something else."); 23511 } 23512 if (authpeer) { 23513 p->relatedpeer = ref_peer(authpeer, "setting dialog's relatedpeer pointer"); 23514 } 23515 23516 req->authenticated = 1; 23517 23518 /* We have a successful authentication, process the SDP portion if there is one */ 23519 if (find_sdp(req)) { 23520 if (process_sdp(p, req, SDP_T38_INITIATE)) { 23521 /* Asterisk does not yet support any Content-Encoding methods. Always 23522 * attempt to process the sdp, but return a 415 if a Content-Encoding header 23523 * was present after processing fails. */ 23524 if (!ast_strlen_zero(get_header(req, "Content-Encoding"))) { 23525 transmit_response_reliable(p, "415 Unsupported Media type", req); 23526 } else { 23527 /* Unacceptable codecs */ 23528 transmit_response_reliable(p, "488 Not acceptable here", req); 23529 } 23530 p->invitestate = INV_COMPLETED; 23531 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23532 ast_debug(1, "No compatible codecs for this SIP call.\n"); 23533 res = -1; 23534 goto request_invite_cleanup; 23535 } 23536 } else { /* No SDP in invite, call control session */ 23537 p->jointcapability = p->capability; 23538 ast_debug(2, "No SDP in Invite, third party call control\n"); 23539 } 23540 23541 /* Initialize the context if it hasn't been already */ 23542 if (ast_strlen_zero(p->context)) 23543 ast_string_field_set(p, context, sip_cfg.default_context); 23544 23545 23546 /* Check number of concurrent calls -vs- incoming limit HERE */ 23547 ast_debug(1, "Checking SIP call limits for device %s\n", p->username); 23548 if ((res = update_call_counter(p, INC_CALL_LIMIT))) { 23549 if (res < 0) { 23550 ast_log(LOG_NOTICE, "Failed to place call for device %s, too many calls\n", p->username); 23551 transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req); 23552 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23553 p->invitestate = INV_COMPLETED; 23554 } 23555 res = 0; 23556 goto request_invite_cleanup; 23557 } 23558 gotdest = get_destination(p, NULL, &cc_recall_core_id); /* Get destination right away */ 23559 extract_uri(p, req); /* Get the Contact URI */ 23560 build_contact(p); /* Build our contact header */ 23561 23562 if (p->rtp) { 23563 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 23564 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 23565 } 23566 23567 if (!replace_id && (gotdest != SIP_GET_DEST_EXTEN_FOUND)) { /* No matching extension found */ 23568 switch(gotdest) { 23569 case SIP_GET_DEST_INVALID_URI: 23570 transmit_response_reliable(p, "416 Unsupported URI scheme", req); 23571 break; 23572 case SIP_GET_DEST_EXTEN_MATCHMORE: 23573 if (ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP) 23574 == SIP_PAGE2_ALLOWOVERLAP_YES) { 23575 transmit_response_reliable(p, "484 Address Incomplete", req); 23576 break; 23577 } 23578 /* 23579 * XXX We would have to implement collecting more digits in 23580 * chan_sip for any other schemes of overlap dialing. 23581 * 23582 * For SIP_PAGE2_ALLOWOVERLAP_DTMF it is better to do this in 23583 * the dialplan using the Incomplete application rather than 23584 * having the channel driver do it. 23585 */ 23586 /* Fall through */ 23587 case SIP_GET_DEST_EXTEN_NOT_FOUND: 23588 { 23589 char *decoded_exten = ast_strdupa(p->exten); 23590 transmit_response_reliable(p, "404 Not Found", req); 23591 ast_uri_decode(decoded_exten); 23592 ast_log(LOG_NOTICE, "Call from '%s' (%s) to extension" 23593 " '%s' rejected because extension not found in context '%s'.\n", 23594 S_OR(p->username, p->peername), ast_sockaddr_stringify(&p->recv), decoded_exten, p->context); 23595 } 23596 break; 23597 case SIP_GET_DEST_REFUSED: 23598 default: 23599 transmit_response_reliable(p, "403 Forbidden", req); 23600 } /* end switch */ 23601 23602 p->invitestate = INV_COMPLETED; 23603 update_call_counter(p, DEC_CALL_LIMIT); 23604 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23605 res = 0; 23606 goto request_invite_cleanup; 23607 } else { 23608 23609 /* If no extension was specified, use the s one */ 23610 /* Basically for calling to IP/Host name only */ 23611 if (ast_strlen_zero(p->exten)) 23612 ast_string_field_set(p, exten, "s"); 23613 /* Initialize our tag */ 23614 23615 make_our_tag(p); 23616 23617 if (handle_request_invite_st(p, req, required, reinvite)) { 23618 p->invitestate = INV_COMPLETED; 23619 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23620 res = -1; 23621 goto request_invite_cleanup; 23622 } 23623 23624 /* First invitation - create the channel. Allocation 23625 * failures are handled below. */ 23626 c = sip_new(p, AST_STATE_DOWN, S_OR(p->peername, NULL), NULL); 23627 if (cc_recall_core_id != -1) { 23628 ast_setup_cc_recall_datastore(c, cc_recall_core_id); 23629 ast_cc_agent_set_interfaces_chanvar(c); 23630 } 23631 *recount = 1; 23632 23633 /* Save Record-Route for any later requests we make on this dialogue */ 23634 build_route(p, req, 0, 0); 23635 23636 if (c) { 23637 ast_party_redirecting_init(&redirecting); 23638 memset(&update_redirecting, 0, sizeof(update_redirecting)); 23639 change_redirecting_information(p, req, &redirecting, &update_redirecting, 23640 FALSE); /*Will return immediately if no Diversion header is present */ 23641 ast_channel_set_redirecting(c, &redirecting, &update_redirecting); 23642 ast_party_redirecting_free(&redirecting); 23643 } 23644 } 23645 } else { 23646 ast_party_redirecting_init(&redirecting); 23647 memset(&update_redirecting, 0, sizeof(update_redirecting)); 23648 if (sipdebug) { 23649 if (!req->ignore) 23650 ast_debug(2, "Got a SIP re-invite for call %s\n", p->callid); 23651 else 23652 ast_debug(2, "Got a SIP re-transmit of INVITE for call %s\n", p->callid); 23653 } 23654 if (!req->ignore) 23655 reinvite = 1; 23656 23657 if (handle_request_invite_st(p, req, required, reinvite)) { 23658 p->invitestate = INV_COMPLETED; 23659 if (!p->lastinvite) { 23660 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23661 } 23662 res = -1; 23663 goto request_invite_cleanup; 23664 } 23665 23666 c = p->owner; 23667 change_redirecting_information(p, req, &redirecting, &update_redirecting, FALSE); /*Will return immediately if no Diversion header is present */ 23668 if (c) { 23669 ast_channel_set_redirecting(c, &redirecting, &update_redirecting); 23670 } 23671 ast_party_redirecting_free(&redirecting); 23672 } 23673 23674 if (reinvite && p->stimer->st_active == TRUE) { 23675 restart_session_timer(p); 23676 } 23677 23678 if (!req->ignore && p) 23679 p->lastinvite = seqno; 23680 23681 if (c && replace_id) { /* Attended transfer or call pickup - we're the target */ 23682 if (!ast_strlen_zero(pickup.exten)) { 23683 append_history(p, "Xfer", "INVITE/Replace received"); 23684 23685 /* Let the caller know we're giving it a shot */ 23686 transmit_response(p, "100 Trying", req); 23687 p->invitestate = INV_PROCEEDING; 23688 ast_setstate(c, AST_STATE_RING); 23689 23690 /* Do the pickup itself */ 23691 ast_channel_unlock(c); 23692 *nounlock = 1; 23693 23694 /* since p->owner (c) is unlocked, we need to go ahead and unlock pvt for both 23695 * magic pickup and ast_hangup. Both of these functions will attempt to lock 23696 * p->owner again, which can cause a deadlock if we already hold a lock on p. 23697 * Locking order is, channel then pvt. Dead lock avoidance must be used if 23698 * called the other way around. */ 23699 sip_pvt_unlock(p); 23700 do_magic_pickup(c, pickup.exten, pickup.context); 23701 /* Now we're either masqueraded or we failed to pickup, in either case we... */ 23702 ast_hangup(c); 23703 sip_pvt_lock(p); /* pvt is expected to remain locked on return, so re-lock it */ 23704 23705 res = 0; 23706 goto request_invite_cleanup; 23707 } else { 23708 /* Go and take over the target call */ 23709 if (sipdebug) 23710 ast_debug(4, "Sending this call to the invite/replcaes handler %s\n", p->callid); 23711 res = handle_invite_replaces(p, req, debug, seqno, addr, nounlock); 23712 refer_locked = 0; 23713 goto request_invite_cleanup; 23714 } 23715 } 23716 23717 23718 if (c) { /* We have a call -either a new call or an old one (RE-INVITE) */ 23719 enum ast_channel_state c_state = c->_state; 23720 23721 if (c_state != AST_STATE_UP && reinvite && 23722 (p->invitestate == INV_TERMINATED || p->invitestate == INV_CONFIRMED)) { 23723 /* If these conditions are true, and the channel is still in the 'ringing' 23724 * state, then this likely means that we have a situation where the initial 23725 * INVITE transaction has completed *but* the channel's state has not yet been 23726 * changed to UP. The reason this could happen is if the reinvite is received 23727 * on the SIP socket prior to an application calling ast_read on this channel 23728 * to read the answer frame we earlier queued on it. In this case, the reinvite 23729 * is completely legitimate so we need to handle this the same as if the channel 23730 * were already UP. Thus we are purposely falling through to the AST_STATE_UP case. 23731 */ 23732 c_state = AST_STATE_UP; 23733 } 23734 23735 switch(c_state) { 23736 case AST_STATE_DOWN: 23737 ast_debug(2, "%s: New call is still down.... Trying... \n", c->name); 23738 transmit_provisional_response(p, "100 Trying", req, 0); 23739 p->invitestate = INV_PROCEEDING; 23740 ast_setstate(c, AST_STATE_RING); 23741 if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */ 23742 enum ast_pbx_result result; 23743 23744 result = ast_pbx_start(c); 23745 23746 switch(result) { 23747 case AST_PBX_FAILED: 23748 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 23749 p->invitestate = INV_COMPLETED; 23750 transmit_response_reliable(p, "503 Unavailable", req); 23751 break; 23752 case AST_PBX_CALL_LIMIT: 23753 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n"); 23754 p->invitestate = INV_COMPLETED; 23755 transmit_response_reliable(p, "480 Temporarily Unavailable", req); 23756 break; 23757 case AST_PBX_SUCCESS: 23758 /* nothing to do */ 23759 break; 23760 } 23761 23762 if (result) { 23763 23764 /* Unlock locks so ast_hangup can do its magic */ 23765 ast_channel_unlock(c); 23766 *nounlock = 1; 23767 sip_pvt_unlock(p); 23768 ast_hangup(c); 23769 sip_pvt_lock(p); 23770 c = NULL; 23771 } 23772 } else { /* Pickup call in call group */ 23773 if (sip_pickup(c)) { 23774 ast_log(LOG_WARNING, "Failed to start Group pickup by %s\n", c->name); 23775 transmit_response_reliable(p, "480 Temporarily Unavailable", req); 23776 sip_alreadygone(p); 23777 c->hangupcause = AST_CAUSE_FAILURE; 23778 23779 /* Unlock locks so ast_hangup can do its magic */ 23780 ast_channel_unlock(c); 23781 *nounlock = 1; 23782 23783 p->invitestate = INV_COMPLETED; 23784 sip_pvt_unlock(p); 23785 ast_hangup(c); 23786 sip_pvt_lock(p); 23787 c = NULL; 23788 } 23789 } 23790 break; 23791 case AST_STATE_RING: 23792 transmit_provisional_response(p, "100 Trying", req, 0); 23793 p->invitestate = INV_PROCEEDING; 23794 break; 23795 case AST_STATE_RINGING: 23796 transmit_provisional_response(p, "180 Ringing", req, 0); 23797 p->invitestate = INV_PROCEEDING; 23798 break; 23799 case AST_STATE_UP: 23800 ast_debug(2, "%s: This call is UP.... \n", c->name); 23801 23802 transmit_response(p, "100 Trying", req); 23803 23804 if (p->t38.state == T38_PEER_REINVITE) { 23805 if (p->t38id > -1) { 23806 /* reset t38 abort timer */ 23807 AST_SCHED_DEL_UNREF(sched, p->t38id, dialog_unref(p, "remove ref for t38id")); 23808 } 23809 p->t38id = ast_sched_add(sched, 5000, sip_t38_abort, dialog_ref(p, "passing dialog ptr into sched structure based on t38id for sip_t38_abort.")); 23810 } else if (p->t38.state == T38_ENABLED) { 23811 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 23812 transmit_response_with_t38_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (req->ignore ? XMIT_UNRELIABLE : XMIT_CRITICAL))); 23813 } else if (p->t38.state == T38_DISABLED) { 23814 /* If this is not a re-invite or something to ignore - it's critical */ 23815 if (p->srtp && !ast_test_flag(p->srtp, SRTP_CRYPTO_OFFER_OK)) { 23816 ast_log(LOG_WARNING, "Target does not support required crypto\n"); 23817 transmit_response_reliable(p, "488 Not Acceptable Here (crypto)", req); 23818 } else { 23819 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 23820 transmit_response_with_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (req->ignore ? XMIT_UNRELIABLE : XMIT_CRITICAL)), p->session_modify == TRUE ? FALSE : TRUE, FALSE); 23821 ast_queue_control(p->owner, AST_CONTROL_UPDATE_RTP_PEER); 23822 } 23823 } 23824 23825 p->invitestate = INV_TERMINATED; 23826 break; 23827 default: 23828 ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %u\n", c->_state); 23829 transmit_response(p, "100 Trying", req); 23830 break; 23831 } 23832 } else { 23833 if (p && (p->autokillid == -1)) { 23834 const char *msg; 23835 23836 if (!p->jointcapability) 23837 msg = "488 Not Acceptable Here (codec error)"; 23838 else { 23839 ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n"); 23840 msg = "503 Unavailable"; 23841 } 23842 transmit_response_reliable(p, msg, req); 23843 p->invitestate = INV_COMPLETED; 23844 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23845 } 23846 } 23847 23848 request_invite_cleanup: 23849 23850 if (refer_locked && p->refer && p->refer->refer_call) { 23851 sip_pvt_unlock(p->refer->refer_call); 23852 if (p->refer->refer_call->owner) { 23853 ast_channel_unlock(p->refer->refer_call->owner); 23854 } 23855 p->refer->refer_call = dialog_unref(p->refer->refer_call, "unref dialog p->refer->refer_call"); 23856 } 23857 if (authpeer) { 23858 authpeer = unref_peer(authpeer, "unref_peer, from handle_request_invite authpeer"); 23859 } 23860 23861 return res; 23862 }
| static int handle_request_invite_st | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| const char * | required, | |||
| int | reinvite | |||
| ) | [static] |
Definition at line 22982 of file chan_sip.c.
References ast_debug, ast_log(), ast_strlen_zero(), FALSE, get_header(), LOG_ERROR, LOG_WARNING, MAX, parse_minse(), parse_session_expires(), sip_st_alloc(), st_get_mode(), st_get_refresher(), st_get_se(), transmit_response_reliable(), transmit_response_with_minse(), transmit_response_with_unsupported(), and TRUE.
Referenced by handle_request_invite().
22984 { 22985 const char *p_uac_se_hdr; /* UAC's Session-Expires header string */ 22986 const char *p_uac_min_se; /* UAC's requested Min-SE interval (char string) */ 22987 int uac_max_se = -1; /* UAC's Session-Expires in integer format */ 22988 int uac_min_se = -1; /* UAC's Min-SE in integer format */ 22989 int st_active = FALSE; /* Session-Timer on/off boolean */ 22990 int st_interval = 0; /* Session-Timer negotiated refresh interval */ 22991 enum st_refresher tmp_st_ref = SESSION_TIMER_REFRESHER_AUTO; /* Session-Timer refresher */ 22992 int dlg_min_se = -1; 22993 int dlg_max_se = global_max_se; 22994 int rtn; 22995 22996 /* Session-Timers */ 22997 if ((p->sipoptions & SIP_OPT_TIMER)) { 22998 enum st_refresher_param st_ref_param = SESSION_TIMER_REFRESHER_PARAM_UNKNOWN; 22999 23000 /* The UAC has requested session-timers for this session. Negotiate 23001 the session refresh interval and who will be the refresher */ 23002 ast_debug(2, "Incoming INVITE with 'timer' option supported\n"); 23003 23004 /* Allocate Session-Timers struct w/in the dialog */ 23005 if (!p->stimer) { 23006 sip_st_alloc(p); 23007 } 23008 23009 /* Parse the Session-Expires header */ 23010 p_uac_se_hdr = get_header(req, "Session-Expires"); 23011 if (!ast_strlen_zero(p_uac_se_hdr)) { 23012 ast_debug(2, "INVITE also has \"Session-Expires\" header.\n"); 23013 rtn = parse_session_expires(p_uac_se_hdr, &uac_max_se, &st_ref_param); 23014 tmp_st_ref = (st_ref_param == SESSION_TIMER_REFRESHER_PARAM_UAC) ? SESSION_TIMER_REFRESHER_THEM : SESSION_TIMER_REFRESHER_US; 23015 if (rtn != 0) { 23016 transmit_response_reliable(p, "400 Session-Expires Invalid Syntax", req); 23017 return -1; 23018 } 23019 } 23020 23021 /* Parse the Min-SE header */ 23022 p_uac_min_se = get_header(req, "Min-SE"); 23023 if (!ast_strlen_zero(p_uac_min_se)) { 23024 ast_debug(2, "INVITE also has \"Min-SE\" header.\n"); 23025 rtn = parse_minse(p_uac_min_se, &uac_min_se); 23026 if (rtn != 0) { 23027 transmit_response_reliable(p, "400 Min-SE Invalid Syntax", req); 23028 return -1; 23029 } 23030 } 23031 23032 dlg_min_se = st_get_se(p, FALSE); 23033 switch (st_get_mode(p, 1)) { 23034 case SESSION_TIMER_MODE_ACCEPT: 23035 case SESSION_TIMER_MODE_ORIGINATE: 23036 if (uac_max_se > 0 && uac_max_se < dlg_min_se) { 23037 transmit_response_with_minse(p, "422 Session Interval Too Small", req, dlg_min_se); 23038 return -1; 23039 } 23040 23041 p->stimer->st_active_peer_ua = TRUE; 23042 st_active = TRUE; 23043 if (st_ref_param == SESSION_TIMER_REFRESHER_PARAM_UNKNOWN) { 23044 tmp_st_ref = st_get_refresher(p); 23045 } 23046 23047 dlg_max_se = st_get_se(p, TRUE); 23048 if (uac_max_se > 0) { 23049 if (dlg_max_se >= uac_min_se) { 23050 st_interval = (uac_max_se < dlg_max_se) ? uac_max_se : dlg_max_se; 23051 } else { 23052 st_interval = uac_max_se; 23053 } 23054 } else if (uac_min_se > 0) { 23055 st_interval = MAX(dlg_max_se, uac_min_se); 23056 } else { 23057 st_interval = dlg_max_se; 23058 } 23059 break; 23060 23061 case SESSION_TIMER_MODE_REFUSE: 23062 if (p->reqsipoptions & SIP_OPT_TIMER) { 23063 transmit_response_with_unsupported(p, "420 Option Disabled", req, required); 23064 ast_log(LOG_WARNING, "Received SIP INVITE with supported but disabled option: %s\n", required); 23065 return -1; 23066 } 23067 break; 23068 23069 default: 23070 ast_log(LOG_ERROR, "Internal Error %u at %s:%d\n", st_get_mode(p, 1), __FILE__, __LINE__); 23071 break; 23072 } 23073 } else { 23074 /* The UAC did not request session-timers. Asterisk (UAS), will now decide 23075 (based on session-timer-mode in sip.conf) whether to run session-timers for 23076 this session or not. */ 23077 switch (st_get_mode(p, 1)) { 23078 case SESSION_TIMER_MODE_ORIGINATE: 23079 st_active = TRUE; 23080 st_interval = st_get_se(p, TRUE); 23081 tmp_st_ref = SESSION_TIMER_REFRESHER_US; 23082 p->stimer->st_active_peer_ua = (p->sipoptions & SIP_OPT_TIMER) ? TRUE : FALSE; 23083 break; 23084 23085 default: 23086 break; 23087 } 23088 } 23089 23090 if (reinvite == 0) { 23091 /* Session-Timers: Start session refresh timer based on negotiation/config */ 23092 if (st_active == TRUE) { 23093 p->stimer->st_active = TRUE; 23094 p->stimer->st_interval = st_interval; 23095 p->stimer->st_ref = tmp_st_ref; 23096 } 23097 } else { 23098 if (p->stimer->st_active == TRUE) { 23099 /* Session-Timers: A re-invite request sent within a dialog will serve as 23100 a refresh request, no matter whether the re-invite was sent for refreshing 23101 the session or modifying it.*/ 23102 ast_debug (2, "Restarting session-timers on a refresh - %s\n", p->callid); 23103 23104 /* The UAC may be adjusting the session-timers mid-session */ 23105 if (st_interval > 0) { 23106 p->stimer->st_interval = st_interval; 23107 p->stimer->st_ref = tmp_st_ref; 23108 } 23109 } 23110 } 23111 23112 return 0; 23113 }
| static int handle_request_message | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Handle incoming MESSAGE request.
Definition at line 24749 of file chan_sip.c.
References ast_verbose, receive_message(), and transmit_response().
Referenced by handle_incoming().
24750 { 24751 if (!req->ignore) { 24752 if (req->debug) 24753 ast_verbose("Receiving message!\n"); 24754 receive_message(p, req); 24755 } else 24756 transmit_response(p, "202 Accepted", req); 24757 return 1; 24758 }
| static int handle_request_notify | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| struct ast_sockaddr * | addr, | |||
| uint32_t | seqno, | |||
| const char * | e | |||
| ) | [static] |
Handle incoming notifications.
Definition at line 22504 of file chan_sip.c.
References AST_CONTROL_TRANSFER, ast_debug, AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, ast_event_new(), ast_event_queue_and_cache(), ast_log(), ast_queue_control_data(), ast_skip_blanks(), ast_strdupa, ast_strlen_zero(), AST_TRANSFER_FAILED, AST_TRANSFER_SUCCESS, FALSE, find_peer(), get_body(), get_header(), get_msg_text(), handle_cc_notify(), LOG_NOTICE, LOG_WARNING, mailbox, sip_scheddestroy(), transmit_response(), TRUE, and unref_peer().
Referenced by handle_incoming().
22505 { 22506 /* This is mostly a skeleton for future improvements */ 22507 /* Mostly created to return proper answers on notifications on outbound REFER's */ 22508 int res = 0; 22509 const char *event = get_header(req, "Event"); 22510 char *sep; 22511 22512 if( (sep = strchr(event, ';')) ) { /* XXX bug here - overwriting string ? */ 22513 *sep++ = '\0'; 22514 } 22515 22516 if (sipdebug) 22517 ast_debug(2, "Got NOTIFY Event: %s\n", event); 22518 22519 if (!strcmp(event, "refer")) { 22520 /* Save nesting depth for now, since there might be other events we will 22521 support in the future */ 22522 22523 /* Handle REFER notifications */ 22524 22525 char buf[1024]; 22526 char *cmd, *code; 22527 int respcode; 22528 int success = TRUE; 22529 22530 /* EventID for each transfer... EventID is basically the REFER cseq 22531 22532 We are getting notifications on a call that we transferred 22533 We should hangup when we are getting a 200 OK in a sipfrag 22534 Check if we have an owner of this event */ 22535 22536 /* Check the content type */ 22537 if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) { 22538 /* We need a sipfrag */ 22539 transmit_response(p, "400 Bad request", req); 22540 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22541 return -1; 22542 } 22543 22544 /* Get the text of the attachment */ 22545 if (get_msg_text(buf, sizeof(buf), req)) { 22546 ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid); 22547 transmit_response(p, "400 Bad request", req); 22548 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22549 return -1; 22550 } 22551 22552 /* 22553 From the RFC... 22554 A minimal, but complete, implementation can respond with a single 22555 NOTIFY containing either the body: 22556 SIP/2.0 100 Trying 22557 22558 if the subscription is pending, the body: 22559 SIP/2.0 200 OK 22560 if the reference was successful, the body: 22561 SIP/2.0 503 Service Unavailable 22562 if the reference failed, or the body: 22563 SIP/2.0 603 Declined 22564 22565 if the REFER request was accepted before approval to follow the 22566 reference could be obtained and that approval was subsequently denied 22567 (see Section 2.4.7). 22568 22569 If there are several REFERs in the same dialog, we need to 22570 match the ID of the event header... 22571 */ 22572 ast_debug(3, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf); 22573 cmd = ast_skip_blanks(buf); 22574 code = cmd; 22575 /* We are at SIP/2.0 */ 22576 while(*code && (*code > 32)) { /* Search white space */ 22577 code++; 22578 } 22579 *code++ = '\0'; 22580 code = ast_skip_blanks(code); 22581 sep = code; 22582 sep++; 22583 while(*sep && (*sep > 32)) { /* Search white space */ 22584 sep++; 22585 } 22586 *sep++ = '\0'; /* Response string */ 22587 respcode = atoi(code); 22588 switch (respcode) { 22589 case 200: /* OK: The new call is up, hangup this call */ 22590 /* Hangup the call that we are replacing */ 22591 break; 22592 case 301: /* Moved permenantly */ 22593 case 302: /* Moved temporarily */ 22594 /* Do we get the header in the packet in this case? */ 22595 success = FALSE; 22596 break; 22597 case 503: /* Service Unavailable: The new call failed */ 22598 case 603: /* Declined: Not accepted */ 22599 /* Cancel transfer, continue the current call */ 22600 success = FALSE; 22601 break; 22602 case 0: /* Parse error */ 22603 /* Cancel transfer, continue the current call */ 22604 ast_log(LOG_NOTICE, "Error parsing sipfrag in NOTIFY in response to REFER.\n"); 22605 success = FALSE; 22606 break; 22607 default: 22608 if (respcode < 200) { 22609 /* ignore provisional responses */ 22610 success = -1; 22611 } else { 22612 ast_log(LOG_NOTICE, "Got unknown code '%d' in NOTIFY in response to REFER.\n", respcode); 22613 success = FALSE; 22614 } 22615 break; 22616 } 22617 if (success == FALSE) { 22618 ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n"); 22619 } 22620 22621 if (p->owner && success != -1) { 22622 enum ast_control_transfer message = success ? AST_TRANSFER_SUCCESS : AST_TRANSFER_FAILED; 22623 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 22624 } 22625 /* Confirm that we received this packet */ 22626 transmit_response(p, "200 OK", req); 22627 } else if (!strcmp(event, "message-summary")) { 22628 const char *mailbox = NULL; 22629 char *c = ast_strdupa(get_body(req, "Voice-Message", ':')); 22630 22631 if (!p->mwi) { 22632 struct sip_peer *peer = find_peer(NULL, &p->recv, TRUE, FINDPEERS, FALSE, p->socket.type); 22633 22634 if (peer) { 22635 mailbox = ast_strdupa(peer->unsolicited_mailbox); 22636 unref_peer(peer, "removing unsolicited mwi ref"); 22637 } 22638 } else { 22639 mailbox = p->mwi->mailbox; 22640 } 22641 22642 if (!ast_strlen_zero(mailbox) && !ast_strlen_zero(c)) { 22643 char *old = strsep(&c, " "); 22644 char *new = strsep(&old, "/"); 22645 struct ast_event *event; 22646 22647 if ((event = ast_event_new(AST_EVENT_MWI, 22648 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 22649 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, "SIP_Remote", 22650 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, atoi(new), 22651 AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, atoi(old), 22652 AST_EVENT_IE_END))) { 22653 ast_event_queue_and_cache(event); 22654 } 22655 transmit_response(p, "200 OK", req); 22656 } else { 22657 transmit_response(p, "489 Bad event", req); 22658 res = -1; 22659 } 22660 } else if (!strcmp(event, "keep-alive")) { 22661 /* Used by Sipura/Linksys for NAT pinhole, 22662 * just confirm that we received the packet. */ 22663 transmit_response(p, "200 OK", req); 22664 } else if (!strcmp(event, "call-completion")) { 22665 res = handle_cc_notify(p, req); 22666 } else { 22667 /* We don't understand this event. */ 22668 transmit_response(p, "489 Bad event", req); 22669 res = -1; 22670 } 22671 22672 if (!p->lastinvite) 22673 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22674 22675 return res; 22676 }
| static int handle_request_options | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| struct ast_sockaddr * | addr, | |||
| const char * | e | |||
| ) | [static] |
Handle incoming OPTIONS request An OPTIONS request should be answered like an INVITE from the same UA, including SDP.
Definition at line 22681 of file chan_sip.c.
References ast_log(), ast_shutting_down(), ast_string_field_set, ast_strlen_zero(), build_contact(), check_user(), context, copy_request(), get_destination(), get_header(), LOG_NOTICE, set_pvt_allowed_methods(), sip_cfg, sip_scheddestroy(), transmit_response(), and transmit_response_with_allow().
Referenced by handle_incoming().
22682 { 22683 const char *msg; 22684 enum sip_get_dest_result gotdest; 22685 int res; 22686 22687 if (p->lastinvite) { 22688 /* if this is a request in an active dialog, just confirm that the dialog exists. */ 22689 transmit_response_with_allow(p, "200 OK", req, 0); 22690 return 0; 22691 } 22692 22693 if (sip_cfg.auth_options_requests) { 22694 /* Do authentication if this OPTIONS request began the dialog */ 22695 copy_request(&p->initreq, req); 22696 set_pvt_allowed_methods(p, req); 22697 res = check_user(p, req, SIP_OPTIONS, e, XMIT_UNRELIABLE, addr); 22698 if (res == AUTH_CHALLENGE_SENT) { 22699 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22700 return 0; 22701 } 22702 if (res < 0) { /* Something failed in authentication */ 22703 ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From")); 22704 transmit_response(p, "403 Forbidden", req); 22705 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22706 return 0; 22707 } 22708 } 22709 22710 /* must go through authentication before getting here */ 22711 gotdest = get_destination(p, req, NULL); 22712 build_contact(p); 22713 22714 if (ast_strlen_zero(p->context)) 22715 ast_string_field_set(p, context, sip_cfg.default_context); 22716 22717 if (ast_shutting_down()) { 22718 msg = "503 Unavailable"; 22719 } else { 22720 msg = "404 Not Found"; 22721 switch (gotdest) { 22722 case SIP_GET_DEST_INVALID_URI: 22723 msg = "416 Unsupported URI scheme"; 22724 break; 22725 case SIP_GET_DEST_EXTEN_MATCHMORE: 22726 case SIP_GET_DEST_REFUSED: 22727 case SIP_GET_DEST_EXTEN_NOT_FOUND: 22728 //msg = "404 Not Found"; 22729 break; 22730 case SIP_GET_DEST_EXTEN_FOUND: 22731 msg = "200 OK"; 22732 break; 22733 } 22734 } 22735 transmit_response_with_allow(p, msg, req, 0); 22736 22737 /* Destroy if this OPTIONS was the opening request, but not if 22738 it's in the middle of a normal call flow. */ 22739 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22740 22741 return 0; 22742 }
| static int handle_request_publish | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| struct ast_sockaddr * | addr, | |||
| const uint32_t | seqno, | |||
| const char * | uri | |||
| ) | [static] |
Definition at line 25181 of file chan_sip.c.
References __sip_ack(), ast_log(), ast_string_field_set, ast_strlen_zero(), check_user(), determine_sip_publish_type(), get_esc(), get_header(), handle_sip_publish_initial(), handle_sip_publish_modify(), handle_sip_publish_refresh(), handle_sip_publish_remove(), LOG_NOTICE, pvt_set_needdestroy(), sip_scheddestroy(), transmit_response(), and transmit_response_with_minexpires().
Referenced by handle_incoming().
25182 { 25183 const char *etag = get_header(req, "SIP-If-Match"); 25184 const char *event = get_header(req, "Event"); 25185 struct event_state_compositor *esc; 25186 enum sip_publish_type publish_type; 25187 const char *expires_str = get_header(req, "Expires"); 25188 int expires_int; 25189 int auth_result; 25190 int handler_result = -1; 25191 25192 if (ast_strlen_zero(event)) { 25193 transmit_response(p, "489 Bad Event", req); 25194 pvt_set_needdestroy(p, "missing Event: header"); 25195 return -1; 25196 } 25197 25198 if (!(esc = get_esc(event))) { 25199 transmit_response(p, "489 Bad Event", req); 25200 pvt_set_needdestroy(p, "unknown event package in publish"); 25201 return -1; 25202 } 25203 25204 auth_result = check_user(p, req, SIP_PUBLISH, uri, XMIT_UNRELIABLE, addr); 25205 if (auth_result == AUTH_CHALLENGE_SENT) { 25206 p->lastinvite = seqno; 25207 return 0; 25208 } else if (auth_result < 0) { 25209 ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From")); 25210 transmit_response(p, "403 Forbidden", req); 25211 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 25212 ast_string_field_set(p, theirtag, NULL); 25213 return 0; 25214 } else if (auth_result == AUTH_SUCCESSFUL && p->lastinvite) { 25215 /* We need to stop retransmitting the 401 */ 25216 __sip_ack(p, p->lastinvite, 1, 0); 25217 } 25218 25219 publish_type = determine_sip_publish_type(req, event, etag, expires_str, &expires_int); 25220 25221 if (expires_int > max_expiry) { 25222 expires_int = max_expiry; 25223 } else if (expires_int < min_expiry && expires_int > 0) { 25224 transmit_response_with_minexpires(p, "423 Interval too small", req); 25225 pvt_set_needdestroy(p, "Expires is less that the min expires allowed."); 25226 return 0; 25227 } 25228 p->expiry = expires_int; 25229 25230 /* It is the responsibility of these handlers to formulate any response 25231 * sent for a PUBLISH 25232 */ 25233 switch (publish_type) { 25234 case SIP_PUBLISH_UNKNOWN: 25235 transmit_response(p, "400 Bad Request", req); 25236 break; 25237 case SIP_PUBLISH_INITIAL: 25238 handler_result = handle_sip_publish_initial(p, req, esc, expires_int); 25239 break; 25240 case SIP_PUBLISH_REFRESH: 25241 handler_result = handle_sip_publish_refresh(p, req, esc, etag, expires_int); 25242 break; 25243 case SIP_PUBLISH_MODIFY: 25244 handler_result = handle_sip_publish_modify(p, req, esc, etag, expires_int); 25245 break; 25246 case SIP_PUBLISH_REMOVE: 25247 handler_result = handle_sip_publish_remove(p, req, esc, etag); 25248 break; 25249 default: 25250 transmit_response(p, "400 Impossible Condition", req); 25251 break; 25252 } 25253 if (!handler_result && p->expiry > 0) { 25254 sip_scheddestroy(p, (p->expiry + 10) * 1000); 25255 } else { 25256 pvt_set_needdestroy(p, "forcing expiration"); 25257 } 25258 25259 return handler_result; 25260 }
| static int handle_request_refer | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| int | debug, | |||
| uint32_t | seqno, | |||
| int * | nounlock | |||
| ) | [static] |
Chan1: Call between asterisk and transferer Chan2: Call between asterisk and transferee
Definition at line 24137 of file chan_sip.c.
References append_history, ast_async_goto(), ast_bridged_channel(), AST_CAUSE_NORMAL_CLEARING, AST_CEL_ATTENDEDTRANSFER, AST_CEL_BLINDTRANSFER, ast_cel_report_event(), ast_channel_lock, ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_clear_flag, AST_CONTROL_UNHOLD, ast_debug, ast_indicate(), AST_LIST_EMPTY, ast_manager_event_multichan, ast_parking_ext_valid(), ast_queue_control(), ast_set_flag, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose, check_sip_domain(), context, EVENT_FLAG_CALL, FALSE, get_refer_info(), local_attended_transfer(), pbx_builtin_setvar_helper(), pvt_set_needdestroy(), sip_alreadygone(), sip_cfg, sip_park(), sip_pvt_lock, sip_pvt_unlock, sip_refer_allocate(), transmit_notify_with_sipfrag(), transmit_response(), and TRUE.
Referenced by handle_incoming().
24138 { 24139 /*! 24140 * Chan1: Call between asterisk and transferer 24141 * Chan2: Call between asterisk and transferee 24142 */ 24143 struct sip_dual current = { 0, }; 24144 struct ast_channel *chans[2] = { 0, }; 24145 char *refer_to = NULL; 24146 char *refer_to_domain = NULL; 24147 char *refer_to_context = NULL; 24148 char *referred_by = NULL; 24149 char *callid = NULL; 24150 int localtransfer = 0; 24151 int attendedtransfer = 0; 24152 int res = 0; 24153 24154 if (req->debug) { 24155 ast_verbose("Call %s got a SIP call transfer from %s: (REFER)!\n", 24156 p->callid, 24157 ast_test_flag(&p->flags[0], SIP_OUTGOING) ? "callee" : "caller"); 24158 } 24159 24160 if (!p->owner) { 24161 /* This is a REFER outside of an existing SIP dialog */ 24162 /* We can't handle that, so decline it */ 24163 ast_debug(3, "Call %s: Declined REFER, outside of dialog...\n", p->callid); 24164 transmit_response(p, "603 Declined (No dialog)", req); 24165 if (!req->ignore) { 24166 append_history(p, "Xfer", "Refer failed. Outside of dialog."); 24167 sip_alreadygone(p); 24168 pvt_set_needdestroy(p, "outside of dialog"); 24169 } 24170 res = 0; 24171 goto handle_refer_cleanup; 24172 } 24173 24174 /* Check if transfer is allowed from this device */ 24175 if (p->allowtransfer == TRANSFER_CLOSED ) { 24176 /* Transfer not allowed, decline */ 24177 transmit_response(p, "603 Declined (policy)", req); 24178 append_history(p, "Xfer", "Refer failed. Allowtransfer == closed."); 24179 /* Do not destroy SIP session */ 24180 res = 0; 24181 goto handle_refer_cleanup; 24182 } 24183 24184 if (!req->ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 24185 /* Already have a pending REFER */ 24186 transmit_response(p, "491 Request pending", req); 24187 append_history(p, "Xfer", "Refer failed. Request pending."); 24188 res = 0; 24189 goto handle_refer_cleanup; 24190 } 24191 24192 /* Allocate memory for call transfer data */ 24193 if (!p->refer && !sip_refer_allocate(p)) { 24194 transmit_response(p, "500 Internal Server Error", req); 24195 append_history(p, "Xfer", "Refer failed. Memory allocation error."); 24196 res = -3; 24197 goto handle_refer_cleanup; 24198 } 24199 24200 res = get_refer_info(p, req); /* Extract headers */ 24201 24202 p->refer->status = REFER_SENT; 24203 24204 if (res != 0) { 24205 switch (res) { 24206 case -2: /* Syntax error */ 24207 transmit_response(p, "400 Bad Request (Refer-to missing)", req); 24208 append_history(p, "Xfer", "Refer failed. Refer-to missing."); 24209 if (req->debug) { 24210 ast_debug(1, "SIP transfer to black hole can't be handled (no refer-to: )\n"); 24211 } 24212 break; 24213 case -3: 24214 transmit_response(p, "603 Declined (Non sip: uri)", req); 24215 append_history(p, "Xfer", "Refer failed. Non SIP uri"); 24216 if (req->debug) { 24217 ast_debug(1, "SIP transfer to non-SIP uri denied\n"); 24218 } 24219 break; 24220 default: 24221 /* Refer-to extension not found, fake a failed transfer */ 24222 transmit_response(p, "202 Accepted", req); 24223 append_history(p, "Xfer", "Refer failed. Bad extension."); 24224 transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE); 24225 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 24226 if (req->debug) { 24227 ast_debug(1, "SIP transfer to bad extension: %s\n", p->refer->refer_to); 24228 } 24229 break; 24230 } 24231 res = 0; 24232 goto handle_refer_cleanup; 24233 } 24234 if (ast_strlen_zero(p->context)) { 24235 ast_string_field_set(p, context, sip_cfg.default_context); 24236 } 24237 24238 /* If we do not support SIP domains, all transfers are local */ 24239 if (sip_cfg.allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 24240 p->refer->localtransfer = 1; 24241 if (sipdebug) { 24242 ast_debug(3, "This SIP transfer is local : %s\n", p->refer->refer_to_domain); 24243 } 24244 } else if (AST_LIST_EMPTY(&domain_list) || check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 24245 /* This PBX doesn't bother with SIP domains or domain is local, so this transfer is local */ 24246 p->refer->localtransfer = 1; 24247 } else if (sipdebug) { 24248 ast_debug(3, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain); 24249 } 24250 24251 /* Is this a repeat of a current request? Ignore it */ 24252 /* Don't know what else to do right now. */ 24253 if (req->ignore) { 24254 goto handle_refer_cleanup; 24255 } 24256 24257 /* If this is a blind transfer, we have the following 24258 channels to work with: 24259 - chan1, chan2: The current call between transferer and transferee (2 channels) 24260 - target_channel: A new call from the transferee to the target (1 channel) 24261 We need to stay tuned to what happens in order to be able 24262 to bring back the call to the transferer */ 24263 24264 /* If this is a attended transfer, we should have all call legs within reach: 24265 - chan1, chan2: The call between the transferer and transferee (2 channels) 24266 - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels) 24267 We want to bridge chan2 with targetcall_pvt! 24268 24269 The replaces call id in the refer message points 24270 to the call leg between Asterisk and the transferer. 24271 So we need to connect the target and the transferee channel 24272 and hangup the two other channels silently 24273 24274 If the target is non-local, the call ID could be on a remote 24275 machine and we need to send an INVITE with replaces to the 24276 target. We basically handle this as a blind transfer 24277 and let the sip_call function catch that we need replaces 24278 header in the INVITE. 24279 */ 24280 24281 /* Get the transferer's channel */ 24282 chans[0] = current.chan1 = p->owner; 24283 24284 /* Find the other part of the bridge (2) - transferee */ 24285 chans[1] = current.chan2 = ast_bridged_channel(current.chan1); 24286 24287 ast_channel_ref(current.chan1); 24288 if (current.chan2) { 24289 ast_channel_ref(current.chan2); 24290 } 24291 24292 if (sipdebug) { 24293 ast_debug(3, "SIP %s transfer: Transferer channel %s, transferee channel %s\n", 24294 p->refer->attendedtransfer ? "attended" : "blind", 24295 current.chan1->name, 24296 current.chan2 ? current.chan2->name : "<none>"); 24297 } 24298 24299 if (!current.chan2 && !p->refer->attendedtransfer) { 24300 /* No bridged channel, propably IVR or echo or similar... */ 24301 /* Guess we should masquerade or something here */ 24302 /* Until we figure it out, refuse transfer of such calls */ 24303 if (sipdebug) { 24304 ast_debug(3, "Refused SIP transfer on non-bridged channel.\n"); 24305 } 24306 p->refer->status = REFER_FAILED; 24307 append_history(p, "Xfer", "Refer failed. Non-bridged channel."); 24308 transmit_response(p, "603 Declined", req); 24309 res = -1; 24310 goto handle_refer_cleanup; 24311 } 24312 24313 if (current.chan2) { 24314 if (sipdebug) { 24315 ast_debug(4, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name); 24316 } 24317 ast_queue_control(current.chan1, AST_CONTROL_UNHOLD); 24318 } 24319 24320 ast_set_flag(&p->flags[0], SIP_GOTREFER); 24321 24322 /* From here on failures will be indicated with NOTIFY requests */ 24323 transmit_response(p, "202 Accepted", req); 24324 24325 /* Attended transfer: Find all call legs and bridge transferee with target*/ 24326 if (p->refer->attendedtransfer) { 24327 /* both p and p->owner _MUST_ be locked while calling local_attended_transfer */ 24328 if ((res = local_attended_transfer(p, ¤t, req, seqno, nounlock))) { 24329 goto handle_refer_cleanup; /* We're done with the transfer */ 24330 } 24331 /* Fall through for remote transfers that we did not find locally */ 24332 if (sipdebug) { 24333 ast_debug(4, "SIP attended transfer: Still not our call - generating INVITE with replaces\n"); 24334 } 24335 /* Fallthrough if we can't find the call leg internally */ 24336 } 24337 24338 /* Copy data we can not safely access after letting the pvt lock go. */ 24339 refer_to = ast_strdupa(p->refer->refer_to); 24340 refer_to_domain = ast_strdupa(p->refer->refer_to_domain); 24341 refer_to_context = ast_strdupa(p->refer->refer_to_context); 24342 referred_by = ast_strdupa(p->refer->referred_by); 24343 callid = ast_strdupa(p->callid); 24344 localtransfer = p->refer->localtransfer; 24345 attendedtransfer = p->refer->attendedtransfer; 24346 24347 if (!*nounlock) { 24348 ast_channel_unlock(p->owner); 24349 *nounlock = 1; 24350 } 24351 sip_pvt_unlock(p); 24352 24353 /* Parking a call. DO NOT hold any locks while calling ast_parking_ext_valid() */ 24354 if (localtransfer && ast_parking_ext_valid(refer_to, current.chan1, refer_to_context)) { 24355 sip_pvt_lock(p); 24356 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 24357 p->refer->status = REFER_200OK; 24358 append_history(p, "Xfer", "REFER to call parking."); 24359 sip_pvt_unlock(p); 24360 24361 ast_manager_event_multichan(EVENT_FLAG_CALL, "Transfer", 2, chans, 24362 "TransferMethod: SIP\r\n" 24363 "TransferType: Blind\r\n" 24364 "Channel: %s\r\n" 24365 "Uniqueid: %s\r\n" 24366 "SIP-Callid: %s\r\n" 24367 "TargetChannel: %s\r\n" 24368 "TargetUniqueid: %s\r\n" 24369 "TransferExten: %s\r\n" 24370 "Transfer2Parking: Yes\r\n", 24371 current.chan1->name, 24372 current.chan1->uniqueid, 24373 callid, 24374 current.chan2->name, 24375 current.chan2->uniqueid, 24376 refer_to); 24377 24378 if (sipdebug) { 24379 ast_debug(4, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name); 24380 } 24381 24382 /* DO NOT hold any locks while calling sip_park */ 24383 if (sip_park(current.chan2, current.chan1, req, seqno, refer_to, refer_to_context)) { 24384 sip_pvt_lock(p); 24385 transmit_notify_with_sipfrag(p, seqno, "500 Internal Server Error", TRUE); 24386 } else { 24387 sip_pvt_lock(p); 24388 } 24389 goto handle_refer_cleanup; 24390 } 24391 24392 /* Blind transfers and remote attended xfers. 24393 * Locks should not be held while calling pbx_builtin_setvar_helper. This function 24394 * locks the channel being passed into it.*/ 24395 if (current.chan1 && current.chan2) { 24396 ast_debug(3, "chan1->name: %s\n", current.chan1->name); 24397 pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name); 24398 } 24399 24400 if (current.chan2) { 24401 pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name); 24402 pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", refer_to_domain); 24403 pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes"); 24404 /* One for the new channel */ 24405 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes"); 24406 /* Attended transfer to remote host, prepare headers for the INVITE */ 24407 if (!ast_strlen_zero(referred_by)) { 24408 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", referred_by); 24409 } 24410 } 24411 24412 sip_pvt_lock(p); 24413 /* Generate a Replaces string to be used in the INVITE during attended transfer */ 24414 if (!ast_strlen_zero(p->refer->replaces_callid)) { 24415 char tempheader[SIPBUFSIZE]; 24416 snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid, 24417 p->refer->replaces_callid_totag ? ";to-tag=" : "", 24418 p->refer->replaces_callid_totag, 24419 p->refer->replaces_callid_fromtag ? ";from-tag=" : "", 24420 p->refer->replaces_callid_fromtag); 24421 24422 if (current.chan2) { 24423 sip_pvt_unlock(p); 24424 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader); 24425 sip_pvt_lock(p); 24426 } 24427 } 24428 24429 /* Connect the call */ 24430 24431 /* FAKE ringing if not attended transfer */ 24432 if (!p->refer->attendedtransfer) { 24433 transmit_notify_with_sipfrag(p, seqno, "180 Ringing", FALSE); 24434 } 24435 24436 /* For blind transfer, this will lead to a new call */ 24437 /* For attended transfer to remote host, this will lead to 24438 a new SIP call with a replaces header, if the dial plan allows it 24439 */ 24440 if (!current.chan2) { 24441 /* We have no bridge, so we're talking with Asterisk somehow */ 24442 /* We need to masquerade this call */ 24443 /* What to do to fix this situation: 24444 * Set up the new call in a new channel 24445 * Let the new channel masq into this channel 24446 Please add that code here :-) 24447 */ 24448 p->refer->status = REFER_FAILED; 24449 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE); 24450 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 24451 append_history(p, "Xfer", "Refer failed (only bridged calls)."); 24452 res = -1; 24453 goto handle_refer_cleanup; 24454 } 24455 ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 24456 24457 /* Do not hold the pvt lock during the indicate and async_goto. Those functions 24458 * lock channels which will invalidate locking order if the pvt lock is held.*/ 24459 /* For blind transfers, move the call to the new extensions. For attended transfers on multiple 24460 * servers - generate an INVITE with Replaces. Either way, let the dial plan decided 24461 * indicate before masquerade so the indication actually makes it to the real channel 24462 * when using local channels with MOH passthru */ 24463 sip_pvt_unlock(p); 24464 ast_indicate(current.chan2, AST_CONTROL_UNHOLD); 24465 res = ast_async_goto(current.chan2, refer_to_context, refer_to, 1); 24466 24467 if (!res) { 24468 ast_manager_event_multichan(EVENT_FLAG_CALL, "Transfer", 2, chans, 24469 "TransferMethod: SIP\r\n" 24470 "TransferType: Blind\r\n" 24471 "Channel: %s\r\n" 24472 "Uniqueid: %s\r\n" 24473 "SIP-Callid: %s\r\n" 24474 "TargetChannel: %s\r\n" 24475 "TargetUniqueid: %s\r\n" 24476 "TransferExten: %s\r\n" 24477 "TransferContext: %s\r\n", 24478 current.chan1->name, 24479 current.chan1->uniqueid, 24480 callid, 24481 current.chan2->name, 24482 current.chan2->uniqueid, 24483 refer_to, 24484 refer_to_context); 24485 /* Success - we have a new channel */ 24486 ast_debug(3, "%s transfer succeeded. Telling transferer.\n", attendedtransfer? "Attended" : "Blind"); 24487 24488 /* XXX - what to we put in CEL 'extra' for attended transfers to external systems? NULL for now */ 24489 ast_channel_lock(current.chan1); 24490 ast_cel_report_event(current.chan1, p->refer->attendedtransfer? AST_CEL_ATTENDEDTRANSFER : AST_CEL_BLINDTRANSFER, NULL, p->refer->attendedtransfer ? NULL : p->refer->refer_to, current.chan2); 24491 ast_channel_unlock(current.chan1); 24492 24493 sip_pvt_lock(p); 24494 transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE); 24495 if (p->refer->localtransfer) { 24496 p->refer->status = REFER_200OK; 24497 } 24498 if (p->owner) { 24499 p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING; 24500 } 24501 append_history(p, "Xfer", "Refer succeeded."); 24502 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 24503 /* Do not hangup call, the other side do that when we say 200 OK */ 24504 /* We could possibly implement a timer here, auto congestion */ 24505 res = 0; 24506 } else { 24507 sip_pvt_lock(p); 24508 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */ 24509 ast_debug(3, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 24510 append_history(p, "Xfer", "Refer failed."); 24511 /* Failure of some kind */ 24512 p->refer->status = REFER_FAILED; 24513 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE); 24514 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 24515 res = -1; 24516 } 24517 24518 handle_refer_cleanup: 24519 if (current.chan1) { 24520 ast_channel_unref(current.chan1); 24521 } 24522 if (current.chan2) { 24523 ast_channel_unref(current.chan2); 24524 } 24525 24526 /* Make sure we exit with the pvt locked */ 24527 return res; 24528 }
| static int handle_request_register | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| struct ast_sockaddr * | sin, | |||
| const char * | e | |||
| ) | [static] |
Handle incoming REGISTER request.
Definition at line 25727 of file chan_sip.c.
References append_history, ast_debug, ast_log(), ast_sockaddr_stringify(), check_via(), copy_request(), get_header(), LOG_NOTICE, LOG_WARNING, register_verify(), sip_methods, sip_scheddestroy(), and cfsip_methods::text.
Referenced by handle_incoming().
25728 { 25729 enum check_auth_result res; 25730 25731 /* If this is not the intial request, and the initial request isn't 25732 * a register, something screwy happened, so bail */ 25733 if (p->initreq.headers && p->initreq.method != SIP_REGISTER) { 25734 ast_log(LOG_WARNING, "Ignoring spurious REGISTER with Call-ID: %s\n", p->callid); 25735 return -1; 25736 } 25737 25738 /* Use this as the basis */ 25739 copy_request(&p->initreq, req); 25740 if (sipdebug) 25741 ast_debug(4, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid); 25742 check_via(p, req); 25743 if ((res = register_verify(p, addr, req, e)) < 0) { 25744 const char *reason; 25745 25746 switch (res) { 25747 case AUTH_SECRET_FAILED: 25748 reason = "Wrong password"; 25749 break; 25750 case AUTH_USERNAME_MISMATCH: 25751 reason = "Username/auth name mismatch"; 25752 break; 25753 case AUTH_NOT_FOUND: 25754 reason = "No matching peer found"; 25755 break; 25756 case AUTH_UNKNOWN_DOMAIN: 25757 reason = "Not a local domain"; 25758 break; 25759 case AUTH_PEER_NOT_DYNAMIC: 25760 reason = "Peer is not supposed to register"; 25761 break; 25762 case AUTH_ACL_FAILED: 25763 reason = "Device does not match ACL"; 25764 break; 25765 case AUTH_BAD_TRANSPORT: 25766 reason = "Device not configured to use this transport type"; 25767 break; 25768 default: 25769 reason = "Unknown failure"; 25770 break; 25771 } 25772 ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n", 25773 get_header(req, "To"), ast_sockaddr_stringify(addr), 25774 reason); 25775 append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason); 25776 } else { 25777 req->authenticated = 1; 25778 append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To")); 25779 } 25780 25781 if (res < 1) { 25782 /* Destroy the session, but keep us around for just a bit in case they don't 25783 get our 200 OK */ 25784 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 25785 } 25786 return res; 25787 }
| static int handle_request_subscribe | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| struct ast_sockaddr * | addr, | |||
| uint32_t | seqno, | |||
| const char * | e | |||
| ) | [static] |
Handle incoming SUBSCRIBE request.
Definition at line 25343 of file chan_sip.c.
References __get_header(), add_peer_mwi_subs(), ao2_lock, ao2_unlock, append_history, ast_debug, ast_extension_state(), ast_extension_state2str(), ast_extension_state_add_destroy(), ast_extension_state_del(), AST_LIST_EMPTY, ast_log(), ast_set_flag, ast_sockaddr_stringify(), ast_string_field_build, ast_strlen_zero(), ast_test_flag, ast_verbose, build_contact(), build_route(), cb_extensionstate(), cb_extensionstate_destroy(), check_user_full(), check_via(), copy_request(), dialog_unlink_all(), FALSE, get_destination(), get_header(), gettag(), handle_cc_subscribe(), LOG_DEBUG, LOG_NOTICE, LOG_WARNING, make_our_tag(), MAX, NONE, option_debug, parse_ok_contact(), pvt_set_needdestroy(), ref_peer(), S_OR, set_pvt_allowed_methods(), sip_cancel_destroy(), sip_cfg, sip_methods, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), sip_send_mwi_to_peer(), cfsip_methods::text, transmit_response(), transmit_response_with_minexpires(), transmit_state_notify(), and unref_peer().
Referenced by handle_incoming().
25344 { 25345 int gotdest = 0; 25346 int res = 0; 25347 int firststate; 25348 struct sip_peer *authpeer = NULL; 25349 const char *eventheader = get_header(req, "Event"); /* Get Event package name */ 25350 int resubscribe = (p->subscribed != NONE) && !req->ignore; 25351 char *event_end; 25352 ptrdiff_t event_len = 0; 25353 25354 if (p->initreq.headers) { 25355 /* We already have a dialog */ 25356 if (p->initreq.method != SIP_SUBSCRIBE) { 25357 /* This is a SUBSCRIBE within another SIP dialog, which we do not support */ 25358 /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */ 25359 transmit_response(p, "403 Forbidden (within dialog)", req); 25360 /* Do not destroy session, since we will break the call if we do */ 25361 ast_debug(1, "Got a subscription within the context of another call, can't handle that - %s (Method %s)\n", p->callid, sip_methods[p->initreq.method].text); 25362 return 0; 25363 } else if (req->debug) { 25364 if (resubscribe) 25365 ast_debug(1, "Got a re-subscribe on existing subscription %s\n", p->callid); 25366 else 25367 ast_debug(1, "Got a new subscription %s (possibly with auth) or retransmission\n", p->callid); 25368 } 25369 } 25370 25371 /* Check if we have a global disallow setting on subscriptions. 25372 if so, we don't have to check peer settings after auth, which saves a lot of processing 25373 */ 25374 if (!sip_cfg.allowsubscribe) { 25375 transmit_response(p, "403 Forbidden (policy)", req); 25376 pvt_set_needdestroy(p, "forbidden"); 25377 return 0; 25378 } 25379 25380 if (!req->ignore && !resubscribe) { /* Set up dialog, new subscription */ 25381 const char *to = get_header(req, "To"); 25382 char totag[128]; 25383 set_pvt_allowed_methods(p, req); 25384 25385 /* Check to see if a tag was provided, if so this is actually a resubscription of a dialog we no longer know about */ 25386 if (!ast_strlen_zero(to) && gettag(req, "To", totag, sizeof(totag))) { 25387 if (req->debug) 25388 ast_verbose("Received resubscription for a dialog we no longer know about. Telling remote side to subscribe again.\n"); 25389 transmit_response(p, "481 Subscription does not exist", req); 25390 pvt_set_needdestroy(p, "subscription does not exist"); 25391 return 0; 25392 } 25393 25394 /* Use this as the basis */ 25395 if (req->debug) 25396 ast_verbose("Creating new subscription\n"); 25397 25398 copy_request(&p->initreq, req); 25399 if (sipdebug) 25400 ast_debug(4, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid); 25401 check_via(p, req); 25402 build_route(p, req, 0, 0); 25403 } else if (req->debug && req->ignore) 25404 ast_verbose("Ignoring this SUBSCRIBE request\n"); 25405 25406 /* Find parameters to Event: header value and remove them for now */ 25407 if (ast_strlen_zero(eventheader)) { 25408 transmit_response(p, "489 Bad Event", req); 25409 ast_debug(2, "Received SIP subscribe for unknown event package: <none>\n"); 25410 pvt_set_needdestroy(p, "unknown event package in subscribe"); 25411 return 0; 25412 } 25413 25414 event_end = strchr(eventheader, ';'); 25415 if (event_end) { 25416 event_len = event_end - eventheader; 25417 } 25418 25419 /* Handle authentication if we're new and not a retransmission. We can't just 25420 * use if !req->ignore, because then we'll end up sending 25421 * a 200 OK if someone retransmits without sending auth */ 25422 if (p->subscribed == NONE || resubscribe) { 25423 res = check_user_full(p, req, SIP_SUBSCRIBE, e, XMIT_UNRELIABLE, addr, &authpeer); 25424 25425 /* if an authentication response was sent, we are done here */ 25426 if (res == AUTH_CHALLENGE_SENT) /* authpeer = NULL here */ 25427 return 0; 25428 if (res != AUTH_SUCCESSFUL) { 25429 ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From")); 25430 transmit_response(p, "403 Forbidden", req); 25431 25432 pvt_set_needdestroy(p, "authentication failed"); 25433 return 0; 25434 } 25435 } 25436 25437 /* At this point, we hold a reference to authpeer (if not NULL). It 25438 * must be released when done. 25439 */ 25440 25441 /* Check if this device is allowed to subscribe at all */ 25442 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) { 25443 transmit_response(p, "403 Forbidden (policy)", req); 25444 pvt_set_needdestroy(p, "subscription not allowed"); 25445 if (authpeer) { 25446 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 1)"); 25447 } 25448 return 0; 25449 } 25450 25451 if (strncmp(eventheader, "message-summary", MAX(event_len, 15)) && strncmp(eventheader, "call-completion", MAX(event_len, 15))) { 25452 /* Get destination right away */ 25453 gotdest = get_destination(p, NULL, NULL); 25454 } 25455 25456 /* Get full contact header - this needs to be used as a request URI in NOTIFY's */ 25457 parse_ok_contact(p, req); 25458 25459 build_contact(p); 25460 if (gotdest != SIP_GET_DEST_EXTEN_FOUND) { 25461 if (gotdest == SIP_GET_DEST_INVALID_URI) { 25462 transmit_response(p, "416 Unsupported URI scheme", req); 25463 } else { 25464 transmit_response(p, "404 Not Found", req); 25465 } 25466 pvt_set_needdestroy(p, "subscription target not found"); 25467 if (authpeer) { 25468 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 2)"); 25469 } 25470 return 0; 25471 } 25472 25473 /* Initialize tag for new subscriptions */ 25474 if (ast_strlen_zero(p->tag)) 25475 make_our_tag(p); 25476 25477 if (!strncmp(eventheader, "presence", MAX(event_len, 8)) || !strncmp(eventheader, "dialog", MAX(event_len, 6))) { /* Presence, RFC 3842 */ 25478 unsigned int pidf_xml; 25479 const char *accept; 25480 int start = 0; 25481 enum subscriptiontype subscribed = NONE; 25482 const char *unknown_acceptheader = NULL; 25483 25484 /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */ 25485 accept = __get_header(req, "Accept", &start); 25486 while ((subscribed == NONE) && !ast_strlen_zero(accept)) { 25487 pidf_xml = strstr(accept, "application/pidf+xml") ? 1 : 0; 25488 25489 /* Older versions of Polycom firmware will claim pidf+xml, but really 25490 * they only support xpidf+xml. */ 25491 if (pidf_xml && strstr(p->useragent, "Polycom")) { 25492 subscribed = XPIDF_XML; 25493 } else if (pidf_xml) { 25494 subscribed = PIDF_XML; /* RFC 3863 format */ 25495 } else if (strstr(accept, "application/dialog-info+xml")) { 25496 subscribed = DIALOG_INFO_XML; 25497 /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */ 25498 } else if (strstr(accept, "application/cpim-pidf+xml")) { 25499 subscribed = CPIM_PIDF_XML; /* RFC 3863 format */ 25500 } else if (strstr(accept, "application/xpidf+xml")) { 25501 subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */ 25502 } else { 25503 unknown_acceptheader = accept; 25504 } 25505 /* check to see if there is another Accept header present */ 25506 accept = __get_header(req, "Accept", &start); 25507 } 25508 25509 if (!start) { 25510 if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */ 25511 transmit_response(p, "489 Bad Event", req); 25512 ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: " 25513 "stateid: %d, laststate: %d, dialogver: %u, subscribecont: " 25514 "'%s', subscribeuri: '%s'\n", 25515 p->stateid, 25516 p->laststate, 25517 p->dialogver, 25518 p->subscribecontext, 25519 p->subscribeuri); 25520 pvt_set_needdestroy(p, "no Accept header"); 25521 if (authpeer) { 25522 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 2)"); 25523 } 25524 return 0; 25525 } 25526 /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least. 25527 so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */ 25528 } else if (subscribed == NONE) { 25529 /* Can't find a format for events that we know about */ 25530 char mybuf[200]; 25531 if (!ast_strlen_zero(unknown_acceptheader)) { 25532 snprintf(mybuf, sizeof(mybuf), "489 Bad Event (format %s)", unknown_acceptheader); 25533 } else { 25534 snprintf(mybuf, sizeof(mybuf), "489 Bad Event"); 25535 } 25536 transmit_response(p, mybuf, req); 25537 ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format:" 25538 "'%s' pvt: subscribed: %d, stateid: %d, laststate: %d," 25539 "dialogver: %u, subscribecont: '%s', subscribeuri: '%s'\n", 25540 unknown_acceptheader, 25541 (int)p->subscribed, 25542 p->stateid, 25543 p->laststate, 25544 p->dialogver, 25545 p->subscribecontext, 25546 p->subscribeuri); 25547 pvt_set_needdestroy(p, "unrecognized format"); 25548 if (authpeer) { 25549 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 2)"); 25550 } 25551 return 0; 25552 } else { 25553 p->subscribed = subscribed; 25554 } 25555 } else if (!strncmp(eventheader, "message-summary", MAX(event_len, 15))) { 25556 int start = 0; 25557 int found_supported = 0; 25558 const char *acceptheader; 25559 25560 acceptheader = __get_header(req, "Accept", &start); 25561 while (!found_supported && !ast_strlen_zero(acceptheader)) { 25562 found_supported = strcmp(acceptheader, "application/simple-message-summary") ? 0 : 1; 25563 if (!found_supported && (option_debug > 2)) { 25564 ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", acceptheader); 25565 } 25566 acceptheader = __get_header(req, "Accept", &start); 25567 } 25568 if (start && !found_supported) { 25569 /* Format requested that we do not support */ 25570 transmit_response(p, "406 Not Acceptable", req); 25571 ast_debug(2, "Received SIP mailbox subscription for unknown format: %s\n", acceptheader); 25572 pvt_set_needdestroy(p, "unknown format"); 25573 if (authpeer) { 25574 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 3)"); 25575 } 25576 return 0; 25577 } 25578 /* Looks like they actually want a mailbox status 25579 This version of Asterisk supports mailbox subscriptions 25580 The subscribed URI needs to exist in the dial plan 25581 In most devices, this is configurable to the voicemailmain extension you use 25582 */ 25583 if (!authpeer || AST_LIST_EMPTY(&authpeer->mailboxes)) { 25584 if (!authpeer) { 25585 transmit_response(p, "404 Not found", req); 25586 } else { 25587 transmit_response(p, "404 Not found (no mailbox)", req); 25588 ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", S_OR(authpeer->name, "")); 25589 } 25590 pvt_set_needdestroy(p, "received 404 response"); 25591 if (authpeer) { 25592 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 3)"); 25593 } 25594 return 0; 25595 } 25596 25597 p->subscribed = MWI_NOTIFICATION; 25598 if (ast_test_flag(&authpeer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY)) { 25599 ao2_unlock(p); 25600 add_peer_mwi_subs(authpeer); 25601 ao2_lock(p); 25602 } 25603 if (authpeer->mwipvt != p) { /* Destroy old PVT if this is a new one */ 25604 /* We only allow one subscription per peer */ 25605 if (authpeer->mwipvt) { 25606 dialog_unlink_all(authpeer->mwipvt); 25607 authpeer->mwipvt = dialog_unref(authpeer->mwipvt, "unref dialog authpeer->mwipvt"); 25608 } 25609 authpeer->mwipvt = dialog_ref(p, "setting peers' mwipvt to p"); 25610 } 25611 if (p->relatedpeer != authpeer) { 25612 if (p->relatedpeer) { 25613 unref_peer(p->relatedpeer, "Unref previously stored relatedpeer ptr"); 25614 } 25615 p->relatedpeer = ref_peer(authpeer, "setting dialog's relatedpeer pointer"); 25616 } 25617 /* Do not release authpeer here */ 25618 } else if (!strncmp(eventheader, "call-completion", MAX(event_len, 15))) { 25619 handle_cc_subscribe(p, req); 25620 } else { /* At this point, Asterisk does not understand the specified event */ 25621 transmit_response(p, "489 Bad Event", req); 25622 ast_debug(2, "Received SIP subscribe for unknown event package: %s\n", eventheader); 25623 pvt_set_needdestroy(p, "unknown event package"); 25624 if (authpeer) { 25625 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 5)"); 25626 } 25627 return 0; 25628 } 25629 25630 /* Add subscription for extension state from the PBX core */ 25631 if (p->subscribed != MWI_NOTIFICATION && p->subscribed != CALL_COMPLETION && !resubscribe) { 25632 if (p->stateid != -1) { 25633 ast_extension_state_del(p->stateid, cb_extensionstate); 25634 } 25635 dialog_ref(p, "copying dialog ptr into extension state struct"); 25636 p->stateid = ast_extension_state_add_destroy(p->context, p->exten, 25637 cb_extensionstate, cb_extensionstate_destroy, p); 25638 if (p->stateid == -1) { 25639 dialog_unref(p, "copying dialog ptr into extension state struct failed"); 25640 } 25641 } 25642 25643 if (!req->ignore) { 25644 p->lastinvite = seqno; 25645 } 25646 if (!p->needdestroy) { 25647 p->expiry = atoi(get_header(req, "Expires")); 25648 25649 /* check if the requested expiry-time is within the approved limits from sip.conf */ 25650 if (p->expiry > max_expiry) { 25651 p->expiry = max_expiry; 25652 } else if (p->expiry < min_expiry && p->expiry > 0) { 25653 transmit_response_with_minexpires(p, "423 Interval too small", req); 25654 ast_log(LOG_WARNING, "Received subscription for extension \"%s\" context \"%s\" " 25655 "with Expire header less that 'minexpire' limit. Received \"Expire: %d\" min is %d\n", 25656 p->exten, p->context, p->expiry, min_expiry); 25657 pvt_set_needdestroy(p, "Expires is less that the min expires allowed."); 25658 if (authpeer) { 25659 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 6)"); 25660 } 25661 return 0; 25662 } 25663 25664 if (sipdebug) { 25665 const char *action = p->expiry > 0 ? "Adding" : "Removing"; 25666 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) { 25667 ast_debug(2, "%s subscription for mailbox notification - peer %s\n", 25668 action, p->relatedpeer->name); 25669 } else if (p->subscribed == CALL_COMPLETION) { 25670 ast_debug(2, "%s CC subscription for peer %s\n", action, p->username); 25671 } else { 25672 ast_debug(2, "%s subscription for extension %s context %s for peer %s\n", 25673 action, p->exten, p->context, p->username); 25674 } 25675 } 25676 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 25677 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 25678 if (p->expiry > 0) 25679 sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */ 25680 25681 if (p->subscribed == MWI_NOTIFICATION) { 25682 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 25683 transmit_response(p, "200 OK", req); 25684 if (p->relatedpeer) { /* Send first notification */ 25685 struct sip_peer *peer = p->relatedpeer; 25686 ref_peer(peer, "ensure a peer ref is held during MWI sending"); 25687 ao2_unlock(p); 25688 sip_send_mwi_to_peer(peer, 0); 25689 ao2_lock(p); 25690 unref_peer(peer, "release a peer ref now that MWI is sent"); 25691 } 25692 } else if (p->subscribed != CALL_COMPLETION) { 25693 sip_pvt_unlock(p); 25694 firststate = ast_extension_state(NULL, p->context, p->exten); 25695 sip_pvt_lock(p); 25696 25697 if (firststate < 0) { 25698 ast_log(LOG_NOTICE, "Got SUBSCRIBE for extension %s@%s from %s, but there is no hint for that extension.\n", p->exten, p->context, ast_sockaddr_stringify(&p->sa)); 25699 transmit_response(p, "404 Not found", req); 25700 pvt_set_needdestroy(p, "no extension for SUBSCRIBE"); 25701 if (authpeer) { 25702 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 6)"); 25703 } 25704 return 0; 25705 } 25706 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 25707 transmit_response(p, "200 OK", req); 25708 transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */ 25709 append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate)); 25710 /* hide the 'complete' exten/context in the refer_to field for later display */ 25711 ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context); 25712 /* Deleted the slow iteration of all sip dialogs to find old subscribes from this peer for exten@context */ 25713 25714 } 25715 if (!p->expiry) { 25716 pvt_set_needdestroy(p, "forcing expiration"); 25717 } 25718 } 25719 25720 if (authpeer) { 25721 unref_peer(authpeer, "unref pointer into (*authpeer)"); 25722 } 25723 return 1; 25724 }
| static int handle_request_update | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
bare-bones support for SIP UPDATE
XXX This is not even close to being RFC 3311-compliant. We don't advertise that we support the UPDATE method, so no one should ever try sending us an UPDATE anyway. However, Asterisk can send an UPDATE to change connected line information, so we need to be prepared to handle this. The way we distinguish such an UPDATE is through the X-Asterisk-rpid-update header.
Actually updating the media session may be some future work.
Definition at line 22941 of file chan_sip.c.
References ast_channel_queue_connected_line_update(), AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, ast_party_connected_line_init(), ast_strlen_zero(), connected, get_header(), get_rpid(), ast_party_connected_line::id, ast_set_party_connected_line::id, ast_party_id::name, ast_set_party_id::name, ast_party_id::number, ast_set_party_id::number, ast_party_name::presentation, ast_party_number::presentation, ast_party_connected_line::source, ast_party_name::str, ast_party_number::str, ast_party_id::tag, transmit_response(), ast_party_name::valid, and ast_party_number::valid.
Referenced by handle_incoming().
22942 { 22943 if (ast_strlen_zero(get_header(req, "X-Asterisk-rpid-update"))) { 22944 transmit_response(p, "501 Method Not Implemented", req); 22945 return 0; 22946 } 22947 if (!p->owner) { 22948 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 22949 return 0; 22950 } 22951 if (get_rpid(p, req)) { 22952 struct ast_party_connected_line connected; 22953 struct ast_set_party_connected_line update_connected; 22954 22955 ast_party_connected_line_init(&connected); 22956 memset(&update_connected, 0, sizeof(update_connected)); 22957 22958 update_connected.id.number = 1; 22959 connected.id.number.valid = 1; 22960 connected.id.number.str = (char *) p->cid_num; 22961 connected.id.number.presentation = p->callingpres; 22962 22963 update_connected.id.name = 1; 22964 connected.id.name.valid = 1; 22965 connected.id.name.str = (char *) p->cid_name; 22966 connected.id.name.presentation = p->callingpres; 22967 22968 connected.id.tag = (char *) p->cid_tag; 22969 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER; 22970 ast_channel_queue_connected_line_update(p->owner, &connected, &update_connected); 22971 } 22972 transmit_response(p, "200 OK", req); 22973 return 0; 22974 }
| static void handle_response | ( | struct sip_pvt * | p, | |
| int | resp, | |||
| const char * | rest, | |||
| struct sip_request * | req, | |||
| uint32_t | seqno | |||
| ) | [static] |
Handle SIP response in dialogue.
Definition at line 21707 of file chan_sip.c.
References __sip_ack(), __sip_semi_ack(), append_history, AST_CC_CCBS, ast_channel_set_redirecting(), ast_clear_flag, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, ast_debug, ast_log(), ast_party_redirecting_free(), ast_party_redirecting_init(), ast_queue_control(), ast_queue_hangup_with_cause(), ast_set_flag, ast_skip_blanks(), ast_skip_nonblanks(), ast_sockaddr_stringify(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verb, ast_verbose, change_redirecting_information(), do_proxy_auth(), FALSE, find_sdp(), find_sip_method(), get_header(), gettag(), handle_response_info(), handle_response_invite(), handle_response_message(), handle_response_notify(), handle_response_peerpoke(), handle_response_publish(), handle_response_refer(), handle_response_register(), handle_response_subscribe(), handle_response_update(), hangup_sip2cause(), ast_channel::hangupcause, LOG_NOTICE, LOG_WARNING, mark_method_allowed(), mark_method_unallowed(), process_sdp(), pvt_set_needdestroy(), rh, sip_alreadygone(), sip_cancel_destroy(), sip_handle_cc(), sip_methods, stop_media_flows(), text, transmit_request(), TRUE, and update_redirecting().
Referenced by handle_incoming().
21708 { 21709 struct ast_channel *owner; 21710 int sipmethod; 21711 const char *c = get_header(req, "Cseq"); 21712 /* GCC 4.2 complains if I try to cast c as a char * when passing it to ast_skip_nonblanks, so make a copy of it */ 21713 char *c_copy = ast_strdupa(c); 21714 /* Skip the Cseq and its subsequent spaces */ 21715 const char *msg = ast_skip_blanks(ast_skip_nonblanks(c_copy)); 21716 21717 if (!msg) 21718 msg = ""; 21719 21720 sipmethod = find_sip_method(msg); 21721 21722 owner = p->owner; 21723 if (owner) { 21724 const char *rp = NULL, *rh = NULL; 21725 21726 owner->hangupcause = 0; 21727 if (ast_test_flag(&p->flags[1], SIP_PAGE2_Q850_REASON) && (rh = get_header(req, "Reason"))) { 21728 rh = ast_skip_blanks(rh); 21729 if (!strncasecmp(rh, "Q.850", 5)) { 21730 rp = strstr(rh, "cause="); 21731 if (rp && sscanf(rp + 6, "%30d", &owner->hangupcause) == 1) { 21732 owner->hangupcause &= 0x7f; 21733 if (req->debug) 21734 ast_verbose("Using Reason header for cause code: %d\n", owner->hangupcause); 21735 } 21736 } 21737 } 21738 21739 if (!owner->hangupcause) 21740 owner->hangupcause = hangup_sip2cause(resp); 21741 } 21742 21743 if (p->socket.type == SIP_TRANSPORT_UDP) { 21744 int ack_res = FALSE; 21745 21746 /* Acknowledge whatever it is destined for */ 21747 if ((resp >= 100) && (resp <= 199)) { 21748 /* NON-INVITE messages do not ack a 1XX response. RFC 3261 section 17.1.2.2 */ 21749 if (sipmethod == SIP_INVITE) { 21750 ack_res = __sip_semi_ack(p, seqno, 0, sipmethod); 21751 } 21752 } else { 21753 ack_res = __sip_ack(p, seqno, 0, sipmethod); 21754 } 21755 21756 if (ack_res == FALSE) { 21757 /* RFC 3261 13.2.2.4 and 17.1.1.2 - We must re-send ACKs to re-transmitted final responses */ 21758 if (sipmethod == SIP_INVITE && resp >= 200) { 21759 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, resp < 300 ? TRUE: FALSE); 21760 } 21761 21762 append_history(p, "Ignore", "Ignoring this retransmit\n"); 21763 return; 21764 } 21765 } 21766 21767 /* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */ 21768 if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite) { 21769 p->pendinginvite = 0; 21770 } 21771 21772 /* Get their tag if we haven't already */ 21773 if (ast_strlen_zero(p->theirtag) || (resp >= 200)) { 21774 char tag[128]; 21775 21776 gettag(req, "To", tag, sizeof(tag)); 21777 ast_string_field_set(p, theirtag, tag); 21778 } else { 21779 /* Store theirtag to track for changes when 200 responses to invites are received without SDP */ 21780 ast_string_field_set(p, theirprovtag, p->theirtag); 21781 } 21782 21783 /* This needs to be configurable on a channel/peer level, 21784 not mandatory for all communication. Sadly enough, NAT implementations 21785 are not so stable so we can always rely on these headers. 21786 Temporarily disabled, while waiting for fix. 21787 Fix assigned to Rizzo :-) 21788 */ 21789 /* check_via_response(p, req); */ 21790 21791 /* RFC 3261 Section 15 specifies that if we receive a 408 or 481 21792 * in response to a BYE, then we should end the current dialog 21793 * and session. It is known that at least one phone manufacturer 21794 * potentially will send a 404 in response to a BYE, so we'll be 21795 * liberal in what we accept and end the dialog and session if we 21796 * receive any of those responses to a BYE. 21797 */ 21798 if ((resp == 404 || resp == 408 || resp == 481) && sipmethod == SIP_BYE) { 21799 pvt_set_needdestroy(p, "received 4XX response to a BYE"); 21800 return; 21801 } 21802 21803 if (p->relatedpeer && sipmethod == SIP_OPTIONS) { 21804 /* We don't really care what the response is, just that it replied back. 21805 Well, as long as it's not a 100 response... since we might 21806 need to hang around for something more "definitive" */ 21807 if (resp != 100) 21808 handle_response_peerpoke(p, resp, req); 21809 } else if (sipmethod == SIP_REFER && resp >= 200) { 21810 handle_response_refer(p, resp, rest, req, seqno); 21811 } else if (sipmethod == SIP_PUBLISH) { 21812 /* SIP PUBLISH transcends this morass of doodoo and instead 21813 * we just always call the response handler. Good gravy! 21814 */ 21815 handle_response_publish(p, resp, rest, req, seqno); 21816 } else if (sipmethod == SIP_INFO) { 21817 /* More good gravy! */ 21818 handle_response_info(p, resp, rest, req, seqno); 21819 } else if (sipmethod == SIP_MESSAGE) { 21820 /* More good gravy! */ 21821 handle_response_message(p, resp, rest, req, seqno); 21822 } else if (sipmethod == SIP_NOTIFY) { 21823 /* The gravy train continues to roll */ 21824 handle_response_notify(p, resp, rest, req, seqno); 21825 } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 21826 switch(resp) { 21827 case 100: /* 100 Trying */ 21828 case 101: /* 101 Dialog establishment */ 21829 case 183: /* 183 Session Progress */ 21830 case 180: /* 180 Ringing */ 21831 case 182: /* 182 Queued */ 21832 case 181: /* 181 Call Is Being Forwarded */ 21833 if (sipmethod == SIP_INVITE) 21834 handle_response_invite(p, resp, rest, req, seqno); 21835 break; 21836 case 200: /* 200 OK */ 21837 p->authtries = 0; /* Reset authentication counter */ 21838 if (sipmethod == SIP_INVITE) { 21839 handle_response_invite(p, resp, rest, req, seqno); 21840 } else if (sipmethod == SIP_REGISTER) { 21841 handle_response_register(p, resp, rest, req, seqno); 21842 } else if (sipmethod == SIP_SUBSCRIBE) { 21843 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 21844 handle_response_subscribe(p, resp, rest, req, seqno); 21845 } else if (sipmethod == SIP_BYE) { /* Ok, we're ready to go */ 21846 pvt_set_needdestroy(p, "received 200 response"); 21847 ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 21848 } 21849 break; 21850 case 401: /* Not www-authorized on SIP method */ 21851 case 407: /* Proxy auth required */ 21852 if (sipmethod == SIP_INVITE) 21853 handle_response_invite(p, resp, rest, req, seqno); 21854 else if (sipmethod == SIP_SUBSCRIBE) 21855 handle_response_subscribe(p, resp, rest, req, seqno); 21856 else if (p->registry && sipmethod == SIP_REGISTER) 21857 handle_response_register(p, resp, rest, req, seqno); 21858 else if (sipmethod == SIP_UPDATE) { 21859 handle_response_update(p, resp, rest, req, seqno); 21860 } else if (sipmethod == SIP_BYE) { 21861 if (p->options) 21862 p->options->auth_type = resp; 21863 if (ast_strlen_zero(p->authname)) { 21864 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s but we have no matching peer!\n", 21865 msg, ast_sockaddr_stringify(&p->recv)); 21866 pvt_set_needdestroy(p, "unable to authenticate BYE"); 21867 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, resp, sipmethod, 0)) { 21868 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 21869 pvt_set_needdestroy(p, "failed to authenticate BYE"); 21870 } 21871 } else { 21872 ast_log(LOG_WARNING, "Got authentication request (%d) on %s to '%s'\n", resp, sip_methods[sipmethod].text, get_header(req, "To")); 21873 pvt_set_needdestroy(p, "received 407 response"); 21874 } 21875 break; 21876 case 403: /* Forbidden - we failed authentication */ 21877 if (sipmethod == SIP_INVITE) 21878 handle_response_invite(p, resp, rest, req, seqno); 21879 else if (sipmethod == SIP_SUBSCRIBE) 21880 handle_response_subscribe(p, resp, rest, req, seqno); 21881 else if (p->registry && sipmethod == SIP_REGISTER) 21882 handle_response_register(p, resp, rest, req, seqno); 21883 else { 21884 ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg); 21885 pvt_set_needdestroy(p, "received 403 response"); 21886 } 21887 break; 21888 case 404: /* Not found */ 21889 if (p->registry && sipmethod == SIP_REGISTER) 21890 handle_response_register(p, resp, rest, req, seqno); 21891 else if (sipmethod == SIP_INVITE) 21892 handle_response_invite(p, resp, rest, req, seqno); 21893 else if (sipmethod == SIP_SUBSCRIBE) 21894 handle_response_subscribe(p, resp, rest, req, seqno); 21895 else if (owner) 21896 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 21897 break; 21898 case 423: /* Interval too brief */ 21899 if (sipmethod == SIP_REGISTER) 21900 handle_response_register(p, resp, rest, req, seqno); 21901 break; 21902 case 408: /* Request timeout - terminate dialog */ 21903 if (sipmethod == SIP_INVITE) 21904 handle_response_invite(p, resp, rest, req, seqno); 21905 else if (sipmethod == SIP_REGISTER) 21906 handle_response_register(p, resp, rest, req, seqno); 21907 else if (sipmethod == SIP_BYE) { 21908 pvt_set_needdestroy(p, "received 408 response"); 21909 ast_debug(4, "Got timeout on bye. Thanks for the answer. Now, kill this call\n"); 21910 } else { 21911 if (owner) 21912 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 21913 pvt_set_needdestroy(p, "received 408 response"); 21914 } 21915 break; 21916 21917 case 428: 21918 case 422: /* Session-Timers: Session Interval Too Small */ 21919 if (sipmethod == SIP_INVITE) { 21920 handle_response_invite(p, resp, rest, req, seqno); 21921 } 21922 break; 21923 21924 case 481: /* Call leg does not exist */ 21925 if (sipmethod == SIP_INVITE) { 21926 handle_response_invite(p, resp, rest, req, seqno); 21927 } else if (sipmethod == SIP_SUBSCRIBE) { 21928 handle_response_subscribe(p, resp, rest, req, seqno); 21929 } else if (sipmethod == SIP_BYE) { 21930 /* The other side has no transaction to bye, 21931 just assume it's all right then */ 21932 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 21933 } else if (sipmethod == SIP_CANCEL) { 21934 /* The other side has no transaction to cancel, 21935 just assume it's all right then */ 21936 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 21937 } else { 21938 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 21939 /* Guessing that this is not an important request */ 21940 } 21941 break; 21942 case 487: 21943 if (sipmethod == SIP_INVITE) 21944 handle_response_invite(p, resp, rest, req, seqno); 21945 break; 21946 case 415: /* Unsupported media type */ 21947 case 488: /* Not acceptable here - codec error */ 21948 case 606: /* Not Acceptable */ 21949 if (sipmethod == SIP_INVITE) 21950 handle_response_invite(p, resp, rest, req, seqno); 21951 break; 21952 case 491: /* Pending */ 21953 if (sipmethod == SIP_INVITE) 21954 handle_response_invite(p, resp, rest, req, seqno); 21955 else { 21956 ast_debug(1, "Got 491 on %s, unsupported. Call ID %s\n", sip_methods[sipmethod].text, p->callid); 21957 pvt_set_needdestroy(p, "received 491 response"); 21958 } 21959 break; 21960 case 405: /* Method not allowed */ 21961 case 501: /* Not Implemented */ 21962 mark_method_unallowed(&p->allowed_methods, sipmethod); 21963 if (p->relatedpeer) { 21964 mark_method_allowed(&p->relatedpeer->disallowed_methods, sipmethod); 21965 } 21966 if (sipmethod == SIP_INVITE) 21967 handle_response_invite(p, resp, rest, req, seqno); 21968 else 21969 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_sockaddr_stringify(&p->sa), msg); 21970 break; 21971 default: 21972 if ((resp >= 300) && (resp < 700)) { 21973 /* Fatal response */ 21974 if ((resp != 487)) 21975 ast_verb(3, "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_sockaddr_stringify(&p->sa)); 21976 21977 if (sipmethod == SIP_INVITE) 21978 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 21979 21980 /* XXX Locking issues?? XXX */ 21981 switch(resp) { 21982 case 300: /* Multiple Choices */ 21983 case 301: /* Moved permanently */ 21984 case 302: /* Moved temporarily */ 21985 case 305: /* Use Proxy */ 21986 if (p->owner) { 21987 struct ast_party_redirecting redirecting; 21988 struct ast_set_party_redirecting update_redirecting; 21989 21990 ast_party_redirecting_init(&redirecting); 21991 memset(&update_redirecting, 0, sizeof(update_redirecting)); 21992 change_redirecting_information(p, req, &redirecting, 21993 &update_redirecting, TRUE); 21994 ast_channel_set_redirecting(p->owner, &redirecting, 21995 &update_redirecting); 21996 ast_party_redirecting_free(&redirecting); 21997 } 21998 /* Fall through */ 21999 case 486: /* Busy here */ 22000 case 600: /* Busy everywhere */ 22001 case 603: /* Decline */ 22002 if (p->owner) { 22003 sip_handle_cc(p, req, AST_CC_CCBS); 22004 ast_queue_control(p->owner, AST_CONTROL_BUSY); 22005 } 22006 break; 22007 case 482: /* Loop Detected */ 22008 case 480: /* Temporarily Unavailable */ 22009 case 404: /* Not Found */ 22010 case 410: /* Gone */ 22011 case 400: /* Bad Request */ 22012 case 500: /* Server error */ 22013 if (sipmethod == SIP_SUBSCRIBE) { 22014 handle_response_subscribe(p, resp, rest, req, seqno); 22015 break; 22016 } 22017 /* Fall through */ 22018 case 502: /* Bad gateway */ 22019 case 503: /* Service Unavailable */ 22020 case 504: /* Server Timeout */ 22021 if (owner) 22022 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 22023 break; 22024 case 484: /* Address Incomplete */ 22025 if (owner && sipmethod != SIP_BYE) { 22026 switch (ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) { 22027 case SIP_PAGE2_ALLOWOVERLAP_YES: 22028 ast_queue_hangup_with_cause(p->owner, hangup_sip2cause(resp)); 22029 break; 22030 default: 22031 ast_queue_hangup_with_cause(p->owner, hangup_sip2cause(404)); 22032 break; 22033 } 22034 } 22035 break; 22036 default: 22037 /* Send hangup */ 22038 if (owner && sipmethod != SIP_BYE) 22039 ast_queue_hangup_with_cause(p->owner, hangup_sip2cause(resp)); 22040 break; 22041 } 22042 /* ACK on invite */ 22043 if (sipmethod == SIP_INVITE) 22044 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 22045 sip_alreadygone(p); 22046 if (!p->owner) { 22047 pvt_set_needdestroy(p, "transaction completed"); 22048 } 22049 } else if ((resp >= 100) && (resp < 200)) { 22050 if (sipmethod == SIP_INVITE) { 22051 if (!req->ignore && sip_cancel_destroy(p)) 22052 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 22053 if (find_sdp(req)) 22054 process_sdp(p, req, SDP_T38_NONE); 22055 if (p->owner) { 22056 /* Queue a progress frame */ 22057 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 22058 } 22059 } 22060 } else 22061 ast_log(LOG_NOTICE, "Don't know how to handle a %d %s response from %s\n", resp, rest, p->owner ? p->owner->name : ast_sockaddr_stringify(&p->sa)); 22062 } 22063 } else { 22064 /* Responses to OUTGOING SIP requests on INCOMING calls 22065 get handled here. As well as out-of-call message responses */ 22066 if (req->debug) 22067 ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg); 22068 22069 if (sipmethod == SIP_INVITE && resp == 200) { 22070 /* Tags in early session is replaced by the tag in 200 OK, which is 22071 the final reply to our INVITE */ 22072 char tag[128]; 22073 22074 gettag(req, "To", tag, sizeof(tag)); 22075 ast_string_field_set(p, theirtag, tag); 22076 } 22077 22078 switch(resp) { 22079 case 200: 22080 if (sipmethod == SIP_INVITE) { 22081 handle_response_invite(p, resp, rest, req, seqno); 22082 } else if (sipmethod == SIP_CANCEL) { 22083 ast_debug(1, "Got 200 OK on CANCEL\n"); 22084 22085 /* Wait for 487, then destroy */ 22086 } else if (sipmethod == SIP_BYE) { 22087 pvt_set_needdestroy(p, "transaction completed"); 22088 } 22089 break; 22090 case 401: /* www-auth */ 22091 case 407: 22092 if (sipmethod == SIP_INVITE) 22093 handle_response_invite(p, resp, rest, req, seqno); 22094 else if (sipmethod == SIP_BYE) { 22095 if (p->authtries == MAX_AUTHTRIES || do_proxy_auth(p, req, resp, sipmethod, 0)) { 22096 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 22097 pvt_set_needdestroy(p, "failed to authenticate BYE"); 22098 } 22099 } 22100 break; 22101 case 481: /* Call leg does not exist */ 22102 if (sipmethod == SIP_INVITE) { 22103 /* Re-invite failed */ 22104 handle_response_invite(p, resp, rest, req, seqno); 22105 } else if (sipmethod == SIP_BYE) { 22106 pvt_set_needdestroy(p, "received 481 response"); 22107 } else if (sipdebug) { 22108 ast_debug(1, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid); 22109 } 22110 break; 22111 case 501: /* Not Implemented */ 22112 if (sipmethod == SIP_INVITE) 22113 handle_response_invite(p, resp, rest, req, seqno); 22114 break; 22115 default: /* Errors without handlers */ 22116 if ((resp >= 100) && (resp < 200)) { 22117 if (sipmethod == SIP_INVITE) { /* re-invite */ 22118 if (!req->ignore && sip_cancel_destroy(p)) 22119 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 22120 } 22121 } 22122 if ((resp >= 300) && (resp < 700)) { 22123 if ((resp != 487)) 22124 ast_verb(3, "Incoming call: Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_sockaddr_stringify(&p->sa)); 22125 switch(resp) { 22126 case 415: /* Unsupported media type */ 22127 case 488: /* Not acceptable here - codec error */ 22128 case 603: /* Decline */ 22129 case 500: /* Server error */ 22130 case 502: /* Bad gateway */ 22131 case 503: /* Service Unavailable */ 22132 case 504: /* Server timeout */ 22133 22134 /* re-invite failed */ 22135 if (sipmethod == SIP_INVITE && sip_cancel_destroy(p)) 22136 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 22137 break; 22138 } 22139 } 22140 break; 22141 } 22142 } 22143 }
| static void handle_response_info | ( | struct sip_pvt * | p, | |
| int | resp, | |||
| const char * | rest, | |||
| struct sip_request * | req, | |||
| uint32_t | seqno | |||
| ) | [static] |
Definition at line 21621 of file chan_sip.c.
References ast_log(), ast_sockaddr_stringify(), ast_verb, LOG_WARNING, mark_method_allowed(), mark_method_unallowed(), sip_methods, text, and cfsip_methods::text.
Referenced by handle_response().
21622 { 21623 int sipmethod = SIP_INFO; 21624 21625 switch (resp) { 21626 case 401: /* Not www-authorized on SIP method */ 21627 case 407: /* Proxy auth required */ 21628 ast_log(LOG_WARNING, "Host '%s' requests authentication (%d) for '%s'\n", 21629 ast_sockaddr_stringify(&p->sa), resp, sip_methods[sipmethod].text); 21630 break; 21631 case 405: /* Method not allowed */ 21632 case 501: /* Not Implemented */ 21633 mark_method_unallowed(&p->allowed_methods, sipmethod); 21634 if (p->relatedpeer) { 21635 mark_method_allowed(&p->relatedpeer->disallowed_methods, sipmethod); 21636 } 21637 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", 21638 ast_sockaddr_stringify(&p->sa), sip_methods[sipmethod].text); 21639 break; 21640 default: 21641 if (300 <= resp && resp < 700) { 21642 ast_verb(3, "Got SIP %s response %d \"%s\" back from host '%s'\n", 21643 sip_methods[sipmethod].text, resp, rest, ast_sockaddr_stringify(&p->sa)); 21644 } 21645 break; 21646 } 21647 }
| static void handle_response_invite | ( | struct sip_pvt * | p, | |
| int | resp, | |||
| const char * | rest, | |||
| struct sip_request * | req, | |||
| uint32_t | seqno | |||
| ) | [static] |
Handle SIP response to INVITE dialogue.
Definition at line 20691 of file chan_sip.c.
References append_history, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_NORMAL_CLEARING, AST_CC_CCNR, ast_channel_queue_connected_line_update(), ast_channel_queue_redirecting_update(), AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER, AST_CONTROL_ANSWER, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_UPDATE_RTP_PEER, ast_debug, ast_log(), ast_null_frame, ast_party_connected_line_init(), ast_party_redirecting_free(), ast_party_redirecting_init(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, ast_queue_control(), ast_queue_frame(), ast_queue_hangup_with_cause(), ast_random(), ast_rtp_instance_activate(), ast_rtp_instance_get_remote_address(), ast_sched_add(), AST_SCHED_DEL_UNREF, ast_set_flag, ast_setstate(), ast_sockaddr_isnull(), AST_STATE_RINGING, AST_STATE_UP, ast_string_field_set, ast_strlen_zero(), ast_test_flag, build_route(), change_redirecting_information(), change_t38_state(), check_pendings(), connected, do_proxy_auth(), EVENT_FLAG_SYSTEM, FALSE, find_sdp(), get_header(), get_rpid(), hangup_sip2cause(), ast_party_connected_line::id, ast_set_party_connected_line::id, LOG_NOTICE, LOG_WARNING, manager_event, ast_party_id::name, ast_set_party_id::name, ast_party_id::number, ast_set_party_id::number, parse_ok_contact(), parse_session_expires(), ast_party_name::presentation, ast_party_number::presentation, proc_422_rsp(), process_sdp(), pvt_set_needdestroy(), set_address_from_contact(), set_pvt_allowed_methods(), sip_alreadygone(), sip_cancel_destroy(), sip_cfg, sip_handle_cc(), sip_queue_hangup_cause(), sip_reinvite_retry(), sip_scheddestroy(), ast_party_connected_line::source, st_get_mode(), st_get_se(), start_session_timer(), ast_party_name::str, ast_party_number::str, ast_party_id::tag, transmit_reinvite_with_sdp(), transmit_request(), TRUE, update_call_counter(), update_redirecting(), ast_party_name::valid, and ast_party_number::valid.
Referenced by handle_response().
20692 { 20693 int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING); 20694 int res = 0; 20695 int xmitres = 0; 20696 int reinvite = ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 20697 char *p_hdrval; 20698 int rtn; 20699 struct ast_party_connected_line connected; 20700 struct ast_set_party_connected_line update_connected; 20701 20702 if (reinvite) 20703 ast_debug(4, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid); 20704 else 20705 ast_debug(4, "SIP response %d to standard invite\n", resp); 20706 20707 if (p->alreadygone) { /* This call is already gone */ 20708 ast_debug(1, "Got response on call that is already terminated: %s (ignoring)\n", p->callid); 20709 return; 20710 } 20711 20712 /* Acknowledge sequence number - This only happens on INVITE from SIP-call */ 20713 /* Don't auto congest anymore since we've gotten something useful back */ 20714 AST_SCHED_DEL_UNREF(sched, p->initid, dialog_unref(p, "when you delete the initid sched, you should dec the refcount for the stored dialog ptr")); 20715 20716 /* RFC3261 says we must treat every 1xx response (but not 100) 20717 that we don't recognize as if it was 183. 20718 */ 20719 if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 181 && resp != 182 && resp != 183) 20720 resp = 183; 20721 20722 /* Any response between 100 and 199 is PROCEEDING */ 20723 if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING) 20724 p->invitestate = INV_PROCEEDING; 20725 20726 /* Final response, not 200 ? */ 20727 if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA )) 20728 p->invitestate = INV_COMPLETED; 20729 20730 if ((resp >= 200 && reinvite)) { 20731 p->ongoing_reinvite = 0; 20732 if (p->reinviteid > -1) { 20733 AST_SCHED_DEL_UNREF(sched, p->reinviteid, dialog_unref(p, "unref dialog for reinvite timeout because of a final response")); 20734 } 20735 } 20736 20737 /* Final response, clear out pending invite */ 20738 if ((resp == 200 || resp >= 300) && p->pendinginvite && seqno == p->pendinginvite) { 20739 p->pendinginvite = 0; 20740 } 20741 20742 /* If this is a response to our initial INVITE, we need to set what we can use 20743 * for this peer. 20744 */ 20745 if (!reinvite) { 20746 set_pvt_allowed_methods(p, req); 20747 } 20748 20749 switch (resp) { 20750 case 100: /* Trying */ 20751 case 101: /* Dialog establishment */ 20752 if (!req->ignore && p->invitestate != INV_CANCELLED && sip_cancel_destroy(p)) 20753 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 20754 check_pendings(p); 20755 break; 20756 20757 case 180: /* 180 Ringing */ 20758 case 182: /* 182 Queued */ 20759 if (!req->ignore && p->invitestate != INV_CANCELLED && sip_cancel_destroy(p)) 20760 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 20761 /* Store Route-set from provisional SIP responses so 20762 * early-dialog request can be routed properly 20763 * */ 20764 parse_ok_contact(p, req); 20765 if (!reinvite) { 20766 build_route(p, req, 1, resp); 20767 } 20768 if (!req->ignore && p->owner) { 20769 if (get_rpid(p, req)) { 20770 /* Queue a connected line update */ 20771 ast_party_connected_line_init(&connected); 20772 memset(&update_connected, 0, sizeof(update_connected)); 20773 20774 update_connected.id.number = 1; 20775 connected.id.number.valid = 1; 20776 connected.id.number.str = (char *) p->cid_num; 20777 connected.id.number.presentation = p->callingpres; 20778 20779 update_connected.id.name = 1; 20780 connected.id.name.valid = 1; 20781 connected.id.name.str = (char *) p->cid_name; 20782 connected.id.name.presentation = p->callingpres; 20783 20784 connected.id.tag = (char *) p->cid_tag; 20785 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; 20786 ast_channel_queue_connected_line_update(p->owner, &connected, 20787 &update_connected); 20788 } 20789 sip_handle_cc(p, req, AST_CC_CCNR); 20790 ast_queue_control(p->owner, AST_CONTROL_RINGING); 20791 if (p->owner->_state != AST_STATE_UP) { 20792 ast_setstate(p->owner, AST_STATE_RINGING); 20793 } 20794 } 20795 if (find_sdp(req)) { 20796 if (p->invitestate != INV_CANCELLED) 20797 p->invitestate = INV_EARLY_MEDIA; 20798 res = process_sdp(p, req, SDP_T38_NONE); 20799 if (!req->ignore && p->owner) { 20800 /* Queue a progress frame only if we have SDP in 180 or 182 */ 20801 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 20802 } 20803 ast_rtp_instance_activate(p->rtp); 20804 } 20805 check_pendings(p); 20806 break; 20807 20808 case 181: /* Call Is Being Forwarded */ 20809 if (!req->ignore && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 20810 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 20811 /* Store Route-set from provisional SIP responses so 20812 * early-dialog request can be routed properly 20813 * */ 20814 parse_ok_contact(p, req); 20815 if (!reinvite) { 20816 build_route(p, req, 1, resp); 20817 } 20818 if (!req->ignore && p->owner) { 20819 struct ast_party_redirecting redirecting; 20820 struct ast_set_party_redirecting update_redirecting; 20821 20822 ast_party_redirecting_init(&redirecting); 20823 memset(&update_redirecting, 0, sizeof(update_redirecting)); 20824 change_redirecting_information(p, req, &redirecting, &update_redirecting, 20825 FALSE); 20826 ast_channel_queue_redirecting_update(p->owner, &redirecting, 20827 &update_redirecting); 20828 ast_party_redirecting_free(&redirecting); 20829 sip_handle_cc(p, req, AST_CC_CCNR); 20830 } 20831 check_pendings(p); 20832 break; 20833 20834 case 183: /* Session progress */ 20835 if (!req->ignore && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 20836 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 20837 /* Store Route-set from provisional SIP responses so 20838 * early-dialog request can be routed properly 20839 * */ 20840 parse_ok_contact(p, req); 20841 if (!reinvite) { 20842 build_route(p, req, 1, resp); 20843 } 20844 if (!req->ignore && p->owner) { 20845 if (get_rpid(p, req)) { 20846 /* Queue a connected line update */ 20847 ast_party_connected_line_init(&connected); 20848 memset(&update_connected, 0, sizeof(update_connected)); 20849 20850 update_connected.id.number = 1; 20851 connected.id.number.valid = 1; 20852 connected.id.number.str = (char *) p->cid_num; 20853 connected.id.number.presentation = p->callingpres; 20854 20855 update_connected.id.name = 1; 20856 connected.id.name.valid = 1; 20857 connected.id.name.str = (char *) p->cid_name; 20858 connected.id.name.presentation = p->callingpres; 20859 20860 connected.id.tag = (char *) p->cid_tag; 20861 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; 20862 ast_channel_queue_connected_line_update(p->owner, &connected, 20863 &update_connected); 20864 } 20865 sip_handle_cc(p, req, AST_CC_CCNR); 20866 } 20867 if (find_sdp(req)) { 20868 if (p->invitestate != INV_CANCELLED) 20869 p->invitestate = INV_EARLY_MEDIA; 20870 res = process_sdp(p, req, SDP_T38_NONE); 20871 if (!req->ignore && p->owner) { 20872 /* Queue a progress frame */ 20873 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 20874 } 20875 ast_rtp_instance_activate(p->rtp); 20876 } else { 20877 /* Alcatel PBXs are known to send 183s with no SDP after sending 20878 * a 100 Trying response. We're just going to treat this sort of thing 20879 * the same as we would treat a 180 Ringing 20880 */ 20881 if (!req->ignore && p->owner) { 20882 ast_queue_control(p->owner, AST_CONTROL_RINGING); 20883 } 20884 } 20885 check_pendings(p); 20886 break; 20887 20888 case 200: /* 200 OK on invite - someone's answering our call */ 20889 if (!req->ignore && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 20890 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 20891 p->authtries = 0; 20892 if (find_sdp(req)) { 20893 if ((res = process_sdp(p, req, SDP_T38_ACCEPT)) && !req->ignore) { 20894 if (!reinvite) { 20895 /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */ 20896 /* For re-invites, we try to recover */ 20897 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 20898 p->hangupcause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 20899 if (p->owner) { 20900 p->owner->hangupcause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 20901 sip_queue_hangup_cause(p, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 20902 } 20903 } 20904 } 20905 ast_rtp_instance_activate(p->rtp); 20906 } else if (!reinvite) { 20907 struct ast_sockaddr remote_address = {{0,}}; 20908 20909 ast_rtp_instance_get_remote_address(p->rtp, &remote_address); 20910 if (ast_sockaddr_isnull(&remote_address) || (!ast_strlen_zero(p->theirprovtag) && strcmp(p->theirtag, p->theirprovtag))) { 20911 ast_log(LOG_WARNING, "Received response: \"200 OK\" from '%s' without SDP\n", p->relatedpeer->name); 20912 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 20913 ast_rtp_instance_activate(p->rtp); 20914 } 20915 } 20916 20917 if (!req->ignore && p->owner) { 20918 int rpid_changed; 20919 20920 rpid_changed = get_rpid(p, req); 20921 if (rpid_changed || !reinvite) { 20922 /* Queue a connected line update */ 20923 ast_party_connected_line_init(&connected); 20924 memset(&update_connected, 0, sizeof(update_connected)); 20925 if (rpid_changed 20926 || !ast_strlen_zero(p->cid_num) 20927 || (p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) { 20928 update_connected.id.number = 1; 20929 connected.id.number.valid = 1; 20930 connected.id.number.str = (char *) p->cid_num; 20931 connected.id.number.presentation = p->callingpres; 20932 } 20933 if (rpid_changed 20934 || !ast_strlen_zero(p->cid_name) 20935 || (p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) { 20936 update_connected.id.name = 1; 20937 connected.id.name.valid = 1; 20938 connected.id.name.str = (char *) p->cid_name; 20939 connected.id.name.presentation = p->callingpres; 20940 } 20941 if (update_connected.id.number || update_connected.id.name) { 20942 connected.id.tag = (char *) p->cid_tag; 20943 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; 20944 ast_channel_queue_connected_line_update(p->owner, &connected, 20945 &update_connected); 20946 } 20947 } 20948 } 20949 20950 /* Parse contact header for continued conversation */ 20951 /* When we get 200 OK, we know which device (and IP) to contact for this call */ 20952 /* This is important when we have a SIP proxy between us and the phone */ 20953 if (outgoing) { 20954 update_call_counter(p, DEC_CALL_RINGING); 20955 parse_ok_contact(p, req); 20956 /* Save Record-Route for any later requests we make on this dialogue */ 20957 if (!reinvite) { 20958 build_route(p, req, 1, resp); 20959 } 20960 if(set_address_from_contact(p)) { 20961 /* Bad contact - we don't know how to reach this device */ 20962 /* We need to ACK, but then send a bye */ 20963 if (!p->route && !req->ignore) 20964 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 20965 } 20966 20967 } 20968 20969 if (!req->ignore && p->owner) { 20970 if (!reinvite && !res) { 20971 ast_queue_control(p->owner, AST_CONTROL_ANSWER); 20972 if (sip_cfg.callevents) 20973 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", 20974 "Channel: %s\r\nChanneltype: %s\r\nUniqueid: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\nPeername: %s\r\n", 20975 p->owner->name, "SIP", p->owner->uniqueid, p->callid, p->fullcontact, p->peername); 20976 } else { /* RE-invite */ 20977 if (p->t38.state == T38_DISABLED) { 20978 ast_queue_control(p->owner, AST_CONTROL_UPDATE_RTP_PEER); 20979 } else { 20980 ast_queue_frame(p->owner, &ast_null_frame); 20981 } 20982 } 20983 } else { 20984 /* It's possible we're getting an 200 OK after we've tried to disconnect 20985 by sending CANCEL */ 20986 /* First send ACK, then send bye */ 20987 if (!req->ignore) 20988 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 20989 } 20990 20991 /* Check for Session-Timers related headers */ 20992 if (st_get_mode(p, 0) != SESSION_TIMER_MODE_REFUSE) { 20993 p_hdrval = (char*)get_header(req, "Session-Expires"); 20994 if (!ast_strlen_zero(p_hdrval)) { 20995 /* UAS supports Session-Timers */ 20996 enum st_refresher_param st_ref_param; 20997 int tmp_st_interval = 0; 20998 rtn = parse_session_expires(p_hdrval, &tmp_st_interval, &st_ref_param); 20999 if (rtn != 0) { 21000 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 21001 } else if (tmp_st_interval < st_get_se(p, FALSE)) { 21002 ast_log(LOG_WARNING, "Got Session-Expires less than local Min-SE in 200 OK, tearing down call\n"); 21003 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 21004 } 21005 if (st_ref_param == SESSION_TIMER_REFRESHER_PARAM_UAC) { 21006 p->stimer->st_ref = SESSION_TIMER_REFRESHER_US; 21007 } else if (st_ref_param == SESSION_TIMER_REFRESHER_PARAM_UAS) { 21008 p->stimer->st_ref = SESSION_TIMER_REFRESHER_THEM; 21009 } else { 21010 ast_log(LOG_WARNING, "Unknown refresher on %s\n", p->callid); 21011 } 21012 if (tmp_st_interval) { 21013 p->stimer->st_interval = tmp_st_interval; 21014 } 21015 p->stimer->st_active = TRUE; 21016 p->stimer->st_active_peer_ua = TRUE; 21017 start_session_timer(p); 21018 } else { 21019 /* UAS doesn't support Session-Timers */ 21020 if (st_get_mode(p, 0) == SESSION_TIMER_MODE_ORIGINATE) { 21021 p->stimer->st_ref = SESSION_TIMER_REFRESHER_US; 21022 p->stimer->st_active_peer_ua = FALSE; 21023 start_session_timer(p); 21024 } 21025 } 21026 } 21027 21028 21029 /* If I understand this right, the branch is different for a non-200 ACK only */ 21030 p->invitestate = INV_TERMINATED; 21031 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 21032 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE); 21033 check_pendings(p); 21034 break; 21035 21036 case 407: /* Proxy authentication */ 21037 case 401: /* Www auth */ 21038 /* First we ACK */ 21039 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 21040 if (p->options) 21041 p->options->auth_type = resp; 21042 21043 /* Then we AUTH */ 21044 ast_string_field_set(p, theirtag, NULL); /* forget their old tag, so we don't match tags when getting response */ 21045 if (!req->ignore) { 21046 if (p->authtries < MAX_AUTHTRIES) 21047 p->invitestate = INV_CALLING; 21048 if (p->authtries == MAX_AUTHTRIES || do_proxy_auth(p, req, resp, SIP_INVITE, 1)) { 21049 ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); 21050 pvt_set_needdestroy(p, "failed to authenticate on INVITE"); 21051 sip_alreadygone(p); 21052 if (p->owner) 21053 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 21054 } 21055 } 21056 break; 21057 21058 case 403: /* Forbidden */ 21059 /* First we ACK */ 21060 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 21061 ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From")); 21062 if (!req->ignore && p->owner) { 21063 sip_queue_hangup_cause(p, hangup_sip2cause(resp)); 21064 } 21065 break; 21066 21067 case 404: /* Not found */ 21068 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 21069 if (p->owner && !req->ignore) { 21070 sip_queue_hangup_cause(p, hangup_sip2cause(resp)); 21071 } 21072 break; 21073 21074 case 481: /* Call leg does not exist */ 21075 /* Could be REFER caused INVITE with replaces */ 21076 ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid); 21077 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 21078 if (p->owner) { 21079 ast_queue_hangup_with_cause(p->owner, hangup_sip2cause(resp)); 21080 } 21081 break; 21082 21083 case 422: /* Session-Timers: Session interval too small */ 21084 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 21085 ast_string_field_set(p, theirtag, NULL); 21086 proc_422_rsp(p, req); 21087 break; 21088 21089 case 428: /* Use identity header - rfc 4474 - not supported by Asterisk yet */ 21090 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 21091 append_history(p, "Identity", "SIP identity is required. Not supported by Asterisk."); 21092 ast_log(LOG_WARNING, "SIP identity required by proxy. SIP dialog '%s'. Giving up.\n", p->callid); 21093 if (p->owner && !req->ignore) { 21094 ast_queue_hangup_with_cause(p->owner, hangup_sip2cause(resp)); 21095 } 21096 break; 21097 21098 case 487: /* Cancelled transaction */ 21099 /* We have sent CANCEL on an outbound INVITE 21100 This transaction is already scheduled to be killed by sip_hangup(). 21101 */ 21102 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 21103 if (p->owner && !req->ignore) { 21104 ast_queue_hangup_with_cause(p->owner, AST_CAUSE_NORMAL_CLEARING); 21105 append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request"); 21106 } else if (!req->ignore) { 21107 update_call_counter(p, DEC_CALL_LIMIT); 21108 append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog."); 21109 } 21110 check_pendings(p); 21111 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 21112 break; 21113 case 415: /* Unsupported media type */ 21114 case 488: /* Not acceptable here */ 21115 case 606: /* Not Acceptable */ 21116 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 21117 if (p->udptl && p->t38.state == T38_LOCAL_REINVITE) { 21118 change_t38_state(p, T38_DISABLED); 21119 /* Try to reset RTP timers */ 21120 //ast_rtp_set_rtptimers_onhold(p->rtp); 21121 21122 /* Trigger a reinvite back to audio */ 21123 transmit_reinvite_with_sdp(p, FALSE, FALSE); 21124 } else { 21125 /* We can't set up this call, so give up */ 21126 if (p->owner && !req->ignore) { 21127 ast_queue_hangup_with_cause(p->owner, hangup_sip2cause(resp)); 21128 } 21129 } 21130 break; 21131 case 491: /* Pending */ 21132 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 21133 if (p->owner && !req->ignore) { 21134 if (p->owner->_state != AST_STATE_UP) { 21135 ast_queue_hangup_with_cause(p->owner, hangup_sip2cause(resp)); 21136 } else { 21137 /* This is a re-invite that failed. */ 21138 /* Reset the flag after a while 21139 */ 21140 int wait; 21141 /* RFC 3261, if owner of call, wait between 2.1 to 4 seconds, 21142 * if not owner of call, wait 0 to 2 seconds */ 21143 if (p->outgoing_call) { 21144 wait = 2100 + ast_random() % 2000; 21145 } else { 21146 wait = ast_random() % 2000; 21147 } 21148 p->waitid = ast_sched_add(sched, wait, sip_reinvite_retry, dialog_ref(p, "passing dialog ptr into sched structure based on waitid for sip_reinvite_retry.")); 21149 ast_debug(2, "Reinvite race. Scheduled sip_reinvite_retry in %d secs in handle_response_invite (waitid %d, dialog '%s')\n", 21150 wait, p->waitid, p->callid); 21151 } 21152 } 21153 break; 21154 21155 case 408: /* Request timeout */ 21156 case 405: /* Not allowed */ 21157 case 501: /* Not implemented */ 21158 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 21159 if (p->owner) { 21160 ast_queue_hangup_with_cause(p->owner, hangup_sip2cause(resp)); 21161 } 21162 break; 21163 } 21164 if (xmitres == XMIT_ERROR) 21165 ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid); 21166 }
| static void handle_response_message | ( | struct sip_pvt * | p, | |
| int | resp, | |||
| const char * | rest, | |||
| struct sip_request * | req, | |||
| uint32_t | seqno | |||
| ) | [static] |
Definition at line 21657 of file chan_sip.c.
References ast_log(), ast_sockaddr_stringify(), ast_verb, LOG_WARNING, mark_method_allowed(), mark_method_unallowed(), sip_methods, text, and cfsip_methods::text.
Referenced by handle_response().
21658 { 21659 int sipmethod = SIP_MESSAGE; 21660 /* Out-of-dialog MESSAGE currently not supported. */ 21661 //int in_dialog = ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 21662 21663 switch (resp) { 21664 case 401: /* Not www-authorized on SIP method */ 21665 case 407: /* Proxy auth required */ 21666 ast_log(LOG_WARNING, "Host '%s' requests authentication (%d) for '%s'\n", 21667 ast_sockaddr_stringify(&p->sa), resp, sip_methods[sipmethod].text); 21668 break; 21669 case 405: /* Method not allowed */ 21670 case 501: /* Not Implemented */ 21671 mark_method_unallowed(&p->allowed_methods, sipmethod); 21672 if (p->relatedpeer) { 21673 mark_method_allowed(&p->relatedpeer->disallowed_methods, sipmethod); 21674 } 21675 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", 21676 ast_sockaddr_stringify(&p->sa), sip_methods[sipmethod].text); 21677 break; 21678 default: 21679 if (100 <= resp && resp < 200) { 21680 /* Must allow provisional responses for out-of-dialog requests. */ 21681 } else if (200 <= resp && resp < 300) { 21682 p->authtries = 0; /* Reset authentication counter */ 21683 } else if (300 <= resp && resp < 700) { 21684 ast_verb(3, "Got SIP %s response %d \"%s\" back from host '%s'\n", 21685 sip_methods[sipmethod].text, resp, rest, ast_sockaddr_stringify(&p->sa)); 21686 } 21687 break; 21688 } 21689 }
| static void handle_response_notify | ( | struct sip_pvt * | p, | |
| int | resp, | |||
| const char * | rest, | |||
| struct sip_request * | req, | |||
| uint32_t | seqno | |||
| ) | [static] |
Definition at line 21171 of file chan_sip.c.
References ast_clear_flag, ast_debug, ast_log(), ast_sockaddr_stringify(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, cb_extensionstate(), do_proxy_auth(), get_header(), LOG_NOTICE, LOG_WARNING, NONE, and pvt_set_needdestroy().
Referenced by handle_response().
21172 { 21173 switch (resp) { 21174 case 200: /* Notify accepted */ 21175 /* They got the notify, this is the end */ 21176 if (p->owner) { 21177 if (p->refer) { 21178 ast_log(LOG_NOTICE, "Got OK on REFER Notify message\n"); 21179 } else { 21180 ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name); 21181 } 21182 } else { 21183 if (p->subscribed == NONE && !p->refer) { 21184 ast_debug(4, "Got 200 accepted on NOTIFY %s\n", p->callid); 21185 pvt_set_needdestroy(p, "received 200 response"); 21186 } 21187 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 21188 /* Ready to send the next state we have on queue */ 21189 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 21190 cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p); 21191 } 21192 } 21193 break; 21194 case 401: /* Not www-authorized on SIP method */ 21195 case 407: /* Proxy auth */ 21196 if (!p->notify) { 21197 break; /* Only device notify can use NOTIFY auth */ 21198 } 21199 ast_string_field_set(p, theirtag, NULL); 21200 if (ast_strlen_zero(p->authname)) { 21201 ast_log(LOG_WARNING, "Asked to authenticate NOTIFY to %s but we have no matching peer or realm auth!\n", ast_sockaddr_stringify(&p->recv)); 21202 pvt_set_needdestroy(p, "unable to authenticate NOTIFY"); 21203 } 21204 if (p->authtries > 1 || do_proxy_auth(p, req, resp, SIP_NOTIFY, 0)) { 21205 ast_log(LOG_NOTICE, "Failed to authenticate on NOTIFY to '%s'\n", get_header(&p->initreq, "From")); 21206 pvt_set_needdestroy(p, "failed to authenticate NOTIFY"); 21207 } 21208 break; 21209 case 481: /* Call leg does not exist */ 21210 pvt_set_needdestroy(p, "Received 481 response for NOTIFY"); 21211 break; 21212 } 21213 }
| static void handle_response_peerpoke | ( | struct sip_pvt * | p, | |
| int | resp, | |||
| struct sip_request * | req | |||
| ) | [static] |
Handle qualification responses (OPTIONS).
Definition at line 21554 of file chan_sip.c.
References ast_check_realtime(), AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_log(), AST_SCHED_REPLACE_UNREF, ast_tvdiff_ms(), ast_tvnow(), ast_update_realtime(), DEFAULT_FREQ_NOTOK, EVENT_FLAG_SYSTEM, LOG_NOTICE, manager_event, pvt_set_needdestroy(), ref_peer(), register_peer_exten(), SENTINEL, sip_cfg, sip_poke_peer_s(), TRUE, and unref_peer().
Referenced by handle_response().
21555 { 21556 struct sip_peer *peer = /* ref_peer( */ p->relatedpeer /* , "bump refcount on p, as it is being used in this function(handle_response_peerpoke)")*/ ; /* hope this is already refcounted! */ 21557 int statechanged, is_reachable, was_reachable; 21558 int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps); 21559 21560 /* 21561 * Compute the response time to a ping (goes in peer->lastms.) 21562 * -1 means did not respond, 0 means unknown, 21563 * 1..maxms is a valid response, >maxms means late response. 21564 */ 21565 if (pingtime < 1) { /* zero = unknown, so round up to 1 */ 21566 pingtime = 1; 21567 } 21568 21569 if (!peer->maxms) { /* this should never happens */ 21570 pvt_set_needdestroy(p, "got OPTIONS response but qualify is not enabled"); 21571 return; 21572 } 21573 21574 /* Now determine new state and whether it has changed. 21575 * Use some helper variables to simplify the writing 21576 * of the expressions. 21577 */ 21578 was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms; 21579 is_reachable = pingtime <= peer->maxms; 21580 statechanged = peer->lastms == 0 /* yes, unknown before */ 21581 || was_reachable != is_reachable; 21582 21583 peer->lastms = pingtime; 21584 peer->call = dialog_unref(peer->call, "unref dialog peer->call"); 21585 if (statechanged) { 21586 const char *s = is_reachable ? "Reachable" : "Lagged"; 21587 char str_lastms[20]; 21588 snprintf(str_lastms, sizeof(str_lastms), "%d", pingtime); 21589 21590 ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n", 21591 peer->name, s, pingtime, peer->maxms); 21592 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", peer->name); 21593 if (sip_cfg.peer_rtupdate) { 21594 ast_update_realtime(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", "name", peer->name, "lastms", str_lastms, SENTINEL); 21595 } 21596 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 21597 "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n", 21598 peer->name, s, pingtime); 21599 if (is_reachable && sip_cfg.regextenonqualify) 21600 register_peer_exten(peer, TRUE); 21601 } 21602 21603 pvt_set_needdestroy(p, "got OPTIONS response"); 21604 21605 /* Try again eventually */ 21606 AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, 21607 is_reachable ? peer->qualifyfreq : DEFAULT_FREQ_NOTOK, 21608 sip_poke_peer_s, peer, 21609 unref_peer(_data, "removing poke peer ref"), 21610 unref_peer(peer, "removing poke peer ref"), 21611 ref_peer(peer, "adding poke peer ref")); 21612 }
| static void handle_response_publish | ( | struct sip_pvt * | p, | |
| int | resp, | |||
| const char * | rest, | |||
| struct sip_request * | req, | |||
| uint32_t | seqno | |||
| ) | [static] |
Definition at line 20605 of file chan_sip.c.
References ast_assert, ast_copy_string(), ast_log(), ast_string_field_set, ast_strlen_zero(), do_proxy_auth(), get_header(), LOG_NOTICE, mark_method_unallowed(), pvt_set_needdestroy(), and sip_alreadygone().
Referenced by handle_response().
20606 { 20607 struct sip_epa_entry *epa_entry = p->epa_entry; 20608 const char *etag = get_header(req, "Sip-ETag"); 20609 20610 ast_assert(epa_entry != NULL); 20611 20612 if (resp == 401 || resp == 407) { 20613 ast_string_field_set(p, theirtag, NULL); 20614 if (p->options) { 20615 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 20616 } 20617 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, resp, SIP_PUBLISH, 0)) { 20618 ast_log(LOG_NOTICE, "Failed to authenticate on PUBLISH to '%s'\n", get_header(&p->initreq, "From")); 20619 pvt_set_needdestroy(p, "Failed to authenticate on PUBLISH"); 20620 sip_alreadygone(p); 20621 } 20622 return; 20623 } 20624 20625 if (resp == 501 || resp == 405) { 20626 mark_method_unallowed(&p->allowed_methods, SIP_PUBLISH); 20627 } 20628 20629 if (resp == 200) { 20630 p->authtries = 0; 20631 /* If I've read section 6, item 6 of RFC 3903 correctly, 20632 * an ESC will only generate a new etag when it sends a 200 OK 20633 */ 20634 if (!ast_strlen_zero(etag)) { 20635 ast_copy_string(epa_entry->entity_tag, etag, sizeof(epa_entry->entity_tag)); 20636 } 20637 /* The nominal case. Everything went well. Everybody is happy. 20638 * Each EPA will have a specific action to take as a result of this 20639 * development, so ... callbacks! 20640 */ 20641 if (epa_entry->static_data->handle_ok) { 20642 epa_entry->static_data->handle_ok(p, req, epa_entry); 20643 } 20644 } else { 20645 /* Rather than try to make individual callbacks for each error 20646 * type, there is just a single error callback. The callback 20647 * can distinguish between error messages and do what it needs to 20648 */ 20649 if (epa_entry->static_data->handle_error) { 20650 epa_entry->static_data->handle_error(p, resp, req, epa_entry); 20651 } 20652 } 20653 }
| static void handle_response_refer | ( | struct sip_pvt * | p, | |
| int | resp, | |||
| const char * | rest, | |||
| struct sip_request * | req, | |||
| uint32_t | seqno | |||
| ) | [static] |
Definition at line 21302 of file chan_sip.c.
References AST_CONTROL_CONGESTION, AST_CONTROL_TRANSFER, ast_debug, ast_log(), ast_queue_control(), ast_queue_control_data(), ast_sockaddr_stringify(), ast_strlen_zero(), AST_TRANSFER_FAILED, do_proxy_auth(), get_header(), LOG_NOTICE, LOG_WARNING, and pvt_set_needdestroy().
Referenced by handle_response().
21303 { 21304 enum ast_control_transfer message = AST_TRANSFER_FAILED; 21305 21306 /* If no refer structure exists, then do nothing */ 21307 if (!p->refer) 21308 return; 21309 21310 switch (resp) { 21311 case 202: /* Transfer accepted */ 21312 /* We need to do something here */ 21313 /* The transferee is now sending INVITE to target */ 21314 p->refer->status = REFER_ACCEPTED; 21315 /* Now wait for next message */ 21316 ast_debug(3, "Got 202 accepted on transfer\n"); 21317 /* We should hang along, waiting for NOTIFY's here */ 21318 break; 21319 21320 case 401: /* Not www-authorized on SIP method */ 21321 case 407: /* Proxy auth */ 21322 if (ast_strlen_zero(p->authname)) { 21323 ast_log(LOG_WARNING, "Asked to authenticate REFER to %s but we have no matching peer or realm auth!\n", 21324 ast_sockaddr_stringify(&p->recv)); 21325 if (p->owner) { 21326 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 21327 } 21328 pvt_set_needdestroy(p, "unable to authenticate REFER"); 21329 } 21330 if (p->authtries > 1 || do_proxy_auth(p, req, resp, SIP_REFER, 0)) { 21331 ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From")); 21332 p->refer->status = REFER_NOAUTH; 21333 if (p->owner) { 21334 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 21335 } 21336 pvt_set_needdestroy(p, "failed to authenticate REFER"); 21337 } 21338 break; 21339 21340 case 405: /* Method not allowed */ 21341 /* Return to the current call onhold */ 21342 /* Status flag needed to be reset */ 21343 ast_log(LOG_NOTICE, "SIP transfer to %s failed, REFER not allowed. \n", p->refer->refer_to); 21344 pvt_set_needdestroy(p, "received 405 response"); 21345 p->refer->status = REFER_FAILED; 21346 if (p->owner) { 21347 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 21348 } 21349 break; 21350 21351 case 481: /* Call leg does not exist */ 21352 21353 /* A transfer with Replaces did not work */ 21354 /* OEJ: We should Set flag, cancel the REFER, go back 21355 to original call - but right now we can't */ 21356 ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid); 21357 if (p->owner) 21358 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 21359 pvt_set_needdestroy(p, "received 481 response"); 21360 break; 21361 21362 case 500: /* Server error */ 21363 case 501: /* Method not implemented */ 21364 /* Return to the current call onhold */ 21365 /* Status flag needed to be reset */ 21366 ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to); 21367 pvt_set_needdestroy(p, "received 500/501 response"); 21368 p->refer->status = REFER_FAILED; 21369 if (p->owner) { 21370 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 21371 } 21372 break; 21373 case 603: /* Transfer declined */ 21374 ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to); 21375 p->refer->status = REFER_FAILED; 21376 pvt_set_needdestroy(p, "received 603 response"); 21377 if (p->owner) { 21378 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 21379 } 21380 break; 21381 default: 21382 /* We should treat unrecognized 9xx as 900. 400 is actually 21383 specified as a possible response, but any 4-6xx is 21384 theoretically possible. */ 21385 21386 if (resp < 299) { /* 1xx cases don't get here */ 21387 ast_log(LOG_WARNING, "SIP transfer to %s had unxpected 2xx response (%d), confusion is possible. \n", p->refer->refer_to, resp); 21388 } else { 21389 ast_log(LOG_WARNING, "SIP transfer to %s with response (%d). \n", p->refer->refer_to, resp); 21390 } 21391 21392 p->refer->status = REFER_FAILED; 21393 pvt_set_needdestroy(p, "received failure response"); 21394 if (p->owner) { 21395 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 21396 } 21397 break; 21398 } 21399 }
| static int handle_response_register | ( | struct sip_pvt * | p, | |
| int | resp, | |||
| const char * | rest, | |||
| struct sip_request * | req, | |||
| uint32_t | seqno | |||
| ) | [static] |
Handle responses on REGISTER to services.
Definition at line 21402 of file chan_sip.c.
References __get_header(), ast_debug, ast_log(), AST_SCHED_DEL_UNREF, AST_SCHED_REPLACE_UNREF, ast_string_field_set, ast_strlen_zero(), ast_tvnow(), do_register_auth(), EVENT_FLAG_SYSTEM, get_header(), LOG_NOTICE, LOG_WARNING, manager_event, MAX, pvt_set_needdestroy(), REG_STATE_NOAUTH, REG_STATE_REGISTERED, REG_STATE_REJECTED, REG_STATE_UNREGISTERED, registry_addref(), registry_unref(), regstate2str(), S_OR, sip_reregister(), and transmit_register().
Referenced by handle_response().
21403 { 21404 int expires, expires_ms; 21405 struct sip_registry *r; 21406 r=p->registry; 21407 21408 switch (resp) { 21409 case 401: /* Unauthorized */ 21410 if (p->authtries == MAX_AUTHTRIES || do_register_auth(p, req, resp)) { 21411 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries); 21412 pvt_set_needdestroy(p, "failed to authenticate REGISTER"); 21413 } 21414 break; 21415 case 403: /* Forbidden */ 21416 if (global_reg_retry_403) { 21417 ast_log(LOG_NOTICE, "Treating 403 response to REGISTER as non-fatal for %s@%s\n", 21418 p->registry->username, p->registry->hostname); 21419 ast_string_field_set(r, nonce, ""); 21420 ast_string_field_set(p, nonce, ""); 21421 break; 21422 } 21423 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); 21424 AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 403")); 21425 r->regstate = REG_STATE_NOAUTH; 21426 pvt_set_needdestroy(p, "received 403 response"); 21427 break; 21428 case 404: /* Not found */ 21429 ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username, p->registry->hostname); 21430 pvt_set_needdestroy(p, "received 404 response"); 21431 if (r->call) 21432 r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 404"); 21433 r->regstate = REG_STATE_REJECTED; 21434 AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 404")); 21435 break; 21436 case 407: /* Proxy auth */ 21437 if (p->authtries == MAX_AUTHTRIES || do_register_auth(p, req, resp)) { 21438 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries); 21439 pvt_set_needdestroy(p, "failed to authenticate REGISTER"); 21440 } 21441 break; 21442 case 408: /* Request timeout */ 21443 /* Got a timeout response, so reset the counter of failed responses */ 21444 if (r) { 21445 r->regattempts = 0; 21446 } else { 21447 ast_log(LOG_WARNING, "Got a 408 response to our REGISTER on call %s after we had destroyed the registry object\n", p->callid); 21448 } 21449 break; 21450 case 423: /* Interval too brief */ 21451 r->expiry = atoi(get_header(req, "Min-Expires")); 21452 ast_log(LOG_WARNING, "Got 423 Interval too brief for service %s@%s, minimum is %d seconds\n", p->registry->username, p->registry->hostname, r->expiry); 21453 AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 423")); 21454 if (r->call) { 21455 r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 423"); 21456 pvt_set_needdestroy(p, "received 423 response"); 21457 } 21458 if (r->expiry > max_expiry) { 21459 ast_log(LOG_WARNING, "Required expiration time from %s@%s is too high, giving up\n", p->registry->username, p->registry->hostname); 21460 r->expiry = r->configured_expiry; 21461 r->regstate = REG_STATE_REJECTED; 21462 } else { 21463 r->regstate = REG_STATE_UNREGISTERED; 21464 transmit_register(r, SIP_REGISTER, NULL, NULL); 21465 } 21466 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: SIP\r\nUsername: %s\r\nDomain: %s\r\nStatus: %s\r\n", r->username, r->hostname, regstate2str(r->regstate)); 21467 break; 21468 case 479: /* SER: Not able to process the URI - address is wrong in register*/ 21469 ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username, p->registry->hostname); 21470 pvt_set_needdestroy(p, "received 479 response"); 21471 if (r->call) 21472 r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 479"); 21473 r->regstate = REG_STATE_REJECTED; 21474 AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 479")); 21475 break; 21476 case 200: /* 200 OK */ 21477 if (!r) { 21478 ast_log(LOG_WARNING, "Got 200 OK on REGISTER, but there isn't a registry entry for '%s' (we probably already got the OK)\n", S_OR(p->peername, p->username)); 21479 pvt_set_needdestroy(p, "received erroneous 200 response"); 21480 return 0; 21481 } 21482 21483 r->regstate = REG_STATE_REGISTERED; 21484 r->regtime = ast_tvnow(); /* Reset time of last successful registration */ 21485 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: SIP\r\nUsername: %s\r\nDomain: %s\r\nStatus: %s\r\n", r->username, r->hostname, regstate2str(r->regstate)); 21486 r->regattempts = 0; 21487 ast_debug(1, "Registration successful\n"); 21488 if (r->timeout > -1) { 21489 ast_debug(1, "Cancelling timeout %d\n", r->timeout); 21490 } 21491 AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 200")); 21492 if (r->call) 21493 r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 200"); 21494 p->registry = registry_unref(p->registry, "unref registry entry p->registry"); 21495 21496 /* destroy dialog now to avoid interference with next register */ 21497 pvt_set_needdestroy(p, "Registration successfull"); 21498 21499 /* set us up for re-registering 21500 * figure out how long we got registered for 21501 * according to section 6.13 of RFC, contact headers override 21502 * expires headers, so check those first */ 21503 expires = 0; 21504 21505 /* XXX todo: try to save the extra call */ 21506 if (!ast_strlen_zero(get_header(req, "Contact"))) { 21507 const char *contact = NULL; 21508 const char *tmptmp = NULL; 21509 int start = 0; 21510 for(;;) { 21511 contact = __get_header(req, "Contact", &start); 21512 /* this loop ensures we get a contact header about our register request */ 21513 if(!ast_strlen_zero(contact)) { 21514 if( (tmptmp=strstr(contact, p->our_contact))) { 21515 contact=tmptmp; 21516 break; 21517 } 21518 } else 21519 break; 21520 } 21521 tmptmp = strcasestr(contact, "expires="); 21522 if (tmptmp) { 21523 if (sscanf(tmptmp + 8, "%30d", &expires) != 1) { 21524 expires = 0; 21525 } 21526 } 21527 21528 } 21529 if (!expires) 21530 expires=atoi(get_header(req, "expires")); 21531 if (!expires) 21532 expires=default_expiry; 21533 21534 expires_ms = expires * 1000; 21535 if (expires <= EXPIRY_GUARD_LIMIT) 21536 expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT), EXPIRY_GUARD_MIN); 21537 else 21538 expires_ms -= EXPIRY_GUARD_SECS * 1000; 21539 if (sipdebug) 21540 ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 21541 21542 r->refresh= (int) expires_ms / 1000; 21543 21544 /* Schedule re-registration before we expire */ 21545 AST_SCHED_REPLACE_UNREF(r->expire, sched, expires_ms, sip_reregister, r, 21546 registry_unref(_data,"unref in REPLACE del fail"), 21547 registry_unref(r,"unref in REPLACE add fail"), 21548 registry_addref(r,"The Addition side of REPLACE")); 21549 } 21550 return 1; 21551 }
| static void handle_response_subscribe | ( | struct sip_pvt * | p, | |
| int | resp, | |||
| const char * | rest, | |||
| struct sip_request * | req, | |||
| uint32_t | seqno | |||
| ) | [static] |
Definition at line 21216 of file chan_sip.c.
References ao2_callback, ao2_ref, ast_cc_monitor_failed(), ast_debug, ast_free, ast_log(), ast_sched_add(), ast_string_field_set, ASTOBJ_REF, ASTOBJ_UNREF, do_proxy_auth(), find_sip_monitor_instance_by_subscription_pvt(), get_header(), LOG_NOTICE, LOG_WARNING, pvt_set_needdestroy(), set_pvt_allowed_methods(), sip_alreadygone(), sip_subscribe_mwi_destroy(), sip_subscribe_mwi_do(), and transmit_response_with_date().
Referenced by handle_response().
21217 { 21218 if (p->subscribed == CALL_COMPLETION) { 21219 struct sip_monitor_instance *monitor_instance; 21220 21221 if (resp < 300) { 21222 return; 21223 } 21224 21225 /* Final failure response received. */ 21226 monitor_instance = ao2_callback(sip_monitor_instances, 0, 21227 find_sip_monitor_instance_by_subscription_pvt, p); 21228 if (monitor_instance) { 21229 ast_cc_monitor_failed(monitor_instance->core_id, 21230 monitor_instance->device_name, 21231 "Received error response to our SUBSCRIBE"); 21232 } 21233 return; 21234 } 21235 21236 if (p->subscribed != MWI_NOTIFICATION) { 21237 return; 21238 } 21239 if (!p->mwi) { 21240 return; 21241 } 21242 21243 switch (resp) { 21244 case 200: /* Subscription accepted */ 21245 ast_debug(3, "Got 200 OK on subscription for MWI\n"); 21246 set_pvt_allowed_methods(p, req); 21247 if (p->options) { 21248 if (p->options->outboundproxy) { 21249 ao2_ref(p->options->outboundproxy, -1); 21250 } 21251 ast_free(p->options); 21252 p->options = NULL; 21253 } 21254 p->mwi->subscribed = 1; 21255 if ((p->mwi->resub = ast_sched_add(sched, mwi_expiry * 1000, sip_subscribe_mwi_do, ASTOBJ_REF(p->mwi))) < 0) { 21256 ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); 21257 } 21258 break; 21259 case 401: 21260 case 407: 21261 ast_string_field_set(p, theirtag, NULL); 21262 if (p->authtries > 1 || do_proxy_auth(p, req, resp, SIP_SUBSCRIBE, 0)) { 21263 ast_log(LOG_NOTICE, "Failed to authenticate on SUBSCRIBE to '%s'\n", get_header(&p->initreq, "From")); 21264 p->mwi->call = NULL; 21265 ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); 21266 pvt_set_needdestroy(p, "failed to authenticate SUBSCRIBE"); 21267 } 21268 break; 21269 case 403: 21270 transmit_response_with_date(p, "200 OK", req); 21271 ast_log(LOG_WARNING, "Authentication failed while trying to subscribe for MWI.\n"); 21272 p->mwi->call = NULL; 21273 ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); 21274 pvt_set_needdestroy(p, "received 403 response"); 21275 sip_alreadygone(p); 21276 break; 21277 case 404: 21278 ast_log(LOG_WARNING, "Subscription failed for MWI. The remote side said that a mailbox may not have been configured.\n"); 21279 p->mwi->call = NULL; 21280 ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); 21281 pvt_set_needdestroy(p, "received 404 response"); 21282 break; 21283 case 481: 21284 ast_log(LOG_WARNING, "Subscription failed for MWI. The remote side said that our dialog did not exist.\n"); 21285 p->mwi->call = NULL; 21286 ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); 21287 pvt_set_needdestroy(p, "received 481 response"); 21288 break; 21289 case 500: 21290 case 501: 21291 ast_log(LOG_WARNING, "Subscription failed for MWI. The remote side may have suffered a heart attack.\n"); 21292 p->mwi->call = NULL; 21293 ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); 21294 pvt_set_needdestroy(p, "received 500/501 response"); 21295 break; 21296 } 21297 }
| static void handle_response_update | ( | struct sip_pvt * | p, | |
| int | resp, | |||
| const char * | rest, | |||
| struct sip_request * | req, | |||
| uint32_t | seqno | |||
| ) | [static] |
Handle authentication challenge for SIP UPDATE.
This function is only called upon the receipt of a 401/407 response to an UPDATE.
Definition at line 20545 of file chan_sip.c.
References ast_log(), do_proxy_auth(), get_header(), and LOG_NOTICE.
Referenced by handle_response().
20546 { 20547 if (p->options) { 20548 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 20549 } 20550 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, resp, SIP_UPDATE, 1)) { 20551 ast_log(LOG_NOTICE, "Failed to authenticate on UPDATE to '%s'\n", get_header(&p->initreq, "From")); 20552 } 20553 }
| static int handle_sip_publish_initial | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| struct event_state_compositor * | esc, | |||
| const int | expires | |||
| ) | [static] |
Definition at line 25075 of file chan_sip.c.
References ao2_ref, event_state_compositor::callbacks, create_esc_entry(), transmit_response(), and transmit_response_with_sip_etag().
Referenced by handle_request_publish().
25076 { 25077 struct sip_esc_entry *esc_entry = create_esc_entry(esc, req, expires); 25078 int res = 0; 25079 25080 if (!esc_entry) { 25081 transmit_response(p, "503 Internal Server Failure", req); 25082 return -1; 25083 } 25084 25085 if (esc->callbacks->initial_handler) { 25086 res = esc->callbacks->initial_handler(p, req, esc, esc_entry); 25087 } 25088 25089 if (!res) { 25090 transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 0); 25091 } 25092 25093 ao2_ref(esc_entry, -1); 25094 return res; 25095 }
| static int handle_sip_publish_modify | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| struct event_state_compositor * | esc, | |||
| const char *const | etag, | |||
| const int | expires | |||
| ) | [static] |
Definition at line 25125 of file chan_sip.c.
References ao2_ref, AST_SCHED_REPLACE_UNREF, event_state_compositor::callbacks, get_esc_entry(), publish_expire(), transmit_response(), and transmit_response_with_sip_etag().
Referenced by handle_request_publish().
25126 { 25127 struct sip_esc_entry *esc_entry = get_esc_entry(etag, esc); 25128 int expires_ms = expires * 1000; 25129 int res = 0; 25130 25131 if (!esc_entry) { 25132 transmit_response(p, "412 Conditional Request Failed", req); 25133 return -1; 25134 } 25135 25136 AST_SCHED_REPLACE_UNREF(esc_entry->sched_id, sched, expires_ms, publish_expire, esc_entry, 25137 ao2_ref(_data, -1), 25138 ao2_ref(esc_entry, -1), 25139 ao2_ref(esc_entry, +1)); 25140 25141 if (esc->callbacks->modify_handler) { 25142 res = esc->callbacks->modify_handler(p, req, esc, esc_entry); 25143 } 25144 25145 if (!res) { 25146 transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 1); 25147 } 25148 25149 ao2_ref(esc_entry, -1); 25150 return res; 25151 }
| static int handle_sip_publish_refresh | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| struct event_state_compositor * | esc, | |||
| const char *const | etag, | |||
| const int | expires | |||
| ) | [static] |
Definition at line 25097 of file chan_sip.c.
References ao2_ref, AST_SCHED_REPLACE_UNREF, event_state_compositor::callbacks, get_esc_entry(), publish_expire(), transmit_response(), and transmit_response_with_sip_etag().
Referenced by handle_request_publish().
25098 { 25099 struct sip_esc_entry *esc_entry = get_esc_entry(etag, esc); 25100 int expires_ms = expires * 1000; 25101 int res = 0; 25102 25103 if (!esc_entry) { 25104 transmit_response(p, "412 Conditional Request Failed", req); 25105 return -1; 25106 } 25107 25108 AST_SCHED_REPLACE_UNREF(esc_entry->sched_id, sched, expires_ms, publish_expire, esc_entry, 25109 ao2_ref(_data, -1), 25110 ao2_ref(esc_entry, -1), 25111 ao2_ref(esc_entry, +1)); 25112 25113 if (esc->callbacks->refresh_handler) { 25114 res = esc->callbacks->refresh_handler(p, req, esc, esc_entry); 25115 } 25116 25117 if (!res) { 25118 transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 1); 25119 } 25120 25121 ao2_ref(esc_entry, -1); 25122 return res; 25123 }
| static int handle_sip_publish_remove | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| struct event_state_compositor * | esc, | |||
| const char *const | etag | |||
| ) | [static] |
Definition at line 25153 of file chan_sip.c.
References ao2_ref, ao2_unlink, AST_SCHED_DEL, event_state_compositor::callbacks, event_state_compositor::compositor, get_esc_entry(), transmit_response(), and transmit_response_with_sip_etag().
Referenced by handle_request_publish().
25154 { 25155 struct sip_esc_entry *esc_entry = get_esc_entry(etag, esc); 25156 int res = 0; 25157 25158 if (!esc_entry) { 25159 transmit_response(p, "412 Conditional Request Failed", req); 25160 return -1; 25161 } 25162 25163 AST_SCHED_DEL(sched, esc_entry->sched_id); 25164 /* Scheduler's ref of the esc_entry */ 25165 ao2_ref(esc_entry, -1); 25166 25167 if (esc->callbacks->remove_handler) { 25168 res = esc->callbacks->remove_handler(p, req, esc, esc_entry); 25169 } 25170 25171 if (!res) { 25172 transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 1); 25173 } 25174 25175 /* Ref from finding the esc_entry earlier in function */ 25176 ao2_unlink(esc->compositor, esc_entry); 25177 ao2_ref(esc_entry, -1); 25178 return res; 25179 }
| static int handle_t38_options | ( | struct ast_flags * | flags, | |
| struct ast_flags * | mask, | |||
| struct ast_variable * | v, | |||
| unsigned int * | maxdatagram | |||
| ) | [static] |
Handle T.38 configuration options common to users and peers.
Definition at line 27511 of file chan_sip.c.
References ast_clear_flag, ast_log(), ast_set2_flag, ast_set_flag, ast_strdupa, ast_true(), ast_variable::lineno, LOG_WARNING, ast_variable::name, ast_variable::value, and word.
Referenced by build_peer(), and reload_config().
27513 { 27514 int res = 1; 27515 27516 if (!strcasecmp(v->name, "t38pt_udptl")) { 27517 char *buf = ast_strdupa(v->value); 27518 char *word, *next = buf; 27519 27520 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT); 27521 27522 while ((word = strsep(&next, ","))) { 27523 if (ast_true(word) || !strcasecmp(word, "fec")) { 27524 ast_clear_flag(&flags[1], SIP_PAGE2_T38SUPPORT); 27525 ast_set_flag(&flags[1], SIP_PAGE2_T38SUPPORT_UDPTL_FEC); 27526 } else if (!strcasecmp(word, "redundancy")) { 27527 ast_clear_flag(&flags[1], SIP_PAGE2_T38SUPPORT); 27528 ast_set_flag(&flags[1], SIP_PAGE2_T38SUPPORT_UDPTL_REDUNDANCY); 27529 } else if (!strcasecmp(word, "none")) { 27530 ast_clear_flag(&flags[1], SIP_PAGE2_T38SUPPORT); 27531 ast_set_flag(&flags[1], SIP_PAGE2_T38SUPPORT_UDPTL); 27532 } else if (!strncasecmp(word, "maxdatagram=", 12)) { 27533 if (sscanf(&word[12], "%30u", maxdatagram) != 1) { 27534 ast_log(LOG_WARNING, "Invalid maxdatagram '%s' at line %d of %s\n", v->value, v->lineno, config); 27535 *maxdatagram = global_t38_maxdatagram; 27536 } 27537 } 27538 } 27539 } else if (!strcasecmp(v->name, "t38pt_usertpsource")) { 27540 ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION); 27541 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION); 27542 } else { 27543 res = 0; 27544 } 27545 27546 return res; 27547 }
| const char* hangup_cause2sip | ( | int | cause | ) |
Convert Asterisk hangup causes to SIP codes.
Possible values from causes.h
AST_CAUSE_NOTDEFINED AST_CAUSE_NORMAL AST_CAUSE_BUSY
AST_CAUSE_FAILURE AST_CAUSE_CONGESTION AST_CAUSE_UNALLOCATED
In addition to these, a lot of PRI codes is defined in causes.h
...should we take care of them too ?
Quote RFC 3398
ISUP Cause value SIP response
---------------- ------------
1 unallocated number 404 Not Found
2 no route to network 404 Not found
3 no route to destination 404 Not found
16 normal call clearing --- (*)
17 user busy 486 Busy here
18 no user responding 408 Request Timeout
19 no answer from the user 480 Temporarily unavailable
20 subscriber absent 480 Temporarily unavailable
21 call rejected 403 Forbidden (+)
22 number changed (w/o diagnostic) 410 Gone
22 number changed (w/ diagnostic) 301 Moved Permanently
23 redirection to new destination 410 Gone
26 non-selected user clearing 404 Not Found (=)
27 destination out of order 502 Bad Gateway
28 address incomplete 484 Address incomplete
29 facility rejected 501 Not implemented
31 normal unspecified 480 Temporarily unavailable
Definition at line 6426 of file chan_sip.c.
References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_CALL_REJECTED, AST_CAUSE_CHAN_NOT_IMPLEMENTED, AST_CAUSE_CONGESTION, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_FACILITY_REJECTED, AST_CAUSE_FAILURE, AST_CAUSE_INVALID_NUMBER_FORMAT, AST_CAUSE_NO_ANSWER, AST_CAUSE_NO_ROUTE_DESTINATION, AST_CAUSE_NO_ROUTE_TRANSIT_NET, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_NORMAL_UNSPECIFIED, AST_CAUSE_NOTDEFINED, AST_CAUSE_NUMBER_CHANGED, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNALLOCATED, AST_CAUSE_UNREGISTERED, AST_CAUSE_USER_BUSY, and ast_debug.
Referenced by sip_hangup().
06427 { 06428 switch (cause) { 06429 case AST_CAUSE_UNALLOCATED: /* 1 */ 06430 case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */ 06431 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */ 06432 return "404 Not Found"; 06433 case AST_CAUSE_CONGESTION: /* 34 */ 06434 case AST_CAUSE_SWITCH_CONGESTION: /* 42 */ 06435 return "503 Service Unavailable"; 06436 case AST_CAUSE_NO_USER_RESPONSE: /* 18 */ 06437 return "408 Request Timeout"; 06438 case AST_CAUSE_NO_ANSWER: /* 19 */ 06439 case AST_CAUSE_UNREGISTERED: /* 20 */ 06440 return "480 Temporarily unavailable"; 06441 case AST_CAUSE_CALL_REJECTED: /* 21 */ 06442 return "403 Forbidden"; 06443 case AST_CAUSE_NUMBER_CHANGED: /* 22 */ 06444 return "410 Gone"; 06445 case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */ 06446 return "480 Temporarily unavailable"; 06447 case AST_CAUSE_INVALID_NUMBER_FORMAT: 06448 return "484 Address incomplete"; 06449 case AST_CAUSE_USER_BUSY: 06450 return "486 Busy here"; 06451 case AST_CAUSE_FAILURE: 06452 return "500 Server internal failure"; 06453 case AST_CAUSE_FACILITY_REJECTED: /* 29 */ 06454 return "501 Not Implemented"; 06455 case AST_CAUSE_CHAN_NOT_IMPLEMENTED: 06456 return "503 Service Unavailable"; 06457 /* Used in chan_iax2 */ 06458 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 06459 return "502 Bad Gateway"; 06460 case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */ 06461 return "488 Not Acceptable Here"; 06462 06463 case AST_CAUSE_NOTDEFINED: 06464 default: 06465 ast_debug(1, "AST hangup cause %d (no match found in SIP)\n", cause); 06466 return NULL; 06467 } 06468 06469 /* Never reached */ 06470 return 0; 06471 }
| int hangup_sip2cause | ( | int | cause | ) |
Convert SIP hangup causes to Asterisk hangup causes.
Definition at line 6304 of file chan_sip.c.
References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CALL_REJECTED, AST_CAUSE_CONGESTION, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_FACILITY_REJECTED, AST_CAUSE_FAILURE, AST_CAUSE_INTERWORKING, AST_CAUSE_INVALID_NUMBER_FORMAT, AST_CAUSE_NO_ANSWER, AST_CAUSE_NO_ROUTE_DESTINATION, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_NORMAL, AST_CAUSE_NORMAL_TEMPORARY_FAILURE, AST_CAUSE_NUMBER_CHANGED, AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE, AST_CAUSE_UNALLOCATED, and AST_CAUSE_USER_BUSY.
Referenced by __transmit_response(), handle_response(), and handle_response_invite().
06305 { 06306 /* Possible values taken from causes.h */ 06307 06308 switch(cause) { 06309 case 401: /* Unauthorized */ 06310 return AST_CAUSE_CALL_REJECTED; 06311 case 403: /* Not found */ 06312 return AST_CAUSE_CALL_REJECTED; 06313 case 404: /* Not found */ 06314 return AST_CAUSE_UNALLOCATED; 06315 case 405: /* Method not allowed */ 06316 return AST_CAUSE_INTERWORKING; 06317 case 407: /* Proxy authentication required */ 06318 return AST_CAUSE_CALL_REJECTED; 06319 case 408: /* No reaction */ 06320 return AST_CAUSE_NO_USER_RESPONSE; 06321 case 409: /* Conflict */ 06322 return AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 06323 case 410: /* Gone */ 06324 return AST_CAUSE_NUMBER_CHANGED; 06325 case 411: /* Length required */ 06326 return AST_CAUSE_INTERWORKING; 06327 case 413: /* Request entity too large */ 06328 return AST_CAUSE_INTERWORKING; 06329 case 414: /* Request URI too large */ 06330 return AST_CAUSE_INTERWORKING; 06331 case 415: /* Unsupported media type */ 06332 return AST_CAUSE_INTERWORKING; 06333 case 420: /* Bad extension */ 06334 return AST_CAUSE_NO_ROUTE_DESTINATION; 06335 case 480: /* No answer */ 06336 return AST_CAUSE_NO_ANSWER; 06337 case 481: /* No answer */ 06338 return AST_CAUSE_INTERWORKING; 06339 case 482: /* Loop detected */ 06340 return AST_CAUSE_INTERWORKING; 06341 case 483: /* Too many hops */ 06342 return AST_CAUSE_NO_ANSWER; 06343 case 484: /* Address incomplete */ 06344 return AST_CAUSE_INVALID_NUMBER_FORMAT; 06345 case 485: /* Ambiguous */ 06346 return AST_CAUSE_UNALLOCATED; 06347 case 486: /* Busy everywhere */ 06348 return AST_CAUSE_BUSY; 06349 case 487: /* Request terminated */ 06350 return AST_CAUSE_INTERWORKING; 06351 case 488: /* No codecs approved */ 06352 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 06353 case 491: /* Request pending */ 06354 return AST_CAUSE_INTERWORKING; 06355 case 493: /* Undecipherable */ 06356 return AST_CAUSE_INTERWORKING; 06357 case 500: /* Server internal failure */ 06358 return AST_CAUSE_FAILURE; 06359 case 501: /* Call rejected */ 06360 return AST_CAUSE_FACILITY_REJECTED; 06361 case 502: 06362 return AST_CAUSE_DESTINATION_OUT_OF_ORDER; 06363 case 503: /* Service unavailable */ 06364 return AST_CAUSE_CONGESTION; 06365 case 504: /* Gateway timeout */ 06366 return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE; 06367 case 505: /* SIP version not supported */ 06368 return AST_CAUSE_INTERWORKING; 06369 case 600: /* Busy everywhere */ 06370 return AST_CAUSE_USER_BUSY; 06371 case 603: /* Decline */ 06372 return AST_CAUSE_CALL_REJECTED; 06373 case 604: /* Does not exist anywhere */ 06374 return AST_CAUSE_UNALLOCATED; 06375 case 606: /* Not acceptable */ 06376 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 06377 default: 06378 if (cause < 500 && cause >= 400) { 06379 /* 4xx class error that is unknown - someting wrong with our request */ 06380 return AST_CAUSE_INTERWORKING; 06381 } else if (cause < 600 && cause >= 500) { 06382 /* 5xx class error - problem in the remote end */ 06383 return AST_CAUSE_CONGESTION; 06384 } else if (cause < 700 && cause >= 600) { 06385 /* 6xx - global errors in the 4xx class */ 06386 return AST_CAUSE_INTERWORKING; 06387 } 06388 return AST_CAUSE_NORMAL; 06389 } 06390 /* Never reached */ 06391 return 0; 06392 }
| static int init_req | ( | struct sip_request * | req, | |
| int | sipmethod, | |||
| const char * | recip | |||
| ) | [static] |
Initialize SIP request.
Definition at line 10518 of file chan_sip.c.
References ast_free, ast_str_create(), ast_str_set(), sip_methods, and cfsip_methods::text.
Referenced by initreqprep(), reqprep(), and transmit_register().
10519 { 10520 /* Initialize a request */ 10521 memset(req, 0, sizeof(*req)); 10522 if (!(req->data = ast_str_create(SIP_MIN_PACKET))) 10523 goto e_return; 10524 if (!(req->content = ast_str_create(SIP_MIN_PACKET))) 10525 goto e_free_data; 10526 req->method = sipmethod; 10527 req->header[0] = 0; 10528 ast_str_set(&req->data, 0, "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip); 10529 req->headers++; 10530 return 0; 10531 10532 e_free_data: 10533 ast_free(req->data); 10534 req->data = NULL; 10535 e_return: 10536 return -1; 10537 }
| static int init_resp | ( | struct sip_request * | resp, | |
| const char * | msg | |||
| ) | [static] |
Initialize SIP response, based on SIP request.
Definition at line 10496 of file chan_sip.c.
References ast_free, ast_str_create(), and ast_str_set().
Referenced by respprep().
10497 { 10498 /* Initialize a response */ 10499 memset(resp, 0, sizeof(*resp)); 10500 resp->method = SIP_RESPONSE; 10501 if (!(resp->data = ast_str_create(SIP_MIN_PACKET))) 10502 goto e_return; 10503 if (!(resp->content = ast_str_create(SIP_MIN_PACKET))) 10504 goto e_free_data; 10505 resp->header[0] = 0; 10506 ast_str_set(&resp->data, 0, "SIP/2.0 %s\r\n", msg); 10507 resp->headers++; 10508 return 0; 10509 10510 e_free_data: 10511 ast_free(resp->data); 10512 resp->data = NULL; 10513 e_return: 10514 return -1; 10515 }
| static int initialize_escs | ( | void | ) | [static] |
Definition at line 1056 of file chan_sip.c.
References ao2_container_alloc, ARRAY_LEN, esc_cmp_fn(), esc_hash_fn(), and event_state_compositors.
Referenced by load_module().
01057 { 01058 int i, res = 0; 01059 for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) { 01060 if (!((event_state_compositors[i].compositor) = 01061 ao2_container_alloc(ESC_MAX_BUCKETS, esc_hash_fn, esc_cmp_fn))) { 01062 res = -1; 01063 } 01064 } 01065 return res; 01066 }
| static void initialize_initreq | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Initialize the initital request packet in the pvt structure. This packet is used for creating replies and future requests in a dialog.
Definition at line 3206 of file chan_sip.c.
References ast_debug, ast_verbose, copy_request(), parse_request(), sip_methods, and cfsip_methods::text.
Referenced by transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_reinvite_with_sdp(), and update_connectedline().
03207 { 03208 if (p->initreq.headers) { 03209 ast_debug(1, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid); 03210 } else { 03211 ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid); 03212 } 03213 /* Use this as the basis */ 03214 copy_request(&p->initreq, req); 03215 parse_request(&p->initreq); 03216 if (req->debug) { 03217 ast_verbose("Initreq: %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 03218 } 03219 }
| static int initialize_udptl | ( | struct sip_pvt * | p | ) | [static] |
Definition at line 7091 of file chan_sip.c.
References ast_channel_set_fd(), ast_clear_flag, ast_debug, ast_log(), AST_LOG_WARNING, ast_test_flag, ast_udptl_fd(), ast_udptl_new_with_bindaddr(), ast_udptl_setnat(), ast_udptl_setqos(), bindaddr, and set_t38_capabilities().
Referenced by process_sdp(), process_sdp_a_image(), and sip_indicate().
07092 { 07093 int natflags = ast_test_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP); 07094 07095 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) { 07096 return 1; 07097 } 07098 07099 /* If we've already initialized T38, don't take any further action */ 07100 if (p->udptl) { 07101 return 0; 07102 } 07103 07104 /* T38 can be supported by this dialog, create it and set the derived properties */ 07105 if ((p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, &bindaddr))) { 07106 if (p->owner) { 07107 ast_channel_set_fd(p->owner, 5, ast_udptl_fd(p->udptl)); 07108 } 07109 07110 ast_udptl_setqos(p->udptl, global_tos_audio, global_cos_audio); 07111 p->t38_maxdatagram = p->relatedpeer ? p->relatedpeer->t38_maxdatagram : global_t38_maxdatagram; 07112 set_t38_capabilities(p); 07113 07114 ast_debug(1, "Setting NAT on UDPTL to %s\n", natflags ? "On" : "Off"); 07115 ast_udptl_setnat(p->udptl, natflags); 07116 } else { 07117 ast_log(AST_LOG_WARNING, "UDPTL creation failed - disabling T38 for this dialog\n"); 07118 ast_clear_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT); 07119 return 1; 07120 } 07121 07122 return 0; 07123 }
| static void initreqprep | ( | struct sip_request * | req, | |
| struct sip_pvt * | p, | |||
| int | sipmethod, | |||
| const char *const | explicit_uri | |||
| ) | [static] |
Initiate new SIP request to peer/user.
Definition at line 12345 of file chan_sip.c.
References add_header(), add_header_max_forwards(), add_route(), ast_copy_string(), AST_DIGIT_ANYNUM, ast_escape_quoted(), ast_party_id_presentation(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, ast_sockaddr_port, ast_sockaddr_stringify_host_remote(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_set(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_encode(), build_contact(), exten, init_req(), ourport, sip_cfg, sip_methods, sip_standard_port(), and cfsip_methods::text.
Referenced by transmit_invite(), and transmit_notify_with_mwi().
12346 { 12347 struct ast_str *invite = ast_str_alloca(256); 12348 char from[256]; 12349 char to[256]; 12350 char tmp_n[SIPBUFSIZE/2]; /* build a local copy of 'n' if needed */ 12351 char tmp_l[SIPBUFSIZE/2]; /* build a local copy of 'l' if needed */ 12352 const char *l = NULL; /* XXX what is this, exactly ? */ 12353 const char *n = NULL; /* XXX what is this, exactly ? */ 12354 const char *d = NULL; /* domain in from header */ 12355 const char *urioptions = ""; 12356 int ourport; 12357 12358 if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) { 12359 const char *s = p->username; /* being a string field, cannot be NULL */ 12360 12361 /* Test p->username against allowed characters in AST_DIGIT_ANY 12362 If it matches the allowed characters list, then sipuser = ";user=phone" 12363 If not, then sipuser = "" 12364 */ 12365 /* + is allowed in first position in a tel: uri */ 12366 if (*s == '+') 12367 s++; 12368 for (; *s; s++) { 12369 if (!strchr(AST_DIGIT_ANYNUM, *s) ) 12370 break; 12371 } 12372 /* If we have only digits, add ;user=phone to the uri */ 12373 if (!*s) 12374 urioptions = ";user=phone"; 12375 } 12376 12377 12378 snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text); 12379 12380 if (ast_strlen_zero(p->fromdomain)) { 12381 d = ast_sockaddr_stringify_host_remote(&p->ourip); 12382 } 12383 if (p->owner) { 12384 if ((ast_party_id_presentation(&p->owner->connected.id) & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED) { 12385 l = p->owner->connected.id.number.valid ? p->owner->connected.id.number.str : NULL; 12386 n = p->owner->connected.id.name.valid ? p->owner->connected.id.name.str : NULL; 12387 } else { 12388 /* Even if we are using RPID, we shouldn't leak information in the From if the user wants 12389 * their callerid restricted */ 12390 l = "anonymous"; 12391 n = CALLERID_UNKNOWN; 12392 d = FROMDOMAIN_INVALID; 12393 } 12394 } 12395 12396 /* Hey, it's a NOTIFY! See if they've configured a mwi_from. 12397 * XXX Right now, this logic works because the only place that mwi_from 12398 * is set on the sip_pvt is in sip_send_mwi_to_peer. If things changed, then 12399 * we might end up putting the mwi_from setting into other types of NOTIFY 12400 * messages as well. 12401 */ 12402 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->mwi_from)) { 12403 l = p->mwi_from; 12404 } 12405 12406 if (ast_strlen_zero(l)) 12407 l = default_callerid; 12408 if (ast_strlen_zero(n)) 12409 n = l; 12410 /* Allow user to be overridden */ 12411 if (!ast_strlen_zero(p->fromuser)) 12412 l = p->fromuser; 12413 else /* Save for any further attempts */ 12414 ast_string_field_set(p, fromuser, l); 12415 12416 /* Allow user to be overridden */ 12417 if (!ast_strlen_zero(p->fromname)) 12418 n = p->fromname; 12419 else /* Save for any further attempts */ 12420 ast_string_field_set(p, fromname, n); 12421 12422 /* Allow domain to be overridden */ 12423 if (!ast_strlen_zero(p->fromdomain)) 12424 d = p->fromdomain; 12425 else /* Save for any further attempts */ 12426 ast_string_field_set(p, fromdomain, d); 12427 12428 ast_copy_string(tmp_l, l, sizeof(tmp_l)); 12429 if (sip_cfg.pedanticsipchecking) { 12430 ast_escape_quoted(n, tmp_n, sizeof(tmp_n)); 12431 n = tmp_n; 12432 ast_uri_encode(l, tmp_l, sizeof(tmp_l), 0); 12433 } 12434 12435 ourport = (p->fromdomainport && (p->fromdomainport != STANDARD_SIP_PORT)) ? p->fromdomainport : ast_sockaddr_port(&p->ourip); 12436 if (!sip_standard_port(p->socket.type, ourport)) { 12437 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%s", n, tmp_l, d, ourport, p->tag); 12438 } else { 12439 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, tmp_l, d, p->tag); 12440 } 12441 12442 if (!ast_strlen_zero(explicit_uri)) { 12443 ast_str_set(&invite, 0, "%s", explicit_uri); 12444 } else { 12445 /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */ 12446 if (!ast_strlen_zero(p->fullcontact)) { 12447 /* If we have full contact, trust it */ 12448 ast_str_append(&invite, 0, "%s", p->fullcontact); 12449 } else { 12450 /* Otherwise, use the username while waiting for registration */ 12451 ast_str_append(&invite, 0, "sip:"); 12452 if (!ast_strlen_zero(p->username)) { 12453 n = p->username; 12454 if (sip_cfg.pedanticsipchecking) { 12455 ast_uri_encode(n, tmp_n, sizeof(tmp_n), 0); 12456 n = tmp_n; 12457 } 12458 ast_str_append(&invite, 0, "%s@", n); 12459 } 12460 ast_str_append(&invite, 0, "%s", p->tohost); 12461 if (p->portinuri) { 12462 ast_str_append(&invite, 0, ":%d", ast_sockaddr_port(&p->sa)); 12463 } 12464 ast_str_append(&invite, 0, "%s", urioptions); 12465 } 12466 } 12467 12468 /* If custom URI options have been provided, append them */ 12469 if (p->options && !ast_strlen_zero(p->options->uri_options)) 12470 ast_str_append(&invite, 0, ";%s", p->options->uri_options); 12471 12472 /* This is the request URI, which is the next hop of the call 12473 which may or may not be the destination of the call 12474 */ 12475 ast_string_field_set(p, uri, ast_str_buffer(invite)); 12476 12477 if (!ast_strlen_zero(p->todnid)) { 12478 /*! \todo Need to add back the VXML URL here at some point, possibly use build_string for all this junk */ 12479 if (!strchr(p->todnid, '@')) { 12480 /* We have no domain in the dnid */ 12481 snprintf(to, sizeof(to), "<sip:%s@%s>%s%s", p->todnid, p->tohost, ast_strlen_zero(p->theirtag) ? "" : ";tag=", p->theirtag); 12482 } else { 12483 snprintf(to, sizeof(to), "<sip:%s>%s%s", p->todnid, ast_strlen_zero(p->theirtag) ? "" : ";tag=", p->theirtag); 12484 } 12485 } else { 12486 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 12487 /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ 12488 snprintf(to, sizeof(to), "<%s%s>;tag=%s", (strncasecmp(p->uri, "sip:", 4) ? "sip:" : ""), p->uri, p->theirtag); 12489 } else if (p->options && p->options->vxml_url) { 12490 /* If there is a VXML URL append it to the SIP URL */ 12491 snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); 12492 } else { 12493 snprintf(to, sizeof(to), "<%s>", p->uri); 12494 } 12495 } 12496 12497 init_req(req, sipmethod, p->uri); 12498 /* now tmp_n is available so reuse it to build the CSeq */ 12499 snprintf(tmp_n, sizeof(tmp_n), "%u %s", ++p->ocseq, sip_methods[sipmethod].text); 12500 12501 add_header(req, "Via", p->via); 12502 add_header_max_forwards(p, req); 12503 /* This will be a no-op most of the time. However, under certain circumstances, 12504 * NOTIFY messages will use this function for preparing the request and should 12505 * have Route headers present. 12506 */ 12507 add_route(req, p->route); 12508 12509 add_header(req, "From", from); 12510 add_header(req, "To", to); 12511 ast_string_field_set(p, exten, l); 12512 build_contact(p); 12513 add_header(req, "Contact", p->our_contact); 12514 add_header(req, "Call-ID", p->callid); 12515 add_header(req, "CSeq", tmp_n); 12516 if (!ast_strlen_zero(global_useragent)) { 12517 add_header(req, "User-Agent", global_useragent); 12518 } 12519 }
| static const char * insecure2str | ( | int | mode | ) | [static] |
Convert Insecure setting to printable string.
Definition at line 17589 of file chan_sip.c.
References map_x_s().
Referenced by _sip_show_peer().
17590 { 17591 return map_x_s(insecurestr, mode, "<error>"); 17592 }
| static int interpret_t38_parameters | ( | struct sip_pvt * | p, | |
| const struct ast_control_t38_parameters * | parameters | |||
| ) | [static] |
Helper function which updates T.38 capability information and triggers a reinvite.
Definition at line 6997 of file chan_sip.c.
References AST_CONTROL_T38_PARAMETERS, ast_queue_control_data(), AST_SCHED_DEL_UNREF, ast_set_flag, AST_T38_NEGOTIATED, AST_T38_REFUSED, AST_T38_REQUEST_NEGOTIATE, AST_T38_REQUEST_PARMS, AST_T38_REQUEST_TERMINATE, AST_T38_TERMINATED, ast_test_flag, ast_udptl_get_far_max_ifp(), ast_udptl_set_local_max_ifp(), change_t38_state(), FALSE, ast_control_t38_parameters::fill_bit_removal, ast_control_t38_parameters::max_ifp, MIN, ast_control_t38_parameters::request_response, transmit_reinvite_with_sdp(), transmit_response_reliable(), transmit_response_with_t38_sdp(), and TRUE.
Referenced by sip_indicate().
06998 { 06999 int res = 0; 07000 07001 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) || !p->udptl) { 07002 return -1; 07003 } 07004 switch (parameters->request_response) { 07005 case AST_T38_NEGOTIATED: 07006 case AST_T38_REQUEST_NEGOTIATE: /* Request T38 */ 07007 /* Negotiation can not take place without a valid max_ifp value. */ 07008 if (!parameters->max_ifp) { 07009 change_t38_state(p, T38_DISABLED); 07010 if (p->t38.state == T38_PEER_REINVITE) { 07011 AST_SCHED_DEL_UNREF(sched, p->t38id, dialog_unref(p, "when you delete the t38id sched, you should dec the refcount for the stored dialog ptr")); 07012 transmit_response_reliable(p, "488 Not acceptable here", &p->initreq); 07013 } 07014 break; 07015 } else if (p->t38.state == T38_PEER_REINVITE) { 07016 AST_SCHED_DEL_UNREF(sched, p->t38id, dialog_unref(p, "when you delete the t38id sched, you should dec the refcount for the stored dialog ptr")); 07017 p->t38.our_parms = *parameters; 07018 /* modify our parameters to conform to the peer's parameters, 07019 * based on the rules in the ITU T.38 recommendation 07020 */ 07021 if (!p->t38.their_parms.fill_bit_removal) { 07022 p->t38.our_parms.fill_bit_removal = FALSE; 07023 } 07024 if (!p->t38.their_parms.transcoding_mmr) { 07025 p->t38.our_parms.transcoding_mmr = FALSE; 07026 } 07027 if (!p->t38.their_parms.transcoding_jbig) { 07028 p->t38.our_parms.transcoding_jbig = FALSE; 07029 } 07030 p->t38.our_parms.version = MIN(p->t38.our_parms.version, p->t38.their_parms.version); 07031 p->t38.our_parms.rate_management = p->t38.their_parms.rate_management; 07032 ast_udptl_set_local_max_ifp(p->udptl, p->t38.our_parms.max_ifp); 07033 change_t38_state(p, T38_ENABLED); 07034 transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 07035 } else if (p->t38.state != T38_ENABLED) { 07036 p->t38.our_parms = *parameters; 07037 ast_udptl_set_local_max_ifp(p->udptl, p->t38.our_parms.max_ifp); 07038 change_t38_state(p, T38_LOCAL_REINVITE); 07039 if (!p->pendinginvite) { 07040 transmit_reinvite_with_sdp(p, TRUE, FALSE); 07041 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 07042 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 07043 } 07044 } 07045 break; 07046 case AST_T38_TERMINATED: 07047 case AST_T38_REFUSED: 07048 case AST_T38_REQUEST_TERMINATE: /* Shutdown T38 */ 07049 if (p->t38.state == T38_PEER_REINVITE) { 07050 AST_SCHED_DEL_UNREF(sched, p->t38id, dialog_unref(p, "when you delete the t38id sched, you should dec the refcount for the stored dialog ptr")); 07051 change_t38_state(p, T38_DISABLED); 07052 transmit_response_reliable(p, "488 Not acceptable here", &p->initreq); 07053 } else if (p->t38.state == T38_ENABLED) 07054 transmit_reinvite_with_sdp(p, FALSE, FALSE); 07055 break; 07056 case AST_T38_REQUEST_PARMS: { /* Application wants remote's parameters re-sent */ 07057 struct ast_control_t38_parameters parameters = p->t38.their_parms; 07058 07059 if (p->t38.state == T38_PEER_REINVITE) { 07060 AST_SCHED_DEL_UNREF(sched, p->t38id, dialog_unref(p, "when you delete the t38id sched, you should dec the refcount for the stored dialog ptr")); 07061 parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl); 07062 parameters.request_response = AST_T38_REQUEST_NEGOTIATE; 07063 if (p->owner) { 07064 ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, ¶meters, sizeof(parameters)); 07065 } 07066 /* we need to return a positive value here, so that applications that 07067 * send this request can determine conclusively whether it was accepted or not... 07068 * older versions of chan_sip would just silently accept it and return zero. 07069 */ 07070 res = AST_T38_REQUEST_PARMS; 07071 } 07072 break; 07073 } 07074 default: 07075 res = -1; 07076 break; 07077 } 07078 07079 return res; 07080 }
| static int is_method_allowed | ( | unsigned int * | allowed_methods, | |
| enum sipmethod | method | |||
| ) | [static] |
Check if method is allowed for a device or a dialog.
Definition at line 8658 of file chan_sip.c.
Referenced by sip_sendtext(), and update_connectedline().
| static void list_route | ( | struct sip_route * | route | ) | [static] |
List all routes - mostly for debugging.
Definition at line 14686 of file chan_sip.c.
References ast_verbose.
Referenced by build_route().
14687 { 14688 if (!route) { 14689 ast_verbose("list_route: no route\n"); 14690 } else { 14691 for (;route; route = route->next) 14692 ast_verbose("list_route: hop: <%s>\n", route->hop); 14693 } 14694 }
| static int load_module | ( | void | ) | [static] |
PBX load module - initialization.
Definition at line 31787 of file chan_sip.c.
References ao2_container_alloc, ao2_t_container_alloc, ao2_t_ref, ARRAY_LEN, ast_cc_agent_register(), ast_cc_monitor_register(), ast_channel_register(), ast_check_realtime(), ast_clear_flag, ast_cli_register_multiple(), ast_custom_function_register, ast_data_register_multiple, ast_log(), ast_manager_register_xml, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_realtime_require_field(), ast_register_application_xml, ast_rtp_glue_register, ast_string_field_set, AST_TEST_REGISTER, ast_udptl_proto_register(), ast_verbose, ASTOBJ_CONTAINER_INIT, BOGUS_PEER_MD5SECRET, CHANNEL_MODULE_LOAD, dialog_cmp_cb(), dialog_hash_cb(), EVENT_FLAG_REPORTING, EVENT_FLAG_SYSTEM, initialize_escs(), io_context_create(), io_context_destroy(), LOG_ERROR, manager_show_registry(), manager_sip_qualify_peer(), manager_sip_show_peer(), manager_sip_show_peers(), manager_sipnotify(), network_change_event_subscribe(), peer_cmp_cb(), peer_hash_cb(), peer_ipcmp_cb(), peer_iphash_cb(), regl, reload_config(), restart_monitor(), RQ_CHAR, RQ_INTEGER4, RQ_UINTEGER2, sched_context_create(), sched_context_destroy(), ast_channel_tech::send_digit_begin, SENTINEL, sip_addheader(), sip_dtmfmode(), sip_epa_register(), sip_is_xml_parsable(), sip_monitor_instance_cmp_fn(), sip_monitor_instance_hash_fn(), sip_poke_all_peers(), sip_register_tests(), sip_removeheader(), sip_reqresp_parser_init(), sip_send_all_mwi_subscriptions(), sip_send_all_registers(), sip_tech_info, submwil, temp_peer(), threadt_cmp_cb(), and threadt_hash_cb().
31788 { 31789 ast_verbose("SIP channel loading...\n"); 31790 31791 /* the fact that ao2_containers can't resize automatically is a major worry! */ 31792 /* if the number of objects gets above MAX_XXX_BUCKETS, things will slow down */ 31793 peers = ao2_t_container_alloc(HASH_PEER_SIZE, peer_hash_cb, peer_cmp_cb, "allocate peers"); 31794 peers_by_ip = ao2_t_container_alloc(HASH_PEER_SIZE, peer_iphash_cb, peer_ipcmp_cb, "allocate peers_by_ip"); 31795 dialogs = ao2_t_container_alloc(HASH_DIALOG_SIZE, dialog_hash_cb, dialog_cmp_cb, "allocate dialogs"); 31796 dialogs_to_destroy = ao2_t_container_alloc(1, NULL, NULL, "allocate dialogs_to_destroy"); 31797 threadt = ao2_t_container_alloc(HASH_DIALOG_SIZE, threadt_hash_cb, threadt_cmp_cb, "allocate threadt table"); 31798 if (!peers || !peers_by_ip || !dialogs || !dialogs_to_destroy || !threadt) { 31799 ast_log(LOG_ERROR, "Unable to create primary SIP container(s)\n"); 31800 return AST_MODULE_LOAD_FAILURE; 31801 } 31802 31803 ASTOBJ_CONTAINER_INIT(®l); /* Registry object list -- not searched for anything */ 31804 ASTOBJ_CONTAINER_INIT(&submwil); /* MWI subscription object list */ 31805 31806 if (!(sched = sched_context_create())) { 31807 ast_log(LOG_ERROR, "Unable to create scheduler context\n"); 31808 return AST_MODULE_LOAD_FAILURE; 31809 } 31810 31811 if (!(io = io_context_create())) { 31812 ast_log(LOG_ERROR, "Unable to create I/O context\n"); 31813 sched_context_destroy(sched); 31814 return AST_MODULE_LOAD_FAILURE; 31815 } 31816 31817 sip_reloadreason = CHANNEL_MODULE_LOAD; 31818 31819 can_parse_xml = sip_is_xml_parsable(); 31820 if (reload_config(sip_reloadreason)) { /* Load the configuration from sip.conf */ 31821 return AST_MODULE_LOAD_DECLINE; 31822 } 31823 31824 /* Initialize bogus peer. Can be done first after reload_config() */ 31825 if (!(bogus_peer = temp_peer("(bogus_peer)"))) { 31826 ast_log(LOG_ERROR, "Unable to create bogus_peer for authentication\n"); 31827 io_context_destroy(io); 31828 sched_context_destroy(sched); 31829 return AST_MODULE_LOAD_FAILURE; 31830 } 31831 /* Make sure the auth will always fail. */ 31832 ast_string_field_set(bogus_peer, md5secret, BOGUS_PEER_MD5SECRET); 31833 ast_clear_flag(&bogus_peer->flags[0], SIP_INSECURE); 31834 31835 /* Prepare the version that does not require DTMF BEGIN frames. 31836 * We need to use tricks such as memcpy and casts because the variable 31837 * has const fields. 31838 */ 31839 memcpy(&sip_tech_info, &sip_tech, sizeof(sip_tech)); 31840 memset((void *) &sip_tech_info.send_digit_begin, 0, sizeof(sip_tech_info.send_digit_begin)); 31841 31842 /* Make sure we can register our sip channel type */ 31843 if (ast_channel_register(&sip_tech)) { 31844 ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n"); 31845 ao2_t_ref(bogus_peer, -1, "unref the bogus_peer"); 31846 io_context_destroy(io); 31847 sched_context_destroy(sched); 31848 return AST_MODULE_LOAD_FAILURE; 31849 } 31850 31851 #ifdef TEST_FRAMEWORK 31852 AST_TEST_REGISTER(test_sip_peers_get); 31853 AST_TEST_REGISTER(test_sip_mwi_subscribe_parse); 31854 AST_TEST_REGISTER(test_tcp_message_fragmentation); 31855 AST_TEST_REGISTER(get_in_brackets_const_test); 31856 #endif 31857 31858 /* Register AstData providers */ 31859 ast_data_register_multiple(sip_data_providers, ARRAY_LEN(sip_data_providers)); 31860 31861 /* Register all CLI functions for SIP */ 31862 ast_cli_register_multiple(cli_sip, ARRAY_LEN(cli_sip)); 31863 31864 /* Tell the UDPTL subdriver that we're here */ 31865 ast_udptl_proto_register(&sip_udptl); 31866 31867 /* Tell the RTP engine about our RTP glue */ 31868 ast_rtp_glue_register(&sip_rtp_glue); 31869 31870 /* Register dialplan applications */ 31871 ast_register_application_xml(app_dtmfmode, sip_dtmfmode); 31872 ast_register_application_xml(app_sipaddheader, sip_addheader); 31873 ast_register_application_xml(app_sipremoveheader, sip_removeheader); 31874 31875 /* Register dialplan functions */ 31876 ast_custom_function_register(&sip_header_function); 31877 ast_custom_function_register(&sippeer_function); 31878 ast_custom_function_register(&sipchaninfo_function); 31879 ast_custom_function_register(&checksipdomain_function); 31880 31881 /* Register manager commands */ 31882 ast_manager_register_xml("SIPpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_sip_show_peers); 31883 ast_manager_register_xml("SIPshowpeer", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_sip_show_peer); 31884 ast_manager_register_xml("SIPqualifypeer", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_sip_qualify_peer); 31885 ast_manager_register_xml("SIPshowregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_show_registry); 31886 ast_manager_register_xml("SIPnotify", EVENT_FLAG_SYSTEM, manager_sipnotify); 31887 sip_poke_all_peers(); 31888 sip_send_all_registers(); 31889 sip_send_all_mwi_subscriptions(); 31890 initialize_escs(); 31891 31892 if (sip_epa_register(&cc_epa_static_data)) { 31893 return AST_MODULE_LOAD_DECLINE; 31894 } 31895 31896 if (sip_reqresp_parser_init() == -1) { 31897 ast_log(LOG_ERROR, "Unable to initialize the SIP request and response parser\n"); 31898 return AST_MODULE_LOAD_DECLINE; 31899 } 31900 31901 if (can_parse_xml) { 31902 /* SIP CC agents require the ability to parse XML PIDF bodies 31903 * in incoming PUBLISH requests 31904 */ 31905 if (ast_cc_agent_register(&sip_cc_agent_callbacks)) { 31906 return AST_MODULE_LOAD_DECLINE; 31907 } 31908 } 31909 if (ast_cc_monitor_register(&sip_cc_monitor_callbacks)) { 31910 return AST_MODULE_LOAD_DECLINE; 31911 } 31912 if (!(sip_monitor_instances = ao2_container_alloc(37, sip_monitor_instance_hash_fn, sip_monitor_instance_cmp_fn))) { 31913 return AST_MODULE_LOAD_DECLINE; 31914 } 31915 31916 /* And start the monitor for the first time */ 31917 restart_monitor(); 31918 31919 ast_realtime_require_field(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", 31920 "name", RQ_CHAR, 10, 31921 "ipaddr", RQ_CHAR, INET6_ADDRSTRLEN - 1, 31922 "port", RQ_UINTEGER2, 5, 31923 "regseconds", RQ_INTEGER4, 11, 31924 "defaultuser", RQ_CHAR, 10, 31925 "fullcontact", RQ_CHAR, 35, 31926 "regserver", RQ_CHAR, 20, 31927 "useragent", RQ_CHAR, 20, 31928 "lastms", RQ_INTEGER4, 11, 31929 SENTINEL); 31930 31931 31932 sip_register_tests(); 31933 network_change_event_subscribe(); 31934 31935 return AST_MODULE_LOAD_SUCCESS; 31936 }
| static int local_attended_transfer | ( | struct sip_pvt * | transferer, | |
| struct sip_dual * | current, | |||
| struct sip_request * | req, | |||
| uint32_t | seqno, | |||
| int * | nounlock | |||
| ) | [static] |
Find all call legs and bridge transferee with target called from handle_request_refer.
If this function is successful, only the transferer pvt lock will remain on return. Setting nounlock indicates to handle_request_do() that the pvt's owner it locked does not require an unlock.
Definition at line 23877 of file chan_sip.c.
References ao2_t_ref, append_history, ast_alloca, ast_bridged_channel(), AST_CEL_ATTENDEDTRANSFER, ast_cel_report_event(), ast_channel_queue_connected_line_update(), ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_clear_flag, ast_connected_line_build_data(), AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, AST_CONTROL_READ_ACTION, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, ast_copy_string(), ast_debug, ast_do_masquerade(), AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO, ast_indicate(), ast_manager_event_multichan, ast_party_connected_line_copy(), ast_party_connected_line_free(), ast_party_connected_line_init(), ast_queue_control_data(), ast_set_flag, ast_state2str(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_streamfile(), ast_strlen_zero(), ast_waitstream(), attempt_transfer(), EVENT_FLAG_CALL, frame_size, get_sip_pvt_byid_locked(), pbx_builtin_getvar_helper(), sip_pvt_lock, sip_pvt_unlock, ast_party_connected_line::source, transmit_notify_with_sipfrag(), TRUE, and xfersound.
Referenced by handle_request_refer().
23878 { 23879 struct sip_dual target; /* Chan 1: Call from tranferer to Asterisk */ 23880 /* Chan 2: Call from Asterisk to target */ 23881 int res = 0; 23882 struct sip_pvt *targetcall_pvt; 23883 struct ast_party_connected_line connected_to_transferee; 23884 struct ast_party_connected_line connected_to_target; 23885 char transferer_linkedid[32]; 23886 struct ast_channel *chans[2]; 23887 23888 /* Check if the call ID of the replaces header does exist locally */ 23889 if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 23890 transferer->refer->replaces_callid_fromtag))) { 23891 if (transferer->refer->localtransfer) { 23892 /* We did not find the refered call. Sorry, can't accept then */ 23893 /* Let's fake a response from someone else in order 23894 to follow the standard */ 23895 transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE); 23896 append_history(transferer, "Xfer", "Refer failed"); 23897 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 23898 transferer->refer->status = REFER_FAILED; 23899 return -1; 23900 } 23901 /* Fall through for remote transfers that we did not find locally */ 23902 ast_debug(3, "SIP attended transfer: Not our call - generating INVITE with replaces\n"); 23903 return 0; 23904 } 23905 23906 /* Ok, we can accept this transfer */ 23907 append_history(transferer, "Xfer", "Refer accepted"); 23908 if (!targetcall_pvt->owner) { /* No active channel */ 23909 ast_debug(4, "SIP attended transfer: Error: No owner of target call\n"); 23910 /* Cancel transfer */ 23911 transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE); 23912 append_history(transferer, "Xfer", "Refer failed"); 23913 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 23914 transferer->refer->status = REFER_FAILED; 23915 sip_pvt_unlock(targetcall_pvt); 23916 if (targetcall_pvt) 23917 ao2_t_ref(targetcall_pvt, -1, "Drop targetcall_pvt pointer"); 23918 return -1; 23919 } 23920 23921 /* We have a channel, find the bridge */ 23922 target.chan1 = ast_channel_ref(targetcall_pvt->owner); /* Transferer to Asterisk */ 23923 target.chan2 = ast_bridged_channel(targetcall_pvt->owner); /* Asterisk to target */ 23924 if (target.chan2) { 23925 ast_channel_ref(target.chan2); 23926 } 23927 23928 if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) { 23929 /* Wrong state of new channel */ 23930 if (target.chan2) 23931 ast_debug(4, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state)); 23932 else if (target.chan1->_state != AST_STATE_RING) 23933 ast_debug(4, "SIP attended transfer: Error: No target channel\n"); 23934 else 23935 ast_debug(4, "SIP attended transfer: Attempting transfer in ringing state\n"); 23936 } 23937 23938 /* Transfer */ 23939 if (sipdebug) { 23940 if (current->chan2) /* We have two bridges */ 23941 ast_debug(4, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name); 23942 else /* One bridge, propably transfer of IVR/voicemail etc */ 23943 ast_debug(4, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name); 23944 } 23945 23946 ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 23947 23948 ast_copy_string(transferer_linkedid, transferer->owner->linkedid, sizeof(transferer_linkedid)); 23949 23950 /* Perform the transfer */ 23951 chans[0] = transferer->owner; 23952 chans[1] = target.chan1; 23953 ast_manager_event_multichan(EVENT_FLAG_CALL, "Transfer", 2, chans, 23954 "TransferMethod: SIP\r\n" 23955 "TransferType: Attended\r\n" 23956 "Channel: %s\r\n" 23957 "Uniqueid: %s\r\n" 23958 "SIP-Callid: %s\r\n" 23959 "TargetChannel: %s\r\n" 23960 "TargetUniqueid: %s\r\n", 23961 transferer->owner->name, 23962 transferer->owner->uniqueid, 23963 transferer->callid, 23964 target.chan1->name, 23965 target.chan1->uniqueid); 23966 ast_party_connected_line_init(&connected_to_transferee); 23967 ast_party_connected_line_init(&connected_to_target); 23968 /* No need to lock current->chan1 here since it was locked in sipsock_read */ 23969 ast_party_connected_line_copy(&connected_to_transferee, ¤t->chan1->connected); 23970 /* No need to lock target.chan1 here since it was locked in get_sip_pvt_byid_locked */ 23971 ast_party_connected_line_copy(&connected_to_target, &target.chan1->connected); 23972 connected_to_target.source = connected_to_transferee.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER; 23973 res = attempt_transfer(current, &target); 23974 if (res) { 23975 /* Failed transfer */ 23976 transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE); 23977 append_history(transferer, "Xfer", "Refer failed"); 23978 ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); 23979 /* if transfer failed, go ahead and unlock targetcall_pvt and it's owner channel */ 23980 sip_pvt_unlock(targetcall_pvt); 23981 ast_channel_unlock(target.chan1); 23982 } else { 23983 /* Transfer succeeded! */ 23984 const char *xfersound = pbx_builtin_getvar_helper(target.chan1, "ATTENDED_TRANSFER_COMPLETE_SOUND"); 23985 23986 /* target.chan1 was locked in get_sip_pvt_byid_locked, do not unlock target.chan1 before this */ 23987 ast_cel_report_event(target.chan1, AST_CEL_ATTENDEDTRANSFER, NULL, transferer_linkedid, target.chan2); 23988 23989 /* Tell transferer that we're done. */ 23990 transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE); 23991 append_history(transferer, "Xfer", "Refer succeeded"); 23992 transferer->refer->status = REFER_200OK; 23993 if (target.chan2 && !ast_strlen_zero(xfersound) && ast_streamfile(target.chan2, xfersound, target.chan2->language) >= 0) { 23994 ast_waitstream(target.chan2, ""); 23995 } 23996 23997 /* By forcing the masquerade, we know that target.chan1 and target.chan2 are bridged. We then 23998 * can queue connected line updates where they need to go. 23999 * 24000 * before a masquerade, all channel and pvt locks must be unlocked. Any recursive 24001 * channel locks held before this function invalidates channel container locking order. 24002 * Since we are unlocking both the pvt (transferer) and its owner channel (current.chan1) 24003 * it is possible for current.chan1 to be destroyed in the pbx thread. To prevent this 24004 * we must give c a reference before any unlocking takes place. 24005 */ 24006 24007 ast_channel_ref(current->chan1); 24008 ast_channel_unlock(current->chan1); /* current.chan1 is p->owner before the masq, it was locked by socket_read()*/ 24009 ast_channel_unlock(target.chan1); 24010 *nounlock = 1; /* we just unlocked the dialog's channel and have no plans of locking it again. */ 24011 sip_pvt_unlock(targetcall_pvt); 24012 sip_pvt_unlock(transferer); 24013 24014 ast_do_masquerade(target.chan1); 24015 24016 if (target.chan2) { 24017 ast_indicate(target.chan2, AST_CONTROL_UNHOLD); 24018 } 24019 24020 if (current->chan2 && current->chan2->_state == AST_STATE_RING) { 24021 ast_indicate(target.chan1, AST_CONTROL_RINGING); 24022 } 24023 24024 if (target.chan2) { 24025 ast_channel_queue_connected_line_update(target.chan1, &connected_to_transferee, NULL); 24026 ast_channel_queue_connected_line_update(target.chan2, &connected_to_target, NULL); 24027 } else { 24028 /* Since target.chan1 isn't actually connected to another channel, there is no way for us 24029 * to queue a frame so that its connected line status will be updated. 24030 * 24031 * Instead, we use the somewhat hackish approach of using a special control frame type that 24032 * instructs ast_read to perform a specific action. In this case, the frame we queue tells 24033 * ast_read to call the connected line interception macro configured for target.chan1. 24034 */ 24035 struct ast_control_read_action_payload *frame_payload; 24036 int payload_size; 24037 int frame_size; 24038 unsigned char connected_line_data[1024]; 24039 payload_size = ast_connected_line_build_data(connected_line_data, 24040 sizeof(connected_line_data), &connected_to_target, NULL); 24041 frame_size = payload_size + sizeof(*frame_payload); 24042 if (payload_size != -1) { 24043 frame_payload = ast_alloca(frame_size); 24044 frame_payload->payload_size = payload_size; 24045 memcpy(frame_payload->payload, connected_line_data, payload_size); 24046 frame_payload->action = AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO; 24047 ast_queue_control_data(target.chan1, AST_CONTROL_READ_ACTION, frame_payload, frame_size); 24048 } 24049 /* In addition to queueing the read action frame so that target.chan1's connected line info 24050 * will be updated, we also are going to queue a plain old connected line update on target.chan1. This 24051 * way, either Dial or Queue can apply this connected line update to the outgoing ringing channel. 24052 */ 24053 ast_channel_queue_connected_line_update(target.chan1, &connected_to_transferee, NULL); 24054 24055 } 24056 sip_pvt_lock(transferer); /* the transferer pvt is expected to remain locked on return */ 24057 24058 ast_channel_unref(current->chan1); 24059 } 24060 24061 /* at this point if the transfer is successful only the transferer pvt should be locked. */ 24062 ast_party_connected_line_free(&connected_to_target); 24063 ast_party_connected_line_free(&connected_to_transferee); 24064 ast_channel_unref(target.chan1); 24065 if (target.chan2) { 24066 ast_channel_unref(target.chan2); 24067 } 24068 if (targetcall_pvt) 24069 ao2_t_ref(targetcall_pvt, -1, "drop targetcall_pvt"); 24070 return 1; 24071 }
| static void lws2sws | ( | struct ast_str * | msgbuf | ) | [static] |
Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled.
Definition at line 8746 of file chan_sip.c.
References ast_str_strlen(), and len().
Referenced by handle_request_do(), and read_raw_content_length().
08747 { 08748 char *msgbuf = data->str; 08749 int len = ast_str_strlen(data); 08750 int h = 0, t = 0; 08751 int lws = 0; 08752 08753 for (; h < len;) { 08754 /* Eliminate all CRs */ 08755 if (msgbuf[h] == '\r') { 08756 h++; 08757 continue; 08758 } 08759 /* Check for end-of-line */ 08760 if (msgbuf[h] == '\n') { 08761 /* Check for end-of-message */ 08762 if (h + 1 == len) 08763 break; 08764 /* Check for a continuation line */ 08765 if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 08766 /* Merge continuation line */ 08767 h++; 08768 continue; 08769 } 08770 /* Propagate LF and start new line */ 08771 msgbuf[t++] = msgbuf[h++]; 08772 lws = 0; 08773 continue; 08774 } 08775 if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 08776 if (lws) { 08777 h++; 08778 continue; 08779 } 08780 msgbuf[t++] = msgbuf[h++]; 08781 lws = 1; 08782 continue; 08783 } 08784 msgbuf[t++] = msgbuf[h++]; 08785 if (lws) 08786 lws = 0; 08787 } 08788 msgbuf[t] = '\0'; 08789 data->used = t; 08790 }
| static void make_our_tag | ( | struct sip_pvt * | pvt | ) | [static] |
Make our SIP dialog tag.
Definition at line 7938 of file chan_sip.c.
References ast_random(), and ast_string_field_build.
Referenced by handle_request_invite(), handle_request_subscribe(), sip_alloc(), and transmit_response_using_temp().
07939 { 07940 ast_string_field_build(pvt, tag, "as%08lx", (unsigned long)ast_random()); 07941 }
| static int manager_show_registry | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Show SIP registrations in the manager API.
Definition at line 17186 of file chan_sip.c.
References ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_listack(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, regl, regstate2str(), S_OR, and total.
Referenced by load_module().
17187 { 17188 const char *id = astman_get_header(m, "ActionID"); 17189 char idtext[256] = ""; 17190 int total = 0; 17191 17192 if (!ast_strlen_zero(id)) 17193 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 17194 17195 astman_send_listack(s, m, "Registrations will follow", "start"); 17196 17197 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 17198 ASTOBJ_RDLOCK(iterator); 17199 astman_append(s, 17200 "Event: RegistryEntry\r\n" 17201 "%s" 17202 "Host: %s\r\n" 17203 "Port: %d\r\n" 17204 "Username: %s\r\n" 17205 "Domain: %s\r\n" 17206 "DomainPort: %d\r\n" 17207 "Refresh: %d\r\n" 17208 "State: %s\r\n" 17209 "RegistrationTime: %ld\r\n" 17210 "\r\n", 17211 idtext, 17212 iterator->hostname, 17213 iterator->portno ? iterator->portno : STANDARD_SIP_PORT, 17214 iterator->username, 17215 S_OR(iterator->regdomain,iterator->hostname), 17216 iterator->regdomainport ? iterator->regdomainport : STANDARD_SIP_PORT, 17217 iterator->refresh, 17218 regstate2str(iterator->regstate), 17219 (long) iterator->regtime.tv_sec); 17220 ASTOBJ_UNLOCK(iterator); 17221 total++; 17222 } while(0)); 17223 17224 astman_append(s, 17225 "Event: RegistrationsComplete\r\n" 17226 "EventList: Complete\r\n" 17227 "ListItems: %d\r\n" 17228 "%s" 17229 "\r\n", total, idtext); 17230 17231 return 0; 17232 }
| static int manager_sip_qualify_peer | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Qualify SIP peers in the manager API.
Definition at line 17996 of file chan_sip.c.
References _sip_qualify_peer(), ast_strlen_zero(), astman_append(), astman_get_header(), and astman_send_error().
Referenced by load_module().
17997 { 17998 const char *a[4]; 17999 const char *peer; 18000 18001 peer = astman_get_header(m, "Peer"); 18002 if (ast_strlen_zero(peer)) { 18003 astman_send_error(s, m, "Peer: <name> missing."); 18004 return 0; 18005 } 18006 a[0] = "sip"; 18007 a[1] = "qualify"; 18008 a[2] = "peer"; 18009 a[3] = peer; 18010 18011 _sip_qualify_peer(1, -1, s, m, 4, a); 18012 astman_append(s, "\r\n\r\n" ); 18013 return 0; 18014 }
| static int manager_sip_show_peer | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Show SIP peers in the manager API.
Definition at line 17937 of file chan_sip.c.
References _sip_show_peer(), ast_strlen_zero(), astman_append(), astman_get_header(), and astman_send_error().
Referenced by load_module().
17938 { 17939 const char *a[4]; 17940 const char *peer; 17941 17942 peer = astman_get_header(m, "Peer"); 17943 if (ast_strlen_zero(peer)) { 17944 astman_send_error(s, m, "Peer: <name> missing."); 17945 return 0; 17946 } 17947 a[0] = "sip"; 17948 a[1] = "show"; 17949 a[2] = "peer"; 17950 a[3] = peer; 17951 17952 _sip_show_peer(1, -1, s, m, 4, a); 17953 astman_append(s, "\r\n" ); 17954 return 0; 17955 }
| static int manager_sip_show_peers | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Show SIP peers in the manager API.
Definition at line 17236 of file chan_sip.c.
References _sip_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_listack(), and total.
Referenced by load_module().
17237 { 17238 const char *id = astman_get_header(m, "ActionID"); 17239 const char *a[] = {"sip", "show", "peers"}; 17240 char idtext[256] = ""; 17241 int total = 0; 17242 17243 if (!ast_strlen_zero(id)) 17244 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 17245 17246 astman_send_listack(s, m, "Peer status list will follow", "start"); 17247 /* List the peers in separate manager events */ 17248 _sip_show_peers(-1, &total, s, m, 3, a); 17249 /* Send final confirmation */ 17250 astman_append(s, 17251 "Event: PeerlistComplete\r\n" 17252 "EventList: Complete\r\n" 17253 "ListItems: %d\r\n" 17254 "%s" 17255 "\r\n", total, idtext); 17256 return 0; 17257 }
| static int manager_sipnotify | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 13406 of file chan_sip.c.
References ast_log(), ast_set_flag, ast_str_append(), ast_str_strlen(), ast_strlen_zero(), ast_variable_new(), ast_variables_destroy(), astman_get_header(), astman_get_variables_order(), astman_send_ack(), astman_send_error(), create_addr(), dialog_unlink_all(), LOG_WARNING, ast_variable::name, ast_variable::next, ORDER_NATURAL, sip_alloc(), sip_notify_allocate(), sip_scheddestroy(), transmit_invite(), ast_variable::value, and var.
Referenced by load_module().
13407 { 13408 const char *channame = astman_get_header(m, "Channel"); 13409 struct ast_variable *vars = astman_get_variables_order(m, ORDER_NATURAL); 13410 struct sip_pvt *p; 13411 struct ast_variable *header, *var; 13412 13413 if (ast_strlen_zero(channame)) { 13414 astman_send_error(s, m, "SIPNotify requires a channel name"); 13415 return 0; 13416 } 13417 13418 if (!strncasecmp(channame, "sip/", 4)) { 13419 channame += 4; 13420 } 13421 13422 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) { 13423 astman_send_error(s, m, "Unable to build sip pvt data for notify (memory/socket error)"); 13424 return 0; 13425 } 13426 13427 if (create_addr(p, channame, NULL, 0)) { 13428 /* Maybe they're not registered, etc. */ 13429 dialog_unlink_all(p); 13430 dialog_unref(p, "unref dialog inside for loop" ); 13431 /* sip_destroy(p); */ 13432 astman_send_error(s, m, "Could not create address"); 13433 return 0; 13434 } 13435 13436 /* Notify is outgoing call */ 13437 ast_set_flag(&p->flags[0], SIP_OUTGOING); 13438 sip_notify_allocate(p); 13439 13440 p->notify->headers = header = ast_variable_new("Subscription-State", "terminated", ""); 13441 13442 for (var = vars; var; var = var->next) { 13443 if (!strcasecmp(var->name, "Content")) { 13444 if (ast_str_strlen(p->notify->content)) 13445 ast_str_append(&p->notify->content, 0, "\r\n"); 13446 ast_str_append(&p->notify->content, 0, "%s", var->value); 13447 } else if (!strcasecmp(var->name, "Content-Length")) { 13448 ast_log(LOG_WARNING, "it is not necessary to specify Content-Length, ignoring\n"); 13449 } else { 13450 header->next = ast_variable_new(var->name, var->value, ""); 13451 header = header->next; 13452 } 13453 } 13454 13455 sip_scheddestroy(p, SIP_TRANS_TIMEOUT); 13456 transmit_invite(p, SIP_NOTIFY, 0, 2, NULL); 13457 dialog_unref(p, "bump down the count of p since we're done with it."); 13458 13459 astman_send_ack(s, m, "Notify Sent"); 13460 ast_variables_destroy(vars); 13461 return 0; 13462 }
| static int map_s_x | ( | const struct _map_x_s * | table, | |
| const char * | s, | |||
| int | errorvalue | |||
| ) | [static] |
map from a string to an integer value, case insensitive. If no match is found, return errorvalue.
Definition at line 2261 of file chan_sip.c.
Referenced by str2dtmfmode(), str2stmode(), and str2strefresherparam().
02262 { 02263 const struct _map_x_s *cur; 02264 02265 for (cur = table; cur->s; cur++) 02266 if (!strcasecmp(cur->s, s)) 02267 return cur->x; 02268 return errorvalue; 02269 }
| static const char* map_x_s | ( | const struct _map_x_s * | table, | |
| int | x, | |||
| const char * | errorstring | |||
| ) | [static] |
map from an integer value to a string. If no match is found, return errorstring
Definition at line 2248 of file chan_sip.c.
Referenced by allowoverlap2str(), dtmfmode2str(), faxec2str(), insecure2str(), referstatus2str(), regstate2str(), stmode2str(), strefresher2str(), strefresherparam2str(), and trust_id_outbound2str().
02249 { 02250 const struct _map_x_s *cur; 02251 02252 for (cur = table; cur->s; cur++) 02253 if (cur->x == x) 02254 return cur->s; 02255 return errorstring; 02256 }
| static void mark_method_allowed | ( | unsigned int * | allowed_methods, | |
| enum sipmethod | method | |||
| ) | [static] |
Definition at line 8647 of file chan_sip.c.
Referenced by handle_response(), handle_response_info(), handle_response_message(), mark_parsed_methods(), and set_pvt_allowed_methods().
| static void mark_method_unallowed | ( | unsigned int * | allowed_methods, | |
| enum sipmethod | method | |||
| ) | [static] |
Definition at line 8652 of file chan_sip.c.
Referenced by handle_response(), handle_response_info(), handle_response_message(), and handle_response_publish().
| static void mark_parsed_methods | ( | unsigned int * | methods, | |
| char * | methods_str | |||
| ) | [static] |
Definition at line 8663 of file chan_sip.c.
References ast_skip_blanks(), ast_strlen_zero(), find_sip_method(), and mark_method_allowed().
Referenced by build_peer(), parse_allowed_methods(), and reload_config().
08664 { 08665 char *method; 08666 for (method = strsep(&methods_str, ","); !ast_strlen_zero(method); method = strsep(&methods_str, ",")) { 08667 int id = find_sip_method(ast_skip_blanks(method)); 08668 if (id == SIP_UNKNOWN) { 08669 continue; 08670 } 08671 mark_method_allowed(methods, id); 08672 } 08673 }
| static int match_and_cleanup_peer_sched | ( | void * | peerobj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 3011 of file chan_sip.c.
References ast_dnsmgr_release(), CMP_MATCH, peer_sched_cleanup(), SIP_PEERS_ALL, and unref_peer().
Referenced by unlink_peers_from_tables().
03012 { 03013 struct sip_peer *peer = peerobj; 03014 peer_unlink_flag_t which = *(peer_unlink_flag_t *)arg; 03015 03016 if (which == SIP_PEERS_ALL || peer->the_mark) { 03017 peer_sched_cleanup(peer); 03018 if (peer->dnsmgr) { 03019 ast_dnsmgr_release(peer->dnsmgr); 03020 peer->dnsmgr = NULL; 03021 unref_peer(peer, "Release peer from dnsmgr"); 03022 } 03023 return CMP_MATCH; 03024 } 03025 return 0; 03026 }
| static enum match_req_res match_req_to_dialog | ( | struct sip_pvt * | sip_pvt_ptr, | |
| struct match_req_args * | arg | |||
| ) | [static] |
Definition at line 8184 of file chan_sip.c.
References ast_strlen_zero(), ast_test_flag, match_req_args::authentication_present, match_req_args::callid, match_req_args::fromtag, match_req_args::method, match_req_args::ruri, match_req_args::seqno, SIP_REQ_LOOP_DETECTED, SIP_REQ_MATCH, SIP_REQ_NOT_MATCH, sip_uri_cmp(), match_req_args::totag, match_req_args::viabranch, and match_req_args::viasentby.
Referenced by find_call().
08185 { 08186 const char *init_ruri = NULL; 08187 if (sip_pvt_ptr->initreq.headers) { 08188 init_ruri = REQ_OFFSET_TO_STR(&sip_pvt_ptr->initreq, rlPart2); 08189 } 08190 08191 /* 08192 * Match Tags and call-id to Dialog 08193 */ 08194 if (!ast_strlen_zero(arg->callid) && strcmp(sip_pvt_ptr->callid, arg->callid)) { 08195 /* call-id does not match. */ 08196 return SIP_REQ_NOT_MATCH; 08197 } 08198 if (arg->method == SIP_RESPONSE) { 08199 /* Verify totag if we have one stored for this dialog, but never be strict about this for 08200 * a response until the dialog is established */ 08201 if (!ast_strlen_zero(sip_pvt_ptr->theirtag) && ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) { 08202 if (ast_strlen_zero(arg->totag)) { 08203 /* missing totag when they already gave us one earlier */ 08204 return SIP_REQ_NOT_MATCH; 08205 } 08206 if (strcmp(arg->totag, sip_pvt_ptr->theirtag)) { 08207 /* The totag of the response does not match the one we have stored */ 08208 return SIP_REQ_NOT_MATCH; 08209 } 08210 } 08211 /* Verify fromtag of response matches the tag we gave them. */ 08212 if (strcmp(arg->fromtag, sip_pvt_ptr->tag)) { 08213 /* fromtag from response does not match our tag */ 08214 return SIP_REQ_NOT_MATCH; 08215 } 08216 } else { 08217 /* Verify the fromtag of Request matches the tag they provided earlier. 08218 * If this is a Request with authentication credentials, forget their old 08219 * tag as it is not valid after the 401 or 407 response. */ 08220 if (!arg->authentication_present && strcmp(arg->fromtag, sip_pvt_ptr->theirtag)) { 08221 /* their tag does not match the one was have stored for them */ 08222 return SIP_REQ_NOT_MATCH; 08223 } 08224 /* Verify if totag is present in Request, that it matches what we gave them as our tag earlier */ 08225 if (!ast_strlen_zero(arg->totag) && (strcmp(arg->totag, sip_pvt_ptr->tag))) { 08226 /* totag from Request does not match our tag */ 08227 return SIP_REQ_NOT_MATCH; 08228 } 08229 } 08230 08231 /* 08232 * Compare incoming request against initial transaction. 08233 * 08234 * This is a best effort attempt at distinguishing forked requests from 08235 * our initial transaction. If all the elements are NOT in place to evaluate 08236 * this, this block is ignored and the dialog match is made regardless. 08237 * Once the totag is established after the dialog is confirmed, this is not necessary. 08238 * 08239 * CRITERIA required for initial transaction matching. 08240 * 08241 * 1. Is a Request 08242 * 2. Callid and theirtag match (this is done in the dialog matching block) 08243 * 3. totag is NOT present 08244 * 4. CSeq matchs our initial transaction's cseq number 08245 * 5. pvt has init via branch parameter stored 08246 */ 08247 if ((arg->method != SIP_RESPONSE) && /* must be a Request */ 08248 ast_strlen_zero(arg->totag) && /* must not have a totag */ 08249 (sip_pvt_ptr->init_icseq == arg->seqno) && /* the cseq must be the same as this dialogs initial cseq */ 08250 !ast_strlen_zero(sip_pvt_ptr->initviabranch) && /* The dialog must have started with a RFC3261 compliant branch tag */ 08251 init_ruri) { /* the dialog must have an initial request uri associated with it */ 08252 /* This Request matches all the criteria required for Loop/Merge detection. 08253 * Now we must go down the path of comparing VIA's and RURIs. */ 08254 if (ast_strlen_zero(arg->viabranch) || 08255 strcmp(arg->viabranch, sip_pvt_ptr->initviabranch) || 08256 ast_strlen_zero(arg->viasentby) || 08257 strcmp(arg->viasentby, sip_pvt_ptr->initviasentby)) { 08258 /* At this point, this request does not match this Dialog.*/ 08259 08260 /* if methods are different this is just a mismatch */ 08261 if ((sip_pvt_ptr->method != arg->method)) { 08262 return SIP_REQ_NOT_MATCH; 08263 } 08264 08265 /* If RUIs are different, this is a forked request to a separate URI. 08266 * Returning a mismatch allows this Request to be processed separately. */ 08267 if (sip_uri_cmp(init_ruri, arg->ruri)) { 08268 /* not a match, request uris are different */ 08269 return SIP_REQ_NOT_MATCH; 08270 } 08271 08272 /* Loop/Merge Detected 08273 * 08274 * ---Current Matches to Initial Request--- 08275 * request uri 08276 * Call-id 08277 * their-tag 08278 * no totag present 08279 * method 08280 * cseq 08281 * 08282 * --- Does not Match Initial Request --- 08283 * Top Via 08284 * 08285 * Without the same Via, this can not match our initial transaction for this dialog, 08286 * but given that this Request matches everything else associated with that initial 08287 * Request this is most certainly a Forked request in which we have already received 08288 * part of the fork. 08289 */ 08290 return SIP_REQ_LOOP_DETECTED; 08291 } 08292 } /* end of Request Via check */ 08293 08294 /* Match Authentication Request. 08295 * 08296 * A Request with an Authentication header must come back with the 08297 * same Request URI. Otherwise it is not a match. 08298 */ 08299 if ((arg->method != SIP_RESPONSE) && /* Must be a Request type to even begin checking this */ 08300 ast_strlen_zero(arg->totag) && /* no totag is present to match */ 08301 arg->authentication_present && /* Authentication header is present in Request */ 08302 sip_uri_cmp(init_ruri, arg->ruri)) { /* Compare the Request URI of both the last Request and this new one */ 08303 08304 /* Authentication was provided, but the Request URI did not match the last one on this dialog. */ 08305 return SIP_REQ_NOT_MATCH; 08306 } 08307 08308 return SIP_REQ_MATCH; 08309 }
| static int method_match | ( | enum sipmethod | id, | |
| const char * | name | |||
| ) | [static] |
returns true if 'name' (with optional trailing whitespace) matches the sip method 'id'. Strictly speaking, SIP methods are case SENSITIVE, but we do a case-insensitive comparison to be more tolerant. following Jon Postel's rule: Be gentle in what you accept, strict with what you send
Definition at line 3346 of file chan_sip.c.
References len(), sip_methods, and text.
Referenced by __sip_autodestruct(), __sip_semi_ack(), and find_sip_method().
03347 { 03348 int len = strlen(sip_methods[id].text); 03349 int l_name = name ? strlen(name) : 0; 03350 /* true if the string is long enough, and ends with whitespace, and matches */ 03351 return (l_name >= len && name && name[len] < 33 && 03352 !strncasecmp(sip_methods[id].text, name, len)); 03353 }
| static void mwi_event_cb | ( | const struct ast_event * | event, | |
| void * | userdata | |||
| ) | [static] |
Receive MWI events that we have subscribed to.
Definition at line 15048 of file chan_sip.c.
References sip_send_mwi_to_peer().
Referenced by add_peer_mwi_subs().
15049 { 15050 struct sip_peer *peer = userdata; 15051 15052 sip_send_mwi_to_peer(peer, 0); 15053 }
| static void network_change_event_cb | ( | const struct ast_event * | event, | |
| void * | userdata | |||
| ) | [static] |
Definition at line 15078 of file chan_sip.c.
References ast_debug, ast_sched_add(), and network_change_event_sched_cb().
Referenced by network_change_event_subscribe().
15079 { 15080 ast_debug(1, "SIP, got a network change event, renewing all SIP registrations.\n"); 15081 if (network_change_event_sched_id == -1) { 15082 network_change_event_sched_id = ast_sched_add(sched, 1000, network_change_event_sched_cb, NULL); 15083 } 15084 }
| static int network_change_event_sched_cb | ( | const void * | data | ) | [static] |
Definition at line 15070 of file chan_sip.c.
References sip_send_all_mwi_subscriptions(), and sip_send_all_registers().
Referenced by network_change_event_cb().
15071 { 15072 network_change_event_sched_id = -1; 15073 sip_send_all_registers(); 15074 sip_send_all_mwi_subscriptions(); 15075 return 0; 15076 }
| static void network_change_event_subscribe | ( | void | ) | [static] |
Definition at line 15055 of file chan_sip.c.
References AST_EVENT_IE_END, AST_EVENT_NETWORK_CHANGE, ast_event_subscribe(), and network_change_event_cb().
Referenced by load_module(), and reload_config().
15056 { 15057 if (!network_change_event_subscription) { 15058 network_change_event_subscription = ast_event_subscribe(AST_EVENT_NETWORK_CHANGE, 15059 network_change_event_cb, "SIP Network Change", NULL, AST_EVENT_IE_END); 15060 } 15061 }
| static void network_change_event_unsubscribe | ( | void | ) | [static] |
Definition at line 15063 of file chan_sip.c.
References ast_event_unsubscribe().
Referenced by reload_config(), and unload_module().
15064 { 15065 if (network_change_event_subscription) { 15066 network_change_event_subscription = ast_event_unsubscribe(network_change_event_subscription); 15067 } 15068 }
| static struct sip_proxy* obproxy_get | ( | struct sip_pvt * | dialog, | |
| struct sip_peer * | peer | |||
| ) | [static, read] |
Get default outbound proxy or global proxy.
Definition at line 3311 of file chan_sip.c.
References append_history, ast_debug, and sip_cfg.
Referenced by __sip_subscribe_mwi_do(), create_addr(), create_addr_from_peer(), and transmit_register().
03312 { 03313 if (dialog && dialog->options && dialog->options->outboundproxy) { 03314 if (sipdebug) { 03315 ast_debug(1, "OBPROXY: Applying dialplan set OBproxy to this call\n"); 03316 } 03317 append_history(dialog, "OBproxy", "Using dialplan obproxy %s", dialog->options->outboundproxy->name); 03318 return dialog->options->outboundproxy; 03319 } 03320 if (peer && peer->outboundproxy) { 03321 if (sipdebug) { 03322 ast_debug(1, "OBPROXY: Applying peer OBproxy to this call\n"); 03323 } 03324 append_history(dialog, "OBproxy", "Using peer obproxy %s", peer->outboundproxy->name); 03325 return peer->outboundproxy; 03326 } 03327 if (sip_cfg.outboundproxy.name[0]) { 03328 if (sipdebug) { 03329 ast_debug(1, "OBPROXY: Applying global OBproxy to this call\n"); 03330 } 03331 append_history(dialog, "OBproxy", "Using global obproxy %s", sip_cfg.outboundproxy.name); 03332 return &sip_cfg.outboundproxy; 03333 } 03334 if (sipdebug) { 03335 ast_debug(1, "OBPROXY: Not applying OBproxy to this call\n"); 03336 } 03337 return NULL; 03338 }
| static void on_dns_update_mwi | ( | struct ast_sockaddr * | old, | |
| struct ast_sockaddr * | new, | |||
| void * | data | |||
| ) | [static] |
Definition at line 12845 of file chan_sip.c.
References ast_debug, ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_stringify(), and ast_strdupa.
Referenced by __sip_subscribe_mwi_do().
12846 { 12847 struct sip_subscription_mwi *mwi = data; 12848 const char *old_str; 12849 12850 /* This shouldn't happen, but just in case */ 12851 if (ast_sockaddr_isnull(new)) { 12852 ast_debug(1, "Empty sockaddr change...ignoring!\n"); 12853 return; 12854 } 12855 12856 old_str = ast_strdupa(ast_sockaddr_stringify(old)); 12857 ast_debug(1, "Changing mwi %s from %s to %s\n", mwi->hostname, old_str, ast_sockaddr_stringify(new)); 12858 ast_sockaddr_copy(&mwi->us, new); 12859 }
| static void on_dns_update_peer | ( | struct ast_sockaddr * | old, | |
| struct ast_sockaddr * | new, | |||
| void * | data | |||
| ) | [static] |
Definition at line 12816 of file chan_sip.c.
References ao2_link, ao2_lock, ao2_unlink, ao2_unlock, ast_debug, ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_strdupa, and default_sip_port().
Referenced by build_peer(), and transmit_register().
12817 { 12818 struct sip_peer *peer = data; 12819 const char *old_str; 12820 12821 /* This shouldn't happen, but just in case */ 12822 if (ast_sockaddr_isnull(new)) { 12823 ast_debug(1, "Empty sockaddr change...ignoring!\n"); 12824 return; 12825 } 12826 12827 if (!ast_sockaddr_isnull(&peer->addr)) { 12828 ao2_unlink(peers_by_ip, peer); 12829 } 12830 12831 if (!ast_sockaddr_port(new)) { 12832 ast_sockaddr_set_port(new, default_sip_port(peer->socket.type)); 12833 } 12834 12835 old_str = ast_strdupa(ast_sockaddr_stringify(old)); 12836 ast_debug(1, "Changing peer %s address from %s to %s\n", peer->name, old_str, ast_sockaddr_stringify(new)); 12837 12838 ao2_lock(peer); 12839 ast_sockaddr_copy(&peer->addr, new); 12840 ao2_unlock(peer); 12841 12842 ao2_link(peers_by_ip, peer); 12843 }
| static void on_dns_update_registry | ( | struct ast_sockaddr * | old, | |
| struct ast_sockaddr * | new, | |||
| void * | data | |||
| ) | [static] |
Definition at line 12795 of file chan_sip.c.
References ast_debug, ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_strdupa, and S_OR.
Referenced by transmit_register().
12796 { 12797 struct sip_registry *reg = data; 12798 const char *old_str; 12799 12800 /* This shouldn't happen, but just in case */ 12801 if (ast_sockaddr_isnull(new)) { 12802 ast_debug(1, "Empty sockaddr change...ignoring!\n"); 12803 return; 12804 } 12805 12806 if (!ast_sockaddr_port(new)) { 12807 ast_sockaddr_set_port(new, reg->portno); 12808 } 12809 12810 old_str = ast_strdupa(ast_sockaddr_stringify(old)); 12811 12812 ast_debug(1, "Changing registry %s from %s to %s\n", S_OR(reg->peername, reg->hostname), old_str, ast_sockaddr_stringify(new)); 12813 ast_sockaddr_copy(®->us, new); 12814 }
| static unsigned int parse_allowed_methods | ( | struct sip_request * | req | ) | [static] |
parse the Allow header to see what methods the endpoint we are communicating with allows.
We parse the allow header on incoming Registrations and save the result to the SIP peer that is registering. When the registration expires, we clear what we know about the peer's allowed methods. When the peer re-registers, we once again parse to see if the list of allowed methods has changed.
For peers that do not register, we parse the first message we receive during a call to see what is allowed, and save the information for the duration of the call.
| req | The SIP request we are parsing |
| The | methods allowed |
Definition at line 8690 of file chan_sip.c.
References ast_strdupa, ast_strip_quoted(), ast_strlen_zero(), get_header(), and mark_parsed_methods().
Referenced by set_pvt_allowed_methods().
08691 { 08692 char *allow = ast_strdupa(get_header(req, "Allow")); 08693 unsigned int allowed_methods = SIP_UNKNOWN; 08694 08695 if (ast_strlen_zero(allow)) { 08696 /* I have witnessed that REGISTER requests from Polycom phones do not 08697 * place the phone's allowed methods in an Allow header. Instead, they place the 08698 * allowed methods in a methods= parameter in the Contact header. 08699 */ 08700 char *contact = ast_strdupa(get_header(req, "Contact")); 08701 char *methods = strstr(contact, ";methods="); 08702 08703 if (ast_strlen_zero(methods)) { 08704 /* RFC 3261 states: 08705 * 08706 * "The absence of an Allow header field MUST NOT be 08707 * interpreted to mean that the UA sending the message supports no 08708 * methods. Rather, it implies that the UA is not providing any 08709 * information on what methods it supports." 08710 * 08711 * For simplicity, we'll assume that the peer allows all known 08712 * SIP methods if they have no Allow header. We can then clear out the necessary 08713 * bits if the peer lets us know that we have sent an unsupported method. 08714 */ 08715 return UINT_MAX; 08716 } 08717 allow = ast_strip_quoted(methods + 9, "\"", "\""); 08718 } 08719 mark_parsed_methods(&allowed_methods, allow); 08720 return allowed_methods; 08721 }
| static void parse_copy | ( | struct sip_request * | dst, | |
| const struct sip_request * | src | |||
| ) | [static] |
Copy SIP request, parse it.
Definition at line 4266 of file chan_sip.c.
References copy_request(), and parse_request().
Referenced by send_request(), and send_response().
04267 { 04268 copy_request(dst, src); 04269 parse_request(dst); 04270 }
| int parse_minse | ( | const char * | p_hdrval, | |
| int *const | p_interval | |||
| ) | [static] |
Session-Timers: Function for parsing Min-SE header.
Definition at line 26856 of file chan_sip.c.
References ast_debug, ast_log(), ast_skip_blanks(), ast_strlen_zero(), and LOG_WARNING.
Referenced by handle_request_invite_st(), and proc_422_rsp().
26857 { 26858 if (ast_strlen_zero(p_hdrval)) { 26859 ast_log(LOG_WARNING, "Null Min-SE header\n"); 26860 return -1; 26861 } 26862 26863 *p_interval = 0; 26864 p_hdrval = ast_skip_blanks(p_hdrval); 26865 if (!sscanf(p_hdrval, "%30d", p_interval)) { 26866 ast_log(LOG_WARNING, "Parsing of Min-SE header failed %s\n", p_hdrval); 26867 return -1; 26868 } 26869 26870 ast_debug(2, "Received Min-SE: %d\n", *p_interval); 26871 return 0; 26872 }
| static void parse_moved_contact | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| char ** | name, | |||
| char ** | number, | |||
| int | set_call_forward | |||
| ) | [static] |
Parse 302 Moved temporalily response.
Definition at line 20358 of file chan_sip.c.
References ao2_ref, ast_copy_string(), ast_debug, ast_log(), ast_strdup, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), find_closing_quote(), get_header(), get_in_brackets(), get_transport(), LOG_NOTICE, pbx_builtin_setvar_helper(), remove_uri_parameters(), and set_socket_transport().
Referenced by change_redirecting_information().
20359 { 20360 char contact[SIPBUFSIZE]; 20361 char *contact_name = NULL; 20362 char *contact_number = NULL; 20363 char *separator, *trans; 20364 char *domain; 20365 enum sip_transport transport = SIP_TRANSPORT_UDP; 20366 20367 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 20368 if ((separator = strchr(contact, ','))) 20369 *separator = '\0'; 20370 20371 contact_number = get_in_brackets(contact); 20372 if ((trans = strcasestr(contact_number, ";transport="))) { 20373 trans += 11; 20374 20375 if ((separator = strchr(trans, ';'))) 20376 *separator = '\0'; 20377 20378 if (!strncasecmp(trans, "tcp", 3)) 20379 transport = SIP_TRANSPORT_TCP; 20380 else if (!strncasecmp(trans, "tls", 3)) 20381 transport = SIP_TRANSPORT_TLS; 20382 else { 20383 if (strncasecmp(trans, "udp", 3)) 20384 ast_debug(1, "received contact with an invalid transport, '%s'\n", contact_number); 20385 /* This will assume UDP for all unknown transports */ 20386 transport = SIP_TRANSPORT_UDP; 20387 } 20388 } 20389 contact_number = remove_uri_parameters(contact_number); 20390 20391 if (p->socket.tcptls_session) { 20392 ao2_ref(p->socket.tcptls_session, -1); 20393 p->socket.tcptls_session = NULL; 20394 } 20395 20396 set_socket_transport(&p->socket, transport); 20397 20398 if (set_call_forward && ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) { 20399 char *host = NULL; 20400 if (!strncasecmp(contact_number, "sip:", 4)) 20401 contact_number += 4; 20402 else if (!strncasecmp(contact_number, "sips:", 5)) 20403 contact_number += 5; 20404 separator = strchr(contact_number, '/'); 20405 if (separator) 20406 *separator = '\0'; 20407 if ((host = strchr(contact_number, '@'))) { 20408 *host++ = '\0'; 20409 ast_debug(2, "Found promiscuous redirection to 'SIP/%s::::%s@%s'\n", contact_number, get_transport(transport), host); 20410 if (p->owner) 20411 ast_string_field_build(p->owner, call_forward, "SIP/%s::::%s@%s", contact_number, get_transport(transport), host); 20412 } else { 20413 ast_debug(2, "Found promiscuous redirection to 'SIP/::::%s@%s'\n", get_transport(transport), contact_number); 20414 if (p->owner) 20415 ast_string_field_build(p->owner, call_forward, "SIP/::::%s@%s", get_transport(transport), contact_number); 20416 } 20417 } else { 20418 separator = strchr(contact, '@'); 20419 if (separator) { 20420 *separator++ = '\0'; 20421 domain = separator; 20422 } else { 20423 /* No username part */ 20424 domain = contact; 20425 } 20426 separator = strchr(contact, '/'); /* WHEN do we hae a forward slash in the URI? */ 20427 if (separator) 20428 *separator = '\0'; 20429 20430 if (!strncasecmp(contact_number, "sip:", 4)) 20431 contact_number += 4; 20432 else if (!strncasecmp(contact_number, "sips:", 5)) 20433 contact_number += 5; 20434 separator = strchr(contact_number, ';'); /* And username ; parameters? */ 20435 if (separator) 20436 *separator = '\0'; 20437 ast_uri_decode(contact_number); 20438 if (set_call_forward) { 20439 ast_debug(2, "Received 302 Redirect to extension '%s' (domain %s)\n", contact_number, domain); 20440 if (p->owner) { 20441 pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain); 20442 ast_string_field_set(p->owner, call_forward, contact_number); 20443 } 20444 } 20445 } 20446 20447 /* We've gotten the number for the contact, now get the name */ 20448 20449 if (*contact == '\"') { 20450 contact_name = contact + 1; 20451 if (!(separator = (char *)find_closing_quote(contact_name, NULL))) { 20452 ast_log(LOG_NOTICE, "No closing quote on name in Contact header? %s\n", contact); 20453 } 20454 *separator = '\0'; 20455 } 20456 20457 if (name && !ast_strlen_zero(contact_name)) { 20458 *name = ast_strdup(contact_name); 20459 } 20460 if (number) { 20461 *number = ast_strdup(contact_number); 20462 } 20463 }
| static int parse_ok_contact | ( | struct sip_pvt * | pvt, | |
| struct sip_request * | req | |||
| ) | [static] |
Save contact header for 200 OK on INVITE.
Definition at line 14355 of file chan_sip.c.
References ast_copy_string(), ast_string_field_set, get_header(), get_in_brackets(), and TRUE.
Referenced by handle_request_invite(), handle_request_subscribe(), and handle_response_invite().
14356 { 14357 char contact[SIPBUFSIZE]; 14358 char *c; 14359 14360 /* Look for brackets */ 14361 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 14362 c = get_in_brackets(contact); 14363 14364 /* Save full contact to call pvt for later bye or re-invite */ 14365 ast_string_field_set(pvt, fullcontact, c); 14366 14367 /* Save URI for later ACKs, BYE or RE-invites */ 14368 ast_string_field_set(pvt, okcontacturi, c); 14369 14370 /* We should return false for URI:s we can't handle, 14371 like tel:, mailto:,ldap: etc */ 14372 return TRUE; 14373 }
| static enum parse_register_result parse_register_contact | ( | struct sip_pvt * | pvt, | |
| struct sip_peer * | p, | |||
| struct sip_request * | req | |||
| ) | [static] |
Parse contact header and save registration (peer registration).
Definition at line 14462 of file chan_sip.c.
References __get_header(), ao2_t_link, ao2_t_unlink, ast_apply_ha(), ast_copy_string(), ast_db_put(), ast_debug, ast_log(), ast_sched_add(), AST_SCHED_DEL_UNREF, ast_sched_when(), AST_SENSE_ALLOW, ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_resolve_first_transport(), ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verb, ast_verbose, copy_socket_data(), default_sip_port(), EVENT_FLAG_SYSTEM, expire_register(), FALSE, get_header(), get_in_brackets(), get_transport_str2enum(), LOG_NOTICE, LOG_WARNING, manager_event, parse_uri_legacy_check(), ref_peer(), register_peer_exten(), set_socket_transport(), sip_cfg, sip_poke_peer(), sip_pvt_lock, sip_pvt_unlock, TRUE, unref_peer(), VERBOSE_PREFIX_3, and VERBOSITY_ATLEAST.
Referenced by register_verify().
14463 { 14464 char contact[SIPBUFSIZE]; 14465 char data[SIPBUFSIZE]; 14466 const char *expires = get_header(req, "Expires"); 14467 int expire = atoi(expires); 14468 char *curi = NULL, *hostport = NULL, *transport = NULL; 14469 int transport_type; 14470 const char *useragent; 14471 struct ast_sockaddr oldsin, testsa; 14472 char *firstcuri = NULL; 14473 int start = 0; 14474 int wildcard_found = 0; 14475 int single_binding_found = 0; 14476 14477 ast_copy_string(contact, __get_header(req, "Contact", &start), sizeof(contact)); 14478 14479 if (ast_strlen_zero(expires)) { /* No expires header, try look in Contact: */ 14480 char *s = strcasestr(contact, ";expires="); 14481 if (s) { 14482 expires = strsep(&s, ";"); /* trim ; and beyond */ 14483 if (sscanf(expires + 9, "%30d", &expire) != 1) { 14484 expire = default_expiry; 14485 } 14486 } else { 14487 /* Nothing has been specified */ 14488 expire = default_expiry; 14489 } 14490 } 14491 14492 if (expire > max_expiry) { 14493 expire = max_expiry; 14494 } 14495 if (expire < min_expiry && expire != 0) { 14496 expire = min_expiry; 14497 } 14498 pvt->expiry = expire; 14499 14500 copy_socket_data(&pvt->socket, &req->socket); 14501 14502 do { 14503 /* Look for brackets */ 14504 curi = contact; 14505 if (strchr(contact, '<') == NULL) /* No <, check for ; and strip it */ 14506 strsep(&curi, ";"); /* This is Header options, not URI options */ 14507 curi = get_in_brackets(contact); 14508 if (!firstcuri) { 14509 firstcuri = ast_strdupa(curi); 14510 } 14511 14512 if (!strcasecmp(curi, "*")) { 14513 wildcard_found = 1; 14514 } else { 14515 single_binding_found = 1; 14516 } 14517 14518 if (wildcard_found && (ast_strlen_zero(expires) || expire != 0 || single_binding_found)) { 14519 /* Contact header parameter "*" detected, so punt if: Expires header is missing, 14520 * Expires value is not zero, or another Contact header is present. */ 14521 return PARSE_REGISTER_FAILED; 14522 } 14523 14524 ast_copy_string(contact, __get_header(req, "Contact", &start), sizeof(contact)); 14525 } while (!ast_strlen_zero(contact)); 14526 curi = firstcuri; 14527 14528 /* if they did not specify Contact: or Expires:, they are querying 14529 what we currently have stored as their contact address, so return 14530 it 14531 */ 14532 if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) { 14533 /* If we have an active registration, tell them when the registration is going to expire */ 14534 if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact)) { 14535 pvt->expiry = ast_sched_when(sched, peer->expire); 14536 } 14537 return PARSE_REGISTER_QUERY; 14538 } else if (!strcasecmp(curi, "*") || !expire) { /* Unregister this peer */ 14539 /* This means remove all registrations and return OK */ 14540 AST_SCHED_DEL_UNREF(sched, peer->expire, 14541 unref_peer(peer, "remove register expire ref")); 14542 ast_verb(3, "Unregistered SIP '%s'\n", peer->name); 14543 expire_register(ref_peer(peer,"add ref for explicit expire_register")); 14544 return PARSE_REGISTER_UPDATE; 14545 } 14546 14547 /* Store whatever we got as a contact from the client */ 14548 ast_string_field_set(peer, fullcontact, curi); 14549 14550 /* For the 200 OK, we should use the received contact */ 14551 ast_string_field_build(pvt, our_contact, "<%s>", curi); 14552 14553 /* Make sure it's a SIP URL */ 14554 if (ast_strlen_zero(curi) || parse_uri_legacy_check(curi, "sip:,sips:", &curi, NULL, &hostport, &transport)) { 14555 ast_log(LOG_NOTICE, "Not a valid SIP contact (missing sip:/sips:) trying to use anyway\n"); 14556 } 14557 14558 /* handle the transport type specified in Contact header. */ 14559 if (!(transport_type = get_transport_str2enum(transport))) { 14560 transport_type = pvt->socket.type; 14561 } 14562 14563 /* if the peer's socket type is different than the Registration 14564 * transport type, change it. If it got this far, it is a 14565 * supported type, but check just in case */ 14566 if ((peer->socket.type != transport_type) && (peer->transports & transport_type)) { 14567 set_socket_transport(&peer->socket, transport_type); 14568 } 14569 14570 oldsin = peer->addr; 14571 14572 /* If we were already linked into the peers_by_ip container unlink ourselves so nobody can find us */ 14573 if (!ast_sockaddr_isnull(&peer->addr) && (!peer->is_realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS))) { 14574 ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table"); 14575 } 14576 14577 if (!ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) && !ast_test_flag(&peer->flags[0], SIP_NAT_RPORT_PRESENT)) { 14578 /* use the data provided in the Contact header for call routing */ 14579 ast_debug(1, "Store REGISTER's Contact header for call routing.\n"); 14580 /* XXX This could block for a long time XXX */ 14581 /*! \todo Check NAPTR/SRV if we have not got a port in the URI */ 14582 if (ast_sockaddr_resolve_first_transport(&testsa, hostport, 0, peer->socket.type)) { 14583 ast_log(LOG_WARNING, "Invalid hostport '%s'\n", hostport); 14584 ast_string_field_set(peer, fullcontact, ""); 14585 ast_string_field_set(pvt, our_contact, ""); 14586 return PARSE_REGISTER_FAILED; 14587 } 14588 14589 /* If we have a port number in the given URI, make sure we do remember to not check for NAPTR/SRV records. 14590 The hostport part is actually a host. */ 14591 peer->portinuri = ast_sockaddr_port(&testsa) ? TRUE : FALSE; 14592 14593 if (!ast_sockaddr_port(&testsa)) { 14594 ast_sockaddr_set_port(&testsa, default_sip_port(transport_type)); 14595 } 14596 14597 ast_sockaddr_copy(&peer->addr, &testsa); 14598 } else { 14599 /* Don't trust the contact field. Just use what they came to us 14600 with */ 14601 ast_debug(1, "Store REGISTER's src-IP:port for call routing.\n"); 14602 peer->addr = pvt->recv; 14603 } 14604 14605 /* Check that they're allowed to register at this IP */ 14606 if (ast_apply_ha(sip_cfg.contact_ha, &peer->addr) != AST_SENSE_ALLOW || 14607 ast_apply_ha(peer->contactha, &peer->addr) != AST_SENSE_ALLOW) { 14608 ast_log(LOG_WARNING, "Domain '%s' disallowed by contact ACL (violating IP %s)\n", hostport, 14609 ast_sockaddr_stringify_addr(&peer->addr)); 14610 ast_string_field_set(peer, fullcontact, ""); 14611 ast_string_field_set(pvt, our_contact, ""); 14612 return PARSE_REGISTER_DENIED; 14613 } 14614 14615 /* if the Contact header information copied into peer->addr matches the 14616 * received address, and the transport types are the same, then copy socket 14617 * data into the peer struct */ 14618 if ((peer->socket.type == pvt->socket.type) && 14619 !ast_sockaddr_cmp(&peer->addr, &pvt->recv)) { 14620 copy_socket_data(&peer->socket, &pvt->socket); 14621 } 14622 14623 /* Now that our address has been updated put ourselves back into the container for lookups */ 14624 if (!peer->is_realtime || ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 14625 ao2_t_link(peers_by_ip, peer, "ao2_link into peers_by_ip table"); 14626 } 14627 14628 /* Save SIP options profile */ 14629 peer->sipoptions = pvt->sipoptions; 14630 14631 if (!ast_strlen_zero(curi) && ast_strlen_zero(peer->username)) { 14632 ast_string_field_set(peer, username, curi); 14633 } 14634 14635 AST_SCHED_DEL_UNREF(sched, peer->expire, 14636 unref_peer(peer, "remove register expire ref")); 14637 14638 if (peer->is_realtime && !ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 14639 peer->expire = -1; 14640 } else { 14641 peer->expire = ast_sched_add(sched, (expire + 10) * 1000, expire_register, 14642 ref_peer(peer, "add registration ref")); 14643 if (peer->expire == -1) { 14644 unref_peer(peer, "remote registration ref"); 14645 } 14646 } 14647 snprintf(data, sizeof(data), "%s:%d:%s:%s", ast_sockaddr_stringify(&peer->addr), 14648 expire, peer->username, peer->fullcontact); 14649 /* We might not immediately be able to reconnect via TCP, but try caching it anyhow */ 14650 if (!peer->rt_fromcontact || !sip_cfg.peer_rtupdate) 14651 ast_db_put("SIP/Registry", peer->name, data); 14652 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Registered\r\nAddress: %s\r\n", peer->name, ast_sockaddr_stringify(&peer->addr)); 14653 14654 /* Is this a new IP address for us? */ 14655 if (VERBOSITY_ATLEAST(2) && ast_sockaddr_cmp(&peer->addr, &oldsin)) { 14656 ast_verbose(VERBOSE_PREFIX_3 "Registered SIP '%s' at %s\n", peer->name, 14657 ast_sockaddr_stringify(&peer->addr)); 14658 } 14659 sip_pvt_unlock(pvt); 14660 sip_poke_peer(peer, 0); 14661 sip_pvt_lock(pvt); 14662 register_peer_exten(peer, 1); 14663 14664 /* Save User agent */ 14665 useragent = get_header(req, "User-Agent"); 14666 if (strcasecmp(useragent, peer->useragent)) { 14667 ast_string_field_set(peer, useragent, useragent); 14668 ast_verb(4, "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name); 14669 } 14670 return PARSE_REGISTER_UPDATE; 14671 }
| static int parse_request | ( | struct sip_request * | req | ) | [static] |
Parse a SIP message.
Definition at line 8795 of file chan_sip.c.
References ast_debug, ast_log(), ast_str_buffer(), ast_str_strlen(), ast_strlen_zero(), determine_firstline_parts(), and LOG_WARNING.
Referenced by handle_request_do(), initialize_initreq(), and parse_copy().
08796 { 08797 char *c = req->data->str; 08798 ptrdiff_t *dst = req->header; 08799 int i = 0, lim = SIP_MAX_HEADERS - 1; 08800 unsigned int skipping_headers = 0; 08801 ptrdiff_t current_header_offset = 0; 08802 char *previous_header = ""; 08803 08804 req->header[0] = 0; 08805 req->headers = -1; /* mark that we are working on the header */ 08806 for (; *c; c++) { 08807 if (*c == '\r') { /* remove \r */ 08808 *c = '\0'; 08809 } else if (*c == '\n') { /* end of this line */ 08810 *c = '\0'; 08811 current_header_offset = (c + 1) - ast_str_buffer(req->data); 08812 previous_header = ast_str_buffer(req->data) + dst[i]; 08813 if (skipping_headers) { 08814 /* check to see if this line is blank; if so, turn off 08815 the skipping flag, so the next line will be processed 08816 as a body line */ 08817 if (ast_strlen_zero(previous_header)) { 08818 skipping_headers = 0; 08819 } 08820 dst[i] = current_header_offset; /* record start of next line */ 08821 continue; 08822 } 08823 if (sipdebug) { 08824 ast_debug(4, "%7s %2d [%3d]: %s\n", 08825 req->headers < 0 ? "Header" : "Body", 08826 i, (int) strlen(previous_header), previous_header); 08827 } 08828 if (ast_strlen_zero(previous_header) && req->headers < 0) { 08829 req->headers = i; /* record number of header lines */ 08830 dst = req->line; /* start working on the body */ 08831 i = 0; 08832 lim = SIP_MAX_LINES - 1; 08833 } else { /* move to next line, check for overflows */ 08834 if (i++ == lim) { 08835 /* if we're processing headers, then skip any remaining 08836 headers and move on to processing the body, otherwise 08837 we're done */ 08838 if (req->headers != -1) { 08839 break; 08840 } else { 08841 req->headers = i; 08842 dst = req->line; 08843 i = 0; 08844 lim = SIP_MAX_LINES - 1; 08845 skipping_headers = 1; 08846 } 08847 } 08848 } 08849 dst[i] = current_header_offset; /* record start of next line */ 08850 } 08851 } 08852 08853 /* Check for last header or body line without CRLF. The RFC for SDP requires CRLF, 08854 but since some devices send without, we'll be generous in what we accept. However, 08855 if we've already reached the maximum number of lines for portion of the message 08856 we were parsing, we can't accept any more, so just ignore it. 08857 */ 08858 previous_header = ast_str_buffer(req->data) + dst[i]; 08859 if ((i < lim) && !ast_strlen_zero(previous_header)) { 08860 if (sipdebug) { 08861 ast_debug(4, "%7s %2d [%3d]: %s\n", 08862 req->headers < 0 ? "Header" : "Body", 08863 i, (int) strlen(previous_header), previous_header ); 08864 } 08865 i++; 08866 } 08867 08868 /* update count of header or body lines */ 08869 if (req->headers >= 0) { /* we are in the body */ 08870 req->lines = i; 08871 } else { /* no body */ 08872 req->headers = i; 08873 req->lines = 0; 08874 /* req->data->used will be a NULL byte */ 08875 req->line[0] = ast_str_strlen(req->data); 08876 } 08877 08878 if (*c) { 08879 ast_log(LOG_WARNING, "Too many lines, skipping <%s>\n", c); 08880 } 08881 08882 /* Split up the first line parts */ 08883 return determine_firstline_parts(req); 08884 }
| int parse_session_expires | ( | const char * | p_hdrval, | |
| int *const | p_interval, | |||
| enum st_refresher_param *const | p_ref | |||
| ) | [static] |
Session-Timers: Function for parsing Session-Expires header.
Definition at line 26876 of file chan_sip.c.
References ast_debug, ast_log(), ast_skip_blanks(), ast_strdupa, ast_strlen_zero(), and LOG_WARNING.
Referenced by handle_request_invite_st(), and handle_response_invite().
26877 { 26878 char *p_token; 26879 int ref_idx; 26880 char *p_se_hdr; 26881 26882 if (ast_strlen_zero(p_hdrval)) { 26883 ast_log(LOG_WARNING, "Null Session-Expires header\n"); 26884 return -1; 26885 } 26886 26887 *p_ref = SESSION_TIMER_REFRESHER_PARAM_UNKNOWN; 26888 *p_interval = 0; 26889 26890 p_se_hdr = ast_strdupa(p_hdrval); 26891 p_se_hdr = ast_skip_blanks(p_se_hdr); 26892 26893 while ((p_token = strsep(&p_se_hdr, ";"))) { 26894 p_token = ast_skip_blanks(p_token); 26895 if (!sscanf(p_token, "%30d", p_interval)) { 26896 ast_log(LOG_WARNING, "Parsing of Session-Expires failed\n"); 26897 return -1; 26898 } 26899 26900 ast_debug(2, "Session-Expires: %d\n", *p_interval); 26901 26902 if (!p_se_hdr) 26903 continue; 26904 26905 p_se_hdr = ast_skip_blanks(p_se_hdr); 26906 ref_idx = strlen("refresher="); 26907 if (!strncasecmp(p_se_hdr, "refresher=", ref_idx)) { 26908 p_se_hdr += ref_idx; 26909 p_se_hdr = ast_skip_blanks(p_se_hdr); 26910 26911 if (!strncasecmp(p_se_hdr, "uac", strlen("uac"))) { 26912 *p_ref = SESSION_TIMER_REFRESHER_PARAM_UAC; 26913 ast_debug(2, "Refresher: UAC\n"); 26914 } else if (!strncasecmp(p_se_hdr, "uas", strlen("uas"))) { 26915 *p_ref = SESSION_TIMER_REFRESHER_PARAM_UAS; 26916 ast_debug(2, "Refresher: UAS\n"); 26917 } else { 26918 ast_log(LOG_WARNING, "Invalid refresher value %s\n", p_se_hdr); 26919 return -1; 26920 } 26921 break; 26922 } 26923 } 26924 return 0; 26925 }
| static int parse_uri_legacy_check | ( | char * | uri, | |
| const char * | scheme, | |||
| char ** | user, | |||
| char ** | pass, | |||
| char ** | hostport, | |||
| char ** | transport | |||
| ) | [static] |
parse uri in a way that allows semicolon stripping if legacy mode is enabled
Definition at line 14381 of file chan_sip.c.
References parse_uri(), and sip_cfg.
Referenced by __set_address_from_contact(), check_user_full(), get_also_info(), get_destination(), parse_register_contact(), and register_verify().
14382 { 14383 int ret = parse_uri(uri, scheme, user, pass, hostport, transport); 14384 if (sip_cfg.legacy_useroption_parsing) { /* if legacy mode is active, strip semis from the user field */ 14385 char *p; 14386 if ((p = strchr(uri, (int)';'))) { 14387 *p = '\0'; 14388 } 14389 } 14390 return ret; 14391 }
| static int peer_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 30709 of file chan_sip.c.
References CMP_MATCH, and CMP_STOP.
Referenced by load_module().
| static int peer_dump_func | ( | void * | userobj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 17500 of file chan_sip.c.
References ao2_t_ref, ast_cli(), and ast_cli_args::fd.
Referenced by sip_show_objects().
17501 { 17502 struct sip_peer *peer = userobj; 17503 int refc = ao2_t_ref(userobj, 0, ""); 17504 struct ast_cli_args *a = (struct ast_cli_args *) arg; 17505 17506 ast_cli(a->fd, "name: %s\ntype: peer\nobjflags: %d\nrefcount: %d\n\n", 17507 peer->name, 0, refc); 17508 return 0; 17509 }
| static int peer_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 30699 of file chan_sip.c.
References ast_str_case_hash().
Referenced by load_module().
30700 { 30701 const struct sip_peer *peer = obj; 30702 30703 return ast_str_case_hash(peer->name); 30704 }
| static int peer_ipcmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Match Peers by IP and Port number.
This function has two modes.
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.
Definition at line 30757 of file chan_sip.c.
References ast_sockaddr_cmp_addr(), ast_sockaddr_port, ast_test_flag, CMP_MATCH, and CMP_STOP.
Referenced by load_module().
30758 { 30759 struct sip_peer *peer = obj, *peer2 = arg; 30760 30761 if (ast_sockaddr_cmp_addr(&peer->addr, &peer2->addr)) { 30762 /* IP doesn't match */ 30763 return 0; 30764 } 30765 30766 /* We matched the IP, check to see if we need to match by port as well. */ 30767 if ((peer->transports & peer2->transports) & (SIP_TRANSPORT_TLS | SIP_TRANSPORT_TCP)) { 30768 /* peer matching on port is not possible with TCP/TLS */ 30769 return CMP_MATCH | CMP_STOP; 30770 } else if (ast_test_flag(&peer2->flags[0], SIP_INSECURE_PORT)) { 30771 /* We are allowing match without port for peers configured that 30772 * way in this pass through the peers. */ 30773 return ast_test_flag(&peer->flags[0], SIP_INSECURE_PORT) ? 30774 (CMP_MATCH | CMP_STOP) : 0; 30775 } 30776 30777 /* Now only return a match if the port matches, as well. */ 30778 return ast_sockaddr_port(&peer->addr) == ast_sockaddr_port(&peer2->addr) ? 30779 (CMP_MATCH | CMP_STOP) : 0; 30780 }
| static int peer_iphash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Hash function based on the the peer's ip address. For IPv6, we use the end of the address.
Definition at line 30721 of file chan_sip.c.
References ast_log(), ast_sockaddr_hash(), ast_sockaddr_isnull(), and LOG_ERROR.
Referenced by load_module().
30722 { 30723 const struct sip_peer *peer = obj; 30724 int ret = 0; 30725 30726 if (ast_sockaddr_isnull(&peer->addr)) { 30727 ast_log(LOG_ERROR, "Empty address\n"); 30728 } 30729 30730 ret = ast_sockaddr_hash(&peer->addr); 30731 30732 if (ret < 0) { 30733 ret = -ret; 30734 } 30735 30736 return ret; 30737 }
| static void peer_mailboxes_to_str | ( | struct ast_str ** | mailbox_str, | |
| struct sip_peer * | peer | |||
| ) | [static] |
list peer mailboxes to CLI
Definition at line 18034 of file chan_sip.c.
References AST_LIST_NEXT, AST_LIST_TRAVERSE, ast_str_append(), ast_strlen_zero(), mailbox, and S_OR.
Referenced by _sip_show_peer(), function_sippeer(), show_channels_cb(), and sip_send_mwi_to_peer().
18035 { 18036 struct sip_mailbox *mailbox; 18037 18038 AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { 18039 ast_str_append(mailbox_str, 0, "%s%s%s%s", 18040 mailbox->mailbox, 18041 ast_strlen_zero(mailbox->context) ? "" : "@", 18042 S_OR(mailbox->context, ""), 18043 AST_LIST_NEXT(mailbox, entry) ? "," : ""); 18044 } 18045 }
| static int peer_markall_func | ( | void * | device, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 28722 of file chan_sip.c.
Referenced by reload_config().
| static void peer_sched_cleanup | ( | struct sip_peer * | peer | ) | [static] |
Definition at line 2992 of file chan_sip.c.
References AST_SCHED_DEL_UNREF, and unref_peer().
Referenced by match_and_cleanup_peer_sched().
02993 { 02994 if (peer->pokeexpire != -1) { 02995 AST_SCHED_DEL_UNREF(sched, peer->pokeexpire, 02996 unref_peer(peer, "removing poke peer ref")); 02997 } 02998 if (peer->expire != -1) { 02999 AST_SCHED_DEL_UNREF(sched, peer->expire, 03000 unref_peer(peer, "remove register expire ref")); 03001 } 03002 }
| static int peer_status | ( | struct sip_peer * | peer, | |
| char * | status, | |||
| int | statuslen | |||
| ) | [static] |
Definition at line 17051 of file chan_sip.c.
References ast_copy_string().
Referenced by _sip_show_peer(), _sip_show_peers_one(), and function_sippeer().
17052 { 17053 int res = 0; 17054 if (peer->maxms) { 17055 if (peer->lastms < 0) { 17056 ast_copy_string(status, "UNREACHABLE", statuslen); 17057 } else if (peer->lastms > peer->maxms) { 17058 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 17059 res = 1; 17060 } else if (peer->lastms) { 17061 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 17062 res = 1; 17063 } else { 17064 ast_copy_string(status, "UNKNOWN", statuslen); 17065 } 17066 } else { 17067 ast_copy_string(status, "Unmonitored", statuslen); 17068 /* Checking if port is 0 */ 17069 res = -1; 17070 } 17071 return res; 17072 }
| int peercomparefunc | ( | const void * | a, | |
| const void * | b | |||
| ) |
Definition at line 17279 of file chan_sip.c.
Referenced by _sip_show_peers().
| static int peers_data_provider_get | ( | const struct ast_data_search * | search, | |
| struct ast_data * | data_root | |||
| ) | [static] |
Definition at line 31667 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, ARRAY_LEN, ast_cdr_flags2str(), ast_data_add_bool(), ast_data_add_codecs(), ast_data_add_int(), ast_data_add_node(), ast_data_add_str(), ast_data_add_structure, ast_data_remove_node(), ast_data_search_match(), ast_describe_caller_presentation(), AST_LIST_TRAVERSE, get_transport_list(), mailbox, text, and transfermode2str().
31669 { 31670 struct sip_peer *peer; 31671 struct ao2_iterator i; 31672 struct ast_data *data_peer, *data_peer_mailboxes = NULL, *data_peer_mailbox, *enum_node; 31673 struct ast_data *data_sip_options; 31674 int total_mailboxes, x; 31675 struct sip_mailbox *mailbox; 31676 31677 i = ao2_iterator_init(peers, 0); 31678 while ((peer = ao2_iterator_next(&i))) { 31679 ao2_lock(peer); 31680 31681 data_peer = ast_data_add_node(data_root, "peer"); 31682 if (!data_peer) { 31683 ao2_unlock(peer); 31684 ao2_ref(peer, -1); 31685 continue; 31686 } 31687 31688 ast_data_add_structure(sip_peer, data_peer, peer); 31689 31690 /* transfer mode */ 31691 enum_node = ast_data_add_node(data_peer, "allowtransfer"); 31692 if (!enum_node) { 31693 ao2_unlock(peer); 31694 ao2_ref(peer, -1); 31695 continue; 31696 } 31697 ast_data_add_str(enum_node, "text", transfermode2str(peer->allowtransfer)); 31698 ast_data_add_int(enum_node, "value", peer->allowtransfer); 31699 31700 /* transports */ 31701 ast_data_add_str(data_peer, "transports", get_transport_list(peer->transports)); 31702 31703 /* peer type */ 31704 if ((peer->type & SIP_TYPE_USER) && (peer->type & SIP_TYPE_PEER)) { 31705 ast_data_add_str(data_peer, "type", "friend"); 31706 } else if (peer->type & SIP_TYPE_PEER) { 31707 ast_data_add_str(data_peer, "type", "peer"); 31708 } else if (peer->type & SIP_TYPE_USER) { 31709 ast_data_add_str(data_peer, "type", "user"); 31710 } 31711 31712 /* mailboxes */ 31713 total_mailboxes = 0; 31714 AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { 31715 if (!total_mailboxes) { 31716 data_peer_mailboxes = ast_data_add_node(data_peer, "mailboxes"); 31717 if (!data_peer_mailboxes) { 31718 break; 31719 } 31720 total_mailboxes++; 31721 } 31722 31723 data_peer_mailbox = ast_data_add_node(data_peer_mailboxes, "mailbox"); 31724 if (!data_peer_mailbox) { 31725 continue; 31726 } 31727 ast_data_add_str(data_peer_mailbox, "mailbox", mailbox->mailbox); 31728 ast_data_add_str(data_peer_mailbox, "context", mailbox->context); 31729 } 31730 31731 /* amaflags */ 31732 enum_node = ast_data_add_node(data_peer, "amaflags"); 31733 if (!enum_node) { 31734 ao2_unlock(peer); 31735 ao2_ref(peer, -1); 31736 continue; 31737 } 31738 ast_data_add_int(enum_node, "value", peer->amaflags); 31739 ast_data_add_str(enum_node, "text", ast_cdr_flags2str(peer->amaflags)); 31740 31741 /* sip options */ 31742 data_sip_options = ast_data_add_node(data_peer, "sipoptions"); 31743 if (!data_sip_options) { 31744 ao2_unlock(peer); 31745 ao2_ref(peer, -1); 31746 continue; 31747 } 31748 for (x = 0 ; x < ARRAY_LEN(sip_options); x++) { 31749 ast_data_add_bool(data_sip_options, sip_options[x].text, peer->sipoptions & sip_options[x].id); 31750 } 31751 31752 /* callingpres */ 31753 enum_node = ast_data_add_node(data_peer, "callingpres"); 31754 if (!enum_node) { 31755 ao2_unlock(peer); 31756 ao2_ref(peer, -1); 31757 continue; 31758 } 31759 ast_data_add_int(enum_node, "value", peer->callingpres); 31760 ast_data_add_str(enum_node, "text", ast_describe_caller_presentation(peer->callingpres)); 31761 31762 /* codecs */ 31763 ast_data_add_codecs(data_peer, "codecs", peer->capability); 31764 31765 if (!ast_data_search_match(search, data_peer)) { 31766 ast_data_remove_node(data_root, data_peer); 31767 } 31768 31769 ao2_unlock(peer); 31770 ao2_ref(peer, -1); 31771 } 31772 ao2_iterator_destroy(&i); 31773 31774 return 0; 31775 }
| unsigned int port_str2int | ( | const char * | pt, | |
| unsigned int | standard | |||
| ) |
converts ascii port to int representation. If no pt buffer is provided or the pt has errors when being converted to an int value, the port provided as the standard is used.
Definition at line 3300 of file chan_sip.c.
References ast_strlen_zero().
Referenced by build_peer(), reload_config(), and sip_parse_register_line().
03301 { 03302 int port = standard; 03303 if (ast_strlen_zero(pt) || (sscanf(pt, "%30d", &port) != 1) || (port < 1) || (port > 65535)) { 03304 port = standard; 03305 } 03306 03307 return port; 03308 }
| static void print_codec_to_cli | ( | int | fd, | |
| struct ast_codec_pref * | pref | |||
| ) | [static] |
Print codec list from preference to CLI/manager.
Definition at line 17871 of file chan_sip.c.
References ast_cli(), ast_codec_pref_index(), ast_getformatname(), and ast_codec_pref::framing.
Referenced by _sip_show_peer(), sip_show_settings(), and sip_show_user().
17872 { 17873 int x; 17874 format_t codec; 17875 17876 for(x = 0; x < 64 ; x++) { 17877 codec = ast_codec_pref_index(pref, x); 17878 if (!codec) 17879 break; 17880 ast_cli(fd, "%s", ast_getformatname(codec)); 17881 ast_cli(fd, ":%d", pref->framing[x]); 17882 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 17883 ast_cli(fd, ","); 17884 } 17885 if (!x) 17886 ast_cli(fd, "none"); 17887 }
| static void print_group | ( | int | fd, | |
| ast_group_t | group, | |||
| int | crlf | |||
| ) | [static] |
Print call group and pickup group.
Definition at line 17552 of file chan_sip.c.
References ast_cli(), and ast_print_group().
Referenced by _sip_show_peer(), and sip_show_user().
17553 { 17554 char buf[256]; 17555 ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) ); 17556 }
| static void proc_422_rsp | ( | struct sip_pvt * | p, | |
| struct sip_request * | rsp | |||
| ) | [static] |
Handle 422 response to INVITE with session-timer requested.
Session-Timers: An INVITE originated by Asterisk that asks for session-timers support from the UAS can result into a 422 response. This is how a UAS or an intermediary proxy server tells Asterisk that the session refresh interval offered by Asterisk is too low for them. The proc_422_rsp() function handles a 422 response. It extracts the Min-SE header that comes back in 422 and sends a new INVITE accordingly.
Definition at line 26935 of file chan_sip.c.
References ast_log(), ast_strlen_zero(), get_header(), LOG_WARNING, parse_minse(), and transmit_invite().
Referenced by handle_response_invite().
26936 { 26937 int rtn; 26938 const char *p_hdrval; 26939 int minse; 26940 26941 p_hdrval = get_header(rsp, "Min-SE"); 26942 if (ast_strlen_zero(p_hdrval)) { 26943 ast_log(LOG_WARNING, "422 response without a Min-SE header %s\n", p_hdrval); 26944 return; 26945 } 26946 rtn = parse_minse(p_hdrval, &minse); 26947 if (rtn != 0) { 26948 ast_log(LOG_WARNING, "Parsing of Min-SE header failed %s\n", p_hdrval); 26949 return; 26950 } 26951 p->stimer->st_cached_min_se = minse; 26952 if (p->stimer->st_interval < minse) { 26953 p->stimer->st_interval = minse; 26954 } 26955 transmit_invite(p, SIP_INVITE, 1, 2, NULL); 26956 }
| static int proc_session_timer | ( | const void * | vp | ) | [static] |
Session-Timers: Process session refresh timeout event.
Definition at line 26786 of file chan_sip.c.
References ast_channel_trylock, ast_channel_unlock, ast_debug, ast_log(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, FALSE, LOG_WARNING, sip_pvt_lock, sip_pvt_unlock, stop_session_timer(), transmit_reinvite_with_sdp(), and TRUE.
Referenced by start_session_timer().
26787 { 26788 struct sip_pvt *p = (struct sip_pvt *) vp; 26789 int res = 0; 26790 26791 if (!p->stimer) { 26792 ast_log(LOG_WARNING, "Null stimer in proc_session_timer - %s\n", p->callid); 26793 goto return_unref; 26794 } 26795 26796 ast_debug(2, "Session timer expired: %d - %s\n", p->stimer->st_schedid, p->callid); 26797 26798 if (!p->owner) { 26799 goto return_unref; 26800 } 26801 26802 if ((p->stimer->st_active != TRUE) || (p->owner->_state != AST_STATE_UP)) { 26803 goto return_unref; 26804 } 26805 26806 if (p->stimer->st_ref == SESSION_TIMER_REFRESHER_US) { 26807 res = 1; 26808 if (T38_ENABLED == p->t38.state) { 26809 transmit_reinvite_with_sdp(p, TRUE, TRUE); 26810 } else { 26811 transmit_reinvite_with_sdp(p, FALSE, TRUE); 26812 } 26813 } else { 26814 if (p->stimer->quit_flag) { 26815 goto return_unref; 26816 } 26817 ast_log(LOG_WARNING, "Session-Timer expired - %s\n", p->callid); 26818 sip_pvt_lock(p); 26819 while (p->owner && ast_channel_trylock(p->owner)) { 26820 sip_pvt_unlock(p); 26821 usleep(1); 26822 if (p->stimer && p->stimer->quit_flag) { 26823 goto return_unref; 26824 } 26825 sip_pvt_lock(p); 26826 } 26827 26828 ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV); 26829 ast_channel_unlock(p->owner); 26830 sip_pvt_unlock(p); 26831 } 26832 26833 return_unref: 26834 if (!res) { 26835 /* An error occurred. Stop session timer processing */ 26836 if (p->stimer) { 26837 ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid); 26838 /* Don't pass go, don't collect $200.. we are the scheduled 26839 * callback. We can rip ourself out here. */ 26840 p->stimer->st_schedid = -1; 26841 /* Calling stop_session_timer is nice for consistent debug 26842 * logs. */ 26843 stop_session_timer(p); 26844 } 26845 26846 /* If we are not asking to be rescheduled, then we need to release our 26847 * reference to the dialog. */ 26848 dialog_unref(p, "removing session timer ref"); 26849 } 26850 26851 return res; 26852 }
| static int process_crypto | ( | struct sip_pvt * | p, | |
| struct ast_rtp_instance * | rtp, | |||
| struct sip_srtp ** | srtp, | |||
| const char * | a | |||
| ) | [static] |
Definition at line 30537 of file chan_sip.c.
References ast_debug, ast_log(), ast_set_flag, ast_test_flag, FALSE, LOG_WARNING, sdp_crypto_process(), sdp_crypto_setup(), setup_srtp(), and TRUE.
Referenced by process_sdp().
30538 { 30539 /* If no RTP instance exists for this media stream don't bother processing the crypto line */ 30540 if (!rtp) { 30541 ast_debug(3, "Received offer with crypto line for media stream that is not enabled\n"); 30542 return FALSE; 30543 } 30544 30545 if (strncasecmp(a, "crypto:", 7)) { 30546 return FALSE; 30547 } 30548 if (!*srtp) { 30549 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 30550 ast_log(LOG_WARNING, "Ignoring unexpected crypto attribute in SDP answer\n"); 30551 return FALSE; 30552 } 30553 30554 if (setup_srtp(srtp) < 0) { 30555 return FALSE; 30556 } 30557 } 30558 30559 if (!(*srtp)->crypto && !((*srtp)->crypto = sdp_crypto_setup())) { 30560 return FALSE; 30561 } 30562 30563 if (sdp_crypto_process((*srtp)->crypto, a, rtp) < 0) { 30564 return FALSE; 30565 } 30566 30567 ast_set_flag(*srtp, SRTP_CRYPTO_OFFER_OK); 30568 30569 return TRUE; 30570 }
| static int process_sdp | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| int | t38action | |||
| ) | [static] |
Process SIP SDP offer, select formats and activate media channels If offer is rejected, we will not change any properties of the call Return 0 on success, a negative value on errors. Must be called after find_sdp().
< RTP audio destination IP address
< RTP video destination IP address
< RTP text destination IP address
< UDPTL image destination IP address
< RTP audio destination port number
< RTP video destination port number
< RTP text destination port number
< UDPTL image destination port number
Definition at line 9092 of file chan_sip.c.
References ast_async_goto(), ast_channel_lock, ast_channel_set_fd(), ast_channel_unlock, ast_clear_flag, ast_codec_choose(), AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, ast_copy_string(), ast_debug, ast_exists_extension(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_T140RED, ast_getformatname_multiple(), ast_log(), ast_null_frame, ast_queue_control(), ast_queue_control_data(), ast_queue_frame(), ast_rtp_codecs_payload_formats(), ast_rtp_codecs_payloads_clear(), ast_rtp_codecs_payloads_copy(), ast_rtp_codecs_payloads_set_m_type(), AST_RTP_DTMF, ast_rtp_instance_fd(), ast_rtp_instance_get_codecs(), ast_rtp_instance_get_remote_address(), ast_rtp_instance_set_prop(), ast_rtp_instance_set_remote_address(), ast_rtp_instance_stop(), ast_rtp_lookup_mime_multiple2(), AST_RTP_PROPERTY_DTMF, AST_RTP_PROPERTY_DTMF_COMPENSATE, AST_RTP_PROPERTY_RTCP, ast_rtp_red_init(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), ast_skip_blanks(), ast_sockaddr_isnull(), ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_str_alloca, ast_strlen_zero(), ast_test_flag, ast_udptl_get_far_max_datagram(), ast_udptl_set_error_correction_scheme(), ast_udptl_set_far_max_datagram(), ast_udptl_set_peer(), ast_udptl_stop(), ast_verbose, change_hold_state(), change_t38_state(), FALSE, get_sdp_iterate(), get_sdp_line(), initialize_udptl(), len(), LOG_ERROR, LOG_NOTICE, LOG_WARNING, pbx_builtin_setvar_helper(), process_crypto(), process_sdp_a_audio(), process_sdp_a_image(), process_sdp_a_sendonly(), process_sdp_a_text(), process_sdp_a_video(), process_sdp_c(), process_sdp_o(), S_COR, S_OR, sip_debug_test_pvt(), sockaddr_is_null_or_any(), text, TRUE, type, UDPTL_ERROR_CORRECTION_NONE, value, and VERBOSE_PREFIX_2.
Referenced by handle_incoming(), handle_request_invite(), handle_response(), and handle_response_invite().
09093 { 09094 /* Iterators for SDP parsing */ 09095 int start = req->sdp_start; 09096 int next = start; 09097 int iterator = start; 09098 09099 /* Temporary vars for SDP parsing */ 09100 char type = '\0'; 09101 const char *value = NULL; 09102 const char *m = NULL; /* SDP media offer */ 09103 const char *nextm = NULL; 09104 int len = -1; 09105 09106 /* Host information */ 09107 struct ast_sockaddr sessionsa; 09108 struct ast_sockaddr audiosa; 09109 struct ast_sockaddr videosa; 09110 struct ast_sockaddr textsa; 09111 struct ast_sockaddr imagesa; 09112 struct ast_sockaddr *sa = NULL; /*!< RTP audio destination IP address */ 09113 struct ast_sockaddr *vsa = NULL; /*!< RTP video destination IP address */ 09114 struct ast_sockaddr *tsa = NULL; /*!< RTP text destination IP address */ 09115 struct ast_sockaddr *isa = NULL; /*!< UDPTL image destination IP address */ 09116 int portno = -1; /*!< RTP audio destination port number */ 09117 int vportno = -1; /*!< RTP video destination port number */ 09118 int tportno = -1; /*!< RTP text destination port number */ 09119 int udptlportno = -1; /*!< UDPTL image destination port number */ 09120 09121 /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */ 09122 format_t peercapability = 0, vpeercapability = 0, tpeercapability = 0; 09123 int peernoncodeccapability = 0, vpeernoncodeccapability = 0, tpeernoncodeccapability = 0; 09124 09125 struct ast_rtp_codecs newaudiortp, newvideortp, newtextrtp; 09126 format_t newjointcapability; /* Negotiated capability */ 09127 format_t newpeercapability; 09128 int newnoncodeccapability; 09129 09130 const char *codecs; 09131 unsigned int codec; 09132 09133 /* SRTP */ 09134 int secure_audio = FALSE; 09135 int secure_video = FALSE; 09136 09137 /* Others */ 09138 int sendonly = -1; 09139 unsigned int numberofports; 09140 int numberofmediastreams = 0; 09141 int last_rtpmap_codec = 0; 09142 int red_data_pt[10]; /* For T.140 RED */ 09143 int red_num_gen = 0; /* For T.140 RED */ 09144 char red_fmtp[100] = "empty"; /* For T.140 RED */ 09145 int debug = sip_debug_test_pvt(p); 09146 09147 /* START UNKNOWN */ 09148 char buf[SIPBUFSIZE]; 09149 /* END UNKNOWN */ 09150 09151 /* Initial check */ 09152 if (!p->rtp) { 09153 ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n"); 09154 return -1; 09155 } 09156 09157 /* Make sure that the codec structures are all cleared out */ 09158 ast_rtp_codecs_payloads_clear(&newaudiortp, NULL); 09159 ast_rtp_codecs_payloads_clear(&newvideortp, NULL); 09160 ast_rtp_codecs_payloads_clear(&newtextrtp, NULL); 09161 09162 /* Update our last rtprx when we receive an SDP, too */ 09163 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 09164 09165 memset(p->offered_media, 0, sizeof(p->offered_media)); 09166 09167 /* default: novideo and notext set */ 09168 p->novideo = TRUE; 09169 p->notext = TRUE; 09170 09171 /* Scan for the first media stream (m=) line to limit scanning of globals */ 09172 nextm = get_sdp_iterate(&next, req, "m"); 09173 if (ast_strlen_zero(nextm)) { 09174 ast_log(LOG_WARNING, "Insufficient information for SDP (m= not found)\n"); 09175 return -1; 09176 } 09177 09178 /* Scan session level SDP parameters (lines before first media stream) */ 09179 while ((type = get_sdp_line(&iterator, next - 1, req, &value)) != '\0') { 09180 int processed = FALSE; 09181 switch (type) { 09182 case 'o': 09183 /* If we end up receiving SDP that doesn't actually modify the session we don't want to treat this as a fatal 09184 * error. We just want to ignore the SDP and let the rest of the packet be handled as normal. 09185 */ 09186 if (!process_sdp_o(value, p)) { 09187 return (p->session_modify == FALSE) ? 0 : -1; 09188 } 09189 processed = TRUE; 09190 break; 09191 case 'c': 09192 if (process_sdp_c(value, &sessionsa)) { 09193 processed = TRUE; 09194 sa = &sessionsa; 09195 vsa = sa; 09196 tsa = sa; 09197 isa = sa; 09198 } 09199 break; 09200 case 'a': 09201 if (process_sdp_a_sendonly(value, &sendonly)) { 09202 processed = TRUE; 09203 } 09204 else if (process_sdp_a_audio(value, p, &newaudiortp, &last_rtpmap_codec)) 09205 processed = TRUE; 09206 else if (process_sdp_a_video(value, p, &newvideortp, &last_rtpmap_codec)) 09207 processed = TRUE; 09208 else if (process_sdp_a_text(value, p, &newtextrtp, red_fmtp, &red_num_gen, red_data_pt, &last_rtpmap_codec)) 09209 processed = TRUE; 09210 else if (process_sdp_a_image(value, p)) 09211 processed = TRUE; 09212 break; 09213 } 09214 09215 ast_debug(3, "Processing session-level SDP %c=%s... %s\n", type, value, (processed == TRUE)? "OK." : "UNSUPPORTED OR FAILED."); 09216 } 09217 09218 /* Scan media stream (m=) specific parameters loop */ 09219 while (!ast_strlen_zero(nextm)) { 09220 int audio = FALSE; 09221 int video = FALSE; 09222 int image = FALSE; 09223 int text = FALSE; 09224 int processed_crypto = FALSE; 09225 char protocol[18] = {0,}; 09226 unsigned int x; 09227 09228 numberofports = 0; 09229 len = -1; 09230 start = next; 09231 m = nextm; 09232 iterator = next; 09233 nextm = get_sdp_iterate(&next, req, "m"); 09234 09235 /* Check for 'audio' media offer */ 09236 if (strncmp(m, "audio ", 6) == 0) { 09237 if ((sscanf(m, "audio %30u/%30u RTP/%4s %n", &x, &numberofports, protocol, &len) == 3 && len > 0) || 09238 (sscanf(m, "audio %30u RTP/%4s %n", &x, protocol, &len) == 2 && len > 0)) { 09239 if (x == 0) { 09240 ast_log(LOG_WARNING, "Ignoring audio media offer because port number is zero\n"); 09241 continue; 09242 } 09243 09244 /* Check number of ports offered for stream */ 09245 if (numberofports > 1) { 09246 ast_log(LOG_WARNING, "%u ports offered for audio media, not supported by Asterisk. Will try anyway...\n", numberofports); 09247 } 09248 09249 if (!strcmp(protocol, "SAVP")) { 09250 secure_audio = 1; 09251 } else if (strcmp(protocol, "AVP")) { 09252 ast_log(LOG_WARNING, "Unknown RTP profile in audio offer: %s\n", m); 09253 continue; 09254 } 09255 09256 if (p->offered_media[SDP_AUDIO].order_offered) { 09257 ast_log(LOG_WARNING, "Rejecting non-primary audio stream: %s\n", m); 09258 return -1; 09259 } 09260 09261 audio = TRUE; 09262 p->offered_media[SDP_AUDIO].order_offered = ++numberofmediastreams; 09263 portno = x; 09264 09265 /* Scan through the RTP payload types specified in a "m=" line: */ 09266 codecs = m + len; 09267 ast_copy_string(p->offered_media[SDP_AUDIO].codecs, codecs, sizeof(p->offered_media[SDP_AUDIO].codecs)); 09268 for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 09269 if (sscanf(codecs, "%30u%n", &codec, &len) != 1) { 09270 ast_log(LOG_WARNING, "Invalid syntax in RTP audio format list: %s\n", codecs); 09271 return -1; 09272 } 09273 if (debug) { 09274 ast_verbose("Found RTP audio format %u\n", codec); 09275 } 09276 09277 ast_rtp_codecs_payloads_set_m_type(&newaudiortp, NULL, codec); 09278 } 09279 } else { 09280 ast_log(LOG_WARNING, "Rejecting audio media offer due to invalid or unsupported syntax: %s\n", m); 09281 return -1; 09282 } 09283 } 09284 /* Check for 'video' media offer */ 09285 else if (strncmp(m, "video ", 6) == 0) { 09286 if ((sscanf(m, "video %30u/%30u RTP/%4s %n", &x, &numberofports, protocol, &len) == 3 && len > 0) || 09287 (sscanf(m, "video %30u RTP/%4s %n", &x, protocol, &len) == 2 && len > 0)) { 09288 if (x == 0) { 09289 ast_log(LOG_WARNING, "Ignoring video media offer because port number is zero\n"); 09290 continue; 09291 } 09292 09293 /* Check number of ports offered for stream */ 09294 if (numberofports > 1) { 09295 ast_log(LOG_WARNING, "%u ports offered for video media, not supported by Asterisk. Will try anyway...\n", numberofports); 09296 } 09297 09298 if (!strcmp(protocol, "SAVP")) { 09299 secure_video = 1; 09300 } else if (strcmp(protocol, "AVP")) { 09301 ast_log(LOG_WARNING, "Unknown RTP profile in video offer: %s\n", m); 09302 continue; 09303 } 09304 09305 if (p->offered_media[SDP_VIDEO].order_offered) { 09306 ast_log(LOG_WARNING, "Rejecting non-primary video stream: %s\n", m); 09307 return -1; 09308 } 09309 09310 video = TRUE; 09311 p->novideo = FALSE; 09312 p->offered_media[SDP_VIDEO].order_offered = ++numberofmediastreams; 09313 vportno = x; 09314 09315 /* Scan through the RTP payload types specified in a "m=" line: */ 09316 codecs = m + len; 09317 ast_copy_string(p->offered_media[SDP_VIDEO].codecs, codecs, sizeof(p->offered_media[SDP_VIDEO].codecs)); 09318 for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 09319 if (sscanf(codecs, "%30u%n", &codec, &len) != 1) { 09320 ast_log(LOG_WARNING, "Invalid syntax in RTP video format list: %s\n", codecs); 09321 return -1; 09322 } 09323 if (debug) { 09324 ast_verbose("Found RTP video format %u\n", codec); 09325 } 09326 ast_rtp_codecs_payloads_set_m_type(&newvideortp, NULL, codec); 09327 } 09328 } else { 09329 ast_log(LOG_WARNING, "Rejecting video media offer due to invalid or unsupported syntax: %s\n", m); 09330 return -1; 09331 } 09332 } 09333 /* Check for 'text' media offer */ 09334 else if (strncmp(m, "text ", 5) == 0) { 09335 if ((sscanf(m, "text %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 09336 (sscanf(m, "text %30u RTP/AVP %n", &x, &len) == 1 && len > 0)) { 09337 if (x == 0) { 09338 ast_log(LOG_WARNING, "Ignoring text media offer because port number is zero\n"); 09339 continue; 09340 } 09341 09342 /* Check number of ports offered for stream */ 09343 if (numberofports > 1) { 09344 ast_log(LOG_WARNING, "%u ports offered for text media, not supported by Asterisk. Will try anyway...\n", numberofports); 09345 } 09346 09347 if (p->offered_media[SDP_TEXT].order_offered) { 09348 ast_log(LOG_WARNING, "Rejecting non-primary text stream: %s\n", m); 09349 return -1; 09350 } 09351 09352 text = TRUE; 09353 p->notext = FALSE; 09354 p->offered_media[SDP_TEXT].order_offered = ++numberofmediastreams; 09355 tportno = x; 09356 09357 /* Scan through the RTP payload types specified in a "m=" line: */ 09358 codecs = m + len; 09359 ast_copy_string(p->offered_media[SDP_TEXT].codecs, codecs, sizeof(p->offered_media[SDP_TEXT].codecs)); 09360 for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 09361 if (sscanf(codecs, "%30u%n", &codec, &len) != 1) { 09362 ast_log(LOG_WARNING, "Invalid syntax in RTP video format list: %s\n", codecs); 09363 return -1; 09364 } 09365 if (debug) { 09366 ast_verbose("Found RTP text format %u\n", codec); 09367 } 09368 ast_rtp_codecs_payloads_set_m_type(&newtextrtp, NULL, codec); 09369 } 09370 } else { 09371 ast_log(LOG_WARNING, "Rejecting text media offer due to invalid or unsupported syntax: %s\n", m); 09372 return -1; 09373 } 09374 } 09375 /* Check for 'image' media offer */ 09376 else if (strncmp(m, "image ", 6) == 0) { 09377 if (((sscanf(m, "image %30u udptl t38%n", &x, &len) == 1 && len > 0) || 09378 (sscanf(m, "image %30u UDPTL t38%n", &x, &len) == 1 && len > 0))) { 09379 if (x == 0) { 09380 ast_log(LOG_WARNING, "Ignoring image media offer because port number is zero\n"); 09381 continue; 09382 } 09383 09384 if (initialize_udptl(p)) { 09385 ast_log(LOG_WARNING, "Rejecting offer with image stream due to UDPTL initialization failure\n"); 09386 return -1; 09387 } 09388 09389 if (p->offered_media[SDP_IMAGE].order_offered) { 09390 ast_log(LOG_WARNING, "Rejecting non-primary image stream: %s\n", m); 09391 return -1; 09392 } 09393 09394 image = TRUE; 09395 if (debug) { 09396 ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid); 09397 } 09398 09399 p->offered_media[SDP_IMAGE].order_offered = ++numberofmediastreams; 09400 udptlportno = x; 09401 09402 if (p->t38.state != T38_ENABLED) { 09403 memset(&p->t38.their_parms, 0, sizeof(p->t38.their_parms)); 09404 09405 /* default EC to none, the remote end should 09406 * respond with the EC they want to use */ 09407 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 09408 } 09409 } else if (sscanf(m, "image %30u %17s t38%n", &x, protocol, &len) == 2 && len > 0) { 09410 ast_log(LOG_WARNING, "Declining image stream due to unsupported transport: %s\n", m); 09411 continue; 09412 } else { 09413 ast_log(LOG_WARNING, "Rejecting image media offer due to invalid or unsupported syntax: %s\n", m); 09414 return -1; 09415 } 09416 } else { 09417 ast_log(LOG_WARNING, "Unsupported top-level media type in offer: %s\n", m); 09418 continue; 09419 } 09420 09421 /* Media stream specific parameters */ 09422 while ((type = get_sdp_line(&iterator, next - 1, req, &value)) != '\0') { 09423 int processed = FALSE; 09424 09425 switch (type) { 09426 case 'c': 09427 if (audio) { 09428 if (process_sdp_c(value, &audiosa)) { 09429 processed = TRUE; 09430 sa = &audiosa; 09431 } 09432 } else if (video) { 09433 if (process_sdp_c(value, &videosa)) { 09434 processed = TRUE; 09435 vsa = &videosa; 09436 } 09437 } else if (text) { 09438 if (process_sdp_c(value, &textsa)) { 09439 processed = TRUE; 09440 tsa = &textsa; 09441 } 09442 } else if (image) { 09443 if (process_sdp_c(value, &imagesa)) { 09444 processed = TRUE; 09445 isa = &imagesa; 09446 } 09447 } 09448 break; 09449 case 'a': 09450 /* Audio specific scanning */ 09451 if (audio) { 09452 if (process_sdp_a_sendonly(value, &sendonly)) { 09453 processed = TRUE; 09454 } else if (!processed_crypto && process_crypto(p, p->rtp, &p->srtp, value)) { 09455 processed_crypto = TRUE; 09456 processed = TRUE; 09457 } else if (process_sdp_a_audio(value, p, &newaudiortp, &last_rtpmap_codec)) { 09458 processed = TRUE; 09459 } 09460 } 09461 /* Video specific scanning */ 09462 else if (video) { 09463 if (!processed_crypto && process_crypto(p, p->vrtp, &p->vsrtp, value)) { 09464 processed_crypto = TRUE; 09465 processed = TRUE; 09466 } else if (process_sdp_a_video(value, p, &newvideortp, &last_rtpmap_codec)) { 09467 processed = TRUE; 09468 } 09469 } 09470 /* Text (T.140) specific scanning */ 09471 else if (text) { 09472 if (process_sdp_a_text(value, p, &newtextrtp, red_fmtp, &red_num_gen, red_data_pt, &last_rtpmap_codec)) { 09473 processed = TRUE; 09474 } else if (!processed_crypto && process_crypto(p, p->trtp, &p->tsrtp, value)) { 09475 processed_crypto = TRUE; 09476 processed = TRUE; 09477 } 09478 } 09479 /* Image (T.38 FAX) specific scanning */ 09480 else if (image) { 09481 if (process_sdp_a_image(value, p)) 09482 processed = TRUE; 09483 } 09484 break; 09485 } 09486 09487 ast_debug(3, "Processing media-level (%s) SDP %c=%s... %s\n", 09488 (audio == TRUE)? "audio" : (video == TRUE)? "video" : (text == TRUE)? "text" : "image", 09489 type, value, 09490 (processed == TRUE)? "OK." : "UNSUPPORTED OR FAILED."); 09491 } 09492 09493 /* Ensure crypto lines are provided where necessary */ 09494 if (audio && secure_audio && !processed_crypto) { 09495 ast_log(LOG_WARNING, "Rejecting secure audio stream without encryption details: %s\n", m); 09496 return -1; 09497 } else if (video && secure_video && !processed_crypto) { 09498 ast_log(LOG_WARNING, "Rejecting secure video stream without encryption details: %s\n", m); 09499 return -1; 09500 } 09501 } 09502 09503 /* Sanity checks */ 09504 if (!sa && !vsa && !tsa && !isa) { 09505 ast_log(LOG_WARNING, "Insufficient information in SDP (c=)...\n"); 09506 return -1; 09507 } 09508 09509 if ((portno == -1) && 09510 (vportno == -1) && 09511 (tportno == -1) && 09512 (udptlportno == -1)) { 09513 ast_log(LOG_WARNING, "Failing due to no acceptable offer found\n"); 09514 return -1; 09515 } 09516 09517 if (secure_audio && !(p->srtp && (ast_test_flag(p->srtp, SRTP_CRYPTO_OFFER_OK)))) { 09518 ast_log(LOG_WARNING, "Can't provide secure audio requested in SDP offer\n"); 09519 return -1; 09520 } 09521 09522 if (!secure_audio && p->srtp) { 09523 ast_log(LOG_WARNING, "We are requesting SRTP for audio, but they responded without it!\n"); 09524 return -1; 09525 } 09526 09527 if (secure_video && !(p->vsrtp && (ast_test_flag(p->vsrtp, SRTP_CRYPTO_OFFER_OK)))) { 09528 ast_log(LOG_WARNING, "Can't provide secure video requested in SDP offer\n"); 09529 return -1; 09530 } 09531 09532 if (!p->novideo && !secure_video && p->vsrtp) { 09533 ast_log(LOG_WARNING, "We are requesting SRTP for video, but they responded without it!\n"); 09534 return -1; 09535 } 09536 09537 if (!(secure_audio || secure_video) && ast_test_flag(&p->flags[1], SIP_PAGE2_USE_SRTP)) { 09538 ast_log(LOG_WARNING, "Matched device setup to use SRTP, but request was not!\n"); 09539 return -1; 09540 } 09541 09542 if (udptlportno == -1) { 09543 change_t38_state(p, T38_DISABLED); 09544 } 09545 09546 /* Now gather all of the codecs that we are asked for: */ 09547 ast_rtp_codecs_payload_formats(&newaudiortp, &peercapability, &peernoncodeccapability); 09548 ast_rtp_codecs_payload_formats(&newvideortp, &vpeercapability, &vpeernoncodeccapability); 09549 ast_rtp_codecs_payload_formats(&newtextrtp, &tpeercapability, &tpeernoncodeccapability); 09550 09551 newjointcapability = p->capability & (peercapability | vpeercapability | tpeercapability); 09552 newpeercapability = (peercapability | vpeercapability | tpeercapability); 09553 newnoncodeccapability = p->noncodeccapability & peernoncodeccapability; 09554 09555 if (debug) { 09556 /* shame on whoever coded this.... */ 09557 char s1[SIPBUFSIZE], s2[SIPBUFSIZE], s3[SIPBUFSIZE], s4[SIPBUFSIZE], s5[SIPBUFSIZE]; 09558 09559 ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s/text=%s, combined - %s\n", 09560 ast_getformatname_multiple(s1, SIPBUFSIZE, p->capability), 09561 ast_getformatname_multiple(s2, SIPBUFSIZE, peercapability), 09562 ast_getformatname_multiple(s3, SIPBUFSIZE, vpeercapability), 09563 ast_getformatname_multiple(s4, SIPBUFSIZE, tpeercapability), 09564 ast_getformatname_multiple(s5, SIPBUFSIZE, newjointcapability)); 09565 } 09566 if (debug) { 09567 struct ast_str *s1 = ast_str_alloca(SIPBUFSIZE); 09568 struct ast_str *s2 = ast_str_alloca(SIPBUFSIZE); 09569 struct ast_str *s3 = ast_str_alloca(SIPBUFSIZE); 09570 09571 ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n", 09572 ast_rtp_lookup_mime_multiple2(s1, p->noncodeccapability, 0, 0), 09573 ast_rtp_lookup_mime_multiple2(s2, peernoncodeccapability, 0, 0), 09574 ast_rtp_lookup_mime_multiple2(s3, newnoncodeccapability, 0, 0)); 09575 } 09576 if (!newjointcapability && udptlportno == -1) { 09577 ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n"); 09578 /* Do NOT Change current setting */ 09579 return -1; 09580 } 09581 09582 if (portno != -1 || vportno != -1 || tportno != -1) { 09583 /* We are now ready to change the sip session and RTP structures with the offered codecs, since 09584 they are acceptable */ 09585 p->jointcapability = newjointcapability; /* Our joint codec profile for this call */ 09586 p->peercapability = newpeercapability; /* The other side's capability in latest offer */ 09587 p->jointnoncodeccapability = newnoncodeccapability; /* DTMF capabilities */ 09588 09589 /* respond with single most preferred joint codec, limiting the other side's choice */ 09590 if (ast_test_flag(&p->flags[1], SIP_PAGE2_PREFERRED_CODEC)) { 09591 p->jointcapability = ast_codec_choose(&p->prefs, p->jointcapability, 1); 09592 } 09593 } 09594 09595 /* Setup audio address and port */ 09596 if (p->rtp) { 09597 if (sa && portno > 0) { 09598 ast_sockaddr_set_port(sa, portno); 09599 ast_rtp_instance_set_remote_address(p->rtp, sa); 09600 if (debug) { 09601 ast_verbose("Peer audio RTP is at port %s\n", 09602 ast_sockaddr_stringify(sa)); 09603 } 09604 09605 ast_rtp_codecs_payloads_copy(&newaudiortp, ast_rtp_instance_get_codecs(p->rtp), p->rtp); 09606 /* Ensure RTCP is enabled since it may be inactive 09607 if we're coming back from a T.38 session */ 09608 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_RTCP, 1); 09609 /* Ensure audio RTCP reads are enabled */ 09610 if (p->owner) { 09611 ast_channel_set_fd(p->owner, 1, ast_rtp_instance_fd(p->rtp, 1)); 09612 } 09613 09614 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) { 09615 ast_clear_flag(&p->flags[0], SIP_DTMF); 09616 if (newnoncodeccapability & AST_RTP_DTMF) { 09617 /* XXX Would it be reasonable to drop the DSP at this point? XXX */ 09618 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 09619 /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */ 09620 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF, 1); 09621 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 09622 } else { 09623 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 09624 } 09625 } 09626 } else if (udptlportno > 0) { 09627 if (debug) 09628 ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session.\n"); 09629 /* Prevent audio RTCP reads */ 09630 if (p->owner) { 09631 ast_channel_set_fd(p->owner, 1, -1); 09632 } 09633 /* Silence RTCP while audio RTP is inactive */ 09634 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_RTCP, 0); 09635 } else { 09636 ast_rtp_instance_stop(p->rtp); 09637 if (debug) 09638 ast_verbose("Peer doesn't provide audio\n"); 09639 } 09640 } 09641 09642 /* Setup video address and port */ 09643 if (p->vrtp) { 09644 if (vsa && vportno > 0) { 09645 ast_sockaddr_set_port(vsa, vportno); 09646 ast_rtp_instance_set_remote_address(p->vrtp, vsa); 09647 if (debug) { 09648 ast_verbose("Peer video RTP is at port %s\n", 09649 ast_sockaddr_stringify(vsa)); 09650 } 09651 ast_rtp_codecs_payloads_copy(&newvideortp, ast_rtp_instance_get_codecs(p->vrtp), p->vrtp); 09652 } else { 09653 ast_rtp_instance_stop(p->vrtp); 09654 if (debug) 09655 ast_verbose("Peer doesn't provide video\n"); 09656 } 09657 } 09658 09659 /* Setup text address and port */ 09660 if (p->trtp) { 09661 if (tsa && tportno > 0) { 09662 ast_sockaddr_set_port(tsa, tportno); 09663 ast_rtp_instance_set_remote_address(p->trtp, tsa); 09664 if (debug) { 09665 ast_verbose("Peer T.140 RTP is at port %s\n", 09666 ast_sockaddr_stringify(tsa)); 09667 } 09668 if ((p->jointcapability & AST_FORMAT_T140RED)) { 09669 p->red = 1; 09670 ast_rtp_red_init(p->trtp, 300, red_data_pt, 2); 09671 } else { 09672 p->red = 0; 09673 } 09674 ast_rtp_codecs_payloads_copy(&newtextrtp, ast_rtp_instance_get_codecs(p->trtp), p->trtp); 09675 } else { 09676 ast_rtp_instance_stop(p->trtp); 09677 if (debug) 09678 ast_verbose("Peer doesn't provide T.140\n"); 09679 } 09680 } 09681 09682 /* Setup image address and port */ 09683 if (p->udptl) { 09684 if (isa && udptlportno > 0) { 09685 if (ast_test_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP) && ast_test_flag(&p->flags[1], SIP_PAGE2_UDPTL_DESTINATION)) { 09686 ast_rtp_instance_get_remote_address(p->rtp, isa); 09687 if (!ast_sockaddr_isnull(isa) && debug) { 09688 ast_debug(1, "Peer T.38 UDPTL is set behind NAT and with destination, destination address now %s\n", ast_sockaddr_stringify(isa)); 09689 } 09690 } 09691 ast_sockaddr_set_port(isa, udptlportno); 09692 ast_udptl_set_peer(p->udptl, isa); 09693 if (debug) 09694 ast_debug(1,"Peer T.38 UDPTL is at port %s\n", ast_sockaddr_stringify(isa)); 09695 09696 /* verify the far max ifp can be calculated. this requires far max datagram to be set. */ 09697 if (!ast_udptl_get_far_max_datagram(p->udptl)) { 09698 /* setting to zero will force a default if none was provided by the SDP */ 09699 ast_udptl_set_far_max_datagram(p->udptl, 0); 09700 } 09701 09702 /* Remote party offers T38, we need to update state */ 09703 if ((t38action == SDP_T38_ACCEPT) && 09704 (p->t38.state == T38_LOCAL_REINVITE)) { 09705 change_t38_state(p, T38_ENABLED); 09706 } else if ((t38action == SDP_T38_INITIATE) && 09707 p->owner && p->lastinvite) { 09708 change_t38_state(p, T38_PEER_REINVITE); /* T38 Offered in re-invite from remote party */ 09709 /* If fax detection is enabled then send us off to the fax extension */ 09710 if (ast_test_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_T38)) { 09711 ast_channel_lock(p->owner); 09712 if (strcmp(p->owner->exten, "fax")) { 09713 const char *target_context = S_OR(p->owner->macrocontext, p->owner->context); 09714 ast_channel_unlock(p->owner); 09715 if (ast_exists_extension(p->owner, target_context, "fax", 1, 09716 S_COR(p->owner->caller.id.number.valid, p->owner->caller.id.number.str, NULL))) { 09717 ast_verbose(VERBOSE_PREFIX_2 "Redirecting '%s' to fax extension due to peer T.38 re-INVITE\n", p->owner->name); 09718 pbx_builtin_setvar_helper(p->owner, "FAXEXTEN", p->owner->exten); 09719 if (ast_async_goto(p->owner, target_context, "fax", 1)) { 09720 ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", p->owner->name, target_context); 09721 } 09722 } else { 09723 ast_log(LOG_NOTICE, "T.38 re-INVITE detected but no fax extension\n"); 09724 } 09725 } else { 09726 ast_channel_unlock(p->owner); 09727 } 09728 } 09729 } 09730 } else { 09731 change_t38_state(p, T38_DISABLED); 09732 ast_udptl_stop(p->udptl); 09733 if (debug) 09734 ast_debug(1, "Peer doesn't provide T.38 UDPTL\n"); 09735 } 09736 } 09737 09738 if ((portno == -1) && (p->t38.state != T38_DISABLED)) { 09739 ast_debug(3, "Have T.38 but no audio, accepting offer anyway\n"); 09740 return 0; 09741 } 09742 09743 /* Ok, we're going with this offer */ 09744 ast_debug(2, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, p->jointcapability)); 09745 09746 if (!p->owner) /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */ 09747 return 0; 09748 09749 ast_debug(4, "We have an owner, now see if we need to change this call\n"); 09750 09751 if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 09752 if (debug) { 09753 char s1[SIPBUFSIZE], s2[SIPBUFSIZE]; 09754 ast_debug(1, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n", 09755 ast_getformatname_multiple(s1, SIPBUFSIZE, p->jointcapability), 09756 ast_getformatname_multiple(s2, SIPBUFSIZE, p->owner->nativeformats)); 09757 } 09758 p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability) | (p->capability & tpeercapability); 09759 ast_set_read_format(p->owner, p->owner->readformat); 09760 ast_set_write_format(p->owner, p->owner->writeformat); 09761 } 09762 09763 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && (!ast_sockaddr_isnull(sa) || !ast_sockaddr_isnull(vsa) || !ast_sockaddr_isnull(tsa) || !ast_sockaddr_isnull(isa)) && (!sendonly || sendonly == -1)) { 09764 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 09765 /* Activate a re-invite */ 09766 ast_queue_frame(p->owner, &ast_null_frame); 09767 change_hold_state(p, req, FALSE, sendonly); 09768 } else if ((sockaddr_is_null_or_any(sa) && sockaddr_is_null_or_any(vsa) && sockaddr_is_null_or_any(tsa) && sockaddr_is_null_or_any(isa)) || (sendonly && sendonly != -1)) { 09769 ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 09770 S_OR(p->mohsuggest, NULL), 09771 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 09772 if (sendonly) 09773 ast_rtp_instance_stop(p->rtp); 09774 /* RTCP needs to go ahead, even if we're on hold!!! */ 09775 /* Activate a re-invite */ 09776 ast_queue_frame(p->owner, &ast_null_frame); 09777 change_hold_state(p, req, TRUE, sendonly); 09778 } 09779 09780 return 0; 09781 }
| static int process_sdp_a_audio | ( | const char * | a, | |
| struct sip_pvt * | p, | |||
| struct ast_rtp_codecs * | newaudiortp, | |||
| int * | last_rtpmap_codec | |||
| ) | [static] |
Definition at line 9909 of file chan_sip.c.
References ast_codec_pref_setsize(), ast_debug, AST_FORMAT_G719, AST_FORMAT_SIREN14, AST_FORMAT_SIREN7, ast_getformatname(), ast_log(), ast_rtp_codecs_packetization_set(), ast_rtp_codecs_payload_lookup(), ast_rtp_codecs_payloads_set_rtpmap_type_rate(), ast_rtp_codecs_payloads_unset(), ast_rtp_instance_get_codecs(), AST_RTP_MAX_PT, AST_RTP_OPT_G726_NONSTANDARD, ast_test_flag, ast_verbose, ast_rtp_payload_type::asterisk_format, ast_rtp_payload_type::code, FALSE, format, LOG_WARNING, ast_rtp_codecs::pref, sip_debug_test_pvt(), and TRUE.
Referenced by process_sdp().
09910 { 09911 int found = FALSE; 09912 unsigned int codec; 09913 char mimeSubtype[128]; 09914 char fmtp_string[64]; 09915 unsigned int sample_rate; 09916 int debug = sip_debug_test_pvt(p); 09917 09918 if (!strncasecmp(a, "ptime", 5)) { 09919 char *tmp = strrchr(a, ':'); 09920 long int framing = 0; 09921 if (tmp) { 09922 tmp++; 09923 framing = strtol(tmp, NULL, 10); 09924 if (framing == LONG_MIN || framing == LONG_MAX) { 09925 framing = 0; 09926 ast_debug(1, "Can't read framing from SDP: %s\n", a); 09927 } 09928 } 09929 if (framing && p->autoframing) { 09930 struct ast_codec_pref *pref = &ast_rtp_instance_get_codecs(p->rtp)->pref; 09931 int codec_n; 09932 for (codec_n = 0; codec_n < AST_RTP_MAX_PT; codec_n++) { 09933 struct ast_rtp_payload_type format = ast_rtp_codecs_payload_lookup(ast_rtp_instance_get_codecs(p->rtp), codec_n); 09934 if (!format.asterisk_format || !format.code) /* non-codec or not found */ 09935 continue; 09936 ast_debug(1, "Setting framing for %s to %ld\n", ast_getformatname(format.code), framing); 09937 ast_codec_pref_setsize(pref, format.code, framing); 09938 } 09939 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, pref); 09940 } 09941 found = TRUE; 09942 } else if (sscanf(a, "rtpmap: %30u %127[^/]/%30u", &codec, mimeSubtype, &sample_rate) == 3) { 09943 /* We have a rtpmap to handle */ 09944 if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 09945 if (!(ast_rtp_codecs_payloads_set_rtpmap_type_rate(newaudiortp, NULL, codec, "audio", mimeSubtype, 09946 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0, sample_rate))) { 09947 if (debug) 09948 ast_verbose("Found audio description format %s for ID %u\n", mimeSubtype, codec); 09949 //found_rtpmap_codecs[last_rtpmap_codec] = codec; 09950 (*last_rtpmap_codec)++; 09951 found = TRUE; 09952 } else { 09953 ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec); 09954 if (debug) 09955 ast_verbose("Found unknown media description format %s for ID %u\n", mimeSubtype, codec); 09956 } 09957 } else { 09958 if (debug) 09959 ast_verbose("Discarded description format %s for ID %u\n", mimeSubtype, codec); 09960 } 09961 } else if (sscanf(a, "fmtp: %30u %63[^\t\n]", &codec, fmtp_string) == 2) { 09962 struct ast_rtp_payload_type payload; 09963 09964 payload = ast_rtp_codecs_payload_lookup(newaudiortp, codec); 09965 if (payload.code && payload.asterisk_format) { 09966 unsigned int bit_rate; 09967 09968 switch (payload.code) { 09969 case AST_FORMAT_SIREN7: 09970 if (sscanf(fmtp_string, "bitrate=%30u", &bit_rate) == 1) { 09971 if (bit_rate != 32000) { 09972 ast_log(LOG_WARNING, "Got Siren7 offer at %u bps, but only 32000 bps supported; ignoring.\n", bit_rate); 09973 ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec); 09974 } else { 09975 found = TRUE; 09976 } 09977 } 09978 break; 09979 case AST_FORMAT_SIREN14: 09980 if (sscanf(fmtp_string, "bitrate=%30u", &bit_rate) == 1) { 09981 if (bit_rate != 48000) { 09982 ast_log(LOG_WARNING, "Got Siren14 offer at %u bps, but only 48000 bps supported; ignoring.\n", bit_rate); 09983 ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec); 09984 } else { 09985 found = TRUE; 09986 } 09987 } 09988 break; 09989 case AST_FORMAT_G719: 09990 if (sscanf(fmtp_string, "bitrate=%30u", &bit_rate) == 1) { 09991 if (bit_rate != 64000) { 09992 ast_log(LOG_WARNING, "Got G.719 offer at %u bps, but only 64000 bps supported; ignoring.\n", bit_rate); 09993 ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec); 09994 } else { 09995 found = TRUE; 09996 } 09997 } 09998 } 09999 } 10000 } 10001 10002 return found; 10003 }
| static int process_sdp_a_image | ( | const char * | a, | |
| struct sip_pvt * | p | |||
| ) | [static] |
Definition at line 10088 of file chan_sip.c.
References ast_debug, ast_strdupa, AST_T38_RATE_12000, AST_T38_RATE_14400, AST_T38_RATE_2400, AST_T38_RATE_4800, AST_T38_RATE_7200, AST_T38_RATE_9600, AST_T38_RATE_MANAGEMENT_LOCAL_TCF, AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF, ast_udptl_set_error_correction_scheme(), ast_udptl_set_far_max_datagram(), FALSE, initialize_udptl(), TRUE, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, and UDPTL_ERROR_CORRECTION_REDUNDANCY.
Referenced by process_sdp().
10089 { 10090 int found = FALSE; 10091 char s[256]; 10092 unsigned int x; 10093 char *attrib = ast_strdupa(a); 10094 char *pos; 10095 10096 if (initialize_udptl(p)) { 10097 return found; 10098 } 10099 10100 /* Due to a typo in an IANA registration of one of the T.38 attributes, 10101 * RFC5347 section 2.5.2 recommends that all T.38 attributes be parsed in 10102 * a case insensitive manner. Hence, the importance of proof reading (and 10103 * code reviews). 10104 */ 10105 for (pos = attrib; *pos; ++pos) { 10106 *pos = tolower(*pos); 10107 } 10108 10109 if ((sscanf(attrib, "t38faxmaxbuffer:%30u", &x) == 1)) { 10110 ast_debug(3, "MaxBufferSize:%u\n", x); 10111 found = TRUE; 10112 } else if ((sscanf(attrib, "t38maxbitrate:%30u", &x) == 1) || (sscanf(attrib, "t38faxmaxrate:%30u", &x) == 1)) { 10113 ast_debug(3, "T38MaxBitRate: %u\n", x); 10114 switch (x) { 10115 case 14400: 10116 p->t38.their_parms.rate = AST_T38_RATE_14400; 10117 break; 10118 case 12000: 10119 p->t38.their_parms.rate = AST_T38_RATE_12000; 10120 break; 10121 case 9600: 10122 p->t38.their_parms.rate = AST_T38_RATE_9600; 10123 break; 10124 case 7200: 10125 p->t38.their_parms.rate = AST_T38_RATE_7200; 10126 break; 10127 case 4800: 10128 p->t38.their_parms.rate = AST_T38_RATE_4800; 10129 break; 10130 case 2400: 10131 p->t38.their_parms.rate = AST_T38_RATE_2400; 10132 break; 10133 } 10134 found = TRUE; 10135 } else if ((sscanf(attrib, "t38faxversion:%30u", &x) == 1)) { 10136 ast_debug(3, "FaxVersion: %u\n", x); 10137 p->t38.their_parms.version = x; 10138 found = TRUE; 10139 } else if ((sscanf(attrib, "t38faxmaxdatagram:%30u", &x) == 1) || (sscanf(attrib, "t38maxdatagram:%30u", &x) == 1)) { 10140 /* override the supplied value if the configuration requests it */ 10141 if (((signed int) p->t38_maxdatagram >= 0) && ((unsigned int) p->t38_maxdatagram > x)) { 10142 ast_debug(1, "Overriding T38FaxMaxDatagram '%u' with '%u'\n", x, p->t38_maxdatagram); 10143 x = p->t38_maxdatagram; 10144 } 10145 ast_debug(3, "FaxMaxDatagram: %u\n", x); 10146 ast_udptl_set_far_max_datagram(p->udptl, x); 10147 found = TRUE; 10148 } else if ((strncmp(attrib, "t38faxfillbitremoval", 20) == 0)) { 10149 if (sscanf(attrib, "t38faxfillbitremoval:%30u", &x) == 1) { 10150 ast_debug(3, "FillBitRemoval: %u\n", x); 10151 if (x == 1) { 10152 p->t38.their_parms.fill_bit_removal = TRUE; 10153 } 10154 } else { 10155 ast_debug(3, "FillBitRemoval\n"); 10156 p->t38.their_parms.fill_bit_removal = TRUE; 10157 } 10158 found = TRUE; 10159 } else if ((strncmp(attrib, "t38faxtranscodingmmr", 20) == 0)) { 10160 if (sscanf(attrib, "t38faxtranscodingmmr:%30u", &x) == 1) { 10161 ast_debug(3, "Transcoding MMR: %u\n", x); 10162 if (x == 1) { 10163 p->t38.their_parms.transcoding_mmr = TRUE; 10164 } 10165 } else { 10166 ast_debug(3, "Transcoding MMR\n"); 10167 p->t38.their_parms.transcoding_mmr = TRUE; 10168 } 10169 found = TRUE; 10170 } else if ((strncmp(attrib, "t38faxtranscodingjbig", 21) == 0)) { 10171 if (sscanf(attrib, "t38faxtranscodingjbig:%30u", &x) == 1) { 10172 ast_debug(3, "Transcoding JBIG: %u\n", x); 10173 if (x == 1) { 10174 p->t38.their_parms.transcoding_jbig = TRUE; 10175 } 10176 } else { 10177 ast_debug(3, "Transcoding JBIG\n"); 10178 p->t38.their_parms.transcoding_jbig = TRUE; 10179 } 10180 found = TRUE; 10181 } else if ((sscanf(attrib, "t38faxratemanagement:%255s", s) == 1)) { 10182 ast_debug(3, "RateManagement: %s\n", s); 10183 if (!strcasecmp(s, "localTCF")) 10184 p->t38.their_parms.rate_management = AST_T38_RATE_MANAGEMENT_LOCAL_TCF; 10185 else if (!strcasecmp(s, "transferredTCF")) 10186 p->t38.their_parms.rate_management = AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF; 10187 found = TRUE; 10188 } else if ((sscanf(attrib, "t38faxudpec:%255s", s) == 1)) { 10189 ast_debug(3, "UDP EC: %s\n", s); 10190 if (!strcasecmp(s, "t38UDPRedundancy")) { 10191 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY); 10192 } else if (!strcasecmp(s, "t38UDPFEC")) { 10193 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC); 10194 } else { 10195 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 10196 } 10197 found = TRUE; 10198 } 10199 10200 return found; 10201 }
| static int process_sdp_a_sendonly | ( | const char * | a, | |
| int * | sendonly | |||
| ) | [static] |
Definition at line 9889 of file chan_sip.c.
Referenced by process_sdp().
09890 { 09891 int found = FALSE; 09892 09893 if (!strcasecmp(a, "sendonly")) { 09894 if (*sendonly == -1) 09895 *sendonly = 1; 09896 found = TRUE; 09897 } else if (!strcasecmp(a, "inactive")) { 09898 if (*sendonly == -1) 09899 *sendonly = 2; 09900 found = TRUE; 09901 } else if (!strcasecmp(a, "sendrecv")) { 09902 if (*sendonly == -1) 09903 *sendonly = 0; 09904 found = TRUE; 09905 } 09906 return found; 09907 }
| static int process_sdp_a_text | ( | const char * | a, | |
| struct sip_pvt * | p, | |||
| struct ast_rtp_codecs * | newtextrtp, | |||
| char * | red_fmtp, | |||
| int * | red_num_gen, | |||
| int * | red_data_pt, | |||
| int * | last_rtpmap_codec | |||
| ) | [static] |
Definition at line 10039 of file chan_sip.c.
References AST_RED_MAX_GENERATION, ast_rtp_codecs_payloads_set_rtpmap_type_rate(), ast_verbose, FALSE, sip_debug_test_pvt(), and TRUE.
Referenced by process_sdp().
10040 { 10041 int found = FALSE; 10042 unsigned int codec; 10043 char mimeSubtype[128]; 10044 unsigned int sample_rate; 10045 char *red_cp; 10046 int debug = sip_debug_test_pvt(p); 10047 10048 if (sscanf(a, "rtpmap: %30u %127[^/]/%30u", &codec, mimeSubtype, &sample_rate) == 3) { 10049 /* We have a rtpmap to handle */ 10050 if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 10051 if (!strncasecmp(mimeSubtype, "T140", 4)) { /* Text */ 10052 if (p->trtp) { 10053 /* ast_verbose("Adding t140 mimeSubtype to textrtp struct\n"); */ 10054 ast_rtp_codecs_payloads_set_rtpmap_type_rate(newtextrtp, NULL, codec, "text", mimeSubtype, 0, sample_rate); 10055 found = TRUE; 10056 } 10057 } else if (!strncasecmp(mimeSubtype, "RED", 3)) { /* Text with Redudancy */ 10058 if (p->trtp) { 10059 ast_rtp_codecs_payloads_set_rtpmap_type_rate(newtextrtp, NULL, codec, "text", mimeSubtype, 0, sample_rate); 10060 sprintf(red_fmtp, "fmtp:%u ", codec); 10061 if (debug) 10062 ast_verbose("RED submimetype has payload type: %u\n", codec); 10063 found = TRUE; 10064 } 10065 } 10066 } else { 10067 if (debug) 10068 ast_verbose("Discarded description format %s for ID %u\n", mimeSubtype, codec); 10069 } 10070 } else if (!strncmp(a, red_fmtp, strlen(red_fmtp))) { 10071 /* count numbers of generations in fmtp */ 10072 red_cp = &red_fmtp[strlen(red_fmtp)]; 10073 strncpy(red_fmtp, a, 100); 10074 10075 sscanf(red_cp, "%30u", (unsigned *)&red_data_pt[*red_num_gen]); 10076 red_cp = strtok(red_cp, "/"); 10077 while (red_cp && (*red_num_gen)++ < AST_RED_MAX_GENERATION) { 10078 sscanf(red_cp, "%30u", (unsigned *)&red_data_pt[*red_num_gen]); 10079 red_cp = strtok(NULL, "/"); 10080 } 10081 red_cp = red_fmtp; 10082 found = TRUE; 10083 } 10084 10085 return found; 10086 }
| static int process_sdp_a_video | ( | const char * | a, | |
| struct sip_pvt * | p, | |||
| struct ast_rtp_codecs * | newvideortp, | |||
| int * | last_rtpmap_codec | |||
| ) | [static] |
Definition at line 10005 of file chan_sip.c.
References ast_rtp_codecs_payloads_set_rtpmap_type_rate(), ast_rtp_codecs_payloads_unset(), ast_verbose, FALSE, sip_debug_test_pvt(), and TRUE.
Referenced by process_sdp().
10006 { 10007 int found = FALSE; 10008 unsigned int codec; 10009 char mimeSubtype[128]; 10010 unsigned int sample_rate; 10011 int debug = sip_debug_test_pvt(p); 10012 10013 if (sscanf(a, "rtpmap: %30u %127[^/]/%30u", &codec, mimeSubtype, &sample_rate) == 3) { 10014 /* We have a rtpmap to handle */ 10015 if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 10016 /* Note: should really look at the '#chans' params too */ 10017 if (!strncasecmp(mimeSubtype, "H26", 3) || !strncasecmp(mimeSubtype, "MP4", 3)) { 10018 if (!(ast_rtp_codecs_payloads_set_rtpmap_type_rate(newvideortp, NULL, codec, "video", mimeSubtype, 0, sample_rate))) { 10019 if (debug) 10020 ast_verbose("Found video description format %s for ID %u\n", mimeSubtype, codec); 10021 //found_rtpmap_codecs[last_rtpmap_codec] = codec; 10022 (*last_rtpmap_codec)++; 10023 found = TRUE; 10024 } else { 10025 ast_rtp_codecs_payloads_unset(newvideortp, NULL, codec); 10026 if (debug) 10027 ast_verbose("Found unknown media description format %s for ID %u\n", mimeSubtype, codec); 10028 } 10029 } 10030 } else { 10031 if (debug) 10032 ast_verbose("Discarded description format %s for ID %u\n", mimeSubtype, codec); 10033 } 10034 } 10035 10036 return found; 10037 }
| static int process_sdp_c | ( | const char * | c, | |
| struct ast_sockaddr * | addr | |||
| ) | [static] |
Definition at line 9862 of file chan_sip.c.
References ast_log(), ast_sockaddr_resolve_first_af(), FALSE, LOG_WARNING, and TRUE.
Referenced by process_sdp().
09863 { 09864 char proto[4], host[258]; 09865 int af; 09866 09867 /* Check for Media-description-level-address */ 09868 if (sscanf(c, "IN %3s %255s", proto, host) == 2) { 09869 if (!strcmp("IP4", proto)) { 09870 af = AF_INET; 09871 } else if (!strcmp("IP6", proto)) { 09872 af = AF_INET6; 09873 } else { 09874 ast_log(LOG_WARNING, "Unknown protocol '%s'.\n", proto); 09875 return FALSE; 09876 } 09877 if (ast_sockaddr_resolve_first_af(addr, host, 0, af)) { 09878 ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in c= line, '%s'\n", c); 09879 return FALSE; 09880 } 09881 return TRUE; 09882 } else { 09883 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 09884 return FALSE; 09885 } 09886 return FALSE; 09887 }
| static int process_sdp_o | ( | const char * | o, | |
| struct sip_pvt * | p | |||
| ) | [static] |
Definition at line 9783 of file chan_sip.c.
References ast_debug, ast_log(), ast_strdupa, ast_strlen_zero(), ast_test_flag, FALSE, LOG_WARNING, and TRUE.
Referenced by process_sdp().
09784 { 09785 char *o_copy; 09786 char *token; 09787 int64_t rua_version; 09788 09789 /* Store the SDP version number of remote UA. This will allow us to 09790 distinguish between session modifications and session refreshes. If 09791 the remote UA does not send an incremented SDP version number in a 09792 subsequent RE-INVITE then that means its not changing media session. 09793 The RE-INVITE may have been sent to update connected party, remote 09794 target or to refresh the session (Session-Timers). Asterisk must not 09795 change media session and increment its own version number in answer 09796 SDP in this case. */ 09797 09798 p->session_modify = TRUE; 09799 09800 if (ast_strlen_zero(o)) { 09801 ast_log(LOG_WARNING, "SDP syntax error. SDP without an o= line\n"); 09802 return FALSE; 09803 } 09804 09805 o_copy = ast_strdupa(o); 09806 token = strsep(&o_copy, " "); /* Skip username */ 09807 if (!o_copy) { 09808 ast_log(LOG_WARNING, "SDP syntax error in o= line username\n"); 09809 return FALSE; 09810 } 09811 token = strsep(&o_copy, " "); /* Skip session-id */ 09812 if (!o_copy) { 09813 ast_log(LOG_WARNING, "SDP syntax error in o= line session-id\n"); 09814 return FALSE; 09815 } 09816 token = strsep(&o_copy, " "); /* Version */ 09817 if (!o_copy) { 09818 ast_log(LOG_WARNING, "SDP syntax error in o= line\n"); 09819 return FALSE; 09820 } 09821 if (!sscanf(token, "%30" SCNd64, &rua_version)) { 09822 ast_log(LOG_WARNING, "SDP syntax error in o= line version\n"); 09823 return FALSE; 09824 } 09825 09826 /* we need to check the SDP version number the other end sent us; 09827 * our rules for deciding what to accept are a bit complex. 09828 * 09829 * 1) if 'ignoresdpversion' has been set for this dialog, then 09830 * we will just accept whatever they sent and assume it is 09831 * a modification of the session, even if it is not 09832 * 2) otherwise, if this is the first SDP we've seen from them 09833 * we accept it 09834 * 3) otherwise, if the new SDP version number is higher than the 09835 * old one, we accept it 09836 * 4) otherwise, if this SDP is in response to us requesting a switch 09837 * to T.38, we accept the SDP, but also generate a warning message 09838 * that this peer should have the 'ignoresdpversion' option set, 09839 * because it is not following the SDP offer/answer RFC; if we did 09840 * not request a switch to T.38, then we stop parsing the SDP, as it 09841 * has not changed from the previous version 09842 */ 09843 09844 if (ast_test_flag(&p->flags[1], SIP_PAGE2_IGNORESDPVERSION) || 09845 (p->sessionversion_remote < 0) || 09846 (p->sessionversion_remote < rua_version)) { 09847 p->sessionversion_remote = rua_version; 09848 } else { 09849 if (p->t38.state == T38_LOCAL_REINVITE) { 09850 p->sessionversion_remote = rua_version; 09851 ast_log(LOG_WARNING, "Call %s responded to our T.38 reinvite without changing SDP version; 'ignoresdpversion' should be set for this peer.\n", p->callid); 09852 } else { 09853 p->session_modify = FALSE; 09854 ast_debug(2, "Call %s responded to our reinvite without changing SDP version; ignoring SDP.\n", p->callid); 09855 return FALSE; 09856 } 09857 } 09858 09859 return TRUE; 09860 }
| static int process_via | ( | struct sip_pvt * | p, | |
| const struct sip_request * | req | |||
| ) | [static] |
Process the Via header according to RFC 3261 section 18.2.2.
| p | a sip_pvt structure that will be modified according to the received header | |
| req | a sip request with a Via header to process |
This function will update the destination of the response according to the Via header in the request and RFC 3261 section 18.2.2. We do not have a transport layer so we ignore certain values like the 'received' param (we set the destination address to the addres the request came from in the respprep() function).
| -1 | error | |
| 0 | success |
Definition at line 8128 of file chan_sip.c.
References addr_is_multicast(), ast_log(), ast_sockaddr_resolve_first_transport(), ast_sockaddr_set_port, free_via(), get_header(), LOG_ERROR, LOG_WARNING, PARSE_PORT_FORBID, and parse_via().
Referenced by respprep().
08129 { 08130 struct sip_via *via = parse_via(get_header(req, "Via")); 08131 08132 if (!via) { 08133 ast_log(LOG_ERROR, "error processing via header\n"); 08134 return -1; 08135 } 08136 08137 if (via->maddr) { 08138 if (ast_sockaddr_resolve_first_transport(&p->sa, via->maddr, PARSE_PORT_FORBID, p->socket.type)) { 08139 ast_log(LOG_WARNING, "Can't find address for maddr '%s'\n", via->maddr); 08140 ast_log(LOG_ERROR, "error processing via header\n"); 08141 free_via(via); 08142 return -1; 08143 } 08144 08145 if (addr_is_multicast(&p->sa)) { 08146 setsockopt(sipsock, IPPROTO_IP, IP_MULTICAST_TTL, &via->ttl, sizeof(via->ttl)); 08147 } 08148 } 08149 08150 ast_sockaddr_set_port(&p->sa, via->port ? via->port : STANDARD_SIP_PORT); 08151 08152 free_via(via); 08153 return 0; 08154 }
| static struct sip_proxy* proxy_from_config | ( | const char * | proxy, | |
| int | sipconf_lineno, | |||
| struct sip_proxy * | dest | |||
| ) | [static, read] |
Parse proxy string and return an ao2_alloc'd proxy. If dest is non-NULL, no allocation is performed and dest is used instead. On error NULL is returned.
Definition at line 3253 of file chan_sip.c.
References ao2_alloc, ao2_ref, ast_copy_string(), ast_log(), ast_skip_blanks(), ast_strdupa, ast_strlen_zero(), FALSE, LOG_WARNING, name, proxy_update(), and sip_parse_host().
Referenced by build_peer(), reload_config(), and sip_request_call().
03254 { 03255 char *mutable_proxy, *sep, *name; 03256 int allocated = 0; 03257 03258 if (!dest) { 03259 dest = ao2_alloc(sizeof(struct sip_proxy), NULL); 03260 if (!dest) { 03261 ast_log(LOG_WARNING, "Unable to allocate config storage for proxy\n"); 03262 return NULL; 03263 } 03264 allocated = 1; 03265 } 03266 03267 /* Format is: [transport://]name[:port][,force] */ 03268 mutable_proxy = ast_skip_blanks(ast_strdupa(proxy)); 03269 sep = strchr(mutable_proxy, ','); 03270 if (sep) { 03271 *sep++ = '\0'; 03272 dest->force = !strncasecmp(ast_skip_blanks(sep), "force", 5); 03273 } else { 03274 dest->force = FALSE; 03275 } 03276 03277 sip_parse_host(mutable_proxy, sipconf_lineno, &name, &dest->port, &dest->transport); 03278 03279 /* Check that there is a name at all */ 03280 if (ast_strlen_zero(name)) { 03281 if (allocated) { 03282 ao2_ref(dest, -1); 03283 } else { 03284 dest->name[0] = '\0'; 03285 } 03286 return NULL; 03287 } 03288 ast_copy_string(dest->name, name, sizeof(dest->name)); 03289 03290 /* Resolve host immediately */ 03291 proxy_update(dest); 03292 03293 return dest; 03294 }
| static int proxy_update | ( | struct sip_proxy * | proxy | ) | [static] |
Resolve DNS srv name or host name in a sip_proxy structure
Definition at line 3229 of file chan_sip.c.
References ast_get_ip_or_srv(), ast_log(), ast_sockaddr_parse(), ast_sockaddr_set_port, FALSE, get_address_family_filter(), LOG_WARNING, sip_cfg, and TRUE.
Referenced by proxy_from_config().
03230 { 03231 /* if it's actually an IP address and not a name, 03232 there's no need for a managed lookup */ 03233 if (!ast_sockaddr_parse(&proxy->ip, proxy->name, 0)) { 03234 /* Ok, not an IP address, then let's check if it's a domain or host */ 03235 /* XXX Todo - if we have proxy port, don't do SRV */ 03236 proxy->ip.ss.ss_family = get_address_family_filter(SIP_TRANSPORT_UDP); /* Filter address family */ 03237 if (ast_get_ip_or_srv(&proxy->ip, proxy->name, sip_cfg.srvlookup ? "_sip._udp" : NULL) < 0) { 03238 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", proxy->name); 03239 return FALSE; 03240 } 03241 03242 } 03243 03244 ast_sockaddr_set_port(&proxy->ip, proxy->port); 03245 03246 proxy->last_dnsupdate = time(NULL); 03247 return TRUE; 03248 }
| static int publish_expire | ( | const void * | data | ) | [static] |
Definition at line 1009 of file chan_sip.c.
References ao2_ref, ao2_unlink, ast_assert, event_state_compositor::compositor, and get_esc().
Referenced by create_esc_entry(), handle_sip_publish_modify(), and handle_sip_publish_refresh().
01010 { 01011 struct sip_esc_entry *esc_entry = (struct sip_esc_entry *) data; 01012 struct event_state_compositor *esc = get_esc(esc_entry->event); 01013 01014 ast_assert(esc != NULL); 01015 01016 ao2_unlink(esc->compositor, esc_entry); 01017 ao2_ref(esc_entry, -1); 01018 return 0; 01019 }
| static void pvt_set_needdestroy | ( | struct sip_pvt * | pvt, | |
| const char * | reason | |||
| ) | [inline, static] |
Definition at line 3194 of file chan_sip.c.
References append_history.
Referenced by __sip_autodestruct(), handle_incoming(), handle_request_publish(), handle_request_refer(), handle_request_subscribe(), handle_response(), handle_response_invite(), handle_response_notify(), handle_response_peerpoke(), handle_response_publish(), handle_response_refer(), handle_response_register(), handle_response_subscribe(), retrans_pkt(), sip_hangup(), and sip_reg_timeout().
03195 { 03196 if (pvt->final_destruction_scheduled) { 03197 return; /* This is already scheduled for final destruction, let the scheduler take care of it. */ 03198 } 03199 append_history(pvt, "NeedDestroy", "Setting needdestroy because %s", reason); 03200 pvt->needdestroy = 1; 03201 }
| static int read_raw_content_length | ( | const char * | message | ) | [static] |
Get the content length from an unparsed SIP message.
Definition at line 2532 of file chan_sip.c.
References ast_free, ast_str_buffer(), ast_str_create(), ast_str_set(), lws2sws(), and sip_cfg.
Referenced by check_message_integrity().
02533 { 02534 char *content_length_str; 02535 int content_length = -1; 02536 02537 struct ast_str *msg_copy; 02538 char *msg; 02539 02540 /* Using a ast_str because lws2sws takes one of those */ 02541 if (!(msg_copy = ast_str_create(strlen(message) + 1))) { 02542 return -1; 02543 } 02544 ast_str_set(&msg_copy, 0, "%s", message); 02545 02546 if (sip_cfg.pedanticsipchecking) { 02547 lws2sws(msg_copy); 02548 } 02549 02550 msg = ast_str_buffer(msg_copy); 02551 02552 /* Let's find a Content-Length header */ 02553 if ((content_length_str = strcasestr(msg, "\nContent-Length:"))) { 02554 content_length_str += sizeof("\nContent-Length:") - 1; 02555 } else if ((content_length_str = strcasestr(msg, "\nl:"))) { 02556 content_length_str += sizeof("\nl:") - 1; 02557 } else { 02558 /* RFC 3261 18.3 02559 * "In the case of stream-oriented transports such as TCP, the Content- 02560 * Length header field indicates the size of the body. The Content- 02561 * Length header field MUST be used with stream oriented transports." 02562 */ 02563 goto done; 02564 } 02565 02566 /* Double-check that this is a complete header */ 02567 if (!strchr(content_length_str, '\n')) { 02568 goto done; 02569 } 02570 02571 if (sscanf(content_length_str, "%30d", &content_length) != 1) { 02572 content_length = -1; 02573 } 02574 02575 done: 02576 ast_free(msg_copy); 02577 return content_length; 02578 }
| static struct sip_peer * realtime_peer | ( | const char * | newpeername, | |
| struct ast_sockaddr * | addr, | |||
| int | devstate_only, | |||
| int | which_objects | |||
| ) | [static, read] |
realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf Checks the "sipregs" realtime family from extconfig.conf if it's configured. This returns a pointer to a peer and because we use build_peer, we can rest assured that the refcount is bumped.
Definition at line 5149 of file chan_sip.c.
References ao2_t_link, ast_check_realtime(), ast_copy_flags, ast_copy_string(), ast_debug, AST_SCHED_REPLACE_UNREF, ast_sockaddr_isnull(), ast_sockaddr_stringify_addr(), ast_test_flag, ast_variables_destroy(), build_peer(), cleanup(), expire_register(), ipaddr, ast_variable::name, ast_variable::next, realtime_peer_by_addr(), realtime_peer_by_name(), ref_peer(), sip_cfg, TRUE, unref_peer(), ast_variable::value, and var.
Referenced by find_peer().
05150 { 05151 struct sip_peer *peer = NULL; 05152 struct ast_variable *var = NULL; 05153 struct ast_variable *varregs = NULL; 05154 char ipaddr[INET6_ADDRSTRLEN]; 05155 int realtimeregs = ast_check_realtime("sipregs"); 05156 05157 if (addr) { 05158 ast_copy_string(ipaddr, ast_sockaddr_stringify_addr(addr), sizeof(ipaddr)); 05159 } else { 05160 ipaddr[0] = '\0'; 05161 } 05162 05163 if (newpeername && realtime_peer_by_name(&newpeername, addr, ipaddr, &var, realtimeregs ? &varregs : NULL)) { 05164 ; 05165 } else if (addr && realtime_peer_by_addr(&newpeername, addr, ipaddr, &var, realtimeregs ? &varregs : NULL)) { 05166 ; 05167 } else { 05168 return NULL; 05169 } 05170 05171 /* If we're looking for users, don't return peers (although this check 05172 * should probably be done in realtime_peer_by_* instead...) */ 05173 if (which_objects == FINDUSERS) { 05174 struct ast_variable *tmp; 05175 for (tmp = var; tmp; tmp = tmp->next) { 05176 if (!strcasecmp(tmp->name, "type") && (!strcasecmp(tmp->value, "peer"))) { 05177 goto cleanup; 05178 } 05179 } 05180 } 05181 05182 /* Peer found in realtime, now build it in memory */ 05183 peer = build_peer(newpeername, var, varregs, TRUE, devstate_only); 05184 if (!peer) { 05185 goto cleanup; 05186 } 05187 05188 /* Previous versions of Asterisk did not require the type field to be 05189 * set for real time peers. This statement preserves that behavior. */ 05190 if (peer->type == 0) { 05191 if (which_objects == FINDUSERS) { 05192 peer->type = SIP_TYPE_USER; 05193 } else if (which_objects == FINDPEERS) { 05194 peer->type = SIP_TYPE_PEER; 05195 } else { 05196 peer->type = SIP_TYPE_PEER | SIP_TYPE_USER; 05197 } 05198 } 05199 05200 ast_debug(3, "-REALTIME- loading peer from database to memory. Name: %s. Peer objects: %d\n", peer->name, rpeerobjs); 05201 05202 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && !devstate_only) { 05203 /* Cache peer */ 05204 ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS); 05205 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 05206 AST_SCHED_REPLACE_UNREF(peer->expire, sched, sip_cfg.rtautoclear * 1000, expire_register, peer, 05207 unref_peer(_data, "remove registration ref"), 05208 unref_peer(peer, "remove registration ref"), 05209 ref_peer(peer, "add registration ref")); 05210 } 05211 ao2_t_link(peers, peer, "link peer into peers table"); 05212 if (!ast_sockaddr_isnull(&peer->addr)) { 05213 ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table"); 05214 } 05215 } 05216 peer->is_realtime = 1; 05217 05218 cleanup: 05219 ast_variables_destroy(var); 05220 ast_variables_destroy(varregs); 05221 return peer; 05222 }
| static int realtime_peer_by_addr | ( | const char ** | name, | |
| struct ast_sockaddr * | addr, | |||
| const char * | ipaddr, | |||
| struct ast_variable ** | var, | |||
| struct ast_variable ** | varregs | |||
| ) | [static] |
Definition at line 5080 of file chan_sip.c.
References ast_copy_string(), ast_load_realtime(), ast_log(), ast_sockaddr_stringify_port(), ast_variables_destroy(), get_insecure_variable_from_sippeers(), get_insecure_variable_from_sipregs(), get_name_from_variable(), LOG_WARNING, realtime_peer_get_sippeer_helper(), and SENTINEL.
Referenced by realtime_peer().
05081 { 05082 char portstring[6]; /* up to 5 digits plus null terminator */ 05083 ast_copy_string(portstring, ast_sockaddr_stringify_port(addr), sizeof(portstring)); 05084 05085 /* We're not finding this peer by this name anymore. Reset it. */ 05086 *name = NULL; 05087 05088 /* First check for fixed IP hosts */ 05089 if ((*var = ast_load_realtime("sippeers", "host", ipaddr, "port", portstring, SENTINEL))) { 05090 ; 05091 /* Check for registered hosts (in sipregs) */ 05092 } else if (varregs && (*varregs = ast_load_realtime("sipregs", "ipaddr", ipaddr, "port", portstring, SENTINEL)) && 05093 (*var = realtime_peer_get_sippeer_helper(name, varregs))) { 05094 ; 05095 /* Check for registered hosts (in sippeers) */ 05096 } else if (!varregs && (*var = ast_load_realtime("sippeers", "ipaddr", ipaddr, "port", portstring, SENTINEL))) { 05097 ; 05098 /* We couldn't match on ipaddress and port, so we need to check if port is insecure */ 05099 } else if ((*var = get_insecure_variable_from_sippeers("host", ipaddr))) { 05100 ; 05101 /* Same as above, but try the IP address field (in sipregs) 05102 * Observe that it fetches the name/var at the same time, without the 05103 * realtime_peer_get_sippeer_helper. Also note that it is quite inefficient. 05104 * Avoid sipregs if possible. */ 05105 } else if (varregs && (*varregs = get_insecure_variable_from_sipregs("ipaddr", ipaddr, var))) { 05106 ; 05107 /* Same as above, but try the IP address field (in sippeers) */ 05108 } else if (!varregs && (*var = get_insecure_variable_from_sippeers("ipaddr", ipaddr))) { 05109 ; 05110 } 05111 05112 /* Nothing found? */ 05113 if (!*var) { 05114 return 0; 05115 } 05116 05117 /* Check peer name. It must not be empty. There may exist a 05118 * different match that does have a name, but it's too late for 05119 * that now. */ 05120 if (!*name && !(*name = get_name_from_variable(*var))) { 05121 ast_log(LOG_WARNING, "Found peer for IP %s but it has no name\n", ipaddr); 05122 ast_variables_destroy(*var); 05123 *var = NULL; 05124 if (varregs && *varregs) { 05125 ast_variables_destroy(*varregs); 05126 *varregs = NULL; 05127 } 05128 return 0; 05129 } 05130 05131 /* Make sure varregs is populated if var is. The inverse, 05132 * ensuring that var is set when varregs is, is taken 05133 * care of by realtime_peer_get_sippeer_helper(). */ 05134 if (varregs && !*varregs) { 05135 *varregs = ast_load_realtime("sipregs", "name", *name, SENTINEL); 05136 } 05137 return 1; 05138 }
| static int realtime_peer_by_name | ( | const char *const * | name, | |
| struct ast_sockaddr * | addr, | |||
| const char * | ipaddr, | |||
| struct ast_variable ** | var, | |||
| struct ast_variable ** | varregs | |||
| ) | [static] |
Definition at line 5008 of file chan_sip.c.
References ast_free, ast_load_realtime(), ast_sockaddr_cmp(), ast_sockaddr_resolve(), ast_variables_destroy(), get_address_family_filter(), ast_variable::name, ast_variable::next, PARSE_PORT_FORBID, SENTINEL, and ast_variable::value.
Referenced by realtime_peer().
05009 { 05010 /* Peer by name and host=dynamic */ 05011 if ((*var = ast_load_realtime("sippeers", "name", *name, "host", "dynamic", SENTINEL))) { 05012 ; 05013 /* Peer by name and host=IP */ 05014 } else if (addr && !(*var = ast_load_realtime("sippeers", "name", *name, "host", ipaddr, SENTINEL))) { 05015 ; 05016 /* Peer by name and host=HOSTNAME */ 05017 } else if ((*var = ast_load_realtime("sippeers", "name", *name, SENTINEL))) { 05018 /*!\note 05019 * If this one loaded something, then we need to ensure that the host 05020 * field matched. The only reason why we can't have this as a criteria 05021 * is because we only have the IP address and the host field might be 05022 * set as a name (and the reverse PTR might not match). 05023 */ 05024 if (addr) { 05025 struct ast_variable *tmp; 05026 for (tmp = *var; tmp; tmp = tmp->next) { 05027 if (!strcasecmp(tmp->name, "host")) { 05028 struct ast_sockaddr *addrs = NULL; 05029 05030 if (ast_sockaddr_resolve(&addrs, 05031 tmp->value, 05032 PARSE_PORT_FORBID, 05033 get_address_family_filter(SIP_TRANSPORT_UDP)) <= 0 || 05034 ast_sockaddr_cmp(&addrs[0], addr)) { 05035 /* No match */ 05036 ast_variables_destroy(*var); 05037 *var = NULL; 05038 } 05039 ast_free(addrs); 05040 break; 05041 } 05042 } 05043 } 05044 } 05045 05046 /* Did we find anything? */ 05047 if (*var) { 05048 if (varregs) { 05049 *varregs = ast_load_realtime("sipregs", "name", *name, SENTINEL); 05050 } 05051 return 1; 05052 } 05053 return 0; 05054 }
| static struct ast_variable* realtime_peer_get_sippeer_helper | ( | const char ** | name, | |
| struct ast_variable ** | varregs | |||
| ) | [static, read] |
Definition at line 5062 of file chan_sip.c.
References ast_load_realtime(), ast_log(), ast_variables_destroy(), get_name_from_variable(), LOG_WARNING, SENTINEL, and var.
Referenced by realtime_peer_by_addr().
05062 { 05063 struct ast_variable *var = NULL; 05064 const char *old_name = *name; 05065 *name = get_name_from_variable(*varregs); 05066 if (!*name || !(var = ast_load_realtime("sippeers", "name", *name, SENTINEL))) { 05067 if (!*name) { 05068 ast_log(LOG_WARNING, "Found sipreg but it has no name\n"); 05069 } 05070 ast_variables_destroy(*varregs); 05071 *varregs = NULL; 05072 *name = old_name; 05073 } 05074 return var; 05075 }
| static void realtime_update_peer | ( | const char * | peername, | |
| struct ast_sockaddr * | addr, | |||
| const char * | username, | |||
| const char * | fullcontact, | |||
| const char * | useragent, | |||
| int | expirey, | |||
| unsigned short | deprecated_username, | |||
| int | lastms | |||
| ) | [static] |
Update peer object in realtime storage If the Asterisk system name is set in asterisk.conf, we will use that name and store that in the "regserver" field in the sippeers table to facilitate multi-server setups.
Definition at line 4718 of file chan_sip.c.
References ast_check_realtime(), ast_config_AST_SYSTEM_NAME, ast_copy_string(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_sockaddr_stringify_port(), ast_strlen_zero(), ast_update_realtime(), ipaddr, SENTINEL, and sip_cfg.
Referenced by update_peer().
04719 { 04720 char port[10]; 04721 char ipaddr[INET6_ADDRSTRLEN]; 04722 char regseconds[20]; 04723 char *tablename = NULL; 04724 char str_lastms[20]; 04725 04726 const char *sysname = ast_config_AST_SYSTEM_NAME; 04727 char *syslabel = NULL; 04728 04729 time_t nowtime = time(NULL) + expirey; 04730 const char *fc = fullcontact ? "fullcontact" : NULL; 04731 04732 int realtimeregs = ast_check_realtime("sipregs"); 04733 04734 tablename = realtimeregs ? "sipregs" : "sippeers"; 04735 04736 04737 snprintf(str_lastms, sizeof(str_lastms), "%d", lastms); 04738 snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); /* Expiration time */ 04739 ast_copy_string(ipaddr, ast_sockaddr_isnull(addr) ? "" : ast_sockaddr_stringify_addr(addr), sizeof(ipaddr)); 04740 ast_copy_string(port, ast_sockaddr_port(addr) ? ast_sockaddr_stringify_port(addr) : "", sizeof(port)); 04741 04742 if (ast_strlen_zero(sysname)) /* No system name, disable this */ 04743 sysname = NULL; 04744 else if (sip_cfg.rtsave_sysname) 04745 syslabel = "regserver"; 04746 04747 /* XXX IMPORTANT: Anytime you add a new parameter to be updated, you 04748 * must also add it to contrib/scripts/asterisk.ldap-schema, 04749 * contrib/scripts/asterisk.ldif, 04750 * and to configs/res_ldap.conf.sample as described in 04751 * bugs 15156 and 15895 04752 */ 04753 if (fc) { 04754 ast_update_realtime(tablename, "name", peername, "ipaddr", ipaddr, 04755 "port", port, "regseconds", regseconds, 04756 deprecated_username ? "username" : "defaultuser", defaultuser, 04757 "useragent", useragent, "lastms", str_lastms, 04758 fc, fullcontact, syslabel, sysname, SENTINEL); /* note fc and syslabel _can_ be NULL */ 04759 } else { 04760 ast_update_realtime(tablename, "name", peername, "ipaddr", ipaddr, 04761 "port", port, "regseconds", regseconds, 04762 "useragent", useragent, "lastms", str_lastms, 04763 deprecated_username ? "username" : "defaultuser", defaultuser, 04764 syslabel, sysname, SENTINEL); /* note syslabel _can_ be NULL */ 04765 } 04766 }
| static void receive_message | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Receive SIP MESSAGE method messages.
Definition at line 16885 of file chan_sip.c.
References AST_FRAME_TEXT, ast_log(), ast_queue_frame(), ast_verbose, ast_frame::data, ast_frame::datalen, f, ast_frame::frametype, get_header(), get_msg_text(), ast_frame_subclass::integer, LOG_WARNING, ast_frame::offset, ast_frame::ptr, sip_debug_test_pvt(), sip_scheddestroy(), ast_frame::subclass, and transmit_response().
Referenced by handle_request_message().
16886 { 16887 char buf[1400]; 16888 char *bufp; 16889 struct ast_frame f; 16890 const char *content_type = get_header(req, "Content-Type"); 16891 16892 if (strncmp(content_type, "text/plain", strlen("text/plain"))) { /* No text/plain attachment */ 16893 transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */ 16894 if (!p->owner) 16895 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16896 return; 16897 } 16898 16899 if (get_msg_text(buf, sizeof(buf), req)) { 16900 ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); 16901 transmit_response(p, "500 Internal Server Error", req); 16902 if (!p->owner) { 16903 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16904 } 16905 return; 16906 } 16907 16908 /* Strip trailing line feeds from message body. (get_msg_text may add 16909 * a trailing linefeed and we don't need any at the end) */ 16910 bufp = buf + strlen(buf); 16911 while (--bufp >= buf && *bufp == '\n') { 16912 *bufp = '\0'; 16913 } 16914 16915 if (p->owner) { 16916 if (sip_debug_test_pvt(p)) 16917 ast_verbose("SIP Text message received: '%s'\n", buf); 16918 memset(&f, 0, sizeof(f)); 16919 f.frametype = AST_FRAME_TEXT; 16920 f.subclass.integer = 0; 16921 f.offset = 0; 16922 f.data.ptr = buf; 16923 f.datalen = strlen(buf) + 1; 16924 ast_queue_frame(p->owner, &f); 16925 transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */ 16926 return; 16927 } 16928 16929 /* Message outside of a call, we do not support that */ 16930 ast_log(LOG_WARNING, "Received message to %s from %s, dropped it...\n Content-Type:%s\n Message: %s\n", get_header(req, "To"), get_header(req, "From"), content_type, buf); 16931 transmit_response(p, "405 Method Not Allowed", req); 16932 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16933 return; 16934 }
| static struct sip_peer* ref_peer | ( | struct sip_peer * | peer, | |
| char * | tag | |||
| ) | [static, read] |
Definition at line 2985 of file chan_sip.c.
References ao2_t_ref.
Referenced by build_peer(), check_peer_ok(), create_addr(), handle_request_invite(), handle_request_subscribe(), handle_response_peerpoke(), parse_register_contact(), realtime_peer(), reg_source_db(), register_verify(), sip_poke_all_peers(), sip_poke_noanswer(), sip_poke_peer(), sip_unregister(), and update_call_counter().
02986 { 02987 ao2_t_ref(peer, 1, tag); 02988 return peer; 02989 }
| static void ref_proxy | ( | struct sip_pvt * | pvt, | |
| struct sip_proxy * | proxy | |||
| ) | [static] |
maintain proper refcounts for a sip_pvt's outboundproxy
This function sets pvt's outboundproxy pointer to the one referenced by the proxy parameter. Because proxy may be a refcounted object, and because pvt's old outboundproxy may also be a refcounted object, we need to maintain the proper refcounts.
| pvt | The sip_pvt for which we wish to set the outboundproxy | |
| proxy | The sip_proxy which we will point pvt towards. |
Definition at line 3067 of file chan_sip.c.
References ao2_ref, and sip_cfg.
Referenced by __sip_ack(), __sip_subscribe_mwi_do(), create_addr(), and create_addr_from_peer().
03068 { 03069 struct sip_proxy *old_obproxy = pvt->outboundproxy; 03070 /* The sip_cfg.outboundproxy is statically allocated, and so 03071 * we don't ever need to adjust refcounts for it 03072 */ 03073 if (proxy && proxy != &sip_cfg.outboundproxy) { 03074 ao2_ref(proxy, +1); 03075 } 03076 pvt->outboundproxy = proxy; 03077 if (old_obproxy && old_obproxy != &sip_cfg.outboundproxy) { 03078 ao2_ref(old_obproxy, -1); 03079 } 03080 }
| static const char * referstatus2str | ( | enum referstatus | rstatus | ) | [static] |
Convert transfer status to string.
Definition at line 3189 of file chan_sip.c.
References map_x_s().
Referenced by show_channels_cb().
03190 { 03191 return map_x_s(referstatusstrings, rstatus, ""); 03192 }
| static void reg_source_db | ( | struct sip_peer * | peer | ) | [static] |
Get registration details from Asterisk DB.
Definition at line 14291 of file chan_sip.c.
References args, AST_APP_ARG, ast_db_get(), ast_debug, AST_DECLARE_APP_ARGS, AST_NONSTANDARD_RAW_ARGS, ast_random(), AST_SCHED_REPLACE_UNREF, ast_sockaddr_copy(), ast_sockaddr_parse(), ast_sockaddr_stringify_host(), ast_string_field_set, expire_register(), ref_peer(), register_peer_exten(), sip_cfg, sip_poke_peer_s(), TRUE, and unref_peer().
Referenced by build_peer(), and temp_peer().
14292 { 14293 char data[256]; 14294 struct ast_sockaddr sa; 14295 int expire; 14296 char full_addr[128]; 14297 AST_DECLARE_APP_ARGS(args, 14298 AST_APP_ARG(addr); 14299 AST_APP_ARG(port); 14300 AST_APP_ARG(expiry_str); 14301 AST_APP_ARG(username); 14302 AST_APP_ARG(contact); 14303 ); 14304 14305 /* If read-only RT backend, then refresh from local DB cache */ 14306 if (peer->rt_fromcontact && sip_cfg.peer_rtupdate) { 14307 return; 14308 } 14309 if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) { 14310 return; 14311 } 14312 14313 AST_NONSTANDARD_RAW_ARGS(args, data, ':'); 14314 14315 snprintf(full_addr, sizeof(full_addr), "%s:%s", args.addr, args.port); 14316 14317 if (!ast_sockaddr_parse(&sa, full_addr, 0)) { 14318 return; 14319 } 14320 14321 if (args.expiry_str) { 14322 expire = atoi(args.expiry_str); 14323 } else { 14324 return; 14325 } 14326 14327 if (args.username) { 14328 ast_string_field_set(peer, username, args.username); 14329 } 14330 if (args.contact) { 14331 ast_string_field_set(peer, fullcontact, args.contact); 14332 } 14333 14334 ast_debug(2, "SIP Seeding peer from astdb: '%s' at %s@%s for %d\n", 14335 peer->name, peer->username, ast_sockaddr_stringify_host(&sa), expire); 14336 14337 ast_sockaddr_copy(&peer->addr, &sa); 14338 if (peer->maxms) { 14339 /* Don't poke peer immediately, just schedule it within qualifyfreq */ 14340 AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, 14341 ast_random() % ((peer->qualifyfreq) ? peer->qualifyfreq : global_qualifyfreq) + 1, 14342 sip_poke_peer_s, peer, 14343 unref_peer(_data, "removing poke peer ref"), 14344 unref_peer(peer, "removing poke peer ref"), 14345 ref_peer(peer, "adding poke peer ref")); 14346 } 14347 AST_SCHED_REPLACE_UNREF(peer->expire, sched, (expire + 10) * 1000, expire_register, peer, 14348 unref_peer(_data, "remove registration ref"), 14349 unref_peer(peer, "remove registration ref"), 14350 ref_peer(peer, "add registration ref")); 14351 register_peer_exten(peer, TRUE); 14352 }
| static void register_peer_exten | ( | struct sip_peer * | peer, | |
| int | onoff | |||
| ) | [static] |
Automatically add peer extension to dial plan.
Definition at line 4769 of file chan_sip.c.
References ast_add_extension(), ast_context_find(), ast_context_remove_extension(), ast_copy_string(), ast_exists_extension(), ast_free_ptr(), ast_log(), ast_strdup, ast_strlen_zero(), context, E_MATCH, ext, LOG_WARNING, pbx_find_extension(), S_OR, and sip_cfg.
Referenced by expire_register(), handle_response_peerpoke(), parse_register_contact(), reg_source_db(), sip_destroy_peer(), and sip_poke_noanswer().
04770 { 04771 char multi[256]; 04772 char *stringp, *ext, *context; 04773 struct pbx_find_info q = { .stacklen = 0 }; 04774 04775 /* XXX note that sip_cfg.regcontext is both a global 'enable' flag and 04776 * the name of the global regexten context, if not specified 04777 * individually. 04778 */ 04779 if (ast_strlen_zero(sip_cfg.regcontext)) 04780 return; 04781 04782 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 04783 stringp = multi; 04784 while ((ext = strsep(&stringp, "&"))) { 04785 if ((context = strchr(ext, '@'))) { 04786 *context++ = '\0'; /* split ext@context */ 04787 if (!ast_context_find(context)) { 04788 ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context); 04789 continue; 04790 } 04791 } else { 04792 context = sip_cfg.regcontext; 04793 } 04794 if (onoff) { 04795 if (!ast_exists_extension(NULL, context, ext, 1, NULL)) { 04796 ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop", 04797 ast_strdup(peer->name), ast_free_ptr, "SIP"); 04798 } 04799 } else if (pbx_find_extension(NULL, NULL, &q, context, ext, 1, NULL, "", E_MATCH)) { 04800 ast_context_remove_extension(context, ext, 1, NULL); 04801 } 04802 } 04803 }
| static enum check_auth_result register_verify | ( | struct sip_pvt * | p, | |
| struct ast_sockaddr * | addr, | |||
| struct sip_request * | req, | |||
| const char * | uri | |||
| ) | [static] |
Verify registration of user
Definition at line 15276 of file chan_sip.c.
References ao2_lock, ao2_t_link, ao2_unlock, ast_apply_ha(), ast_copy_flags, ast_copy_string(), AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), AST_LIST_EMPTY, ast_log(), ast_set_flag, ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_sockaddr_stringify_port(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), build_contact(), check_auth(), check_request_transport, check_sip_domain(), EVENT_FLAG_SYSTEM, exten, extract_host_from_hostport(), FALSE, find_peer(), get_header(), get_in_brackets(), LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event, name, parse_register_contact(), parse_uri_legacy_check(), ref_peer(), remove_uri_parameters(), sip_cancel_destroy(), sip_cfg, SIP_PEDANTIC_DECODE, sip_pvt_lock, sip_pvt_unlock, sip_send_mwi_to_peer(), temp_peer(), terminate_uri(), transmit_fake_auth_response(), transmit_response(), transmit_response_with_date(), TRUE, unref_peer(), update_peer(), and update_peer_lastmsgssent().
Referenced by handle_request_register().
15278 { 15279 enum check_auth_result res = AUTH_NOT_FOUND; 15280 struct sip_peer *peer; 15281 char tmp[256]; 15282 char *c, *name, *unused_password, *domain; 15283 char *uri2 = ast_strdupa(uri); 15284 int send_mwi = 0; 15285 15286 terminate_uri(uri2); 15287 15288 ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp)); 15289 15290 c = get_in_brackets(tmp); 15291 c = remove_uri_parameters(c); 15292 15293 if (parse_uri_legacy_check(c, "sip:,sips:", &name, &unused_password, &domain, NULL)) { 15294 ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_sockaddr_stringify_addr(addr)); 15295 return -1; 15296 } 15297 15298 SIP_PEDANTIC_DECODE(name); 15299 SIP_PEDANTIC_DECODE(domain); 15300 15301 extract_host_from_hostport(&domain); 15302 15303 if (ast_strlen_zero(domain)) { 15304 /* <sip:name@[EMPTY]>, never good */ 15305 transmit_response(p, "404 Not found", &p->initreq); 15306 return AUTH_UNKNOWN_DOMAIN; 15307 } 15308 15309 if (ast_strlen_zero(name)) { 15310 /* <sip:[EMPTY][@]hostport>, unsure whether valid for 15311 * registration. RFC 3261, 10.2 states: 15312 * "The To header field and the Request-URI field typically 15313 * differ, as the former contains a user name." 15314 * But, Asterisk has always treated the domain-only uri as a 15315 * username: we allow admins to create accounts described by 15316 * domain name. */ 15317 name = domain; 15318 } 15319 15320 /* This here differs from 1.4 and 1.6: the domain matching ACLs were 15321 * skipped if it was a domain-only URI (used as username). Here we treat 15322 * <sip:hostport> as <sip:host@hostport> and won't forget to test the 15323 * domain ACLs against host. */ 15324 if (!AST_LIST_EMPTY(&domain_list)) { 15325 if (!check_sip_domain(domain, NULL, 0)) { 15326 if (sip_cfg.alwaysauthreject) { 15327 transmit_fake_auth_response(p, &p->initreq, XMIT_UNRELIABLE); 15328 } else { 15329 transmit_response(p, "404 Not found (unknown domain)", &p->initreq); 15330 } 15331 return AUTH_UNKNOWN_DOMAIN; 15332 } 15333 } 15334 15335 ast_string_field_set(p, exten, name); 15336 build_contact(p); 15337 if (req->ignore) { 15338 /* Expires is a special case, where we only want to load the peer if this isn't a deregistration attempt */ 15339 const char *expires = get_header(req, "Expires"); 15340 int expire = atoi(expires); 15341 15342 if (ast_strlen_zero(expires)) { /* No expires header; look in Contact */ 15343 if ((expires = strcasestr(get_header(req, "Contact"), ";expires="))) { 15344 expire = atoi(expires + 9); 15345 } 15346 } 15347 if (!ast_strlen_zero(expires) && expire == 0) { 15348 transmit_response_with_date(p, "200 OK", req); 15349 return 0; 15350 } 15351 } 15352 peer = find_peer(name, NULL, TRUE, FINDPEERS, FALSE, 0); 15353 15354 /* If we don't want username disclosure, use the bogus_peer when a user 15355 * is not found. */ 15356 if (!peer && sip_cfg.alwaysauthreject && !sip_cfg.autocreatepeer) { 15357 peer = bogus_peer; 15358 ref_peer(peer, "register_verify: ref the bogus_peer"); 15359 } 15360 15361 if (!(peer && ast_apply_ha(peer->ha, addr))) { 15362 /* Peer fails ACL check */ 15363 if (peer) { 15364 unref_peer(peer, "register_verify: unref_peer: from find_peer operation"); 15365 peer = NULL; 15366 res = AUTH_ACL_FAILED; 15367 } else { 15368 res = AUTH_NOT_FOUND; 15369 } 15370 } 15371 15372 if (peer) { 15373 ao2_lock(peer); 15374 if (!peer->host_dynamic) { 15375 ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name); 15376 res = AUTH_PEER_NOT_DYNAMIC; 15377 } else { 15378 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT_FORCE_RPORT); 15379 if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri2, XMIT_UNRELIABLE, req->ignore))) { 15380 if (sip_cancel_destroy(p)) 15381 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 15382 15383 if (check_request_transport(peer, req)) { 15384 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 15385 transmit_response_with_date(p, "403 Forbidden", req); 15386 res = AUTH_BAD_TRANSPORT; 15387 } else { 15388 15389 /* We have a successful registration attempt with proper authentication, 15390 now, update the peer */ 15391 switch (parse_register_contact(p, peer, req)) { 15392 case PARSE_REGISTER_DENIED: 15393 ast_log(LOG_WARNING, "Registration denied because of contact ACL\n"); 15394 transmit_response_with_date(p, "603 Denied", req); 15395 res = 0; 15396 break; 15397 case PARSE_REGISTER_FAILED: 15398 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 15399 transmit_response_with_date(p, "400 Bad Request", req); 15400 res = 0; 15401 break; 15402 case PARSE_REGISTER_QUERY: 15403 ast_string_field_set(p, fullcontact, peer->fullcontact); 15404 transmit_response_with_date(p, "200 OK", req); 15405 res = 0; 15406 break; 15407 case PARSE_REGISTER_UPDATE: 15408 ast_string_field_set(p, fullcontact, peer->fullcontact); 15409 /* If expiry is 0, peer has been unregistered already */ 15410 if (p->expiry != 0) { 15411 update_peer(peer, p->expiry); 15412 } 15413 /* Say OK and ask subsystem to retransmit msg counter */ 15414 transmit_response_with_date(p, "200 OK", req); 15415 send_mwi = 1; 15416 res = 0; 15417 break; 15418 } 15419 } 15420 15421 } 15422 } 15423 ao2_unlock(peer); 15424 } 15425 if (!peer && sip_cfg.autocreatepeer) { 15426 /* Create peer if we have autocreate mode enabled */ 15427 peer = temp_peer(name); 15428 if (peer) { 15429 ao2_t_link(peers, peer, "link peer into peer table"); 15430 if (!ast_sockaddr_isnull(&peer->addr)) { 15431 ao2_t_link(peers_by_ip, peer, "link peer into peers-by-ip table"); 15432 } 15433 ao2_lock(peer); 15434 if (sip_cancel_destroy(p)) 15435 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 15436 switch (parse_register_contact(p, peer, req)) { 15437 case PARSE_REGISTER_DENIED: 15438 ast_log(LOG_WARNING, "Registration denied because of contact ACL\n"); 15439 transmit_response_with_date(p, "403 Forbidden", req); 15440 res = 0; 15441 break; 15442 case PARSE_REGISTER_FAILED: 15443 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 15444 transmit_response_with_date(p, "400 Bad Request", req); 15445 res = 0; 15446 break; 15447 case PARSE_REGISTER_QUERY: 15448 ast_string_field_set(p, fullcontact, peer->fullcontact); 15449 transmit_response_with_date(p, "200 OK", req); 15450 send_mwi = 1; 15451 res = 0; 15452 break; 15453 case PARSE_REGISTER_UPDATE: 15454 ast_string_field_set(p, fullcontact, peer->fullcontact); 15455 /* Say OK and ask subsystem to retransmit msg counter */ 15456 transmit_response_with_date(p, "200 OK", req); 15457 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Registered\r\nAddress: %s\r\n", peer->name, ast_sockaddr_stringify(addr)); 15458 send_mwi = 1; 15459 res = 0; 15460 break; 15461 } 15462 ao2_unlock(peer); 15463 } 15464 } 15465 if (!res) { 15466 if (send_mwi) { 15467 sip_pvt_unlock(p); 15468 sip_send_mwi_to_peer(peer, 0); 15469 sip_pvt_lock(p); 15470 } else { 15471 update_peer_lastmsgssent(peer, -1, 0); 15472 } 15473 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", peer->name); 15474 } 15475 if (res < 0) { 15476 switch (res) { 15477 case AUTH_SECRET_FAILED: 15478 /* Wrong password in authentication. Go away, don't try again until you fixed it */ 15479 transmit_response(p, "403 Forbidden", &p->initreq); 15480 if (global_authfailureevents) { 15481 const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr)); 15482 const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr)); 15483 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 15484 "ChannelType: SIP\r\n" 15485 "Peer: SIP/%s\r\n" 15486 "PeerStatus: Rejected\r\n" 15487 "Cause: AUTH_SECRET_FAILED\r\n" 15488 "Address: %s\r\n" 15489 "Port: %s\r\n", 15490 name, peer_addr, peer_port); 15491 } 15492 break; 15493 case AUTH_USERNAME_MISMATCH: 15494 /* Username and digest username does not match. 15495 Asterisk uses the From: username for authentication. We need the 15496 devices to use the same authentication user name until we support 15497 proper authentication by digest auth name */ 15498 case AUTH_NOT_FOUND: 15499 case AUTH_PEER_NOT_DYNAMIC: 15500 case AUTH_ACL_FAILED: 15501 if (sip_cfg.alwaysauthreject) { 15502 transmit_fake_auth_response(p, &p->initreq, XMIT_UNRELIABLE); 15503 if (global_authfailureevents) { 15504 const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr)); 15505 const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr)); 15506 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 15507 "ChannelType: SIP\r\n" 15508 "Peer: SIP/%s\r\n" 15509 "PeerStatus: Rejected\r\n" 15510 "Cause: %s\r\n" 15511 "Address: %s\r\n" 15512 "Port: %s\r\n", 15513 name, 15514 res == AUTH_PEER_NOT_DYNAMIC ? "AUTH_PEER_NOT_DYNAMIC" : "URI_NOT_FOUND", 15515 peer_addr, peer_port); 15516 } 15517 } else { 15518 /* URI not found */ 15519 if (res == AUTH_PEER_NOT_DYNAMIC) { 15520 transmit_response(p, "403 Forbidden", &p->initreq); 15521 if (global_authfailureevents) { 15522 const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr)); 15523 const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr)); 15524 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 15525 "ChannelType: SIP\r\n" 15526 "Peer: SIP/%s\r\n" 15527 "PeerStatus: Rejected\r\n" 15528 "Cause: AUTH_PEER_NOT_DYNAMIC\r\n" 15529 "Address: %s\r\n" 15530 "Port: %s\r\n", 15531 name, peer_addr, peer_port); 15532 } 15533 } else { 15534 transmit_response(p, "404 Not found", &p->initreq); 15535 if (global_authfailureevents) { 15536 const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr)); 15537 const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr)); 15538 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 15539 "ChannelType: SIP\r\n" 15540 "Peer: SIP/%s\r\n" 15541 "PeerStatus: Rejected\r\n" 15542 "Cause: %s\r\n" 15543 "Address: %s\r\n" 15544 "Port: %s\r\n", 15545 name, 15546 (res == AUTH_USERNAME_MISMATCH) ? "AUTH_USERNAME_MISMATCH" : "URI_NOT_FOUND", 15547 peer_addr, peer_port); 15548 } 15549 } 15550 } 15551 break; 15552 case AUTH_BAD_TRANSPORT: 15553 default: 15554 break; 15555 } 15556 } 15557 if (peer) { 15558 unref_peer(peer, "register_verify: unref_peer: tossing stack peer pointer at end of func"); 15559 } 15560 15561 return res; 15562 }
| static struct sip_registry* registry_addref | ( | struct sip_registry * | reg, | |
| char * | tag | |||
| ) | [static, read] |
Add object reference to SIP registry.
Definition at line 3171 of file chan_sip.c.
References ast_debug, and ASTOBJ_REF.
Referenced by handle_response_register(), sip_send_all_registers(), and transmit_register().
03172 { 03173 ast_debug(3, "SIP Registry %s: refcount now %u\n", reg->hostname, reg->refcount + 1); 03174 return ASTOBJ_REF(reg); /* Add pointer to registry in packet */ 03175 }
| void * registry_unref | ( | struct sip_registry * | reg, | |
| char * | tag | |||
| ) | [static] |
Definition at line 3163 of file chan_sip.c.
References ast_debug, ASTOBJ_UNREF, and sip_registry_destroy().
Referenced by __sip_destroy(), cleanup_all_regs(), dialog_unlink_all(), handle_response_register(), sip_reg_timeout(), sip_register(), sip_registry_destroy(), sip_reregister(), sip_send_all_registers(), and transmit_register().
03164 { 03165 ast_debug(3, "SIP Registry %s: refcount now %u\n", reg->hostname, reg->refcount - 1); 03166 ASTOBJ_UNREF(reg, sip_registry_destroy); 03167 return NULL; 03168 }
| static const char * regstate2str | ( | enum sipregistrystate | regstate | ) | [static] |
Convert registration state status to string.
Definition at line 13558 of file chan_sip.c.
References map_x_s().
Referenced by handle_response_register(), manager_show_registry(), sip_reg_timeout(), and sip_show_registry().
13559 { 13560 return map_x_s(regstatestrings, regstate, "Unknown"); 13561 }
| static int reinvite_timeout | ( | const void * | data | ) | [static] |
Definition at line 6473 of file chan_sip.c.
References ao2_unlock, ast_channel_unlock, ast_channel_unref, check_pendings(), and sip_pvt_lock_full().
Referenced by sip_hangup().
06474 { 06475 struct sip_pvt *dialog = (struct sip_pvt *) data; 06476 struct ast_channel *owner = sip_pvt_lock_full(dialog); 06477 dialog->reinviteid = -1; 06478 check_pendings(dialog); 06479 if (owner) { 06480 ast_channel_unlock(owner); 06481 ast_channel_unref(owner); 06482 } 06483 ao2_unlock(dialog); 06484 dialog_unref(dialog, "unref for reinvite timeout"); 06485 return 0; 06486 }
| static int reload | ( | void | ) | [static] |
Part of Asterisk module interface.
Definition at line 30645 of file chan_sip.c.
References sip_reload().
30646 { 30647 if (sip_reload(0, 0, NULL)) 30648 return 0; 30649 return 1; 30650 }
| static int reload_config | ( | enum channelreloadreason | reason | ) | [static] |
Re-read SIP.conf config file.
< Don't force proxy usage, use route: headers
< Keep track of hold status for a peer
< Match auth username if available instead of From: Default off.
< Default DTMF setting: RFC2833
< Allow re-invites
< Default to nat=force_rport
Definition at line 28774 of file chan_sip.c.
References ast_tcptls_session_args::accept_fd, add_realm_authentication(), add_sip_domain(), ao2_t_callback, ao2_t_link, ao2_t_ref, ast_append_ha(), ast_bind(), ast_category_browse(), AST_CERTFILE, ast_clear_flag, ast_config_AST_SYSTEM_NAME, ast_config_destroy(), ast_config_load, ast_context_find_or_create(), ast_copy_flags, ast_copy_string(), ast_debug, ast_enable_packet_fragmentation(), ast_false(), ast_find_ourip(), AST_FLAGS_ALL, ast_free, ast_free_ha(), ast_get_version(), ast_jb_read_conf(), AST_LIST_EMPTY, ast_log(), AST_MAX_CONTEXT, ast_mutex_lock, ast_mutex_unlock, ast_parse_allow_disallow(), ast_parse_arg(), ast_set2_flag, ast_set_flag, ast_set_qos(), ast_skip_blanks(), ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_is_any(), ast_sockaddr_is_ipv6(), ast_sockaddr_isnull(), ast_sockaddr_parse(), ast_sockaddr_port, ast_sockaddr_resolve_first(), ast_sockaddr_set_port, ast_sockaddr_setnull(), ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_ssl_setup(), ast_str2cos(), ast_str2tos(), ast_strdup, ast_strdupa, ast_strip(), ast_strlen_zero(), ast_tcptls_server_start(), ast_test_flag, ast_tls_read_conf(), ast_true(), ast_unload_realtime(), ast_variable_browse(), ast_variable_retrieve(), ast_verb, ASTOBJ_CONTAINER_DESTROYALL, bindaddr, build_peer(), ast_tls_config::cafile, ast_tls_config::capath, ast_tls_config::certfile, CHANNEL_MODULE_LOAD, channelreloadreason2txt(), ast_tls_config::cipher, cleanup_all_regs(), cleanup_stale_contexts(), clear_sip_domains(), CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, context, DEFAULT_AUTHLIMIT, DEFAULT_AUTHTIMEOUT, DEFAULT_CONTEXT, DEFAULT_MAXMS, DEFAULT_PARKINGLOT, default_prefs, DEFAULT_REALM, display_nat_warning(), ast_tls_config::enabled, errno, EVENT_FLAG_SYSTEM, externaddr, FALSE, gen, global_jbconf, handle_common_options(), handle_t38_options(), internip, ast_variable::lineno, ast_tcptls_session_args::local_address, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event, mark_parsed_methods(), MAXHOSTNAMELEN, media_address, ast_variable::name, network_change_event_subscribe(), network_change_event_unsubscribe(), ast_variable::next, OBJ_NODATA, PARSE_ADDR, PARSE_DEFAULT, PARSE_IN_RANGE, PARSE_INT32, peer_markall_func(), port_str2int(), proxy_from_config(), ast_tls_config::pvtfile, regl, S_OR, secret, sip_cfg, sip_register(), sip_registry_destroy(), sip_subscribe_mwi(), str2stmode(), str2strefresherparam(), ast_tcptls_session_args::tls_cfg, TRUE, unref_peer(), and ast_variable::value.
Referenced by load_module(), and sip_do_reload().
28775 { 28776 struct ast_config *cfg, *ucfg; 28777 struct ast_variable *v; 28778 struct sip_peer *peer; 28779 char *cat, *stringp, *context, *oldregcontext; 28780 char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT]; 28781 struct ast_flags mask[3] = {{0}}; 28782 struct ast_flags setflags[3] = {{0}}; 28783 struct ast_flags config_flags = { reason == CHANNEL_MODULE_LOAD ? 0 : ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? 0 : CONFIG_FLAG_FILEUNCHANGED }; 28784 int auto_sip_domains = FALSE; 28785 struct ast_sockaddr old_bindaddr = bindaddr; 28786 int registry_count = 0, peer_count = 0, timerb_set = 0, timert1_set = 0; 28787 int subscribe_network_change = 1; 28788 time_t run_start, run_end; 28789 int bindport = 0; 28790 28791 run_start = time(0); 28792 ast_unload_realtime("sipregs"); 28793 ast_unload_realtime("sippeers"); 28794 cfg = ast_config_load(config, config_flags); 28795 28796 /* We *must* have a config file otherwise stop immediately */ 28797 if (!cfg) { 28798 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 28799 return -1; 28800 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 28801 ucfg = ast_config_load("users.conf", config_flags); 28802 if (ucfg == CONFIG_STATUS_FILEUNCHANGED) { 28803 return 1; 28804 } else if (ucfg == CONFIG_STATUS_FILEINVALID) { 28805 ast_log(LOG_ERROR, "Contents of users.conf are invalid and cannot be parsed\n"); 28806 return 1; 28807 } 28808 /* Must reread both files, because one changed */ 28809 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 28810 if ((cfg = ast_config_load(config, config_flags)) == CONFIG_STATUS_FILEINVALID) { 28811 ast_log(LOG_ERROR, "Contents of %s are invalid and cannot be parsed\n", config); 28812 ast_config_destroy(ucfg); 28813 return 1; 28814 } 28815 if (!cfg) { 28816 /* should have been able to reload here */ 28817 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 28818 return -1; 28819 } 28820 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 28821 ast_log(LOG_ERROR, "Contents of %s are invalid and cannot be parsed\n", config); 28822 return 1; 28823 } else { 28824 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 28825 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 28826 ast_log(LOG_ERROR, "Contents of users.conf are invalid and cannot be parsed\n"); 28827 ast_config_destroy(cfg); 28828 return 1; 28829 } 28830 } 28831 28832 ast_free_ha(sip_cfg.contact_ha); 28833 sip_cfg.contact_ha = NULL; 28834 28835 default_tls_cfg.enabled = FALSE; /* Default: Disable TLS */ 28836 28837 if (reason != CHANNEL_MODULE_LOAD) { 28838 ast_debug(4, "--------------- SIP reload started\n"); 28839 28840 clear_sip_domains(); 28841 ast_mutex_lock(&authl_lock); 28842 if (authl) { 28843 ao2_t_ref(authl, -1, "Removing old global authentication"); 28844 authl = NULL; 28845 } 28846 ast_mutex_unlock(&authl_lock); 28847 28848 28849 cleanup_all_regs(); 28850 /* Then, actually destroy users and registry */ 28851 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 28852 ast_debug(4, "--------------- Done destroying registry list\n"); 28853 ao2_t_callback(peers, OBJ_NODATA, peer_markall_func, NULL, "callback to mark all peers"); 28854 } 28855 28856 /* Reset certificate handling for TLS sessions */ 28857 if (reason != CHANNEL_MODULE_LOAD) { 28858 ast_free(default_tls_cfg.certfile); 28859 ast_free(default_tls_cfg.pvtfile); 28860 ast_free(default_tls_cfg.cipher); 28861 ast_free(default_tls_cfg.cafile); 28862 ast_free(default_tls_cfg.capath); 28863 } 28864 default_tls_cfg.certfile = ast_strdup(AST_CERTFILE); /*XXX Not sure if this is useful */ 28865 default_tls_cfg.pvtfile = ast_strdup(""); 28866 default_tls_cfg.cipher = ast_strdup(""); 28867 default_tls_cfg.cafile = ast_strdup(""); 28868 default_tls_cfg.capath = ast_strdup(""); 28869 28870 /* Initialize copy of current sip_cfg.regcontext for later use in removing stale contexts */ 28871 ast_copy_string(oldcontexts, sip_cfg.regcontext, sizeof(oldcontexts)); 28872 oldregcontext = oldcontexts; 28873 28874 /* Clear all flags before setting default values */ 28875 /* Preserve debugging settings for console */ 28876 sipdebug &= sip_debug_console; 28877 ast_clear_flag(&global_flags[0], AST_FLAGS_ALL); 28878 ast_clear_flag(&global_flags[1], AST_FLAGS_ALL); 28879 ast_clear_flag(&global_flags[2], AST_FLAGS_ALL); 28880 28881 /* Reset IP addresses */ 28882 ast_sockaddr_parse(&bindaddr, "0.0.0.0:0", 0); 28883 memset(&internip, 0, sizeof(internip)); 28884 28885 /* Free memory for local network address mask */ 28886 ast_free_ha(localaddr); 28887 memset(&localaddr, 0, sizeof(localaddr)); 28888 memset(&externaddr, 0, sizeof(externaddr)); 28889 memset(&media_address, 0, sizeof(media_address)); 28890 memset(&default_prefs, 0 , sizeof(default_prefs)); 28891 memset(&sip_cfg.outboundproxy, 0, sizeof(struct sip_proxy)); 28892 sip_cfg.outboundproxy.force = FALSE; /*!< Don't force proxy usage, use route: headers */ 28893 default_transports = SIP_TRANSPORT_UDP; 28894 default_primary_transport = SIP_TRANSPORT_UDP; 28895 ourport_tcp = STANDARD_SIP_PORT; 28896 ourport_tls = STANDARD_TLS_PORT; 28897 externtcpport = STANDARD_SIP_PORT; 28898 externtlsport = STANDARD_TLS_PORT; 28899 sip_cfg.srvlookup = DEFAULT_SRVLOOKUP; 28900 global_tos_sip = DEFAULT_TOS_SIP; 28901 global_tos_audio = DEFAULT_TOS_AUDIO; 28902 global_tos_video = DEFAULT_TOS_VIDEO; 28903 global_tos_text = DEFAULT_TOS_TEXT; 28904 global_cos_sip = DEFAULT_COS_SIP; 28905 global_cos_audio = DEFAULT_COS_AUDIO; 28906 global_cos_video = DEFAULT_COS_VIDEO; 28907 global_cos_text = DEFAULT_COS_TEXT; 28908 28909 externhost[0] = '\0'; /* External host name (for behind NAT DynDNS support) */ 28910 externexpire = 0; /* Expiration for DNS re-issuing */ 28911 externrefresh = 10; 28912 28913 /* Reset channel settings to default before re-configuring */ 28914 sip_cfg.allow_external_domains = DEFAULT_ALLOW_EXT_DOM; /* Allow external invites */ 28915 sip_cfg.regcontext[0] = '\0'; 28916 sip_cfg.capability = DEFAULT_CAPABILITY; 28917 sip_cfg.regextenonqualify = DEFAULT_REGEXTENONQUALIFY; 28918 sip_cfg.legacy_useroption_parsing = DEFAULT_LEGACY_USEROPTION_PARSING; 28919 sip_cfg.notifyringing = DEFAULT_NOTIFYRINGING; 28920 sip_cfg.notifycid = DEFAULT_NOTIFYCID; 28921 sip_cfg.notifyhold = FALSE; /*!< Keep track of hold status for a peer */ 28922 sip_cfg.directrtpsetup = FALSE; /* Experimental feature, disabled by default */ 28923 sip_cfg.alwaysauthreject = DEFAULT_ALWAYSAUTHREJECT; 28924 sip_cfg.auth_options_requests = DEFAULT_AUTH_OPTIONS; 28925 sip_cfg.allowsubscribe = FALSE; 28926 sip_cfg.disallowed_methods = SIP_UNKNOWN; 28927 sip_cfg.contact_ha = NULL; /* Reset the contact ACL */ 28928 snprintf(global_useragent, sizeof(global_useragent), "%s %s", DEFAULT_USERAGENT, ast_get_version()); 28929 snprintf(global_sdpsession, sizeof(global_sdpsession), "%s %s", DEFAULT_SDPSESSION, ast_get_version()); 28930 snprintf(global_sdpowner, sizeof(global_sdpowner), "%s", DEFAULT_SDPOWNER); 28931 global_prematuremediafilter = TRUE; 28932 ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime)); 28933 ast_copy_string(sip_cfg.realm, S_OR(ast_config_AST_SYSTEM_NAME, DEFAULT_REALM), sizeof(sip_cfg.realm)); 28934 sip_cfg.domainsasrealm = DEFAULT_DOMAINSASREALM; 28935 ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid)); 28936 ast_copy_string(default_mwi_from, DEFAULT_MWI_FROM, sizeof(default_mwi_from)); 28937 sip_cfg.compactheaders = DEFAULT_COMPACTHEADERS; 28938 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 28939 global_regattempts_max = 0; 28940 global_reg_retry_403 = 0; 28941 sip_cfg.pedanticsipchecking = DEFAULT_PEDANTIC; 28942 sip_cfg.autocreatepeer = DEFAULT_AUTOCREATEPEER; 28943 global_autoframing = 0; 28944 sip_cfg.allowguest = DEFAULT_ALLOWGUEST; 28945 global_callcounter = DEFAULT_CALLCOUNTER; 28946 global_match_auth_username = FALSE; /*!< Match auth username if available instead of From: Default off. */ 28947 global_rtptimeout = 0; 28948 global_rtpholdtimeout = 0; 28949 global_rtpkeepalive = DEFAULT_RTPKEEPALIVE; 28950 sip_cfg.allowtransfer = TRANSFER_OPENFORALL; /* Merrily accept all transfers by default */ 28951 sip_cfg.rtautoclear = 120; 28952 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE); /* Default for all devices: TRUE */ 28953 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP_YES); /* Default for all devices: Yes */ 28954 sip_cfg.peer_rtupdate = TRUE; 28955 global_dynamic_exclude_static = 0; /* Exclude static peers */ 28956 sip_cfg.tcp_enabled = FALSE; 28957 28958 /* Session-Timers */ 28959 global_st_mode = SESSION_TIMER_MODE_ACCEPT; 28960 global_st_refresher = SESSION_TIMER_REFRESHER_PARAM_UAS; 28961 global_min_se = DEFAULT_MIN_SE; 28962 global_max_se = DEFAULT_MAX_SE; 28963 28964 /* Peer poking settings */ 28965 global_qualify_gap = DEFAULT_QUALIFY_GAP; 28966 global_qualify_peers = DEFAULT_QUALIFY_PEERS; 28967 28968 /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for devices */ 28969 ast_copy_string(sip_cfg.default_context, DEFAULT_CONTEXT, sizeof(sip_cfg.default_context)); 28970 sip_cfg.default_subscribecontext[0] = '\0'; 28971 sip_cfg.default_max_forwards = DEFAULT_MAX_FORWARDS; 28972 default_language[0] = '\0'; 28973 default_fromdomain[0] = '\0'; 28974 default_fromdomainport = 0; 28975 default_qualify = DEFAULT_QUALIFY; 28976 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 28977 ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret)); 28978 ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest)); 28979 ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten)); 28980 ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */ 28981 ast_set_flag(&global_flags[0], SIP_DIRECT_MEDIA); /*!< Allow re-invites */ 28982 ast_set_flag(&global_flags[0], SIP_NAT_FORCE_RPORT); /*!< Default to nat=force_rport */ 28983 ast_copy_string(default_engine, DEFAULT_ENGINE, sizeof(default_engine)); 28984 ast_copy_string(default_parkinglot, DEFAULT_PARKINGLOT, sizeof(default_parkinglot)); 28985 28986 /* Debugging settings, always default to off */ 28987 dumphistory = FALSE; 28988 recordhistory = FALSE; 28989 sipdebug &= ~sip_debug_config; 28990 28991 /* Misc settings for the channel */ 28992 global_relaxdtmf = FALSE; 28993 sip_cfg.callevents = DEFAULT_CALLEVENTS; 28994 global_authfailureevents = FALSE; 28995 global_t1 = DEFAULT_TIMER_T1; 28996 global_timer_b = 64 * DEFAULT_TIMER_T1; 28997 global_t1min = DEFAULT_T1MIN; 28998 global_qualifyfreq = DEFAULT_QUALIFYFREQ; 28999 global_t38_maxdatagram = -1; 29000 global_shrinkcallerid = 1; 29001 authlimit = DEFAULT_AUTHLIMIT; 29002 authtimeout = DEFAULT_AUTHTIMEOUT; 29003 global_store_sip_cause = DEFAULT_STORE_SIP_CAUSE; 29004 29005 sip_cfg.matchexternaddrlocally = DEFAULT_MATCHEXTERNADDRLOCALLY; 29006 29007 /* Copy the default jb config over global_jbconf */ 29008 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 29009 29010 ast_clear_flag(&global_flags[1], SIP_PAGE2_FAX_DETECT); 29011 ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT | SIP_PAGE2_VIDEOSUPPORT_ALWAYS); 29012 ast_clear_flag(&global_flags[1], SIP_PAGE2_TEXTSUPPORT); 29013 ast_clear_flag(&global_flags[1], SIP_PAGE2_IGNORESDPVERSION); 29014 29015 29016 /* Read the [general] config section of sip.conf (or from realtime config) */ 29017 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) { 29018 if (handle_common_options(&setflags[0], &mask[0], v)) { 29019 continue; 29020 } 29021 if (handle_t38_options(&setflags[0], &mask[0], v, &global_t38_maxdatagram)) { 29022 continue; 29023 } 29024 /* handle jb conf */ 29025 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 29026 continue; 29027 29028 /* handle tls conf, don't allow setting of tlsverifyclient as it isn't supported by chan_sip */ 29029 if (!strcasecmp(v->name, "tlsverifyclient")) { 29030 ast_log(LOG_WARNING, "Ignoring unsupported option 'tlsverifyclient'\n"); 29031 continue; 29032 } else if (!ast_tls_read_conf(&default_tls_cfg, &sip_tls_desc, v->name, v->value)) { 29033 continue; 29034 } 29035 29036 if (!strcasecmp(v->name, "context")) { 29037 ast_copy_string(sip_cfg.default_context, v->value, sizeof(sip_cfg.default_context)); 29038 } else if (!strcasecmp(v->name, "subscribecontext")) { 29039 ast_copy_string(sip_cfg.default_subscribecontext, v->value, sizeof(sip_cfg.default_subscribecontext)); 29040 } else if (!strcasecmp(v->name, "callcounter")) { 29041 global_callcounter = ast_true(v->value) ? 1 : 0; 29042 } else if (!strcasecmp(v->name, "allowguest")) { 29043 sip_cfg.allowguest = ast_true(v->value) ? 1 : 0; 29044 } else if (!strcasecmp(v->name, "realm")) { 29045 ast_copy_string(sip_cfg.realm, v->value, sizeof(sip_cfg.realm)); 29046 } else if (!strcasecmp(v->name, "domainsasrealm")) { 29047 sip_cfg.domainsasrealm = ast_true(v->value); 29048 } else if (!strcasecmp(v->name, "useragent")) { 29049 ast_copy_string(global_useragent, v->value, sizeof(global_useragent)); 29050 ast_debug(1, "Setting SIP channel User-Agent Name to %s\n", global_useragent); 29051 } else if (!strcasecmp(v->name, "sdpsession")) { 29052 ast_copy_string(global_sdpsession, v->value, sizeof(global_sdpsession)); 29053 } else if (!strcasecmp(v->name, "sdpowner")) { 29054 /* Field cannot contain spaces */ 29055 if (!strstr(v->value, " ")) { 29056 ast_copy_string(global_sdpowner, v->value, sizeof(global_sdpowner)); 29057 } else { 29058 ast_log(LOG_WARNING, "'%s' must not contain spaces at line %d. Using default.\n", v->value, v->lineno); 29059 } 29060 } else if (!strcasecmp(v->name, "allowtransfer")) { 29061 sip_cfg.allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 29062 } else if (!strcasecmp(v->name, "rtcachefriends")) { 29063 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 29064 } else if (!strcasecmp(v->name, "rtsavesysname")) { 29065 sip_cfg.rtsave_sysname = ast_true(v->value); 29066 } else if (!strcasecmp(v->name, "rtupdate")) { 29067 sip_cfg.peer_rtupdate = ast_true(v->value); 29068 } else if (!strcasecmp(v->name, "ignoreregexpire")) { 29069 sip_cfg.ignore_regexpire = ast_true(v->value); 29070 } else if (!strcasecmp(v->name, "timert1")) { 29071 /* Defaults to 500ms, but RFC 3261 states that it is recommended 29072 * for the value to be set higher, though a lower value is only 29073 * allowed on private networks unconnected to the Internet. */ 29074 global_t1 = atoi(v->value); 29075 } else if (!strcasecmp(v->name, "timerb")) { 29076 int tmp = atoi(v->value); 29077 if (tmp < 500) { 29078 global_timer_b = global_t1 * 64; 29079 ast_log(LOG_WARNING, "Invalid value for timerb ('%s'). Setting to default ('%d').\n", v->value, global_timer_b); 29080 } 29081 timerb_set = 1; 29082 } else if (!strcasecmp(v->name, "t1min")) { 29083 global_t1min = atoi(v->value); 29084 } else if (!strcasecmp(v->name, "transport")) { 29085 char *val = ast_strdupa(v->value); 29086 char *trans; 29087 29088 default_transports = default_primary_transport = 0; 29089 while ((trans = strsep(&val, ","))) { 29090 trans = ast_skip_blanks(trans); 29091 29092 if (!strncasecmp(trans, "udp", 3)) { 29093 default_transports |= SIP_TRANSPORT_UDP; 29094 } else if (!strncasecmp(trans, "tcp", 3)) { 29095 default_transports |= SIP_TRANSPORT_TCP; 29096 } else if (!strncasecmp(trans, "tls", 3)) { 29097 default_transports |= SIP_TRANSPORT_TLS; 29098 } else { 29099 ast_log(LOG_NOTICE, "'%s' is not a valid transport type. if no other is specified, udp will be used.\n", trans); 29100 } 29101 if (default_primary_transport == 0) { 29102 default_primary_transport = default_transports; 29103 } 29104 } 29105 } else if (!strcasecmp(v->name, "tcpenable")) { 29106 if (!ast_false(v->value)) { 29107 ast_debug(2, "Enabling TCP socket for listening\n"); 29108 sip_cfg.tcp_enabled = TRUE; 29109 } 29110 } else if (!strcasecmp(v->name, "tcpbindaddr")) { 29111 if (ast_parse_arg(v->value, PARSE_ADDR, 29112 &sip_tcp_desc.local_address)) { 29113 ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n", 29114 v->name, v->value, v->lineno, config); 29115 } 29116 ast_debug(2, "Setting TCP socket address to %s\n", 29117 ast_sockaddr_stringify(&sip_tcp_desc.local_address)); 29118 } else if (!strcasecmp(v->name, "dynamic_exclude_static") || !strcasecmp(v->name, "dynamic_excludes_static")) { 29119 global_dynamic_exclude_static = ast_true(v->value); 29120 } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) { 29121 int ha_error = 0; 29122 sip_cfg.contact_ha = ast_append_ha(v->name + 7, v->value, sip_cfg.contact_ha, &ha_error); 29123 if (ha_error) { 29124 ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value); 29125 } 29126 } else if (!strcasecmp(v->name, "rtautoclear")) { 29127 int i = atoi(v->value); 29128 if (i > 0) { 29129 sip_cfg.rtautoclear = i; 29130 } else { 29131 i = 0; 29132 } 29133 ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR); 29134 } else if (!strcasecmp(v->name, "usereqphone")) { 29135 ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE); 29136 } else if (!strcasecmp(v->name, "prematuremedia")) { 29137 global_prematuremediafilter = ast_true(v->value); 29138 } else if (!strcasecmp(v->name, "relaxdtmf")) { 29139 global_relaxdtmf = ast_true(v->value); 29140 } else if (!strcasecmp(v->name, "vmexten")) { 29141 ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten)); 29142 } else if (!strcasecmp(v->name, "rtptimeout")) { 29143 if ((sscanf(v->value, "%30d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) { 29144 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 29145 global_rtptimeout = 0; 29146 } 29147 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 29148 if ((sscanf(v->value, "%30d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) { 29149 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 29150 global_rtpholdtimeout = 0; 29151 } 29152 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 29153 if ((sscanf(v->value, "%30d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) { 29154 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 29155 global_rtpkeepalive = DEFAULT_RTPKEEPALIVE; 29156 } 29157 } else if (!strcasecmp(v->name, "compactheaders")) { 29158 sip_cfg.compactheaders = ast_true(v->value); 29159 } else if (!strcasecmp(v->name, "notifymimetype")) { 29160 ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime)); 29161 } else if (!strcasecmp(v->name, "directrtpsetup")) { 29162 sip_cfg.directrtpsetup = ast_true(v->value); 29163 } else if (!strcasecmp(v->name, "notifyringing")) { 29164 sip_cfg.notifyringing = ast_true(v->value); 29165 } else if (!strcasecmp(v->name, "notifyhold")) { 29166 sip_cfg.notifyhold = ast_true(v->value); 29167 } else if (!strcasecmp(v->name, "notifycid")) { 29168 if (!strcasecmp(v->value, "ignore-context")) { 29169 sip_cfg.notifycid = IGNORE_CONTEXT; 29170 } else { 29171 sip_cfg.notifycid = ast_true(v->value) ? ENABLED : DISABLED; 29172 } 29173 } else if (!strcasecmp(v->name, "alwaysauthreject")) { 29174 sip_cfg.alwaysauthreject = ast_true(v->value); 29175 } else if (!strcasecmp(v->name, "auth_options_requests")) { 29176 if (ast_true(v->value)) { 29177 sip_cfg.auth_options_requests = 1; 29178 } 29179 } else if (!strcasecmp(v->name, "mohinterpret")) { 29180 ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret)); 29181 } else if (!strcasecmp(v->name, "mohsuggest")) { 29182 ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest)); 29183 } else if (!strcasecmp(v->name, "language")) { 29184 ast_copy_string(default_language, v->value, sizeof(default_language)); 29185 } else if (!strcasecmp(v->name, "regcontext")) { 29186 ast_copy_string(newcontexts, v->value, sizeof(newcontexts)); 29187 stringp = newcontexts; 29188 /* Let's remove any contexts that are no longer defined in regcontext */ 29189 cleanup_stale_contexts(stringp, oldregcontext); 29190 /* Create contexts if they don't exist already */ 29191 while ((context = strsep(&stringp, "&"))) { 29192 ast_copy_string(used_context, context, sizeof(used_context)); 29193 ast_context_find_or_create(NULL, NULL, context, "SIP"); 29194 } 29195 ast_copy_string(sip_cfg.regcontext, v->value, sizeof(sip_cfg.regcontext)); 29196 } else if (!strcasecmp(v->name, "regextenonqualify")) { 29197 sip_cfg.regextenonqualify = ast_true(v->value); 29198 } else if (!strcasecmp(v->name, "legacy_useroption_parsing")) { 29199 sip_cfg.legacy_useroption_parsing = ast_true(v->value); 29200 } else if (!strcasecmp(v->name, "callerid")) { 29201 ast_copy_string(default_callerid, v->value, sizeof(default_callerid)); 29202 } else if (!strcasecmp(v->name, "mwi_from")) { 29203 ast_copy_string(default_mwi_from, v->value, sizeof(default_mwi_from)); 29204 } else if (!strcasecmp(v->name, "fromdomain")) { 29205 char *fromdomainport; 29206 ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain)); 29207 if ((fromdomainport = strchr(default_fromdomain, ':'))) { 29208 *fromdomainport++ = '\0'; 29209 if (!(default_fromdomainport = port_str2int(fromdomainport, 0))) { 29210 ast_log(LOG_NOTICE, "'%s' is not a valid port number for fromdomain.\n",fromdomainport); 29211 } 29212 } else { 29213 default_fromdomainport = STANDARD_SIP_PORT; 29214 } 29215 } else if (!strcasecmp(v->name, "outboundproxy")) { 29216 struct sip_proxy *proxy; 29217 if (ast_strlen_zero(v->value)) { 29218 ast_log(LOG_WARNING, "no value given for outbound proxy on line %d of sip.conf\n", v->lineno); 29219 continue; 29220 } 29221 proxy = proxy_from_config(v->value, v->lineno, &sip_cfg.outboundproxy); 29222 if (!proxy) { 29223 ast_log(LOG_WARNING, "failure parsing the outbound proxy on line %d of sip.conf.\n", v->lineno); 29224 continue; 29225 } 29226 } else if (!strcasecmp(v->name, "autocreatepeer")) { 29227 sip_cfg.autocreatepeer = ast_true(v->value); 29228 } else if (!strcasecmp(v->name, "match_auth_username")) { 29229 global_match_auth_username = ast_true(v->value); 29230 } else if (!strcasecmp(v->name, "srvlookup")) { 29231 sip_cfg.srvlookup = ast_true(v->value); 29232 } else if (!strcasecmp(v->name, "pedantic")) { 29233 sip_cfg.pedanticsipchecking = ast_true(v->value); 29234 } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) { 29235 max_expiry = atoi(v->value); 29236 if (max_expiry < 1) { 29237 max_expiry = DEFAULT_MAX_EXPIRY; 29238 } 29239 } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) { 29240 min_expiry = atoi(v->value); 29241 if (min_expiry < 1) { 29242 min_expiry = DEFAULT_MIN_EXPIRY; 29243 } 29244 } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) { 29245 default_expiry = atoi(v->value); 29246 if (default_expiry < 1) { 29247 default_expiry = DEFAULT_DEFAULT_EXPIRY; 29248 } 29249 } else if (!strcasecmp(v->name, "mwiexpiry") || !strcasecmp(v->name, "mwiexpirey")) { 29250 mwi_expiry = atoi(v->value); 29251 if (mwi_expiry < 1) { 29252 mwi_expiry = DEFAULT_MWI_EXPIRY; 29253 } 29254 } else if (!strcasecmp(v->name, "tcpauthtimeout")) { 29255 if (ast_parse_arg(v->value, PARSE_INT32|PARSE_DEFAULT|PARSE_IN_RANGE, 29256 &authtimeout, DEFAULT_AUTHTIMEOUT, 1, INT_MAX)) { 29257 ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n", 29258 v->name, v->value, v->lineno, config); 29259 } 29260 } else if (!strcasecmp(v->name, "tcpauthlimit")) { 29261 if (ast_parse_arg(v->value, PARSE_INT32|PARSE_DEFAULT|PARSE_IN_RANGE, 29262 &authlimit, DEFAULT_AUTHLIMIT, 1, INT_MAX)) { 29263 ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n", 29264 v->name, v->value, v->lineno, config); 29265 } 29266 } else if (!strcasecmp(v->name, "sipdebug")) { 29267 if (ast_true(v->value)) 29268 sipdebug |= sip_debug_config; 29269 } else if (!strcasecmp(v->name, "dumphistory")) { 29270 dumphistory = ast_true(v->value); 29271 } else if (!strcasecmp(v->name, "recordhistory")) { 29272 recordhistory = ast_true(v->value); 29273 } else if (!strcasecmp(v->name, "registertimeout")) { 29274 global_reg_timeout = atoi(v->value); 29275 if (global_reg_timeout < 1) { 29276 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 29277 } 29278 } else if (!strcasecmp(v->name, "registerattempts")) { 29279 global_regattempts_max = atoi(v->value); 29280 } else if (!strcasecmp(v->name, "register_retry_403")) { 29281 global_reg_retry_403 = ast_true(v->value); 29282 } else if (!strcasecmp(v->name, "bindaddr") || !strcasecmp(v->name, "udpbindaddr")) { 29283 if (ast_parse_arg(v->value, PARSE_ADDR, &bindaddr)) { 29284 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 29285 } 29286 } else if (!strcasecmp(v->name, "localnet")) { 29287 struct ast_ha *na; 29288 int ha_error = 0; 29289 29290 if (!(na = ast_append_ha("d", v->value, localaddr, &ha_error))) { 29291 ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value); 29292 } else { 29293 localaddr = na; 29294 } 29295 if (ha_error) { 29296 ast_log(LOG_ERROR, "Bad localnet configuration value line %d : %s\n", v->lineno, v->value); 29297 } 29298 } else if (!strcasecmp(v->name, "media_address")) { 29299 if (ast_parse_arg(v->value, PARSE_ADDR, &media_address)) 29300 ast_log(LOG_WARNING, "Invalid address for media_address keyword: %s\n", v->value); 29301 } else if (!strcasecmp(v->name, "externaddr") || !strcasecmp(v->name, "externip")) { 29302 if (ast_parse_arg(v->value, PARSE_ADDR, &externaddr)) { 29303 ast_log(LOG_WARNING, 29304 "Invalid address for externaddr keyword: %s\n", 29305 v->value); 29306 } 29307 externexpire = 0; 29308 } else if (!strcasecmp(v->name, "externhost")) { 29309 ast_copy_string(externhost, v->value, sizeof(externhost)); 29310 if (ast_sockaddr_resolve_first(&externaddr, externhost, 0)) { 29311 ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost); 29312 } 29313 externexpire = time(NULL); 29314 } else if (!strcasecmp(v->name, "externrefresh")) { 29315 if (sscanf(v->value, "%30d", &externrefresh) != 1) { 29316 ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno); 29317 externrefresh = 10; 29318 } 29319 } else if (!strcasecmp(v->name, "externtcpport")) { 29320 if (!(externtcpport = port_str2int(v->value, 0))) { 29321 ast_log(LOG_WARNING, "Invalid externtcpport value, must be a positive integer between 1 and 65535 at line %d\n", v->lineno); 29322 externtcpport = 0; 29323 } 29324 } else if (!strcasecmp(v->name, "externtlsport")) { 29325 if (!(externtlsport = port_str2int(v->value, STANDARD_TLS_PORT))) { 29326 ast_log(LOG_WARNING, "Invalid externtlsport value, must be a positive integer between 1 and 65535 at line %d\n", v->lineno); 29327 } 29328 } else if (!strcasecmp(v->name, "allow")) { 29329 int error = ast_parse_allow_disallow(&default_prefs, &sip_cfg.capability, v->value, TRUE); 29330 if (error) { 29331 ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value); 29332 } 29333 } else if (!strcasecmp(v->name, "disallow")) { 29334 int error = ast_parse_allow_disallow(&default_prefs, &sip_cfg.capability, v->value, FALSE); 29335 if (error) { 29336 ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value); 29337 } 29338 } else if (!strcasecmp(v->name, "preferred_codec_only")) { 29339 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_PREFERRED_CODEC); 29340 } else if (!strcasecmp(v->name, "autoframing")) { 29341 global_autoframing = ast_true(v->value); 29342 } else if (!strcasecmp(v->name, "allowexternaldomains")) { 29343 sip_cfg.allow_external_domains = ast_true(v->value); 29344 } else if (!strcasecmp(v->name, "autodomain")) { 29345 auto_sip_domains = ast_true(v->value); 29346 } else if (!strcasecmp(v->name, "domain")) { 29347 char *domain = ast_strdupa(v->value); 29348 char *cntx = strchr(domain, ','); 29349 29350 if (cntx) { 29351 *cntx++ = '\0'; 29352 } 29353 29354 if (ast_strlen_zero(cntx)) { 29355 ast_debug(1, "No context specified at line %d for domain '%s'\n", v->lineno, domain); 29356 } 29357 if (ast_strlen_zero(domain)) { 29358 ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno); 29359 } else { 29360 add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, cntx ? ast_strip(cntx) : ""); 29361 } 29362 } else if (!strcasecmp(v->name, "register")) { 29363 if (sip_register(v->value, v->lineno) == 0) { 29364 registry_count++; 29365 } 29366 } else if (!strcasecmp(v->name, "mwi")) { 29367 sip_subscribe_mwi(v->value, v->lineno); 29368 } else if (!strcasecmp(v->name, "tos_sip")) { 29369 if (ast_str2tos(v->value, &global_tos_sip)) { 29370 ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, refer to QoS documentation\n", v->lineno); 29371 } 29372 } else if (!strcasecmp(v->name, "tos_audio")) { 29373 if (ast_str2tos(v->value, &global_tos_audio)) { 29374 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, refer to QoS documentation\n", v->lineno); 29375 } 29376 } else if (!strcasecmp(v->name, "tos_video")) { 29377 if (ast_str2tos(v->value, &global_tos_video)) { 29378 ast_log(LOG_WARNING, "Invalid tos_video value at line %d, refer to QoS documentation\n", v->lineno); 29379 } 29380 } else if (!strcasecmp(v->name, "tos_text")) { 29381 if (ast_str2tos(v->value, &global_tos_text)) { 29382 ast_log(LOG_WARNING, "Invalid tos_text value at line %d, refer to QoS documentation\n", v->lineno); 29383 } 29384 } else if (!strcasecmp(v->name, "cos_sip")) { 29385 if (ast_str2cos(v->value, &global_cos_sip)) { 29386 ast_log(LOG_WARNING, "Invalid cos_sip value at line %d, refer to QoS documentation\n", v->lineno); 29387 } 29388 } else if (!strcasecmp(v->name, "cos_audio")) { 29389 if (ast_str2cos(v->value, &global_cos_audio)) { 29390 ast_log(LOG_WARNING, "Invalid cos_audio value at line %d, refer to QoS documentation\n", v->lineno); 29391 } 29392 } else if (!strcasecmp(v->name, "cos_video")) { 29393 if (ast_str2cos(v->value, &global_cos_video)) { 29394 ast_log(LOG_WARNING, "Invalid cos_video value at line %d, refer to QoS documentation\n", v->lineno); 29395 } 29396 } else if (!strcasecmp(v->name, "cos_text")) { 29397 if (ast_str2cos(v->value, &global_cos_text)) { 29398 ast_log(LOG_WARNING, "Invalid cos_text value at line %d, refer to QoS documentation\n", v->lineno); 29399 } 29400 } else if (!strcasecmp(v->name, "bindport")) { 29401 if (sscanf(v->value, "%5d", &bindport) != 1) { 29402 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 29403 } 29404 } else if (!strcasecmp(v->name, "qualify")) { 29405 if (!strcasecmp(v->value, "no")) { 29406 default_qualify = 0; 29407 } else if (!strcasecmp(v->value, "yes")) { 29408 default_qualify = DEFAULT_MAXMS; 29409 } else if (sscanf(v->value, "%30d", &default_qualify) != 1) { 29410 ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno); 29411 default_qualify = 0; 29412 } 29413 } else if (!strcasecmp(v->name, "qualifyfreq")) { 29414 int i; 29415 if (sscanf(v->value, "%30d", &i) == 1) { 29416 global_qualifyfreq = i * 1000; 29417 } else { 29418 ast_log(LOG_WARNING, "Invalid qualifyfreq number '%s' at line %d of %s\n", v->value, v->lineno, config); 29419 global_qualifyfreq = DEFAULT_QUALIFYFREQ; 29420 } 29421 } else if (!strcasecmp(v->name, "callevents")) { 29422 sip_cfg.callevents = ast_true(v->value); 29423 } else if (!strcasecmp(v->name, "authfailureevents")) { 29424 global_authfailureevents = ast_true(v->value); 29425 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 29426 default_maxcallbitrate = atoi(v->value); 29427 if (default_maxcallbitrate < 0) 29428 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 29429 } else if (!strcasecmp(v->name, "matchexternaddrlocally") || !strcasecmp(v->name, "matchexterniplocally")) { 29430 sip_cfg.matchexternaddrlocally = ast_true(v->value); 29431 } else if (!strcasecmp(v->name, "session-timers")) { 29432 int i = (int) str2stmode(v->value); 29433 if (i < 0) { 29434 ast_log(LOG_WARNING, "Invalid session-timers '%s' at line %d of %s\n", v->value, v->lineno, config); 29435 global_st_mode = SESSION_TIMER_MODE_ACCEPT; 29436 } else { 29437 global_st_mode = i; 29438 } 29439 } else if (!strcasecmp(v->name, "session-expires")) { 29440 if (sscanf(v->value, "%30d", &global_max_se) != 1) { 29441 ast_log(LOG_WARNING, "Invalid session-expires '%s' at line %d of %s\n", v->value, v->lineno, config); 29442 global_max_se = DEFAULT_MAX_SE; 29443 } 29444 } else if (!strcasecmp(v->name, "session-minse")) { 29445 if (sscanf(v->value, "%30d", &global_min_se) != 1) { 29446 ast_log(LOG_WARNING, "Invalid session-minse '%s' at line %d of %s\n", v->value, v->lineno, config); 29447 global_min_se = DEFAULT_MIN_SE; 29448 } 29449 if (global_min_se < DEFAULT_MIN_SE) { 29450 ast_log(LOG_WARNING, "session-minse '%s' at line %d of %s is not allowed to be < %d secs\n", v->value, v->lineno, config, DEFAULT_MIN_SE); 29451 global_min_se = DEFAULT_MIN_SE; 29452 } 29453 } else if (!strcasecmp(v->name, "session-refresher")) { 29454 int i = (int) str2strefresherparam(v->value); 29455 if (i < 0) { 29456 ast_log(LOG_WARNING, "Invalid session-refresher '%s' at line %d of %s\n", v->value, v->lineno, config); 29457 global_st_refresher = SESSION_TIMER_REFRESHER_PARAM_UAS; 29458 } else { 29459 global_st_refresher = i; 29460 } 29461 } else if (!strcasecmp(v->name, "storesipcause")) { 29462 global_store_sip_cause = ast_true(v->value); 29463 } else if (!strcasecmp(v->name, "qualifygap")) { 29464 if (sscanf(v->value, "%30d", &global_qualify_gap) != 1) { 29465 ast_log(LOG_WARNING, "Invalid qualifygap '%s' at line %d of %s\n", v->value, v->lineno, config); 29466 global_qualify_gap = DEFAULT_QUALIFY_GAP; 29467 } 29468 } else if (!strcasecmp(v->name, "qualifypeers")) { 29469 if (sscanf(v->value, "%30d", &global_qualify_peers) != 1) { 29470 ast_log(LOG_WARNING, "Invalid pokepeers '%s' at line %d of %s\n", v->value, v->lineno, config); 29471 global_qualify_peers = DEFAULT_QUALIFY_PEERS; 29472 } 29473 } else if (!strcasecmp(v->name, "disallowed_methods")) { 29474 char *disallow = ast_strdupa(v->value); 29475 mark_parsed_methods(&sip_cfg.disallowed_methods, disallow); 29476 } else if (!strcasecmp(v->name, "shrinkcallerid")) { 29477 if (ast_true(v->value)) { 29478 global_shrinkcallerid = 1; 29479 } else if (ast_false(v->value)) { 29480 global_shrinkcallerid = 0; 29481 } else { 29482 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno); 29483 } 29484 } else if (!strcasecmp(v->name, "use_q850_reason")) { 29485 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_Q850_REASON); 29486 } else if (!strcasecmp(v->name, "maxforwards")) { 29487 if (sscanf(v->value, "%30d", &sip_cfg.default_max_forwards) != 1 29488 || sip_cfg.default_max_forwards < 1 || 255 < sip_cfg.default_max_forwards) { 29489 ast_log(LOG_WARNING, "'%s' is not a valid maxforwards value at line %d. Using default.\n", v->value, v->lineno); 29490 sip_cfg.default_max_forwards = DEFAULT_MAX_FORWARDS; 29491 } 29492 } else if (!strcasecmp(v->name, "subscribe_network_change_event")) { 29493 if (ast_true(v->value)) { 29494 subscribe_network_change = 1; 29495 } else if (ast_false(v->value)) { 29496 subscribe_network_change = 0; 29497 } else { 29498 ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno); 29499 } 29500 } else if (!strcasecmp(v->name, "snom_aoc_enabled")) { 29501 ast_set2_flag(&global_flags[2], ast_true(v->value), SIP_PAGE3_SNOM_AOC); 29502 } else if (!strcasecmp(v->name, "parkinglot")) { 29503 ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot)); 29504 } 29505 } 29506 29507 /* Override global defaults if setting found in general section */ 29508 ast_copy_flags(&global_flags[0], &setflags[0], mask[0].flags); 29509 ast_copy_flags(&global_flags[1], &setflags[1], mask[1].flags); 29510 ast_copy_flags(&global_flags[2], &setflags[2], mask[2].flags); 29511 29512 if (subscribe_network_change) { 29513 network_change_event_subscribe(); 29514 } else { 29515 network_change_event_unsubscribe(); 29516 } 29517 29518 if (global_t1 < global_t1min) { 29519 ast_log(LOG_WARNING, "'t1min' (%d) cannot be greater than 't1timer' (%d). Resetting 't1timer' to the value of 't1min'\n", global_t1min, global_t1); 29520 global_t1 = global_t1min; 29521 } 29522 29523 if (global_timer_b < global_t1 * 64) { 29524 if (timerb_set && timert1_set) { 29525 ast_log(LOG_WARNING, "Timer B has been set lower than recommended (%d < 64 * timert1=%d). (RFC 3261, 17.1.1.2)\n", global_timer_b, global_t1); 29526 } else if (timerb_set) { 29527 if ((global_t1 = global_timer_b / 64) < global_t1min) { 29528 ast_log(LOG_WARNING, "Timer B has been set lower than recommended (%d < 64 * timert1=%d). (RFC 3261, 17.1.1.2)\n", global_timer_b, global_t1); 29529 global_t1 = global_t1min; 29530 global_timer_b = global_t1 * 64; 29531 } 29532 } else { 29533 global_timer_b = global_t1 * 64; 29534 } 29535 } 29536 if (!sip_cfg.allow_external_domains && AST_LIST_EMPTY(&domain_list)) { 29537 ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n"); 29538 sip_cfg.allow_external_domains = 1; 29539 } 29540 /* If not or badly configured, set default transports */ 29541 if (!sip_cfg.tcp_enabled && (default_transports & SIP_TRANSPORT_TCP)) { 29542 ast_log(LOG_WARNING, "Cannot use 'tcp' transport with tcpenable=no. Removing from available transports.\n"); 29543 default_primary_transport &= ~SIP_TRANSPORT_TCP; 29544 default_transports &= ~SIP_TRANSPORT_TCP; 29545 } 29546 if (!default_tls_cfg.enabled && (default_transports & SIP_TRANSPORT_TLS)) { 29547 ast_log(LOG_WARNING, "Cannot use 'tls' transport with tlsenable=no. Removing from available transports.\n"); 29548 default_primary_transport &= ~SIP_TRANSPORT_TLS; 29549 default_transports &= ~SIP_TRANSPORT_TLS; 29550 } 29551 if (!default_transports) { 29552 ast_log(LOG_WARNING, "No valid transports available, falling back to 'udp'.\n"); 29553 default_transports = default_primary_transport = SIP_TRANSPORT_UDP; 29554 } else if (!default_primary_transport) { 29555 ast_log(LOG_WARNING, "No valid default transport. Selecting 'udp' as default.\n"); 29556 default_primary_transport = SIP_TRANSPORT_UDP; 29557 } 29558 29559 /* Build list of authentication to various SIP realms, i.e. service providers */ 29560 for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) { 29561 /* Format for authentication is auth = username:password@realm */ 29562 if (!strcasecmp(v->name, "auth")) { 29563 add_realm_authentication(&authl, v->value, v->lineno); 29564 } 29565 } 29566 29567 if (bindport) { 29568 if (ast_sockaddr_port(&bindaddr)) { 29569 ast_log(LOG_WARNING, "bindport is also specified in bindaddr. " 29570 "Using %d.\n", bindport); 29571 } 29572 ast_sockaddr_set_port(&bindaddr, bindport); 29573 } 29574 29575 if (!ast_sockaddr_port(&bindaddr)) { 29576 ast_sockaddr_set_port(&bindaddr, STANDARD_SIP_PORT); 29577 } 29578 29579 /* Set UDP address and open socket */ 29580 ast_sockaddr_copy(&internip, &bindaddr); 29581 if (ast_find_ourip(&internip, &bindaddr, 0)) { 29582 ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n"); 29583 ast_config_destroy(cfg); 29584 return 0; 29585 } 29586 29587 ast_mutex_lock(&netlock); 29588 if ((sipsock > -1) && (ast_sockaddr_cmp(&old_bindaddr, &bindaddr))) { 29589 close(sipsock); 29590 sipsock = -1; 29591 } 29592 if (sipsock < 0) { 29593 sipsock = socket(ast_sockaddr_is_ipv6(&bindaddr) ? 29594 AF_INET6 : AF_INET, SOCK_DGRAM, 0); 29595 if (sipsock < 0) { 29596 ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno)); 29597 ast_config_destroy(cfg); 29598 ast_mutex_unlock(&netlock); 29599 return -1; 29600 } else { 29601 /* Allow SIP clients on the same host to access us: */ 29602 const int reuseFlag = 1; 29603 29604 setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR, 29605 (const char*)&reuseFlag, 29606 sizeof reuseFlag); 29607 29608 ast_enable_packet_fragmentation(sipsock); 29609 29610 if (ast_bind(sipsock, &bindaddr) < 0) { 29611 ast_log(LOG_WARNING, "Failed to bind to %s: %s\n", 29612 ast_sockaddr_stringify(&bindaddr), strerror(errno)); 29613 close(sipsock); 29614 sipsock = -1; 29615 } else { 29616 ast_verb(2, "SIP Listening on %s\n", ast_sockaddr_stringify(&bindaddr)); 29617 ast_set_qos(sipsock, global_tos_sip, global_cos_sip, "SIP"); 29618 } 29619 } 29620 } else { 29621 ast_set_qos(sipsock, global_tos_sip, global_cos_sip, "SIP"); 29622 } 29623 ast_mutex_unlock(&netlock); 29624 29625 /* Start TCP server */ 29626 if (sip_cfg.tcp_enabled) { 29627 if (ast_sockaddr_isnull(&sip_tcp_desc.local_address)) { 29628 ast_sockaddr_copy(&sip_tcp_desc.local_address, &bindaddr); 29629 } 29630 if (!ast_sockaddr_port(&sip_tcp_desc.local_address)) { 29631 ast_sockaddr_set_port(&sip_tcp_desc.local_address, STANDARD_SIP_PORT); 29632 } 29633 } else { 29634 ast_sockaddr_setnull(&sip_tcp_desc.local_address); 29635 } 29636 ast_tcptls_server_start(&sip_tcp_desc); 29637 if (sip_cfg.tcp_enabled && sip_tcp_desc.accept_fd == -1) { 29638 /* TCP server start failed. Tell the admin */ 29639 ast_log(LOG_ERROR, "SIP TCP Server start failed. Not listening on TCP socket.\n"); 29640 } else { 29641 ast_debug(2, "SIP TCP server started\n"); 29642 } 29643 29644 /* Start TLS server if needed */ 29645 memcpy(sip_tls_desc.tls_cfg, &default_tls_cfg, sizeof(default_tls_cfg)); 29646 29647 if (ast_ssl_setup(sip_tls_desc.tls_cfg)) { 29648 if (ast_sockaddr_isnull(&sip_tls_desc.local_address)) { 29649 ast_sockaddr_copy(&sip_tls_desc.local_address, &bindaddr); 29650 ast_sockaddr_set_port(&sip_tls_desc.local_address, 29651 STANDARD_TLS_PORT); 29652 } 29653 if (!ast_sockaddr_port(&sip_tls_desc.local_address)) { 29654 ast_sockaddr_set_port(&sip_tls_desc.local_address, 29655 STANDARD_TLS_PORT); 29656 } 29657 ast_tcptls_server_start(&sip_tls_desc); 29658 if (default_tls_cfg.enabled && sip_tls_desc.accept_fd == -1) { 29659 ast_log(LOG_ERROR, "TLS Server start failed. Not listening on TLS socket.\n"); 29660 sip_tls_desc.tls_cfg = NULL; 29661 } 29662 } else if (sip_tls_desc.tls_cfg->enabled) { 29663 sip_tls_desc.tls_cfg = NULL; 29664 ast_log(LOG_WARNING, "SIP TLS server did not load because of errors.\n"); 29665 } 29666 29667 if (ucfg) { 29668 struct ast_variable *gen; 29669 int genhassip, genregistersip; 29670 const char *hassip, *registersip; 29671 29672 genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip")); 29673 genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip")); 29674 gen = ast_variable_browse(ucfg, "general"); 29675 cat = ast_category_browse(ucfg, NULL); 29676 while (cat) { 29677 if (strcasecmp(cat, "general")) { 29678 hassip = ast_variable_retrieve(ucfg, cat, "hassip"); 29679 registersip = ast_variable_retrieve(ucfg, cat, "registersip"); 29680 if (ast_true(hassip) || (!hassip && genhassip)) { 29681 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0, 0); 29682 if (peer) { 29683 /* user.conf entries are always of type friend */ 29684 peer->type = SIP_TYPE_USER | SIP_TYPE_PEER; 29685 ao2_t_link(peers, peer, "link peer into peer table"); 29686 if ((peer->type & SIP_TYPE_PEER) && !ast_sockaddr_isnull(&peer->addr)) { 29687 ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table"); 29688 } 29689 29690 unref_peer(peer, "unref_peer: from reload_config"); 29691 peer_count++; 29692 } 29693 } 29694 if (ast_true(registersip) || (!registersip && genregistersip)) { 29695 char tmp[256]; 29696 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 29697 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 29698 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 29699 const char *contact = ast_variable_retrieve(ucfg, cat, "contact"); 29700 const char *authuser = ast_variable_retrieve(ucfg, cat, "authuser"); 29701 if (!host) { 29702 host = ast_variable_retrieve(ucfg, "general", "host"); 29703 } 29704 if (!username) { 29705 username = ast_variable_retrieve(ucfg, "general", "username"); 29706 } 29707 if (!secret) { 29708 secret = ast_variable_retrieve(ucfg, "general", "secret"); 29709 } 29710 if (!contact) { 29711 contact = "s"; 29712 } 29713 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 29714 if (!ast_strlen_zero(secret)) { 29715 if (!ast_strlen_zero(authuser)) { 29716 snprintf(tmp, sizeof(tmp), "%s?%s:%s:%s@%s/%s", cat, username, secret, authuser, host, contact); 29717 } else { 29718 snprintf(tmp, sizeof(tmp), "%s?%s:%s@%s/%s", cat, username, secret, host, contact); 29719 } 29720 } else if (!ast_strlen_zero(authuser)) { 29721 snprintf(tmp, sizeof(tmp), "%s?%s::%s@%s/%s", cat, username, authuser, host, contact); 29722 } else { 29723 snprintf(tmp, sizeof(tmp), "%s?%s@%s/%s", cat, username, host, contact); 29724 } 29725 if (sip_register(tmp, 0) == 0) { 29726 registry_count++; 29727 } 29728 } 29729 } 29730 } 29731 cat = ast_category_browse(ucfg, cat); 29732 } 29733 ast_config_destroy(ucfg); 29734 } 29735 29736 /* Load peers, users and friends */ 29737 cat = NULL; 29738 while ( (cat = ast_category_browse(cfg, cat)) ) { 29739 const char *utype; 29740 if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication")) 29741 continue; 29742 utype = ast_variable_retrieve(cfg, cat, "type"); 29743 if (!utype) { 29744 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 29745 continue; 29746 } else { 29747 if (!strcasecmp(utype, "user")) { 29748 ; 29749 } else if (!strcasecmp(utype, "friend")) { 29750 ; 29751 } else if (!strcasecmp(utype, "peer")) { 29752 ; 29753 } else { 29754 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf"); 29755 continue; 29756 } 29757 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0, 0); 29758 if (peer) { 29759 display_nat_warning(cat, reason, &peer->flags[0]); 29760 ao2_t_link(peers, peer, "link peer into peers table"); 29761 if ((peer->type & SIP_TYPE_PEER) && !ast_sockaddr_isnull(&peer->addr)) { 29762 ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table"); 29763 } 29764 unref_peer(peer, "unref the result of the build_peer call. Now, the links from the tables are the only ones left."); 29765 peer_count++; 29766 } 29767 } 29768 } 29769 29770 /* Add default domains - host name, IP address and IP:port 29771 * Only do this if user added any sip domain with "localdomains" 29772 * In order to *not* break backwards compatibility 29773 * Some phones address us at IP only, some with additional port number 29774 */ 29775 if (auto_sip_domains) { 29776 char temp[MAXHOSTNAMELEN]; 29777 29778 /* First our default IP address */ 29779 if (!ast_sockaddr_isnull(&bindaddr) && !ast_sockaddr_is_any(&bindaddr)) { 29780 add_sip_domain(ast_sockaddr_stringify_addr(&bindaddr), 29781 SIP_DOMAIN_AUTO, NULL); 29782 } else if (!ast_sockaddr_isnull(&internip) && !ast_sockaddr_is_any(&internip)) { 29783 /* Our internal IP address, if configured */ 29784 add_sip_domain(ast_sockaddr_stringify_addr(&internip), 29785 SIP_DOMAIN_AUTO, NULL); 29786 } else { 29787 ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n"); 29788 } 29789 29790 /* If TCP is running on a different IP than UDP, then add it too */ 29791 if (!ast_sockaddr_isnull(&sip_tcp_desc.local_address) && 29792 !ast_sockaddr_cmp(&bindaddr, &sip_tcp_desc.local_address)) { 29793 add_sip_domain(ast_sockaddr_stringify_addr(&sip_tcp_desc.local_address), 29794 SIP_DOMAIN_AUTO, NULL); 29795 } 29796 29797 /* If TLS is running on a different IP than UDP and TCP, then add that too */ 29798 if (!ast_sockaddr_isnull(&sip_tls_desc.local_address) && 29799 !ast_sockaddr_cmp(&bindaddr, &sip_tls_desc.local_address) && 29800 !ast_sockaddr_cmp(&sip_tcp_desc.local_address, 29801 &sip_tls_desc.local_address)) { 29802 add_sip_domain(ast_sockaddr_stringify_addr(&sip_tcp_desc.local_address), 29803 SIP_DOMAIN_AUTO, NULL); 29804 } 29805 29806 /* Our extern IP address, if configured */ 29807 if (!ast_sockaddr_isnull(&externaddr)) { 29808 add_sip_domain(ast_sockaddr_stringify_addr(&externaddr), 29809 SIP_DOMAIN_AUTO, NULL); 29810 } 29811 29812 /* Extern host name (NAT traversal support) */ 29813 if (!ast_strlen_zero(externhost)) { 29814 add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL); 29815 } 29816 29817 /* Our host name */ 29818 if (!gethostname(temp, sizeof(temp))) { 29819 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 29820 } 29821 } 29822 29823 /* Release configuration from memory */ 29824 ast_config_destroy(cfg); 29825 29826 /* Load the list of manual NOTIFY types to support */ 29827 if (notify_types) 29828 ast_config_destroy(notify_types); 29829 if ((notify_types = ast_config_load(notify_config, config_flags)) == CONFIG_STATUS_FILEINVALID) { 29830 ast_log(LOG_ERROR, "Contents of %s are invalid and cannot be parsed.\n", notify_config); 29831 notify_types = NULL; 29832 } 29833 29834 /* Done, tell the manager */ 29835 manager_event(EVENT_FLAG_SYSTEM, "ChannelReload", "ChannelType: SIP\r\nReloadReason: %s\r\nRegistry_Count: %d\r\nPeer_Count: %d\r\n", channelreloadreason2txt(reason), registry_count, peer_count); 29836 run_end = time(0); 29837 ast_debug(4, "SIP reload_config done...Runtime= %d sec\n", (int)(run_end-run_start)); 29838 29839 return 0; 29840 }
| static char * remove_uri_parameters | ( | char * | uri | ) | [static] |
Definition at line 12299 of file chan_sip.c.
Referenced by extract_uri(), parse_moved_contact(), register_verify(), reqprep(), and transmit_state_notify().
12300 { 12301 char *atsign; 12302 atsign = strchr(uri, '@'); /* First, locate the at sign */ 12303 if (!atsign) { 12304 atsign = uri; /* Ok hostname only, let's stick with the rest */ 12305 } 12306 atsign = strchr(atsign, ';'); /* Locate semi colon */ 12307 if (atsign) 12308 *atsign = '\0'; /* Kill at the semi colon */ 12309 return uri; 12310 }
| static int reply_digest | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| char * | header, | |||
| int | sipmethod, | |||
| char * | digest, | |||
| int | digest_len | |||
| ) | [static] |
reply to authentication for outbound registrations
Definition at line 19848 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_skip_blanks(), ast_string_field_ptr_set, ast_string_field_set, ast_strlen_zero(), build_reply_digest(), get_header(), and LOG_WARNING.
Referenced by do_proxy_auth(), and do_register_auth().
19849 { 19850 char tmp[512]; 19851 char *c; 19852 char oldnonce[256]; 19853 19854 /* table of recognised keywords, and places where they should be copied */ 19855 const struct x { 19856 const char *key; 19857 const ast_string_field *field; 19858 } *i, keys[] = { 19859 { "realm=", &p->realm }, 19860 { "nonce=", &p->nonce }, 19861 { "opaque=", &p->opaque }, 19862 { "qop=", &p->qop }, 19863 { "domain=", &p->domain }, 19864 { NULL, 0 }, 19865 }; 19866 19867 ast_copy_string(tmp, get_header(req, header), sizeof(tmp)); 19868 if (ast_strlen_zero(tmp)) 19869 return -1; 19870 if (strncasecmp(tmp, "Digest ", strlen("Digest "))) { 19871 ast_log(LOG_WARNING, "missing Digest.\n"); 19872 return -1; 19873 } 19874 c = tmp + strlen("Digest "); 19875 ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce)); 19876 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 19877 for (i = keys; i->key != NULL; i++) { 19878 char *src, *separator; 19879 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 19880 continue; 19881 /* Found. Skip keyword, take text in quotes or up to the separator. */ 19882 c += strlen(i->key); 19883 if (*c == '"') { 19884 src = ++c; 19885 separator = "\""; 19886 } else { 19887 src = c; 19888 separator = ","; 19889 } 19890 strsep(&c, separator); /* clear separator and move ptr */ 19891 ast_string_field_ptr_set(p, i->field, src); 19892 break; 19893 } 19894 if (i->key == NULL) /* not found, try ',' */ 19895 strsep(&c, ","); 19896 } 19897 /* Reset nonce count */ 19898 if (strcmp(p->nonce, oldnonce)) 19899 p->noncecount = 0; 19900 19901 /* Save auth data for following registrations */ 19902 if (p->registry) { 19903 struct sip_registry *r = p->registry; 19904 19905 if (strcmp(r->nonce, p->nonce)) { 19906 ast_string_field_set(r, realm, p->realm); 19907 ast_string_field_set(r, nonce, p->nonce); 19908 ast_string_field_set(r, authdomain, p->domain); 19909 ast_string_field_set(r, opaque, p->opaque); 19910 ast_string_field_set(r, qop, p->qop); 19911 r->noncecount = 0; 19912 } 19913 } 19914 return build_reply_digest(p, sipmethod, digest, digest_len); 19915 }
| static int reqprep | ( | struct sip_request * | req, | |
| struct sip_pvt * | p, | |||
| int | sipmethod, | |||
| uint32_t | seqno, | |||
| int | newbranch | |||
| ) | [static] |
Initialize a SIP request message (not the initial one in a dialog).
< Strict routing flag
Definition at line 10706 of file chan_sip.c.
References add_header(), add_header_max_forwards(), add_route(), ast_copy_string(), ast_debug, ast_random(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, build_via(), copy_header(), FALSE, get_header(), get_in_brackets(), init_req(), remove_uri_parameters(), set_destination(), sip_methods, st_get_se(), text, cfsip_methods::text, TRUE, and url.
Referenced by transmit_cc_notify(), transmit_info_with_aoc(), transmit_info_with_digit(), transmit_info_with_vidupdate(), transmit_invite(), transmit_message_with_text(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), transmit_state_notify(), and update_connectedline().
10707 { 10708 struct sip_request *orig = &p->initreq; 10709 char stripped[80]; 10710 char tmp[80]; 10711 char newto[256]; 10712 const char *c; 10713 const char *ot, *of; 10714 int is_strict = FALSE; /*!< Strict routing flag */ 10715 int is_outbound = ast_test_flag(&p->flags[0], SIP_OUTGOING); /* Session direction */ 10716 10717 snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text); 10718 10719 if (!seqno) { 10720 p->ocseq++; 10721 seqno = p->ocseq; 10722 } 10723 10724 /* A CANCEL must have the same branch as the INVITE that it is canceling. */ 10725 if (sipmethod == SIP_CANCEL) { 10726 p->branch = p->invite_branch; 10727 build_via(p); 10728 } else if (newbranch && (sipmethod == SIP_INVITE)) { 10729 p->branch ^= ast_random(); 10730 p->invite_branch = p->branch; 10731 build_via(p); 10732 } else if (newbranch) { 10733 p->branch ^= ast_random(); 10734 build_via(p); 10735 } 10736 10737 /* Check for strict or loose router */ 10738 if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop, ";lr") == NULL) { 10739 is_strict = TRUE; 10740 if (sipdebug) 10741 ast_debug(1, "Strict routing enforced for session %s\n", p->callid); 10742 } 10743 10744 if (sipmethod == SIP_CANCEL) 10745 c = REQ_OFFSET_TO_STR(&p->initreq, rlPart2); /* Use original URI */ 10746 else if (sipmethod == SIP_ACK) { 10747 /* Use URI from Contact: in 200 OK (if INVITE) 10748 (we only have the contacturi on INVITEs) */ 10749 if (!ast_strlen_zero(p->okcontacturi)) 10750 c = is_strict ? p->route->hop : p->okcontacturi; 10751 else 10752 c = REQ_OFFSET_TO_STR(&p->initreq, rlPart2); 10753 } else if (!ast_strlen_zero(p->okcontacturi)) 10754 c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */ 10755 else if (!ast_strlen_zero(p->uri)) 10756 c = p->uri; 10757 else { 10758 char *n; 10759 /* We have no URI, use To: or From: header as URI (depending on direction) */ 10760 ast_copy_string(stripped, get_header(orig, is_outbound ? "To" : "From"), 10761 sizeof(stripped)); 10762 n = get_in_brackets(stripped); 10763 c = remove_uri_parameters(n); 10764 } 10765 init_req(req, sipmethod, c); 10766 10767 snprintf(tmp, sizeof(tmp), "%u %s", seqno, sip_methods[sipmethod].text); 10768 10769 add_header(req, "Via", p->via); 10770 /* 10771 * Use the learned route set unless this is a CANCEL on an ACK for a non-2xx 10772 * final response. For a CANCEL or ACK, we have to send to the same destination 10773 * as the original INVITE. 10774 */ 10775 if (p->route && 10776 !(sipmethod == SIP_CANCEL || 10777 (sipmethod == SIP_ACK && (p->invitestate == INV_COMPLETED || p->invitestate == INV_CANCELLED)))) { 10778 set_destination(p, p->route->hop); 10779 add_route(req, is_strict ? p->route->next : p->route); 10780 } 10781 add_header_max_forwards(p, req); 10782 10783 ot = get_header(orig, "To"); 10784 of = get_header(orig, "From"); 10785 10786 /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly 10787 as our original request, including tag (or presumably lack thereof) */ 10788 if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) { 10789 /* Add the proper tag if we don't have it already. If they have specified 10790 their tag, use it. Otherwise, use our own tag */ 10791 if (is_outbound && !ast_strlen_zero(p->theirtag)) 10792 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 10793 else if (!is_outbound) 10794 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 10795 else 10796 snprintf(newto, sizeof(newto), "%s", ot); 10797 ot = newto; 10798 } 10799 10800 if (is_outbound) { 10801 add_header(req, "From", of); 10802 add_header(req, "To", ot); 10803 } else { 10804 add_header(req, "From", ot); 10805 add_header(req, "To", of); 10806 } 10807 /* Do not add Contact for MESSAGE, BYE and Cancel requests */ 10808 if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE) 10809 add_header(req, "Contact", p->our_contact); 10810 10811 copy_header(req, orig, "Call-ID"); 10812 add_header(req, "CSeq", tmp); 10813 10814 if (!ast_strlen_zero(global_useragent)) 10815 add_header(req, "User-Agent", global_useragent); 10816 10817 if (!ast_strlen_zero(p->url)) { 10818 add_header(req, "Access-URL", p->url); 10819 ast_string_field_set(p, url, NULL); 10820 } 10821 10822 /* Add Session-Timers related headers if the feature is active for this session. 10823 An exception to this behavior is the ACK request. Since Asterisk never requires 10824 session-timers support from a remote end-point (UAS) in an INVITE, it must 10825 not send 'Require: timer' header in the ACK request. 10826 This should only be added in the INVITE transactions, not MESSAGE or REFER or other 10827 in-dialog messages. 10828 */ 10829 if (p->stimer && p->stimer->st_active == TRUE && p->stimer->st_active_peer_ua == TRUE 10830 && sipmethod == SIP_INVITE) { 10831 char se_hdr[256]; 10832 snprintf(se_hdr, sizeof(se_hdr), "%d;refresher=%s", p->stimer->st_interval, 10833 p->stimer->st_ref == SESSION_TIMER_REFRESHER_US ? "uac" : "uas"); 10834 add_header(req, "Session-Expires", se_hdr); 10835 snprintf(se_hdr, sizeof(se_hdr), "%d", st_get_se(p, FALSE)); 10836 add_header(req, "Min-SE", se_hdr); 10837 } 10838 10839 return 0; 10840 }
| static int resp_needs_contact | ( | const char * | msg, | |
| enum sipmethod | method | |||
| ) | [inline, static] |
Test if this response needs a contact header.
Definition at line 10554 of file chan_sip.c.
Referenced by respprep().
10554 { 10555 /* Requirements for Contact header inclusion in responses generated 10556 * from the header tables found in the following RFCs. Where the 10557 * Contact header was marked mandatory (m) or optional (o) this 10558 * function returns 1. 10559 * 10560 * - RFC 3261 (ACK, BYE, CANCEL, INVITE, OPTIONS, REGISTER) 10561 * - RFC 2976 (INFO) 10562 * - RFC 3262 (PRACK) 10563 * - RFC 3265 (SUBSCRIBE, NOTIFY) 10564 * - RFC 3311 (UPDATE) 10565 * - RFC 3428 (MESSAGE) 10566 * - RFC 3515 (REFER) 10567 * - RFC 3903 (PUBLISH) 10568 */ 10569 10570 switch (method) { 10571 /* 1xx, 2xx, 3xx, 485 */ 10572 case SIP_INVITE: 10573 case SIP_UPDATE: 10574 case SIP_SUBSCRIBE: 10575 case SIP_NOTIFY: 10576 if ((msg[0] >= '1' && msg[0] <= '3') || !strncmp(msg, "485", 3)) 10577 return 1; 10578 break; 10579 10580 /* 2xx, 3xx, 485 */ 10581 case SIP_REGISTER: 10582 case SIP_OPTIONS: 10583 if (msg[0] == '2' || msg[0] == '3' || !strncmp(msg, "485", 3)) 10584 return 1; 10585 break; 10586 10587 /* 3xx, 485 */ 10588 case SIP_BYE: 10589 case SIP_PRACK: 10590 case SIP_MESSAGE: 10591 case SIP_PUBLISH: 10592 if (msg[0] == '3' || !strncmp(msg, "485", 3)) 10593 return 1; 10594 break; 10595 10596 /* 2xx, 3xx, 4xx, 5xx, 6xx */ 10597 case SIP_REFER: 10598 if (msg[0] >= '2' && msg[0] <= '6') 10599 return 1; 10600 break; 10601 10602 /* contact will not be included for everything else */ 10603 case SIP_ACK: 10604 case SIP_CANCEL: 10605 case SIP_INFO: 10606 case SIP_PING: 10607 default: 10608 return 0; 10609 } 10610 return 0; 10611 }
| static int respprep | ( | struct sip_request * | resp, | |
| struct sip_pvt * | p, | |||
| const char * | msg, | |||
| const struct sip_request * | req | |||
| ) | [static] |
Prepare SIP response packet.
Definition at line 10614 of file chan_sip.c.
References add_header(), add_supported_header(), ast_copy_string(), ast_log(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, copy_all_header(), copy_header(), copy_via_headers(), get_header(), init_resp(), LOG_WARNING, process_via(), resp_needs_contact(), TRUE, and url.
Referenced by __transmit_response(), transmit_response_with_allow(), transmit_response_with_auth(), transmit_response_with_date(), transmit_response_with_minexpires(), transmit_response_with_minse(), transmit_response_with_retry_after(), transmit_response_with_sdp(), transmit_response_with_sip_etag(), transmit_response_with_t38_sdp(), transmit_response_with_unsupported(), update_connectedline(), and update_redirecting().
10615 { 10616 char newto[256]; 10617 const char *ot; 10618 10619 init_resp(resp, msg); 10620 copy_via_headers(p, resp, req, "Via"); 10621 if (msg[0] == '1' || msg[0] == '2') 10622 copy_all_header(resp, req, "Record-Route"); 10623 copy_header(resp, req, "From"); 10624 ot = get_header(req, "To"); 10625 if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) { 10626 /* Add the proper tag if we don't have it already. If they have specified 10627 their tag, use it. Otherwise, use our own tag */ 10628 if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING)) 10629 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 10630 else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) 10631 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 10632 else 10633 ast_copy_string(newto, ot, sizeof(newto)); 10634 ot = newto; 10635 } 10636 add_header(resp, "To", ot); 10637 copy_header(resp, req, "Call-ID"); 10638 copy_header(resp, req, "CSeq"); 10639 if (!ast_strlen_zero(global_useragent)) 10640 add_header(resp, "Server", global_useragent); 10641 add_header(resp, "Allow", ALLOWED_METHODS); 10642 add_supported_header(p, resp); 10643 10644 /* If this is an invite, add Session-Timers related headers if the feature is active for this session */ 10645 if (p->method == SIP_INVITE && p->stimer && p->stimer->st_active == TRUE) { 10646 char se_hdr[256]; 10647 snprintf(se_hdr, sizeof(se_hdr), "%d;refresher=%s", p->stimer->st_interval, 10648 p->stimer->st_ref == SESSION_TIMER_REFRESHER_US ? "uas" : "uac"); 10649 add_header(resp, "Session-Expires", se_hdr); 10650 /* RFC 2048, Section 9 10651 * If the refresher parameter in the Session-Expires header field in the 10652 * 2xx response has a value of 'uac', the UAS MUST place a Require 10653 * header field into the response with the value 'timer'. 10654 * ... 10655 * If the refresher parameter in 10656 * the 2xx response has a value of 'uas' and the Supported header field 10657 * in the request contained the value 'timer', the UAS SHOULD place a 10658 * Require header field into the response with the value 'timer' 10659 */ 10660 if (p->stimer->st_ref == SESSION_TIMER_REFRESHER_THEM || 10661 (p->stimer->st_ref == SESSION_TIMER_REFRESHER_US && 10662 p->stimer->st_active_peer_ua == TRUE)) { 10663 resp->reqsipoptions |= SIP_OPT_TIMER; 10664 } 10665 } 10666 10667 if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_PUBLISH)) { 10668 /* For registration responses, we also need expiry and 10669 contact info */ 10670 char tmp[256]; 10671 10672 snprintf(tmp, sizeof(tmp), "%d", p->expiry); 10673 add_header(resp, "Expires", tmp); 10674 if (p->expiry) { /* Only add contact if we have an expiry time */ 10675 char contact[SIPBUFSIZE]; 10676 const char *contact_uri = p->method == SIP_SUBSCRIBE ? p->our_contact : p->fullcontact; 10677 char *brackets = strchr(contact_uri, '<'); 10678 snprintf(contact, sizeof(contact), "%s%s%s;expires=%d", brackets ? "" : "<", contact_uri, brackets ? "" : ">", p->expiry); 10679 add_header(resp, "Contact", contact); /* Not when we unregister */ 10680 } 10681 } else if (!ast_strlen_zero(p->our_contact) && resp_needs_contact(msg, p->method)) { 10682 add_header(resp, "Contact", p->our_contact); 10683 } 10684 10685 if (!ast_strlen_zero(p->url)) { 10686 add_header(resp, "Access-URL", p->url); 10687 ast_string_field_set(p, url, NULL); 10688 } 10689 10690 /* default to routing the response to the address where the request 10691 * came from. Since we don't have a transport layer, we do this here. 10692 * The process_via() function will update the port to either the port 10693 * specified in the via header or the default port later on (per RFC 10694 * 3261 section 18.2.2). 10695 */ 10696 p->sa = p->recv; 10697 10698 if (process_via(p, req)) { 10699 ast_log(LOG_WARNING, "error processing via header, will send response to originating address\n"); 10700 } 10701 10702 return 0; 10703 }
| static int restart_monitor | ( | void | ) | [static] |
Start the channel monitor thread.
Definition at line 26693 of file chan_sip.c.
References ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_pthread_create_background, AST_PTHREADT_NULL, AST_PTHREADT_STOP, do_monitor(), LOG_ERROR, and LOG_WARNING.
Referenced by load_module(), sip_reload(), and sip_request_call().
26694 { 26695 /* If we're supposed to be stopped -- stay stopped */ 26696 if (monitor_thread == AST_PTHREADT_STOP) 26697 return 0; 26698 ast_mutex_lock(&monlock); 26699 if (monitor_thread == pthread_self()) { 26700 ast_mutex_unlock(&monlock); 26701 ast_log(LOG_WARNING, "Cannot kill myself\n"); 26702 return -1; 26703 } 26704 if (monitor_thread != AST_PTHREADT_NULL) { 26705 /* Wake up the thread */ 26706 pthread_kill(monitor_thread, SIGURG); 26707 } else { 26708 /* Start a new monitor */ 26709 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 26710 ast_mutex_unlock(&monlock); 26711 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 26712 return -1; 26713 } 26714 } 26715 ast_mutex_unlock(&monlock); 26716 return 0; 26717 }
| static void restart_session_timer | ( | struct sip_pvt * | p | ) | [static] |
Session-Timers: Restart session timer.
Definition at line 26721 of file chan_sip.c.
References ast_debug, AST_SCHED_DEL_UNREF, start_session_timer(), and TRUE.
Referenced by handle_request_invite().
26722 { 26723 if (p->stimer->st_active == TRUE) { 26724 ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid); 26725 AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid, 26726 dialog_unref(p, "Removing session timer ref")); 26727 start_session_timer(p); 26728 } 26729 }
| static int retrans_pkt | ( | const void * | data | ) | [static] |
Retransmit SIP message if no answer (Called from scheduler).
Definition at line 3739 of file chan_sip.c.
References __sip_xmit(), append_history, AST_CAUSE_NO_USER_RESPONSE, ast_channel_trylock, ast_channel_unlock, ast_debug, ast_free, ast_log(), ast_queue_hangup_with_cause(), ast_sockaddr_stringify(), ast_str_buffer(), ast_test_flag, ast_tvdiff_ms(), ast_tvnow(), ast_verbose, DEFAULT_RETRANS, LOG_WARNING, pvt_set_needdestroy(), sip_alreadygone(), sip_debug_test_pvt(), sip_methods, sip_nat_mode(), sip_pvt_lock, sip_pvt_unlock, sip_real_dst(), cfsip_methods::text, and UNLINK.
Referenced by __sip_reliable_xmit(), and sip_show_sched().
03740 { 03741 struct sip_pkt *pkt = (struct sip_pkt *)data, *prev, *cur = NULL; 03742 int reschedule = DEFAULT_RETRANS; 03743 int xmitres = 0; 03744 /* how many ms until retrans timeout is reached */ 03745 int64_t diff = pkt->retrans_stop_time - ast_tvdiff_ms(ast_tvnow(), pkt->time_sent); 03746 03747 /* Do not retransmit if time out is reached. This will be negative if the time between 03748 * the first transmission and now is larger than our timeout period. This is a fail safe 03749 * check in case the scheduler gets behind or the clock is changed. */ 03750 if ((diff <= 0) || (diff > pkt->retrans_stop_time)) { 03751 pkt->retrans_stop = 1; 03752 } 03753 03754 /* Lock channel PVT */ 03755 sip_pvt_lock(pkt->owner); 03756 03757 if (!pkt->retrans_stop) { 03758 pkt->retrans++; 03759 if (!pkt->timer_t1) { /* Re-schedule using timer_a and timer_t1 */ 03760 if (sipdebug) { 03761 ast_debug(4, "SIP TIMER: Not rescheduling id #%d:%s (Method %d) (No timer T1)\n", 03762 pkt->retransid, 03763 sip_methods[pkt->method].text, 03764 pkt->method); 03765 } 03766 } else { 03767 int siptimer_a; 03768 03769 if (sipdebug) { 03770 ast_debug(4, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", 03771 pkt->retransid, 03772 pkt->retrans, 03773 sip_methods[pkt->method].text, 03774 pkt->method); 03775 } 03776 if (!pkt->timer_a) { 03777 pkt->timer_a = 2 ; 03778 } else { 03779 pkt->timer_a = 2 * pkt->timer_a; 03780 } 03781 03782 /* For non-invites, a maximum of 4 secs */ 03783 siptimer_a = pkt->timer_t1 * pkt->timer_a; /* Double each time */ 03784 if (pkt->method != SIP_INVITE && siptimer_a > 4000) { 03785 siptimer_a = 4000; 03786 } 03787 03788 /* Reschedule re-transmit */ 03789 reschedule = siptimer_a; 03790 ast_debug(4, "** SIP timers: Rescheduling retransmission %d to %d ms (t1 %d ms (Retrans id #%d)) \n", 03791 pkt->retrans + 1, 03792 siptimer_a, 03793 pkt->timer_t1, 03794 pkt->retransid); 03795 } 03796 03797 if (sip_debug_test_pvt(pkt->owner)) { 03798 const struct ast_sockaddr *dst = sip_real_dst(pkt->owner); 03799 ast_verbose("Retransmitting #%d (%s) to %s:\n%s\n---\n", 03800 pkt->retrans, sip_nat_mode(pkt->owner), 03801 ast_sockaddr_stringify(dst), 03802 ast_str_buffer(pkt->data)); 03803 } 03804 03805 append_history(pkt->owner, "ReTx", "%d %s", reschedule, ast_str_buffer(pkt->data)); 03806 xmitres = __sip_xmit(pkt->owner, pkt->data); 03807 03808 /* If there was no error during the network transmission, schedule the next retransmission, 03809 * but if the next retransmission is going to be beyond our timeout period, mark the packet's 03810 * stop_retrans value and set the next retransmit to be the exact time of timeout. This will 03811 * allow any responses to the packet to be processed before the packet is destroyed on the next 03812 * call to this function by the scheduler. */ 03813 if (xmitres != XMIT_ERROR) { 03814 if (reschedule >= diff) { 03815 pkt->retrans_stop = 1; 03816 reschedule = diff; 03817 } 03818 sip_pvt_unlock(pkt->owner); 03819 return reschedule; 03820 } 03821 } 03822 03823 /* At this point, either the packet's retransmission timed out, or there was a 03824 * transmission error, either way destroy the scheduler item and this packet. */ 03825 03826 pkt->retransid = -1; /* Kill this scheduler item */ 03827 03828 if (pkt->method != SIP_OPTIONS && xmitres == 0) { 03829 if (pkt->is_fatal || sipdebug) { /* Tell us if it's critical or if we're debugging */ 03830 ast_log(LOG_WARNING, "Retransmission timeout reached on transmission %s for seqno %u (%s %s) -- See https://wiki.asterisk.org/wiki/display/AST/SIP+Retransmissions\n" 03831 "Packet timed out after %dms with no response\n", 03832 pkt->owner->callid, 03833 pkt->seqno, 03834 pkt->is_fatal ? "Critical" : "Non-critical", 03835 pkt->is_resp ? "Response" : "Request", 03836 (int) ast_tvdiff_ms(ast_tvnow(), pkt->time_sent)); 03837 } 03838 } else if (pkt->method == SIP_OPTIONS && sipdebug) { 03839 ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s) -- See https://wiki.asterisk.org/wiki/display/AST/SIP+Retransmissions\n", pkt->owner->callid); 03840 } 03841 03842 if (xmitres == XMIT_ERROR) { 03843 ast_log(LOG_WARNING, "Transmit error :: Cancelling transmission on Call ID %s\n", pkt->owner->callid); 03844 append_history(pkt->owner, "XmitErr", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)"); 03845 } else { 03846 append_history(pkt->owner, "MaxRetries", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)"); 03847 } 03848 03849 if (pkt->is_fatal) { 03850 while(pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) { 03851 sip_pvt_unlock(pkt->owner); /* SIP_PVT, not channel */ 03852 usleep(1); 03853 sip_pvt_lock(pkt->owner); 03854 } 03855 if (pkt->owner->owner && !pkt->owner->owner->hangupcause) { 03856 pkt->owner->owner->hangupcause = AST_CAUSE_NO_USER_RESPONSE; 03857 } 03858 if (pkt->owner->owner) { 03859 ast_log(LOG_WARNING, "Hanging up call %s - no reply to our critical packet (see https://wiki.asterisk.org/wiki/display/AST/SIP+Retransmissions).\n", pkt->owner->callid); 03860 03861 if (pkt->is_resp && 03862 (pkt->response_code >= 200) && 03863 (pkt->response_code < 300) && 03864 pkt->owner->pendinginvite && 03865 ast_test_flag(&pkt->owner->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) { 03866 /* This is a timeout of the 2XX response to a pending INVITE. In this case terminate the INVITE 03867 * transaction just as if we received the ACK, but immediately hangup with a BYE (sip_hangup 03868 * will send the BYE as long as the dialog is not set as "alreadygone") 03869 * RFC 3261 section 13.3.1.4. 03870 * "If the server retransmits the 2xx response for 64*T1 seconds without receiving 03871 * an ACK, the dialog is confirmed, but the session SHOULD be terminated. This is 03872 * accomplished with a BYE, as described in Section 15." */ 03873 pkt->owner->invitestate = INV_TERMINATED; 03874 pkt->owner->pendinginvite = 0; 03875 } else { 03876 /* there is nothing left to do, mark the dialog as gone */ 03877 sip_alreadygone(pkt->owner); 03878 } 03879 ast_queue_hangup_with_cause(pkt->owner->owner, AST_CAUSE_NO_USER_RESPONSE); 03880 ast_channel_unlock(pkt->owner->owner); 03881 } else { 03882 /* If no channel owner, destroy now */ 03883 03884 /* Let the peerpoke system expire packets when the timer expires for poke_noanswer */ 03885 if (pkt->method != SIP_OPTIONS && pkt->method != SIP_REGISTER) { 03886 pvt_set_needdestroy(pkt->owner, "no response to critical packet"); 03887 sip_alreadygone(pkt->owner); 03888 append_history(pkt->owner, "DialogKill", "Killing this failed dialog immediately"); 03889 } 03890 } 03891 } 03892 03893 if (pkt->method == SIP_BYE) { 03894 /* We're not getting answers on SIP BYE's. Tear down the call anyway. */ 03895 sip_alreadygone(pkt->owner); 03896 if (pkt->owner->owner) { 03897 ast_channel_unlock(pkt->owner->owner); 03898 } 03899 append_history(pkt->owner, "ByeFailure", "Remote peer doesn't respond to bye. Destroying call anyway."); 03900 pvt_set_needdestroy(pkt->owner, "no response to BYE"); 03901 } 03902 03903 /* Remove the packet */ 03904 for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) { 03905 if (cur == pkt) { 03906 UNLINK(cur, pkt->owner->packets, prev); 03907 sip_pvt_unlock(pkt->owner); 03908 if (pkt->owner) { 03909 pkt->owner = dialog_unref(pkt->owner,"pkt is being freed, its dialog ref is dead now"); 03910 } 03911 if (pkt->data) { 03912 ast_free(pkt->data); 03913 } 03914 pkt->data = NULL; 03915 ast_free(pkt); 03916 return 0; 03917 } 03918 } 03919 /* error case */ 03920 ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n"); 03921 sip_pvt_unlock(pkt->owner); 03922 return 0; 03923 }
| static int send_provisional_keepalive | ( | const void * | data | ) | [static] |
Definition at line 4331 of file chan_sip.c.
References send_provisional_keepalive_full().
Referenced by update_provisional_keepalive().
04331 { 04332 struct sip_pvt *pvt = (struct sip_pvt *) data; 04333 04334 return send_provisional_keepalive_full(pvt, 0); 04335 }
| static int send_provisional_keepalive_full | ( | struct sip_pvt * | pvt, | |
| int | with_sdp | |||
| ) | [static] |
Definition at line 4281 of file chan_sip.c.
References ast_channel_unlock, ast_channel_unref, FALSE, S_OR, sip_pvt_lock_full(), sip_pvt_unlock, transmit_response(), and transmit_response_with_sdp().
Referenced by send_provisional_keepalive(), and send_provisional_keepalive_with_sdp().
04282 { 04283 const char *msg = NULL; 04284 struct ast_channel *chan; 04285 int res = 0; 04286 int old_sched_id = pvt->provisional_keepalive_sched_id; 04287 04288 chan = sip_pvt_lock_full(pvt); 04289 /* Check that nothing has changed while we were waiting for the lock */ 04290 if (old_sched_id != pvt->provisional_keepalive_sched_id) { 04291 /* Keepalive has been cancelled or rescheduled, clean up and leave */ 04292 if (chan) { 04293 ast_channel_unlock(chan); 04294 chan = ast_channel_unref(chan); 04295 } 04296 sip_pvt_unlock(pvt); 04297 dialog_unref(pvt, "dialog ref for provisional keepalive"); 04298 return 0; 04299 } 04300 04301 if (!pvt->last_provisional || !strncasecmp(pvt->last_provisional, "100", 3)) { 04302 msg = "183 Session Progress"; 04303 } 04304 04305 if (pvt->invitestate < INV_COMPLETED) { 04306 if (with_sdp) { 04307 transmit_response_with_sdp(pvt, S_OR(msg, pvt->last_provisional), &pvt->initreq, XMIT_UNRELIABLE, FALSE, FALSE); 04308 } else { 04309 transmit_response(pvt, S_OR(msg, pvt->last_provisional), &pvt->initreq); 04310 } 04311 res = PROVIS_KEEPALIVE_TIMEOUT; 04312 } 04313 04314 if (chan) { 04315 ast_channel_unlock(chan); 04316 chan = ast_channel_unref(chan); 04317 } 04318 04319 if (!res) { 04320 pvt->provisional_keepalive_sched_id = -1; 04321 } 04322 04323 sip_pvt_unlock(pvt); 04324 04325 if (!res) { 04326 dialog_unref(pvt, "dialog ref for provisional keepalive"); 04327 } 04328 return res; 04329 }
| static int send_provisional_keepalive_with_sdp | ( | const void * | data | ) | [static] |
Definition at line 4337 of file chan_sip.c.
References send_provisional_keepalive_full().
Referenced by update_provisional_keepalive().
04337 { 04338 struct sip_pvt *pvt = (void *)data; 04339 04340 return send_provisional_keepalive_full(pvt, 1); 04341 }
| static int send_request | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| enum xmittype | reliable, | |||
| uint32_t | seqno | |||
| ) | [static] |
Definition at line 4422 of file chan_sip.c.
References __sip_reliable_xmit(), __sip_xmit(), add_blank(), append_history, ast_sockaddr_stringify(), ast_str_buffer(), ast_test_flag, ast_verbose, deinit_req(), finalize_content(), get_header(), parse_copy(), sip_debug_test_pvt(), sip_methods, and cfsip_methods::text.
Referenced by transmit_cc_notify(), transmit_info_with_aoc(), transmit_info_with_digit(), transmit_info_with_vidupdate(), transmit_invite(), transmit_message_with_text(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_register(), transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), transmit_state_notify(), and update_connectedline().
04423 { 04424 int res; 04425 04426 /* If we have an outbound proxy, reset peer address 04427 Only do this once. 04428 */ 04429 if (p->outboundproxy) { 04430 p->sa = p->outboundproxy->ip; 04431 } 04432 04433 finalize_content(req); 04434 add_blank(req); 04435 if (sip_debug_test_pvt(p)) { 04436 if (ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT)) { 04437 ast_verbose("%sTransmitting (NAT) to %s:\n%s\n---\n", reliable ? "Reliably " : "", ast_sockaddr_stringify(&p->recv), ast_str_buffer(req->data)); 04438 } else { 04439 ast_verbose("%sTransmitting (no NAT) to %s:\n%s\n---\n", reliable ? "Reliably " : "", ast_sockaddr_stringify(&p->sa), ast_str_buffer(req->data)); 04440 } 04441 } 04442 if (p->do_history) { 04443 struct sip_request tmp = { .rlPart1 = 0, }; 04444 parse_copy(&tmp, req); 04445 append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", ast_str_buffer(tmp.data), get_header(&tmp, "CSeq"), sip_methods[tmp.method].text); 04446 deinit_req(&tmp); 04447 } 04448 res = (reliable) ? 04449 __sip_reliable_xmit(p, seqno, 0, req->data, (reliable == XMIT_CRITICAL), req->method) : 04450 __sip_xmit(p, req->data); 04451 deinit_req(req); 04452 return res; 04453 }
| static int send_response | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| enum xmittype | reliable, | |||
| uint32_t | seqno | |||
| ) | [static] |
Transmit response on SIP request.
Definition at line 4380 of file chan_sip.c.
References __sip_reliable_xmit(), __sip_xmit(), add_blank(), append_history, AST_SCHED_DEL_UNREF, ast_sockaddr_stringify(), ast_str_buffer(), ast_verbose, deinit_req(), finalize_content(), get_header(), parse_copy(), sip_debug_test_pvt(), sip_methods, sip_nat_mode(), sip_real_dst(), and cfsip_methods::text.
Referenced by __transmit_response(), transmit_response_with_allow(), transmit_response_with_auth(), transmit_response_with_date(), transmit_response_with_minexpires(), transmit_response_with_minse(), transmit_response_with_retry_after(), transmit_response_with_sdp(), transmit_response_with_sip_etag(), transmit_response_with_t38_sdp(), transmit_response_with_unsupported(), update_connectedline(), and update_redirecting().
04381 { 04382 int res; 04383 04384 finalize_content(req); 04385 add_blank(req); 04386 if (sip_debug_test_pvt(p)) { 04387 const struct ast_sockaddr *dst = sip_real_dst(p); 04388 04389 ast_verbose("\n<--- %sTransmitting (%s) to %s --->\n%s\n<------------>\n", 04390 reliable ? "Reliably " : "", sip_nat_mode(p), 04391 ast_sockaddr_stringify(dst), 04392 ast_str_buffer(req->data)); 04393 } 04394 if (p->do_history) { 04395 struct sip_request tmp = { .rlPart1 = 0, }; 04396 parse_copy(&tmp, req); 04397 append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", ast_str_buffer(tmp.data), get_header(&tmp, "CSeq"), 04398 (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? REQ_OFFSET_TO_STR(&tmp, rlPart2) : sip_methods[tmp.method].text); 04399 deinit_req(&tmp); 04400 } 04401 04402 /* If we are sending a final response to an INVITE, stop retransmitting provisional responses */ 04403 if (p->initreq.method == SIP_INVITE && reliable == XMIT_CRITICAL) { 04404 AST_SCHED_DEL_UNREF(sched, p->provisional_keepalive_sched_id, dialog_unref(p, "when you delete the provisional_keepalive_sched_id, you should dec the refcount for the stored dialog ptr")); 04405 } 04406 04407 res = (reliable) ? 04408 __sip_reliable_xmit(p, seqno, 1, req->data, (reliable == XMIT_CRITICAL), req->method) : 04409 __sip_xmit(p, req->data); 04410 deinit_req(req); 04411 if (res > 0) { 04412 return 0; 04413 } 04414 return res; 04415 }
| static enum ast_cc_service_type service_string_to_service_type | ( | const char *const | service_string | ) | [static] |
Definition at line 830 of file chan_sip.c.
References AST_CC_CCBS, AST_CC_CCNL, AST_CC_NONE, service, and sip_cc_service_map.
Referenced by sip_get_cc_information().
00831 { 00832 enum ast_cc_service_type service; 00833 for (service = AST_CC_CCBS; service <= AST_CC_CCNL; ++service) { 00834 if (!strcasecmp(service_string, sip_cc_service_map[service].service_string)) { 00835 return service; 00836 } 00837 } 00838 return AST_CC_NONE; 00839 }
| static int set_address_from_contact | ( | struct sip_pvt * | pvt | ) | [static] |
Change the other partys IP address based on given contact.
Definition at line 14448 of file chan_sip.c.
References __set_address_from_contact(), and ast_test_flag.
Referenced by handle_response_invite().
14449 { 14450 if (ast_test_flag(&pvt->flags[0], SIP_NAT_FORCE_RPORT)) { 14451 /* NAT: Don't trust the contact field. Just use what they came to us 14452 with. */ 14453 /*! \todo We need to save the TRANSPORT here too */ 14454 pvt->sa = pvt->recv; 14455 return 0; 14456 } 14457 14458 return __set_address_from_contact(pvt->fullcontact, &pvt->sa, pvt->socket.type == SIP_TRANSPORT_TLS ? 1 : 0); 14459 }
| static void set_destination | ( | struct sip_pvt * | p, | |
| char * | uri | |||
| ) | [static] |
Set destination from SIP URI.
Parse uri to h (host) and port - uri is already just the part inside the <> general form we are expecting is sip[s]:username[:password][;parameter][:port][;...] If there's a port given, turn NAPTR/SRV off. NAPTR might indicate SIPS preference even for SIP: uri's
If there's a sips: uri scheme, TLS will be required.
Definition at line 10423 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_sockaddr_port, ast_sockaddr_resolve_first_transport(), ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_verbose, FALSE, hostname, LOG_WARNING, PARSE_PORT_FORBID, sip_debug_test_pvt(), and TRUE.
Referenced by reqprep().
10424 { 10425 char *h, *maddr, hostname[256]; 10426 int hn; 10427 int debug=sip_debug_test_pvt(p); 10428 int tls_on = FALSE; 10429 10430 if (debug) 10431 ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri); 10432 10433 /* Find and parse hostname */ 10434 h = strchr(uri, '@'); 10435 if (h) 10436 ++h; 10437 else { 10438 h = uri; 10439 if (!strncasecmp(h, "sip:", 4)) { 10440 h += 4; 10441 } else if (!strncasecmp(h, "sips:", 5)) { 10442 h += 5; 10443 tls_on = TRUE; 10444 } 10445 } 10446 hn = strcspn(h, ";>") + 1; 10447 if (hn > sizeof(hostname)) 10448 hn = sizeof(hostname); 10449 ast_copy_string(hostname, h, hn); 10450 /* XXX bug here if string has been trimmed to sizeof(hostname) */ 10451 h += hn - 1; 10452 10453 /*! \todo XXX If we have sip_cfg.srvlookup on, then look for NAPTR/SRV, 10454 * otherwise, just look for A records */ 10455 if (ast_sockaddr_resolve_first_transport(&p->sa, hostname, 0, p->socket.type)) { 10456 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 10457 return; 10458 } 10459 10460 /* Got the hostname - but maybe there's a "maddr=" to override address? */ 10461 maddr = strstr(h, "maddr="); 10462 if (maddr) { 10463 int port; 10464 10465 maddr += 6; 10466 hn = strspn(maddr, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 10467 "0123456789-.:[]") + 1; 10468 if (hn > sizeof(hostname)) 10469 hn = sizeof(hostname); 10470 ast_copy_string(hostname, maddr, hn); 10471 10472 port = ast_sockaddr_port(&p->sa); 10473 10474 /*! \todo XXX If we have sip_cfg.srvlookup on, then look for 10475 * NAPTR/SRV, otherwise, just look for A records */ 10476 if (ast_sockaddr_resolve_first_transport(&p->sa, hostname, PARSE_PORT_FORBID, p->socket.type)) { 10477 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 10478 return; 10479 } 10480 10481 ast_sockaddr_set_port(&p->sa, port); 10482 } 10483 10484 if (!ast_sockaddr_port(&p->sa)) { 10485 ast_sockaddr_set_port(&p->sa, tls_on ? 10486 STANDARD_TLS_PORT : STANDARD_SIP_PORT); 10487 } 10488 10489 if (debug) { 10490 ast_verbose("set_destination: set destination to %s\n", 10491 ast_sockaddr_stringify(&p->sa)); 10492 } 10493 }
| static void set_insecure_flags | ( | struct ast_flags * | flags, | |
| const char * | value, | |||
| int | lineno | |||
| ) | [static] |
Parse insecure= setting in sip.conf and set flags according to setting.
Definition at line 27485 of file chan_sip.c.
References ast_copy_string(), ast_false(), ast_log(), ast_set_flag, ast_strlen_zero(), LOG_WARNING, and word.
Referenced by get_insecure_variable_from_config(), get_insecure_variable_from_sipregs(), and handle_common_options().
27486 { 27487 if (ast_strlen_zero(value)) 27488 return; 27489 27490 if (!ast_false(value)) { 27491 char buf[64]; 27492 char *word, *next; 27493 27494 ast_copy_string(buf, value, sizeof(buf)); 27495 next = buf; 27496 while ((word = strsep(&next, ","))) { 27497 if (!strcasecmp(word, "port")) 27498 ast_set_flag(&flags[0], SIP_INSECURE_PORT); 27499 else if (!strcasecmp(word, "invite")) 27500 ast_set_flag(&flags[0], SIP_INSECURE_INVITE); 27501 else 27502 ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno); 27503 } 27504 } 27505 }
| static void set_nonce_randdata | ( | struct sip_pvt * | p, | |
| int | forceupdate | |||
| ) | [static] |
builds the sip_pvt's randdata field which is used for the nonce challenge. When forceupdate is not set, the nonce is only updated if the current one is stale. In this case, a stalenonce is one which has already received a response, if a nonce has not received a response it is not always necessary or beneficial to create a new one.
Definition at line 14822 of file chan_sip.c.
References ast_random(), ast_string_field_build, and ast_strlen_zero().
Referenced by check_auth(), and transmit_fake_auth_response().
14823 { 14824 if (p->stalenonce || forceupdate || ast_strlen_zero(p->randdata)) { 14825 ast_string_field_build(p, randdata, "%08lx", (unsigned long)ast_random()); /* Create nonce for challenge */ 14826 p->stalenonce = 0; 14827 } 14828 }
| static void set_peer_defaults | ( | struct sip_peer * | peer | ) | [static] |
Set peer defaults before configuring specific configurations.
Definition at line 27919 of file chan_sip.c.
References ao2_ref, ast_copy_flags, ast_sockaddr_setnull(), ast_string_field_set, cid_name, cid_num, clear_peer_mailboxes(), context, default_prefs, language, mohinterpret, mohsuggest, secret, set_socket_transport(), and sip_cfg.
Referenced by build_peer(), and temp_peer().
27920 { 27921 if (peer->expire == 0) { 27922 /* Don't reset expire or port time during reload 27923 if we have an active registration 27924 */ 27925 peer->expire = -1; 27926 peer->pokeexpire = -1; 27927 set_socket_transport(&peer->socket, SIP_TRANSPORT_UDP); 27928 } 27929 peer->type = SIP_TYPE_PEER; 27930 ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 27931 ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 27932 ast_copy_flags(&peer->flags[2], &global_flags[2], SIP_PAGE3_FLAGS_TO_COPY); 27933 ast_string_field_set(peer, context, sip_cfg.default_context); 27934 ast_string_field_set(peer, subscribecontext, sip_cfg.default_subscribecontext); 27935 ast_string_field_set(peer, language, default_language); 27936 ast_string_field_set(peer, mohinterpret, default_mohinterpret); 27937 ast_string_field_set(peer, mohsuggest, default_mohsuggest); 27938 ast_string_field_set(peer, engine, default_engine); 27939 ast_sockaddr_setnull(&peer->addr); 27940 ast_sockaddr_setnull(&peer->defaddr); 27941 peer->capability = sip_cfg.capability; 27942 peer->maxcallbitrate = default_maxcallbitrate; 27943 peer->rtptimeout = global_rtptimeout; 27944 peer->rtpholdtimeout = global_rtpholdtimeout; 27945 peer->rtpkeepalive = global_rtpkeepalive; 27946 peer->allowtransfer = sip_cfg.allowtransfer; 27947 peer->autoframing = global_autoframing; 27948 peer->t38_maxdatagram = global_t38_maxdatagram; 27949 peer->qualifyfreq = global_qualifyfreq; 27950 if (global_callcounter) 27951 peer->call_limit=INT_MAX; 27952 ast_string_field_set(peer, vmexten, default_vmexten); 27953 ast_string_field_set(peer, secret, ""); 27954 ast_string_field_set(peer, remotesecret, ""); 27955 ast_string_field_set(peer, md5secret, ""); 27956 ast_string_field_set(peer, cid_num, ""); 27957 ast_string_field_set(peer, cid_name, ""); 27958 ast_string_field_set(peer, cid_tag, ""); 27959 ast_string_field_set(peer, fromdomain, ""); 27960 ast_string_field_set(peer, fromuser, ""); 27961 ast_string_field_set(peer, regexten, ""); 27962 peer->callgroup = 0; 27963 peer->pickupgroup = 0; 27964 peer->maxms = default_qualify; 27965 peer->prefs = default_prefs; 27966 peer->stimer.st_mode_oper = global_st_mode; /* Session-Timers */ 27967 peer->stimer.st_ref = global_st_refresher; 27968 peer->stimer.st_min_se = global_min_se; 27969 peer->stimer.st_max_se = global_max_se; 27970 peer->timer_t1 = global_t1; 27971 peer->timer_b = global_timer_b; 27972 clear_peer_mailboxes(peer); 27973 peer->disallowed_methods = sip_cfg.disallowed_methods; 27974 peer->transports = default_transports; 27975 peer->default_outbound_transport = default_primary_transport; 27976 if (peer->outboundproxy) { 27977 ao2_ref(peer->outboundproxy, -1); 27978 peer->outboundproxy = NULL; 27979 } 27980 }
| static unsigned int set_pvt_allowed_methods | ( | struct sip_pvt * | pvt, | |
| struct sip_request * | req | |||
| ) | [static] |
A wrapper for parse_allowed_methods geared toward sip_pvts
This function, in addition to setting the allowed methods for a sip_pvt also will take into account the setting of the SIP_PAGE2_RPID_UPDATE flag.
| pvt | The sip_pvt we are setting the allowed_methods for | |
| req | The request which we are parsing |
| The | methods alloweded by the sip_pvt |
Definition at line 8732 of file chan_sip.c.
References ast_test_flag, mark_method_allowed(), and parse_allowed_methods().
Referenced by check_peer_ok(), handle_request_invite(), handle_request_options(), handle_request_subscribe(), handle_response_invite(), and handle_response_subscribe().
08733 { 08734 pvt->allowed_methods = parse_allowed_methods(req); 08735 08736 if (ast_test_flag(&pvt->flags[1], SIP_PAGE2_RPID_UPDATE)) { 08737 mark_method_allowed(&pvt->allowed_methods, SIP_UPDATE); 08738 } 08739 pvt->allowed_methods &= ~(pvt->disallowed_methods); 08740 08741 return pvt->allowed_methods; 08742 }
| static void set_socket_transport | ( | struct sip_socket * | socket, | |
| int | transport | |||
| ) | [static] |
Definition at line 14202 of file chan_sip.c.
References ao2_ref.
Referenced by __sip_subscribe_mwi_do(), _sip_tcp_helper_thread(), build_peer(), create_addr(), expire_register(), get_transport_pvt(), parse_moved_contact(), parse_register_contact(), set_peer_defaults(), sip_alloc(), sip_request_call(), sip_send_mwi_to_peer(), sipsock_read(), and transmit_register().
14203 { 14204 /* if the transport type changes, clear all socket data */ 14205 if (socket->type != transport) { 14206 socket->fd = -1; 14207 socket->type = transport; 14208 if (socket->tcptls_session) { 14209 ao2_ref(socket->tcptls_session, -1); 14210 socket->tcptls_session = NULL; 14211 } 14212 } 14213 }
| static void set_t38_capabilities | ( | struct sip_pvt * | p | ) | [static] |
Set the global T38 capabilities on a SIP dialog structure.
Definition at line 5390 of file chan_sip.c.
References ast_test_flag, ast_udptl_set_error_correction_scheme(), UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, and UDPTL_ERROR_CORRECTION_REDUNDANCY.
Referenced by check_peer_ok(), and initialize_udptl().
05391 { 05392 if (p->udptl) { 05393 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) == SIP_PAGE2_T38SUPPORT_UDPTL_REDUNDANCY) { 05394 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY); 05395 } else if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) == SIP_PAGE2_T38SUPPORT_UDPTL_FEC) { 05396 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC); 05397 } else if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) == SIP_PAGE2_T38SUPPORT_UDPTL) { 05398 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 05399 } 05400 } 05401 }
| static int setup_srtp | ( | struct sip_srtp ** | srtp | ) | [static] |
Definition at line 30523 of file chan_sip.c.
References ast_log(), ast_rtp_engine_srtp_is_registered(), LOG_ERROR, and sip_srtp_alloc().
Referenced by process_crypto(), and sip_call().
30524 { 30525 if (!ast_rtp_engine_srtp_is_registered()) { 30526 ast_log(LOG_ERROR, "No SRTP module loaded, can't setup SRTP session.\n"); 30527 return -1; 30528 } 30529 30530 if (!(*srtp = sip_srtp_alloc())) { /* Allocate SRTP data structure */ 30531 return -1; 30532 } 30533 30534 return 0; 30535 }
| static int show_channels_cb | ( | void * | __cur, | |
| void * | __arg, | |||
| int | flags | |||
| ) | [static] |
callback for show channel|subscription
Definition at line 18982 of file chan_sip.c.
References ast_cli(), AST_CLI_YESNO, ast_extension_state2str(), ast_getformatname_multiple(), ast_sockaddr_stringify_addr(), ast_str_alloca, ast_str_buffer(), ast_test_flag, FORMAT, FORMAT4, NONE, peer_mailboxes_to_str(), referstatus2str(), S_OR, sip_pvt_lock, sip_pvt_unlock, sip_real_dst(), and subscription_type2str().
Referenced by sip_show_channels().
18983 { 18984 struct sip_pvt *cur = __cur; 18985 struct __show_chan_arg *arg = __arg; 18986 const struct ast_sockaddr *dst; 18987 18988 sip_pvt_lock(cur); 18989 dst = sip_real_dst(cur); 18990 18991 /* XXX indentation preserved to reduce diff. Will be fixed later */ 18992 if (cur->subscribed == NONE && !arg->subscriptions) { 18993 /* set if SIP transfer in progress */ 18994 const char *referstatus = cur->refer ? referstatus2str(cur->refer->status) : ""; 18995 char formatbuf[SIPBUFSIZE/2]; 18996 18997 ast_cli(arg->fd, FORMAT, ast_sockaddr_stringify_addr(dst), 18998 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 18999 cur->callid, 19000 ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0), 19001 AST_CLI_YESNO(ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD)), 19002 cur->needdestroy ? "(d)" : "", 19003 cur->lastmsg , 19004 referstatus, 19005 cur->relatedpeer ? cur->relatedpeer->name : "<guest>" 19006 ); 19007 arg->numchans++; 19008 } 19009 if (cur->subscribed != NONE && arg->subscriptions) { 19010 struct ast_str *mailbox_str = ast_str_alloca(512); 19011 if (cur->subscribed == MWI_NOTIFICATION && cur->relatedpeer) 19012 peer_mailboxes_to_str(&mailbox_str, cur->relatedpeer); 19013 ast_cli(arg->fd, FORMAT4, ast_sockaddr_stringify_addr(dst), 19014 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 19015 cur->callid, 19016 /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */ 19017 cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri, 19018 cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 19019 subscription_type2str(cur->subscribed), 19020 cur->subscribed == MWI_NOTIFICATION ? S_OR(ast_str_buffer(mailbox_str), "<none>") : "<none>", 19021 cur->expiry 19022 ); 19023 arg->numchans++; 19024 } 19025 sip_pvt_unlock(cur); 19026 return 0; /* don't care, we scan all channels */ 19027 }
| static int show_chanstats_cb | ( | void * | __cur, | |
| void * | __arg, | |||
| int | flags | |||
| ) | [static] |
Callback for show_chanstats.
Definition at line 18584 of file chan_sip.c.
References ast_cli(), ast_log(), ast_rtp_instance_get_stats(), AST_RTP_INSTANCE_STAT_ALL, ast_sockaddr_stringify_addr(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), ast_channel::cdr, invstate2stringtable::desc, FORMAT, invitestate2string, LOG_WARNING, NONE, ast_rtp_instance_stats::rxcount, ast_rtp_instance_stats::rxjitter, ast_rtp_instance_stats::rxploss, sip_pvt_lock, sip_pvt_unlock, ast_cdr::start, ast_rtp_instance_stats::txcount, ast_rtp_instance_stats::txjitter, and ast_rtp_instance_stats::txploss.
Referenced by sip_show_channelstats().
18585 { 18586 #define FORMAT2 "%-15.15s %-11.11s %-8.8s %-10.10s %-10.10s ( %%) %-6.6s %-10.10s %-10.10s ( %%) %-6.6s\n" 18587 #define FORMAT "%-15.15s %-11.11s %-8.8s %-10.10u%-1.1s %-10.10u (%5.2f%%) %-6.4lf %-10.10u%-1.1s %-10.10u (%5.2f%%) %-6.4lf\n" 18588 struct sip_pvt *cur = __cur; 18589 struct ast_rtp_instance_stats stats; 18590 char durbuf[10]; 18591 int duration; 18592 int durh, durm, durs; 18593 struct ast_channel *c; 18594 struct __show_chan_arg *arg = __arg; 18595 int fd = arg->fd; 18596 18597 sip_pvt_lock(cur); 18598 c = cur->owner; 18599 18600 if (cur->subscribed != NONE) { 18601 /* Subscriptions */ 18602 sip_pvt_unlock(cur); 18603 return 0; /* don't care, we scan all channels */ 18604 } 18605 18606 if (!cur->rtp) { 18607 if (sipdebug) { 18608 ast_cli(fd, "%-15.15s %-11.11s (inv state: %s) -- %s\n", 18609 ast_sockaddr_stringify_addr(&cur->sa), cur->callid, 18610 invitestate2string[cur->invitestate].desc, 18611 "-- No RTP active"); 18612 } 18613 sip_pvt_unlock(cur); 18614 return 0; /* don't care, we scan all channels */ 18615 } 18616 18617 if (ast_rtp_instance_get_stats(cur->rtp, &stats, AST_RTP_INSTANCE_STAT_ALL)) { 18618 sip_pvt_unlock(cur); 18619 ast_log(LOG_WARNING, "Could not get RTP stats.\n"); 18620 return 0; 18621 } 18622 18623 if (c && c->cdr && !ast_tvzero(c->cdr->start)) { 18624 duration = (int)(ast_tvdiff_ms(ast_tvnow(), c->cdr->start) / 1000); 18625 durh = duration / 3600; 18626 durm = (duration % 3600) / 60; 18627 durs = duration % 60; 18628 snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs); 18629 } else { 18630 durbuf[0] = '\0'; 18631 } 18632 18633 ast_cli(fd, FORMAT, 18634 ast_sockaddr_stringify_addr(&cur->sa), 18635 cur->callid, 18636 durbuf, 18637 stats.rxcount > (unsigned int) 100000 ? (unsigned int) (stats.rxcount)/(unsigned int) 1000 : stats.rxcount, 18638 stats.rxcount > (unsigned int) 100000 ? "K":" ", 18639 stats.rxploss, 18640 (stats.rxcount + stats.rxploss) > 0 ? (double) stats.rxploss / (stats.rxcount + stats.rxploss) * 100 : 0, 18641 stats.rxjitter, 18642 stats.txcount > (unsigned int) 100000 ? (unsigned int) (stats.txcount)/(unsigned int) 1000 : stats.txcount, 18643 stats.txcount > (unsigned int) 100000 ? "K":" ", 18644 stats.txploss, 18645 stats.txcount > 0 ? (double) stats.txploss / stats.txcount * 100 : 0, 18646 stats.txjitter 18647 ); 18648 arg->numchans++; 18649 sip_pvt_unlock(cur); 18650 18651 return 0; /* don't care, we scan all channels */ 18652 }
| static int sip_addheader | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Add a SIP header to an outbound INVITE.
Definition at line 30310 of file chan_sip.c.
References ast_alloca, ast_channel_lock, ast_channel_unlock, ast_debug, ast_get_encoded_str(), ast_log(), ast_strlen_zero(), FALSE, inbuf(), len(), LOG_WARNING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), and TRUE.
Referenced by load_module().
30311 { 30312 int no = 0; 30313 int ok = FALSE; 30314 char varbuf[30]; 30315 const char *inbuf = data; 30316 char *subbuf; 30317 30318 if (ast_strlen_zero(inbuf)) { 30319 ast_log(LOG_WARNING, "This application requires the argument: Header\n"); 30320 return 0; 30321 } 30322 ast_channel_lock(chan); 30323 30324 /* Check for headers */ 30325 while (!ok && no <= 50) { 30326 no++; 30327 snprintf(varbuf, sizeof(varbuf), "__SIPADDHEADER%.2d", no); 30328 30329 /* Compare without the leading underscores */ 30330 if ((pbx_builtin_getvar_helper(chan, (const char *) varbuf + 2) == (const char *) NULL)) { 30331 ok = TRUE; 30332 } 30333 } 30334 if (ok) { 30335 size_t len = strlen(inbuf); 30336 subbuf = ast_alloca(len + 1); 30337 ast_get_encoded_str(inbuf, subbuf, len + 1); 30338 pbx_builtin_setvar_helper(chan, varbuf, subbuf); 30339 if (sipdebug) { 30340 ast_debug(1, "SIP Header added \"%s\" as %s\n", inbuf, varbuf); 30341 } 30342 } else { 30343 ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n"); 30344 } 30345 ast_channel_unlock(chan); 30346 return 0; 30347 }
| struct sip_pvt* sip_alloc | ( | ast_string_field | callid, | |
| struct ast_sockaddr * | addr, | |||
| int | useglobal_nat, | |||
| const int | intended_method, | |||
| struct sip_request * | req | |||
| ) | [read] |
Allocate sip_pvt structure, set defaults and link in the container. Returns a reference to the object so whoever uses it later must remember to release the reference.
Definition at line 7967 of file chan_sip.c.
References ao2_t_alloc, ao2_t_link, ao2_t_ref, ast_cc_config_params_init, ast_copy_flags, ast_debug, AST_LIST_HEAD_INIT_NOLOCK, ast_random(), AST_RTP_DTMF, ast_sip_ouraddrfor(), ast_sockaddr_copy(), ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag, build_callid_pvt(), build_via(), context, default_prefs, do_setnat(), free_via(), get_header(), internip, make_our_tag(), mohinterpret, mohsuggest, NONE, parkinglot, parse_via(), set_socket_transport(), sip_cfg, sip_destroy_fn(), sip_methods, cfsip_methods::text, and TRUE.
Referenced by __sip_subscribe_mwi_do(), find_call(), manager_sipnotify(), sip_cc_monitor_request_cc(), sip_cli_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_publish(), and transmit_register().
07969 { 07970 struct sip_pvt *p; 07971 07972 if (!(p = ao2_t_alloc(sizeof(*p), sip_destroy_fn, "allocate a dialog(pvt) struct"))) 07973 return NULL; 07974 07975 if (ast_string_field_init(p, 512)) { 07976 ao2_t_ref(p, -1, "failed to string_field_init, drop p"); 07977 return NULL; 07978 } 07979 07980 if (!(p->cc_params = ast_cc_config_params_init())) { 07981 ao2_t_ref(p, -1, "Yuck, couldn't allocate cc_params struct. Get rid o' p"); 07982 return NULL; 07983 } 07984 07985 /* If this dialog is created as the result of an incoming Request. Lets store 07986 * some information about that request */ 07987 if (req) { 07988 struct sip_via *via; 07989 const char *cseq = get_header(req, "Cseq"); 07990 uint32_t seqno; 07991 07992 /* get branch parameter from initial Request that started this dialog */ 07993 via = parse_via(get_header(req, "Via")); 07994 if (via) { 07995 /* only store the branch if it begins with the magic prefix "z9hG4bK", otherwise 07996 * it is not useful to us to have it */ 07997 if (!ast_strlen_zero(via->branch) && !strncasecmp(via->branch, "z9hG4bK", 7)) { 07998 ast_string_field_set(p, initviabranch, via->branch); 07999 ast_string_field_set(p, initviasentby, via->sent_by); 08000 } 08001 free_via(via); 08002 } 08003 08004 /* Store initial incoming cseq. An error in sscanf here is ignored. There is no approperiate 08005 * except not storing the number. CSeq validation must take place before dialog creation in find_call */ 08006 if (!ast_strlen_zero(cseq) && (sscanf(cseq, "%30u", &seqno) == 1)) { 08007 p->init_icseq = seqno; 08008 } 08009 /* Later in ast_sip_ouraddrfor we need this to choose the right ip and port for the specific transport */ 08010 set_socket_transport(&p->socket, req->socket.type); 08011 } else { 08012 set_socket_transport(&p->socket, SIP_TRANSPORT_UDP); 08013 } 08014 08015 p->socket.fd = -1; 08016 p->method = intended_method; 08017 p->initid = -1; 08018 p->waitid = -1; 08019 p->reinviteid = -1; 08020 p->autokillid = -1; 08021 p->request_queue_sched_id = -1; 08022 p->provisional_keepalive_sched_id = -1; 08023 p->t38id = -1; 08024 p->subscribed = NONE; 08025 p->stateid = -1; 08026 p->sessionversion_remote = -1; 08027 p->session_modify = TRUE; 08028 p->stimer = NULL; 08029 p->prefs = default_prefs; /* Set default codecs for this call */ 08030 p->maxforwards = sip_cfg.default_max_forwards; 08031 08032 if (intended_method != SIP_OPTIONS) { /* Peerpoke has it's own system */ 08033 p->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */ 08034 p->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */ 08035 } 08036 08037 if (!addr) { 08038 p->ourip = internip; 08039 } else { 08040 ast_sockaddr_copy(&p->sa, addr); 08041 ast_sip_ouraddrfor(&p->sa, &p->ourip, p); 08042 } 08043 08044 /* Copy global flags to this PVT at setup. */ 08045 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 08046 ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 08047 ast_copy_flags(&p->flags[2], &global_flags[2], SIP_PAGE3_FLAGS_TO_COPY); 08048 08049 p->do_history = recordhistory; 08050 08051 p->branch = ast_random(); 08052 make_our_tag(p); 08053 p->ocseq = INITIAL_CSEQ; 08054 p->allowed_methods = UINT_MAX; 08055 08056 if (sip_methods[intended_method].need_rtp) { 08057 p->maxcallbitrate = default_maxcallbitrate; 08058 p->autoframing = global_autoframing; 08059 } 08060 08061 if (useglobal_nat && addr) { 08062 /* Setup NAT structure according to global settings if we have an address */ 08063 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT_FORCE_RPORT); 08064 ast_sockaddr_copy(&p->recv, addr); 08065 08066 do_setnat(p); 08067 } 08068 08069 if (p->method != SIP_REGISTER) { 08070 ast_string_field_set(p, fromdomain, default_fromdomain); 08071 p->fromdomainport = default_fromdomainport; 08072 } 08073 build_via(p); 08074 if (!callid) 08075 build_callid_pvt(p); 08076 else 08077 ast_string_field_set(p, callid, callid); 08078 /* Assign default music on hold class */ 08079 ast_string_field_set(p, mohinterpret, default_mohinterpret); 08080 ast_string_field_set(p, mohsuggest, default_mohsuggest); 08081 p->capability = sip_cfg.capability; 08082 p->allowtransfer = sip_cfg.allowtransfer; 08083 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 08084 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) { 08085 p->noncodeccapability |= AST_RTP_DTMF; 08086 } 08087 ast_string_field_set(p, context, sip_cfg.default_context); 08088 ast_string_field_set(p, parkinglot, default_parkinglot); 08089 ast_string_field_set(p, engine, default_engine); 08090 08091 AST_LIST_HEAD_INIT_NOLOCK(&p->request_queue); 08092 08093 /* Add to active dialog list */ 08094 08095 ao2_t_link(dialogs, p, "link pvt into dialogs table"); 08096 08097 ast_debug(1, "Allocating new SIP dialog for %s - %s (%s)\n", callid ? callid : p->callid, sip_methods[intended_method].text, p->rtp ? "With RTP" : "No RTP"); 08098 return p; 08099 }
| static void sip_alreadygone | ( | struct sip_pvt * | dialog | ) | [static] |
Encapsulate setting of SIP_ALREADYGONE to be able to trace it with debugging.
Definition at line 3222 of file chan_sip.c.
References ast_debug.
Referenced by handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), handle_response_publish(), handle_response_subscribe(), retrans_pkt(), sip_indicate(), and sip_sipredirect().
03223 { 03224 ast_debug(3, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid); 03225 dialog->alreadygone = 1; 03226 }
| static int sip_answer | ( | struct ast_channel * | ast | ) | [static] |
sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface
Definition at line 6729 of file chan_sip.c.
References ast_channel::_state, ast_debug, ast_rtp_instance_update_source(), ast_set_flag, ast_setstate(), AST_STATE_UP, ast_test_flag, FALSE, sip_pvt_lock, sip_pvt_unlock, start_session_timer(), ast_channel::tech_pvt, transmit_response_with_sdp(), TRUE, and try_suggested_sip_codec().
06730 { 06731 int res = 0; 06732 struct sip_pvt *p = ast->tech_pvt; 06733 int oldsdp = FALSE; 06734 06735 if (!p) { 06736 ast_debug(1, "Asked to answer channel %s without tech pvt; ignoring\n", 06737 ast->name); 06738 return res; 06739 } 06740 sip_pvt_lock(p); 06741 if (ast->_state != AST_STATE_UP) { 06742 try_suggested_sip_codec(p); 06743 06744 if (ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT)) { 06745 oldsdp = TRUE; 06746 } 06747 06748 ast_setstate(ast, AST_STATE_UP); 06749 ast_debug(1, "SIP answering channel: %s\n", ast->name); 06750 ast_rtp_instance_update_source(p->rtp); 06751 res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL, oldsdp, TRUE); 06752 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 06753 /* RFC says the session timer starts counting on 200, 06754 * not on INVITE. */ 06755 if (p->stimer->st_active == TRUE) { 06756 start_session_timer(p); 06757 } 06758 } 06759 sip_pvt_unlock(p); 06760 return res; 06761 }
| static int sip_call | ( | struct ast_channel * | ast, | |
| char * | dest, | |||
| int | timeout | |||
| ) | [static] |
Initiate SIP call from PBX used from the dial() application.
Definition at line 5763 of file chan_sip.c.
References ast_channel::_state, ao2_t_ref, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_USER_BUSY, ast_cc_get_monitor_by_recall_core_id(), ast_cc_is_recall(), ast_channel_get_device_name(), AST_CHANNEL_NAME, ast_channel_queue_connected_line_update(), ast_clear_flag, AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER, ast_copy_string(), ast_debug, AST_FORMAT_AUDIO_MASK, AST_LIST_TRAVERSE, ast_log(), ast_party_connected_line_init(), ast_party_id_presentation(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, ast_rtp_instance_available_formats(), AST_SCHED_REPLACE_UNREF, ast_set_flag, AST_STATE_DOWN, AST_STATE_RESERVED, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_var_name(), ast_var_value(), auto_congest(), ast_channel::caller, cid_name, connected, ast_channel::hangupcause, ast_party_connected_line::id, ast_set_party_connected_line::id, ast_party_caller::id, LOG_WARNING, ast_party_id::name, ast_set_party_id::name, ast_party_id::number, ast_set_party_id::number, ast_party_name::presentation, ast_party_number::presentation, ast_cc_monitor::private_data, setup_srtp(), sip_pvt_lock, sip_pvt_unlock, ast_party_connected_line::source, ast_party_name::str, ast_party_number::str, ast_party_id::tag, ast_channel::tech_pvt, transmit_invite(), update_call_counter(), ast_party_name::valid, ast_party_number::valid, and ast_channel::varshead.
05764 { 05765 int res; 05766 struct sip_pvt *p = ast->tech_pvt; /* chan is locked, so the reference cannot go away */ 05767 struct varshead *headp; 05768 struct ast_var_t *current; 05769 const char *referer = NULL; /* SIP referrer */ 05770 int cc_core_id; 05771 char uri[SIPBUFSIZE] = ""; 05772 05773 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 05774 ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name); 05775 return -1; 05776 } 05777 05778 if (ast_cc_is_recall(ast, &cc_core_id, "SIP")) { 05779 char device_name[AST_CHANNEL_NAME]; 05780 struct ast_cc_monitor *recall_monitor; 05781 struct sip_monitor_instance *monitor_instance; 05782 ast_channel_get_device_name(ast, device_name, sizeof(device_name)); 05783 if ((recall_monitor = ast_cc_get_monitor_by_recall_core_id(cc_core_id, device_name))) { 05784 monitor_instance = recall_monitor->private_data; 05785 ast_copy_string(uri, monitor_instance->notify_uri, sizeof(uri)); 05786 ao2_t_ref(recall_monitor, -1, "Got the URI we need so unreffing monitor"); 05787 } 05788 } 05789 05790 /* Check whether there is vxml_url, distinctive ring variables */ 05791 headp=&ast->varshead; 05792 AST_LIST_TRAVERSE(headp, current, entries) { 05793 /* Check whether there is a VXML_URL variable */ 05794 if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) { 05795 p->options->vxml_url = ast_var_value(current); 05796 } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) { 05797 p->options->uri_options = ast_var_value(current); 05798 } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 05799 /* Check whether there is a variable with a name starting with SIPADDHEADER */ 05800 p->options->addsipheaders = 1; 05801 } else if (!strcasecmp(ast_var_name(current), "SIPFROMDOMAIN")) { 05802 ast_string_field_set(p, fromdomain, ast_var_value(current)); 05803 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) { 05804 /* This is a transferred call */ 05805 p->options->transfer = 1; 05806 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) { 05807 /* This is the referrer */ 05808 referer = ast_var_value(current); 05809 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) { 05810 /* We're replacing a call. */ 05811 p->options->replaces = ast_var_value(current); 05812 } else if (!strcasecmp(ast_var_name(current), "SIP_MAX_FORWARDS")) { 05813 if (sscanf(ast_var_value(current), "%d", &(p->maxforwards)) != 1) { 05814 ast_log(LOG_WARNING, "The SIP_MAX_FORWARDS channel variable is not a valid integer.\n"); 05815 } 05816 } 05817 } 05818 05819 /* Check to see if we should try to force encryption */ 05820 if (p->req_secure_signaling && p->socket.type != SIP_TRANSPORT_TLS) { 05821 ast_log(LOG_WARNING, "Encrypted signaling is required\n"); 05822 ast->hangupcause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 05823 return -1; 05824 } 05825 05826 if (ast_test_flag(&p->flags[1], SIP_PAGE2_USE_SRTP)) { 05827 if (ast_test_flag(&p->flags[0], SIP_REINVITE)) { 05828 ast_debug(1, "Direct media not possible when using SRTP, ignoring canreinvite setting\n"); 05829 ast_clear_flag(&p->flags[0], SIP_REINVITE); 05830 } 05831 05832 if (p->rtp && !p->srtp && setup_srtp(&p->srtp) < 0) { 05833 ast_log(LOG_WARNING, "SRTP audio setup failed\n"); 05834 return -1; 05835 } 05836 05837 if (p->vrtp && !p->vsrtp && setup_srtp(&p->vsrtp) < 0) { 05838 ast_log(LOG_WARNING, "SRTP video setup failed\n"); 05839 return -1; 05840 } 05841 05842 if (p->trtp && !p->tsrtp && setup_srtp(&p->tsrtp) < 0) { 05843 ast_log(LOG_WARNING, "SRTP text setup failed\n"); 05844 return -1; 05845 } 05846 } 05847 05848 res = 0; 05849 ast_set_flag(&p->flags[0], SIP_OUTGOING); 05850 05851 /* T.38 re-INVITE FAX detection should never be done for outgoing calls, 05852 * so ensure it is disabled. 05853 */ 05854 ast_clear_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_T38); 05855 05856 if (p->options->transfer) { 05857 char buf[SIPBUFSIZE/2]; 05858 05859 if (referer) { 05860 if (sipdebug) 05861 ast_debug(3, "Call for %s transferred by %s\n", p->username, referer); 05862 snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer); 05863 } else 05864 snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name); 05865 ast_string_field_set(p, cid_name, buf); 05866 } 05867 ast_debug(1, "Outgoing Call for %s\n", p->username); 05868 05869 res = update_call_counter(p, INC_CALL_RINGING); 05870 05871 if (res == -1) { 05872 ast->hangupcause = AST_CAUSE_USER_BUSY; 05873 return res; 05874 } 05875 p->callingpres = ast_party_id_presentation(&ast->caller.id); 05876 p->jointcapability = ast_rtp_instance_available_formats(p->rtp, p->capability, p->prefcodec); 05877 p->jointnoncodeccapability = p->noncodeccapability; 05878 05879 /* If there are no audio formats left to offer, punt */ 05880 if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 05881 ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username); 05882 res = -1; 05883 } else { 05884 int xmitres; 05885 struct ast_party_connected_line connected; 05886 struct ast_set_party_connected_line update_connected; 05887 05888 sip_pvt_lock(p); 05889 05890 /* Supply initial connected line information if available. */ 05891 memset(&update_connected, 0, sizeof(update_connected)); 05892 ast_party_connected_line_init(&connected); 05893 if (!ast_strlen_zero(p->cid_num) 05894 || (p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) { 05895 update_connected.id.number = 1; 05896 connected.id.number.valid = 1; 05897 connected.id.number.str = (char *) p->cid_num; 05898 connected.id.number.presentation = p->callingpres; 05899 } 05900 if (!ast_strlen_zero(p->cid_name) 05901 || (p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) { 05902 update_connected.id.name = 1; 05903 connected.id.name.valid = 1; 05904 connected.id.name.str = (char *) p->cid_name; 05905 connected.id.name.presentation = p->callingpres; 05906 } 05907 if (update_connected.id.number || update_connected.id.name) { 05908 connected.id.tag = (char *) p->cid_tag; 05909 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; 05910 ast_channel_queue_connected_line_update(ast, &connected, &update_connected); 05911 } 05912 05913 xmitres = transmit_invite(p, SIP_INVITE, 1, 2, uri); 05914 if (xmitres == XMIT_ERROR) { 05915 sip_pvt_unlock(p); 05916 return -1; 05917 } 05918 p->invitestate = INV_CALLING; 05919 05920 /* Initialize auto-congest time */ 05921 AST_SCHED_REPLACE_UNREF(p->initid, sched, p->timer_b, auto_congest, p, 05922 dialog_unref(_data, "dialog ptr dec when SCHED_REPLACE del op succeeded"), 05923 dialog_unref(p, "dialog ptr dec when SCHED_REPLACE add failed"), 05924 dialog_ref(p, "dialog ptr inc when SCHED_REPLACE add succeeded") ); 05925 sip_pvt_unlock(p); 05926 } 05927 return res; 05928 }
| int sip_cancel_destroy | ( | struct sip_pvt * | p | ) |
Cancel destruction of SIP dialog. Be careful as this also absorbs the reference - if you call it from within the scheduler, this might be the last reference.
Definition at line 4143 of file chan_sip.c.
References append_history, and AST_SCHED_DEL_UNREF.
Referenced by handle_request_invite(), handle_request_subscribe(), handle_response(), handle_response_invite(), register_verify(), sip_hangup(), and sip_scheddestroy().
04144 { 04145 if (p->final_destruction_scheduled) { 04146 return 0; 04147 } 04148 04149 if (p->autokillid > -1) { 04150 append_history(p, "CancelDestroy", ""); 04151 AST_SCHED_DEL_UNREF(sched, p->autokillid, dialog_unref(p, "remove ref for autokillid")); 04152 } 04153 return 0; 04154 }
| static void sip_cc_agent_destructor | ( | struct ast_cc_agent * | agent | ) | [static] |
Definition at line 1812 of file chan_sip.c.
References ast_free, ast_test_flag, ast_cc_agent::private_data, sip_cc_agent_stop_offer_timer(), sip_pvt_lock, sip_pvt_unlock, and transmit_response().
01813 { 01814 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01815 01816 if (!agent_pvt) { 01817 /* The agent constructor probably failed. */ 01818 return; 01819 } 01820 01821 sip_cc_agent_stop_offer_timer(agent); 01822 if (agent_pvt->subscribe_pvt) { 01823 sip_pvt_lock(agent_pvt->subscribe_pvt); 01824 if (!ast_test_flag(&agent_pvt->subscribe_pvt->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) { 01825 /* If we haven't sent a 200 OK for the SUBSCRIBE dialog yet, then we need to send a response letting 01826 * the subscriber know something went wrong 01827 */ 01828 transmit_response(agent_pvt->subscribe_pvt, "500 Internal Server Error", &agent_pvt->subscribe_pvt->initreq); 01829 } 01830 sip_pvt_unlock(agent_pvt->subscribe_pvt); 01831 agent_pvt->subscribe_pvt = dialog_unref(agent_pvt->subscribe_pvt, "SIP CC agent destructor: Remove ref to subscription"); 01832 } 01833 ast_free(agent_pvt); 01834 }
| static int sip_cc_agent_init | ( | struct ast_cc_agent * | agent, | |
| struct ast_channel * | chan | |||
| ) | [static] |
Definition at line 1699 of file chan_sip.c.
References ast_assert, ast_calloc, ast_copy_string(), ast_set_flag, ast_cc_agent::private_data, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech, ast_channel::tech_pvt, and ast_channel_tech::type.
01700 { 01701 struct sip_cc_agent_pvt *agent_pvt = ast_calloc(1, sizeof(*agent_pvt)); 01702 struct sip_pvt *call_pvt = chan->tech_pvt; 01703 01704 if (!agent_pvt) { 01705 return -1; 01706 } 01707 01708 ast_assert(!strcmp(chan->tech->type, "SIP")); 01709 01710 ast_copy_string(agent_pvt->original_callid, call_pvt->callid, sizeof(agent_pvt->original_callid)); 01711 ast_copy_string(agent_pvt->original_exten, call_pvt->exten, sizeof(agent_pvt->original_exten)); 01712 agent_pvt->offer_timer_id = -1; 01713 agent->private_data = agent_pvt; 01714 sip_pvt_lock(call_pvt); 01715 ast_set_flag(&call_pvt->flags[0], SIP_OFFER_CC); 01716 sip_pvt_unlock(call_pvt); 01717 return 0; 01718 }
| static int sip_cc_agent_recall | ( | struct ast_cc_agent * | agent | ) | [static] |
Definition at line 1792 of file chan_sip.c.
References ast_cc_agent_caller_busy(), ast_cc_agent::core_id, ast_cc_agent::device_name, ast_cc_agent::private_data, sip_pvt_lock, sip_pvt_unlock, and transmit_cc_notify().
01793 { 01794 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01795 /* If we have received a PUBLISH beforehand stating that the caller in question 01796 * is not available, we can save ourself a bit of effort here and just report 01797 * the caller as busy 01798 */ 01799 if (!agent_pvt->is_available) { 01800 return ast_cc_agent_caller_busy(agent->core_id, "Caller %s is busy, reporting to the core", 01801 agent->device_name); 01802 } 01803 /* Otherwise, we transmit a NOTIFY to the caller and await either 01804 * a PUBLISH or an INVITE 01805 */ 01806 sip_pvt_lock(agent_pvt->subscribe_pvt); 01807 transmit_cc_notify(agent, agent_pvt->subscribe_pvt, CC_READY); 01808 sip_pvt_unlock(agent_pvt->subscribe_pvt); 01809 return 0; 01810 }
| static void sip_cc_agent_respond | ( | struct ast_cc_agent * | agent, | |
| enum ast_cc_agent_response_reason | reason | |||
| ) | [static] |
Definition at line 1748 of file chan_sip.c.
References AST_CC_AGENT_RESPONSE_SUCCESS, ast_set_flag, ast_strlen_zero(), ast_cc_agent::private_data, sip_pvt_lock, sip_pvt_unlock, transmit_cc_notify(), transmit_response(), and TRUE.
01749 { 01750 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01751 01752 sip_pvt_lock(agent_pvt->subscribe_pvt); 01753 ast_set_flag(&agent_pvt->subscribe_pvt->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 01754 if (reason == AST_CC_AGENT_RESPONSE_SUCCESS || !ast_strlen_zero(agent_pvt->notify_uri)) { 01755 /* The second half of this if statement may be a bit hard to grasp, 01756 * so here's an explanation. When a subscription comes into 01757 * chan_sip, as long as it is not malformed, it will be passed 01758 * to the CC core. If the core senses an out-of-order state transition, 01759 * then the core will call this callback with the "reason" set to a 01760 * failure condition. 01761 * However, an out-of-order state transition will occur during a resubscription 01762 * for CC. In such a case, we can see that we have already generated a notify_uri 01763 * and so we can detect that this isn't a *real* failure. Rather, it is just 01764 * something the core doesn't recognize as a legitimate SIP state transition. 01765 * Thus we respond with happiness and flowers. 01766 */ 01767 transmit_response(agent_pvt->subscribe_pvt, "200 OK", &agent_pvt->subscribe_pvt->initreq); 01768 transmit_cc_notify(agent, agent_pvt->subscribe_pvt, CC_QUEUED); 01769 } else { 01770 transmit_response(agent_pvt->subscribe_pvt, "500 Internal Error", &agent_pvt->subscribe_pvt->initreq); 01771 } 01772 sip_pvt_unlock(agent_pvt->subscribe_pvt); 01773 agent_pvt->is_available = TRUE; 01774 }
| static int sip_cc_agent_start_monitoring | ( | struct ast_cc_agent * | agent | ) | [static] |
Definition at line 1783 of file chan_sip.c.
| static int sip_cc_agent_start_offer_timer | ( | struct ast_cc_agent * | agent | ) | [static] |
Definition at line 1730 of file chan_sip.c.
References ast_get_cc_offer_timer(), ast_sched_add(), ast_cc_agent::cc_params, ast_cc_agent::private_data, and sip_offer_timer_expire().
01731 { 01732 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01733 int when; 01734 01735 when = ast_get_cc_offer_timer(agent->cc_params) * 1000; 01736 agent_pvt->offer_timer_id = ast_sched_add(sched, when, sip_offer_timer_expire, agent); 01737 return 0; 01738 }
| static int sip_cc_agent_status_request | ( | struct ast_cc_agent * | agent | ) | [static] |
Definition at line 1776 of file chan_sip.c.
References ast_cc_agent_status_response(), AST_DEVICE_INUSE, AST_DEVICE_NOT_INUSE, ast_cc_agent::core_id, and ast_cc_agent::private_data.
01777 { 01778 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01779 enum ast_device_state state = agent_pvt->is_available ? AST_DEVICE_NOT_INUSE : AST_DEVICE_INUSE; 01780 return ast_cc_agent_status_response(agent->core_id, state); 01781 }
| static int sip_cc_agent_stop_offer_timer | ( | struct ast_cc_agent * | agent | ) | [static] |
Definition at line 1740 of file chan_sip.c.
References AST_SCHED_DEL, and ast_cc_agent::private_data.
Referenced by sip_cc_agent_destructor().
01741 { 01742 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01743 01744 AST_SCHED_DEL(sched, agent_pvt->offer_timer_id); 01745 return 0; 01746 }
| static int sip_cc_monitor_cancel_available_timer | ( | struct ast_cc_monitor * | monitor, | |
| int * | sched_id | |||
| ) | [static] |
Definition at line 2051 of file chan_sip.c.
References ao2_t_ref, and AST_SCHED_DEL.
02052 { 02053 if (*sched_id != -1) { 02054 AST_SCHED_DEL(sched, *sched_id); 02055 ao2_t_ref(monitor, -1, "Removing scheduler's reference to the monitor"); 02056 } 02057 return 0; 02058 }
| static void sip_cc_monitor_destructor | ( | void * | private_data | ) | [static] |
Definition at line 2060 of file chan_sip.c.
References ao2_unlink, and ast_module_unref().
02061 { 02062 struct sip_monitor_instance *monitor_instance = private_data; 02063 ao2_unlink(sip_monitor_instances, monitor_instance); 02064 ast_module_unref(ast_module_info->self); 02065 }
| static int sip_cc_monitor_request_cc | ( | struct ast_cc_monitor * | monitor, | |
| int * | available_timer_id | |||
| ) | [static] |
Definition at line 1918 of file chan_sip.c.
References ao2_t_ref, ast_cc_available_timer_expire(), AST_CC_CCBS, ast_get_ccbs_available_timer(), ast_get_ccnr_available_timer(), ast_sched_add(), ast_set_flag, ast_sip_ouraddrfor(), ast_cc_interface::config_params, create_addr(), FALSE, ast_cc_monitor::interface, ast_cc_monitor::private_data, service, ast_cc_monitor::service_offered, sip_alloc(), sip_pvt_lock, sip_pvt_unlock, and transmit_invite().
01919 { 01920 struct sip_monitor_instance *monitor_instance = monitor->private_data; 01921 enum ast_cc_service_type service = monitor->service_offered; 01922 int when; 01923 01924 if (!monitor_instance) { 01925 return -1; 01926 } 01927 01928 if (!(monitor_instance->subscription_pvt = sip_alloc(NULL, NULL, 0, SIP_SUBSCRIBE, NULL))) { 01929 return -1; 01930 } 01931 01932 when = service == AST_CC_CCBS ? ast_get_ccbs_available_timer(monitor->interface->config_params) : 01933 ast_get_ccnr_available_timer(monitor->interface->config_params); 01934 01935 sip_pvt_lock(monitor_instance->subscription_pvt); 01936 ast_set_flag(&monitor_instance->subscription_pvt->flags[0], SIP_OUTGOING); 01937 create_addr(monitor_instance->subscription_pvt, monitor_instance->peername, 0, 1); 01938 ast_sip_ouraddrfor(&monitor_instance->subscription_pvt->sa, &monitor_instance->subscription_pvt->ourip, monitor_instance->subscription_pvt); 01939 monitor_instance->subscription_pvt->subscribed = CALL_COMPLETION; 01940 monitor_instance->subscription_pvt->expiry = when; 01941 01942 transmit_invite(monitor_instance->subscription_pvt, SIP_SUBSCRIBE, FALSE, 2, monitor_instance->subscribe_uri); 01943 sip_pvt_unlock(monitor_instance->subscription_pvt); 01944 01945 ao2_t_ref(monitor, +1, "Adding a ref to the monitor for the scheduler"); 01946 *available_timer_id = ast_sched_add(sched, when * 1000, ast_cc_available_timer_expire, monitor); 01947 return 0; 01948 }
| static int sip_cc_monitor_suspend | ( | struct ast_cc_monitor * | monitor | ) | [static] |
Definition at line 1976 of file chan_sip.c.
References ao2_ref, ast_calloc, ast_log(), ast_strlen_zero(), construct_pidf_body(), ast_cc_monitor::core_id, create_epa_entry(), LOG_WARNING, ast_cc_monitor::private_data, and transmit_publish().
01977 { 01978 struct sip_monitor_instance *monitor_instance = monitor->private_data; 01979 enum sip_publish_type publish_type; 01980 struct cc_epa_entry *cc_entry; 01981 01982 if (!monitor_instance) { 01983 return -1; 01984 } 01985 01986 if (!monitor_instance->suspension_entry) { 01987 /* We haven't yet allocated the suspension entry, so let's give it a shot */ 01988 if (!(monitor_instance->suspension_entry = create_epa_entry("call-completion", monitor_instance->peername))) { 01989 ast_log(LOG_WARNING, "Unable to allocate sip EPA entry for call-completion\n"); 01990 ao2_ref(monitor_instance, -1); 01991 return -1; 01992 } 01993 if (!(cc_entry = ast_calloc(1, sizeof(*cc_entry)))) { 01994 ast_log(LOG_WARNING, "Unable to allocate space for instance data of EPA entry for call-completion\n"); 01995 ao2_ref(monitor_instance, -1); 01996 return -1; 01997 } 01998 cc_entry->core_id = monitor->core_id; 01999 monitor_instance->suspension_entry->instance_data = cc_entry; 02000 publish_type = SIP_PUBLISH_INITIAL; 02001 } else { 02002 publish_type = SIP_PUBLISH_MODIFY; 02003 cc_entry = monitor_instance->suspension_entry->instance_data; 02004 } 02005 02006 cc_entry->current_state = CC_CLOSED; 02007 02008 if (ast_strlen_zero(monitor_instance->notify_uri)) { 02009 /* If we have no set notify_uri, then what this means is that we have 02010 * not received a NOTIFY from this destination stating that he is 02011 * currently available. 02012 * 02013 * This situation can arise when the core calls the suspend callbacks 02014 * of multiple destinations. If one of the other destinations aside 02015 * from this one notified Asterisk that he is available, then there 02016 * is no reason to take any suspension action on this device. Rather, 02017 * we should return now and if we receive a NOTIFY while monitoring 02018 * is still "suspended" then we can immediately respond with the 02019 * proper PUBLISH to let this endpoint know what is going on. 02020 */ 02021 return 0; 02022 } 02023 construct_pidf_body(CC_CLOSED, monitor_instance->suspension_entry->body, sizeof(monitor_instance->suspension_entry->body), monitor_instance->peername); 02024 return transmit_publish(monitor_instance->suspension_entry, publish_type, monitor_instance->notify_uri); 02025 }
| static int sip_cc_monitor_unsuspend | ( | struct ast_cc_monitor * | monitor | ) | [static] |
Definition at line 2027 of file chan_sip.c.
References ast_assert, ast_strlen_zero(), construct_pidf_body(), ast_cc_monitor::private_data, and transmit_publish().
02028 { 02029 struct sip_monitor_instance *monitor_instance = monitor->private_data; 02030 struct cc_epa_entry *cc_entry; 02031 02032 if (!monitor_instance) { 02033 return -1; 02034 } 02035 02036 ast_assert(monitor_instance->suspension_entry != NULL); 02037 02038 cc_entry = monitor_instance->suspension_entry->instance_data; 02039 cc_entry->current_state = CC_OPEN; 02040 if (ast_strlen_zero(monitor_instance->notify_uri)) { 02041 /* This means we are being asked to unsuspend a call leg we never 02042 * sent a PUBLISH on. As such, there is no reason to send another 02043 * PUBLISH at this point either. We can just return instead. 02044 */ 02045 return 0; 02046 } 02047 construct_pidf_body(CC_OPEN, monitor_instance->suspension_entry->body, sizeof(monitor_instance->suspension_entry->body), monitor_instance->peername); 02048 return transmit_publish(monitor_instance->suspension_entry, SIP_PUBLISH_MODIFY, monitor_instance->notify_uri); 02049 }
| static int sip_check_authtimeout | ( | time_t | start | ) | [static] |
Check if the authtimeout has expired.
| start | the time when the session started |
| 0 | the timeout has expired | |
| -1 | error |
Definition at line 2483 of file chan_sip.c.
References ast_log(), errno, and LOG_ERROR.
Referenced by _sip_tcp_helper_thread(), and sip_tcptls_read().
02484 { 02485 int timeout; 02486 time_t now; 02487 if(time(&now) == -1) { 02488 ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno)); 02489 return -1; 02490 } 02491 02492 timeout = (authtimeout - (now - start)) * 1000; 02493 if (timeout < 0) { 02494 /* we have timed out */ 02495 return 0; 02496 } 02497 02498 return timeout; 02499 }
| static char * sip_cli_notify | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Cli command to send SIP notify to peer.
Definition at line 19680 of file chan_sip.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_copy_string(), ast_log(), ast_set_flag, ast_sip_ouraddrfor(), ast_str_append(), ast_str_strlen(), ast_unescape_semicolon(), ast_variable_browse(), ast_variable_new(), build_via(), change_callid_pvt(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sipnotify(), create_addr(), dialog_unlink_all(), ast_cli_args::fd, ast_cli_args::line, LOG_WARNING, ast_cli_args::n, ast_variable::name, ast_variable::next, ast_cli_args::pos, sip_alloc(), sip_notify_allocate(), sip_scheddestroy(), transmit_invite(), ast_cli_entry::usage, ast_variable::value, var, and ast_cli_args::word.
19681 { 19682 struct ast_variable *varlist; 19683 int i; 19684 19685 switch (cmd) { 19686 case CLI_INIT: 19687 e->command = "sip notify"; 19688 e->usage = 19689 "Usage: sip notify <type> <peer> [<peer>...]\n" 19690 " Send a NOTIFY message to a SIP peer or peers\n" 19691 " Message types are defined in sip_notify.conf\n"; 19692 return NULL; 19693 case CLI_GENERATE: 19694 return complete_sipnotify(a->line, a->word, a->pos, a->n); 19695 } 19696 19697 if (a->argc < 4) 19698 return CLI_SHOWUSAGE; 19699 19700 if (!notify_types) { 19701 ast_cli(a->fd, "No %s file found, or no types listed there\n", notify_config); 19702 return CLI_FAILURE; 19703 } 19704 19705 varlist = ast_variable_browse(notify_types, a->argv[2]); 19706 19707 if (!varlist) { 19708 ast_cli(a->fd, "Unable to find notify type '%s'\n", a->argv[2]); 19709 return CLI_FAILURE; 19710 } 19711 19712 for (i = 3; i < a->argc; i++) { 19713 struct sip_pvt *p; 19714 char buf[512]; 19715 struct ast_variable *header, *var; 19716 19717 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) { 19718 ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n"); 19719 return CLI_FAILURE; 19720 } 19721 19722 if (create_addr(p, a->argv[i], NULL, 1)) { 19723 /* Maybe they're not registered, etc. */ 19724 dialog_unlink_all(p); 19725 dialog_unref(p, "unref dialog inside for loop" ); 19726 /* sip_destroy(p); */ 19727 ast_cli(a->fd, "Could not create address for '%s'\n", a->argv[i]); 19728 continue; 19729 } 19730 19731 /* Notify is outgoing call */ 19732 ast_set_flag(&p->flags[0], SIP_OUTGOING); 19733 sip_notify_allocate(p); 19734 p->notify->headers = header = ast_variable_new("Subscription-State", "terminated", ""); 19735 19736 for (var = varlist; var; var = var->next) { 19737 ast_copy_string(buf, var->value, sizeof(buf)); 19738 ast_unescape_semicolon(buf); 19739 19740 if (!strcasecmp(var->name, "Content")) { 19741 if (ast_str_strlen(p->notify->content)) 19742 ast_str_append(&p->notify->content, 0, "\r\n"); 19743 ast_str_append(&p->notify->content, 0, "%s", buf); 19744 } else if (!strcasecmp(var->name, "Content-Length")) { 19745 ast_log(LOG_WARNING, "it is not necessary to specify Content-Length in sip_notify.conf, ignoring\n"); 19746 } else { 19747 header->next = ast_variable_new(var->name, buf, ""); 19748 header = header->next; 19749 } 19750 } 19751 19752 /* Now that we have the peer's address, set our ip and change callid */ 19753 ast_sip_ouraddrfor(&p->sa, &p->ourip, p); 19754 build_via(p); 19755 19756 change_callid_pvt(p, NULL); 19757 19758 ast_cli(a->fd, "Sending NOTIFY of type '%s' to '%s'\n", a->argv[2], a->argv[i]); 19759 sip_scheddestroy(p, SIP_TRANS_TIMEOUT); 19760 transmit_invite(p, SIP_NOTIFY, 0, 2, NULL); 19761 dialog_unref(p, "bump down the count of p since we're done with it."); 19762 } 19763 19764 return CLI_SUCCESS; 19765 }
| static int sip_debug_test_addr | ( | const struct ast_sockaddr * | addr | ) | [inline, static] |
See if we pass debug IP filter.
Definition at line 3372 of file chan_sip.c.
References ast_sockaddr_cmp(), ast_sockaddr_cmp_addr(), ast_sockaddr_isnull(), ast_sockaddr_port, and debugaddr.
Referenced by check_peer_ok(), handle_request_do(), and sip_debug_test_pvt().
03373 { 03374 /* Can't debug if sipdebug is not enabled */ 03375 if (!sipdebug) { 03376 return 0; 03377 } 03378 03379 /* A null debug_addr means we'll debug any address */ 03380 if (ast_sockaddr_isnull(&debugaddr)) { 03381 return 1; 03382 } 03383 03384 /* If no port was specified for a debug address, just compare the 03385 * addresses, otherwise compare the address and port 03386 */ 03387 if (ast_sockaddr_port(&debugaddr)) { 03388 return !ast_sockaddr_cmp(&debugaddr, addr); 03389 } else { 03390 return !ast_sockaddr_cmp_addr(&debugaddr, addr); 03391 } 03392 }
| static int sip_debug_test_pvt | ( | struct sip_pvt * | p | ) | [inline, static] |
Test PVT for debugging output.
Definition at line 3411 of file chan_sip.c.
References sip_debug_test_addr(), and sip_real_dst().
Referenced by __sip_destroy(), add_sdp(), build_route(), check_via(), do_register_auth(), get_also_info(), get_destination(), get_rdnis(), get_refer_info(), handle_incoming(), process_sdp(), process_sdp_a_audio(), process_sdp_a_text(), process_sdp_a_video(), receive_message(), retrans_pkt(), send_request(), send_response(), set_destination(), sip_scheddestroy(), sip_sendhtml(), sip_sendtext(), and transmit_register().
03412 { 03413 if (!sipdebug) { 03414 return 0; 03415 } 03416 return sip_debug_test_addr(sip_real_dst(p)); 03417 }
| struct sip_pvt* sip_destroy | ( | struct sip_pvt * | p | ) | [read] |
Destroy SIP call structure. Make it return NULL so the caller can do things like foo = sip_destroy(foo); and reduce the chance of bugs due to dangling pointers.
Definition at line 6296 of file chan_sip.c.
References __sip_destroy(), ast_debug, and TRUE.
Referenced by sip_destroy_fn().
06297 { 06298 ast_debug(3, "Destroying SIP dialog %s\n", p->callid); 06299 __sip_destroy(p, TRUE, TRUE); 06300 return NULL; 06301 }
| static void sip_destroy_fn | ( | void * | p | ) | [static] |
Definition at line 6286 of file chan_sip.c.
References sip_destroy().
Referenced by sip_alloc().
06287 { 06288 sip_destroy(p); 06289 }
| static void sip_destroy_peer | ( | struct sip_peer * | peer | ) | [static] |
Destroy peer object from memory.
Definition at line 4828 of file chan_sip.c.
References ao2_ref, ao2_t_ref, ast_atomic_fetchadd_int(), ast_cc_config_params_destroy(), ast_debug, ast_free_ha(), ast_string_field_free_memory, ast_test_flag, ast_variables_destroy(), clear_peer_mailboxes(), dialog_unlink_all(), FALSE, and register_peer_exten().
Referenced by sip_destroy_peer_fn().
04829 { 04830 ast_debug(3, "Destroying SIP peer %s\n", peer->name); 04831 04832 /* 04833 * Remove any mailbox event subscriptions for this peer before 04834 * we destroy anything. An event subscription callback may be 04835 * happening right now. 04836 */ 04837 clear_peer_mailboxes(peer); 04838 04839 if (peer->outboundproxy) { 04840 ao2_ref(peer->outboundproxy, -1); 04841 peer->outboundproxy = NULL; 04842 } 04843 04844 /* Delete it, it needs to disappear */ 04845 if (peer->call) { 04846 dialog_unlink_all(peer->call); 04847 peer->call = dialog_unref(peer->call, "peer->call is being unset"); 04848 } 04849 04850 if (peer->mwipvt) { /* We have an active subscription, delete it */ 04851 dialog_unlink_all(peer->mwipvt); 04852 peer->mwipvt = dialog_unref(peer->mwipvt, "unreffing peer->mwipvt"); 04853 } 04854 04855 if (peer->chanvars) { 04856 ast_variables_destroy(peer->chanvars); 04857 peer->chanvars = NULL; 04858 } 04859 04860 register_peer_exten(peer, FALSE); 04861 ast_free_ha(peer->ha); 04862 ast_free_ha(peer->directmediaha); 04863 if (peer->selfdestruct) 04864 ast_atomic_fetchadd_int(&apeerobjs, -1); 04865 else if (!ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && peer->is_realtime) { 04866 ast_atomic_fetchadd_int(&rpeerobjs, -1); 04867 ast_debug(3, "-REALTIME- peer Destroyed. Name: %s. Realtime Peer objects: %d\n", peer->name, rpeerobjs); 04868 } else 04869 ast_atomic_fetchadd_int(&speerobjs, -1); 04870 if (peer->auth) { 04871 ao2_t_ref(peer->auth, -1, "Removing peer authentication"); 04872 peer->auth = NULL; 04873 } 04874 04875 if (peer->socket.tcptls_session) { 04876 ao2_ref(peer->socket.tcptls_session, -1); 04877 peer->socket.tcptls_session = NULL; 04878 } 04879 04880 ast_cc_config_params_destroy(peer->cc_params); 04881 04882 ast_string_field_free_memory(peer); 04883 }
| static void sip_destroy_peer_fn | ( | void * | peer | ) | [static] |
Definition at line 4822 of file chan_sip.c.
References sip_destroy_peer().
Referenced by build_peer(), and temp_peer().
04823 { 04824 sip_destroy_peer(peer); 04825 }
| static int sip_devicestate | ( | void * | data | ) | [static] |
Part of PBX channel interface.
If we have qualify on and the device is not reachable, regardless of registration state we return AST_DEVICE_UNAVAILABLE
For peers with call limit:
For peers without call limit:
Peers that does not have a known call and can't be reached by OPTIONS
If we return AST_DEVICE_UNKNOWN, the device state engine will try to find out a state by walking the channel list.
The queue system (app_queue.c) treats a member as "active" if devicestate is != AST_DEVICE_UNAVAILBALE && != AST_DEVICE_INVALID
When placing a call to the queue member, queue system sets a member to busy if != AST_DEVICE_NOT_INUSE and != AST_DEVICE_UNKNOWN
Definition at line 27209 of file chan_sip.c.
References ast_debug, AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, AST_DEVICE_ONHOLD, AST_DEVICE_RINGING, AST_DEVICE_RINGINUSE, AST_DEVICE_UNAVAILABLE, ast_sockaddr_isnull(), ast_strdupa, FALSE, find_peer(), TRUE, and unref_peer().
27210 { 27211 char *host; 27212 char *tmp; 27213 struct sip_peer *p; 27214 27215 int res = AST_DEVICE_INVALID; 27216 27217 /* make sure data is not null. Maybe unnecessary, but better be safe */ 27218 host = ast_strdupa(data ? data : ""); 27219 if ((tmp = strchr(host, '@'))) 27220 host = tmp + 1; 27221 27222 ast_debug(3, "Checking device state for peer %s\n", host); 27223 27224 /* If find_peer asks for a realtime peer, then this breaks rtautoclear. This 27225 * is because when a peer tries to autoexpire, the last thing it does is to 27226 * queue up an event telling the system that the devicestate has changed 27227 * (presumably to unavailable). If we ask for a realtime peer here, this would 27228 * load it BACK into memory, thus defeating the point of trying to clear dead 27229 * hosts out of memory. 27230 */ 27231 if ((p = find_peer(host, NULL, FALSE, FINDALLDEVICES, TRUE, 0))) { 27232 if (!(ast_sockaddr_isnull(&p->addr) && ast_sockaddr_isnull(&p->defaddr))) { 27233 /* we have an address for the peer */ 27234 27235 /* Check status in this order 27236 - Hold 27237 - Ringing 27238 - Busy (enforced only by call limit) 27239 - Inuse (we have a call) 27240 - Unreachable (qualify) 27241 If we don't find any of these state, report AST_DEVICE_NOT_INUSE 27242 for registered devices */ 27243 27244 if (p->onHold) 27245 /* First check for hold or ring states */ 27246 res = AST_DEVICE_ONHOLD; 27247 else if (p->inRinging) { 27248 if (p->inRinging == p->inUse) 27249 res = AST_DEVICE_RINGING; 27250 else 27251 res = AST_DEVICE_RINGINUSE; 27252 } else if (p->call_limit && (p->inUse == p->call_limit)) 27253 /* check call limit */ 27254 res = AST_DEVICE_BUSY; 27255 else if (p->call_limit && p->busy_level && p->inUse >= p->busy_level) 27256 /* We're forcing busy before we've reached the call limit */ 27257 res = AST_DEVICE_BUSY; 27258 else if (p->call_limit && p->inUse) 27259 /* Not busy, but we do have a call */ 27260 res = AST_DEVICE_INUSE; 27261 else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0))) 27262 /* We don't have a call. Are we reachable at all? Requires qualify= */ 27263 res = AST_DEVICE_UNAVAILABLE; 27264 else /* Default reply if we're registered and have no other data */ 27265 res = AST_DEVICE_NOT_INUSE; 27266 } else { 27267 /* there is no address, it's unavailable */ 27268 res = AST_DEVICE_UNAVAILABLE; 27269 } 27270 unref_peer(p, "unref_peer, from sip_devicestate, release ref from find_peer"); 27271 } 27272 27273 return res; 27274 }
| static char * sip_do_debug | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Turn on SIP debugging (CLI command).
Definition at line 19637 of file chan_sip.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sip_peer(), debugaddr, ast_cli_args::fd, ast_cli_args::n, ast_cli_args::pos, sip_do_debug_ip(), sip_do_debug_peer(), ast_cli_entry::usage, and ast_cli_args::word.
19638 { 19639 int oldsipdebug = sipdebug & sip_debug_console; 19640 const char *what; 19641 19642 if (cmd == CLI_INIT) { 19643 e->command = "sip set debug {on|off|ip|peer}"; 19644 e->usage = 19645 "Usage: sip set debug {off|on|ip addr[:port]|peer peername}\n" 19646 " Globally disables dumping of SIP packets,\n" 19647 " or enables it either globally or for a (single)\n" 19648 " IP address or registered peer.\n"; 19649 return NULL; 19650 } else if (cmd == CLI_GENERATE) { 19651 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer")) 19652 return complete_sip_peer(a->word, a->n, 0); 19653 return NULL; 19654 } 19655 19656 what = a->argv[e->args-1]; /* guaranteed to exist */ 19657 if (a->argc == e->args) { /* on/off */ 19658 if (!strcasecmp(what, "on")) { 19659 sipdebug |= sip_debug_console; 19660 sipdebug_text = 1; /*! \note this can be a special debug command - "sip debug text" or something */ 19661 memset(&debugaddr, 0, sizeof(debugaddr)); 19662 ast_cli(a->fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 19663 return CLI_SUCCESS; 19664 } else if (!strcasecmp(what, "off")) { 19665 sipdebug &= ~sip_debug_console; 19666 sipdebug_text = 0; 19667 ast_cli(a->fd, "SIP Debugging Disabled\n"); 19668 return CLI_SUCCESS; 19669 } 19670 } else if (a->argc == e->args +1) {/* ip/peer */ 19671 if (!strcasecmp(what, "ip")) 19672 return sip_do_debug_ip(a->fd, a->argv[e->args]); 19673 else if (!strcasecmp(what, "peer")) 19674 return sip_do_debug_peer(a->fd, a->argv[e->args]); 19675 } 19676 return CLI_SHOWUSAGE; /* default, failure */ 19677 }
| static char * sip_do_debug_ip | ( | int | fd, | |
| const char * | arg | |||
| ) | [static] |
Enable SIP Debugging for a single IP.
Definition at line 19606 of file chan_sip.c.
References ast_cli(), ast_sockaddr_resolve_first_af(), ast_sockaddr_stringify_addr(), CLI_SHOWUSAGE, CLI_SUCCESS, and debugaddr.
Referenced by sip_do_debug().
19607 { 19608 if (ast_sockaddr_resolve_first_af(&debugaddr, arg, 0, 0)) { 19609 return CLI_SHOWUSAGE; 19610 } 19611 19612 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_sockaddr_stringify_addr(&debugaddr)); 19613 sipdebug |= sip_debug_console; 19614 19615 return CLI_SUCCESS; 19616 }
| static char * sip_do_debug_peer | ( | int | fd, | |
| const char * | arg | |||
| ) | [static] |
Turn on SIP debugging for a given peer.
Definition at line 19619 of file chan_sip.c.
References ast_cli(), ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_stringify_addr(), CLI_SUCCESS, debugaddr, FALSE, find_peer(), TRUE, and unref_peer().
Referenced by sip_do_debug().
19620 { 19621 struct sip_peer *peer = find_peer(arg, NULL, TRUE, FINDPEERS, FALSE, 0); 19622 if (!peer) 19623 ast_cli(fd, "No such peer '%s'\n", arg); 19624 else if (ast_sockaddr_isnull(&peer->addr)) 19625 ast_cli(fd, "Unable to get IP address of peer '%s'\n", arg); 19626 else { 19627 ast_sockaddr_copy(&debugaddr, &peer->addr); 19628 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_sockaddr_stringify_addr(&debugaddr)); 19629 sipdebug |= sip_debug_console; 19630 } 19631 if (peer) 19632 unref_peer(peer, "sip_do_debug_peer: unref_peer, from find_peer call"); 19633 return CLI_SUCCESS; 19634 }
| static int sip_do_reload | ( | enum channelreloadreason | reason | ) | [static] |
Reload module.
Definition at line 30573 of file chan_sip.c.
References ast_debug, ast_sched_dump(), reload_config(), sip_poke_all_peers(), sip_send_all_mwi_subscriptions(), sip_send_all_registers(), and unlink_marked_peers_from_tables().
Referenced by do_monitor().
30574 { 30575 time_t start_poke, end_poke; 30576 30577 reload_config(reason); 30578 ast_sched_dump(sched); 30579 30580 start_poke = time(0); 30581 /* Prune peers who still are supposed to be deleted */ 30582 unlink_marked_peers_from_tables(); 30583 30584 ast_debug(4, "--------------- Done destroying pruned peers\n"); 30585 30586 /* Send qualify (OPTIONS) to all peers */ 30587 sip_poke_all_peers(); 30588 30589 /* Register with all services */ 30590 sip_send_all_registers(); 30591 30592 sip_send_all_mwi_subscriptions(); 30593 30594 end_poke = time(0); 30595 30596 ast_debug(4, "do_reload finished. peer poke/prune reg contact time = %d sec.\n", (int)(end_poke-start_poke)); 30597 30598 ast_debug(4, "--------------- SIP reload done\n"); 30599 30600 return 0; 30601 }
| static int sip_dtmfmode | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Set the DTMFmode for an outbound SIP call (application).
Definition at line 30256 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_log(), AST_RTP_DTMF, ast_rtp_instance_set_prop(), AST_RTP_PROPERTY_DTMF, ast_set_flag, ast_test_flag, disable_dsp_detect(), enable_dsp_detect(), LOG_WARNING, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech, and ast_channel::tech_pvt.
Referenced by load_module().
30257 { 30258 struct sip_pvt *p; 30259 const char *mode = data; 30260 30261 if (!data) { 30262 ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n"); 30263 return 0; 30264 } 30265 ast_channel_lock(chan); 30266 if (!IS_SIP_TECH(chan->tech)) { 30267 ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n"); 30268 ast_channel_unlock(chan); 30269 return 0; 30270 } 30271 p = chan->tech_pvt; 30272 if (!p) { 30273 ast_channel_unlock(chan); 30274 return 0; 30275 } 30276 sip_pvt_lock(p); 30277 if (!strcasecmp(mode, "info")) { 30278 ast_clear_flag(&p->flags[0], SIP_DTMF); 30279 ast_set_flag(&p->flags[0], SIP_DTMF_INFO); 30280 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 30281 } else if (!strcasecmp(mode, "shortinfo")) { 30282 ast_clear_flag(&p->flags[0], SIP_DTMF); 30283 ast_set_flag(&p->flags[0], SIP_DTMF_SHORTINFO); 30284 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 30285 } else if (!strcasecmp(mode, "rfc2833")) { 30286 ast_clear_flag(&p->flags[0], SIP_DTMF); 30287 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 30288 p->jointnoncodeccapability |= AST_RTP_DTMF; 30289 } else if (!strcasecmp(mode, "inband")) { 30290 ast_clear_flag(&p->flags[0], SIP_DTMF); 30291 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 30292 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 30293 } else { 30294 ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n", mode); 30295 } 30296 if (p->rtp) 30297 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 30298 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || 30299 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) { 30300 enable_dsp_detect(p); 30301 } else { 30302 disable_dsp_detect(p); 30303 } 30304 sip_pvt_unlock(p); 30305 ast_channel_unlock(chan); 30306 return 0; 30307 }
| static void sip_dump_history | ( | struct sip_pvt * | dialog | ) | [static] |
Dump SIP history to debug log file at end of lifespan for SIP dialog.
Definition at line 19406 of file chan_sip.c.
References ast_debug, AST_LIST_TRAVERSE, ast_log(), LOG_NOTICE, and option_debug.
Referenced by __sip_destroy().
19407 { 19408 int x = 0; 19409 struct sip_history *hist; 19410 static int errmsg = 0; 19411 19412 if (!dialog) 19413 return; 19414 19415 if (!option_debug && !sipdebug) { 19416 if (!errmsg) { 19417 ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n"); 19418 errmsg = 1; 19419 } 19420 return; 19421 } 19422 19423 ast_debug(1, "\n---------- SIP HISTORY for '%s' \n", dialog->callid); 19424 if (dialog->subscribed) 19425 ast_debug(1, " * Subscription\n"); 19426 else 19427 ast_debug(1, " * SIP Call\n"); 19428 if (dialog->history) 19429 AST_LIST_TRAVERSE(dialog->history, hist, list) 19430 ast_debug(1, " %-3.3d. %s\n", ++x, hist->event); 19431 if (!x) 19432 ast_debug(1, "Call '%s' has no history\n", dialog->callid); 19433 ast_debug(1, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid); 19434 }
| static int sip_epa_register | ( | const struct epa_static_data * | static_data | ) | [static] |
Definition at line 851 of file chan_sip.c.
References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, and AST_LIST_UNLOCK.
Referenced by load_module().
00852 { 00853 struct epa_backend *backend = ast_calloc(1, sizeof(*backend)); 00854 00855 if (!backend) { 00856 return -1; 00857 } 00858 00859 backend->static_data = static_data; 00860 00861 AST_LIST_LOCK(&epa_static_data_list); 00862 AST_LIST_INSERT_TAIL(&epa_static_data_list, backend, next); 00863 AST_LIST_UNLOCK(&epa_static_data_list); 00864 return 0; 00865 }
| static void sip_epa_unregister_all | ( | void | ) | [static] |
Definition at line 867 of file chan_sip.c.
References ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, and AST_LIST_UNLOCK.
Referenced by unload_module().
00868 { 00869 struct epa_backend *backend; 00870 00871 AST_LIST_LOCK(&epa_static_data_list); 00872 while ((backend = AST_LIST_REMOVE_HEAD(&epa_static_data_list, next))) { 00873 ast_free(backend); 00874 } 00875 AST_LIST_UNLOCK(&epa_static_data_list); 00876 }
| static int sip_fixup | ( | struct ast_channel * | oldchan, | |
| struct ast_channel * | newchan | |||
| ) | [static] |
sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links
Definition at line 6872 of file chan_sip.c.
References append_history, ast_debug, AST_FLAG_ZOMBIE, ast_log(), ast_test_flag, LOG_WARNING, sip_pvt_lock, sip_pvt_unlock, sip_set_rtp_peer(), and ast_channel::tech_pvt.
06873 { 06874 int ret = -1; 06875 struct sip_pvt *p; 06876 06877 if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE)) 06878 ast_debug(1, "New channel is zombie\n"); 06879 if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE)) 06880 ast_debug(1, "Old channel is zombie\n"); 06881 06882 if (!newchan || !newchan->tech_pvt) { 06883 if (!newchan) 06884 ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name); 06885 else 06886 ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name); 06887 return -1; 06888 } 06889 p = newchan->tech_pvt; 06890 06891 sip_pvt_lock(p); 06892 append_history(p, "Masq", "Old channel: %s\n", oldchan->name); 06893 append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name); 06894 if (p->owner != oldchan) 06895 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner); 06896 else { 06897 p->owner = newchan; 06898 /* Re-invite RTP back to Asterisk. Needed if channel is masqueraded out of a native 06899 RTP bridge (i.e., RTP not going through Asterisk): RTP bridge code might not be 06900 able to do this if the masquerade happens before the bridge breaks (e.g., AMI 06901 redirect of both channels). Note that a channel can not be masqueraded *into* 06902 a native bridge. So there is no danger that this breaks a native bridge that 06903 should stay up. */ 06904 sip_set_rtp_peer(newchan, NULL, NULL, 0, 0, 0); 06905 ret = 0; 06906 } 06907 ast_debug(3, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name); 06908 06909 sip_pvt_unlock(p); 06910 return ret; 06911 }
| static const char * sip_get_callid | ( | struct ast_channel * | chan | ) | [static] |
Deliver SIP call ID for the call.
Definition at line 4676 of file chan_sip.c.
References ast_channel::tech_pvt.
| static int sip_get_cc_information | ( | struct sip_request * | req, | |
| char * | subscribe_uri, | |||
| size_t | size, | |||
| enum ast_cc_service_type * | service | |||
| ) | [static] |
Definition at line 2067 of file chan_sip.c.
References AST_CC_NONE, ast_copy_string(), ast_strdupa, ast_strlen_zero(), get_header(), get_in_brackets(), and service_string_to_service_type().
Referenced by sip_handle_cc().
02068 { 02069 char *call_info = ast_strdupa(get_header(req, "Call-Info")); 02070 char *uri; 02071 char *purpose; 02072 char *service_str; 02073 static const char cc_purpose[] = "purpose=call-completion"; 02074 static const int cc_purpose_len = sizeof(cc_purpose) - 1; 02075 02076 if (ast_strlen_zero(call_info)) { 02077 /* No Call-Info present. Definitely no CC offer */ 02078 return -1; 02079 } 02080 02081 uri = strsep(&call_info, ";"); 02082 02083 while ((purpose = strsep(&call_info, ";"))) { 02084 if (!strncmp(purpose, cc_purpose, cc_purpose_len)) { 02085 break; 02086 } 02087 } 02088 if (!purpose) { 02089 /* We didn't find the appropriate purpose= parameter. Oh well */ 02090 return -1; 02091 } 02092 02093 /* Okay, call-completion has been offered. Let's figure out what type of service this is */ 02094 while ((service_str = strsep(&call_info, ";"))) { 02095 if (!strncmp(service_str, "m=", 2)) { 02096 break; 02097 } 02098 } 02099 if (!service_str) { 02100 /* So they didn't offer a particular service, We'll just go with CCBS since it really 02101 * doesn't matter anyway 02102 */ 02103 service_str = "BS"; 02104 } else { 02105 /* We already determined that there is an "m=" so no need to check 02106 * the result of this strsep 02107 */ 02108 strsep(&service_str, "="); 02109 } 02110 02111 if ((*service = service_string_to_service_type(service_str)) == AST_CC_NONE) { 02112 /* Invalid service offered */ 02113 return -1; 02114 } 02115 02116 ast_copy_string(subscribe_uri, get_in_brackets(uri), size); 02117 02118 return 0; 02119 }
| static format_t sip_get_codec | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 30236 of file chan_sip.c.
References ast_channel::tech_pvt.
30237 { 30238 struct sip_pvt *p = chan->tech_pvt; 30239 return p->peercapability ? p->peercapability : p->capability; 30240 }
| static enum ast_rtp_glue_result sip_get_rtp_peer | ( | struct ast_channel * | chan, | |
| struct ast_rtp_instance ** | instance | |||
| ) | [static] |
Definition at line 29947 of file chan_sip.c.
References ao2_ref, apply_directmedia_ha(), ast_bridged_channel(), AST_JB_FORCED, AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_LOCAL, AST_RTP_GLUE_RESULT_REMOTE, ast_test_flag, global_jbconf, sip_pvt_lock, sip_pvt_trylock, sip_pvt_unlock, sip_tech_info, ast_channel::tech, and ast_channel::tech_pvt.
29948 { 29949 struct sip_pvt *p = NULL; 29950 struct ast_channel *opp_chan; 29951 struct sip_pvt *opp = NULL; 29952 enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_LOCAL; 29953 29954 if (!(p = chan->tech_pvt)) { 29955 return AST_RTP_GLUE_RESULT_FORBID; 29956 } 29957 29958 if ((opp_chan = ast_bridged_channel(chan)) && (((opp_chan->tech != &sip_tech) && (opp_chan->tech != &sip_tech_info)) || 29959 (!(opp = opp_chan->tech_pvt)))) { 29960 return AST_RTP_GLUE_RESULT_FORBID; 29961 } 29962 29963 sip_pvt_lock(p); 29964 while (opp && sip_pvt_trylock(opp)) { 29965 sip_pvt_unlock(p); 29966 usleep(1); 29967 sip_pvt_lock(p); 29968 } 29969 29970 if (!(p->rtp)) { 29971 if (opp) { 29972 sip_pvt_unlock(opp); 29973 } 29974 sip_pvt_unlock(p); 29975 return AST_RTP_GLUE_RESULT_FORBID; 29976 } 29977 29978 ao2_ref(p->rtp, +1); 29979 *instance = p->rtp; 29980 29981 if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) { 29982 res = AST_RTP_GLUE_RESULT_REMOTE; 29983 if (opp && !apply_directmedia_ha(p, opp, "audio")) { 29984 res = AST_RTP_GLUE_RESULT_FORBID; 29985 } 29986 } else if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA_NAT)) { 29987 res = AST_RTP_GLUE_RESULT_REMOTE; 29988 } else if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) { 29989 res = AST_RTP_GLUE_RESULT_FORBID; 29990 } 29991 29992 if (opp) { 29993 sip_pvt_unlock(opp); 29994 } 29995 29996 if (p->srtp) { 29997 res = AST_RTP_GLUE_RESULT_FORBID; 29998 } 29999 30000 sip_pvt_unlock(p); 30001 30002 return res; 30003 }
| static enum ast_rtp_glue_result sip_get_trtp_peer | ( | struct ast_channel * | chan, | |
| struct ast_rtp_instance ** | instance | |||
| ) | [static] |
Definition at line 30054 of file chan_sip.c.
References ao2_ref, apply_directmedia_ha(), ast_bridged_channel(), AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_REMOTE, ast_test_flag, sip_pvt_lock, sip_pvt_trylock, sip_pvt_unlock, sip_tech_info, ast_channel::tech, and ast_channel::tech_pvt.
30055 { 30056 struct sip_pvt *p = NULL; 30057 struct ast_channel *opp_chan; 30058 struct sip_pvt *opp = NULL; 30059 enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_FORBID; 30060 30061 if (!(p = chan->tech_pvt)) { 30062 return AST_RTP_GLUE_RESULT_FORBID; 30063 } 30064 30065 if ((opp_chan = ast_bridged_channel(chan)) && (((opp_chan->tech != &sip_tech) && (opp_chan->tech != &sip_tech_info)) || 30066 (!(opp = opp_chan->tech_pvt)))) { 30067 return AST_RTP_GLUE_RESULT_FORBID; 30068 } 30069 30070 sip_pvt_lock(p); 30071 while (opp && sip_pvt_trylock(opp)) { 30072 sip_pvt_unlock(p); 30073 usleep(1); 30074 sip_pvt_lock(p); 30075 } 30076 30077 if (!(p->trtp)) { 30078 if (opp) { 30079 sip_pvt_unlock(opp); 30080 } 30081 sip_pvt_unlock(p); 30082 return AST_RTP_GLUE_RESULT_FORBID; 30083 } 30084 30085 ao2_ref(p->trtp, +1); 30086 *instance = p->trtp; 30087 30088 if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) { 30089 res = AST_RTP_GLUE_RESULT_REMOTE; 30090 if (opp && !apply_directmedia_ha(p, opp, "text")) { 30091 res = AST_RTP_GLUE_RESULT_FORBID; 30092 } 30093 } 30094 30095 if (opp) { 30096 sip_pvt_unlock(opp); 30097 } 30098 sip_pvt_unlock(p); 30099 30100 return res; 30101 }
| static struct ast_udptl * sip_get_udptl_peer | ( | struct ast_channel * | chan | ) | [static, read] |
Definition at line 29867 of file chan_sip.c.
References apply_directmedia_ha(), ast_bridged_channel(), ast_test_flag, sip_pvt_lock, sip_pvt_trylock, sip_pvt_unlock, sip_tech_info, ast_channel::tech, and ast_channel::tech_pvt.
29868 { 29869 struct sip_pvt *p; 29870 struct ast_channel *opp_chan; 29871 struct sip_pvt *opp; 29872 struct ast_udptl *udptl = NULL; 29873 29874 p = chan->tech_pvt; 29875 if (!p) { 29876 return NULL; 29877 } 29878 29879 if (!(opp_chan = ast_bridged_channel(chan))) { 29880 return NULL; 29881 } else if (((opp_chan->tech != &sip_tech) && (opp_chan->tech != &sip_tech_info)) || 29882 (!(opp = opp_chan->tech_pvt))) { 29883 return NULL; 29884 } 29885 29886 sip_pvt_lock(p); 29887 while (sip_pvt_trylock(opp)) { 29888 sip_pvt_unlock(p); 29889 usleep(1); 29890 sip_pvt_lock(p); 29891 } 29892 29893 if (p->udptl && ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) { 29894 if (apply_directmedia_ha(p, opp, "UDPTL T.38 data")) { 29895 udptl = p->udptl; 29896 } 29897 } 29898 29899 sip_pvt_unlock(opp); 29900 sip_pvt_unlock(p); 29901 return udptl; 29902 }
| static enum ast_rtp_glue_result sip_get_vrtp_peer | ( | struct ast_channel * | chan, | |
| struct ast_rtp_instance ** | instance | |||
| ) | [static] |
Definition at line 30005 of file chan_sip.c.
References ao2_ref, apply_directmedia_ha(), ast_bridged_channel(), AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_REMOTE, ast_test_flag, sip_pvt_lock, sip_pvt_trylock, sip_pvt_unlock, sip_tech_info, ast_channel::tech, and ast_channel::tech_pvt.
30006 { 30007 struct sip_pvt *p = NULL; 30008 struct ast_channel *opp_chan; 30009 struct sip_pvt *opp = NULL; 30010 enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_FORBID; 30011 30012 if (!(p = chan->tech_pvt)) { 30013 return AST_RTP_GLUE_RESULT_FORBID; 30014 } 30015 30016 if ((opp_chan = ast_bridged_channel(chan)) && (((opp_chan->tech != &sip_tech) && (opp_chan->tech != &sip_tech_info)) || 30017 (!(opp = opp_chan->tech_pvt)))) { 30018 return AST_RTP_GLUE_RESULT_FORBID; 30019 } 30020 30021 sip_pvt_lock(p); 30022 while (opp && sip_pvt_trylock(opp)) { 30023 sip_pvt_unlock(p); 30024 usleep(1); 30025 sip_pvt_lock(p); 30026 } 30027 30028 if (!(p->vrtp)) { 30029 if (opp) { 30030 sip_pvt_unlock(opp); 30031 } 30032 sip_pvt_unlock(p); 30033 return AST_RTP_GLUE_RESULT_FORBID; 30034 } 30035 30036 ao2_ref(p->vrtp, +1); 30037 *instance = p->vrtp; 30038 30039 if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) { 30040 res = AST_RTP_GLUE_RESULT_REMOTE; 30041 if (opp && !apply_directmedia_ha(p, opp, "video")) { 30042 res = AST_RTP_GLUE_RESULT_FORBID; 30043 } 30044 } 30045 30046 if (opp) { 30047 sip_pvt_unlock(opp); 30048 } 30049 sip_pvt_unlock(p); 30050 30051 return res; 30052 }
| static void sip_handle_cc | ( | struct sip_pvt * | pvt, | |
| struct sip_request * | req, | |||
| enum ast_cc_service_type | service | |||
| ) | [static] |
Definition at line 2138 of file chan_sip.c.
References ao2_ref, AST_CC_GENERIC_MONITOR_TYPE, ast_cc_get_current_core_id(), AST_CC_MONITOR_ALWAYS, AST_CC_MONITOR_GENERIC, AST_CC_MONITOR_NATIVE, AST_CC_MONITOR_NEVER, ast_channel_get_device_name(), AST_CHANNEL_NAME, ast_get_cc_monitor_policy(), ast_module_ref(), ast_queue_cc_frame(), sip_get_cc_information(), and sip_monitor_instance_init().
Referenced by handle_response(), and handle_response_invite().
02139 { 02140 enum ast_cc_monitor_policies monitor_policy = ast_get_cc_monitor_policy(pvt->cc_params); 02141 int core_id; 02142 char interface_name[AST_CHANNEL_NAME]; 02143 02144 if (monitor_policy == AST_CC_MONITOR_NEVER) { 02145 /* Don't bother, just return */ 02146 return; 02147 } 02148 02149 if ((core_id = ast_cc_get_current_core_id(pvt->owner)) == -1) { 02150 /* For some reason, CC is invalid, so don't try it! */ 02151 return; 02152 } 02153 02154 ast_channel_get_device_name(pvt->owner, interface_name, sizeof(interface_name)); 02155 02156 if (monitor_policy == AST_CC_MONITOR_ALWAYS || monitor_policy == AST_CC_MONITOR_NATIVE) { 02157 char subscribe_uri[SIPBUFSIZE]; 02158 char device_name[AST_CHANNEL_NAME]; 02159 enum ast_cc_service_type offered_service; 02160 struct sip_monitor_instance *monitor_instance; 02161 if (sip_get_cc_information(req, subscribe_uri, sizeof(subscribe_uri), &offered_service)) { 02162 /* If CC isn't being offered to us, or for some reason the CC offer is 02163 * not formatted correctly, then it may still be possible to use generic 02164 * call completion since the monitor policy may be "always" 02165 */ 02166 goto generic; 02167 } 02168 ast_channel_get_device_name(pvt->owner, device_name, sizeof(device_name)); 02169 if (!(monitor_instance = sip_monitor_instance_init(core_id, subscribe_uri, pvt->peername, device_name))) { 02170 /* Same deal. We can try using generic still */ 02171 goto generic; 02172 } 02173 /* We bump the refcount of chan_sip because once we queue this frame, the CC core 02174 * will have a reference to callbacks in this module. We decrement the module 02175 * refcount once the monitor destructor is called 02176 */ 02177 ast_module_ref(ast_module_info->self); 02178 ast_queue_cc_frame(pvt->owner, "SIP", pvt->dialstring, offered_service, monitor_instance); 02179 ao2_ref(monitor_instance, -1); 02180 return; 02181 } 02182 02183 generic: 02184 if (monitor_policy == AST_CC_MONITOR_GENERIC || monitor_policy == AST_CC_MONITOR_ALWAYS) { 02185 ast_queue_cc_frame(pvt->owner, AST_CC_GENERIC_MONITOR_TYPE, interface_name, service, NULL); 02186 } 02187 }
| static int sip_hangup | ( | struct ast_channel * | ast | ) | [static] |
sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup
Definition at line 6490 of file chan_sip.c.
References __sip_semi_ack(), ast_channel::_state, append_history, ast_bridged_channel(), ast_cause2str(), AST_CAUSE_ANSWERED_ELSEWHERE, ast_channel_trylock, ast_channel_unlock, ast_clear_flag, ast_debug, AST_FLAG_ANSWERED_ELSEWHERE, ast_log(), AST_MAX_USER_FIELD, ast_module_unref(), ast_rtp_instance_get_quality(), ast_rtp_instance_set_stats_vars(), AST_RTP_INSTANCE_STAT_FIELD_QUALITY, ast_sched_add(), AST_SCHED_DEL_UNREF, ast_set_flag, ast_state2str(), AST_STATE_UP, ast_str_buffer(), ast_str_strlen(), ast_test_flag, CHANNEL_DEADLOCK_AVOIDANCE, disable_dsp_detect(), FALSE, find_sip_method(), hangup_cause2sip(), ast_channel::hangupcause, LOG_WARNING, pbx_builtin_setvar_helper(), pvt_set_needdestroy(), quality, reinvite_timeout(), sip_cancel_destroy(), sip_pvt_lock, sip_pvt_trylock, sip_pvt_unlock, sip_scheddestroy(), stop_media_flows(), stop_session_timer(), ast_channel::tech, ast_channel::tech_pvt, transmit_request(), transmit_request_with_auth(), transmit_response_reliable(), TRUE, and update_call_counter().
06491 { 06492 struct sip_pvt *p = ast->tech_pvt; 06493 int needcancel = FALSE; 06494 int needdestroy = 0; 06495 struct ast_channel *oldowner = ast; 06496 06497 if (!p) { 06498 ast_debug(1, "Asked to hangup channel that was not connected\n"); 06499 return 0; 06500 } 06501 if (ast_test_flag(ast, AST_FLAG_ANSWERED_ELSEWHERE) || ast->hangupcause == AST_CAUSE_ANSWERED_ELSEWHERE) { 06502 ast_debug(1, "This call was answered elsewhere\n"); 06503 if (ast->hangupcause == AST_CAUSE_ANSWERED_ELSEWHERE) { 06504 ast_debug(1, "####### It's the cause code, buddy. The cause code!!!\n"); 06505 } 06506 append_history(p, "Cancel", "Call answered elsewhere"); 06507 p->answered_elsewhere = TRUE; 06508 } 06509 06510 /* Store hangupcause locally in PVT so we still have it before disconnect */ 06511 if (p->owner) 06512 p->hangupcause = p->owner->hangupcause; 06513 06514 if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 06515 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 06516 if (sipdebug) 06517 ast_debug(1, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 06518 update_call_counter(p, DEC_CALL_LIMIT); 06519 } 06520 ast_debug(4, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid); 06521 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 06522 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */ 06523 p->needdestroy = 0; 06524 if (p->owner) { 06525 p->owner->tech_pvt = dialog_unref(p->owner->tech_pvt, "unref p->owner->tech_pvt"); 06526 sip_pvt_lock(p); 06527 p->owner = NULL; /* Owner will be gone after we return, so take it away */ 06528 sip_pvt_unlock(p); 06529 } 06530 ast_module_unref(ast_module_info->self); 06531 return 0; 06532 } 06533 06534 ast_debug(1, "Hangup call %s, SIP callid %s\n", ast->name, p->callid); 06535 06536 sip_pvt_lock(p); 06537 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 06538 if (sipdebug) 06539 ast_debug(1, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 06540 update_call_counter(p, DEC_CALL_LIMIT); 06541 } 06542 06543 /* Determine how to disconnect */ 06544 if (p->owner != ast) { 06545 ast_log(LOG_WARNING, "Huh? We aren't the owner? Can't hangup call.\n"); 06546 sip_pvt_unlock(p); 06547 return 0; 06548 } 06549 /* If the call is not UP, we need to send CANCEL instead of BYE */ 06550 /* In case of re-invites, the call might be UP even though we have an incomplete invite transaction */ 06551 if (p->invitestate < INV_COMPLETED && p->owner->_state != AST_STATE_UP) { 06552 needcancel = TRUE; 06553 ast_debug(4, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state)); 06554 } 06555 06556 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 06557 06558 append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", ast_cause2str(p->hangupcause)); 06559 06560 /* Disconnect */ 06561 disable_dsp_detect(p); 06562 06563 p->owner = NULL; 06564 ast->tech_pvt = dialog_unref(ast->tech_pvt, "unref ast->tech_pvt"); 06565 06566 ast_module_unref(ast_module_info->self); 06567 /* Do not destroy this pvt until we have timeout or 06568 get an answer to the BYE or INVITE/CANCEL 06569 If we get no answer during retransmit period, drop the call anyway. 06570 (Sorry, mother-in-law, you can't deny a hangup by sending 06571 603 declined to BYE...) 06572 */ 06573 if (p->alreadygone) 06574 needdestroy = 1; /* Set destroy flag at end of this function */ 06575 else if (p->invitestate != INV_CALLING) 06576 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 06577 06578 /* Start the process if it's not already started */ 06579 if (!p->alreadygone && p->initreq.data && ast_str_strlen(p->initreq.data)) { 06580 if (needcancel) { /* Outgoing call, not up */ 06581 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06582 /* if we can't send right now, mark it pending */ 06583 if (p->invitestate == INV_CALLING) { 06584 /* We can't send anything in CALLING state */ 06585 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 06586 /* Do we need a timer here if we don't hear from them at all? Yes we do or else we will get hung dialogs and those are no fun. */ 06587 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 06588 append_history(p, "DELAY", "Not sending cancel, waiting for timeout"); 06589 } else { 06590 struct sip_pkt *cur; 06591 06592 for (cur = p->packets; cur; cur = cur->next) { 06593 __sip_semi_ack(p, cur->seqno, cur->is_resp, cur->method ? cur->method : find_sip_method(ast_str_buffer(cur->data))); 06594 } 06595 p->invitestate = INV_CANCELLED; 06596 /* Send a new request: CANCEL */ 06597 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 06598 /* Actually don't destroy us yet, wait for the 487 on our original 06599 INVITE, but do set an autodestruct just in case we never get it. */ 06600 needdestroy = 0; 06601 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 06602 } 06603 } else { /* Incoming call, not up */ 06604 const char *res; 06605 AST_SCHED_DEL_UNREF(sched, p->provisional_keepalive_sched_id, dialog_unref(p, "when you delete the provisional_keepalive_sched_id, you should dec the refcount for the stored dialog ptr")); 06606 if (p->hangupcause && (res = hangup_cause2sip(p->hangupcause))) 06607 transmit_response_reliable(p, res, &p->initreq); 06608 else 06609 transmit_response_reliable(p, "603 Declined", &p->initreq); 06610 p->invitestate = INV_TERMINATED; 06611 } 06612 } else { /* Call is in UP state, send BYE */ 06613 if (p->stimer->st_active == TRUE) { 06614 stop_session_timer(p); 06615 } 06616 06617 if (!p->pendinginvite) { 06618 struct ast_channel *bridge = ast_bridged_channel(oldowner); 06619 char quality_buf[AST_MAX_USER_FIELD], *quality; 06620 06621 /* We need to get the lock on bridge because ast_rtp_instance_set_stats_vars will attempt 06622 * to lock the bridge. This may get hairy... 06623 */ 06624 while (bridge && ast_channel_trylock(bridge)) { 06625 sip_pvt_unlock(p); 06626 do { 06627 CHANNEL_DEADLOCK_AVOIDANCE(oldowner); 06628 } while (sip_pvt_trylock(p)); 06629 bridge = ast_bridged_channel(oldowner); 06630 } 06631 06632 if (p->rtp) { 06633 ast_rtp_instance_set_stats_vars(oldowner, p->rtp); 06634 } 06635 06636 if (bridge) { 06637 struct sip_pvt *q = bridge->tech_pvt; 06638 06639 if (IS_SIP_TECH(bridge->tech) && q && q->rtp) { 06640 ast_rtp_instance_set_stats_vars(bridge, q->rtp); 06641 } 06642 ast_channel_unlock(bridge); 06643 } 06644 06645 /* 06646 * The channel variables are set below just to get the AMI 06647 * VarSet event because the channel is being hungup. 06648 */ 06649 if (p->rtp && (quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) { 06650 if (p->do_history) { 06651 append_history(p, "RTCPaudio", "Quality:%s", quality); 06652 } 06653 pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", quality); 06654 } 06655 if (p->vrtp && (quality = ast_rtp_instance_get_quality(p->vrtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) { 06656 if (p->do_history) { 06657 append_history(p, "RTCPvideo", "Quality:%s", quality); 06658 } 06659 pbx_builtin_setvar_helper(oldowner, "RTPVIDEOQOS", quality); 06660 } 06661 if (p->trtp && (quality = ast_rtp_instance_get_quality(p->trtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) { 06662 if (p->do_history) { 06663 append_history(p, "RTCPtext", "Quality:%s", quality); 06664 } 06665 pbx_builtin_setvar_helper(oldowner, "RTPTEXTQOS", quality); 06666 } 06667 06668 /* Send a hangup */ 06669 if (oldowner->_state == AST_STATE_UP) { 06670 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 06671 } 06672 06673 } else { 06674 /* Note we will need a BYE when this all settles out 06675 but we can't send one while we have "INVITE" outstanding. */ 06676 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 06677 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 06678 AST_SCHED_DEL_UNREF(sched, p->waitid, dialog_unref(p, "when you delete the waitid sched, you should dec the refcount for the stored dialog ptr")); 06679 if (sip_cancel_destroy(p)) { 06680 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 06681 } 06682 /* If we have an ongoing reinvite, there is a chance that we have gotten a provisional 06683 * response, but something weird has happened and we will never receive a final response. 06684 * So, just in case, check for pending actions after a bit of time to trigger the pending 06685 * bye that we are setting above */ 06686 if (p->ongoing_reinvite && p->reinviteid < 0) { 06687 p->reinviteid = ast_sched_add(sched, 32 * p->timer_t1, reinvite_timeout, dialog_ref(p, "ref for reinvite_timeout")); 06688 } 06689 } 06690 } 06691 } 06692 if (needdestroy) { 06693 pvt_set_needdestroy(p, "hangup"); 06694 } 06695 sip_pvt_unlock(p); 06696 return 0; 06697 }
| static int sip_indicate | ( | struct ast_channel * | ast, | |
| int | condition, | |||
| const void * | data, | |||
| size_t | datalen | |||
| ) | [static] |
Play indication to user With SIP a lot of indications is sent as messages, letting the device play the indication - busy signal, congestion etc.
Definition at line 7130 of file chan_sip.c.
References ast_channel::_state, AST_AOC_D, ast_aoc_decode(), ast_aoc_destroy_decoded(), AST_AOC_E, ast_aoc_get_msg_type(), ast_aoc_get_termination_request(), AST_AOC_REQUEST, AST_AOC_S, AST_CONTROL_AOC, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_FLASH, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, AST_CONTROL_VIDUPDATE, ast_debug, ast_log(), ast_moh_start(), ast_moh_stop(), ast_rtp_instance_change_source(), ast_rtp_instance_update_source(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_UP, ast_test_flag, initialize_udptl(), interpret_t38_parameters(), LOG_ERROR, LOG_WARNING, sip_alreadygone(), sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, transmit_info_with_aoc(), transmit_info_with_vidupdate(), transmit_provisional_response(), transmit_response(), transmit_response_reliable(), TRUE, update_connectedline(), and update_redirecting().
07131 { 07132 struct sip_pvt *p = ast->tech_pvt; 07133 int res = 0; 07134 07135 if (!p) { 07136 ast_debug(1, "Asked to indicate condition on channel %s with no pvt; ignoring\n", 07137 ast->name); 07138 return res; 07139 } 07140 07141 sip_pvt_lock(p); 07142 switch(condition) { 07143 case AST_CONTROL_RINGING: 07144 if (ast->_state == AST_STATE_RING) { 07145 p->invitestate = INV_EARLY_MEDIA; 07146 if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) || 07147 (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) { 07148 /* Send 180 ringing if out-of-band seems reasonable */ 07149 transmit_provisional_response(p, "180 Ringing", &p->initreq, 0); 07150 ast_set_flag(&p->flags[0], SIP_RINGING); 07151 if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES) 07152 break; 07153 } else { 07154 /* Well, if it's not reasonable, just send in-band */ 07155 } 07156 } 07157 res = -1; 07158 break; 07159 case AST_CONTROL_BUSY: 07160 if (ast->_state != AST_STATE_UP) { 07161 transmit_response_reliable(p, "486 Busy Here", &p->initreq); 07162 p->invitestate = INV_COMPLETED; 07163 sip_alreadygone(p); 07164 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 07165 break; 07166 } 07167 res = -1; 07168 break; 07169 case AST_CONTROL_CONGESTION: 07170 if (ast->_state != AST_STATE_UP) { 07171 transmit_response_reliable(p, "503 Service Unavailable", &p->initreq); 07172 p->invitestate = INV_COMPLETED; 07173 sip_alreadygone(p); 07174 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 07175 break; 07176 } 07177 res = -1; 07178 break; 07179 case AST_CONTROL_INCOMPLETE: 07180 if (ast->_state != AST_STATE_UP) { 07181 switch (ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) { 07182 case SIP_PAGE2_ALLOWOVERLAP_YES: 07183 transmit_response_reliable(p, "484 Address Incomplete", &p->initreq); 07184 p->invitestate = INV_COMPLETED; 07185 sip_alreadygone(p); 07186 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 07187 break; 07188 case SIP_PAGE2_ALLOWOVERLAP_DTMF: 07189 /* Just wait for inband DTMF digits */ 07190 break; 07191 default: 07192 /* it actually means no support for overlap */ 07193 transmit_response_reliable(p, "404 Not Found", &p->initreq); 07194 p->invitestate = INV_COMPLETED; 07195 sip_alreadygone(p); 07196 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 07197 break; 07198 } 07199 } 07200 break; 07201 case AST_CONTROL_PROCEEDING: 07202 if ((ast->_state != AST_STATE_UP) && 07203 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 07204 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 07205 transmit_response(p, "100 Trying", &p->initreq); 07206 p->invitestate = INV_PROCEEDING; 07207 break; 07208 } 07209 res = -1; 07210 break; 07211 case AST_CONTROL_PROGRESS: 07212 if ((ast->_state != AST_STATE_UP) && 07213 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 07214 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 07215 p->invitestate = INV_EARLY_MEDIA; 07216 transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE); 07217 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 07218 break; 07219 } 07220 res = -1; 07221 break; 07222 case AST_CONTROL_HOLD: 07223 ast_rtp_instance_update_source(p->rtp); 07224 ast_moh_start(ast, data, p->mohinterpret); 07225 break; 07226 case AST_CONTROL_UNHOLD: 07227 ast_rtp_instance_update_source(p->rtp); 07228 ast_moh_stop(ast); 07229 break; 07230 case AST_CONTROL_VIDUPDATE: /* Request a video frame update */ 07231 if (p->vrtp && !p->novideo) { 07232 transmit_info_with_vidupdate(p); 07233 /* ast_rtcp_send_h261fur(p->vrtp); */ 07234 } else 07235 res = -1; 07236 break; 07237 case AST_CONTROL_T38_PARAMETERS: 07238 res = -1; 07239 if (datalen != sizeof(struct ast_control_t38_parameters)) { 07240 ast_log(LOG_ERROR, "Invalid datalen for AST_CONTROL_T38_PARAMETERS. Expected %d, got %d\n", (int) sizeof(struct ast_control_t38_parameters), (int) datalen); 07241 } else { 07242 const struct ast_control_t38_parameters *parameters = data; 07243 if (!initialize_udptl(p)) { 07244 res = interpret_t38_parameters(p, parameters); 07245 } 07246 } 07247 break; 07248 case AST_CONTROL_SRCUPDATE: 07249 ast_rtp_instance_update_source(p->rtp); 07250 break; 07251 case AST_CONTROL_SRCCHANGE: 07252 ast_rtp_instance_change_source(p->rtp); 07253 break; 07254 case AST_CONTROL_CONNECTED_LINE: 07255 update_connectedline(p, data, datalen); 07256 break; 07257 case AST_CONTROL_REDIRECTING: 07258 update_redirecting(p, data, datalen); 07259 break; 07260 case AST_CONTROL_AOC: 07261 { 07262 struct ast_aoc_decoded *decoded = ast_aoc_decode((struct ast_aoc_encoded *) data, datalen, ast); 07263 if (!decoded) { 07264 ast_log(LOG_ERROR, "Error decoding indicated AOC data\n"); 07265 res = -1; 07266 break; 07267 } 07268 switch (ast_aoc_get_msg_type(decoded)) { 07269 case AST_AOC_REQUEST: 07270 if (ast_aoc_get_termination_request(decoded)) { 07271 /* TODO, once there is a way to get AOC-E on hangup, attempt that here 07272 * before hanging up the channel.*/ 07273 07274 /* The other side has already initiated the hangup. This frame 07275 * just says they are waiting to get AOC-E before completely tearing 07276 * the call down. Since SIP does not support this at the moment go 07277 * ahead and terminate the call here to avoid an unnecessary timeout. */ 07278 ast_debug(1, "AOC-E termination request received on %s. This is not yet supported on sip. Continue with hangup \n", p->owner->name); 07279 ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV); 07280 } 07281 break; 07282 case AST_AOC_D: 07283 case AST_AOC_E: 07284 if (ast_test_flag(&p->flags[2], SIP_PAGE3_SNOM_AOC)) { 07285 transmit_info_with_aoc(p, decoded); 07286 } 07287 break; 07288 case AST_AOC_S: /* S not supported yet */ 07289 default: 07290 break; 07291 } 07292 ast_aoc_destroy_decoded(decoded); 07293 } 07294 break; 07295 case AST_CONTROL_UPDATE_RTP_PEER: /* Absorb this since it is handled by the bridge */ 07296 break; 07297 case AST_CONTROL_FLASH: /* We don't currently handle AST_CONTROL_FLASH here, but it is expected, so we don't need to warn either. */ 07298 res = -1; 07299 break; 07300 case -1: 07301 res = -1; 07302 break; 07303 default: 07304 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition); 07305 res = -1; 07306 break; 07307 } 07308 sip_pvt_unlock(p); 07309 return res; 07310 }
| static int sip_is_xml_parsable | ( | void | ) | [static] |
Definition at line 30441 of file chan_sip.c.
Referenced by load_module().
| static int sip_monitor_instance_cmp_fn | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1844 of file chan_sip.c.
References CMP_MATCH, and CMP_STOP.
Referenced by load_module().
| static void sip_monitor_instance_destructor | ( | void * | data | ) | [static] |
Definition at line 1852 of file chan_sip.c.
References ao2_t_ref, ast_string_field_free_memory, FALSE, sip_pvt_lock, sip_pvt_unlock, transmit_invite(), and transmit_publish().
Referenced by sip_monitor_instance_init().
01853 { 01854 struct sip_monitor_instance *monitor_instance = data; 01855 if (monitor_instance->subscription_pvt) { 01856 sip_pvt_lock(monitor_instance->subscription_pvt); 01857 monitor_instance->subscription_pvt->expiry = 0; 01858 transmit_invite(monitor_instance->subscription_pvt, SIP_SUBSCRIBE, FALSE, 0, monitor_instance->subscribe_uri); 01859 sip_pvt_unlock(monitor_instance->subscription_pvt); 01860 dialog_unref(monitor_instance->subscription_pvt, "Unref monitor instance ref of subscription pvt"); 01861 } 01862 if (monitor_instance->suspension_entry) { 01863 monitor_instance->suspension_entry->body[0] = '\0'; 01864 transmit_publish(monitor_instance->suspension_entry, SIP_PUBLISH_REMOVE ,monitor_instance->notify_uri); 01865 ao2_t_ref(monitor_instance->suspension_entry, -1, "Decrementing suspension entry refcount in sip_monitor_instance_destructor"); 01866 } 01867 ast_string_field_free_memory(monitor_instance); 01868 }
| static int sip_monitor_instance_hash_fn | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 1838 of file chan_sip.c.
Referenced by load_module().
| static struct sip_monitor_instance* sip_monitor_instance_init | ( | int | core_id, | |
| const char *const | subscribe_uri, | |||
| const char *const | peername, | |||
| const char *const | device_name | |||
| ) | [static, read] |
Definition at line 1870 of file chan_sip.c.
References ao2_alloc, ao2_link, ao2_ref, ast_string_field_init, ast_string_field_set, and sip_monitor_instance_destructor().
Referenced by sip_handle_cc().
01871 { 01872 struct sip_monitor_instance *monitor_instance = ao2_alloc(sizeof(*monitor_instance), sip_monitor_instance_destructor); 01873 01874 if (!monitor_instance) { 01875 return NULL; 01876 } 01877 01878 if (ast_string_field_init(monitor_instance, 256)) { 01879 ao2_ref(monitor_instance, -1); 01880 return NULL; 01881 } 01882 01883 ast_string_field_set(monitor_instance, subscribe_uri, subscribe_uri); 01884 ast_string_field_set(monitor_instance, peername, peername); 01885 ast_string_field_set(monitor_instance, device_name, device_name); 01886 monitor_instance->core_id = core_id; 01887 ao2_link(sip_monitor_instances, monitor_instance); 01888 return monitor_instance; 01889 }
| static const char * sip_nat_mode | ( | const struct sip_pvt * | p | ) | [static] |
Display SIP nat mode.
Definition at line 3405 of file chan_sip.c.
References ast_test_flag.
Referenced by check_via(), retrans_pkt(), and send_response().
03406 { 03407 return ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT) ? "NAT" : "no NAT"; 03408 }
| static struct ast_channel* sip_new | ( | struct sip_pvt * | i, | |
| int | state, | |||
| const char * | title, | |||
| const char * | linkedid | |||
| ) | [static, read] |
Initiate a call in the SIP channel.
Definition at line 7323 of file chan_sip.c.
References accountcode, ast_channel::adsicpe, ast_channel::amaflags, ast_party_caller::ani, append_history, AST_ADSI_UNAVAILABLE, ast_atomic_fetchadd_int(), ast_best_codec(), ast_channel_alloc, ast_channel_cc_params_init(), ast_channel_lock, ast_channel_set_fd(), ast_channel_unlock, ast_codec_choose(), ast_copy_string(), ast_debug, ast_exists_extension(), AST_FLAG_DISABLE_DEVSTATE_CACHE, AST_FORMAT_TEXT_MASK, AST_FORMAT_VIDEO_MASK, ast_get_encoded_str(), ast_getformatname_multiple(), ast_jb_configure(), ast_log(), ast_module_ref(), AST_RTP_DTMF_MODE_INBAND, AST_RTP_DTMF_MODE_RFC2833, ast_rtp_instance_dtmf_mode_set(), ast_rtp_instance_fd(), ast_rtp_instance_set_read_format(), ast_rtp_instance_set_write_format(), AST_STATE_RING, ast_strdup, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_fd(), ast_uri_decode(), ast_channel::caller, ast_channel::callgroup, ast_channel::context, ast_channel::dialed, enable_dsp_detect(), EVENT_FLAG_SYSTEM, ast_channel::exten, exten, ast_channel::flags, ast_party_redirecting::from, global_jbconf, ast_party_caller::id, language, LOG_WARNING, manager_event, ast_variable::name, ast_party_id::name, ast_channel::nativeformats, ast_variable::next, ast_party_dialed::number, ast_party_id::number, parkinglot, pbx_builtin_setvar_helper(), ast_channel::pickupgroup, ast_party_number::presentation, ast_party_name::presentation, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::redirecting, ast_channel::rings, sip_cfg, sip_pvt_lock, sip_pvt_unlock, sip_tech_info, ast_party_dialed::str, ast_party_number::str, ast_party_id::tag, ast_channel::tech, ast_channel::tech_pvt, text, ast_party_number::valid, ast_variable::value, and ast_channel::writeformat.
Referenced by handle_request_invite(), and sip_request_call().
07324 { 07325 struct ast_channel *tmp; 07326 struct ast_variable *v = NULL; 07327 format_t fmt; 07328 format_t what; 07329 format_t video; 07330 format_t text; 07331 format_t needvideo = 0; 07332 int needtext = 0; 07333 char buf[SIPBUFSIZE]; 07334 char *exten; 07335 07336 { 07337 const char *my_name; /* pick a good name */ 07338 07339 if (title) { 07340 my_name = title; 07341 } else { 07342 my_name = ast_strdupa(i->fromdomain); 07343 } 07344 07345 sip_pvt_unlock(i); 07346 /* Don't hold a sip pvt lock while we allocate a channel */ 07347 tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, linkedid, i->amaflags, "SIP/%s-%08x", my_name, (unsigned)ast_atomic_fetchadd_int((int *)&chan_idx, +1)); 07348 } 07349 if (!tmp) { 07350 ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n"); 07351 sip_pvt_lock(i); 07352 return NULL; 07353 } 07354 ast_channel_lock(tmp); 07355 sip_pvt_lock(i); 07356 ast_channel_cc_params_init(tmp, i->cc_params); 07357 tmp->caller.id.tag = ast_strdup(i->cid_tag); 07358 07359 tmp->tech = ( ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO || ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_SHORTINFO) ? &sip_tech_info : &sip_tech; 07360 07361 /* Select our native format based on codec preference until we receive 07362 something from another device to the contrary. */ 07363 if (i->jointcapability) { /* The joint capabilities of us and peer */ 07364 what = i->jointcapability; 07365 video = i->jointcapability & AST_FORMAT_VIDEO_MASK; 07366 text = i->jointcapability & AST_FORMAT_TEXT_MASK; 07367 } else if (i->capability) { /* Our configured capability for this peer */ 07368 what = i->capability; 07369 video = i->capability & AST_FORMAT_VIDEO_MASK; 07370 text = i->capability & AST_FORMAT_TEXT_MASK; 07371 } else { 07372 what = sip_cfg.capability; /* Global codec support */ 07373 video = sip_cfg.capability & AST_FORMAT_VIDEO_MASK; 07374 text = sip_cfg.capability & AST_FORMAT_TEXT_MASK; 07375 } 07376 07377 /* Set the native formats for audio and merge in video */ 07378 tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | video | text; 07379 ast_debug(3, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, tmp->nativeformats)); 07380 ast_debug(3, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->jointcapability)); 07381 ast_debug(3, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->capability)); 07382 ast_debug(3, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, ast_codec_choose(&i->prefs, what, 1))); 07383 if (i->prefcodec) 07384 ast_debug(3, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->prefcodec)); 07385 07386 /* XXX Why are we choosing a codec from the native formats?? */ 07387 fmt = ast_best_codec(tmp->nativeformats); 07388 07389 /* If we have a prefcodec setting, we have an inbound channel that set a 07390 preferred format for this call. Otherwise, we check the jointcapability 07391 We also check for vrtp. If it's not there, we are not allowed do any video anyway. 07392 */ 07393 if (i->vrtp) { 07394 if (ast_test_flag(&i->flags[1], SIP_PAGE2_VIDEOSUPPORT)) 07395 needvideo = AST_FORMAT_VIDEO_MASK; 07396 else if (i->prefcodec) 07397 needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK; /* Outbound call */ 07398 else 07399 needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK; /* Inbound call */ 07400 } 07401 07402 if (i->trtp) { 07403 if (i->prefcodec) 07404 needtext = i->prefcodec & AST_FORMAT_TEXT_MASK; /* Outbound call */ 07405 else 07406 needtext = i->jointcapability & AST_FORMAT_TEXT_MASK; /* Inbound call */ 07407 } 07408 07409 if (needvideo) 07410 ast_debug(3, "This channel can handle video! HOLLYWOOD next!\n"); 07411 else 07412 ast_debug(3, "This channel will not be able to handle video.\n"); 07413 07414 enable_dsp_detect(i); 07415 07416 if ((ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || 07417 (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) { 07418 if (i->rtp) { 07419 ast_rtp_instance_dtmf_mode_set(i->rtp, AST_RTP_DTMF_MODE_INBAND); 07420 } 07421 } else if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) { 07422 if (i->rtp) { 07423 ast_rtp_instance_dtmf_mode_set(i->rtp, AST_RTP_DTMF_MODE_RFC2833); 07424 } 07425 } 07426 07427 /* Set file descriptors for audio, video, and realtime text. Since 07428 * UDPTL is created as needed in the lifetime of a dialog, its file 07429 * descriptor is set in initialize_udptl */ 07430 if (i->rtp) { 07431 ast_channel_set_fd(tmp, 0, ast_rtp_instance_fd(i->rtp, 0)); 07432 ast_channel_set_fd(tmp, 1, ast_rtp_instance_fd(i->rtp, 1)); 07433 ast_rtp_instance_set_write_format(i->rtp, fmt); 07434 ast_rtp_instance_set_read_format(i->rtp, fmt); 07435 } 07436 if (needvideo && i->vrtp) { 07437 ast_channel_set_fd(tmp, 2, ast_rtp_instance_fd(i->vrtp, 0)); 07438 ast_channel_set_fd(tmp, 3, ast_rtp_instance_fd(i->vrtp, 1)); 07439 } 07440 if (needtext && i->trtp) { 07441 ast_channel_set_fd(tmp, 4, ast_rtp_instance_fd(i->trtp, 0)); 07442 } 07443 if (i->udptl) { 07444 ast_channel_set_fd(tmp, 5, ast_udptl_fd(i->udptl)); 07445 } 07446 07447 if (state == AST_STATE_RING) 07448 tmp->rings = 1; 07449 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 07450 07451 tmp->writeformat = fmt; 07452 tmp->rawwriteformat = fmt; 07453 07454 tmp->readformat = fmt; 07455 tmp->rawreadformat = fmt; 07456 07457 tmp->tech_pvt = dialog_ref(i, "sip_new: set chan->tech_pvt to i"); 07458 07459 tmp->callgroup = i->callgroup; 07460 tmp->pickupgroup = i->pickupgroup; 07461 tmp->caller.id.name.presentation = i->callingpres; 07462 tmp->caller.id.number.presentation = i->callingpres; 07463 if (!ast_strlen_zero(i->parkinglot)) 07464 ast_string_field_set(tmp, parkinglot, i->parkinglot); 07465 if (!ast_strlen_zero(i->accountcode)) 07466 ast_string_field_set(tmp, accountcode, i->accountcode); 07467 if (i->amaflags) 07468 tmp->amaflags = i->amaflags; 07469 if (!ast_strlen_zero(i->language)) 07470 ast_string_field_set(tmp, language, i->language); 07471 i->owner = tmp; 07472 ast_module_ref(ast_module_info->self); 07473 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 07474 /*Since it is valid to have extensions in the dialplan that have unescaped characters in them 07475 * we should decode the uri before storing it in the channel, but leave it encoded in the sip_pvt 07476 * structure so that there aren't issues when forming URI's 07477 */ 07478 exten = ast_strdupa(i->exten); 07479 sip_pvt_unlock(i); 07480 ast_channel_unlock(tmp); 07481 if (!ast_exists_extension(NULL, i->context, i->exten, 1, i->cid_num)) { 07482 ast_uri_decode(exten); 07483 } 07484 ast_channel_lock(tmp); 07485 sip_pvt_lock(i); 07486 ast_copy_string(tmp->exten, exten, sizeof(tmp->exten)); 07487 07488 /* Don't use ast_set_callerid() here because it will 07489 * generate an unnecessary NewCallerID event */ 07490 if (!ast_strlen_zero(i->cid_num)) { 07491 tmp->caller.ani.number.valid = 1; 07492 tmp->caller.ani.number.str = ast_strdup(i->cid_num); 07493 } 07494 if (!ast_strlen_zero(i->rdnis)) { 07495 tmp->redirecting.from.number.valid = 1; 07496 tmp->redirecting.from.number.str = ast_strdup(i->rdnis); 07497 } 07498 07499 if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) { 07500 tmp->dialed.number.str = ast_strdup(i->exten); 07501 } 07502 07503 tmp->priority = 1; 07504 if (!ast_strlen_zero(i->uri)) 07505 pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri); 07506 if (!ast_strlen_zero(i->domain)) 07507 pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain); 07508 if (!ast_strlen_zero(i->callid)) 07509 pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid); 07510 if (i->rtp) 07511 ast_jb_configure(tmp, &global_jbconf); 07512 07513 if (!i->relatedpeer) { 07514 tmp->flags |= AST_FLAG_DISABLE_DEVSTATE_CACHE; 07515 } 07516 /* Set channel variables for this call from configuration */ 07517 for (v = i->chanvars ; v ; v = v->next) { 07518 char valuebuf[1024]; 07519 pbx_builtin_setvar_helper(tmp, v->name, ast_get_encoded_str(v->value, valuebuf, sizeof(valuebuf))); 07520 } 07521 07522 if (i->do_history) 07523 append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid); 07524 07525 /* Inform manager user about new channel and their SIP call ID */ 07526 if (sip_cfg.callevents) 07527 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", 07528 "Channel: %s\r\nUniqueid: %s\r\nChanneltype: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\n", 07529 tmp->name, tmp->uniqueid, "SIP", i->callid, i->fullcontact); 07530 07531 return tmp; 07532 }
| static int sip_notify_allocate | ( | struct sip_pvt * | p | ) | [static] |
Allocate SIP refer structure.
Definition at line 13961 of file chan_sip.c.
References ast_calloc, and ast_str_create().
Referenced by manager_sipnotify(), and sip_cli_notify().
13962 { 13963 p->notify = ast_calloc(1, sizeof(struct sip_notify)); 13964 if (p->notify) { 13965 p->notify->content = ast_str_create(128); 13966 } 13967 return p->notify ? 1 : 0; 13968 }
| static int sip_offer_timer_expire | ( | const void * | data | ) | [static] |
Definition at line 1720 of file chan_sip.c.
References ast_cc_failed(), ast_cc_agent::core_id, ast_cc_agent::device_name, and ast_cc_agent::private_data.
Referenced by sip_cc_agent_start_offer_timer().
01721 { 01722 struct ast_cc_agent *agent = (struct ast_cc_agent *) data; 01723 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01724 01725 agent_pvt->offer_timer_id = -1; 01726 01727 return ast_cc_failed(agent->core_id, "SIP agent %s's offer timer expired", agent->device_name); 01728 }
| static int sip_park | ( | struct ast_channel * | chan1, | |
| struct ast_channel * | chan2, | |||
| struct sip_request * | req, | |||
| uint32_t | seqno, | |||
| const char * | park_exten, | |||
| const char * | park_context | |||
| ) | [static] |
DO NOT hold any locks while calling sip_park
Definition at line 22202 of file chan_sip.c.
References ast_channel::amaflags, ast_calloc, ast_channel_alloc, ast_channel_masquerade(), ast_copy_string(), ast_do_masquerade(), ast_free, ast_hangup(), ast_pthread_create_detached_background, AST_STATE_DOWN, ast_strdup, ast_string_field_set, ast_channel::context, copy_request(), deinit_req(), ast_channel::exten, parkinglot, ast_channel::priority, ast_channel::readformat, sip_park_thread(), and ast_channel::writeformat.
Referenced by handle_request_refer().
22203 { 22204 struct sip_dual *d; 22205 struct ast_channel *transferee, *transferer; 22206 pthread_t th; 22207 22208 transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->linkedid, chan1->amaflags, "Parking/%s", chan1->name); 22209 transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->linkedid, chan2->amaflags, "SIPPeer/%s", chan2->name); 22210 d = ast_calloc(1, sizeof(*d)); 22211 if (!transferee || !transferer || !d) { 22212 if (transferee) { 22213 ast_hangup(transferee); 22214 } 22215 if (transferer) { 22216 ast_hangup(transferer); 22217 } 22218 ast_free(d); 22219 return -1; 22220 } 22221 d->park_exten = ast_strdup(park_exten); 22222 d->park_context = ast_strdup(park_context); 22223 if (!d->park_exten || !d->park_context) { 22224 ast_hangup(transferee); 22225 ast_hangup(transferer); 22226 ast_free(d->park_exten); 22227 ast_free(d->park_context); 22228 ast_free(d); 22229 return -1; 22230 } 22231 22232 /* Make formats okay */ 22233 transferee->readformat = chan1->readformat; 22234 transferee->writeformat = chan1->writeformat; 22235 22236 /* Prepare for taking over the channel */ 22237 if (ast_channel_masquerade(transferee, chan1)) { 22238 ast_hangup(transferee); 22239 ast_hangup(transferer); 22240 ast_free(d->park_exten); 22241 ast_free(d->park_context); 22242 ast_free(d); 22243 return -1; 22244 } 22245 22246 /* Setup the extensions and such */ 22247 ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context)); 22248 ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten)); 22249 transferee->priority = chan1->priority; 22250 22251 ast_do_masquerade(transferee); 22252 22253 /* We make a clone of the peer channel too, so we can play 22254 back the announcement */ 22255 22256 /* Make formats okay */ 22257 transferer->readformat = chan2->readformat; 22258 transferer->writeformat = chan2->writeformat; 22259 ast_string_field_set(transferer, parkinglot, chan2->parkinglot); 22260 22261 /* Prepare for taking over the channel */ 22262 if (ast_channel_masquerade(transferer, chan2)) { 22263 ast_hangup(transferee); 22264 ast_hangup(transferer); 22265 ast_free(d->park_exten); 22266 ast_free(d->park_context); 22267 ast_free(d); 22268 return -1; 22269 } 22270 22271 /* Setup the extensions and such */ 22272 ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context)); 22273 ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten)); 22274 transferer->priority = chan2->priority; 22275 22276 ast_do_masquerade(transferer); 22277 22278 /* Save original request for followup */ 22279 copy_request(&d->req, req); 22280 d->chan1 = transferee; /* Transferee */ 22281 d->chan2 = transferer; /* Transferer */ 22282 d->seqno = seqno; 22283 if (ast_pthread_create_detached_background(&th, NULL, sip_park_thread, d) < 0) { 22284 /* Could not start thread */ 22285 ast_hangup(transferer); 22286 ast_hangup(transferee); 22287 deinit_req(&d->req); 22288 ast_free(d->park_exten); 22289 ast_free(d->park_context); 22290 ast_free(d); /* We don't need it anymore. If thread is created, d will be free'd 22291 by sip_park_thread() */ 22292 return -1; 22293 } 22294 return 0; 22295 }
| static void * sip_park_thread | ( | void * | stuff | ) | [static] |
Park SIP call support function Starts in a new thread, then parks the call XXX Should we add a wait period after streaming audio and before hangup?? Sometimes the audio can't be heard before hangup.
Definition at line 22151 of file chan_sip.c.
References append_history, AST_CAUSE_NORMAL_CLEARING, ast_debug, ast_free, ast_hangup(), ast_log(), AST_LOG_NOTICE, ast_park_call_exten(), ast_set_flag, deinit_req(), ext, ast_channel::hangupcause, ast_channel::tech_pvt, transmit_message_with_text(), transmit_notify_with_sipfrag(), and TRUE.
Referenced by sip_park().
22152 { 22153 struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */ 22154 struct sip_pvt *transferer_pvt; 22155 struct sip_dual *d; 22156 int ext; 22157 int res; 22158 22159 d = stuff; 22160 transferee = d->chan1; 22161 transferer = d->chan2; 22162 transferer_pvt = transferer->tech_pvt; 22163 22164 ast_debug(4, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name); 22165 22166 res = ast_park_call_exten(transferee, transferer, d->park_exten, d->park_context, 0, &ext); 22167 22168 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE 22169 if (res) { 22170 transmit_message_with_text(transferer_pvt, "Unable to park call.\n"); 22171 } else { 22172 /* Then tell the transferer what happened */ 22173 sprintf(buf, "Call parked on extension '%d'", ext); 22174 transmit_message_with_text(transferer_pvt, buf); 22175 } 22176 #endif 22177 22178 /* Any way back to the current call??? */ 22179 /* Transmit response to the REFER request */ 22180 ast_set_flag(&transferer_pvt->flags[0], SIP_DEFER_BYE_ON_TRANSFER); 22181 if (!res) { 22182 /* Transfer succeeded */ 22183 append_history(transferer_pvt, "SIPpark", "Parked call on %d", ext); 22184 transmit_notify_with_sipfrag(transferer_pvt, d->seqno, "200 OK", TRUE); 22185 transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING; 22186 ast_debug(1, "SIP Call parked on extension '%d'\n", ext); 22187 } else { 22188 transmit_notify_with_sipfrag(transferer_pvt, d->seqno, "503 Service Unavailable", TRUE); 22189 append_history(transferer_pvt, "SIPpark", "Parking failed\n"); 22190 ast_log(AST_LOG_NOTICE, "SIP Call parked failed for %s\n", transferee->name); 22191 ast_hangup(transferee); 22192 } 22193 ast_hangup(transferer); 22194 deinit_req(&d->req); 22195 ast_free(d->park_exten); 22196 ast_free(d->park_context); 22197 ast_free(d); 22198 return NULL; 22199 }
| static void sip_peer_hold | ( | struct sip_pvt * | p, | |
| int | hold | |||
| ) | [static] |
Change onhold state of a peer using a pvt structure.
Definition at line 15031 of file chan_sip.c.
References ast_atomic_fetchadd_int(), AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), AST_DEVSTATE_NOT_CACHABLE, and AST_FLAG_DISABLE_DEVSTATE_CACHE.
Referenced by change_hold_state(), and update_call_counter().
15032 { 15033 if (!p->relatedpeer) { 15034 return; 15035 } 15036 15037 /* If they put someone on hold, increment the value... otherwise decrement it */ 15038 ast_atomic_fetchadd_int(&p->relatedpeer->onHold, (hold ? +1 : -1)); 15039 15040 /* Request device state update */ 15041 ast_devstate_changed(AST_DEVICE_UNKNOWN, (p->owner->flags & AST_FLAG_DISABLE_DEVSTATE_CACHE ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE), 15042 "SIP/%s", p->relatedpeer->name); 15043 15044 return; 15045 }
| static int sip_pickup | ( | struct ast_channel * | chan | ) | [static] |
Pickup a call using the subsystem in features.c This is executed in a separate thread.
Definition at line 22320 of file chan_sip.c.
References ast_channel_ref, ast_channel_unref, ast_debug, ast_pthread_create_detached_background, and sip_pickup_thread().
Referenced by handle_request_invite().
22321 { 22322 pthread_t threadid; 22323 22324 ast_channel_ref(chan); 22325 22326 if (ast_pthread_create_detached_background(&threadid, NULL, sip_pickup_thread, chan)) { 22327 ast_debug(1, "Unable to start Group pickup thread on channel %s\n", chan->name); 22328 ast_channel_unref(chan); 22329 return -1; 22330 } 22331 ast_debug(1, "Started Group pickup thread on channel %s\n", chan->name); 22332 return 0; 22333 }
| static void * sip_pickup_thread | ( | void * | stuff | ) | [static] |
SIP pickup support function Starts in a new thread, then pickup the call.
Definition at line 22301 of file chan_sip.c.
References AST_CAUSE_CALL_REJECTED, AST_CAUSE_NORMAL_CLEARING, ast_channel_unref, ast_hangup(), ast_pickup_call(), and ast_channel::hangupcause.
Referenced by sip_pickup().
22302 { 22303 struct ast_channel *chan; 22304 chan = stuff; 22305 22306 if (ast_pickup_call(chan)) { 22307 chan->hangupcause = AST_CAUSE_CALL_REJECTED; 22308 } else { 22309 chan->hangupcause = AST_CAUSE_NORMAL_CLEARING; 22310 } 22311 ast_hangup(chan); 22312 ast_channel_unref(chan); 22313 chan = NULL; 22314 return NULL; 22315 }
| static void sip_poke_all_peers | ( | void | ) | [static] |
Send a poke to all known peers.
Definition at line 30451 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_iterator_next, ao2_unlock, AST_SCHED_REPLACE_UNREF, ref_peer(), sip_poke_peer_s(), and unref_peer().
Referenced by load_module(), and sip_do_reload().
30452 { 30453 int ms = 0, num = 0; 30454 struct ao2_iterator i; 30455 struct sip_peer *peer; 30456 30457 if (!speerobjs) { /* No peers, just give up */ 30458 return; 30459 } 30460 30461 i = ao2_iterator_init(peers, 0); 30462 while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) { 30463 ao2_lock(peer); 30464 /* Don't schedule poking on a peer without qualify */ 30465 if (peer->maxms) { 30466 if (num == global_qualify_peers) { 30467 ms += global_qualify_gap; 30468 num = 0; 30469 } else { 30470 num++; 30471 } 30472 AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, ms, sip_poke_peer_s, peer, 30473 unref_peer(_data, "removing poke peer ref"), 30474 unref_peer(peer, "removing poke peer ref"), 30475 ref_peer(peer, "adding poke peer ref")); 30476 } 30477 ao2_unlock(peer); 30478 unref_peer(peer, "toss iterator peer ptr"); 30479 } 30480 ao2_iterator_destroy(&i); 30481 }
| static int sip_poke_noanswer | ( | const void * | data | ) | [static] |
React to lack of answer to Qualify poke.
Definition at line 27040 of file chan_sip.c.
References ast_check_realtime(), AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_log(), AST_SCHED_REPLACE_UNREF, ast_update_realtime(), DEFAULT_FREQ_NOTOK, dialog_unlink_all(), EVENT_FLAG_SYSTEM, FALSE, LOG_NOTICE, manager_event, ref_peer(), register_peer_exten(), SENTINEL, sip_cfg, sip_poke_peer_s(), and unref_peer().
Referenced by sip_poke_peer(), and sip_show_sched().
27041 { 27042 struct sip_peer *peer = (struct sip_peer *)data; 27043 27044 peer->pokeexpire = -1; 27045 27046 if (peer->lastms > -1) { 27047 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms); 27048 if (sip_cfg.peer_rtupdate) { 27049 ast_update_realtime(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", "name", peer->name, "lastms", "-1", SENTINEL); 27050 } 27051 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1); 27052 if (sip_cfg.regextenonqualify) { 27053 register_peer_exten(peer, FALSE); 27054 } 27055 } 27056 27057 if (peer->call) { 27058 dialog_unlink_all(peer->call); 27059 peer->call = dialog_unref(peer->call, "unref dialog peer->call"); 27060 /* peer->call = sip_destroy(peer->call);*/ 27061 } 27062 27063 /* Don't send a devstate change if nothing changed. */ 27064 if (peer->lastms > -1) { 27065 peer->lastms = -1; 27066 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", peer->name); 27067 } 27068 27069 /* Try again quickly */ 27070 AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, 27071 DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer, 27072 unref_peer(_data, "removing poke peer ref"), 27073 unref_peer(peer, "removing poke peer ref"), 27074 ref_peer(peer, "adding poke peer ref")); 27075 27076 /* Release the ref held by the running scheduler entry */ 27077 unref_peer(peer, "release peer poke noanswer ref"); 27078 27079 return 0; 27080 }
| static int sip_poke_peer | ( | struct sip_peer * | peer, | |
| int | force | |||
| ) | [static] |
Check availability of peer, also keep NAT open.
Definition at line 27090 of file chan_sip.c.
References ast_copy_flags, ast_copy_string(), ast_log(), AST_SCHED_DEL_UNREF, AST_SCHED_REPLACE_UNREF, ast_set_flag, ast_sip_ouraddrfor(), ast_sockaddr_isnull(), ast_sockaddr_stringify_host_remote(), ast_string_field_set, ast_strlen_zero(), ast_tvnow(), build_via(), change_callid_pvt(), copy_socket_data(), dialog_unlink_all(), LOG_NOTICE, ref_peer(), sip_alloc(), sip_poke_noanswer(), transmit_invite(), and unref_peer().
Referenced by _sip_qualify_peer(), build_peer(), parse_register_contact(), and sip_poke_peer_s().
27091 { 27092 struct sip_pvt *p; 27093 int xmitres = 0; 27094 27095 if ((!peer->maxms && !force) || ast_sockaddr_isnull(&peer->addr)) { 27096 /* IF we have no IP, or this isn't to be monitored, return 27097 immediately after clearing things out */ 27098 AST_SCHED_DEL_UNREF(sched, peer->pokeexpire, 27099 unref_peer(peer, "removing poke peer ref")); 27100 27101 peer->lastms = 0; 27102 if (peer->call) { 27103 peer->call = dialog_unref(peer->call, "unref dialog peer->call"); 27104 } 27105 return 0; 27106 } 27107 if (peer->call) { 27108 if (sipdebug) { 27109 ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n"); 27110 } 27111 dialog_unlink_all(peer->call); 27112 peer->call = dialog_unref(peer->call, "unref dialog peer->call"); 27113 /* peer->call = sip_destroy(peer->call); */ 27114 } 27115 if (!(p = sip_alloc(NULL, NULL, 0, SIP_OPTIONS, NULL))) { 27116 return -1; 27117 } 27118 peer->call = dialog_ref(p, "copy sip alloc from p to peer->call"); 27119 27120 p->sa = peer->addr; 27121 p->recv = peer->addr; 27122 copy_socket_data(&p->socket, &peer->socket); 27123 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 27124 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 27125 ast_copy_flags(&p->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY); 27126 27127 /* Send OPTIONs to peer's fullcontact */ 27128 if (!ast_strlen_zero(peer->fullcontact)) { 27129 ast_string_field_set(p, fullcontact, peer->fullcontact); 27130 } 27131 27132 if (!ast_strlen_zero(peer->fromuser)) { 27133 ast_string_field_set(p, fromuser, peer->fromuser); 27134 } 27135 27136 if (!ast_strlen_zero(peer->tohost)) { 27137 ast_string_field_set(p, tohost, peer->tohost); 27138 } else { 27139 ast_string_field_set(p, tohost, ast_sockaddr_stringify_host_remote(&peer->addr)); 27140 } 27141 27142 /* Recalculate our side, and recalculate Call ID */ 27143 ast_sip_ouraddrfor(&p->sa, &p->ourip, p); 27144 build_via(p); 27145 27146 /* Change the dialog callid. */ 27147 change_callid_pvt(p, NULL); 27148 27149 AST_SCHED_DEL_UNREF(sched, peer->pokeexpire, 27150 unref_peer(peer, "removing poke peer ref")); 27151 27152 if (p->relatedpeer) 27153 p->relatedpeer = unref_peer(p->relatedpeer,"unsetting the relatedpeer field in the dialog, before it is set to something else."); 27154 p->relatedpeer = ref_peer(peer, "setting the relatedpeer field in the dialog"); 27155 ast_set_flag(&p->flags[0], SIP_OUTGOING); 27156 #ifdef VOCAL_DATA_HACK 27157 ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username)); 27158 xmitres = transmit_invite(p, SIP_INVITE, 0, 2, NULL); /* sinks the p refcount */ 27159 #else 27160 xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2, NULL); /* sinks the p refcount */ 27161 #endif 27162 peer->ps = ast_tvnow(); 27163 if (xmitres == XMIT_ERROR) { 27164 /* Immediately unreachable, network problems */ 27165 sip_poke_noanswer(ref_peer(peer, "add ref for peerexpire (fake, for sip_poke_noanswer to remove)")); 27166 } else if (!force) { 27167 AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, peer->maxms * 2, sip_poke_noanswer, peer, 27168 unref_peer(_data, "removing poke peer ref"), 27169 unref_peer(peer, "removing poke peer ref"), 27170 ref_peer(peer, "adding poke peer ref")); 27171 } 27172 dialog_unref(p, "unref dialog at end of sip_poke_peer, obtained from sip_alloc, just before it goes out of scope"); 27173 return 0; 27174 }
| static int sip_poke_peer_s | ( | const void * | data | ) | [static] |
Poke peer (send qualify to check if peer is alive and well).
Definition at line 14266 of file chan_sip.c.
References ao2_find, OBJ_POINTER, sip_poke_peer(), and unref_peer().
Referenced by handle_response_peerpoke(), reg_source_db(), sip_poke_all_peers(), sip_poke_noanswer(), and sip_show_sched().
14267 { 14268 struct sip_peer *peer = (struct sip_peer *)data; 14269 struct sip_peer *foundpeer; 14270 14271 peer->pokeexpire = -1; 14272 14273 foundpeer = ao2_find(peers, peer, OBJ_POINTER); 14274 if (!foundpeer) { 14275 unref_peer(peer, "removing poke peer ref"); 14276 return 0; 14277 } else if (foundpeer->name != peer->name) { 14278 unref_peer(foundpeer, "removing above peer ref"); 14279 unref_peer(peer, "removing poke peer ref"); 14280 return 0; 14281 } 14282 14283 unref_peer(foundpeer, "removing above peer ref"); 14284 sip_poke_peer(peer, 0); 14285 unref_peer(peer, "removing poke peer ref"); 14286 14287 return 0; 14288 }
| static int sip_prepare_socket | ( | struct sip_pvt * | p | ) | [static] |
Definition at line 26283 of file chan_sip.c.
References ast_tcptls_session_args::accept_fd, ao2_alloc, ao2_ref, ao2_t_ref, ao2_t_unlink, ast_calloc, ast_copy_string(), ast_debug, ast_pthread_create_detached_background, ast_sockaddr_copy(), ast_strdup, ast_strlen_zero(), ast_tcptls_client_create(), ast_tcptls_close_session_file(), ast_tls_config::cafile, ast_tls_config::capath, ast_tls_config::certfile, ast_tls_config::cipher, ast_tcptls_session_instance::fd, ast_tcptls_session_args::hostname, ast_tcptls_session_args::name, name, ast_tls_config::pvtfile, ast_tcptls_session_args::remote_address, sip_real_dst(), sip_tcp_locate(), sip_tcp_worker_fn(), sip_tcptls_client_args_destructor(), sip_threadinfo_create(), and ast_tcptls_session_args::tls_cfg.
Referenced by __sip_xmit().
26284 { 26285 struct sip_socket *s = &p->socket; 26286 static const char name[] = "SIP socket"; 26287 struct sip_threadinfo *th = NULL; 26288 struct ast_tcptls_session_instance *tcptls_session; 26289 struct ast_tcptls_session_args *ca; 26290 struct ast_sockaddr sa_tmp; 26291 pthread_t launched; 26292 26293 /* check to see if a socket is already active */ 26294 if ((s->fd != -1) && (s->type == SIP_TRANSPORT_UDP)) { 26295 return s->fd; 26296 } 26297 if ((s->type & (SIP_TRANSPORT_TCP | SIP_TRANSPORT_TLS)) && 26298 (s->tcptls_session) && 26299 (s->tcptls_session->fd != -1)) { 26300 return s->tcptls_session->fd; 26301 } 26302 26303 /*! \todo Check this... This might be wrong, depending on the proxy configuration 26304 If proxy is in "force" mode its correct. 26305 */ 26306 if (p->outboundproxy && p->outboundproxy->transport) { 26307 s->type = p->outboundproxy->transport; 26308 } 26309 26310 if (s->type == SIP_TRANSPORT_UDP) { 26311 s->fd = sipsock; 26312 return s->fd; 26313 } 26314 26315 /* At this point we are dealing with a TCP/TLS connection 26316 * 1. We need to check to see if a connection thread exists 26317 * for this address, if so use that. 26318 * 2. If a thread does not exist for this address, but the tcptls_session 26319 * exists on the socket, the connection was closed. 26320 * 3. If no tcptls_session thread exists for the address, and no tcptls_session 26321 * already exists on the socket, create a new one and launch a new thread. 26322 */ 26323 26324 /* 1. check for existing threads */ 26325 ast_sockaddr_copy(&sa_tmp, sip_real_dst(p)); 26326 if ((tcptls_session = sip_tcp_locate(&sa_tmp))) { 26327 s->fd = tcptls_session->fd; 26328 if (s->tcptls_session) { 26329 ao2_ref(s->tcptls_session, -1); 26330 s->tcptls_session = NULL; 26331 } 26332 s->tcptls_session = tcptls_session; 26333 return s->fd; 26334 /* 2. Thread not found, if tcptls_session already exists, it once had a thread and is now terminated */ 26335 } else if (s->tcptls_session) { 26336 return s->fd; /* XXX whether reconnection is ever necessary here needs to be investigated further */ 26337 } 26338 26339 /* 3. Create a new TCP/TLS client connection */ 26340 /* create new session arguments for the client connection */ 26341 if (!(ca = ao2_alloc(sizeof(*ca), sip_tcptls_client_args_destructor)) || 26342 !(ca->name = ast_strdup(name))) { 26343 goto create_tcptls_session_fail; 26344 } 26345 ca->accept_fd = -1; 26346 ast_sockaddr_copy(&ca->remote_address,sip_real_dst(p)); 26347 /* if type is TLS, we need to create a tls cfg for this session arg */ 26348 if (s->type == SIP_TRANSPORT_TLS) { 26349 if (!(ca->tls_cfg = ast_calloc(1, sizeof(*ca->tls_cfg)))) { 26350 goto create_tcptls_session_fail; 26351 } 26352 memcpy(ca->tls_cfg, &default_tls_cfg, sizeof(*ca->tls_cfg)); 26353 26354 if (!(ca->tls_cfg->certfile = ast_strdup(default_tls_cfg.certfile)) || 26355 !(ca->tls_cfg->pvtfile = ast_strdup(default_tls_cfg.pvtfile)) || 26356 !(ca->tls_cfg->cipher = ast_strdup(default_tls_cfg.cipher)) || 26357 !(ca->tls_cfg->cafile = ast_strdup(default_tls_cfg.cafile)) || 26358 !(ca->tls_cfg->capath = ast_strdup(default_tls_cfg.capath))) { 26359 26360 goto create_tcptls_session_fail; 26361 } 26362 26363 /* this host is used as the common name in ssl/tls */ 26364 if (!ast_strlen_zero(p->tohost)) { 26365 ast_copy_string(ca->hostname, p->tohost, sizeof(ca->hostname)); 26366 } 26367 } 26368 26369 /* Create a client connection for address, this does not start the connection, just sets it up. */ 26370 if (!(s->tcptls_session = ast_tcptls_client_create(ca))) { 26371 goto create_tcptls_session_fail; 26372 } 26373 26374 s->fd = s->tcptls_session->fd; 26375 26376 /* client connections need to have the sip_threadinfo object created before 26377 * the thread is detached. This ensures the alert_pipe is up before it will 26378 * be used. Note that this function links the new threadinfo object into the 26379 * threadt container. */ 26380 if (!(th = sip_threadinfo_create(s->tcptls_session, s->type))) { 26381 goto create_tcptls_session_fail; 26382 } 26383 26384 /* Give the new thread a reference to the tcptls_session */ 26385 ao2_ref(s->tcptls_session, +1); 26386 26387 if (ast_pthread_create_detached_background(&launched, NULL, sip_tcp_worker_fn, s->tcptls_session)) { 26388 ast_debug(1, "Unable to launch '%s'.", ca->name); 26389 ao2_ref(s->tcptls_session, -1); /* take away the thread ref we just gave it */ 26390 goto create_tcptls_session_fail; 26391 } 26392 26393 return s->fd; 26394 26395 create_tcptls_session_fail: 26396 if (ca) { 26397 ao2_t_ref(ca, -1, "failed to create client, getting rid of client tcptls_session arguments"); 26398 } 26399 if (s->tcptls_session) { 26400 ast_tcptls_close_session_file(s->tcptls_session); 26401 s->fd = -1; 26402 ao2_ref(s->tcptls_session, -1); 26403 s->tcptls_session = NULL; 26404 } 26405 if (th) { 26406 ao2_t_unlink(threadt, th, "Removing tcptls thread info object, thread failed to open"); 26407 } 26408 26409 return -1; 26410 }
| static char * sip_prune_realtime | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Remove temporary realtime objects from memory (CLI).
Definition at line 17732 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_find, ao2_t_iterator_next, ao2_t_link, ao2_t_unlink, ao2_unlock, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_cli_complete(), ast_copy_string(), ast_sockaddr_isnull(), ast_test_flag, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sip_peer(), FALSE, ast_cli_args::fd, ast_cli_args::n, name, OBJ_POINTER, OBJ_UNLINK, ast_cli_args::pos, TRUE, unlink_marked_peers_from_tables(), unref_peer(), ast_cli_entry::usage, and ast_cli_args::word.
17733 { 17734 struct sip_peer *peer, *pi; 17735 int prunepeer = FALSE; 17736 int multi = FALSE; 17737 const char *name = NULL; 17738 regex_t regexbuf; 17739 int havepattern = 0; 17740 struct ao2_iterator i; 17741 static const char * const choices[] = { "all", "like", NULL }; 17742 char *cmplt; 17743 17744 if (cmd == CLI_INIT) { 17745 e->command = "sip prune realtime [peer|all]"; 17746 e->usage = 17747 "Usage: sip prune realtime [peer [<name>|all|like <pattern>]|all]\n" 17748 " Prunes object(s) from the cache.\n" 17749 " Optional regular expression pattern is used to filter the objects.\n"; 17750 return NULL; 17751 } else if (cmd == CLI_GENERATE) { 17752 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer")) { 17753 cmplt = ast_cli_complete(a->word, choices, a->n); 17754 if (!cmplt) 17755 cmplt = complete_sip_peer(a->word, a->n - sizeof(choices), SIP_PAGE2_RTCACHEFRIENDS); 17756 return cmplt; 17757 } 17758 if (a->pos == 5 && !strcasecmp(a->argv[4], "like")) 17759 return complete_sip_peer(a->word, a->n, SIP_PAGE2_RTCACHEFRIENDS); 17760 return NULL; 17761 } 17762 switch (a->argc) { 17763 case 4: 17764 name = a->argv[3]; 17765 /* we accept a name in position 3, but keywords are not good. */ 17766 if (!strcasecmp(name, "peer") || !strcasecmp(name, "like")) 17767 return CLI_SHOWUSAGE; 17768 prunepeer = TRUE; 17769 if (!strcasecmp(name, "all")) { 17770 multi = TRUE; 17771 name = NULL; 17772 } 17773 /* else a single name, already set */ 17774 break; 17775 case 5: 17776 /* sip prune realtime {peer|like} name */ 17777 name = a->argv[4]; 17778 if (!strcasecmp(a->argv[3], "peer")) 17779 prunepeer = TRUE; 17780 else if (!strcasecmp(a->argv[3], "like")) { 17781 prunepeer = TRUE; 17782 multi = TRUE; 17783 } else 17784 return CLI_SHOWUSAGE; 17785 if (!strcasecmp(name, "like")) 17786 return CLI_SHOWUSAGE; 17787 if (!multi && !strcasecmp(name, "all")) { 17788 multi = TRUE; 17789 name = NULL; 17790 } 17791 break; 17792 case 6: 17793 name = a->argv[5]; 17794 multi = TRUE; 17795 /* sip prune realtime {peer} like name */ 17796 if (strcasecmp(a->argv[4], "like")) 17797 return CLI_SHOWUSAGE; 17798 if (!strcasecmp(a->argv[3], "peer")) { 17799 prunepeer = TRUE; 17800 } else 17801 return CLI_SHOWUSAGE; 17802 break; 17803 default: 17804 return CLI_SHOWUSAGE; 17805 } 17806 17807 if (multi && name) { 17808 if (regcomp(®exbuf, name, REG_EXTENDED | REG_NOSUB)) { 17809 return CLI_SHOWUSAGE; 17810 } 17811 havepattern = 1; 17812 } 17813 17814 if (multi) { 17815 if (prunepeer) { 17816 int pruned = 0; 17817 17818 i = ao2_iterator_init(peers, 0); 17819 while ((pi = ao2_t_iterator_next(&i, "iterate thru peers table"))) { 17820 ao2_lock(pi); 17821 if (name && regexec(®exbuf, pi->name, 0, NULL, 0)) { 17822 ao2_unlock(pi); 17823 unref_peer(pi, "toss iterator peer ptr before continue"); 17824 continue; 17825 }; 17826 if (ast_test_flag(&pi->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 17827 pi->the_mark = 1; 17828 pruned++; 17829 } 17830 ao2_unlock(pi); 17831 unref_peer(pi, "toss iterator peer ptr"); 17832 } 17833 ao2_iterator_destroy(&i); 17834 if (pruned) { 17835 unlink_marked_peers_from_tables(); 17836 ast_cli(a->fd, "%d peers pruned.\n", pruned); 17837 } else 17838 ast_cli(a->fd, "No peers found to prune.\n"); 17839 } 17840 } else { 17841 if (prunepeer) { 17842 struct sip_peer tmp; 17843 ast_copy_string(tmp.name, name, sizeof(tmp.name)); 17844 if ((peer = ao2_t_find(peers, &tmp, OBJ_POINTER | OBJ_UNLINK, "finding to unlink from peers"))) { 17845 if (!ast_sockaddr_isnull(&peer->addr)) { 17846 ao2_t_unlink(peers_by_ip, peer, "unlinking peer from peers_by_ip also"); 17847 } 17848 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 17849 ast_cli(a->fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name); 17850 /* put it back! */ 17851 ao2_t_link(peers, peer, "link peer into peer table"); 17852 if (!ast_sockaddr_isnull(&peer->addr)) { 17853 ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table"); 17854 } 17855 } else 17856 ast_cli(a->fd, "Peer '%s' pruned.\n", name); 17857 unref_peer(peer, "sip_prune_realtime: unref_peer: tossing temp peer ptr"); 17858 } else 17859 ast_cli(a->fd, "Peer '%s' not found.\n", name); 17860 } 17861 } 17862 17863 if (havepattern) { 17864 regfree(®exbuf); 17865 } 17866 17867 return CLI_SUCCESS; 17868 }
| static struct ast_channel * sip_pvt_lock_full | ( | struct sip_pvt * | pvt | ) | [static, read] |
Definition at line 8328 of file chan_sip.c.
References ast_channel_lock, ast_channel_ref, ast_channel_unlock, ast_channel_unref, sip_pvt_lock, and sip_pvt_unlock.
Referenced by __sip_autodestruct(), dialog_unlink_all(), handle_request_do(), reinvite_timeout(), send_provisional_keepalive_full(), and sip_queue_hangup_cause().
08329 { 08330 struct ast_channel *chan; 08331 08332 /* Locking is simple when it is done right. If you see a deadlock resulting 08333 * in this function, it is not this function's fault, Your problem exists elsewhere. 08334 * This function is perfect... seriously. */ 08335 for (;;) { 08336 /* First, get the channel and grab a reference to it */ 08337 sip_pvt_lock(pvt); 08338 chan = pvt->owner; 08339 if (chan) { 08340 /* The channel can not go away while we hold the pvt lock. 08341 * Give the channel a ref so it will not go away after we let 08342 * the pvt lock go. */ 08343 ast_channel_ref(chan); 08344 } else { 08345 /* no channel, return pvt locked */ 08346 return NULL; 08347 } 08348 08349 /* We had to hold the pvt lock while getting a ref to the owner channel 08350 * but now we have to let this lock go in order to preserve proper 08351 * locking order when grabbing the channel lock */ 08352 sip_pvt_unlock(pvt); 08353 08354 /* Look, no deadlock avoidance, hooray! */ 08355 ast_channel_lock(chan); 08356 sip_pvt_lock(pvt); 08357 08358 if (pvt->owner == chan) { 08359 /* done */ 08360 break; 08361 } 08362 08363 /* If the owner changed while everything was unlocked, no problem, 08364 * just start over and everthing will work. This is rare, do not be 08365 * confused by this loop and think this it is an expensive operation. 08366 * The majority of the calls to this function will never involve multiple 08367 * executions of this loop. */ 08368 ast_channel_unlock(chan); 08369 ast_channel_unref(chan); 08370 sip_pvt_unlock(pvt); 08371 } 08372 08373 /* If owner exists, it is locked and reffed */ 08374 return pvt->owner; 08375 }
| static char * sip_qualify_peer | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Send an OPTIONS packet to a SIP peer.
Definition at line 18017 of file chan_sip.c.
References _sip_qualify_peer(), ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, complete_sip_show_peer(), ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.
18018 { 18019 switch (cmd) { 18020 case CLI_INIT: 18021 e->command = "sip qualify peer"; 18022 e->usage = 18023 "Usage: sip qualify peer <name> [load]\n" 18024 " Requests a response from one SIP peer and the current status.\n" 18025 " Option \"load\" forces lookup of peer in realtime storage.\n"; 18026 return NULL; 18027 case CLI_GENERATE: 18028 return complete_sip_show_peer(a->line, a->word, a->pos, a->n); 18029 } 18030 return _sip_qualify_peer(0, a->fd, NULL, NULL, a->argc, (const char **) a->argv); 18031 }
| static int sip_queryoption | ( | struct ast_channel * | chan, | |
| int | option, | |||
| void * | data, | |||
| int * | datalen | |||
| ) | [static] |
Query an option on a SIP dialog.
Definition at line 4558 of file chan_sip.c.
References ast_copy_string(), ast_debug, ast_log(), AST_OPTION_DEVICE_NAME, AST_OPTION_DIGIT_DETECT, AST_OPTION_SECURE_MEDIA, AST_OPTION_SECURE_SIGNALING, AST_OPTION_T38_STATE, ast_test_flag, LOG_ERROR, sip_pvt_lock, sip_pvt_unlock, T38_STATE_NEGOTIATED, T38_STATE_NEGOTIATING, T38_STATE_UNAVAILABLE, T38_STATE_UNKNOWN, and ast_channel::tech_pvt.
04559 { 04560 int res = -1; 04561 enum ast_t38_state state = T38_STATE_UNAVAILABLE; 04562 struct sip_pvt *p = (struct sip_pvt *) chan->tech_pvt; 04563 char *cp; 04564 04565 sip_pvt_lock(p); 04566 04567 switch (option) { 04568 case AST_OPTION_T38_STATE: 04569 /* Make sure we got an ast_t38_state enum passed in */ 04570 if (*datalen != sizeof(enum ast_t38_state)) { 04571 ast_log(LOG_ERROR, "Invalid datalen for AST_OPTION_T38_STATE option. Expected %d, got %d\n", (int)sizeof(enum ast_t38_state), *datalen); 04572 break; 04573 } 04574 04575 /* Now if T38 support is enabled we need to look and see what the current state is to get what we want to report back */ 04576 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) { 04577 switch (p->t38.state) { 04578 case T38_LOCAL_REINVITE: 04579 case T38_PEER_REINVITE: 04580 state = T38_STATE_NEGOTIATING; 04581 break; 04582 case T38_ENABLED: 04583 state = T38_STATE_NEGOTIATED; 04584 break; 04585 default: 04586 state = T38_STATE_UNKNOWN; 04587 } 04588 } 04589 04590 *((enum ast_t38_state *) data) = state; 04591 res = 0; 04592 04593 break; 04594 case AST_OPTION_DIGIT_DETECT: 04595 cp = (char *) data; 04596 *cp = p->dsp ? 1 : 0; 04597 ast_debug(1, "Reporting digit detection %sabled on %s\n", *cp ? "en" : "dis", chan->name); 04598 break; 04599 case AST_OPTION_SECURE_SIGNALING: 04600 *((unsigned int *) data) = p->req_secure_signaling; 04601 res = 0; 04602 break; 04603 case AST_OPTION_SECURE_MEDIA: 04604 *((unsigned int *) data) = ast_test_flag(&p->flags[1], SIP_PAGE2_USE_SRTP) ? 1 : 0; 04605 res = 0; 04606 break; 04607 case AST_OPTION_DEVICE_NAME: 04608 if (p && p->outgoing_call) { 04609 cp = (char *) data; 04610 ast_copy_string(cp, p->dialstring, *datalen); 04611 res = 0; 04612 } 04613 /* We purposely break with a return of -1 in the 04614 * implied else case here 04615 */ 04616 break; 04617 default: 04618 break; 04619 } 04620 04621 sip_pvt_unlock(p); 04622 04623 return res; 04624 }
| static void sip_queue_hangup_cause | ( | struct sip_pvt * | p, | |
| int | cause | |||
| ) | [static] |
Definition at line 20666 of file chan_sip.c.
References ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_queue_hangup(), ast_queue_hangup_with_cause(), ast_set_hangupsource(), ast_strdupa, name, sip_pvt_lock_full(), and sip_pvt_unlock.
Referenced by handle_request_bye(), handle_request_cancel(), and handle_response_invite().
20667 { 20668 struct ast_channel *owner = p->owner; 20669 const char *name = ast_strdupa(owner->name); 20670 20671 /* Cannot hold any channel/private locks when calling. */ 20672 ast_channel_ref(owner); 20673 ast_channel_unlock(owner); 20674 sip_pvt_unlock(p); 20675 ast_set_hangupsource(owner, name, 0); 20676 if (cause) { 20677 ast_queue_hangup_with_cause(owner, cause); 20678 } else { 20679 ast_queue_hangup(owner); 20680 } 20681 ast_channel_unref(owner); 20682 20683 /* Relock things. */ 20684 owner = sip_pvt_lock_full(p); 20685 if (owner) { 20686 ast_channel_unref(owner); 20687 } 20688 }
| static struct ast_frame * sip_read | ( | struct ast_channel * | ast | ) | [static, read] |
Read SIP RTP from channel.
Definition at line 7782 of file chan_sip.c.
References ast_channel::_state, ast_async_goto(), ast_channel_lock, ast_channel_unlock, ast_exists_extension(), AST_FRAME_VOICE, ast_frfree, ast_log(), ast_null_frame, AST_STATE_UP, ast_test_flag, ast_verbose, ast_channel::caller, ast_channel::context, ast_channel::exten, FALSE, ast_frame::frametype, ast_party_caller::id, LOG_NOTICE, ast_channel::macrocontext, ast_party_id::number, pbx_builtin_setvar_helper(), S_COR, S_OR, sip_pvt_lock, sip_pvt_unlock, sip_rtp_read(), ast_party_number::str, ast_channel::tech_pvt, ast_party_number::valid, and VERBOSE_PREFIX_2.
07783 { 07784 struct ast_frame *fr; 07785 struct sip_pvt *p = ast->tech_pvt; 07786 int faxdetected = FALSE; 07787 07788 sip_pvt_lock(p); 07789 fr = sip_rtp_read(ast, p, &faxdetected); 07790 p->lastrtprx = time(NULL); 07791 07792 /* If we detect a CNG tone and fax detection is enabled then send us off to the fax extension */ 07793 if (faxdetected && ast_test_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_CNG)) { 07794 if (strcmp(ast->exten, "fax")) { 07795 const char *target_context = S_OR(ast->macrocontext, ast->context); 07796 /* We need to unlock 'ast' here because 07797 * ast_exists_extension has the potential to start and 07798 * stop an autoservice on the channel. Such action is 07799 * prone to deadlock if the channel is locked. 07800 */ 07801 sip_pvt_unlock(p); 07802 ast_channel_unlock(ast); 07803 if (ast_exists_extension(ast, target_context, "fax", 1, 07804 S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, NULL))) { 07805 ast_channel_lock(ast); 07806 sip_pvt_lock(p); 07807 ast_verbose(VERBOSE_PREFIX_2 "Redirecting '%s' to fax extension due to CNG detection\n", ast->name); 07808 pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten); 07809 if (ast_async_goto(ast, target_context, "fax", 1)) { 07810 ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context); 07811 } 07812 ast_frfree(fr); 07813 fr = &ast_null_frame; 07814 } else { 07815 ast_channel_lock(ast); 07816 sip_pvt_lock(p); 07817 ast_log(LOG_NOTICE, "FAX CNG detected but no fax extension\n"); 07818 } 07819 } 07820 } 07821 07822 /* Only allow audio through if they sent progress with SDP, or if the channel is actually answered */ 07823 if (fr && fr->frametype == AST_FRAME_VOICE && p->invitestate != INV_EARLY_MEDIA && ast->_state != AST_STATE_UP) { 07824 ast_frfree(fr); 07825 fr = &ast_null_frame; 07826 } 07827 07828 sip_pvt_unlock(p); 07829 07830 return fr; 07831 }
| static struct ast_sockaddr * sip_real_dst | ( | const struct sip_pvt * | p | ) | [static, read] |
The real destination address for a write.
Definition at line 3395 of file chan_sip.c.
References ast_test_flag.
Referenced by __sip_xmit(), check_via(), retrans_pkt(), send_response(), show_channels_cb(), sip_debug_test_pvt(), and sip_prepare_socket().
03396 { 03397 if (p->outboundproxy) { 03398 return &p->outboundproxy->ip; 03399 } 03400 03401 return ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT) || ast_test_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT) ? &p->recv : &p->sa; 03402 }
| static const char* sip_reason_code_to_str | ( | enum AST_REDIRECTING_REASON | code | ) | [static] |
Definition at line 2286 of file chan_sip.c.
References ARRAY_LEN, sip_reason_table, and sip_reasons::text.
Referenced by add_diversion_header().
02287 { 02288 if (code >= 0 && code < ARRAY_LEN(sip_reason_table)) { 02289 return sip_reason_table[code].text; 02290 } 02291 02292 return "unknown"; 02293 }
| static enum AST_REDIRECTING_REASON sip_reason_str_to_code | ( | const char * | text | ) | [static] |
Definition at line 2271 of file chan_sip.c.
References ARRAY_LEN, AST_REDIRECTING_REASON_UNKNOWN, sip_reasons::code, and sip_reason_table.
Referenced by get_rdnis().
02272 { 02273 enum AST_REDIRECTING_REASON ast = AST_REDIRECTING_REASON_UNKNOWN; 02274 int i; 02275 02276 for (i = 0; i < ARRAY_LEN(sip_reason_table); ++i) { 02277 if (!strcasecmp(text, sip_reason_table[i].text)) { 02278 ast = sip_reason_table[i].code; 02279 break; 02280 } 02281 } 02282 02283 return ast; 02284 }
| static int sip_refer_allocate | ( | struct sip_pvt * | p | ) | [static] |
Allocate SIP refer structure.
Definition at line 13954 of file chan_sip.c.
References ast_calloc.
Referenced by get_also_info(), handle_request_invite(), handle_request_refer(), and transmit_refer().
13955 { 13956 p->refer = ast_calloc(1, sizeof(struct sip_refer)); 13957 return p->refer ? 1 : 0; 13958 }
| static int sip_reg_timeout | ( | const void * | data | ) | [static] |
Registration timeout, register again Registered as a timeout handler during transmit_register(), to retransmit the packet if a reply does not come back. This is called by the scheduler so the event is not pending anymore when we are called.
Definition at line 13612 of file chan_sip.c.
References __sip_pretend_ack(), ast_dnsmgr_refresh(), ast_log(), EVENT_FLAG_SYSTEM, LOG_NOTICE, manager_event, pvt_set_needdestroy(), REG_STATE_UNREGISTERED, registry_unref(), regstate2str(), sip_pvt_lock, sip_pvt_unlock, and transmit_register().
Referenced by sip_show_sched(), and transmit_register().
13613 { 13614 13615 /* if we are here, our registration timed out, so we'll just do it over */ 13616 struct sip_registry *r = (struct sip_registry *)data; /* the ref count should have been bumped when the sched item was added */ 13617 struct sip_pvt *p; 13618 13619 /* if we couldn't get a reference to the registry object, punt */ 13620 if (!r) { 13621 return 0; 13622 } 13623 13624 if (r->dnsmgr) { 13625 /* If the registration has timed out, maybe the IP changed. Force a refresh. */ 13626 ast_dnsmgr_refresh(r->dnsmgr); 13627 } 13628 13629 /* If the initial tranmission failed, we may not have an existing dialog, 13630 * so it is possible that r->call == NULL. 13631 * Otherwise destroy it, as we have a timeout so we don't want it. 13632 */ 13633 if (r->call) { 13634 /* Unlink us, destroy old call. Locking is not relevant here because all this happens 13635 in the single SIP manager thread. */ 13636 p = r->call; 13637 sip_pvt_lock(p); 13638 pvt_set_needdestroy(p, "registration timeout"); 13639 /* Pretend to ACK anything just in case */ 13640 __sip_pretend_ack(p); 13641 sip_pvt_unlock(p); 13642 13643 /* decouple the two objects */ 13644 /* p->registry == r, so r has 2 refs, and the unref won't take the object away */ 13645 if (p->registry) { 13646 p->registry = registry_unref(p->registry, "p->registry unreffed"); 13647 } 13648 r->call = dialog_unref(r->call, "unrefing r->call"); 13649 } 13650 /* If we have a limit, stop registration and give up */ 13651 r->timeout = -1; 13652 if (global_regattempts_max && r->regattempts >= global_regattempts_max) { 13653 /* Ok, enough is enough. Don't try any more */ 13654 /* We could add an external notification here... 13655 steal it from app_voicemail :-) */ 13656 ast_log(LOG_NOTICE, " -- Last Registration Attempt #%d failed, Giving up forever trying to register '%s@%s'\n", r->regattempts, r->username, r->hostname); 13657 r->regstate = REG_STATE_FAILED; 13658 } else { 13659 r->regstate = REG_STATE_UNREGISTERED; 13660 transmit_register(r, SIP_REGISTER, NULL, NULL); 13661 ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 13662 } 13663 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: SIP\r\nUsername: %s\r\nDomain: %s\r\nStatus: %s\r\n", r->username, r->hostname, regstate2str(r->regstate)); 13664 registry_unref(r, "unreffing registry_unref r"); 13665 return 0; 13666 }
| static int sip_register | ( | const char * | value, | |
| int | lineno | |||
| ) | [static] |
create sip_registry object from register=> line in sip.conf and link into reg container
Definition at line 8545 of file chan_sip.c.
References ast_atomic_fetchadd_int(), ast_calloc_with_stringfields, ast_log(), ASTOBJ_CONTAINER_LINK, ASTOBJ_INIT, LOG_ERROR, registry_unref(), regl, and sip_parse_register_line().
Referenced by build_peer(), and reload_config().
08546 { 08547 struct sip_registry *reg; 08548 08549 if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) { 08550 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n"); 08551 return -1; 08552 } 08553 08554 ast_atomic_fetchadd_int(®objs, 1); 08555 ASTOBJ_INIT(reg); 08556 08557 if (sip_parse_register_line(reg, default_expiry, value, lineno)) { 08558 registry_unref(reg, "failure to parse, unref the reg pointer"); 08559 return -1; 08560 } 08561 08562 /* set default expiry if necessary */ 08563 if (reg->refresh && !reg->expiry && !reg->configured_expiry) { 08564 reg->refresh = reg->expiry = reg->configured_expiry = default_expiry; 08565 } 08566 08567 /* Add the new registry entry to the list */ 08568 ASTOBJ_CONTAINER_LINK(®l, reg); 08569 08570 /* release the reference given by ASTOBJ_INIT. The container has another reference */ 08571 registry_unref(reg, "unref the reg pointer"); 08572 08573 return 0; 08574 }
| static void sip_register_tests | ( | void | ) | [static] |
SIP test registration.
Definition at line 30855 of file chan_sip.c.
References sip_config_parser_register_tests(), sip_dialplan_function_register_tests(), and sip_request_parser_register_tests().
Referenced by load_module().
30856 { 30857 sip_config_parser_register_tests(); 30858 sip_request_parser_register_tests(); 30859 sip_dialplan_function_register_tests(); 30860 }
| static void sip_registry_destroy | ( | struct sip_registry * | reg | ) | [static] |
Destroy registry object Objects created with the register= statement in static configuration.
Definition at line 5932 of file chan_sip.c.
References ast_atomic_fetchadd_int(), ast_debug, ast_free, AST_SCHED_DEL, ast_string_field_free_memory, dialog_unlink_all(), and registry_unref().
Referenced by registry_unref(), reload_config(), and unload_module().
05933 { 05934 /* Really delete */ 05935 ast_debug(3, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname); 05936 05937 if (reg->call) { 05938 /* Clear registry before destroying to ensure 05939 we don't get reentered trying to grab the registry lock */ 05940 reg->call->registry = registry_unref(reg->call->registry, "destroy reg->call->registry"); 05941 ast_debug(3, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname); 05942 dialog_unlink_all(reg->call); 05943 reg->call = dialog_unref(reg->call, "unref reg->call"); 05944 /* reg->call = sip_destroy(reg->call); */ 05945 } 05946 AST_SCHED_DEL(sched, reg->expire); 05947 AST_SCHED_DEL(sched, reg->timeout); 05948 05949 ast_string_field_free_memory(reg); 05950 ast_atomic_fetchadd_int(®objs, -1); 05951 ast_free(reg); 05952 }
| static int sip_reinvite_retry | ( | const void * | data | ) | [static] |
Reset the NEEDREINVITE flag after waiting when we get 491 on a Re-invite to avoid race conditions between asterisk servers. Called from the scheduler.
Definition at line 20518 of file chan_sip.c.
References ast_channel_trylock, ast_channel_unlock, ast_set_flag, check_pendings(), sip_pvt_lock, and sip_pvt_unlock.
Referenced by handle_response_invite(), and sip_show_sched().
20519 { 20520 struct sip_pvt *p = (struct sip_pvt *) data; 20521 struct ast_channel *owner; 20522 20523 sip_pvt_lock(p); /* called from schedule thread which requires a lock */ 20524 while ((owner = p->owner) && ast_channel_trylock(owner)) { 20525 sip_pvt_unlock(p); 20526 usleep(1); 20527 sip_pvt_lock(p); 20528 } 20529 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 20530 p->waitid = -1; 20531 check_pendings(p); 20532 sip_pvt_unlock(p); 20533 if (owner) { 20534 ast_channel_unlock(owner); 20535 } 20536 dialog_unref(p, "unref the dialog ptr from sip_reinvite_retry, because it held a dialog ptr"); 20537 return 0; 20538 }
| static char * sip_reload | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Force reload of module from cli.
Definition at line 30604 of file chan_sip.c.
References ao2_t_ref, ast_clear_flag, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_string_field_set, ast_verbose, BOGUS_PEER_MD5SECRET, CHANNEL_CLI_RELOAD, CHANNEL_MODULE_RELOAD, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, LOG_ERROR, restart_monitor(), temp_peer(), TRUE, and ast_cli_entry::usage.
Referenced by reload().
30605 { 30606 static struct sip_peer *tmp_peer, *new_peer; 30607 30608 switch (cmd) { 30609 case CLI_INIT: 30610 e->command = "sip reload"; 30611 e->usage = 30612 "Usage: sip reload\n" 30613 " Reloads SIP configuration from sip.conf\n"; 30614 return NULL; 30615 case CLI_GENERATE: 30616 return NULL; 30617 } 30618 30619 ast_mutex_lock(&sip_reload_lock); 30620 if (sip_reloading) { 30621 ast_verbose("Previous SIP reload not yet done\n"); 30622 } else { 30623 sip_reloading = TRUE; 30624 sip_reloadreason = (a && a->fd) ? CHANNEL_CLI_RELOAD : CHANNEL_MODULE_RELOAD; 30625 } 30626 ast_mutex_unlock(&sip_reload_lock); 30627 restart_monitor(); 30628 30629 tmp_peer = bogus_peer; 30630 /* Create new bogus peer possibly with new global settings. */ 30631 if ((new_peer = temp_peer("(bogus_peer)"))) { 30632 ast_string_field_set(new_peer, md5secret, BOGUS_PEER_MD5SECRET); 30633 ast_clear_flag(&new_peer->flags[0], SIP_INSECURE); 30634 bogus_peer = new_peer; 30635 ao2_t_ref(tmp_peer, -1, "unref the old bogus_peer during reload"); 30636 } else { 30637 ast_log(LOG_ERROR, "Could not update the fake authentication peer.\n"); 30638 /* You probably have bigger (memory?) issues to worry about though.. */ 30639 } 30640 30641 return CLI_SUCCESS; 30642 }
| static int sip_removeheader | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Remove SIP headers added previously with SipAddHeader application.
Definition at line 30350 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_debug, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_strlen_zero(), ast_var_delete(), ast_var_name(), ast_var_value(), inbuf(), and ast_channel::varshead.
Referenced by load_module().
30351 { 30352 struct ast_var_t *newvariable; 30353 struct varshead *headp; 30354 int removeall = 0; 30355 char *inbuf = (char *) data; 30356 30357 if (ast_strlen_zero(inbuf)) { 30358 removeall = 1; 30359 } 30360 ast_channel_lock(chan); 30361 30362 headp=&chan->varshead; 30363 AST_LIST_TRAVERSE_SAFE_BEGIN (headp, newvariable, entries) { 30364 if (strncasecmp(ast_var_name(newvariable), "SIPADDHEADER", strlen("SIPADDHEADER")) == 0) { 30365 if (removeall || (!strncasecmp(ast_var_value(newvariable),inbuf,strlen(inbuf)))) { 30366 if (sipdebug) 30367 ast_debug(1,"removing SIP Header \"%s\" as %s\n", 30368 ast_var_value(newvariable), 30369 ast_var_name(newvariable)); 30370 AST_LIST_REMOVE_CURRENT(entries); 30371 ast_var_delete(newvariable); 30372 } 30373 } 30374 } 30375 AST_LIST_TRAVERSE_SAFE_END; 30376 30377 ast_channel_unlock(chan); 30378 return 0; 30379 }
| static struct ast_channel * sip_request_call | ( | const char * | type, | |
| format_t | format, | |||
| const struct ast_channel * | requestor, | |||
| void * | data, | |||
| int * | cause | |||
| ) | [static, read] |
PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here.
* SIP Dial string syntax: * SIP/devicename * or SIP/username@domain (SIP uri) * or SIP/username[:password[:md5secret[:authname[:transport]]]]@host[:port] * or SIP/devicename/extension * or SIP/devicename/extension/IPorHost * or SIP/username@domain//IPorHost * and there is an optional [!dnid] argument you can append to alter the * To: header. *
Definition at line 27291 of file chan_sip.c.
References args, AST_APP_ARG, ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_CHANNEL_UNACCEPTABLE, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNREGISTERED, ast_channel_unlock, ast_copy_string(), ast_debug, AST_DECLARE_APP_ARGS, AST_FORMAT_AUDIO_MASK, ast_getformatname(), ast_getformatname_multiple(), ast_log(), AST_NONSTANDARD_APP_ARGS, ast_sip_ouraddrfor(), AST_STATE_DOWN, ast_string_field_set, ast_strlen_zero(), ast_update_use_count(), build_via(), change_callid_pvt(), create_addr(), dialog_unlink_all(), EVENT_FLAG_SYSTEM, ext, exten, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event, proxy_from_config(), restart_monitor(), secret, set_socket_transport(), sip_alloc(), sip_cfg, sip_new(), sip_pvt_lock, sip_pvt_unlock, and TRUE.
27292 { 27293 struct sip_pvt *p; 27294 struct ast_channel *tmpc = NULL; 27295 char *ext = NULL, *host; 27296 char tmp[256]; 27297 char *dest = data; 27298 char *dnid; 27299 char *secret = NULL; 27300 char *md5secret = NULL; 27301 char *authname = NULL; 27302 char *trans = NULL; 27303 char dialstring[256]; 27304 char *remote_address; 27305 enum sip_transport transport = 0; 27306 format_t oldformat = format; 27307 AST_DECLARE_APP_ARGS(args, 27308 AST_APP_ARG(peerorhost); 27309 AST_APP_ARG(exten); 27310 AST_APP_ARG(remote_address); 27311 ); 27312 27313 /* mask request with some set of allowed formats. 27314 * XXX this needs to be fixed. 27315 * The original code uses AST_FORMAT_AUDIO_MASK, but it is 27316 * unclear what to use here. We have global_capabilities, which is 27317 * configured from sip.conf, and sip_tech.capabilities, which is 27318 * hardwired to all audio formats. 27319 */ 27320 format &= AST_FORMAT_AUDIO_MASK; 27321 if (!format) { 27322 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format %s while capability is %s\n", ast_getformatname(oldformat), ast_getformatname(sip_cfg.capability)); 27323 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; /* Can't find codec to connect to host */ 27324 return NULL; 27325 } 27326 ast_debug(1, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat)); 27327 27328 if (ast_strlen_zero(dest)) { 27329 ast_log(LOG_ERROR, "Unable to create channel with empty destination.\n"); 27330 *cause = AST_CAUSE_CHANNEL_UNACCEPTABLE; 27331 return NULL; 27332 } 27333 27334 if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE, NULL))) { 27335 ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", dest); 27336 *cause = AST_CAUSE_SWITCH_CONGESTION; 27337 return NULL; 27338 } 27339 27340 p->outgoing_call = TRUE; 27341 27342 snprintf(dialstring, sizeof(dialstring), "%s/%s", type, dest); 27343 ast_string_field_set(p, dialstring, dialstring); 27344 27345 if (!(p->options = ast_calloc(1, sizeof(*p->options)))) { 27346 dialog_unlink_all(p); 27347 dialog_unref(p, "unref dialog p from mem fail"); 27348 /* sip_destroy(p); */ 27349 ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n"); 27350 *cause = AST_CAUSE_SWITCH_CONGESTION; 27351 return NULL; 27352 } 27353 27354 /* Save the destination, the SIP dial string */ 27355 ast_copy_string(tmp, dest, sizeof(tmp)); 27356 27357 /* Find DNID and take it away */ 27358 dnid = strchr(tmp, '!'); 27359 if (dnid != NULL) { 27360 *dnid++ = '\0'; 27361 ast_string_field_set(p, todnid, dnid); 27362 } 27363 27364 /* Divvy up the items separated by slashes */ 27365 AST_NONSTANDARD_APP_ARGS(args, tmp, '/'); 27366 27367 /* Find at sign - @ */ 27368 host = strchr(args.peerorhost, '@'); 27369 if (host) { 27370 *host++ = '\0'; 27371 ext = args.peerorhost; 27372 secret = strchr(ext, ':'); 27373 } 27374 if (secret) { 27375 *secret++ = '\0'; 27376 md5secret = strchr(secret, ':'); 27377 } 27378 if (md5secret) { 27379 *md5secret++ = '\0'; 27380 authname = strchr(md5secret, ':'); 27381 } 27382 if (authname) { 27383 *authname++ = '\0'; 27384 trans = strchr(authname, ':'); 27385 } 27386 if (trans) { 27387 *trans++ = '\0'; 27388 if (!strcasecmp(trans, "tcp")) 27389 transport = SIP_TRANSPORT_TCP; 27390 else if (!strcasecmp(trans, "tls")) 27391 transport = SIP_TRANSPORT_TLS; 27392 else { 27393 if (strcasecmp(trans, "udp")) 27394 ast_log(LOG_WARNING, "'%s' is not a valid transport option to Dial() for SIP calls, using udp by default.\n", trans); 27395 transport = SIP_TRANSPORT_UDP; 27396 } 27397 } else { /* use default */ 27398 transport = SIP_TRANSPORT_UDP; 27399 } 27400 27401 if (!host) { 27402 ext = args.exten; 27403 host = args.peerorhost; 27404 remote_address = args.remote_address; 27405 } else { 27406 remote_address = args.remote_address; 27407 if (!ast_strlen_zero(args.exten)) { 27408 ast_log(LOG_NOTICE, "Conflicting extension values given. Using '%s' and not '%s'\n", ext, args.exten); 27409 } 27410 } 27411 27412 if (!ast_strlen_zero(remote_address)) { 27413 p->options->outboundproxy = proxy_from_config(remote_address, 0, NULL); 27414 if (!p->options->outboundproxy) { 27415 ast_log(LOG_WARNING, "Unable to parse outboundproxy %s. We will not use this remote IP address\n", remote_address); 27416 } 27417 } 27418 27419 set_socket_transport(&p->socket, transport); 27420 27421 /* We now have 27422 host = peer name, DNS host name or DNS domain (for SRV) 27423 ext = extension (user part of URI) 27424 dnid = destination of the call (applies to the To: header) 27425 */ 27426 if (create_addr(p, host, NULL, 1)) { 27427 *cause = AST_CAUSE_UNREGISTERED; 27428 ast_debug(3, "Cant create SIP call - target device not registered\n"); 27429 dialog_unlink_all(p); 27430 dialog_unref(p, "unref dialog p UNREGISTERED"); 27431 /* sip_destroy(p); */ 27432 return NULL; 27433 } 27434 if (ast_strlen_zero(p->peername) && ext) 27435 ast_string_field_set(p, peername, ext); 27436 /* Recalculate our side, and recalculate Call ID */ 27437 ast_sip_ouraddrfor(&p->sa, &p->ourip, p); 27438 build_via(p); 27439 27440 /* Change the dialog callid. */ 27441 change_callid_pvt(p, NULL); 27442 27443 /* We have an extension to call, don't use the full contact here */ 27444 /* This to enable dialing registered peers with extension dialling, 27445 like SIP/peername/extension 27446 SIP/peername will still use the full contact 27447 */ 27448 if (ext) { 27449 ast_string_field_set(p, username, ext); 27450 ast_string_field_set(p, fullcontact, NULL); 27451 } 27452 if (secret && !ast_strlen_zero(secret)) 27453 ast_string_field_set(p, peersecret, secret); 27454 27455 if (md5secret && !ast_strlen_zero(md5secret)) 27456 ast_string_field_set(p, peermd5secret, md5secret); 27457 27458 if (authname && !ast_strlen_zero(authname)) 27459 ast_string_field_set(p, authname, authname); 27460 #if 0 27461 printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host); 27462 #endif 27463 p->prefcodec = oldformat; /* Format for this call */ 27464 p->jointcapability = oldformat & p->capability; 27465 sip_pvt_lock(p); 27466 tmpc = sip_new(p, AST_STATE_DOWN, host, requestor ? requestor->linkedid : NULL); /* Place the call */ 27467 if (sip_cfg.callevents) 27468 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", 27469 "Channel: %s\r\nChanneltype: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\nPeername: %s\r\n", 27470 p->owner ? p->owner->name : "", "SIP", p->callid, p->fullcontact, p->peername); 27471 sip_pvt_unlock(p); 27472 if (!tmpc) { 27473 dialog_unlink_all(p); 27474 /* sip_destroy(p); */ 27475 } else { 27476 ast_channel_unlock(tmpc); 27477 } 27478 dialog_unref(p, "toss pvt ptr at end of sip_request_call"); 27479 ast_update_use_count(); 27480 restart_monitor(); 27481 return tmpc; 27482 }
| static int sip_reregister | ( | const void * | data | ) | [static] |
Update registration with SIP Proxy. Called from the scheduler when the previous registration expires, so we don't have to cancel the pending event. We assume the reference so the sip_registry is valid, since it is stored in the scheduled event anyways.
Definition at line 13569 of file chan_sip.c.
References __sip_do_register(), append_history, ast_log(), LOG_NOTICE, and registry_unref().
Referenced by handle_response_register(), sip_send_all_registers(), and sip_show_sched().
13570 { 13571 /* if we are here, we know that we need to reregister. */ 13572 struct sip_registry *r = (struct sip_registry *) data; 13573 13574 /* if we couldn't get a reference to the registry object, punt */ 13575 if (!r) { 13576 return 0; 13577 } 13578 13579 if (r->call && r->call->do_history) { 13580 append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname); 13581 } 13582 /* Since registry's are only added/removed by the the monitor thread, this 13583 may be overkill to reference/dereference at all here */ 13584 if (sipdebug) { 13585 ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname); 13586 } 13587 13588 r->expire = -1; 13589 r->expiry = r->configured_expiry; 13590 __sip_do_register(r); 13591 registry_unref(r, "unref the re-register scheduled event"); 13592 return 0; 13593 }
| static struct ast_frame* sip_rtp_read | ( | struct ast_channel * | ast, | |
| struct sip_pvt * | p, | |||
| int * | faxdetect | |||
| ) | [static, read] |
Read RTP from network.
Definition at line 7691 of file chan_sip.c.
References ast_debug, ast_dsp_free(), ast_dsp_process(), ast_dsp_set_features(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_TEXT_MASK, AST_FORMAT_VIDEO_MASK, AST_FRAME_DTMF, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_VOICE, ast_frfree, ast_getformatname(), ast_null_frame, ast_rtp_instance_read(), ast_set_read_format(), ast_set_write_format(), ast_test_flag, ast_udptl_read(), ast_verbose, ast_frame_subclass::codec, ast_frame::data, ast_frame::datalen, DSP_FEATURE_DIGIT_DETECT, f, ast_channel::fdno, ast_frame::frametype, ast_frame_subclass::integer, ast_frame::ptr, and ast_frame::subclass.
Referenced by sip_read().
07692 { 07693 /* Retrieve audio/etc from channel. Assumes p->lock is already held. */ 07694 struct ast_frame *f; 07695 07696 if (!p->rtp) { 07697 /* We have no RTP allocated for this channel */ 07698 return &ast_null_frame; 07699 } 07700 07701 switch(ast->fdno) { 07702 case 0: 07703 f = ast_rtp_instance_read(p->rtp, 0); /* RTP Audio */ 07704 break; 07705 case 1: 07706 f = ast_rtp_instance_read(p->rtp, 1); /* RTCP Control Channel */ 07707 break; 07708 case 2: 07709 f = ast_rtp_instance_read(p->vrtp, 0); /* RTP Video */ 07710 break; 07711 case 3: 07712 f = ast_rtp_instance_read(p->vrtp, 1); /* RTCP Control Channel for video */ 07713 break; 07714 case 4: 07715 f = ast_rtp_instance_read(p->trtp, 0); /* RTP Text */ 07716 if (sipdebug_text) { 07717 int i; 07718 unsigned char* arr = f->data.ptr; 07719 for (i=0; i < f->datalen; i++) 07720 ast_verbose("%c", (arr[i] > ' ' && arr[i] < '}') ? arr[i] : '.'); 07721 ast_verbose(" -> "); 07722 for (i=0; i < f->datalen; i++) 07723 ast_verbose("%02X ", (unsigned)arr[i]); 07724 ast_verbose("\n"); 07725 } 07726 break; 07727 case 5: 07728 f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */ 07729 break; 07730 default: 07731 f = &ast_null_frame; 07732 } 07733 /* Don't forward RFC2833 if we're not supposed to */ 07734 if (f && (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END) && 07735 (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833)) { 07736 ast_debug(1, "Ignoring DTMF (%c) RTP frame because dtmfmode is not RFC2833\n", f->subclass.integer); 07737 ast_frfree(f); 07738 return &ast_null_frame; 07739 } 07740 07741 /* We already hold the channel lock */ 07742 if (!p->owner || (f && f->frametype != AST_FRAME_VOICE)) 07743 return f; 07744 07745 if (f && f->subclass.codec != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) { 07746 if (!(f->subclass.codec & p->jointcapability)) { 07747 ast_debug(1, "Bogus frame of format '%s' received from '%s'!\n", 07748 ast_getformatname(f->subclass.codec), p->owner->name); 07749 ast_frfree(f); 07750 return &ast_null_frame; 07751 } 07752 ast_debug(1, "Oooh, format changed to %s\n", 07753 ast_getformatname(f->subclass.codec)); 07754 p->owner->nativeformats = (p->owner->nativeformats & (AST_FORMAT_VIDEO_MASK | AST_FORMAT_TEXT_MASK)) | f->subclass.codec; 07755 ast_set_read_format(p->owner, p->owner->readformat); 07756 ast_set_write_format(p->owner, p->owner->writeformat); 07757 } 07758 07759 if (f && p->dsp) { 07760 f = ast_dsp_process(p->owner, p->dsp, f); 07761 if (f && f->frametype == AST_FRAME_DTMF) { 07762 if (f->subclass.integer == 'f') { 07763 ast_debug(1, "Fax CNG detected on %s\n", ast->name); 07764 *faxdetect = 1; 07765 /* If we only needed this DSP for fax detection purposes we can just drop it now */ 07766 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 07767 ast_dsp_set_features(p->dsp, DSP_FEATURE_DIGIT_DETECT); 07768 } else { 07769 ast_dsp_free(p->dsp); 07770 p->dsp = NULL; 07771 } 07772 } else { 07773 ast_debug(1, "* Detected inband DTMF '%c'\n", f->subclass.integer); 07774 } 07775 } 07776 } 07777 07778 return f; 07779 }
| static const char* sip_sanitized_host | ( | const char * | host | ) | [static] |
Definition at line 13668 of file chan_sip.c.
References ast_sockaddr_parse(), ast_sockaddr_stringify_host_remote(), and PARSE_PORT_FORBID.
Referenced by transmit_register().
13669 { 13670 struct ast_sockaddr addr = { { 0, 0, }, }; 13671 13672 /* peer/sip_pvt->tohost and sip_registry->hostname should never have a port 13673 * in them, so we use PARSE_PORT_FORBID here. If this lookup fails, we return 13674 * the original host which is most likely a host name and not an IP. */ 13675 if (!ast_sockaddr_parse(&addr, host, PARSE_PORT_FORBID)) { 13676 return host; 13677 } 13678 return ast_sockaddr_stringify_host_remote(&addr); 13679 }
| void sip_scheddestroy | ( | struct sip_pvt * | p, | |
| int | ms | |||
| ) |
Schedule destruction of SIP dialog.
Definition at line 4107 of file chan_sip.c.
References __sip_autodestruct(), append_history, ast_log(), ast_sched_add(), ast_verbose, LOG_WARNING, sip_cancel_destroy(), sip_debug_test_pvt(), sip_methods, stop_session_timer(), cfsip_methods::text, and TRUE.
Referenced by __sip_autodestruct(), auto_congest(), cb_extensionstate(), check_auth(), check_pendings(), handle_incoming(), handle_invite_replaces(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_options(), handle_request_publish(), handle_request_register(), handle_request_subscribe(), handle_response_invite(), manager_sipnotify(), receive_message(), sip_cli_notify(), sip_hangup(), sip_scheddestroy_final(), sip_send_mwi_to_peer(), sip_sipredirect(), transmit_fake_auth_response(), and transmit_publish().
04108 { 04109 if (p->final_destruction_scheduled) { 04110 return; /* already set final destruction */ 04111 } 04112 04113 if (ms < 0) { 04114 if (p->timer_t1 == 0) { 04115 p->timer_t1 = global_t1; /* Set timer T1 if not set (RFC 3261) */ 04116 } 04117 if (p->timer_b == 0) { 04118 p->timer_b = global_timer_b; /* Set timer B if not set (RFC 3261) */ 04119 } 04120 ms = p->timer_t1 * 64; 04121 } 04122 if (sip_debug_test_pvt(p)) { 04123 ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text); 04124 } 04125 if (sip_cancel_destroy(p)) { 04126 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 04127 } 04128 04129 if (p->do_history) { 04130 append_history(p, "SchedDestroy", "%d ms", ms); 04131 } 04132 p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, dialog_ref(p, "setting ref as passing into ast_sched_add for __sip_autodestruct")); 04133 04134 if (p->stimer && p->stimer->st_active == TRUE && p->stimer->st_schedid > 0) { 04135 stop_session_timer(p); 04136 } 04137 }
| void sip_scheddestroy_final | ( | struct sip_pvt * | p, | |
| int | ms | |||
| ) |
Schedule final destruction of SIP dialog. This can not be canceled. This function is used to keep a dialog around for a period of time in order to properly respond to any retransmits.
Definition at line 4094 of file chan_sip.c.
References sip_scheddestroy().
Referenced by handle_request_bye().
04095 { 04096 if (p->final_destruction_scheduled) { 04097 return; /* already set final destruction */ 04098 } 04099 04100 sip_scheddestroy(p, ms); 04101 if (p->autokillid != -1) { 04102 p->final_destruction_scheduled = 1; 04103 } 04104 }
| static void sip_send_all_mwi_subscriptions | ( | void | ) | [static] |
Send all MWI subscriptions.
Definition at line 30508 of file chan_sip.c.
References ast_sched_add(), AST_SCHED_DEL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_REF, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, sip_subscribe_mwi_destroy(), sip_subscribe_mwi_do(), and submwil.
Referenced by load_module(), network_change_event_sched_cb(), and sip_do_reload().
30509 { 30510 ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do { 30511 struct sip_subscription_mwi *saved; 30512 ASTOBJ_WRLOCK(iterator); 30513 AST_SCHED_DEL(sched, iterator->resub); 30514 saved = ASTOBJ_REF(iterator); 30515 if ((iterator->resub = ast_sched_add(sched, 1, sip_subscribe_mwi_do, saved)) < 0) { 30516 ASTOBJ_UNREF(saved, sip_subscribe_mwi_destroy); 30517 } 30518 ASTOBJ_UNLOCK(iterator); 30519 } while (0)); 30520 }
| static void sip_send_all_registers | ( | void | ) | [static] |
Send all known registrations.
Definition at line 30484 of file chan_sip.c.
References AST_SCHED_REPLACE_UNREF, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, registry_addref(), registry_unref(), regl, and sip_reregister().
Referenced by load_module(), network_change_event_sched_cb(), and sip_do_reload().
30485 { 30486 int ms; 30487 int regspacing; 30488 if (!regobjs) 30489 return; 30490 regspacing = default_expiry * 1000/regobjs; 30491 if (regspacing > 100) { 30492 regspacing = 100; 30493 } 30494 ms = regspacing; 30495 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 30496 ASTOBJ_WRLOCK(iterator); 30497 ms += regspacing; 30498 AST_SCHED_REPLACE_UNREF(iterator->expire, sched, ms, sip_reregister, iterator, 30499 registry_unref(_data, "REPLACE sched del decs the refcount"), 30500 registry_unref(iterator, "REPLACE sched add failure decs the refcount"), 30501 registry_addref(iterator, "REPLACE sched add incs the refcount")); 30502 ASTOBJ_UNLOCK(iterator); 30503 } while (0) 30504 ); 30505 }
| static int sip_send_mwi_to_peer | ( | struct sip_peer * | peer, | |
| int | cache_only | |||
| ) | [static] |
Send message waiting indication to alert peer that they've got voicemail.
Definition at line 26442 of file chan_sip.c.
References ao2_lock, ao2_unlock, ast_app_inboxcount(), ast_set_flag, ast_sip_ouraddrfor(), ast_sockaddr_isnull(), ast_str_alloca, ast_str_buffer(), ast_str_strlen(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, build_via(), change_callid_pvt(), create_addr_from_peer(), dialog_unlink_all(), get_cached_mwi(), peer_mailboxes_to_str(), set_socket_transport(), sip_alloc(), sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), transmit_notify_with_mwi(), and update_peer_lastmsgssent().
Referenced by build_peer(), handle_request_subscribe(), mwi_event_cb(), and register_verify().
26443 { 26444 /* Called with peer lock, but releases it */ 26445 struct sip_pvt *p; 26446 int newmsgs = 0, oldmsgs = 0; 26447 const char *vmexten = NULL; 26448 26449 ao2_lock(peer); 26450 26451 if (peer->vmexten) { 26452 vmexten = ast_strdupa(peer->vmexten); 26453 } 26454 26455 if (ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY) && !peer->mwipvt) { 26456 update_peer_lastmsgssent(peer, -1, 1); 26457 ao2_unlock(peer); 26458 return 0; 26459 } 26460 26461 /* Do we have an IP address? If not, skip this peer */ 26462 if (ast_sockaddr_isnull(&peer->addr) && ast_sockaddr_isnull(&peer->defaddr)) { 26463 update_peer_lastmsgssent(peer, -1, 1); 26464 ao2_unlock(peer); 26465 return 0; 26466 } 26467 26468 /* Attempt to use cached mwi to get message counts. */ 26469 if (!get_cached_mwi(peer, &newmsgs, &oldmsgs) && !cache_only) { 26470 /* Fall back to manually checking the mailbox if not cache_only and get_cached_mwi failed */ 26471 struct ast_str *mailbox_str = ast_str_alloca(512); 26472 peer_mailboxes_to_str(&mailbox_str, peer); 26473 ao2_unlock(peer); 26474 /* If there is no mailbox do nothing */ 26475 if (!ast_str_strlen(mailbox_str)) { 26476 update_peer_lastmsgssent(peer, -1, 0); 26477 return 0; 26478 } 26479 ast_app_inboxcount(ast_str_buffer(mailbox_str), &newmsgs, &oldmsgs); 26480 ao2_lock(peer); 26481 } 26482 26483 if (peer->mwipvt) { 26484 /* Base message on subscription */ 26485 p = dialog_ref(peer->mwipvt, "sip_send_mwi_to_peer: Setting dialog ptr p from peer->mwipvt"); 26486 ao2_unlock(peer); 26487 } else { 26488 ao2_unlock(peer); 26489 /* Build temporary dialog for this message */ 26490 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) { 26491 update_peer_lastmsgssent(peer, -1, 0); 26492 return -1; 26493 } 26494 26495 /* If we don't set the socket type to 0, then create_addr_from_peer will fail immediately if the peer 26496 * uses any transport other than UDP. We set the type to 0 here and then let create_addr_from_peer copy 26497 * the peer's socket information to the sip_pvt we just allocated 26498 */ 26499 set_socket_transport(&p->socket, 0); 26500 if (create_addr_from_peer(p, peer)) { 26501 /* Maybe they're not registered, etc. */ 26502 dialog_unlink_all(p); 26503 dialog_unref(p, "unref dialog p just created via sip_alloc"); 26504 update_peer_lastmsgssent(peer, -1, 0); 26505 return 0; 26506 } 26507 /* Recalculate our side, and recalculate Call ID */ 26508 ast_sip_ouraddrfor(&p->sa, &p->ourip, p); 26509 build_via(p); 26510 26511 ao2_lock(peer); 26512 if (!ast_strlen_zero(peer->mwi_from)) { 26513 ast_string_field_set(p, mwi_from, peer->mwi_from); 26514 } else if (!ast_strlen_zero(default_mwi_from)) { 26515 ast_string_field_set(p, mwi_from, default_mwi_from); 26516 } 26517 ao2_unlock(peer); 26518 26519 /* Change the dialog callid. */ 26520 change_callid_pvt(p, NULL); 26521 26522 /* Destroy this session after 32 secs */ 26523 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 26524 } 26525 26526 /* We have multiple threads (mwi events and monitor retransmits) working with this PVT and as we modify the sip history if that's turned on, 26527 we really need to have a lock on it */ 26528 sip_pvt_lock(p); 26529 26530 /* Send MWI */ 26531 ast_set_flag(&p->flags[0], SIP_OUTGOING); 26532 /* the following will decrement the refcount on p as it finishes */ 26533 transmit_notify_with_mwi(p, newmsgs, oldmsgs, vmexten); 26534 sip_pvt_unlock(p); 26535 dialog_unref(p, "unref dialog ptr p just before it goes out of scope at the end of sip_send_mwi_to_peer."); 26536 26537 update_peer_lastmsgssent(peer, ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)), 0); 26538 26539 return 0; 26540 }
| static int sip_senddigit_begin | ( | struct ast_channel * | ast, | |
| char | digit | |||
| ) | [static] |
Definition at line 6913 of file chan_sip.c.
References ast_debug, ast_rtp_instance_dtmf_begin(), ast_test_flag, sip_pvt_lock, sip_pvt_unlock, and ast_channel::tech_pvt.
06914 { 06915 struct sip_pvt *p = ast->tech_pvt; 06916 int res = 0; 06917 06918 if (!p) { 06919 ast_debug(1, "Asked to begin DTMF digit on channel %s with no pvt; ignoring\n", 06920 ast->name); 06921 return res; 06922 } 06923 06924 sip_pvt_lock(p); 06925 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 06926 case SIP_DTMF_INBAND: 06927 res = -1; /* Tell Asterisk to generate inband indications */ 06928 break; 06929 case SIP_DTMF_RFC2833: 06930 if (p->rtp) 06931 ast_rtp_instance_dtmf_begin(p->rtp, digit); 06932 break; 06933 default: 06934 break; 06935 } 06936 sip_pvt_unlock(p); 06937 06938 return res; 06939 }
| static int sip_senddigit_end | ( | struct ast_channel * | ast, | |
| char | digit, | |||
| unsigned int | duration | |||
| ) | [static] |
Send DTMF character on SIP channel within one call, we're able to transmit in many methods simultaneously.
Definition at line 6943 of file chan_sip.c.
References ast_debug, ast_rtp_instance_dtmf_end_with_duration(), ast_test_flag, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, and transmit_info_with_digit().
06944 { 06945 struct sip_pvt *p = ast->tech_pvt; 06946 int res = 0; 06947 06948 if (!p) { 06949 ast_debug(1, "Asked to end DTMF digit on channel %s with no pvt; ignoring\n", 06950 ast->name); 06951 return res; 06952 } 06953 06954 sip_pvt_lock(p); 06955 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 06956 case SIP_DTMF_INFO: 06957 case SIP_DTMF_SHORTINFO: 06958 transmit_info_with_digit(p, digit, duration); 06959 break; 06960 case SIP_DTMF_RFC2833: 06961 if (p->rtp) 06962 ast_rtp_instance_dtmf_end_with_duration(p->rtp, digit, duration); 06963 break; 06964 case SIP_DTMF_INBAND: 06965 res = -1; /* Tell Asterisk to stop inband indications */ 06966 break; 06967 } 06968 sip_pvt_unlock(p); 06969 06970 return res; 06971 }
| static int sip_sendhtml | ( | struct ast_channel * | chan, | |
| int | subclass, | |||
| const char * | data, | |||
| int | datalen | |||
| ) | [static] |
Send message with Access-URL header, if this is an HTML URL only!
Definition at line 4642 of file chan_sip.c.
References ast_channel::_state, ast_debug, AST_HTML_URL, ast_log(), ast_set_flag, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_string_field_build, ast_test_flag, FALSE, LOG_WARNING, sip_debug_test_pvt(), ast_channel::tech_pvt, transmit_reinvite_with_sdp(), transmit_response(), and url.
04643 { 04644 struct sip_pvt *p = chan->tech_pvt; 04645 04646 if (subclass != AST_HTML_URL) 04647 return -1; 04648 04649 ast_string_field_build(p, url, "<%s>;mode=active", data); 04650 04651 if (sip_debug_test_pvt(p)) 04652 ast_debug(1, "Send URL %s, state = %u!\n", data, chan->_state); 04653 04654 switch (chan->_state) { 04655 case AST_STATE_RING: 04656 transmit_response(p, "100 Trying", &p->initreq); 04657 break; 04658 case AST_STATE_RINGING: 04659 transmit_response(p, "180 Ringing", &p->initreq); 04660 break; 04661 case AST_STATE_UP: 04662 if (!p->pendinginvite) { /* We are up, and have no outstanding invite */ 04663 transmit_reinvite_with_sdp(p, FALSE, FALSE); 04664 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 04665 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 04666 } 04667 break; 04668 default: 04669 ast_log(LOG_WARNING, "Don't know how to send URI when state is %u!\n", chan->_state); 04670 } 04671 04672 return 0; 04673 }
| static int sip_sendtext | ( | struct ast_channel * | ast, | |
| const char * | text | |||
| ) | [static] |
Definition at line 4686 of file chan_sip.c.
References ast_debug, ast_verbose, is_method_allowed(), sip_debug_test_pvt(), ast_channel::tech_pvt, and transmit_message_with_text().
04687 { 04688 struct sip_pvt *dialog = ast->tech_pvt; 04689 int debug; 04690 04691 if (!dialog) { 04692 return -1; 04693 } 04694 /* NOT ast_strlen_zero, because a zero-length message is specifically 04695 * allowed by RFC 3428 (See section 10, Examples) */ 04696 if (!text) { 04697 return 0; 04698 } 04699 if(!is_method_allowed(&dialog->allowed_methods, SIP_MESSAGE)) { 04700 ast_debug(2, "Trying to send MESSAGE to device that does not support it.\n"); 04701 return(0); 04702 } 04703 04704 debug = sip_debug_test_pvt(dialog); 04705 if (debug) { 04706 ast_verbose("Sending text %s on %s\n", text, ast->name); 04707 } 04708 04709 transmit_message_with_text(dialog, text); 04710 return 0; 04711 }
| static char * sip_set_history | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Enable/Disable SIP History logging (CLI).
Definition at line 19768 of file chan_sip.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, FALSE, ast_cli_args::fd, TRUE, and ast_cli_entry::usage.
19769 { 19770 switch (cmd) { 19771 case CLI_INIT: 19772 e->command = "sip set history {on|off}"; 19773 e->usage = 19774 "Usage: sip set history {on|off}\n" 19775 " Enables/Disables recording of SIP dialog history for debugging purposes.\n" 19776 " Use 'sip show history' to view the history of a call number.\n"; 19777 return NULL; 19778 case CLI_GENERATE: 19779 return NULL; 19780 } 19781 19782 if (a->argc != e->args) 19783 return CLI_SHOWUSAGE; 19784 19785 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) { 19786 recordhistory = TRUE; 19787 ast_cli(a->fd, "SIP History Recording Enabled (use 'sip show history')\n"); 19788 } else if (!strncasecmp(a->argv[e->args - 1], "off", 3)) { 19789 recordhistory = FALSE; 19790 ast_cli(a->fd, "SIP History Recording Disabled\n"); 19791 } else { 19792 return CLI_SHOWUSAGE; 19793 } 19794 return CLI_SUCCESS; 19795 }
| static void sip_set_redirstr | ( | struct sip_pvt * | p, | |
| char * | reason | |||
| ) | [static] |
Translate referring cause.
Definition at line 15565 of file chan_sip.c.
References ast_string_field_set.
Referenced by get_rdnis().
15565 { 15566 15567 if (!strcmp(reason, "unknown")) { 15568 ast_string_field_set(p, redircause, "UNKNOWN"); 15569 } else if (!strcmp(reason, "user-busy")) { 15570 ast_string_field_set(p, redircause, "BUSY"); 15571 } else if (!strcmp(reason, "no-answer")) { 15572 ast_string_field_set(p, redircause, "NOANSWER"); 15573 } else if (!strcmp(reason, "unavailable")) { 15574 ast_string_field_set(p, redircause, "UNREACHABLE"); 15575 } else if (!strcmp(reason, "unconditional")) { 15576 ast_string_field_set(p, redircause, "UNCONDITIONAL"); 15577 } else if (!strcmp(reason, "time-of-day")) { 15578 ast_string_field_set(p, redircause, "UNKNOWN"); 15579 } else if (!strcmp(reason, "do-not-disturb")) { 15580 ast_string_field_set(p, redircause, "UNKNOWN"); 15581 } else if (!strcmp(reason, "deflection")) { 15582 ast_string_field_set(p, redircause, "UNKNOWN"); 15583 } else if (!strcmp(reason, "follow-me")) { 15584 ast_string_field_set(p, redircause, "UNKNOWN"); 15585 } else if (!strcmp(reason, "out-of-service")) { 15586 ast_string_field_set(p, redircause, "UNREACHABLE"); 15587 } else if (!strcmp(reason, "away")) { 15588 ast_string_field_set(p, redircause, "UNREACHABLE"); 15589 } else { 15590 ast_string_field_set(p, redircause, "UNKNOWN"); 15591 } 15592 }
| static int sip_set_rtp_peer | ( | struct ast_channel * | chan, | |
| struct ast_rtp_instance * | instance, | |||
| struct ast_rtp_instance * | vinstance, | |||
| struct ast_rtp_instance * | tinstance, | |||
| format_t | codecs, | |||
| int | nat_active | |||
| ) | [static] |
Definition at line 30103 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), ast_channel_lock, ast_channel_set_fd(), ast_channel_unlock, ast_clear_flag, ast_debug, ast_rtp_instance_fd(), ast_rtp_instance_get_and_cmp_remote_address(), ast_rtp_instance_set_prop(), AST_RTP_PROPERTY_RTCP, ast_set_flag, ast_sockaddr_isnull(), ast_sockaddr_stringify(), AST_STATE_UP, ast_test_flag, FALSE, sip_cfg, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, and transmit_reinvite_with_sdp().
Referenced by sip_fixup().
30104 { 30105 struct sip_pvt *p; 30106 int changed = 0; 30107 30108 /* Lock the channel and the private safely. */ 30109 ast_channel_lock(chan); 30110 p = chan->tech_pvt; 30111 if (!p) { 30112 ast_channel_unlock(chan); 30113 return -1; 30114 } 30115 sip_pvt_lock(p); 30116 if (p->owner != chan) { 30117 /* I suppose it could be argued that if this happens it is a bug. */ 30118 ast_debug(1, "The private is not owned by channel %s anymore.\n", chan->name); 30119 sip_pvt_unlock(p); 30120 ast_channel_unlock(chan); 30121 return 0; 30122 } 30123 30124 /* Disable early RTP bridge */ 30125 if ((instance || vinstance || tinstance) && 30126 !ast_bridged_channel(chan) && 30127 !sip_cfg.directrtpsetup) { 30128 sip_pvt_unlock(p); 30129 ast_channel_unlock(chan); 30130 return 0; 30131 } 30132 30133 if (p->alreadygone) { 30134 /* If we're destroyed, don't bother */ 30135 sip_pvt_unlock(p); 30136 ast_channel_unlock(chan); 30137 return 0; 30138 } 30139 30140 /* if this peer cannot handle reinvites of the media stream to devices 30141 that are known to be behind a NAT, then stop the process now 30142 */ 30143 if (nat_active && !ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA_NAT)) { 30144 sip_pvt_unlock(p); 30145 ast_channel_unlock(chan); 30146 return 0; 30147 } 30148 30149 if (instance) { 30150 changed |= ast_rtp_instance_get_and_cmp_remote_address(instance, &p->redirip); 30151 30152 if (p->rtp) { 30153 /* Prevent audio RTCP reads */ 30154 ast_channel_set_fd(chan, 1, -1); 30155 /* Silence RTCP while audio RTP is inactive */ 30156 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_RTCP, 0); 30157 } 30158 } else if (!ast_sockaddr_isnull(&p->redirip)) { 30159 memset(&p->redirip, 0, sizeof(p->redirip)); 30160 changed = 1; 30161 30162 if (p->rtp) { 30163 /* Enable RTCP since it will be inactive if we're coming back 30164 * from a reinvite */ 30165 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_RTCP, 1); 30166 /* Enable audio RTCP reads */ 30167 ast_channel_set_fd(chan, 1, ast_rtp_instance_fd(p->rtp, 1)); 30168 } 30169 } 30170 30171 if (vinstance) { 30172 changed |= ast_rtp_instance_get_and_cmp_remote_address(vinstance, &p->vredirip); 30173 30174 if (p->vrtp) { 30175 /* Prevent video RTCP reads */ 30176 ast_channel_set_fd(chan, 3, -1); 30177 /* Silence RTCP while video RTP is inactive */ 30178 ast_rtp_instance_set_prop(p->vrtp, AST_RTP_PROPERTY_RTCP, 0); 30179 } 30180 } else if (!ast_sockaddr_isnull(&p->vredirip)) { 30181 memset(&p->vredirip, 0, sizeof(p->vredirip)); 30182 changed = 1; 30183 30184 if (p->vrtp) { 30185 /* Enable RTCP since it will be inactive if we're coming back 30186 * from a reinvite */ 30187 ast_rtp_instance_set_prop(p->vrtp, AST_RTP_PROPERTY_RTCP, 1); 30188 /* Enable video RTCP reads */ 30189 ast_channel_set_fd(chan, 3, ast_rtp_instance_fd(p->vrtp, 1)); 30190 } 30191 } 30192 30193 if (tinstance) { 30194 changed |= ast_rtp_instance_get_and_cmp_remote_address(tinstance, &p->tredirip); 30195 } else if (!ast_sockaddr_isnull(&p->tredirip)) { 30196 memset(&p->tredirip, 0, sizeof(p->tredirip)); 30197 changed = 1; 30198 } 30199 if (codecs && (p->redircodecs != codecs)) { 30200 p->redircodecs = codecs; 30201 changed = 1; 30202 } 30203 30204 if (ast_test_flag(&p->flags[2], SIP_PAGE3_DIRECT_MEDIA_OUTGOING) && !p->outgoing_call) { 30205 /* We only wish to withhold sending the initial direct media reinvite on the incoming dialog. 30206 * Further direct media reinvites beyond the initial should be sent. In order to allow further 30207 * direct media reinvites to be sent, we clear this flag. 30208 */ 30209 ast_clear_flag(&p->flags[2], SIP_PAGE3_DIRECT_MEDIA_OUTGOING); 30210 sip_pvt_unlock(p); 30211 ast_channel_unlock(chan); 30212 return 0; 30213 } 30214 30215 if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 30216 if (chan->_state != AST_STATE_UP) { /* We are in early state */ 30217 if (p->do_history) 30218 append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal."); 30219 ast_debug(1, "Early remote bridge setting SIP '%s' - Sending media to %s\n", p->callid, ast_sockaddr_stringify(instance ? &p->redirip : &p->ourip)); 30220 } else if (!p->pendinginvite) { /* We are up, and have no outstanding invite */ 30221 ast_debug(3, "Sending reinvite on SIP '%s' - It's audio soon redirected to IP %s\n", p->callid, ast_sockaddr_stringify(instance ? &p->redirip : &p->ourip)); 30222 transmit_reinvite_with_sdp(p, FALSE, FALSE); 30223 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 30224 ast_debug(3, "Deferring reinvite on SIP '%s' - It's audio will be redirected to IP %s\n", p->callid, ast_sockaddr_stringify(instance ? &p->redirip : &p->ourip)); 30225 /* We have a pending Invite. Send re-invite when we're done with the invite */ 30226 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 30227 } 30228 } 30229 /* Reset lastrtprx timer */ 30230 p->lastrtprx = p->lastrtptx = time(NULL); 30231 sip_pvt_unlock(p); 30232 ast_channel_unlock(chan); 30233 return 0; 30234 }
| static int sip_set_udptl_peer | ( | struct ast_channel * | chan, | |
| struct ast_udptl * | udptl | |||
| ) | [static] |
Definition at line 29904 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_debug, ast_set_flag, ast_sockaddr_stringify(), ast_test_flag, ast_udptl_get_peer(), FALSE, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), and TRUE.
29905 { 29906 struct sip_pvt *p; 29907 29908 /* Lock the channel and the private safely. */ 29909 ast_channel_lock(chan); 29910 p = chan->tech_pvt; 29911 if (!p) { 29912 ast_channel_unlock(chan); 29913 return -1; 29914 } 29915 sip_pvt_lock(p); 29916 if (p->owner != chan) { 29917 /* I suppose it could be argued that if this happens it is a bug. */ 29918 ast_debug(1, "The private is not owned by channel %s anymore.\n", chan->name); 29919 sip_pvt_unlock(p); 29920 ast_channel_unlock(chan); 29921 return 0; 29922 } 29923 29924 if (udptl) { 29925 ast_udptl_get_peer(udptl, &p->udptlredirip); 29926 } else { 29927 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 29928 } 29929 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 29930 if (!p->pendinginvite) { 29931 ast_debug(3, "Sending reinvite on SIP '%s' - It's UDPTL soon redirected to IP %s\n", 29932 p->callid, ast_sockaddr_stringify(udptl ? &p->udptlredirip : &p->ourip)); 29933 transmit_reinvite_with_sdp(p, TRUE, FALSE); 29934 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 29935 ast_debug(3, "Deferring reinvite on SIP '%s' - It's UDPTL will be redirected to IP %s\n", 29936 p->callid, ast_sockaddr_stringify(udptl ? &p->udptlredirip : &p->ourip)); 29937 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 29938 } 29939 } 29940 /* Reset lastrtprx timer */ 29941 p->lastrtprx = p->lastrtptx = time(NULL); 29942 sip_pvt_unlock(p); 29943 ast_channel_unlock(chan); 29944 return 0; 29945 }
| static int sip_setoption | ( | struct ast_channel * | chan, | |
| int | option, | |||
| void * | data, | |||
| int | datalen | |||
| ) | [static] |
Set an option on a SIP dialog.
Definition at line 4498 of file chan_sip.c.
References ast_debug, ast_log(), AST_OPTION_DIGIT_DETECT, AST_OPTION_FORMAT_READ, AST_OPTION_FORMAT_WRITE, AST_OPTION_MAKE_COMPATIBLE, AST_OPTION_SECURE_MEDIA, AST_OPTION_SECURE_SIGNALING, ast_rtp_instance_make_compatible(), ast_rtp_instance_set_read_format(), ast_rtp_instance_set_write_format(), ast_set2_flag, ast_test_flag, disable_dsp_detect(), enable_dsp_detect(), LOG_ERROR, sip_pvt_lock, sip_pvt_unlock, and ast_channel::tech_pvt.
04499 { 04500 int res = -1; 04501 struct sip_pvt *p = chan->tech_pvt; 04502 04503 if (!p) { 04504 ast_log(LOG_ERROR, "Attempt to Ref a null pointer. sip private structure is gone!\n"); 04505 return -1; 04506 } 04507 04508 sip_pvt_lock(p); 04509 04510 switch (option) { 04511 case AST_OPTION_FORMAT_READ: 04512 if (p->rtp) { 04513 res = ast_rtp_instance_set_read_format(p->rtp, *(int *) data); 04514 } 04515 break; 04516 case AST_OPTION_FORMAT_WRITE: 04517 if (p->rtp) { 04518 res = ast_rtp_instance_set_write_format(p->rtp, *(int *) data); 04519 } 04520 break; 04521 case AST_OPTION_MAKE_COMPATIBLE: 04522 if (p->rtp) { 04523 res = ast_rtp_instance_make_compatible(chan, p->rtp, (struct ast_channel *) data); 04524 } 04525 break; 04526 case AST_OPTION_DIGIT_DETECT: 04527 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || 04528 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) { 04529 char *cp = (char *) data; 04530 04531 ast_debug(1, "%sabling digit detection on %s\n", *cp ? "En" : "Dis", chan->name); 04532 if (*cp) { 04533 enable_dsp_detect(p); 04534 } else { 04535 disable_dsp_detect(p); 04536 } 04537 res = 0; 04538 } 04539 break; 04540 case AST_OPTION_SECURE_SIGNALING: 04541 p->req_secure_signaling = *(unsigned int *) data; 04542 res = 0; 04543 break; 04544 case AST_OPTION_SECURE_MEDIA: 04545 ast_set2_flag(&p->flags[1], *(unsigned int *) data, SIP_PAGE2_USE_SRTP); 04546 res = 0; 04547 break; 04548 default: 04549 break; 04550 } 04551 04552 sip_pvt_unlock(p); 04553 04554 return res; 04555 }
| static char * sip_show_channel | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Show details of one active dialog.
Definition at line 19227 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ao2_t_ref, ast_cli_args::argc, ast_cli_args::argv, ARRAY_LEN, ast_cli(), AST_CLI_YESNO, ast_getformatname_multiple(), ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_strlen_zero(), ast_test_flag, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sipch(), dtmfmode2str(), ast_cli_args::fd, len(), ast_cli_args::line, ast_cli_args::n, NONE, ast_cli_args::pos, sip_pvt_lock, sip_pvt_unlock, stmode2str(), strefresher2str(), strefresherparam2str(), subscription_type2str(), transfermode2str(), transport2str(), TRUE, ast_cli_entry::usage, and ast_cli_args::word.
19228 { 19229 struct sip_pvt *cur; 19230 size_t len; 19231 int found = 0; 19232 struct ao2_iterator i; 19233 19234 switch (cmd) { 19235 case CLI_INIT: 19236 e->command = "sip show channel"; 19237 e->usage = 19238 "Usage: sip show channel <call-id>\n" 19239 " Provides detailed status on a given SIP dialog (identified by SIP call-id).\n"; 19240 return NULL; 19241 case CLI_GENERATE: 19242 return complete_sipch(a->line, a->word, a->pos, a->n); 19243 } 19244 19245 if (a->argc != 4) 19246 return CLI_SHOWUSAGE; 19247 len = strlen(a->argv[3]); 19248 19249 i = ao2_iterator_init(dialogs, 0); 19250 while ((cur = ao2_t_iterator_next(&i, "iterate thru dialogs"))) { 19251 sip_pvt_lock(cur); 19252 19253 if (!strncasecmp(cur->callid, a->argv[3], len)) { 19254 char formatbuf[SIPBUFSIZE/2]; 19255 ast_cli(a->fd, "\n"); 19256 if (cur->subscribed != NONE) 19257 ast_cli(a->fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); 19258 else 19259 ast_cli(a->fd, " * SIP Call\n"); 19260 ast_cli(a->fd, " Curr. trans. direction: %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming"); 19261 ast_cli(a->fd, " Call-ID: %s\n", cur->callid); 19262 ast_cli(a->fd, " Owner channel ID: %s\n", cur->owner ? cur->owner->name : "<none>"); 19263 ast_cli(a->fd, " Our Codec Capability: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->capability)); 19264 ast_cli(a->fd, " Non-Codec Capability (DTMF): %d\n", cur->noncodeccapability); 19265 ast_cli(a->fd, " Their Codec Capability: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->peercapability)); 19266 ast_cli(a->fd, " Joint Codec Capability: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->jointcapability)); 19267 ast_cli(a->fd, " Format: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) ); 19268 ast_cli(a->fd, " T.38 support %s\n", AST_CLI_YESNO(cur->udptl != NULL)); 19269 ast_cli(a->fd, " Video support %s\n", AST_CLI_YESNO(cur->vrtp != NULL)); 19270 ast_cli(a->fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate); 19271 ast_cli(a->fd, " Theoretical Address: %s\n", ast_sockaddr_stringify(&cur->sa)); 19272 ast_cli(a->fd, " Received Address: %s\n", ast_sockaddr_stringify(&cur->recv)); 19273 ast_cli(a->fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer)); 19274 ast_cli(a->fd, " Force rport: %s\n", AST_CLI_YESNO(ast_test_flag(&cur->flags[0], SIP_NAT_FORCE_RPORT))); 19275 if (ast_sockaddr_isnull(&cur->redirip)) { 19276 ast_cli(a->fd, 19277 " Audio IP: %s (local)\n", 19278 ast_sockaddr_stringify_addr(&cur->ourip)); 19279 } else { 19280 ast_cli(a->fd, 19281 " Audio IP: %s (Outside bridge)\n", 19282 ast_sockaddr_stringify_addr(&cur->redirip)); 19283 } 19284 ast_cli(a->fd, " Our Tag: %s\n", cur->tag); 19285 ast_cli(a->fd, " Their Tag: %s\n", cur->theirtag); 19286 ast_cli(a->fd, " SIP User agent: %s\n", cur->useragent); 19287 if (!ast_strlen_zero(cur->username)) 19288 ast_cli(a->fd, " Username: %s\n", cur->username); 19289 if (!ast_strlen_zero(cur->peername)) 19290 ast_cli(a->fd, " Peername: %s\n", cur->peername); 19291 if (!ast_strlen_zero(cur->uri)) 19292 ast_cli(a->fd, " Original uri: %s\n", cur->uri); 19293 if (!ast_strlen_zero(cur->cid_num)) 19294 ast_cli(a->fd, " Caller-ID: %s\n", cur->cid_num); 19295 ast_cli(a->fd, " Need Destroy: %s\n", AST_CLI_YESNO(cur->needdestroy)); 19296 ast_cli(a->fd, " Last Message: %s\n", cur->lastmsg); 19297 ast_cli(a->fd, " Promiscuous Redir: %s\n", AST_CLI_YESNO(ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR))); 19298 ast_cli(a->fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); 19299 ast_cli(a->fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF))); 19300 ast_cli(a->fd, " SIP Options: "); 19301 if (cur->sipoptions) { 19302 int x; 19303 for (x = 0 ; x < ARRAY_LEN(sip_options); x++) { 19304 if (cur->sipoptions & sip_options[x].id) 19305 ast_cli(a->fd, "%s ", sip_options[x].text); 19306 } 19307 ast_cli(a->fd, "\n"); 19308 } else 19309 ast_cli(a->fd, "(none)\n"); 19310 19311 if (!cur->stimer) 19312 ast_cli(a->fd, " Session-Timer: Uninitiallized\n"); 19313 else { 19314 ast_cli(a->fd, " Session-Timer: %s\n", cur->stimer->st_active ? "Active" : "Inactive"); 19315 if (cur->stimer->st_active == TRUE) { 19316 ast_cli(a->fd, " S-Timer Interval: %d\n", cur->stimer->st_interval); 19317 ast_cli(a->fd, " S-Timer Refresher: %s\n", strefresher2str(cur->stimer->st_ref)); 19318 ast_cli(a->fd, " S-Timer Sched Id: %d\n", cur->stimer->st_schedid); 19319 ast_cli(a->fd, " S-Timer Peer Sts: %s\n", cur->stimer->st_active_peer_ua ? "Active" : "Inactive"); 19320 ast_cli(a->fd, " S-Timer Cached Min-SE: %d\n", cur->stimer->st_cached_min_se); 19321 ast_cli(a->fd, " S-Timer Cached SE: %d\n", cur->stimer->st_cached_max_se); 19322 ast_cli(a->fd, " S-Timer Cached Ref: %s\n", strefresherparam2str(cur->stimer->st_cached_ref)); 19323 ast_cli(a->fd, " S-Timer Cached Mode: %s\n", stmode2str(cur->stimer->st_cached_mode)); 19324 } 19325 } 19326 19327 /* add transport and media types */ 19328 ast_cli(a->fd, " Transport: %s\n", transport2str(cur->socket.type)); 19329 ast_cli(a->fd, " Media: %s\n", cur->srtp ? "SRTP" : cur->rtp ? "RTP" : "None"); 19330 19331 ast_cli(a->fd, "\n\n"); 19332 19333 found++; 19334 } 19335 19336 sip_pvt_unlock(cur); 19337 19338 ao2_t_ref(cur, -1, "toss dialog ptr set by iterator_next"); 19339 } 19340 ao2_iterator_destroy(&i); 19341 19342 if (!found) 19343 ast_cli(a->fd, "No such SIP Call ID starting with '%s'\n", a->argv[3]); 19344 19345 return CLI_SUCCESS; 19346 }
| static char* sip_show_channels | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
CLI for show channels or subscriptions. This is a new-style CLI handler so a single function contains the prototype for the function, the 'generator' to produce multiple entries in case it is required, and the actual handler for the command.
Definition at line 19034 of file chan_sip.c.
References ao2_t_callback, ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ESS, ast_cli_args::fd, FORMAT2, FORMAT3, OBJ_NODATA, show_channels_cb(), and ast_cli_entry::usage.
19035 { 19036 struct __show_chan_arg arg = { .fd = a->fd, .numchans = 0 }; 19037 19038 19039 if (cmd == CLI_INIT) { 19040 e->command = "sip show {channels|subscriptions}"; 19041 e->usage = 19042 "Usage: sip show channels\n" 19043 " Lists all currently active SIP calls (dialogs).\n" 19044 "Usage: sip show subscriptions\n" 19045 " Lists active SIP subscriptions.\n"; 19046 return NULL; 19047 } else if (cmd == CLI_GENERATE) 19048 return NULL; 19049 19050 if (a->argc != e->args) 19051 return CLI_SHOWUSAGE; 19052 arg.subscriptions = !strcasecmp(a->argv[e->args - 1], "subscriptions"); 19053 if (!arg.subscriptions) 19054 ast_cli(arg.fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Format", "Hold", "Last Message", "Expiry", "Peer"); 19055 else 19056 ast_cli(arg.fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox", "Expiry"); 19057 19058 /* iterate on the container and invoke the callback on each item */ 19059 ao2_t_callback(dialogs, OBJ_NODATA, show_channels_cb, &arg, "callback to show channels"); 19060 19061 /* print summary information */ 19062 ast_cli(arg.fd, "%d active SIP %s%s\n", arg.numchans, 19063 (arg.subscriptions ? "subscription" : "dialog"), 19064 ESS(arg.numchans)); /* ESS(n) returns an "s" if n>1 */ 19065 return CLI_SUCCESS; 19066 #undef FORMAT 19067 #undef FORMAT2 19068 #undef FORMAT3 19069 }
| static char * sip_show_channelstats | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
SIP show channelstats CLI (main function).
Definition at line 18655 of file chan_sip.c.
References ao2_t_callback, ast_cli_args::argc, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, FORMAT2, OBJ_NODATA, show_chanstats_cb(), and ast_cli_entry::usage.
18656 { 18657 struct __show_chan_arg arg = { .fd = a->fd, .numchans = 0 }; 18658 18659 switch (cmd) { 18660 case CLI_INIT: 18661 e->command = "sip show channelstats"; 18662 e->usage = 18663 "Usage: sip show channelstats\n" 18664 " Lists all currently active SIP channel's RTCP statistics.\n" 18665 " Note that calls in the much optimized RTP P2P bridge mode will not show any packets here."; 18666 return NULL; 18667 case CLI_GENERATE: 18668 return NULL; 18669 } 18670 18671 if (a->argc != 3) 18672 return CLI_SHOWUSAGE; 18673 18674 ast_cli(a->fd, FORMAT2, "Peer", "Call ID", "Duration", "Recv: Pack", "Lost", "Jitter", "Send: Pack", "Lost", "Jitter"); 18675 /* iterate on the container and invoke the callback on each item */ 18676 ao2_t_callback(dialogs, OBJ_NODATA, show_chanstats_cb, &arg, "callback to sip show chanstats"); 18677 ast_cli(a->fd, "%d active SIP channel%s\n", arg.numchans, (arg.numchans != 1) ? "s" : ""); 18678 return CLI_SUCCESS; 18679 }
| static char * sip_show_domains | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
CLI command to list local domains.
Definition at line 17903 of file chan_sip.c.
References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, domain_mode_to_text(), ast_cli_args::fd, FORMAT, S_OR, and ast_cli_entry::usage.
17904 { 17905 struct domain *d; 17906 #define FORMAT "%-40.40s %-20.20s %-16.16s\n" 17907 17908 switch (cmd) { 17909 case CLI_INIT: 17910 e->command = "sip show domains"; 17911 e->usage = 17912 "Usage: sip show domains\n" 17913 " Lists all configured SIP local domains.\n" 17914 " Asterisk only responds to SIP messages to local domains.\n"; 17915 return NULL; 17916 case CLI_GENERATE: 17917 return NULL; 17918 } 17919 17920 if (AST_LIST_EMPTY(&domain_list)) { 17921 ast_cli(a->fd, "SIP Domain support not enabled.\n\n"); 17922 return CLI_SUCCESS; 17923 } else { 17924 ast_cli(a->fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); 17925 AST_LIST_LOCK(&domain_list); 17926 AST_LIST_TRAVERSE(&domain_list, d, list) 17927 ast_cli(a->fd, FORMAT, d->domain, S_OR(d->context, "(default)"), 17928 domain_mode_to_text(d->mode)); 17929 AST_LIST_UNLOCK(&domain_list); 17930 ast_cli(a->fd, "\n"); 17931 return CLI_SUCCESS; 17932 } 17933 }
| static char * sip_show_history | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Show history details of one dialog.
Definition at line 19349 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ao2_t_ref, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_LIST_TRAVERSE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sip_show_history(), ast_cli_args::fd, len(), ast_cli_args::line, ast_cli_args::n, NONE, ast_cli_args::pos, sip_pvt_lock, sip_pvt_unlock, ast_cli_entry::usage, and ast_cli_args::word.
19350 { 19351 struct sip_pvt *cur; 19352 size_t len; 19353 int found = 0; 19354 struct ao2_iterator i; 19355 19356 switch (cmd) { 19357 case CLI_INIT: 19358 e->command = "sip show history"; 19359 e->usage = 19360 "Usage: sip show history <call-id>\n" 19361 " Provides detailed dialog history on a given SIP call (specified by call-id).\n"; 19362 return NULL; 19363 case CLI_GENERATE: 19364 return complete_sip_show_history(a->line, a->word, a->pos, a->n); 19365 } 19366 19367 if (a->argc != 4) 19368 return CLI_SHOWUSAGE; 19369 19370 if (!recordhistory) 19371 ast_cli(a->fd, "\n***Note: History recording is currently DISABLED. Use 'sip set history on' to ENABLE.\n"); 19372 19373 len = strlen(a->argv[3]); 19374 19375 i = ao2_iterator_init(dialogs, 0); 19376 while ((cur = ao2_t_iterator_next(&i, "iterate thru dialogs"))) { 19377 sip_pvt_lock(cur); 19378 if (!strncasecmp(cur->callid, a->argv[3], len)) { 19379 struct sip_history *hist; 19380 int x = 0; 19381 19382 ast_cli(a->fd, "\n"); 19383 if (cur->subscribed != NONE) 19384 ast_cli(a->fd, " * Subscription\n"); 19385 else 19386 ast_cli(a->fd, " * SIP Call\n"); 19387 if (cur->history) 19388 AST_LIST_TRAVERSE(cur->history, hist, list) 19389 ast_cli(a->fd, "%d. %s\n", ++x, hist->event); 19390 if (x == 0) 19391 ast_cli(a->fd, "Call '%s' has no history\n", cur->callid); 19392 found++; 19393 } 19394 sip_pvt_unlock(cur); 19395 ao2_t_ref(cur, -1, "toss dialog ptr from iterator_next"); 19396 } 19397 ao2_iterator_destroy(&i); 19398 19399 if (!found) 19400 ast_cli(a->fd, "No such SIP Call ID starting with '%s'\n", a->argv[3]); 19401 19402 return CLI_SUCCESS; 19403 }
| static char * sip_show_inuse | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
CLI Command to show calls within limits set by call_limit.
Definition at line 16937 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_iterator_next, ao2_unlock, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_copy_string(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, FALSE, ast_cli_args::fd, FORMAT, FORMAT2, TRUE, unref_peer(), and ast_cli_entry::usage.
16938 { 16939 #define FORMAT "%-25.25s %-15.15s %-15.15s \n" 16940 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" 16941 char ilimits[40]; 16942 char iused[40]; 16943 int showall = FALSE; 16944 struct ao2_iterator i; 16945 struct sip_peer *peer; 16946 16947 switch (cmd) { 16948 case CLI_INIT: 16949 e->command = "sip show inuse"; 16950 e->usage = 16951 "Usage: sip show inuse [all]\n" 16952 " List all SIP devices usage counters and limits.\n" 16953 " Add option \"all\" to show all devices, not only those with a limit.\n"; 16954 return NULL; 16955 case CLI_GENERATE: 16956 return NULL; 16957 } 16958 16959 if (a->argc < 3) 16960 return CLI_SHOWUSAGE; 16961 16962 if (a->argc == 4 && !strcmp(a->argv[3], "all")) 16963 showall = TRUE; 16964 16965 ast_cli(a->fd, FORMAT, "* Peer name", "In use", "Limit"); 16966 16967 i = ao2_iterator_init(peers, 0); 16968 while ((peer = ao2_t_iterator_next(&i, "iterate thru peer table"))) { 16969 ao2_lock(peer); 16970 if (peer->call_limit) 16971 snprintf(ilimits, sizeof(ilimits), "%d", peer->call_limit); 16972 else 16973 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 16974 snprintf(iused, sizeof(iused), "%d/%d/%d", peer->inUse, peer->inRinging, peer->onHold); 16975 if (showall || peer->call_limit) 16976 ast_cli(a->fd, FORMAT2, peer->name, iused, ilimits); 16977 ao2_unlock(peer); 16978 unref_peer(peer, "toss iterator pointer"); 16979 } 16980 ao2_iterator_destroy(&i); 16981 16982 return CLI_SUCCESS; 16983 #undef FORMAT 16984 #undef FORMAT2 16985 }
| static char * sip_show_mwi | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 18913 of file chan_sip.c.
References ast_cli(), AST_CLI_YESNO, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, FORMAT, submwil, and ast_cli_entry::usage.
18914 { 18915 #define FORMAT "%-30.30s %-12.12s %-10.10s %-10.10s\n" 18916 char host[80]; 18917 18918 switch (cmd) { 18919 case CLI_INIT: 18920 e->command = "sip show mwi"; 18921 e->usage = 18922 "Usage: sip show mwi\n" 18923 " Provides a list of MWI subscriptions and status.\n"; 18924 return NULL; 18925 case CLI_GENERATE: 18926 return NULL; 18927 } 18928 18929 ast_cli(a->fd, FORMAT, "Host", "Username", "Mailbox", "Subscribed"); 18930 18931 ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do { 18932 ASTOBJ_RDLOCK(iterator); 18933 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); 18934 ast_cli(a->fd, FORMAT, host, iterator->username, iterator->mailbox, AST_CLI_YESNO(iterator->subscribed)); 18935 ASTOBJ_UNLOCK(iterator); 18936 } while(0)); 18937 18938 return CLI_SUCCESS; 18939 #undef FORMAT 18940 }
| static char * sip_show_objects | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
List all allocated SIP Objects (realtime or static).
Definition at line 17524 of file chan_sip.c.
References ao2_t_callback, ast_cli_args::argc, ast_cli(), ASTOBJ_CONTAINER_DUMP, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, dialog_dump_func(), ast_cli_args::fd, OBJ_NODATA, peer_dump_func(), regl, and ast_cli_entry::usage.
17525 { 17526 char tmp[256]; 17527 17528 switch (cmd) { 17529 case CLI_INIT: 17530 e->command = "sip show objects"; 17531 e->usage = 17532 "Usage: sip show objects\n" 17533 " Lists status of known SIP objects\n"; 17534 return NULL; 17535 case CLI_GENERATE: 17536 return NULL; 17537 } 17538 17539 if (a->argc != 3) 17540 return CLI_SHOWUSAGE; 17541 ast_cli(a->fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs); 17542 ao2_t_callback(peers, OBJ_NODATA, peer_dump_func, a, "initiate ao2_callback to dump peers"); 17543 ast_cli(a->fd, "-= Peer objects by IP =-\n\n"); 17544 ao2_t_callback(peers_by_ip, OBJ_NODATA, peer_dump_func, a, "initiate ao2_callback to dump peers_by_ip"); 17545 ast_cli(a->fd, "-= Registry objects: %d =-\n\n", regobjs); 17546 ASTOBJ_CONTAINER_DUMP(a->fd, tmp, sizeof(tmp), ®l); 17547 ast_cli(a->fd, "-= Dialog objects:\n\n"); 17548 ao2_t_callback(dialogs, OBJ_NODATA, dialog_dump_func, a, "initiate ao2_callback to dump dialogs"); 17549 return CLI_SUCCESS; 17550 }
| static char * sip_show_peer | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Show one peer in detail.
Definition at line 17958 of file chan_sip.c.
References _sip_show_peer(), ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, complete_sip_show_peer(), ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.
17959 { 17960 switch (cmd) { 17961 case CLI_INIT: 17962 e->command = "sip show peer"; 17963 e->usage = 17964 "Usage: sip show peer <name> [load]\n" 17965 " Shows all details on one SIP peer and the current status.\n" 17966 " Option \"load\" forces lookup of peer in realtime storage.\n"; 17967 return NULL; 17968 case CLI_GENERATE: 17969 return complete_sip_show_peer(a->line, a->word, a->pos, a->n); 17970 } 17971 return _sip_show_peer(0, a->fd, NULL, NULL, a->argc, (const char **) a->argv); 17972 }
| static char * sip_show_peers | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
CLI Show Peers command.
Definition at line 17260 of file chan_sip.c.
References _sip_show_peers(), ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.
17261 { 17262 switch (cmd) { 17263 case CLI_INIT: 17264 e->command = "sip show peers"; 17265 e->usage = 17266 "Usage: sip show peers [like <pattern>]\n" 17267 " Lists all known SIP peers.\n" 17268 " Optional regular expression pattern is used to filter the peer list.\n"; 17269 return NULL; 17270 case CLI_GENERATE: 17271 return NULL; 17272 } 17273 17274 return _sip_show_peers(a->fd, NULL, NULL, NULL, a->argc, (const char **) a->argv); 17275 }
| static char * sip_show_registry | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Show SIP Registry (registrations with other SIP proxies.
Definition at line 18493 of file chan_sip.c.
References ast_cli_args::argc, ast_cli(), ast_localtime(), ast_strftime(), ast_strlen_zero(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, FORMAT, FORMAT2, regl, regstate2str(), and ast_cli_entry::usage.
18494 { 18495 #define FORMAT2 "%-39.39s %-6.6s %-12.12s %8.8s %-20.20s %-25.25s\n" 18496 #define FORMAT "%-39.39s %-6.6s %-12.12s %8d %-20.20s %-25.25s\n" 18497 char host[80]; 18498 char user[80]; 18499 char tmpdat[256]; 18500 struct ast_tm tm; 18501 int counter = 0; 18502 18503 switch (cmd) { 18504 case CLI_INIT: 18505 e->command = "sip show registry"; 18506 e->usage = 18507 "Usage: sip show registry\n" 18508 " Lists all registration requests and status.\n"; 18509 return NULL; 18510 case CLI_GENERATE: 18511 return NULL; 18512 } 18513 18514 if (a->argc != 3) 18515 return CLI_SHOWUSAGE; 18516 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Refresh", "State", "Reg.Time"); 18517 18518 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 18519 ASTOBJ_RDLOCK(iterator); 18520 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); 18521 snprintf(user, sizeof(user), "%s", iterator->username); 18522 if (!ast_strlen_zero(iterator->regdomain)) { 18523 snprintf(tmpdat, sizeof(tmpdat), "%s", user); 18524 snprintf(user, sizeof(user), "%s@%s", tmpdat, iterator->regdomain);} 18525 if (iterator->regdomainport) { 18526 snprintf(tmpdat, sizeof(tmpdat), "%s", user); 18527 snprintf(user, sizeof(user), "%s:%d", tmpdat, iterator->regdomainport);} 18528 if (iterator->regtime.tv_sec) { 18529 ast_localtime(&iterator->regtime, &tm, NULL); 18530 ast_strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm); 18531 } else 18532 tmpdat[0] = '\0'; 18533 ast_cli(a->fd, FORMAT, host, (iterator->dnsmgr) ? "Y" : "N", user, iterator->refresh, regstate2str(iterator->regstate), tmpdat); 18534 ASTOBJ_UNLOCK(iterator); 18535 counter++; 18536 } while(0)); 18537 ast_cli(a->fd, "%d SIP registrations.\n", counter); 18538 return CLI_SUCCESS; 18539 #undef FORMAT 18540 #undef FORMAT2 18541 }
| static char * sip_show_sched | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 18450 of file chan_sip.c.
References __sip_autodestruct(), ast_cli(), ast_sched_report(), ast_str_alloca, ast_str_buffer(), auto_congest(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, expire_register(), ast_cli_args::fd, retrans_pkt(), sip_poke_noanswer(), sip_poke_peer_s(), sip_reg_timeout(), sip_reinvite_retry(), sip_reregister(), and ast_cli_entry::usage.
18451 { 18452 struct ast_str *cbuf; 18453 struct ast_cb_names cbnames = {9, { "retrans_pkt", 18454 "__sip_autodestruct", 18455 "expire_register", 18456 "auto_congest", 18457 "sip_reg_timeout", 18458 "sip_poke_peer_s", 18459 "sip_poke_noanswer", 18460 "sip_reregister", 18461 "sip_reinvite_retry"}, 18462 { retrans_pkt, 18463 __sip_autodestruct, 18464 expire_register, 18465 auto_congest, 18466 sip_reg_timeout, 18467 sip_poke_peer_s, 18468 sip_poke_noanswer, 18469 sip_reregister, 18470 sip_reinvite_retry}}; 18471 18472 switch (cmd) { 18473 case CLI_INIT: 18474 e->command = "sip show sched"; 18475 e->usage = 18476 "Usage: sip show sched\n" 18477 " Shows stats on what's in the sched queue at the moment\n"; 18478 return NULL; 18479 case CLI_GENERATE: 18480 return NULL; 18481 } 18482 18483 cbuf = ast_str_alloca(2048); 18484 18485 ast_cli(a->fd, "\n"); 18486 ast_sched_report(sched, &cbuf, &cbnames); 18487 ast_cli(a->fd, "%s", ast_str_buffer(cbuf)); 18488 18489 return CLI_SUCCESS; 18490 }
| static char * sip_show_settings | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
List global settings for the SIP channel.
Definition at line 18684 of file chan_sip.c.
References ast_ha::addr, allowoverlap2str(), ao2_t_ref, ast_cli_args::argc, ast_check_realtime(), ast_cli(), AST_CLI_ONOFF, AST_CLI_YESNO, ast_getformatname_multiple(), AST_JB_ENABLED, AST_JB_FORCED, AST_JB_LOG, AST_LIST_EMPTY, AST_LIST_TRAVERSE, ast_mutex_lock, ast_mutex_unlock, ast_sockaddr_is_any(), ast_sockaddr_is_ipv6(), ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_tos2str(), bindaddr, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, default_prefs, dtmfmode2str(), ast_tls_config::enabled, externaddr, FALSE, faxec2str(), ast_cli_args::fd, get_transport(), get_transport_list(), global_jbconf, ast_jb_conf::impl, ast_tcptls_session_args::local_address, ast_jb_conf::max_size, ast_ha::netmask, ast_ha::next, prefix, print_codec_to_cli(), ast_jb_conf::resync_threshold, S_OR, sip_cfg, stmode2str(), strefresherparam2str(), ast_jb_conf::target_extra, transfermode2str(), and ast_cli_entry::usage.
18685 { 18686 int realtimepeers; 18687 int realtimeregs; 18688 char codec_buf[SIPBUFSIZE]; 18689 const char *msg; /* temporary msg pointer */ 18690 struct sip_auth_container *credentials; 18691 18692 switch (cmd) { 18693 case CLI_INIT: 18694 e->command = "sip show settings"; 18695 e->usage = 18696 "Usage: sip show settings\n" 18697 " Provides detailed list of the configuration of the SIP channel.\n"; 18698 return NULL; 18699 case CLI_GENERATE: 18700 return NULL; 18701 } 18702 18703 if (a->argc != 3) 18704 return CLI_SHOWUSAGE; 18705 18706 realtimepeers = ast_check_realtime("sippeers"); 18707 realtimeregs = ast_check_realtime("sipregs"); 18708 18709 ast_mutex_lock(&authl_lock); 18710 credentials = authl; 18711 if (credentials) { 18712 ao2_t_ref(credentials, +1, "Ref global auth for show"); 18713 } 18714 ast_mutex_unlock(&authl_lock); 18715 18716 ast_cli(a->fd, "\n\nGlobal Settings:\n"); 18717 ast_cli(a->fd, "----------------\n"); 18718 ast_cli(a->fd, " UDP Bindaddress: %s\n", ast_sockaddr_stringify(&bindaddr)); 18719 if (ast_sockaddr_is_ipv6(&bindaddr) && ast_sockaddr_is_any(&bindaddr)) { 18720 ast_cli(a->fd, " ** Additional Info:\n"); 18721 ast_cli(a->fd, " [::] may include IPv4 in addition to IPv6, if such a feature is enabled in the OS.\n"); 18722 } 18723 ast_cli(a->fd, " TCP SIP Bindaddress: %s\n", 18724 sip_cfg.tcp_enabled != FALSE ? 18725 ast_sockaddr_stringify(&sip_tcp_desc.local_address) : 18726 "Disabled"); 18727 ast_cli(a->fd, " TLS SIP Bindaddress: %s\n", 18728 default_tls_cfg.enabled != FALSE ? 18729 ast_sockaddr_stringify(&sip_tls_desc.local_address) : 18730 "Disabled"); 18731 ast_cli(a->fd, " Videosupport: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT))); 18732 ast_cli(a->fd, " Textsupport: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_TEXTSUPPORT))); 18733 ast_cli(a->fd, " Ignore SDP sess. ver.: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_IGNORESDPVERSION))); 18734 ast_cli(a->fd, " AutoCreate Peer: %s\n", AST_CLI_YESNO(sip_cfg.autocreatepeer)); 18735 ast_cli(a->fd, " Match Auth Username: %s\n", AST_CLI_YESNO(global_match_auth_username)); 18736 ast_cli(a->fd, " Allow unknown access: %s\n", AST_CLI_YESNO(sip_cfg.allowguest)); 18737 ast_cli(a->fd, " Allow subscriptions: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))); 18738 ast_cli(a->fd, " Allow overlap dialing: %s\n", allowoverlap2str(ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP))); 18739 ast_cli(a->fd, " Allow promisc. redir: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_PROMISCREDIR))); 18740 ast_cli(a->fd, " Enable call counters: %s\n", AST_CLI_YESNO(global_callcounter)); 18741 ast_cli(a->fd, " SIP domain support: %s\n", AST_CLI_YESNO(!AST_LIST_EMPTY(&domain_list))); 18742 ast_cli(a->fd, " Realm. auth: %s\n", AST_CLI_YESNO(credentials != NULL)); 18743 if (credentials) { 18744 struct sip_auth *auth; 18745 18746 AST_LIST_TRAVERSE(&credentials->list, auth, node) { 18747 ast_cli(a->fd, " Realm. auth entry: Realm %-15.15s User %-10.20s %s\n", 18748 auth->realm, 18749 auth->username, 18750 !ast_strlen_zero(auth->secret) 18751 ? "<Secret set>" 18752 : (!ast_strlen_zero(auth->md5secret) 18753 ? "<MD5secret set>" : "<Not set>")); 18754 } 18755 ao2_t_ref(credentials, -1, "Unref global auth for show"); 18756 } 18757 ast_cli(a->fd, " Our auth realm %s\n", sip_cfg.realm); 18758 ast_cli(a->fd, " Use domains as realms: %s\n", AST_CLI_YESNO(sip_cfg.domainsasrealm)); 18759 ast_cli(a->fd, " Call to non-local dom.: %s\n", AST_CLI_YESNO(sip_cfg.allow_external_domains)); 18760 ast_cli(a->fd, " URI user is phone no: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_USEREQPHONE))); 18761 ast_cli(a->fd, " Always auth rejects: %s\n", AST_CLI_YESNO(sip_cfg.alwaysauthreject)); 18762 ast_cli(a->fd, " Direct RTP setup: %s\n", AST_CLI_YESNO(sip_cfg.directrtpsetup)); 18763 ast_cli(a->fd, " User Agent: %s\n", global_useragent); 18764 ast_cli(a->fd, " SDP Session Name: %s\n", ast_strlen_zero(global_sdpsession) ? "-" : global_sdpsession); 18765 ast_cli(a->fd, " SDP Owner Name: %s\n", ast_strlen_zero(global_sdpowner) ? "-" : global_sdpowner); 18766 ast_cli(a->fd, " Reg. context: %s\n", S_OR(sip_cfg.regcontext, "(not set)")); 18767 ast_cli(a->fd, " Regexten on Qualify: %s\n", AST_CLI_YESNO(sip_cfg.regextenonqualify)); 18768 ast_cli(a->fd, " Legacy userfield parse: %s\n", AST_CLI_YESNO(sip_cfg.legacy_useroption_parsing)); 18769 ast_cli(a->fd, " Caller ID: %s\n", default_callerid); 18770 if ((default_fromdomainport) && (default_fromdomainport != STANDARD_SIP_PORT)) { 18771 ast_cli(a->fd, " From: Domain: %s:%d\n", default_fromdomain, default_fromdomainport); 18772 } else { 18773 ast_cli(a->fd, " From: Domain: %s\n", default_fromdomain); 18774 } 18775 ast_cli(a->fd, " Record SIP history: %s\n", AST_CLI_ONOFF(recordhistory)); 18776 ast_cli(a->fd, " Call Events: %s\n", AST_CLI_ONOFF(sip_cfg.callevents)); 18777 ast_cli(a->fd, " Auth. Failure Events: %s\n", AST_CLI_ONOFF(global_authfailureevents)); 18778 18779 ast_cli(a->fd, " T.38 support: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT))); 18780 ast_cli(a->fd, " T.38 EC mode: %s\n", faxec2str(ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT))); 18781 ast_cli(a->fd, " T.38 MaxDtgrm: %u\n", global_t38_maxdatagram); 18782 if (!realtimepeers && !realtimeregs) 18783 ast_cli(a->fd, " SIP realtime: Disabled\n" ); 18784 else 18785 ast_cli(a->fd, " SIP realtime: Enabled\n" ); 18786 ast_cli(a->fd, " Qualify Freq : %d ms\n", global_qualifyfreq); 18787 ast_cli(a->fd, " Q.850 Reason header: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_Q850_REASON))); 18788 ast_cli(a->fd, " Store SIP_CAUSE: %s\n", AST_CLI_YESNO(global_store_sip_cause)); 18789 ast_cli(a->fd, "\nNetwork QoS Settings:\n"); 18790 ast_cli(a->fd, "---------------------------\n"); 18791 ast_cli(a->fd, " IP ToS SIP: %s\n", ast_tos2str(global_tos_sip)); 18792 ast_cli(a->fd, " IP ToS RTP audio: %s\n", ast_tos2str(global_tos_audio)); 18793 ast_cli(a->fd, " IP ToS RTP video: %s\n", ast_tos2str(global_tos_video)); 18794 ast_cli(a->fd, " IP ToS RTP text: %s\n", ast_tos2str(global_tos_text)); 18795 ast_cli(a->fd, " 802.1p CoS SIP: %u\n", global_cos_sip); 18796 ast_cli(a->fd, " 802.1p CoS RTP audio: %u\n", global_cos_audio); 18797 ast_cli(a->fd, " 802.1p CoS RTP video: %u\n", global_cos_video); 18798 ast_cli(a->fd, " 802.1p CoS RTP text: %u\n", global_cos_text); 18799 ast_cli(a->fd, " Jitterbuffer enabled: %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_ENABLED))); 18800 if (ast_test_flag(&global_jbconf, AST_JB_ENABLED)) { 18801 ast_cli(a->fd, " Jitterbuffer forced: %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_FORCED))); 18802 ast_cli(a->fd, " Jitterbuffer max size: %ld\n", global_jbconf.max_size); 18803 ast_cli(a->fd, " Jitterbuffer resync: %ld\n", global_jbconf.resync_threshold); 18804 ast_cli(a->fd, " Jitterbuffer impl: %s\n", global_jbconf.impl); 18805 if (!strcasecmp(global_jbconf.impl, "adaptive")) { 18806 ast_cli(a->fd, " Jitterbuffer tgt extra: %ld\n", global_jbconf.target_extra); 18807 } 18808 ast_cli(a->fd, " Jitterbuffer log: %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_LOG))); 18809 } 18810 18811 ast_cli(a->fd, "\nNetwork Settings:\n"); 18812 ast_cli(a->fd, "---------------------------\n"); 18813 /* determine if/how SIP address can be remapped */ 18814 if (localaddr == NULL) 18815 msg = "Disabled, no localnet list"; 18816 else if (ast_sockaddr_isnull(&externaddr)) 18817 msg = "Disabled"; 18818 else if (!ast_strlen_zero(externhost)) 18819 msg = "Enabled using externhost"; 18820 else 18821 msg = "Enabled using externaddr"; 18822 ast_cli(a->fd, " SIP address remapping: %s\n", msg); 18823 ast_cli(a->fd, " Externhost: %s\n", S_OR(externhost, "<none>")); 18824 ast_cli(a->fd, " Externaddr: %s\n", ast_sockaddr_stringify(&externaddr)); 18825 ast_cli(a->fd, " Externrefresh: %d\n", externrefresh); 18826 { 18827 struct ast_ha *d; 18828 const char *prefix = "Localnet:"; 18829 18830 for (d = localaddr; d ; prefix = "", d = d->next) { 18831 const char *addr = ast_strdupa(ast_sockaddr_stringify_addr(&d->addr)); 18832 const char *mask = ast_strdupa(ast_sockaddr_stringify_addr(&d->netmask)); 18833 ast_cli(a->fd, " %-24s%s/%s\n", prefix, addr, mask); 18834 } 18835 } 18836 ast_cli(a->fd, "\nGlobal Signalling Settings:\n"); 18837 ast_cli(a->fd, "---------------------------\n"); 18838 ast_cli(a->fd, " Codecs: "); 18839 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, sip_cfg.capability); 18840 ast_cli(a->fd, "%s\n", codec_buf); 18841 ast_cli(a->fd, " Codec Order: "); 18842 print_codec_to_cli(a->fd, &default_prefs); 18843 ast_cli(a->fd, "\n"); 18844 ast_cli(a->fd, " Relax DTMF: %s\n", AST_CLI_YESNO(global_relaxdtmf)); 18845 ast_cli(a->fd, " RFC2833 Compensation: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE))); 18846 ast_cli(a->fd, " Symmetric RTP: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_SYMMETRICRTP))); 18847 ast_cli(a->fd, " Compact SIP headers: %s\n", AST_CLI_YESNO(sip_cfg.compactheaders)); 18848 ast_cli(a->fd, " RTP Keepalive: %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" ); 18849 ast_cli(a->fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" ); 18850 ast_cli(a->fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)"); 18851 ast_cli(a->fd, " MWI NOTIFY mime type: %s\n", default_notifymime); 18852 ast_cli(a->fd, " DNS SRV lookup: %s\n", AST_CLI_YESNO(sip_cfg.srvlookup)); 18853 ast_cli(a->fd, " Pedantic SIP support: %s\n", AST_CLI_YESNO(sip_cfg.pedanticsipchecking)); 18854 ast_cli(a->fd, " Reg. min duration %d secs\n", min_expiry); 18855 ast_cli(a->fd, " Reg. max duration: %d secs\n", max_expiry); 18856 ast_cli(a->fd, " Reg. default duration: %d secs\n", default_expiry); 18857 ast_cli(a->fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout); 18858 ast_cli(a->fd, " Outbound reg. attempts: %d\n", global_regattempts_max); 18859 ast_cli(a->fd, " Outbound reg. retry 403:%d\n", global_reg_retry_403); 18860 ast_cli(a->fd, " Notify ringing state: %s\n", AST_CLI_YESNO(sip_cfg.notifyringing)); 18861 if (sip_cfg.notifyringing) { 18862 ast_cli(a->fd, " Include CID: %s%s\n", 18863 AST_CLI_YESNO(sip_cfg.notifycid), 18864 sip_cfg.notifycid == IGNORE_CONTEXT ? " (Ignoring context)" : ""); 18865 } 18866 ast_cli(a->fd, " Notify hold state: %s\n", AST_CLI_YESNO(sip_cfg.notifyhold)); 18867 ast_cli(a->fd, " SIP Transfer mode: %s\n", transfermode2str(sip_cfg.allowtransfer)); 18868 ast_cli(a->fd, " Max Call Bitrate: %d kbps\n", default_maxcallbitrate); 18869 ast_cli(a->fd, " Auto-Framing: %s\n", AST_CLI_YESNO(global_autoframing)); 18870 ast_cli(a->fd, " Outb. proxy: %s %s\n", ast_strlen_zero(sip_cfg.outboundproxy.name) ? "<not set>" : sip_cfg.outboundproxy.name, 18871 sip_cfg.outboundproxy.force ? "(forced)" : ""); 18872 ast_cli(a->fd, " Session Timers: %s\n", stmode2str(global_st_mode)); 18873 ast_cli(a->fd, " Session Refresher: %s\n", strefresherparam2str(global_st_refresher)); 18874 ast_cli(a->fd, " Session Expires: %d secs\n", global_max_se); 18875 ast_cli(a->fd, " Session Min-SE: %d secs\n", global_min_se); 18876 ast_cli(a->fd, " Timer T1: %d\n", global_t1); 18877 ast_cli(a->fd, " Timer T1 minimum: %d\n", global_t1min); 18878 ast_cli(a->fd, " Timer B: %d\n", global_timer_b); 18879 ast_cli(a->fd, " No premature media: %s\n", AST_CLI_YESNO(global_prematuremediafilter)); 18880 ast_cli(a->fd, " Max forwards: %d\n", sip_cfg.default_max_forwards); 18881 18882 ast_cli(a->fd, "\nDefault Settings:\n"); 18883 ast_cli(a->fd, "-----------------\n"); 18884 ast_cli(a->fd, " Allowed transports: %s\n", get_transport_list(default_transports)); 18885 ast_cli(a->fd, " Outbound transport: %s\n", get_transport(default_primary_transport)); 18886 ast_cli(a->fd, " Context: %s\n", sip_cfg.default_context); 18887 ast_cli(a->fd, " Force rport: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_NAT_FORCE_RPORT))); 18888 ast_cli(a->fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF))); 18889 ast_cli(a->fd, " Qualify: %d\n", default_qualify); 18890 ast_cli(a->fd, " Use ClientCode: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_USECLIENTCODE))); 18891 ast_cli(a->fd, " Progress inband: %s\n", (ast_test_flag(&global_flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER) ? "Never" : (AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_NO))); 18892 ast_cli(a->fd, " Language: %s\n", default_language); 18893 ast_cli(a->fd, " MOH Interpret: %s\n", default_mohinterpret); 18894 ast_cli(a->fd, " MOH Suggest: %s\n", default_mohsuggest); 18895 ast_cli(a->fd, " Voice Mail Extension: %s\n", default_vmexten); 18896 18897 18898 if (realtimepeers || realtimeregs) { 18899 ast_cli(a->fd, "\nRealtime SIP Settings:\n"); 18900 ast_cli(a->fd, "----------------------\n"); 18901 ast_cli(a->fd, " Realtime Peers: %s\n", AST_CLI_YESNO(realtimepeers)); 18902 ast_cli(a->fd, " Realtime Regs: %s\n", AST_CLI_YESNO(realtimeregs)); 18903 ast_cli(a->fd, " Cache Friends: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS))); 18904 ast_cli(a->fd, " Update: %s\n", AST_CLI_YESNO(sip_cfg.peer_rtupdate)); 18905 ast_cli(a->fd, " Ignore Reg. Expire: %s\n", AST_CLI_YESNO(sip_cfg.ignore_regexpire)); 18906 ast_cli(a->fd, " Save sys. name: %s\n", AST_CLI_YESNO(sip_cfg.rtsave_sysname)); 18907 ast_cli(a->fd, " Auto Clear: %d (%s)\n", sip_cfg.rtautoclear, ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR) ? "Enabled" : "Disabled"); 18908 } 18909 ast_cli(a->fd, "\n----\n"); 18910 return CLI_SUCCESS; 18911 }
| static char* sip_show_tcp | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Show active TCP connections.
Definition at line 17075 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ao2_t_ref, ast_cli_args::argc, ast_cli(), ast_sockaddr_stringify(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, FORMAT, FORMAT2, get_transport(), and ast_cli_entry::usage.
17076 { 17077 struct sip_threadinfo *th; 17078 struct ao2_iterator i; 17079 17080 #define FORMAT2 "%-47.47s %9.9s %6.6s\n" 17081 #define FORMAT "%-47.47s %-9.9s %-6.6s\n" 17082 17083 switch (cmd) { 17084 case CLI_INIT: 17085 e->command = "sip show tcp"; 17086 e->usage = 17087 "Usage: sip show tcp\n" 17088 " Lists all active TCP/TLS sessions.\n"; 17089 return NULL; 17090 case CLI_GENERATE: 17091 return NULL; 17092 } 17093 17094 if (a->argc != 3) 17095 return CLI_SHOWUSAGE; 17096 17097 ast_cli(a->fd, FORMAT2, "Address", "Transport", "Type"); 17098 17099 i = ao2_iterator_init(threadt, 0); 17100 while ((th = ao2_t_iterator_next(&i, "iterate through tcp threads for 'sip show tcp'"))) { 17101 ast_cli(a->fd, FORMAT, 17102 ast_sockaddr_stringify(&th->tcptls_session->remote_address), 17103 get_transport(th->type), 17104 (th->tcptls_session->client ? "Client" : "Server")); 17105 ao2_t_ref(th, -1, "decrement ref from iterator"); 17106 } 17107 ao2_iterator_destroy(&i); 17108 17109 return CLI_SUCCESS; 17110 #undef FORMAT 17111 #undef FORMAT2 17112 }
| static char* sip_show_user | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Show one user in detail.
Definition at line 18374 of file chan_sip.c.
References ao2_lock, ao2_unlock, ast_cli_args::argc, ast_cli_args::argv, ast_callerid_merge(), ast_cdr_flags2str(), ast_cli(), AST_CLI_YESNO, ast_describe_caller_presentation(), ast_strlen_zero(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sip_show_user(), FALSE, ast_cli_args::fd, find_peer(), ast_cli_args::line, ast_cli_args::n, ast_variable::name, ast_variable::next, ast_cli_args::pos, print_codec_to_cli(), print_group(), stmode2str(), strefresherparam2str(), transfermode2str(), TRUE, unref_peer(), ast_cli_entry::usage, ast_variable::value, and ast_cli_args::word.
18375 { 18376 char cbuf[256]; 18377 struct sip_peer *user; 18378 struct ast_variable *v; 18379 int load_realtime; 18380 18381 switch (cmd) { 18382 case CLI_INIT: 18383 e->command = "sip show user"; 18384 e->usage = 18385 "Usage: sip show user <name> [load]\n" 18386 " Shows all details on one SIP user and the current status.\n" 18387 " Option \"load\" forces lookup of peer in realtime storage.\n"; 18388 return NULL; 18389 case CLI_GENERATE: 18390 return complete_sip_show_user(a->line, a->word, a->pos, a->n); 18391 } 18392 18393 if (a->argc < 4) 18394 return CLI_SHOWUSAGE; 18395 18396 /* Load from realtime storage? */ 18397 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? TRUE : FALSE; 18398 18399 if ((user = find_peer(a->argv[3], NULL, load_realtime, FINDUSERS, FALSE, 0))) { 18400 ao2_lock(user); 18401 ast_cli(a->fd, "\n\n"); 18402 ast_cli(a->fd, " * Name : %s\n", user->name); 18403 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>"); 18404 ast_cli(a->fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>"); 18405 ast_cli(a->fd, " Context : %s\n", user->context); 18406 ast_cli(a->fd, " Language : %s\n", user->language); 18407 if (!ast_strlen_zero(user->accountcode)) 18408 ast_cli(a->fd, " Accountcode : %s\n", user->accountcode); 18409 ast_cli(a->fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); 18410 ast_cli(a->fd, " Transfer mode: %s\n", transfermode2str(user->allowtransfer)); 18411 ast_cli(a->fd, " MaxCallBR : %d kbps\n", user->maxcallbitrate); 18412 ast_cli(a->fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); 18413 ast_cli(a->fd, " Call limit : %d\n", user->call_limit); 18414 ast_cli(a->fd, " Callgroup : "); 18415 print_group(a->fd, user->callgroup, 0); 18416 ast_cli(a->fd, " Pickupgroup : "); 18417 print_group(a->fd, user->pickupgroup, 0); 18418 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>")); 18419 ast_cli(a->fd, " ACL : %s\n", AST_CLI_YESNO(user->ha != NULL)); 18420 ast_cli(a->fd, " Sess-Timers : %s\n", stmode2str(user->stimer.st_mode_oper)); 18421 ast_cli(a->fd, " Sess-Refresh : %s\n", strefresherparam2str(user->stimer.st_ref)); 18422 ast_cli(a->fd, " Sess-Expires : %d secs\n", user->stimer.st_max_se); 18423 ast_cli(a->fd, " Sess-Min-SE : %d secs\n", user->stimer.st_min_se); 18424 ast_cli(a->fd, " RTP Engine : %s\n", user->engine); 18425 18426 ast_cli(a->fd, " Codec Order : ("); 18427 print_codec_to_cli(a->fd, &user->prefs); 18428 ast_cli(a->fd, ")\n"); 18429 18430 ast_cli(a->fd, " Auto-Framing: %s \n", AST_CLI_YESNO(user->autoframing)); 18431 if (user->chanvars) { 18432 ast_cli(a->fd, " Variables :\n"); 18433 for (v = user->chanvars ; v ; v = v->next) 18434 ast_cli(a->fd, " %s = %s\n", v->name, v->value); 18435 } 18436 18437 ast_cli(a->fd, "\n"); 18438 18439 ao2_unlock(user); 18440 unref_peer(user, "sip show user"); 18441 } else { 18442 ast_cli(a->fd, "User %s not found.\n", a->argv[3]); 18443 ast_cli(a->fd, "\n"); 18444 } 18445 18446 return CLI_SUCCESS; 18447 }
| static char* sip_show_users | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
CLI Command 'SIP Show Users'.
Definition at line 17115 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_iterator_next, ao2_unlock, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_CLI_YESNO, ast_test_flag, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, FALSE, ast_cli_args::fd, FORMAT, TRUE, unref_peer(), and ast_cli_entry::usage.
17116 { 17117 regex_t regexbuf; 17118 int havepattern = FALSE; 17119 struct ao2_iterator user_iter; 17120 struct sip_peer *user; 17121 17122 #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" 17123 17124 switch (cmd) { 17125 case CLI_INIT: 17126 e->command = "sip show users"; 17127 e->usage = 17128 "Usage: sip show users [like <pattern>]\n" 17129 " Lists all known SIP users.\n" 17130 " Optional regular expression pattern is used to filter the user list.\n"; 17131 return NULL; 17132 case CLI_GENERATE: 17133 return NULL; 17134 } 17135 17136 switch (a->argc) { 17137 case 5: 17138 if (!strcasecmp(a->argv[3], "like")) { 17139 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB)) 17140 return CLI_SHOWUSAGE; 17141 havepattern = TRUE; 17142 } else 17143 return CLI_SHOWUSAGE; 17144 case 3: 17145 break; 17146 default: 17147 return CLI_SHOWUSAGE; 17148 } 17149 17150 ast_cli(a->fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "Forcerport"); 17151 17152 user_iter = ao2_iterator_init(peers, 0); 17153 while ((user = ao2_t_iterator_next(&user_iter, "iterate thru peers table"))) { 17154 ao2_lock(user); 17155 if (!(user->type & SIP_TYPE_USER)) { 17156 ao2_unlock(user); 17157 unref_peer(user, "sip show users"); 17158 continue; 17159 } 17160 17161 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) { 17162 ao2_unlock(user); 17163 unref_peer(user, "sip show users"); 17164 continue; 17165 } 17166 17167 ast_cli(a->fd, FORMAT, user->name, 17168 user->secret, 17169 user->accountcode, 17170 user->context, 17171 AST_CLI_YESNO(user->ha != NULL), 17172 AST_CLI_YESNO(ast_test_flag(&user->flags[0], SIP_NAT_FORCE_RPORT))); 17173 ao2_unlock(user); 17174 unref_peer(user, "sip show users"); 17175 } 17176 ao2_iterator_destroy(&user_iter); 17177 17178 if (havepattern) 17179 regfree(®exbuf); 17180 17181 return CLI_SUCCESS; 17182 #undef FORMAT 17183 }
| static int sip_sipredirect | ( | struct sip_pvt * | p, | |
| const char * | dest | |||
| ) | [static] |
Transfer call before connect with a 302 redirect.
Definition at line 30387 of file chan_sip.c.
References AST_CONTROL_TRANSFER, ast_copy_string(), ast_log(), ast_queue_control_data(), ast_strdupa, ast_string_field_build, ast_strlen_zero(), AST_TRANSFER_SUCCESS, get_header(), LOG_ERROR, sip_alreadygone(), sip_scheddestroy(), and transmit_response_reliable().
Referenced by sip_transfer().
30388 { 30389 char *cdest; 30390 char *extension, *domain; 30391 30392 cdest = ast_strdupa(dest); 30393 30394 extension = strsep(&cdest, "@"); 30395 domain = cdest; 30396 if (ast_strlen_zero(extension)) { 30397 ast_log(LOG_ERROR, "Missing mandatory argument: extension\n"); 30398 return 0; 30399 } 30400 30401 /* we'll issue the redirect message here */ 30402 if (!domain) { 30403 char *local_to_header; 30404 char to_header[256]; 30405 30406 ast_copy_string(to_header, get_header(&p->initreq, "To"), sizeof(to_header)); 30407 if (ast_strlen_zero(to_header)) { 30408 ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n"); 30409 return 0; 30410 } 30411 if (((local_to_header = strcasestr(to_header, "sip:")) || (local_to_header = strcasestr(to_header, "sips:"))) 30412 && (local_to_header = strchr(local_to_header, '@'))) { 30413 char ldomain[256]; 30414 30415 memset(ldomain, 0, sizeof(ldomain)); 30416 local_to_header++; 30417 /* This is okey because lhost and lport are as big as tmp */ 30418 sscanf(local_to_header, "%256[^<>; ]", ldomain); 30419 if (ast_strlen_zero(ldomain)) { 30420 ast_log(LOG_ERROR, "Can't find the host address\n"); 30421 return 0; 30422 } 30423 domain = ast_strdupa(ldomain); 30424 } 30425 } 30426 30427 ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s>", extension, domain); 30428 transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq); 30429 30430 sip_scheddestroy(p, SIP_TRANS_TIMEOUT); /* Make sure we stop send this reply. */ 30431 sip_alreadygone(p); 30432 30433 if (p->owner) { 30434 enum ast_control_transfer message = AST_TRANSFER_SUCCESS; 30435 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 30436 } 30437 /* hangup here */ 30438 return 0; 30439 }
| static struct sip_st_dlg * sip_st_alloc | ( | struct sip_pvt *const | p | ) | [static, read] |
Allocate Session-Timers struct w/in dialog.
Definition at line 7944 of file chan_sip.c.
References ast_calloc, ast_log(), and LOG_ERROR.
Referenced by handle_request_invite_st(), and st_get_mode().
07945 { 07946 struct sip_st_dlg *stp; 07947 07948 if (p->stimer) { 07949 ast_log(LOG_ERROR, "Session-Timer struct already allocated\n"); 07950 return p->stimer; 07951 } 07952 07953 if (!(stp = ast_calloc(1, sizeof(struct sip_st_dlg)))) 07954 return NULL; 07955 07956 p->stimer = stp; 07957 07958 stp->st_schedid = -1; /* Session-Timers ast_sched scheduler id */ 07959 07960 return p->stimer; 07961 }
| static int sip_standard_port | ( | enum sip_transport | type, | |
| int | port | |||
| ) | [static] |
Returns the port to use for this socket.
| type | The type of transport used | |
| port | Port we are checking to see if it's the standard port. |
Definition at line 26218 of file chan_sip.c.
Referenced by initreqprep(), and transmit_notify_with_mwi().
26219 { 26220 if (type & SIP_TRANSPORT_TLS) 26221 return port == STANDARD_TLS_PORT; 26222 else 26223 return port == STANDARD_SIP_PORT; 26224 }
| static int sip_subscribe_mwi | ( | const char * | value, | |
| int | lineno | |||
| ) | [static] |
Parse mwi=> line in sip.conf and add to list.
--- SIP MWI Subscription support
Definition at line 8577 of file chan_sip.c.
References ast_calloc_with_stringfields, ast_copy_string(), ast_log(), ast_string_field_set, ast_strlen_zero(), ASTOBJ_CONTAINER_LINK, ASTOBJ_INIT, ASTOBJ_UNREF, hostname, LOG_WARNING, mailbox, secret, sip_subscribe_mwi_destroy(), and submwil.
Referenced by reload_config().
08578 { 08579 struct sip_subscription_mwi *mwi; 08580 int portnum = 0; 08581 enum sip_transport transport = SIP_TRANSPORT_UDP; 08582 char buf[256] = ""; 08583 char *username = NULL, *hostname = NULL, *secret = NULL, *authuser = NULL, *porta = NULL, *mailbox = NULL; 08584 08585 if (!value) { 08586 return -1; 08587 } 08588 08589 ast_copy_string(buf, value, sizeof(buf)); 08590 08591 username = buf; 08592 08593 if ((hostname = strrchr(buf, '@'))) { 08594 *hostname++ = '\0'; 08595 } else { 08596 return -1; 08597 } 08598 08599 if ((secret = strchr(username, ':'))) { 08600 *secret++ = '\0'; 08601 if ((authuser = strchr(secret, ':'))) { 08602 *authuser++ = '\0'; 08603 } 08604 } 08605 08606 if ((mailbox = strchr(hostname, '/'))) { 08607 *mailbox++ = '\0'; 08608 } 08609 08610 if (ast_strlen_zero(username) || ast_strlen_zero(hostname) || ast_strlen_zero(mailbox)) { 08611 ast_log(LOG_WARNING, "Format for MWI subscription is user[:secret[:authuser]]@host[:port]/mailbox at line %d\n", lineno); 08612 return -1; 08613 } 08614 08615 if ((porta = strchr(hostname, ':'))) { 08616 *porta++ = '\0'; 08617 if (!(portnum = atoi(porta))) { 08618 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 08619 return -1; 08620 } 08621 } 08622 08623 if (!(mwi = ast_calloc_with_stringfields(1, struct sip_subscription_mwi, 256))) { 08624 return -1; 08625 } 08626 08627 ASTOBJ_INIT(mwi); 08628 ast_string_field_set(mwi, username, username); 08629 if (secret) { 08630 ast_string_field_set(mwi, secret, secret); 08631 } 08632 if (authuser) { 08633 ast_string_field_set(mwi, authuser, authuser); 08634 } 08635 ast_string_field_set(mwi, hostname, hostname); 08636 ast_string_field_set(mwi, mailbox, mailbox); 08637 mwi->resub = -1; 08638 mwi->portno = portnum; 08639 mwi->transport = transport; 08640 08641 ASTOBJ_CONTAINER_LINK(&submwil, mwi); 08642 ASTOBJ_UNREF(mwi, sip_subscribe_mwi_destroy); 08643 08644 return 0; 08645 }
| static void sip_subscribe_mwi_destroy | ( | struct sip_subscription_mwi * | mwi | ) | [static] |
Destroy MWI subscription object.
Definition at line 5955 of file chan_sip.c.
References ast_free, AST_SCHED_DEL, and ast_string_field_free_memory.
Referenced by __sip_subscribe_mwi_do(), handle_response_subscribe(), sip_send_all_mwi_subscriptions(), sip_subscribe_mwi(), sip_subscribe_mwi_do(), and unload_module().
05956 { 05957 if (mwi->call) { 05958 mwi->call->mwi = NULL; 05959 mwi->call = dialog_unref(mwi->call, "sip_subscription_mwi destruction"); 05960 } 05961 05962 AST_SCHED_DEL(sched, mwi->resub); 05963 ast_string_field_free_memory(mwi); 05964 ast_free(mwi); 05965 }
| static int sip_subscribe_mwi_do | ( | const void * | data | ) | [static] |
Send a subscription or resubscription for MWI.
Definition at line 12780 of file chan_sip.c.
References __sip_subscribe_mwi_do(), ASTOBJ_UNREF, and sip_subscribe_mwi_destroy().
Referenced by handle_response_subscribe(), and sip_send_all_mwi_subscriptions().
12781 { 12782 struct sip_subscription_mwi *mwi = (struct sip_subscription_mwi*)data; 12783 12784 if (!mwi) { 12785 return -1; 12786 } 12787 12788 mwi->resub = -1; 12789 __sip_subscribe_mwi_do(mwi); 12790 ASTOBJ_UNREF(mwi, sip_subscribe_mwi_destroy); 12791 12792 return 0; 12793 }
| static int sip_t38_abort | ( | const void * | data | ) | [static] |
Called to deny a T38 reinvite if the core does not respond to our request.
Definition at line 22910 of file chan_sip.c.
References change_t38_state(), sip_pvt_lock, sip_pvt_unlock, and transmit_response_reliable().
Referenced by handle_request_invite().
22911 { 22912 struct sip_pvt *p = (struct sip_pvt *) data; 22913 22914 sip_pvt_lock(p); 22915 /* an application may have taken ownership of the T.38 negotiation on this 22916 * channel while we were waiting to grab the lock... if it did, the scheduler 22917 * id will have been reset to -1, which is our indication that we do *not* 22918 * want to abort the negotiation process 22919 */ 22920 if (p->t38id != -1) { 22921 change_t38_state(p, T38_DISABLED); 22922 transmit_response_reliable(p, "488 Not acceptable here", &p->initreq); 22923 p->t38id = -1; 22924 dialog_unref(p, "unref the dialog ptr from sip_t38_abort, because it held a dialog ptr"); 22925 } 22926 sip_pvt_unlock(p); 22927 return 0; 22928 }
| static struct ast_tcptls_session_instance* sip_tcp_locate | ( | struct ast_sockaddr * | s | ) | [static, read] |
Find thread for TCP/TLS session (based on IP/Port.
Definition at line 26243 of file chan_sip.c.
References ao2_callback, ao2_ref, ao2_t_ref, and threadinfo_locate_cb().
Referenced by sip_prepare_socket().
26244 { 26245 struct sip_threadinfo *th; 26246 struct ast_tcptls_session_instance *tcptls_instance = NULL; 26247 26248 if ((th = ao2_callback(threadt, 0, threadinfo_locate_cb, s))) { 26249 tcptls_instance = (ao2_ref(th->tcptls_session, +1), th->tcptls_session); 26250 ao2_t_ref(th, -1, "decrement ref from callback"); 26251 } 26252 26253 return tcptls_instance; 26254 }
| static void * sip_tcp_worker_fn | ( | void * | data | ) | [static] |
SIP TCP connection handler.
Definition at line 2469 of file chan_sip.c.
References _sip_tcp_helper_thread().
Referenced by sip_prepare_socket().
02470 { 02471 struct ast_tcptls_session_instance *tcptls_session = data; 02472 02473 return _sip_tcp_helper_thread(tcptls_session); 02474 }
| static void sip_tcptls_client_args_destructor | ( | void * | obj | ) | [static] |
Definition at line 2349 of file chan_sip.c.
References args, ast_free, ast_ssl_teardown(), ast_tls_config::cafile, ast_tls_config::capath, ast_tls_config::certfile, ast_tls_config::cipher, ast_tcptls_session_args::name, ast_tls_config::pvtfile, and ast_tcptls_session_args::tls_cfg.
Referenced by sip_prepare_socket().
02350 { 02351 struct ast_tcptls_session_args *args = obj; 02352 if (args->tls_cfg) { 02353 ast_free(args->tls_cfg->certfile); 02354 ast_free(args->tls_cfg->pvtfile); 02355 ast_free(args->tls_cfg->cipher); 02356 ast_free(args->tls_cfg->cafile); 02357 ast_free(args->tls_cfg->capath); 02358 02359 ast_ssl_teardown(args->tls_cfg); 02360 } 02361 ast_free(args->tls_cfg); 02362 ast_free((char *) args->name); 02363 }
| static int sip_tcptls_read | ( | struct sip_request * | req, | |
| struct ast_tcptls_session_instance * | tcptls_session, | |||
| int | authenticated, | |||
| time_t | start | |||
| ) | [static] |
Read SIP request or response from a TCP/TLS connection.
| req | The request structure to be filled in | |
| tcptls_session | The TCP/TLS connection from which to read |
| -1 | Failed to read data | |
| 0 | Successfully read data |
Definition at line 2661 of file chan_sip.c.
References ast_debug, ast_log(), ast_sockaddr_stringify(), ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_strlen(), ast_tcptls_server_read(), ast_wait_for_input(), check_message_integrity(), ast_tcptls_session_instance::client, errno, ast_tcptls_session_instance::fd, LOG_WARNING, MESSAGE_FRAGMENT, ast_tcptls_session_instance::overflow_buf, ast_tcptls_session_instance::remote_address, and sip_check_authtimeout().
Referenced by _sip_tcp_helper_thread().
02663 { 02664 enum message_integrity message_integrity = MESSAGE_FRAGMENT; 02665 02666 while (message_integrity == MESSAGE_FRAGMENT) { 02667 size_t datalen; 02668 02669 if (ast_str_strlen(tcptls_session->overflow_buf) == 0) { 02670 char readbuf[4097]; 02671 int timeout; 02672 int res; 02673 if (!tcptls_session->client && !authenticated) { 02674 if ((timeout = sip_check_authtimeout(start)) < 0) { 02675 return -1; 02676 } 02677 02678 if (timeout == 0) { 02679 ast_debug(2, "SIP TCP/TLS server timed out\n"); 02680 return -1; 02681 } 02682 } else { 02683 timeout = -1; 02684 } 02685 res = ast_wait_for_input(tcptls_session->fd, timeout); 02686 if (res < 0) { 02687 ast_debug(2, "SIP TCP/TLS server :: ast_wait_for_input returned %d\n", res); 02688 return -1; 02689 } else if (res == 0) { 02690 ast_debug(2, "SIP TCP/TLS server timed out\n"); 02691 return -1; 02692 } 02693 02694 res = ast_tcptls_server_read(tcptls_session, readbuf, sizeof(readbuf) - 1); 02695 if (res < 0) { 02696 if (errno == EAGAIN || errno == EINTR) { 02697 continue; 02698 } 02699 ast_debug(2, "SIP TCP/TLS server error when receiving data\n"); 02700 return -1; 02701 } else if (res == 0) { 02702 ast_debug(2, "SIP TCP/TLS server has shut down\n"); 02703 return -1; 02704 } 02705 readbuf[res] = '\0'; 02706 ast_str_append(&req->data, 0, "%s", readbuf); 02707 } else { 02708 ast_str_append(&req->data, 0, "%s", ast_str_buffer(tcptls_session->overflow_buf)); 02709 ast_str_reset(tcptls_session->overflow_buf); 02710 } 02711 02712 datalen = ast_str_strlen(req->data); 02713 if (datalen > SIP_MAX_PACKET_SIZE) { 02714 ast_log(LOG_WARNING, "Rejecting TCP/TLS packet from '%s' because way too large: %zu\n", 02715 ast_sockaddr_stringify(&tcptls_session->remote_address), datalen); 02716 return -1; 02717 } 02718 02719 message_integrity = check_message_integrity(&req->data, &tcptls_session->overflow_buf); 02720 } 02721 02722 return 0; 02723 }
| static int sip_tcptls_write | ( | struct ast_tcptls_session_instance * | tcptls_session, | |
| const void * | buf, | |||
| size_t | len | |||
| ) | [static] |
used to indicate to a tcptls thread that data is ready to be written
Definition at line 2411 of file chan_sip.c.
References ao2_alloc, ao2_lock, ao2_t_find, ao2_t_ref, ao2_unlock, AST_LIST_INSERT_TAIL, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_str_create(), ast_str_set(), errno, ast_tcptls_session_instance::fd, ast_tcptls_session_instance::lock, LOG_ERROR, OBJ_POINTER, and tcptls_packet_destructor().
Referenced by __sip_xmit().
02412 { 02413 int res = len; 02414 struct sip_threadinfo *th = NULL; 02415 struct tcptls_packet *packet = NULL; 02416 struct sip_threadinfo tmp = { 02417 .tcptls_session = tcptls_session, 02418 }; 02419 enum sip_tcptls_alert alert = TCPTLS_ALERT_DATA; 02420 02421 if (!tcptls_session) { 02422 return XMIT_ERROR; 02423 } 02424 02425 ast_mutex_lock(&tcptls_session->lock); 02426 02427 if ((tcptls_session->fd == -1) || 02428 !(th = ao2_t_find(threadt, &tmp, OBJ_POINTER, "ao2_find, getting sip_threadinfo in tcp helper thread")) || 02429 !(packet = ao2_alloc(sizeof(*packet), tcptls_packet_destructor)) || 02430 !(packet->data = ast_str_create(len))) { 02431 goto tcptls_write_setup_error; 02432 } 02433 02434 /* goto tcptls_write_error should _NOT_ be used beyond this point */ 02435 ast_str_set(&packet->data, 0, "%s", (char *) buf); 02436 packet->len = len; 02437 02438 /* alert tcptls thread handler that there is a packet to be sent. 02439 * must lock the thread info object to guarantee control of the 02440 * packet queue */ 02441 ao2_lock(th); 02442 if (write(th->alert_pipe[1], &alert, sizeof(alert)) == -1) { 02443 ast_log(LOG_ERROR, "write() to alert pipe failed: %s\n", strerror(errno)); 02444 ao2_t_ref(packet, -1, "could not write to alert pipe, remove packet"); 02445 packet = NULL; 02446 res = XMIT_ERROR; 02447 } else { /* it is safe to queue the frame after issuing the alert when we hold the threadinfo lock */ 02448 AST_LIST_INSERT_TAIL(&th->packet_q, packet, entry); 02449 } 02450 ao2_unlock(th); 02451 02452 ast_mutex_unlock(&tcptls_session->lock); 02453 ao2_t_ref(th, -1, "In sip_tcptls_write, unref threadinfo object after finding it"); 02454 return res; 02455 02456 tcptls_write_setup_error: 02457 if (th) { 02458 ao2_t_ref(th, -1, "In sip_tcptls_write, unref threadinfo obj, could not create packet"); 02459 } 02460 if (packet) { 02461 ao2_t_ref(packet, -1, "could not allocate packet's data"); 02462 } 02463 ast_mutex_unlock(&tcptls_session->lock); 02464 02465 return XMIT_ERROR; 02466 }
| static struct sip_threadinfo* sip_threadinfo_create | ( | struct ast_tcptls_session_instance * | tcptls_session, | |
| int | transport | |||
| ) | [static, read] |
creates a sip_threadinfo object and links it into the threadt table.
Definition at line 2387 of file chan_sip.c.
References ao2_alloc, ao2_t_link, ao2_t_ref, ast_log(), errno, LOG_ERROR, sip_threadinfo_destructor(), and ast_tcptls_session_instance::ssl.
Referenced by _sip_tcp_helper_thread(), and sip_prepare_socket().
02388 { 02389 struct sip_threadinfo *th; 02390 02391 if (!tcptls_session || !(th = ao2_alloc(sizeof(*th), sip_threadinfo_destructor))) { 02392 return NULL; 02393 } 02394 02395 th->alert_pipe[0] = th->alert_pipe[1] = -1; 02396 02397 if (pipe(th->alert_pipe) == -1) { 02398 ao2_t_ref(th, -1, "Failed to open alert pipe on sip_threadinfo"); 02399 ast_log(LOG_ERROR, "Could not create sip alert pipe in tcptls thread, error %s\n", strerror(errno)); 02400 return NULL; 02401 } 02402 ao2_t_ref(tcptls_session, +1, "tcptls_session ref for sip_threadinfo object"); 02403 th->tcptls_session = tcptls_session; 02404 th->type = transport ? transport : (tcptls_session->ssl ? SIP_TRANSPORT_TLS: SIP_TRANSPORT_TCP); 02405 ao2_t_link(threadt, th, "Adding new tcptls helper thread"); 02406 ao2_t_ref(th, -1, "Decrementing threadinfo ref from alloc, only table ref remains"); 02407 return th; 02408 }
| static void sip_threadinfo_destructor | ( | void * | obj | ) | [static] |
Definition at line 2365 of file chan_sip.c.
References ao2_t_ref, and AST_LIST_REMOVE_HEAD.
Referenced by sip_threadinfo_create().
02366 { 02367 struct sip_threadinfo *th = obj; 02368 struct tcptls_packet *packet; 02369 if (th->alert_pipe[1] > -1) { 02370 close(th->alert_pipe[0]); 02371 } 02372 if (th->alert_pipe[1] > -1) { 02373 close(th->alert_pipe[1]); 02374 } 02375 th->alert_pipe[0] = th->alert_pipe[1] = -1; 02376 02377 while ((packet = AST_LIST_REMOVE_HEAD(&th->packet_q, entry))) { 02378 ao2_t_ref(packet, -1, "thread destruction, removing packet from frame queue"); 02379 } 02380 02381 if (th->tcptls_session) { 02382 ao2_t_ref(th->tcptls_session, -1, "remove tcptls_session for sip_threadinfo object"); 02383 } 02384 }
| static int sip_transfer | ( | struct ast_channel * | ast, | |
| const char * | dest | |||
| ) | [static] |
Transfer SIP call.
Definition at line 6974 of file chan_sip.c.
References ast_channel::_state, ast_debug, AST_STATE_RING, sip_pvt_lock, sip_pvt_unlock, sip_sipredirect(), ast_channel::tech_pvt, and transmit_refer().
06975 { 06976 struct sip_pvt *p = ast->tech_pvt; 06977 int res; 06978 06979 if (!p) { 06980 ast_debug(1, "Asked to transfer channel %s with no pvt; ignoring\n", 06981 ast->name); 06982 return -1; 06983 } 06984 06985 if (dest == NULL) /* functions below do not take a NULL */ 06986 dest = ""; 06987 sip_pvt_lock(p); 06988 if (ast->_state == AST_STATE_RING) 06989 res = sip_sipredirect(p, dest); 06990 else 06991 res = transmit_refer(p, dest); 06992 sip_pvt_unlock(p); 06993 return res; 06994 }
| static char * sip_unregister | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Unregister (force expiration) a SIP peer in the registry via CLI.
Definition at line 18547 of file chan_sip.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_SCHED_DEL_UNREF, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sip_unregister(), expire_register(), ast_cli_args::fd, find_peer(), ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ref_peer(), TRUE, unref_peer(), ast_cli_entry::usage, and ast_cli_args::word.
18548 { 18549 struct sip_peer *peer; 18550 int load_realtime = 0; 18551 18552 switch (cmd) { 18553 case CLI_INIT: 18554 e->command = "sip unregister"; 18555 e->usage = 18556 "Usage: sip unregister <peer>\n" 18557 " Unregister (force expiration) a SIP peer from the registry\n"; 18558 return NULL; 18559 case CLI_GENERATE: 18560 return complete_sip_unregister(a->line, a->word, a->pos, a->n); 18561 } 18562 18563 if (a->argc != 3) 18564 return CLI_SHOWUSAGE; 18565 18566 if ((peer = find_peer(a->argv[2], NULL, load_realtime, FINDPEERS, TRUE, 0))) { 18567 if (peer->expire > 0) { 18568 AST_SCHED_DEL_UNREF(sched, peer->expire, 18569 unref_peer(peer, "remove register expire ref")); 18570 expire_register(ref_peer(peer, "ref for expire_register")); 18571 ast_cli(a->fd, "Unregistered peer \'%s\'\n\n", a->argv[2]); 18572 } else { 18573 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]); 18574 } 18575 unref_peer(peer, "sip_unregister: unref_peer via sip_unregister: done with peer from find_peer call"); 18576 } else { 18577 ast_cli(a->fd, "Peer unknown: \'%s\'. Not unregistered.\n", a->argv[2]); 18578 } 18579 18580 return CLI_SUCCESS; 18581 }
| static void sip_unregister_tests | ( | void | ) | [static] |
SIP test registration.
Definition at line 30863 of file chan_sip.c.
References sip_config_parser_unregister_tests(), sip_dialplan_function_unregister_tests(), and sip_request_parser_unregister_tests().
Referenced by unload_module().
30864 { 30865 sip_config_parser_unregister_tests(); 30866 sip_request_parser_unregister_tests(); 30867 sip_dialplan_function_unregister_tests(); 30868 }
| static int sip_write | ( | struct ast_channel * | ast, | |
| struct ast_frame * | frame | |||
| ) | [static] |
Send frame to media channel (rtp).
Definition at line 6764 of file chan_sip.c.
References ast_channel::_state, AST_FORMAT_AUDIO_MASK, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_rtp_instance_update_source(), ast_rtp_instance_write(), ast_rtp_red_buffer(), ast_set_flag, AST_STATE_UP, ast_test_flag, ast_udptl_write(), ast_frame_subclass::codec, ast_frame::frametype, LOG_WARNING, ast_channel::nativeformats, ast_channel::readformat, sip_pvt_lock, sip_pvt_unlock, ast_frame::subclass, ast_channel::tech_pvt, transmit_provisional_response(), TRUE, and ast_channel::writeformat.
06765 { 06766 struct sip_pvt *p = ast->tech_pvt; 06767 int res = 0; 06768 06769 switch (frame->frametype) { 06770 case AST_FRAME_VOICE: 06771 if (!(frame->subclass.codec & ast->nativeformats)) { 06772 char s1[512], s2[512], s3[512]; 06773 ast_log(LOG_WARNING, "Asked to transmit frame type %s, while native formats is %s read/write = %s/%s\n", 06774 ast_getformatname(frame->subclass.codec), 06775 ast_getformatname_multiple(s1, sizeof(s1), ast->nativeformats & AST_FORMAT_AUDIO_MASK), 06776 ast_getformatname_multiple(s2, sizeof(s2), ast->readformat), 06777 ast_getformatname_multiple(s3, sizeof(s3), ast->writeformat)); 06778 return 0; 06779 } 06780 if (p) { 06781 sip_pvt_lock(p); 06782 if (p->t38.state == T38_ENABLED) { 06783 /* drop frame, can't sent VOICE frames while in T.38 mode */ 06784 sip_pvt_unlock(p); 06785 break; 06786 } else if (p->rtp) { 06787 /* If channel is not up, activate early media session */ 06788 if ((ast->_state != AST_STATE_UP) && 06789 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 06790 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06791 ast_rtp_instance_update_source(p->rtp); 06792 if (!global_prematuremediafilter) { 06793 p->invitestate = INV_EARLY_MEDIA; 06794 transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE); 06795 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 06796 } 06797 } 06798 p->lastrtptx = time(NULL); 06799 res = ast_rtp_instance_write(p->rtp, frame); 06800 } 06801 sip_pvt_unlock(p); 06802 } 06803 break; 06804 case AST_FRAME_VIDEO: 06805 if (p) { 06806 sip_pvt_lock(p); 06807 if (p->vrtp) { 06808 /* Activate video early media */ 06809 if ((ast->_state != AST_STATE_UP) && 06810 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 06811 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06812 p->invitestate = INV_EARLY_MEDIA; 06813 transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE); 06814 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 06815 } 06816 p->lastrtptx = time(NULL); 06817 res = ast_rtp_instance_write(p->vrtp, frame); 06818 } 06819 sip_pvt_unlock(p); 06820 } 06821 break; 06822 case AST_FRAME_TEXT: 06823 if (p) { 06824 sip_pvt_lock(p); 06825 if (p->red) { 06826 ast_rtp_red_buffer(p->trtp, frame); 06827 } else { 06828 if (p->trtp) { 06829 /* Activate text early media */ 06830 if ((ast->_state != AST_STATE_UP) && 06831 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 06832 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06833 p->invitestate = INV_EARLY_MEDIA; 06834 transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE); 06835 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 06836 } 06837 p->lastrtptx = time(NULL); 06838 res = ast_rtp_instance_write(p->trtp, frame); 06839 } 06840 } 06841 sip_pvt_unlock(p); 06842 } 06843 break; 06844 case AST_FRAME_IMAGE: 06845 return 0; 06846 break; 06847 case AST_FRAME_MODEM: 06848 if (p) { 06849 sip_pvt_lock(p); 06850 /* UDPTL requires two-way communication, so early media is not needed here. 06851 we simply forget the frames if we get modem frames before the bridge is up. 06852 Fax will re-transmit. 06853 */ 06854 if ((ast->_state == AST_STATE_UP) && 06855 p->udptl && 06856 (p->t38.state == T38_ENABLED)) { 06857 res = ast_udptl_write(p->udptl, frame); 06858 } 06859 sip_pvt_unlock(p); 06860 } 06861 break; 06862 default: 06863 ast_log(LOG_WARNING, "Can't send %u type frames with SIP write\n", frame->frametype); 06864 return 0; 06865 } 06866 06867 return res; 06868 }
| static int sipsock_read | ( | int * | id, | |
| int | fd, | |||
| short | events, | |||
| void * | ignore | |||
| ) | [static] |
Read data from SIP UDP socket.
Definition at line 26088 of file chan_sip.c.
References AST_DYNSTR_BUILD_FAILED, ast_log(), ast_recvfrom(), ast_sockaddr_port, ast_str_create(), ast_str_set(), bindaddr, deinit_req(), errno, handle_request_do(), LOG_NOTICE, LOG_WARNING, and set_socket_transport().
Referenced by do_monitor().
26089 { 26090 struct sip_request req; 26091 struct ast_sockaddr addr; 26092 int res; 26093 static char readbuf[65535]; 26094 26095 memset(&req, 0, sizeof(req)); 26096 res = ast_recvfrom(fd, readbuf, sizeof(readbuf) - 1, 0, &addr); 26097 if (res < 0) { 26098 #if !defined(__FreeBSD__) 26099 if (errno == EAGAIN) 26100 ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n"); 26101 else 26102 #endif 26103 if (errno != ECONNREFUSED) 26104 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 26105 return 1; 26106 } 26107 26108 readbuf[res] = '\0'; 26109 26110 if (!(req.data = ast_str_create(SIP_MIN_PACKET))) { 26111 return 1; 26112 } 26113 26114 if (ast_str_set(&req.data, 0, "%s", readbuf) == AST_DYNSTR_BUILD_FAILED) { 26115 return -1; 26116 } 26117 26118 req.socket.fd = sipsock; 26119 set_socket_transport(&req.socket, SIP_TRANSPORT_UDP); 26120 req.socket.tcptls_session = NULL; 26121 req.socket.port = htons(ast_sockaddr_port(&bindaddr)); 26122 26123 handle_request_do(&req, &addr); 26124 deinit_req(&req); 26125 26126 return 1; 26127 }
| static int sockaddr_is_null_or_any | ( | const struct ast_sockaddr * | addr | ) | [static] |
Definition at line 9082 of file chan_sip.c.
References ast_sockaddr_is_any(), and ast_sockaddr_isnull().
Referenced by process_sdp().
09083 { 09084 return ast_sockaddr_isnull(addr) || ast_sockaddr_is_any(addr); 09085 }
| enum st_mode st_get_mode | ( | struct sip_pvt * | p, | |
| int | no_cached | |||
| ) | [static] |
Get the session-timer mode.
| p | pointer to the SIP dialog | |
| no_cached,set | this to true in order to force a peername lookup on the session timer mode. |
Definition at line 27017 of file chan_sip.c.
References sip_st_alloc().
Referenced by add_supported_header(), handle_request_invite_st(), handle_response_invite(), and transmit_invite().
27018 { 27019 if (!p->stimer) { 27020 sip_st_alloc(p); 27021 if (!p->stimer) { 27022 return SESSION_TIMER_MODE_INVALID; 27023 } 27024 } 27025 27026 if (!no_cached && p->stimer->st_cached_mode != SESSION_TIMER_MODE_INVALID) 27027 return p->stimer->st_cached_mode; 27028 27029 if (p->relatedpeer) { 27030 p->stimer->st_cached_mode = p->relatedpeer->stimer.st_mode_oper; 27031 return p->stimer->st_cached_mode; 27032 } 27033 27034 p->stimer->st_cached_mode = global_st_mode; 27035 return global_st_mode; 27036 }
| enum st_refresher st_get_refresher | ( | struct sip_pvt * | p | ) | [static] |
Get the entity (UAC or UAS) that's acting as the session-timer refresher.
| p | pointer to the SIP dialog |
Definition at line 26995 of file chan_sip.c.
Referenced by handle_request_invite_st().
26996 { 26997 if (p->stimer->st_cached_ref != SESSION_TIMER_REFRESHER_AUTO) { 26998 return p->stimer->st_cached_ref; 26999 } 27000 27001 if (p->relatedpeer) { 27002 p->stimer->st_cached_ref = (p->relatedpeer->stimer.st_ref == SESSION_TIMER_REFRESHER_PARAM_UAC) ? SESSION_TIMER_REFRESHER_THEM : SESSION_TIMER_REFRESHER_US; 27003 return p->stimer->st_cached_ref; 27004 } 27005 27006 p->stimer->st_cached_ref = (global_st_refresher == SESSION_TIMER_REFRESHER_PARAM_UAC) ? SESSION_TIMER_REFRESHER_THEM : SESSION_TIMER_REFRESHER_US; 27007 return p->stimer->st_cached_ref; 27008 }
| int st_get_se | ( | struct sip_pvt * | p, | |
| int | max | |||
| ) | [static] |
Get Max or Min SE (session timer expiry).
| p | pointer to the SIP dialog | |
| max | if true, get max se, otherwise min se |
Definition at line 26963 of file chan_sip.c.
References TRUE.
Referenced by handle_request_invite_st(), handle_response_invite(), reqprep(), and transmit_invite().
26964 { 26965 if (max == TRUE) { 26966 if (p->stimer->st_cached_max_se) { 26967 return p->stimer->st_cached_max_se; 26968 } 26969 if (p->relatedpeer) { 26970 p->stimer->st_cached_max_se = p->relatedpeer->stimer.st_max_se; 26971 return (p->stimer->st_cached_max_se); 26972 } 26973 p->stimer->st_cached_max_se = global_max_se; 26974 return (p->stimer->st_cached_max_se); 26975 } 26976 /* Find Min SE timer */ 26977 if (p->stimer->st_cached_min_se) { 26978 return p->stimer->st_cached_min_se; 26979 } 26980 if (p->relatedpeer) { 26981 p->stimer->st_cached_min_se = p->relatedpeer->stimer.st_min_se; 26982 return (p->stimer->st_cached_min_se); 26983 } 26984 p->stimer->st_cached_min_se = global_min_se; 26985 return (p->stimer->st_cached_min_se); 26986 }
| static void start_session_timer | ( | struct sip_pvt * | p | ) | [static] |
Session-Timers: Start session timer.
Definition at line 26745 of file chan_sip.c.
References ast_debug, ast_log(), ast_sched_add(), AST_SCHED_DEL_UNREF, LOG_ERROR, MIN, proc_session_timer(), and TRUE.
Referenced by handle_response_invite(), restart_session_timer(), and sip_answer().
26746 { 26747 unsigned int timeout_ms; 26748 26749 if (p->stimer->st_schedid > -1) { 26750 /* in the event a timer is already going, stop it */ 26751 ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid); 26752 AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid, 26753 dialog_unref(p, "unref stimer->st_schedid from dialog")); 26754 } 26755 26756 /* 26757 * RFC 4028 Section 10 26758 * If the side not performing refreshes does not receive a 26759 * session refresh request before the session expiration, it SHOULD send 26760 * a BYE to terminate the session, slightly before the session 26761 * expiration. The minimum of 32 seconds and one third of the session 26762 * interval is RECOMMENDED. 26763 */ 26764 26765 timeout_ms = (1000 * p->stimer->st_interval); 26766 if (p->stimer->st_ref == SESSION_TIMER_REFRESHER_US) { 26767 timeout_ms /= 2; 26768 } else { 26769 timeout_ms -= MIN(timeout_ms / 3, 32000); 26770 } 26771 26772 p->stimer->st_schedid = ast_sched_add(sched, timeout_ms, proc_session_timer, 26773 dialog_ref(p, "adding session timer ref")); 26774 26775 if (p->stimer->st_schedid < 0) { 26776 dialog_unref(p, "removing session timer ref"); 26777 ast_log(LOG_ERROR, "ast_sched_add failed - %s\n", p->callid); 26778 } else { 26779 p->stimer->st_active = TRUE; 26780 ast_debug(2, "Session timer started: %d - %s %ums\n", p->stimer->st_schedid, p->callid, timeout_ms); 26781 } 26782 }
| static void state_notify_build_xml | ( | int | state, | |
| int | full, | |||
| const char * | exten, | |||
| const char * | context, | |||
| struct ast_str ** | tmp, | |||
| struct sip_pvt * | p, | |||
| int | subscribed, | |||
| const char * | mfrom, | |||
| const char * | mto | |||
| ) | [static] |
Builds XML portion of NOTIFY messages for presence or dialog updates.
Definition at line 12966 of file chan_sip.c.
References ast_alloca, ast_channel_callback(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, AST_DEVICE_UNAVAILABLE, AST_EXTENSION_BUSY, AST_EXTENSION_INUSE, AST_EXTENSION_NOT_INUSE, AST_EXTENSION_ONHOLD, AST_EXTENSION_RINGING, AST_EXTENSION_UNAVAILABLE, ast_get_hint(), AST_MAX_EXTENSION, AST_PRES_RESTRICTED, AST_PRES_RESTRICTION, ast_str_append(), ast_strdupa, ast_xml_escape(), ast_channel::caller, cid_num, ast_channel::connected, find_calling_channel(), ast_party_connected_line::id, ast_party_caller::id, ast_party_id::name, NONE, ast_party_id::number, ast_party_name::presentation, ast_party_number::presentation, S_COR, sip_cfg, ast_party_name::str, ast_party_number::str, ast_party_name::valid, and ast_party_number::valid.
Referenced by transmit_state_notify().
12967 { 12968 enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN; 12969 const char *statestring = "terminated"; 12970 const char *pidfstate = "--"; 12971 const char *pidfnote= "Ready"; 12972 char hint[AST_MAX_EXTENSION]; 12973 12974 switch (state) { 12975 case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE): 12976 statestring = (sip_cfg.notifyringing) ? "early" : "confirmed"; 12977 local_state = NOTIFY_INUSE; 12978 pidfstate = "busy"; 12979 pidfnote = "Ringing"; 12980 break; 12981 case AST_EXTENSION_RINGING: 12982 statestring = "early"; 12983 local_state = NOTIFY_INUSE; 12984 pidfstate = "busy"; 12985 pidfnote = "Ringing"; 12986 break; 12987 case AST_EXTENSION_INUSE: 12988 statestring = "confirmed"; 12989 local_state = NOTIFY_INUSE; 12990 pidfstate = "busy"; 12991 pidfnote = "On the phone"; 12992 break; 12993 case AST_EXTENSION_BUSY: 12994 statestring = "confirmed"; 12995 local_state = NOTIFY_CLOSED; 12996 pidfstate = "busy"; 12997 pidfnote = "On the phone"; 12998 break; 12999 case AST_EXTENSION_UNAVAILABLE: 13000 statestring = "terminated"; 13001 local_state = NOTIFY_CLOSED; 13002 pidfstate = "away"; 13003 pidfnote = "Unavailable"; 13004 break; 13005 case AST_EXTENSION_ONHOLD: 13006 statestring = "confirmed"; 13007 local_state = NOTIFY_CLOSED; 13008 pidfstate = "busy"; 13009 pidfnote = "On hold"; 13010 break; 13011 case AST_EXTENSION_NOT_INUSE: 13012 default: 13013 /* Default setting */ 13014 break; 13015 } 13016 13017 /* Check which device/devices we are watching and if they are registered */ 13018 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten)) { 13019 char *hint2 = hint, *individual_hint = NULL; 13020 int hint_count = 0, unavailable_count = 0; 13021 13022 while ((individual_hint = strsep(&hint2, "&"))) { 13023 hint_count++; 13024 13025 if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE) 13026 unavailable_count++; 13027 } 13028 13029 /* If none of the hinted devices are registered, we will 13030 * override notification and show no availability. 13031 */ 13032 if (hint_count > 0 && hint_count == unavailable_count) { 13033 local_state = NOTIFY_CLOSED; 13034 pidfstate = "away"; 13035 pidfnote = "Not online"; 13036 } 13037 } 13038 13039 switch (subscribed) { 13040 case XPIDF_XML: 13041 case CPIM_PIDF_XML: 13042 ast_str_append(tmp, 0, 13043 "<?xml version=\"1.0\"?>\n" 13044 "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n" 13045 "<presence>\n"); 13046 ast_str_append(tmp, 0, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom); 13047 ast_str_append(tmp, 0, "<atom id=\"%s\">\n", exten); 13048 ast_str_append(tmp, 0, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto); 13049 ast_str_append(tmp, 0, "<status status=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed"); 13050 ast_str_append(tmp, 0, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline"); 13051 ast_str_append(tmp, 0, "</address>\n</atom>\n</presence>\n"); 13052 break; 13053 case PIDF_XML: /* Eyebeam supports this format */ 13054 ast_str_append(tmp, 0, 13055 "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n" 13056 "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \nxmlns:pp=\"urn:ietf:params:xml:ns:pidf:person\"\nxmlns:es=\"urn:ietf:params:xml:ns:pidf:rpid:status:rpid-status\"\nxmlns:ep=\"urn:ietf:params:xml:ns:pidf:rpid:rpid-person\"\nentity=\"%s\">\n", mfrom); 13057 ast_str_append(tmp, 0, "<pp:person><status>\n"); 13058 if (pidfstate[0] != '-') { 13059 ast_str_append(tmp, 0, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate); 13060 } 13061 ast_str_append(tmp, 0, "</status></pp:person>\n"); 13062 ast_str_append(tmp, 0, "<note>%s</note>\n", pidfnote); /* Note */ 13063 ast_str_append(tmp, 0, "<tuple id=\"%s\">\n", exten); /* Tuple start */ 13064 ast_str_append(tmp, 0, "<contact priority=\"1\">%s</contact>\n", mto); 13065 if (pidfstate[0] == 'b') /* Busy? Still open ... */ 13066 ast_str_append(tmp, 0, "<status><basic>open</basic></status>\n"); 13067 else 13068 ast_str_append(tmp, 0, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed"); 13069 ast_str_append(tmp, 0, "</tuple>\n</presence>\n"); 13070 break; 13071 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 13072 ast_str_append(tmp, 0, "<?xml version=\"1.0\"?>\n"); 13073 ast_str_append(tmp, 0, "<dialog-info xmlns=\"urn:ietf:params:xml:ns:dialog-info\" version=\"%u\" state=\"%s\" entity=\"%s\">\n", p->dialogver, full ? "full" : "partial", mto); 13074 13075 if ((state & AST_EXTENSION_RINGING) && sip_cfg.notifyringing) { 13076 /* Twice the extension length should be enough for XML encoding */ 13077 char local_display[AST_MAX_EXTENSION * 2]; 13078 char remote_display[AST_MAX_EXTENSION * 2]; 13079 char *local_target = ast_strdupa(mto); 13080 /* It may seem odd to base the remote_target on the To header here, 13081 * but testing by reporters on issue ASTERISK-16735 found that basing 13082 * on the From header would cause ringing state hints to not work 13083 * properly on certain SNOM devices. If you are using notifycid properly 13084 * (i.e. in the same extension and context as the dialed call) then this 13085 * should not be an issue since the data will be overwritten shortly 13086 * with channel caller ID 13087 */ 13088 char *remote_target = ast_strdupa(mto); 13089 13090 ast_xml_escape(exten, local_display, sizeof(local_display)); 13091 ast_xml_escape(exten, remote_display, sizeof(remote_display)); 13092 13093 /* There are some limitations to how this works. The primary one is that the 13094 callee must be dialing the same extension that is being monitored. Simply dialing 13095 the hint'd device is not sufficient. */ 13096 if (sip_cfg.notifycid) { 13097 struct ast_channel *caller; 13098 13099 if ((caller = ast_channel_callback(find_calling_channel, NULL, p, 0))) { 13100 static char *anonymous = "anonymous"; 13101 static char *invalid = "anonymous.invalid"; 13102 char *cid_num; 13103 char *connected_num; 13104 int need; 13105 int cid_num_restricted, connected_num_restricted; 13106 13107 ast_channel_lock(caller); 13108 13109 cid_num_restricted = (caller->caller.id.number.presentation & 13110 AST_PRES_RESTRICTION) == AST_PRES_RESTRICTED; 13111 cid_num = S_COR(caller->caller.id.number.valid, 13112 S_COR(cid_num_restricted, anonymous, 13113 caller->caller.id.number.str), ""); 13114 13115 need = strlen(cid_num) + (cid_num_restricted ? strlen(invalid) : 13116 strlen(p->fromdomain)) + sizeof("sip:@"); 13117 13118 remote_target = ast_alloca(need); 13119 snprintf(remote_target, need, "sip:%s@%s", cid_num, 13120 cid_num_restricted ? invalid : p->fromdomain); 13121 13122 ast_xml_escape(S_COR(caller->caller.id.name.valid, 13123 S_COR((caller->caller.id.name.presentation & 13124 AST_PRES_RESTRICTION) == AST_PRES_RESTRICTED, anonymous, 13125 caller->caller.id.name.str), ""), 13126 remote_display, sizeof(remote_display)); 13127 13128 connected_num_restricted = (caller->connected.id.number.presentation & 13129 AST_PRES_RESTRICTION) == AST_PRES_RESTRICTED; 13130 connected_num = S_COR(caller->connected.id.number.valid, 13131 S_COR(connected_num_restricted, anonymous, 13132 caller->connected.id.number.str), ""); 13133 13134 need = strlen(connected_num) + (connected_num_restricted ? strlen(invalid) : 13135 strlen(p->fromdomain)) + sizeof("sip:@"); 13136 local_target = ast_alloca(need); 13137 13138 snprintf(local_target, need, "sip:%s@%s", connected_num, 13139 connected_num_restricted ? invalid : p->fromdomain); 13140 13141 ast_xml_escape(S_COR(caller->connected.id.name.valid, 13142 S_COR((caller->connected.id.name.presentation & 13143 AST_PRES_RESTRICTION) == AST_PRES_RESTRICTED, anonymous, 13144 caller->connected.id.name.str), ""), 13145 local_display, sizeof(local_display)); 13146 13147 ast_channel_unlock(caller); 13148 caller = ast_channel_unref(caller); 13149 } 13150 13151 /* We create a fake call-id which the phone will send back in an INVITE 13152 Replaces header which we can grab and do some magic with. */ 13153 if (sip_cfg.pedanticsipchecking) { 13154 ast_str_append(tmp, 0, "<dialog id=\"%s\" call-id=\"pickup-%s\" local-tag=\"%s\" remote-tag=\"%s\" direction=\"recipient\">\n", 13155 exten, p->callid, p->theirtag, p->tag); 13156 } else { 13157 ast_str_append(tmp, 0, "<dialog id=\"%s\" call-id=\"pickup-%s\" direction=\"recipient\">\n", 13158 exten, p->callid); 13159 } 13160 ast_str_append(tmp, 0, 13161 "<remote>\n" 13162 /* See the limitations of this above. Luckily the phone seems to still be 13163 happy when these values are not correct. */ 13164 "<identity display=\"%s\">%s</identity>\n" 13165 "<target uri=\"%s\"/>\n" 13166 "</remote>\n" 13167 "<local>\n" 13168 "<identity display=\"%s\">%s</identity>\n" 13169 "<target uri=\"%s\"/>\n" 13170 "</local>\n", 13171 remote_display, remote_target, remote_target, local_display, local_target, local_target); 13172 } else { 13173 ast_str_append(tmp, 0, "<dialog id=\"%s\" direction=\"recipient\">\n", exten); 13174 } 13175 13176 } else { 13177 ast_str_append(tmp, 0, "<dialog id=\"%s\">\n", exten); 13178 } 13179 ast_str_append(tmp, 0, "<state>%s</state>\n", statestring); 13180 if (state == AST_EXTENSION_ONHOLD) { 13181 ast_str_append(tmp, 0, "<local>\n<target uri=\"%s\">\n" 13182 "<param pname=\"+sip.rendering\" pvalue=\"no\"/>\n" 13183 "</target>\n</local>\n", mto); 13184 } 13185 ast_str_append(tmp, 0, "</dialog>\n</dialog-info>\n"); 13186 break; 13187 case NONE: 13188 default: 13189 break; 13190 } 13191 }
| static const char* stmode2str | ( | enum st_mode | m | ) | [static] |
Definition at line 17011 of file chan_sip.c.
References map_x_s().
Referenced by _sip_show_peer(), sip_show_channel(), sip_show_settings(), and sip_show_user().
| static void stop_media_flows | ( | struct sip_pvt * | p | ) | [static] |
Immediately stop RTP, VRTP and UDPTL as applicable.
Definition at line 21692 of file chan_sip.c.
References ast_rtp_instance_stop(), and ast_udptl_stop().
Referenced by __sip_autodestruct(), handle_request_bye(), handle_request_cancel(), handle_response(), and sip_hangup().
21693 { 21694 /* Immediately stop RTP, VRTP and UDPTL as applicable */ 21695 if (p->rtp) 21696 ast_rtp_instance_stop(p->rtp); 21697 if (p->vrtp) 21698 ast_rtp_instance_stop(p->vrtp); 21699 if (p->trtp) 21700 ast_rtp_instance_stop(p->trtp); 21701 if (p->udptl) 21702 ast_udptl_stop(p->udptl); 21703 }
| static void stop_session_timer | ( | struct sip_pvt * | p | ) | [static] |
Session-Timers: Stop session timer.
Definition at line 26733 of file chan_sip.c.
References ast_debug, AST_SCHED_DEL_UNREF, FALSE, and TRUE.
Referenced by __sip_destroy(), dialog_unlink_all(), handle_request_bye(), proc_session_timer(), sip_hangup(), and sip_scheddestroy().
26734 { 26735 if (p->stimer->st_active == TRUE) { 26736 p->stimer->st_active = FALSE; 26737 ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid); 26738 AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid, 26739 dialog_unref(p, "removing session timer ref")); 26740 } 26741 }
| static int str2dtmfmode | ( | const char * | str | ) | [static] |
| static enum st_mode str2stmode | ( | const char * | s | ) | [static] |
Definition at line 17016 of file chan_sip.c.
References map_s_x().
Referenced by build_peer(), and reload_config().
| static enum st_refresher str2strefresherparam | ( | const char * | s | ) | [static] |
Definition at line 17041 of file chan_sip.c.
References map_s_x().
Referenced by build_peer(), and reload_config().
17042 { 17043 return map_s_x(strefresher_params, s, -1); 17044 }
| static const char* strefresher2str | ( | enum st_refresher | r | ) | [static] |
Definition at line 17046 of file chan_sip.c.
References map_x_s().
Referenced by sip_show_channel().
17047 { 17048 return map_x_s(strefreshers, r, "Unknown"); 17049 }
| static const char * strefresherparam2str | ( | enum st_refresher | r | ) | [static] |
Definition at line 17036 of file chan_sip.c.
References map_x_s().
Referenced by _sip_show_peer(), sip_show_channel(), sip_show_settings(), and sip_show_user().
17037 { 17038 return map_x_s(strefresher_params, r, "Unknown"); 17039 }
| static const char * subscription_type2str | ( | enum subscriptiontype | subtype | ) | [static] |
Show subscription type in string format.
Definition at line 18944 of file chan_sip.c.
References ARRAY_LEN, subscription_types, cfsubscription_types::text, and type.
Referenced by show_channels_cb(), and sip_show_channel().
18945 { 18946 int i; 18947 18948 for (i = 1; i < ARRAY_LEN(subscription_types); i++) { 18949 if (subscription_types[i].type == subtype) { 18950 return subscription_types[i].text; 18951 } 18952 } 18953 return subscription_types[0].text; 18954 }
| static unsigned int t38_get_rate | ( | enum ast_control_t38_rate | rate | ) | [static] |
Get Max T.38 Transmission rate from T38 capabilities.
Definition at line 11502 of file chan_sip.c.
References AST_T38_RATE_12000, AST_T38_RATE_14400, AST_T38_RATE_2400, AST_T38_RATE_4800, AST_T38_RATE_7200, and AST_T38_RATE_9600.
Referenced by add_sdp().
11503 { 11504 switch (rate) { 11505 case AST_T38_RATE_2400: 11506 return 2400; 11507 case AST_T38_RATE_4800: 11508 return 4800; 11509 case AST_T38_RATE_7200: 11510 return 7200; 11511 case AST_T38_RATE_9600: 11512 return 9600; 11513 case AST_T38_RATE_12000: 11514 return 12000; 11515 case AST_T38_RATE_14400: 11516 return 14400; 11517 default: 11518 return 0; 11519 } 11520 }
| static void tcptls_packet_destructor | ( | void * | obj | ) | [static] |
Definition at line 2342 of file chan_sip.c.
References ast_free.
Referenced by sip_tcptls_write().
02343 { 02344 struct tcptls_packet *packet = obj; 02345 02346 ast_free(packet->data); 02347 }
| static struct sip_peer * temp_peer | ( | const char * | name | ) | [static, read] |
Create temporary peer (used in autocreatepeer mode).
Definition at line 27983 of file chan_sip.c.
References ao2_t_alloc, ao2_t_ref, ast_atomic_fetchadd_int(), ast_cc_config_params_init, ast_copy_string(), ast_string_field_init, default_prefs, reg_source_db(), set_peer_defaults(), sip_destroy_peer_fn(), and TRUE.
Referenced by load_module(), register_verify(), and sip_reload().
27984 { 27985 struct sip_peer *peer; 27986 27987 if (!(peer = ao2_t_alloc(sizeof(*peer), sip_destroy_peer_fn, "allocate a peer struct"))) 27988 return NULL; 27989 27990 if (ast_string_field_init(peer, 512)) { 27991 ao2_t_ref(peer, -1, "failed to string_field_init, drop peer"); 27992 return NULL; 27993 } 27994 27995 if (!(peer->cc_params = ast_cc_config_params_init())) { 27996 ao2_t_ref(peer, -1, "failed to allocate cc_params for peer"); 27997 return NULL; 27998 } 27999 28000 ast_atomic_fetchadd_int(&apeerobjs, 1); 28001 set_peer_defaults(peer); 28002 28003 ast_copy_string(peer->name, name, sizeof(peer->name)); 28004 28005 peer->selfdestruct = TRUE; 28006 peer->host_dynamic = TRUE; 28007 peer->prefs = default_prefs; 28008 reg_source_db(peer); 28009 28010 return peer; 28011 }
| static void temp_pvt_cleanup | ( | void * | data | ) | [static] |
Definition at line 10923 of file chan_sip.c.
References ast_free, and ast_string_field_free_memory.
10924 { 10925 struct sip_pvt *p = data; 10926 10927 ast_string_field_free_memory(p); 10928 10929 ast_free(data); 10930 }
| static int temp_pvt_init | ( | void * | data | ) | [static] |
Definition at line 10915 of file chan_sip.c.
References ast_string_field_init.
10916 { 10917 struct sip_pvt *p = data; 10918 10919 p->do_history = 0; /* XXX do we need it ? isn't already all 0 ? */ 10920 return ast_string_field_init(p, 512); 10921 }
| static char* terminate_uri | ( | char * | uri | ) | [static] |
Terminate the uri at the first ';' or space. Technically we should ignore escaped space per RFC3261 (19.1.1 etc) but don't do it for the time being. Remember the uri format is: (User-parameters was added after RFC 3261)
* * sip:user:password;user-parameters@host:port;uri-parameters?headers * sips:user:password;user-parameters@host:port;uri-parameters?headers * *
Definition at line 15235 of file chan_sip.c.
Referenced by check_user_full(), and register_verify().
| static int threadinfo_locate_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 26226 of file chan_sip.c.
References ast_sockaddr_cmp(), CMP_MATCH, and CMP_STOP.
Referenced by sip_tcp_locate().
26227 { 26228 struct sip_threadinfo *th = obj; 26229 struct ast_sockaddr *s = arg; 26230 26231 if (!ast_sockaddr_cmp(s, &th->tcptls_session->remote_address)) { 26232 return CMP_MATCH | CMP_STOP; 26233 } 26234 26235 return 0; 26236 }
| static int threadt_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 30790 of file chan_sip.c.
References CMP_MATCH, and CMP_STOP.
Referenced by load_module().
| static int threadt_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 30783 of file chan_sip.c.
References ast_sockaddr_hash().
Referenced by load_module().
30784 { 30785 const struct sip_threadinfo *th = obj; 30786 30787 return ast_sockaddr_hash(&th->tcptls_session->remote_address); 30788 }
| static char * transfermode2str | ( | enum transfermodes | mode | ) | [static] |
Convert transfer mode to text string.
Definition at line 16989 of file chan_sip.c.
Referenced by _sip_show_peer(), peers_data_provider_get(), sip_show_channel(), sip_show_settings(), and sip_show_user().
| static int transmit_cc_notify | ( | struct ast_cc_agent * | agent, | |
| struct sip_pvt * | subscription, | |||
| enum sip_cc_notify_state | state | |||
| ) | [static] |
Definition at line 13193 of file chan_sip.c.
References add_content(), add_header(), ast_log(), generate_uri(), LOG_WARNING, ast_cc_agent::private_data, reqprep(), send_request(), sip_cc_notify_state_map, state_string, and TRUE.
Referenced by sip_cc_agent_recall(), and sip_cc_agent_respond().
13194 { 13195 struct sip_request req; 13196 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 13197 char uri[SIPBUFSIZE]; 13198 char state_str[64]; 13199 char subscription_state_hdr[64]; 13200 13201 if (state < CC_QUEUED || state > CC_READY) { 13202 ast_log(LOG_WARNING, "Invalid state provided for transmit_cc_notify (%u)\n", state); 13203 return -1; 13204 } 13205 13206 reqprep(&req, subscription, SIP_NOTIFY, 0, TRUE); 13207 snprintf(state_str, sizeof(state_str), "%s\r\n", sip_cc_notify_state_map[state].state_string); 13208 add_header(&req, "Event", "call-completion"); 13209 add_header(&req, "Content-Type", "application/call-completion"); 13210 snprintf(subscription_state_hdr, sizeof(subscription_state_hdr), "active;expires=%d", subscription->expiry); 13211 add_header(&req, "Subscription-State", subscription_state_hdr); 13212 if (state == CC_READY) { 13213 generate_uri(subscription, agent_pvt->notify_uri, sizeof(agent_pvt->notify_uri)); 13214 snprintf(uri, sizeof(uri) - 1, "cc-URI: %s\r\n", agent_pvt->notify_uri); 13215 } 13216 add_content(&req, state_str); 13217 if (state == CC_READY) { 13218 add_content(&req, uri); 13219 } 13220 return send_request(subscription, &req, XMIT_RELIABLE, subscription->ocseq); 13221 }
| static void transmit_fake_auth_response | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| enum xmittype | reliable | |||
| ) | [static] |
Send a fake 401 Unauthorized response when the administrator wants to hide the names of local devices from fishers.
Definition at line 15134 of file chan_sip.c.
References __transmit_response(), AST_DYNSTR_BUILD_FAILED, ast_skip_blanks(), ast_str_set(), ast_str_thread_get(), ast_strlen_zero(), CHECK_AUTH_BUF_INITLEN, FALSE, get_header(), set_nonce_randdata(), sip_scheddestroy(), and transmit_response_with_auth().
Referenced by register_verify().
15135 { 15136 /* We have to emulate EXACTLY what we'd get with a good peer 15137 * and a bad password, or else we leak information. */ 15138 const char *response = "401 Unauthorized"; 15139 const char *reqheader = "Authorization"; 15140 const char *respheader = "WWW-Authenticate"; 15141 const char *authtoken; 15142 struct ast_str *buf; 15143 char *c; 15144 15145 /* table of recognised keywords, and their value in the digest */ 15146 enum keys { K_NONCE, K_LAST }; 15147 struct x { 15148 const char *key; 15149 const char *s; 15150 } *i, keys[] = { 15151 [K_NONCE] = { "nonce=", "" }, 15152 [K_LAST] = { NULL, NULL} 15153 }; 15154 15155 authtoken = get_header(req, reqheader); 15156 if (req->ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 15157 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 15158 * information */ 15159 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 15160 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 15161 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15162 return; 15163 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 15164 /* We have no auth, so issue challenge and request authentication */ 15165 set_nonce_randdata(p, 1); 15166 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 15167 /* Schedule auto destroy in 32 seconds */ 15168 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15169 return; 15170 } 15171 15172 if (!(buf = ast_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) { 15173 __transmit_response(p, "403 Forbidden", &p->initreq, reliable); 15174 return; 15175 } 15176 15177 /* Make a copy of the response and parse it */ 15178 if (ast_str_set(&buf, 0, "%s", authtoken) == AST_DYNSTR_BUILD_FAILED) { 15179 __transmit_response(p, "403 Forbidden", &p->initreq, reliable); 15180 return; 15181 } 15182 15183 c = buf->str; 15184 15185 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 15186 for (i = keys; i->key != NULL; i++) { 15187 const char *separator = ","; /* default */ 15188 15189 if (strncasecmp(c, i->key, strlen(i->key)) != 0) { 15190 continue; 15191 } 15192 /* Found. Skip keyword, take text in quotes or up to the separator. */ 15193 c += strlen(i->key); 15194 if (*c == '"') { /* in quotes. Skip first and look for last */ 15195 c++; 15196 separator = "\""; 15197 } 15198 i->s = c; 15199 strsep(&c, separator); 15200 break; 15201 } 15202 if (i->key == NULL) { /* not found, jump after space or comma */ 15203 strsep(&c, " ,"); 15204 } 15205 } 15206 15207 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 15208 if (strcasecmp(p->randdata, keys[K_NONCE].s)) { 15209 if (!req->ignore) { 15210 set_nonce_randdata(p, 1); 15211 } 15212 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 15213 15214 /* Schedule auto destroy in 32 seconds */ 15215 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15216 } else { 15217 __transmit_response(p, "403 Forbidden", &p->initreq, reliable); 15218 } 15219 }
| static int transmit_info_with_aoc | ( | struct sip_pvt * | p, | |
| struct ast_aoc_decoded * | decoded | |||
| ) | [static] |
Send SIP INFO advice of charge message.
Definition at line 14048 of file chan_sip.c.
References add_header(), ast_aoc_unit_entry::amount, AST_AOC_CHARGE_CURRENCY, AST_AOC_CHARGE_FREE, AST_AOC_CHARGE_UNIT, AST_AOC_D, AST_AOC_E, ast_aoc_get_charge_type(), ast_aoc_get_currency_amount(), ast_aoc_get_currency_multiplier_decimal(), ast_aoc_get_currency_name(), ast_aoc_get_msg_type(), ast_aoc_get_unit_info(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_strlen_zero(), reqprep(), send_request(), and str.
Referenced by sip_indicate().
14049 { 14050 struct sip_request req; 14051 struct ast_str *str = ast_str_alloca(512); 14052 const struct ast_aoc_unit_entry *unit_entry = ast_aoc_get_unit_info(decoded, 0); 14053 enum ast_aoc_charge_type charging = ast_aoc_get_charge_type(decoded); 14054 14055 reqprep(&req, p, SIP_INFO, 0, 1); 14056 14057 if (ast_aoc_get_msg_type(decoded) == AST_AOC_D) { 14058 ast_str_append(&str, 0, "type=active;"); 14059 } else if (ast_aoc_get_msg_type(decoded) == AST_AOC_E) { 14060 ast_str_append(&str, 0, "type=terminated;"); 14061 } else { 14062 /* unsupported message type */ 14063 return -1; 14064 } 14065 14066 switch (charging) { 14067 case AST_AOC_CHARGE_FREE: 14068 ast_str_append(&str, 0, "free-of-charge;"); 14069 break; 14070 case AST_AOC_CHARGE_CURRENCY: 14071 ast_str_append(&str, 0, "charging;"); 14072 ast_str_append(&str, 0, "charging-info=currency;"); 14073 ast_str_append(&str, 0, "amount=%u;", ast_aoc_get_currency_amount(decoded)); 14074 ast_str_append(&str, 0, "multiplier=%s;", ast_aoc_get_currency_multiplier_decimal(decoded)); 14075 if (!ast_strlen_zero(ast_aoc_get_currency_name(decoded))) { 14076 ast_str_append(&str, 0, "currency=%s;", ast_aoc_get_currency_name(decoded)); 14077 } 14078 break; 14079 case AST_AOC_CHARGE_UNIT: 14080 ast_str_append(&str, 0, "charging;"); 14081 ast_str_append(&str, 0, "charging-info=pulse;"); 14082 if (unit_entry) { 14083 ast_str_append(&str, 0, "recorded-units=%u;", unit_entry->amount); 14084 } 14085 break; 14086 default: 14087 ast_str_append(&str, 0, "not-available;"); 14088 }; 14089 14090 add_header(&req, "AOC", ast_str_buffer(str)); 14091 14092 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 14093 }
| static int transmit_info_with_digit | ( | struct sip_pvt * | p, | |
| const char | digit, | |||
| unsigned int | duration | |||
| ) | [static] |
Send SIP INFO dtmf message, see Cisco documentation on cisco.com.
Definition at line 14096 of file chan_sip.c.
References add_digit(), ast_test_flag, reqprep(), and send_request().
Referenced by sip_senddigit_end().
14097 { 14098 struct sip_request req; 14099 14100 reqprep(&req, p, SIP_INFO, 0, 1); 14101 add_digit(&req, digit, duration, (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_SHORTINFO)); 14102 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 14103 }
| static int transmit_info_with_vidupdate | ( | struct sip_pvt * | p | ) | [static] |
Send SIP INFO with video update request.
Definition at line 14106 of file chan_sip.c.
References add_vidupdate(), reqprep(), and send_request().
Referenced by sip_indicate().
14107 { 14108 struct sip_request req; 14109 14110 reqprep(&req, p, SIP_INFO, 0, 1); 14111 add_vidupdate(&req); 14112 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 14113 }
| static int transmit_invite | ( | struct sip_pvt * | p, | |
| int | sipmethod, | |||
| int | sdp, | |||
| int | init, | |||
| const char *const | explicit_uri | |||
| ) | [static] |
Build REFER/INVITE/OPTIONS/SUBSCRIBE message and transmit it.
| p | sip_pvt structure | |
| sipmethod | ||
| sdp | unknown | |
| init | 0 = Prepare request within dialog, 1= prepare request, new branch, 2= prepare new request and new dialog. do_proxy_auth calls this with init!=2 | |
| explicit_uri |
Definition at line 12610 of file chan_sip.c.
References add_content(), add_diversion_header(), add_header(), add_rpid(), add_sdp(), add_supported_header(), append_date(), ast_channel_lock, ast_channel_unlock, ast_debug, AST_LIST_TRAVERSE, ast_log(), ast_random(), ast_skip_blanks(), ast_str_buffer(), ast_str_strlen(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_var_name(), ast_var_value(), build_via(), FALSE, initialize_initreq(), initreqprep(), LOG_WARNING, ast_variable::name, ast_variable::next, reqprep(), send_request(), st_get_mode(), st_get_se(), TRUE, try_suggested_sip_codec(), ast_variable::value, var, and ast_channel::varshead.
Referenced by __sip_subscribe_mwi_do(), cc_handle_publish_error(), do_proxy_auth(), manager_sipnotify(), proc_422_rsp(), sip_call(), sip_cc_monitor_request_cc(), sip_cli_notify(), sip_monitor_instance_destructor(), sip_poke_peer(), and transmit_publish().
12611 { 12612 struct sip_request req; 12613 struct ast_variable *var; 12614 12615 if (init) {/* Bump branch even on initial requests */ 12616 p->branch ^= ast_random(); 12617 p->invite_branch = p->branch; 12618 build_via(p); 12619 } 12620 if (init > 1) { 12621 initreqprep(&req, p, sipmethod, explicit_uri); 12622 } else { 12623 /* If init=1, we should not generate a new branch. If it's 0, we need a new branch. */ 12624 reqprep(&req, p, sipmethod, 0, init ? 0 : 1); 12625 } 12626 12627 if (p->options && p->options->auth) { 12628 add_header(&req, p->options->authheader, p->options->auth); 12629 } 12630 append_date(&req); 12631 if (sipmethod == SIP_REFER) { /* Call transfer */ 12632 if (p->refer) { 12633 char buf[SIPBUFSIZE]; 12634 if (!ast_strlen_zero(p->refer->refer_to)) { 12635 add_header(&req, "Refer-To", p->refer->refer_to); 12636 } 12637 if (!ast_strlen_zero(p->refer->referred_by)) { 12638 snprintf(buf, sizeof(buf), "%s <%s>", p->refer->referred_by_name, p->refer->referred_by); 12639 add_header(&req, "Referred-By", buf); 12640 } 12641 } 12642 } else if (sipmethod == SIP_SUBSCRIBE) { 12643 char buf[SIPBUFSIZE]; 12644 if (p->subscribed == MWI_NOTIFICATION) { 12645 add_header(&req, "Event", "message-summary"); 12646 add_header(&req, "Accept", "application/simple-message-summary"); 12647 } else if (p->subscribed == CALL_COMPLETION) { 12648 add_header(&req, "Event", "call-completion"); 12649 add_header(&req, "Accept", "application/call-completion"); 12650 } 12651 snprintf(buf, sizeof(buf), "%d", p->expiry); 12652 add_header(&req, "Expires", buf); 12653 } 12654 12655 /* This new INVITE is part of an attended transfer. Make sure that the 12656 other end knows and replace the current call with this new call */ 12657 if (p->options && !ast_strlen_zero(p->options->replaces)) { 12658 add_header(&req, "Replaces", p->options->replaces); 12659 add_header(&req, "Require", "replaces"); 12660 } 12661 12662 /* Add Session-Timers related headers */ 12663 if (st_get_mode(p, 0) == SESSION_TIMER_MODE_ORIGINATE 12664 || (st_get_mode(p, 0) == SESSION_TIMER_MODE_ACCEPT 12665 && st_get_se(p, FALSE) != DEFAULT_MIN_SE)) { 12666 char i2astr[10]; 12667 12668 if (!p->stimer->st_interval) { 12669 p->stimer->st_interval = st_get_se(p, TRUE); 12670 } 12671 12672 p->stimer->st_active = TRUE; 12673 if (st_get_mode(p, 0) == SESSION_TIMER_MODE_ORIGINATE) { 12674 snprintf(i2astr, sizeof(i2astr), "%d", p->stimer->st_interval); 12675 add_header(&req, "Session-Expires", i2astr); 12676 } 12677 12678 snprintf(i2astr, sizeof(i2astr), "%d", st_get_se(p, FALSE)); 12679 add_header(&req, "Min-SE", i2astr); 12680 } 12681 12682 add_header(&req, "Allow", ALLOWED_METHODS); 12683 add_supported_header(p, &req); 12684 12685 if (p->options && p->options->addsipheaders && p->owner) { 12686 struct ast_channel *chan = p->owner; /* The owner channel */ 12687 struct varshead *headp; 12688 12689 ast_channel_lock(chan); 12690 12691 headp = &chan->varshead; 12692 12693 if (!headp) { 12694 ast_log(LOG_WARNING, "No Headp for the channel...ooops!\n"); 12695 } else { 12696 const struct ast_var_t *current; 12697 AST_LIST_TRAVERSE(headp, current, entries) { 12698 /* SIPADDHEADER: Add SIP header to outgoing call */ 12699 if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 12700 char *content, *end; 12701 const char *header = ast_var_value(current); 12702 char *headdup = ast_strdupa(header); 12703 12704 /* Strip of the starting " (if it's there) */ 12705 if (*headdup == '"') { 12706 headdup++; 12707 } 12708 if ((content = strchr(headdup, ':'))) { 12709 *content++ = '\0'; 12710 content = ast_skip_blanks(content); /* Skip white space */ 12711 /* Strip the ending " (if it's there) */ 12712 end = content + strlen(content) -1; 12713 if (*end == '"') { 12714 *end = '\0'; 12715 } 12716 12717 add_header(&req, headdup, content); 12718 if (sipdebug) { 12719 ast_debug(1, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content); 12720 } 12721 } 12722 } 12723 } 12724 } 12725 12726 ast_channel_unlock(chan); 12727 } 12728 if ((sipmethod == SIP_INVITE || sipmethod == SIP_UPDATE) && ast_test_flag(&p->flags[0], SIP_SENDRPID)) 12729 add_rpid(&req, p); 12730 if (sipmethod == SIP_INVITE) { 12731 add_diversion_header(&req, p); 12732 } 12733 if (sdp) { 12734 memset(p->offered_media, 0, sizeof(p->offered_media)); 12735 if (p->udptl && p->t38.state == T38_LOCAL_REINVITE) { 12736 ast_debug(1, "T38 is in state %u on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12737 add_sdp(&req, p, FALSE, FALSE, TRUE); 12738 } else if (p->rtp) { 12739 try_suggested_sip_codec(p); 12740 add_sdp(&req, p, FALSE, TRUE, FALSE); 12741 } 12742 } else if (p->notify) { 12743 for (var = p->notify->headers; var; var = var->next) { 12744 add_header(&req, var->name, var->value); 12745 } 12746 if (ast_str_strlen(p->notify->content)) { 12747 add_content(&req, ast_str_buffer(p->notify->content)); 12748 } 12749 } else if (sipmethod == SIP_PUBLISH) { 12750 char expires[SIPBUFSIZE]; 12751 12752 switch (p->epa_entry->static_data->event) { 12753 case CALL_COMPLETION: 12754 snprintf(expires, sizeof(expires), "%d", p->expiry); 12755 add_header(&req, "Event", "call-completion"); 12756 add_header(&req, "Expires", expires); 12757 if (p->epa_entry->publish_type != SIP_PUBLISH_INITIAL) { 12758 add_header(&req, "SIP-If-Match", p->epa_entry->entity_tag); 12759 } 12760 12761 if (!ast_strlen_zero(p->epa_entry->body)) { 12762 add_header(&req, "Content-Type", "application/pidf+xml"); 12763 add_content(&req, p->epa_entry->body); 12764 } 12765 default: 12766 break; 12767 } 12768 } 12769 12770 if (!p->initreq.headers || init > 2) { 12771 initialize_initreq(p, &req); 12772 } 12773 if (sipmethod == SIP_INVITE || sipmethod == SIP_SUBSCRIBE) { 12774 p->lastinvite = p->ocseq; 12775 } 12776 return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq); 12777 }
| static int transmit_message_with_text | ( | struct sip_pvt * | p, | |
| const char * | text | |||
| ) | [static] |
Transmit text with SIP MESSAGE method.
Definition at line 13944 of file chan_sip.c.
References add_text(), reqprep(), and send_request().
Referenced by sip_park_thread(), and sip_sendtext().
13945 { 13946 struct sip_request req; 13947 13948 reqprep(&req, p, SIP_MESSAGE, 0, 1); 13949 add_text(&req, text); 13950 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 13951 }
| static int transmit_notify_with_mwi | ( | struct sip_pvt * | p, | |
| int | newmsgs, | |||
| int | oldmsgs, | |||
| const char * | vmexten | |||
| ) | [static] |
Notify user of messages waiting in voicemail (RFC3842).
Definition at line 13331 of file chan_sip.c.
References add_content(), add_header(), ast_sockaddr_port, ast_sockaddr_stringify_host_remote(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_test_flag, exten, get_transport(), initialize_initreq(), initreqprep(), ourport, S_OR, send_request(), and sip_standard_port().
Referenced by sip_send_mwi_to_peer().
13332 { 13333 struct sip_request req; 13334 struct ast_str *out = ast_str_alloca(500); 13335 int ourport = (p->fromdomainport && (p->fromdomainport != STANDARD_SIP_PORT)) ? p->fromdomainport : ast_sockaddr_port(&p->ourip); 13336 const char *domain; 13337 const char *exten = S_OR(vmexten, default_vmexten); 13338 13339 initreqprep(&req, p, SIP_NOTIFY, NULL); 13340 add_header(&req, "Event", "message-summary"); 13341 add_header(&req, "Content-Type", default_notifymime); 13342 ast_str_append(&out, 0, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no"); 13343 13344 /* domain initialization occurs here because initreqprep changes ast_sockaddr_stringify string. */ 13345 domain = S_OR(p->fromdomain, ast_sockaddr_stringify_host_remote(&p->ourip)); 13346 13347 if (!sip_standard_port(p->socket.type, ourport)) { 13348 if (p->socket.type == SIP_TRANSPORT_UDP) { 13349 ast_str_append(&out, 0, "Message-Account: sip:%s@%s:%d\r\n", exten, domain, ourport); 13350 } else { 13351 ast_str_append(&out, 0, "Message-Account: sip:%s@%s:%d;transport=%s\r\n", exten, domain, ourport, get_transport(p->socket.type)); 13352 } 13353 } else { 13354 if (p->socket.type == SIP_TRANSPORT_UDP) { 13355 ast_str_append(&out, 0, "Message-Account: sip:%s@%s\r\n", exten, domain); 13356 } else { 13357 ast_str_append(&out, 0, "Message-Account: sip:%s@%s;transport=%s\r\n", exten, domain, get_transport(p->socket.type)); 13358 } 13359 } 13360 /* Cisco has a bug in the SIP stack where it can't accept the 13361 (0/0) notification. This can temporarily be disabled in 13362 sip.conf with the "buggymwi" option */ 13363 ast_str_append(&out, 0, "Voice-Message: %d/%d%s\r\n", 13364 newmsgs, oldmsgs, (ast_test_flag(&p->flags[1], SIP_PAGE2_BUGGY_MWI) ? "" : " (0/0)")); 13365 13366 if (p->subscribed) { 13367 if (p->expiry) { 13368 add_header(&req, "Subscription-State", "active"); 13369 } else { /* Expired */ 13370 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 13371 } 13372 } 13373 13374 add_content(&req, ast_str_buffer(out)); 13375 13376 if (!p->initreq.headers) { 13377 initialize_initreq(p, &req); 13378 } 13379 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 13380 }
| static int transmit_notify_with_sipfrag | ( | struct sip_pvt * | p, | |
| int | cseq, | |||
| char * | message, | |||
| int | terminate | |||
| ) | [static] |
Notify a transferring party of the status of transfer (RFC3515).
Definition at line 13383 of file chan_sip.c.
References add_content(), add_header(), add_supported_header(), initialize_initreq(), reqprep(), and send_request().
Referenced by handle_request_refer(), local_attended_transfer(), and sip_park_thread().
13384 { 13385 struct sip_request req; 13386 char tmp[SIPBUFSIZE/2]; 13387 13388 reqprep(&req, p, SIP_NOTIFY, 0, 1); 13389 snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq); 13390 add_header(&req, "Event", tmp); 13391 add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active"); 13392 add_header(&req, "Content-Type", "message/sipfrag;version=2.0"); 13393 add_header(&req, "Allow", ALLOWED_METHODS); 13394 add_supported_header(p, &req); 13395 13396 snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message); 13397 add_content(&req, tmp); 13398 13399 if (!p->initreq.headers) { 13400 initialize_initreq(p, &req); 13401 } 13402 13403 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 13404 }
| static int transmit_provisional_response | ( | struct sip_pvt * | p, | |
| const char * | msg, | |||
| const struct sip_request * | req, | |||
| int | with_sdp | |||
| ) | [static] |
Definition at line 11189 of file chan_sip.c.
References FALSE, transmit_response(), transmit_response_with_sdp(), and update_provisional_keepalive().
Referenced by handle_request_invite(), sip_indicate(), and sip_write().
11190 { 11191 int res; 11192 11193 if (!(res = with_sdp ? transmit_response_with_sdp(p, msg, req, XMIT_UNRELIABLE, FALSE, FALSE) : transmit_response(p, msg, req))) { 11194 p->last_provisional = msg; 11195 update_provisional_keepalive(p, with_sdp); 11196 } 11197 11198 return res; 11199 }
| static int transmit_publish | ( | struct sip_epa_entry * | epa_entry, | |
| enum sip_publish_type | publish_type, | |||
| const char *const | explicit_uri | |||
| ) | [static] |
Definition at line 12566 of file chan_sip.c.
References ao2_ref, ast_set_flag, ast_sip_ouraddrfor(), create_addr(), dialog_unlink_all(), FALSE, sip_alloc(), sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), transmit_invite(), and TRUE.
Referenced by handle_cc_notify(), sip_cc_monitor_suspend(), sip_cc_monitor_unsuspend(), and sip_monitor_instance_destructor().
12567 { 12568 struct sip_pvt *pvt; 12569 int expires; 12570 12571 epa_entry->publish_type = publish_type; 12572 12573 if (!(pvt = sip_alloc(NULL, NULL, 0, SIP_PUBLISH, NULL))) { 12574 return -1; 12575 } 12576 12577 sip_pvt_lock(pvt); 12578 12579 if (create_addr(pvt, epa_entry->destination, NULL, TRUE)) { 12580 sip_pvt_unlock(pvt); 12581 dialog_unlink_all(pvt); 12582 dialog_unref(pvt, "create_addr failed in transmit_publish. Unref dialog"); 12583 return -1; 12584 } 12585 ast_sip_ouraddrfor(&pvt->sa, &pvt->ourip, pvt); 12586 ast_set_flag(&pvt->flags[0], SIP_OUTGOING); 12587 expires = (publish_type == SIP_PUBLISH_REMOVE) ? 0 : DEFAULT_PUBLISH_EXPIRES; 12588 pvt->expiry = expires; 12589 12590 /* Bump refcount for sip_pvt's reference */ 12591 ao2_ref(epa_entry, +1); 12592 pvt->epa_entry = epa_entry; 12593 12594 transmit_invite(pvt, SIP_PUBLISH, FALSE, 2, explicit_uri); 12595 sip_pvt_unlock(pvt); 12596 sip_scheddestroy(pvt, DEFAULT_TRANS_TIMEOUT); 12597 dialog_unref(pvt, "Done with the sip_pvt allocated for transmitting PUBLISH"); 12598 return 0; 12599 }
| static int transmit_refer | ( | struct sip_pvt * | p, | |
| const char * | dest | |||
| ) | [static] |
Transmit SIP REFER message (initiated by the transfer() dialplan application.
Definition at line 13975 of file chan_sip.c.
References add_header(), add_supported_header(), ast_copy_string(), ast_debug, ast_log(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, FALSE, get_header(), get_in_brackets(), LOG_NOTICE, reqprep(), send_request(), sip_refer_allocate(), and TRUE.
Referenced by sip_transfer().
13976 { 13977 struct sip_request req = { 13978 .headers = 0, 13979 }; 13980 char from[256]; 13981 const char *of; 13982 char *c; 13983 char referto[256]; 13984 int use_tls=FALSE; 13985 13986 if (sipdebug) { 13987 ast_debug(1, "SIP transfer of %s to %s\n", p->callid, dest); 13988 } 13989 13990 /* Are we transfering an inbound or outbound call ? */ 13991 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 13992 of = get_header(&p->initreq, "To"); 13993 } else { 13994 of = get_header(&p->initreq, "From"); 13995 } 13996 13997 ast_copy_string(from, of, sizeof(from)); 13998 of = get_in_brackets(from); 13999 ast_string_field_set(p, from, of); 14000 if (!strncasecmp(of, "sip:", 4)) { 14001 of += 4; 14002 } else if (!strncasecmp(of, "sips:", 5)) { 14003 of += 5; 14004 use_tls = TRUE; 14005 } else { 14006 ast_log(LOG_NOTICE, "From address missing 'sip(s):', assuming sip:\n"); 14007 } 14008 /* Get just the username part */ 14009 if (strchr(dest, '@')) { 14010 c = NULL; 14011 } else if ((c = strchr(of, '@'))) { 14012 *c++ = '\0'; 14013 } 14014 if (c) { 14015 snprintf(referto, sizeof(referto), "<sip%s:%s@%s>", use_tls ? "s" : "", dest, c); 14016 } else { 14017 snprintf(referto, sizeof(referto), "<sip%s:%s>", use_tls ? "s" : "", dest); 14018 } 14019 14020 /* save in case we get 407 challenge */ 14021 sip_refer_allocate(p); 14022 ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to)); 14023 ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by)); 14024 p->refer->status = REFER_SENT; /* Set refer status */ 14025 14026 reqprep(&req, p, SIP_REFER, 0, 1); 14027 14028 add_header(&req, "Refer-To", referto); 14029 add_header(&req, "Allow", ALLOWED_METHODS); 14030 add_supported_header(p, &req); 14031 if (!ast_strlen_zero(p->our_contact)) { 14032 add_header(&req, "Referred-By", p->our_contact); 14033 } 14034 14035 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 14036 14037 /* We should propably wait for a NOTIFY here until we ack the transfer */ 14038 /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */ 14039 14040 /*! \todo In theory, we should hang around and wait for a reply, before 14041 returning to the dial plan here. Don't know really how that would 14042 affect the transfer() app or the pbx, but, well, to make this 14043 useful we should have a STATUS code on transfer(). 14044 */ 14045 }
| static int transmit_register | ( | struct sip_registry * | r, | |
| int | sipmethod, | |||
| const char * | auth, | |||
| const char * | authheader | |||
| ) | [static] |
Transmit register to SIP proxy or UA auth = NULL on the initial registration (from sip_reregister()).
Definition at line 13684 of file chan_sip.c.
References add_header(), add_header_max_forwards(), append_history, ast_debug, ast_dnsmgr_lookup_cb(), ast_log(), ast_random(), ast_sched_add(), AST_SCHED_REPLACE_UNREF, ast_set_flag, ast_sip_ouraddrfor(), ast_sockaddr_cmp(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_set_port, ast_string_field_set, ast_strlen_zero(), ast_verbose, build_callid_registry(), build_contact(), build_localtag_registry(), build_reply_digest(), build_via(), create_addr(), dialog_unlink_all(), exten, FALSE, find_peer(), get_address_family_filter(), get_srv_protocol(), get_srv_service(), init_req(), initialize_initreq(), internip, ast_tcptls_session_args::local_address, LOG_NOTICE, LOG_WARNING, MAXHOSTNAMELEN, obproxy_get(), on_dns_update_peer(), on_dns_update_registry(), REG_STATE_AUTHSENT, REG_STATE_REGSENT, registry_addref(), registry_unref(), S_OR, send_request(), set_socket_transport(), sip_alloc(), sip_cfg, sip_debug_test_pvt(), sip_methods, sip_reg_timeout(), sip_sanitized_host(), cfsip_methods::text, TRUE, and unref_peer().
Referenced by __sip_do_register(), do_register_auth(), handle_response_register(), and sip_reg_timeout().
13685 { 13686 struct sip_request req; 13687 char from[256]; 13688 char to[256]; 13689 char tmp[80]; 13690 char addr[80]; 13691 struct sip_pvt *p; 13692 struct sip_peer *peer = NULL; 13693 int res; 13694 int portno = 0; 13695 13696 /* exit if we are already in process with this registrar ?*/ 13697 if (r == NULL || ((auth == NULL) && (r->regstate == REG_STATE_REGSENT || r->regstate == REG_STATE_AUTHSENT))) { 13698 if (r) { 13699 ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname); 13700 } 13701 return 0; 13702 } 13703 13704 if (r->dnsmgr == NULL) { 13705 char transport[MAXHOSTNAMELEN]; 13706 peer = find_peer(r->hostname, NULL, TRUE, FINDPEERS, FALSE, 0); 13707 snprintf(transport, sizeof(transport), "_%s._%s",get_srv_service(r->transport), get_srv_protocol(r->transport)); /* have to use static get_transport function */ 13708 r->us.ss.ss_family = get_address_family_filter(r->transport); /* Filter address family */ 13709 13710 /* No point in doing a DNS lookup of the register hostname if we're just going to 13711 * end up using an outbound proxy. obproxy_get is safe to call with either of r->call 13712 * or peer NULL. Since we're only concerned with its existence, we're not going to 13713 * bother getting a ref to the proxy*/ 13714 if (!obproxy_get(r->call, peer)) { 13715 registry_addref(r, "add reg ref for dnsmgr"); 13716 ast_dnsmgr_lookup_cb(peer ? peer->tohost : r->hostname, &r->us, &r->dnsmgr, sip_cfg.srvlookup ? transport : NULL, on_dns_update_registry, r); 13717 if (!r->dnsmgr) { 13718 /*dnsmgr refresh disabled, no reference added! */ 13719 registry_unref(r, "remove reg ref, dnsmgr disabled"); 13720 } 13721 } 13722 if (peer) { 13723 peer = unref_peer(peer, "removing peer ref for dnsmgr_lookup"); 13724 } 13725 } 13726 13727 if (r->call) { /* We have a registration */ 13728 if (!auth) { 13729 ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname); 13730 return 0; 13731 } else { 13732 p = dialog_ref(r->call, "getting a copy of the r->call dialog in transmit_register"); 13733 ast_string_field_set(p, theirtag, NULL); /* forget their old tag, so we don't match tags when getting response */ 13734 } 13735 } else { 13736 /* Build callid for registration if we haven't registered before */ 13737 if (!r->callid_valid) { 13738 build_callid_registry(r, &internip, default_fromdomain); 13739 build_localtag_registry(r); 13740 r->callid_valid = TRUE; 13741 } 13742 /* Allocate SIP dialog for registration */ 13743 if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER, NULL))) { 13744 ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n"); 13745 return 0; 13746 } 13747 13748 /* reset tag to consistent value from registry */ 13749 ast_string_field_set(p, tag, r->localtag); 13750 13751 if (p->do_history) { 13752 append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname); 13753 } 13754 13755 p->socket.type = r->transport; 13756 13757 /* Use port number specified if no SRV record was found */ 13758 if (!ast_sockaddr_isnull(&r->us)) { 13759 if (!ast_sockaddr_port(&r->us) && r->portno) { 13760 ast_sockaddr_set_port(&r->us, r->portno); 13761 } 13762 13763 /* It is possible that DNS was unavailable at the time the peer was created. 13764 * Here, if we've updated the address in the registry via manually calling 13765 * ast_dnsmgr_lookup_cb() above, then we call the same function that dnsmgr would 13766 * call if it was updating a peer's address */ 13767 if ((peer = find_peer(S_OR(r->peername, r->hostname), NULL, TRUE, FINDPEERS, FALSE, 0))) { 13768 if (ast_sockaddr_cmp(&peer->addr, &r->us)) { 13769 on_dns_update_peer(&peer->addr, &r->us, peer); 13770 } 13771 peer = unref_peer(peer, "unref after find_peer"); 13772 } 13773 } 13774 13775 /* Find address to hostname */ 13776 if (create_addr(p, S_OR(r->peername, r->hostname), &r->us, 0)) { 13777 /* we have what we hope is a temporary network error, 13778 * probably DNS. We need to reschedule a registration try */ 13779 dialog_unlink_all(p); 13780 p = dialog_unref(p, "unref dialog after unlink_all"); 13781 if (r->timeout > -1) { 13782 AST_SCHED_REPLACE_UNREF(r->timeout, sched, global_reg_timeout * 1000, sip_reg_timeout, r, 13783 registry_unref(_data, "del for REPLACE of registry ptr"), 13784 registry_unref(r, "object ptr dec when SCHED_REPLACE add failed"), 13785 registry_addref(r,"add for REPLACE registry ptr")); 13786 ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout); 13787 } else { 13788 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, registry_addref(r, "add for REPLACE registry ptr")); 13789 ast_log(LOG_WARNING, "Probably a DNS error for registration to %s@%s, trying REGISTER again (after %d seconds)\n", r->username, r->hostname, global_reg_timeout); 13790 } 13791 r->regattempts++; 13792 return 0; 13793 } 13794 13795 /* Copy back Call-ID in case create_addr changed it */ 13796 ast_string_field_set(r, callid, p->callid); 13797 13798 if (!r->dnsmgr && r->portno) { 13799 ast_sockaddr_set_port(&p->sa, r->portno); 13800 ast_sockaddr_set_port(&p->recv, r->portno); 13801 } 13802 if (!ast_strlen_zero(p->fromdomain)) { 13803 portno = (p->fromdomainport) ? p->fromdomainport : STANDARD_SIP_PORT; 13804 } else if (!ast_strlen_zero(r->regdomain)) { 13805 portno = (r->regdomainport) ? r->regdomainport : STANDARD_SIP_PORT; 13806 } else { 13807 portno = ast_sockaddr_port(&p->sa); 13808 } 13809 13810 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */ 13811 r->call = dialog_ref(p, "copying dialog into registry r->call"); /* Save pointer to SIP dialog */ 13812 p->registry = registry_addref(r, "transmit_register: addref to p->registry in transmit_register"); /* Add pointer to registry in packet */ 13813 if (!ast_strlen_zero(r->secret)) { /* Secret (password) */ 13814 ast_string_field_set(p, peersecret, r->secret); 13815 } 13816 if (!ast_strlen_zero(r->md5secret)) 13817 ast_string_field_set(p, peermd5secret, r->md5secret); 13818 /* User name in this realm 13819 - if authuser is set, use that, otherwise use username */ 13820 if (!ast_strlen_zero(r->authuser)) { 13821 ast_string_field_set(p, peername, r->authuser); 13822 ast_string_field_set(p, authname, r->authuser); 13823 } else if (!ast_strlen_zero(r->username)) { 13824 ast_string_field_set(p, peername, r->username); 13825 ast_string_field_set(p, authname, r->username); 13826 ast_string_field_set(p, fromuser, r->username); 13827 } 13828 if (!ast_strlen_zero(r->username)) { 13829 ast_string_field_set(p, username, r->username); 13830 } 13831 /* Save extension in packet */ 13832 if (!ast_strlen_zero(r->callback)) { 13833 ast_string_field_set(p, exten, r->callback); 13834 } 13835 13836 /* Set transport and port so the correct contact is built */ 13837 set_socket_transport(&p->socket, r->transport); 13838 if (r->transport == SIP_TRANSPORT_TLS || r->transport == SIP_TRANSPORT_TCP) { 13839 p->socket.port = 13840 htons(ast_sockaddr_port(&sip_tcp_desc.local_address)); 13841 } 13842 13843 /* 13844 check which address we should use in our contact header 13845 based on whether the remote host is on the external or 13846 internal network so we can register through nat 13847 */ 13848 ast_sip_ouraddrfor(&p->sa, &p->ourip, p); 13849 build_contact(p); 13850 } 13851 13852 /* set up a timeout */ 13853 if (auth == NULL) { 13854 if (r->timeout > -1) { 13855 ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout); 13856 } 13857 AST_SCHED_REPLACE_UNREF(r->timeout, sched, global_reg_timeout * 1000, sip_reg_timeout, r, 13858 registry_unref(_data,"reg ptr unrefed from del in SCHED_REPLACE"), 13859 registry_unref(r,"reg ptr unrefed from add failure in SCHED_REPLACE"), 13860 registry_addref(r,"reg ptr reffed from add in SCHED_REPLACE")); 13861 ast_debug(1, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); 13862 } 13863 13864 snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, S_OR(r->regdomain, sip_sanitized_host(p->tohost)), p->tag); 13865 if (!ast_strlen_zero(p->theirtag)) { 13866 snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, S_OR(r->regdomain, sip_sanitized_host(p->tohost)), p->theirtag); 13867 } else { 13868 snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, S_OR(r->regdomain, sip_sanitized_host(p->tohost))); 13869 } 13870 13871 /* Fromdomain is what we are registering to, regardless of actual 13872 host name from SRV */ 13873 if (portno && portno != STANDARD_SIP_PORT) { 13874 snprintf(addr, sizeof(addr), "sip:%s:%d", S_OR(p->fromdomain,S_OR(r->regdomain, sip_sanitized_host(r->hostname))), portno); 13875 } else { 13876 snprintf(addr, sizeof(addr), "sip:%s", S_OR(p->fromdomain,S_OR(r->regdomain, sip_sanitized_host(r->hostname)))); 13877 } 13878 13879 ast_string_field_set(p, uri, addr); 13880 13881 p->branch ^= ast_random(); 13882 13883 init_req(&req, sipmethod, addr); 13884 13885 /* Add to CSEQ */ 13886 snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text); 13887 p->ocseq = r->ocseq; 13888 13889 build_via(p); 13890 add_header(&req, "Via", p->via); 13891 add_header_max_forwards(p, &req); 13892 add_header(&req, "From", from); 13893 add_header(&req, "To", to); 13894 add_header(&req, "Call-ID", p->callid); 13895 add_header(&req, "CSeq", tmp); 13896 if (!ast_strlen_zero(global_useragent)) 13897 add_header(&req, "User-Agent", global_useragent); 13898 13899 if (auth) { /* Add auth header */ 13900 add_header(&req, authheader, auth); 13901 } else if (!ast_strlen_zero(r->nonce)) { 13902 char digest[1024]; 13903 13904 /* We have auth data to reuse, build a digest header. 13905 * Note, this is not always useful because some parties do not 13906 * like nonces to be reused (for good reasons!) so they will 13907 * challenge us anyways. 13908 */ 13909 if (sipdebug) { 13910 ast_debug(1, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname); 13911 } 13912 ast_string_field_set(p, realm, r->realm); 13913 ast_string_field_set(p, nonce, r->nonce); 13914 ast_string_field_set(p, domain, r->authdomain); 13915 ast_string_field_set(p, opaque, r->opaque); 13916 ast_string_field_set(p, qop, r->qop); 13917 p->noncecount = ++r->noncecount; 13918 13919 memset(digest, 0, sizeof(digest)); 13920 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 13921 add_header(&req, "Authorization", digest); 13922 } else { 13923 ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname); 13924 } 13925 } 13926 13927 snprintf(tmp, sizeof(tmp), "%d", r->expiry); 13928 add_header(&req, "Expires", tmp); 13929 add_header(&req, "Contact", p->our_contact); 13930 13931 initialize_initreq(p, &req); 13932 if (sip_debug_test_pvt(p)) { 13933 ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 13934 } 13935 r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT; 13936 r->regattempts++; /* Another attempt */ 13937 ast_debug(4, "REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname); 13938 res = send_request(p, &req, XMIT_CRITICAL, p->ocseq); 13939 dialog_unref(p, "p is finished here at the end of transmit_register"); 13940 return res; 13941 }
| static int transmit_reinvite_with_sdp | ( | struct sip_pvt * | p, | |
| int | t38version, | |||
| int | oldsdp | |||
| ) | [static] |
Transmit reinvite with SDP.
If t38version is TRUE, we send T38 SDP for re-invite from audio/video to T38 UDPTL transmission on the channel
If oldsdp is TRUE then the SDP version number is not incremented. This is needed for Session-Timers so we can send a re-invite to refresh the SIP session without modifying the media session.
Definition at line 12260 of file chan_sip.c.
References add_header(), add_rpid(), add_sdp(), add_supported_header(), append_history, ast_set_flag, ast_test_flag, FALSE, initialize_initreq(), reqprep(), send_request(), TRUE, and try_suggested_sip_codec().
Referenced by check_pendings(), handle_response_invite(), interpret_t38_parameters(), proc_session_timer(), sip_sendhtml(), sip_set_rtp_peer(), and sip_set_udptl_peer().
12261 { 12262 struct sip_request req; 12263 12264 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 12265 12266 add_header(&req, "Allow", ALLOWED_METHODS); 12267 add_supported_header(p, &req); 12268 if (sipdebug) { 12269 if (oldsdp == TRUE) 12270 add_header(&req, "X-asterisk-Info", "SIP re-invite (Session-Timers)"); 12271 else 12272 add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)"); 12273 } 12274 12275 if (ast_test_flag(&p->flags[0], SIP_SENDRPID)) 12276 add_rpid(&req, p); 12277 12278 if (p->do_history) { 12279 append_history(p, "ReInv", "Re-invite sent"); 12280 } 12281 memset(p->offered_media, 0, sizeof(p->offered_media)); 12282 12283 try_suggested_sip_codec(p); 12284 if (t38version) { 12285 add_sdp(&req, p, oldsdp, FALSE, TRUE); 12286 } else { 12287 add_sdp(&req, p, oldsdp, TRUE, FALSE); 12288 } 12289 12290 /* Use this as the basis */ 12291 initialize_initreq(p, &req); 12292 p->lastinvite = p->ocseq; 12293 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 12294 p->ongoing_reinvite = 1; 12295 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 12296 }
| static int transmit_request | ( | struct sip_pvt * | p, | |
| int | sipmethod, | |||
| uint32_t | seqno, | |||
| enum xmittype | reliable, | |||
| int | newbranch | |||
| ) | [static] |
Transmit generic SIP request returns XMIT_ERROR if transmit failed with a critical error (don't retry).
Definition at line 14118 of file chan_sip.c.
References add_header(), reqprep(), and send_request().
Referenced by check_pendings(), handle_response(), handle_response_invite(), and sip_hangup().
14119 { 14120 struct sip_request resp; 14121 14122 reqprep(&resp, p, sipmethod, seqno, newbranch); 14123 if (sipmethod == SIP_CANCEL && p->answered_elsewhere) { 14124 add_header(&resp, "Reason", "SIP;cause=200;text=\"Call completed elsewhere\""); 14125 } 14126 14127 if (sipmethod == SIP_ACK) { 14128 p->invitestate = INV_CONFIRMED; 14129 } 14130 14131 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 14132 }
| static int transmit_request_with_auth | ( | struct sip_pvt * | p, | |
| int | sipmethod, | |||
| uint32_t | seqno, | |||
| enum xmittype | reliable, | |||
| int | newbranch | |||
| ) | [static] |
Transmit SIP request, auth added.
Definition at line 14150 of file chan_sip.c.
References add_header(), ast_cause2str(), ast_log(), ast_strlen_zero(), ast_test_flag, auth_headers(), build_reply_digest(), dummy(), LOG_WARNING, reqprep(), and send_request().
Referenced by __sip_autodestruct(), check_pendings(), and sip_hangup().
14151 { 14152 struct sip_request resp; 14153 14154 reqprep(&resp, p, sipmethod, seqno, newbranch); 14155 if (!ast_strlen_zero(p->realm)) { 14156 char digest[1024]; 14157 14158 memset(digest, 0, sizeof(digest)); 14159 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 14160 char *dummy, *response; 14161 enum sip_auth_type code = p->options ? p->options->auth_type : PROXY_AUTH; /* XXX force 407 if unknown */ 14162 auth_headers(code, &dummy, &response); 14163 add_header(&resp, response, digest); 14164 } else { 14165 ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid); 14166 } 14167 } 14168 /* If we are hanging up and know a cause for that, send it in clear text to make 14169 debugging easier. */ 14170 if (sipmethod == SIP_BYE) { 14171 char buf[20]; 14172 14173 if (ast_test_flag(&p->flags[1], SIP_PAGE2_Q850_REASON) && p->hangupcause) { 14174 sprintf(buf, "Q.850;cause=%i", p->hangupcause & 0x7f); 14175 add_header(&resp, "Reason", buf); 14176 } 14177 14178 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->hangupcause)); 14179 snprintf(buf, sizeof(buf), "%d", p->hangupcause); 14180 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 14181 } 14182 14183 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 14184 }
| static int transmit_response | ( | struct sip_pvt * | p, | |
| const char * | msg, | |||
| const struct sip_request * | req | |||
| ) | [static] |
Transmit response, no retransmits.
Definition at line 10986 of file chan_sip.c.
References __transmit_response().
Referenced by handle_cc_notify(), handle_cc_subscribe(), handle_incoming(), handle_invite_replaces(), 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_subscribe(), handle_request_update(), handle_sip_publish_initial(), handle_sip_publish_modify(), handle_sip_publish_refresh(), handle_sip_publish_remove(), receive_message(), register_verify(), send_provisional_keepalive_full(), sip_cc_agent_destructor(), sip_cc_agent_respond(), sip_indicate(), sip_sendhtml(), and transmit_provisional_response().
10987 { 10988 return __transmit_response(p, msg, req, XMIT_UNRELIABLE); 10989 }
| static int transmit_response_reliable | ( | struct sip_pvt * | p, | |
| const char * | msg, | |||
| const struct sip_request * | req | |||
| ) | [static] |
Transmit response, Make sure you get an ACK This is only used for responses to INVITEs, where we need to make sure we get an ACK.
Definition at line 11019 of file chan_sip.c.
References __transmit_response().
Referenced by handle_incoming(), handle_invite_replaces(), handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_invite_st(), interpret_t38_parameters(), sip_hangup(), sip_indicate(), sip_sipredirect(), and sip_t38_abort().
11020 { 11021 return __transmit_response(p, msg, req, req->ignore ? XMIT_UNRELIABLE : XMIT_CRITICAL); 11022 }
| static int transmit_response_using_temp | ( | ast_string_field | callid, | |
| struct ast_sockaddr * | addr, | |||
| int | useglobal_nat, | |||
| const int | intended_method, | |||
| const struct sip_request * | req, | |||
| const char * | msg | |||
| ) | [static] |
Transmit response, no retransmits, using a temporary pvt structure.
Definition at line 10933 of file chan_sip.c.
References __transmit_response(), ast_copy_flags, ast_log(), ast_random(), ast_sip_ouraddrfor(), ast_sockaddr_copy(), ast_string_field_init, ast_string_field_set, ast_threadstorage_get(), build_via(), copy_socket_data(), do_setnat(), internip, LOG_ERROR, and make_our_tag().
Referenced by find_call().
10934 { 10935 struct sip_pvt *p = NULL; 10936 10937 if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) { 10938 ast_log(LOG_ERROR, "Failed to get temporary pvt\n"); 10939 return -1; 10940 } 10941 10942 /* XXX the structure may be dirty from previous usage. 10943 * Here we should state clearly how we should reinitialize it 10944 * before using it. 10945 * E.g. certainly the threadstorage should be left alone, 10946 * but other thihngs such as flags etc. maybe need cleanup ? 10947 */ 10948 10949 /* Initialize the bare minimum */ 10950 p->method = intended_method; 10951 10952 if (!addr) { 10953 ast_sockaddr_copy(&p->ourip, &internip); 10954 } else { 10955 ast_sockaddr_copy(&p->sa, addr); 10956 ast_sip_ouraddrfor(&p->sa, &p->ourip, p); 10957 } 10958 10959 p->branch = ast_random(); 10960 make_our_tag(p); 10961 p->ocseq = INITIAL_CSEQ; 10962 10963 if (useglobal_nat && addr) { 10964 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT_FORCE_RPORT); 10965 ast_sockaddr_copy(&p->recv, addr); 10966 do_setnat(p); 10967 } 10968 10969 ast_string_field_set(p, fromdomain, default_fromdomain); 10970 p->fromdomainport = default_fromdomainport; 10971 build_via(p); 10972 ast_string_field_set(p, callid, callid); 10973 10974 copy_socket_data(&p->socket, &req->socket); 10975 10976 /* Use this temporary pvt structure to send the message */ 10977 __transmit_response(p, msg, req, XMIT_UNRELIABLE); 10978 10979 /* Free the string fields, but not the pool space */ 10980 ast_string_field_init(p, 0); 10981 10982 return 0; 10983 }
| static int transmit_response_with_allow | ( | struct sip_pvt * | p, | |
| const char * | msg, | |||
| const struct sip_request * | req, | |||
| enum xmittype | reliable | |||
| ) | [static] |
Append Accept header, content length before transmitting response.
Definition at line 11055 of file chan_sip.c.
References add_header(), respprep(), and send_response().
Referenced by handle_incoming(), and handle_request_options().
11056 { 11057 struct sip_request resp; 11058 respprep(&resp, p, msg, req); 11059 add_header(&resp, "Accept", "application/sdp"); 11060 return send_response(p, &resp, reliable, 0); 11061 }
| static int transmit_response_with_auth | ( | struct sip_pvt * | p, | |
| const char * | msg, | |||
| const struct sip_request * | req, | |||
| const char * | rand, | |||
| enum xmittype | reliable, | |||
| const char * | header, | |||
| int | stale | |||
| ) | [static] |
Respond with authorization request.
Definition at line 11076 of file chan_sip.c.
References add_header(), append_history, ast_log(), get_header(), get_realm(), LOG_WARNING, respprep(), and send_response().
Referenced by check_auth(), and transmit_fake_auth_response().
11077 { 11078 struct sip_request resp; 11079 char tmp[512]; 11080 uint32_t seqno = 0; 11081 11082 if (reliable && (sscanf(get_header(req, "CSeq"), "%30u ", &seqno) != 1)) { 11083 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 11084 return -1; 11085 } 11086 /* Choose Realm */ 11087 get_realm(p, req); 11088 11089 /* Stale means that they sent us correct authentication, but 11090 based it on an old challenge (nonce) */ 11091 snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", p->realm, randdata, stale ? ", stale=true" : ""); 11092 respprep(&resp, p, msg, req); 11093 add_header(&resp, header, tmp); 11094 append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount); 11095 return send_response(p, &resp, reliable, seqno); 11096 }
| static int transmit_response_with_date | ( | struct sip_pvt * | p, | |
| const char * | msg, | |||
| const struct sip_request * | req | |||
| ) | [static] |
Append date and content length before transmitting response.
Definition at line 11046 of file chan_sip.c.
References append_date(), respprep(), and send_response().
Referenced by handle_response_subscribe(), and register_verify().
11047 { 11048 struct sip_request resp; 11049 respprep(&resp, p, msg, req); 11050 append_date(&resp); 11051 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 11052 }
| static int transmit_response_with_minexpires | ( | struct sip_pvt * | p, | |
| const char * | msg, | |||
| const struct sip_request * | req | |||
| ) | [static] |
Append Min-Expires header, content length before transmitting response.
Definition at line 11064 of file chan_sip.c.
References add_header(), respprep(), and send_response().
Referenced by handle_request_publish(), and handle_request_subscribe().
11065 { 11066 struct sip_request resp; 11067 char tmp[32]; 11068 11069 snprintf(tmp, sizeof(tmp), "%d", min_expiry); 11070 respprep(&resp, p, msg, req); 11071 add_header(&resp, "Min-Expires", tmp); 11072 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 11073 }
| static int transmit_response_with_minse | ( | struct sip_pvt * | p, | |
| const char * | msg, | |||
| const struct sip_request * | req, | |||
| int | minse_int | |||
| ) | [static] |
Transmit 422 response with Min-SE header (Session-Timers).
Definition at line 11002 of file chan_sip.c.
References add_header(), append_date(), respprep(), and send_response().
Referenced by handle_request_invite_st().
11003 { 11004 struct sip_request resp; 11005 char minse_str[20]; 11006 11007 respprep(&resp, p, msg, req); 11008 append_date(&resp); 11009 11010 snprintf(minse_str, sizeof(minse_str), "%d", minse_int); 11011 add_header(&resp, "Min-SE", minse_str); 11012 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 11013 }
| static int transmit_response_with_retry_after | ( | struct sip_pvt * | p, | |
| const char * | msg, | |||
| const struct sip_request * | req, | |||
| const char * | seconds | |||
| ) | [static] |
Append Retry-After header field when transmitting response.
Definition at line 11037 of file chan_sip.c.
References add_header(), respprep(), and send_response().
Referenced by handle_incoming().
11038 { 11039 struct sip_request resp; 11040 respprep(&resp, p, msg, req); 11041 add_header(&resp, "Retry-After", seconds); 11042 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 11043 }
| static int transmit_response_with_sdp | ( | struct sip_pvt * | p, | |
| const char * | msg, | |||
| const struct sip_request * | req, | |||
| enum xmittype | reliable, | |||
| int | oldsdp, | |||
| int | rpid | |||
| ) | [static] |
Used for 200 OK and 183 early media.
Definition at line 12169 of file chan_sip.c.
References add_cc_call_info_to_response(), add_required_respheader(), add_rpid(), add_sdp(), ast_debug, ast_log(), ast_rtp_codecs_packetization_set(), ast_rtp_instance_activate(), ast_rtp_instance_get_codecs(), ast_test_flag, FALSE, get_header(), LOG_ERROR, LOG_WARNING, respprep(), send_response(), TRUE, and try_suggested_sip_codec().
Referenced by handle_invite_replaces(), handle_request_invite(), send_provisional_keepalive_full(), sip_answer(), and transmit_provisional_response().
12170 { 12171 struct sip_request resp; 12172 uint32_t seqno; 12173 if (sscanf(get_header(req, "CSeq"), "%30u ", &seqno) != 1) { 12174 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 12175 return -1; 12176 } 12177 respprep(&resp, p, msg, req); 12178 if (rpid == TRUE) { 12179 add_rpid(&resp, p); 12180 } 12181 if (ast_test_flag(&p->flags[0], SIP_OFFER_CC)) { 12182 add_cc_call_info_to_response(p, &resp); 12183 } 12184 if (p->rtp) { 12185 if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 12186 ast_debug(1, "Setting framing from config on incoming call\n"); 12187 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &p->prefs); 12188 } 12189 ast_rtp_instance_activate(p->rtp); 12190 try_suggested_sip_codec(p); 12191 if (p->t38.state == T38_ENABLED) { 12192 add_sdp(&resp, p, oldsdp, TRUE, TRUE); 12193 } else { 12194 add_sdp(&resp, p, oldsdp, TRUE, FALSE); 12195 } 12196 } else 12197 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid); 12198 if (reliable && !p->pendinginvite) 12199 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 12200 add_required_respheader(&resp); 12201 return send_response(p, &resp, reliable, seqno); 12202 }
| static int transmit_response_with_sip_etag | ( | struct sip_pvt * | p, | |
| const char * | msg, | |||
| const struct sip_request * | req, | |||
| struct sip_esc_entry * | esc_entry, | |||
| int | need_new_etag | |||
| ) | [static] |
Definition at line 10902 of file chan_sip.c.
References add_header(), create_new_sip_etag(), respprep(), and send_response().
Referenced by handle_sip_publish_initial(), handle_sip_publish_modify(), handle_sip_publish_refresh(), and handle_sip_publish_remove().
10903 { 10904 struct sip_request resp; 10905 10906 if (need_new_etag) { 10907 create_new_sip_etag(esc_entry, 1); 10908 } 10909 respprep(&resp, p, msg, req); 10910 add_header(&resp, "SIP-ETag", esc_entry->entity_tag); 10911 10912 return send_response(p, &resp, 0, 0); 10913 }
| static int transmit_response_with_t38_sdp | ( | struct sip_pvt * | p, | |
| char * | msg, | |||
| struct sip_request * | req, | |||
| int | retrans | |||
| ) | [static] |
Used for 200 OK and 183 early media.
Definition at line 12085 of file chan_sip.c.
References add_sdp(), ast_log(), get_header(), LOG_ERROR, LOG_WARNING, respprep(), and send_response().
Referenced by handle_request_invite(), and interpret_t38_parameters().
12086 { 12087 struct sip_request resp; 12088 uint32_t seqno; 12089 12090 if (sscanf(get_header(req, "CSeq"), "%30u ", &seqno) != 1) { 12091 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 12092 return -1; 12093 } 12094 respprep(&resp, p, msg, req); 12095 if (p->udptl) { 12096 add_sdp(&resp, p, 0, 0, 1); 12097 } else 12098 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid); 12099 if (retrans && !p->pendinginvite) 12100 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 12101 return send_response(p, &resp, retrans, seqno); 12102 }
| static int transmit_response_with_unsupported | ( | struct sip_pvt * | p, | |
| const char * | msg, | |||
| const struct sip_request * | req, | |||
| const char * | unsupported | |||
| ) | [static] |
Transmit response, no retransmits.
Definition at line 10992 of file chan_sip.c.
References add_header(), append_date(), respprep(), and send_response().
Referenced by handle_request_bye(), handle_request_invite(), and handle_request_invite_st().
10993 { 10994 struct sip_request resp; 10995 respprep(&resp, p, msg, req); 10996 append_date(&resp); 10997 add_header(&resp, "Unsupported", unsupported); 10998 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 10999 }
| static int transmit_state_notify | ( | struct sip_pvt * | p, | |
| int | state, | |||
| int | full, | |||
| int | timeout | |||
| ) | [static] |
Used in the SUBSCRIBE notification subsystem (RFC3265).
Definition at line 13224 of file chan_sip.c.
References add_content(), add_header(), ast_copy_string(), AST_EXTENSION_DEACTIVATED, AST_EXTENSION_REMOVED, ast_log(), ast_str_alloca, ast_str_buffer(), ast_test_flag, cfsubscription_types::event, find_subscription_type(), get_header(), get_in_brackets(), LOG_WARNING, cfsubscription_types::mediatype, NONE, remove_uri_parameters(), reqprep(), send_request(), and state_notify_build_xml().
Referenced by __sip_autodestruct(), cb_extensionstate(), and handle_request_subscribe().
13225 { 13226 struct ast_str *tmp = ast_str_alloca(4000); 13227 char from[256], to[256]; 13228 char *c, *mfrom, *mto; 13229 struct sip_request req; 13230 const struct cfsubscription_types *subscriptiontype; 13231 13232 /* If the subscription has not yet been accepted do not send a NOTIFY */ 13233 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) { 13234 return 0; 13235 } 13236 13237 memset(from, 0, sizeof(from)); 13238 memset(to, 0, sizeof(to)); 13239 13240 subscriptiontype = find_subscription_type(p->subscribed); 13241 13242 ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from)); 13243 c = get_in_brackets(from); 13244 if (strncasecmp(c, "sip:", 4) && strncasecmp(c, "sips:", 5)) { 13245 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 13246 return -1; 13247 } 13248 13249 mfrom = remove_uri_parameters(c); 13250 13251 ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to)); 13252 c = get_in_brackets(to); 13253 if (strncasecmp(c, "sip:", 4) && strncasecmp(c, "sips:", 5)) { 13254 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 13255 return -1; 13256 } 13257 mto = remove_uri_parameters(c); 13258 13259 reqprep(&req, p, SIP_NOTIFY, 0, 1); 13260 13261 switch(state) { 13262 case AST_EXTENSION_DEACTIVATED: 13263 if (timeout) 13264 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 13265 else { 13266 add_header(&req, "Subscription-State", "terminated;reason=probation"); 13267 add_header(&req, "Retry-After", "60"); 13268 } 13269 break; 13270 case AST_EXTENSION_REMOVED: 13271 add_header(&req, "Subscription-State", "terminated;reason=noresource"); 13272 break; 13273 default: 13274 if (p->expiry) 13275 add_header(&req, "Subscription-State", "active"); 13276 else /* Expired */ 13277 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 13278 } 13279 13280 switch (p->subscribed) { 13281 case XPIDF_XML: 13282 case CPIM_PIDF_XML: 13283 add_header(&req, "Event", subscriptiontype->event); 13284 state_notify_build_xml(state, full, p->exten, p->context, &tmp, p, p->subscribed, mfrom, mto); 13285 add_header(&req, "Content-Type", subscriptiontype->mediatype); 13286 p->dialogver++; 13287 break; 13288 case PIDF_XML: /* Eyebeam supports this format */ 13289 add_header(&req, "Event", subscriptiontype->event); 13290 state_notify_build_xml(state, full, p->exten, p->context, &tmp, p, p->subscribed, mfrom, mto); 13291 add_header(&req, "Content-Type", subscriptiontype->mediatype); 13292 p->dialogver++; 13293 break; 13294 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 13295 add_header(&req, "Event", subscriptiontype->event); 13296 state_notify_build_xml(state, full, p->exten, p->context, &tmp, p, p->subscribed, mfrom, mto); 13297 add_header(&req, "Content-Type", subscriptiontype->mediatype); 13298 p->dialogver++; 13299 break; 13300 case NONE: 13301 default: 13302 break; 13303 } 13304 13305 add_content(&req, ast_str_buffer(tmp)); 13306 13307 p->pendinginvite = p->ocseq; /* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */ 13308 13309 /* Send as XMIT_CRITICAL as we may never receive a 200 OK Response which clears p->pendinginvite. 13310 * 13311 * extensionstate_update() uses p->pendinginvite for queuing control. 13312 * Updates stall if pendinginvite <> 0. 13313 * 13314 * The most appropriate solution is to remove the subscription when the NOTIFY transaction fails. 13315 * The client will re-subscribe after restarting or maxexpiry timeout. 13316 */ 13317 13318 /* RFC6665 4.2.2. Sending State Information to Subscribers 13319 * If the NOTIFY request fails due to expiration of SIP Timer F (transaction timeout), 13320 * the notifier SHOULD remove the subscription. 13321 */ 13322 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 13323 }
| static const char* transport2str | ( | enum sip_transport | transport | ) | [static] |
Definition at line 19212 of file chan_sip.c.
Referenced by sip_show_channel().
| static const char* trust_id_outbound2str | ( | int | mode | ) | [static] |
Definition at line 17614 of file chan_sip.c.
References map_x_s().
Referenced by _sip_show_peer().
17615 { 17616 return map_x_s(trust_id_outboundstr, mode, "<error>"); 17617 }
| static void try_suggested_sip_codec | ( | struct sip_pvt * | p | ) | [static] |
Try setting codec suggested by the SIP_CODEC channel variable.
Definition at line 6700 of file chan_sip.c.
References ast_getformatbyname(), ast_log(), LOG_NOTICE, and pbx_builtin_getvar_helper().
Referenced by sip_answer(), transmit_invite(), transmit_reinvite_with_sdp(), and transmit_response_with_sdp().
06701 { 06702 format_t fmt; 06703 const char *codec; 06704 06705 if (p->outgoing_call) { 06706 codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC_OUTBOUND"); 06707 } else if (!(codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC_INBOUND"))) { 06708 codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC"); 06709 } 06710 06711 if (!codec) 06712 return; 06713 06714 fmt = ast_getformatbyname(codec); 06715 if (fmt) { 06716 ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec); 06717 if (p->jointcapability & fmt) { 06718 p->jointcapability &= fmt; 06719 p->capability &= fmt; 06720 } else 06721 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n"); 06722 } else 06723 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec); 06724 return; 06725 }
| static void unlink_all_peers_from_tables | ( | void | ) | [static] |
Definition at line 3042 of file chan_sip.c.
References SIP_PEERS_ALL, and unlink_peers_from_tables().
Referenced by unload_module().
03043 { 03044 unlink_peers_from_tables(SIP_PEERS_ALL); 03045 }
| static void unlink_marked_peers_from_tables | ( | void | ) | [static] |
Definition at line 3037 of file chan_sip.c.
References SIP_PEERS_MARKED, and unlink_peers_from_tables().
Referenced by sip_do_reload(), and sip_prune_realtime().
03038 { 03039 unlink_peers_from_tables(SIP_PEERS_MARKED); 03040 }
| static void unlink_peer_from_tables | ( | struct sip_peer * | peer | ) | [static] |
Definition at line 3048 of file chan_sip.c.
References ao2_t_unlink, and ast_sockaddr_isnull().
Referenced by expire_register().
03049 { 03050 ao2_t_unlink(peers, peer, "ao2_unlink of peer from peers table"); 03051 if (!ast_sockaddr_isnull(&peer->addr)) { 03052 ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table"); 03053 } 03054 }
| static void unlink_peers_from_tables | ( | peer_unlink_flag_t | flag | ) | [static] |
Definition at line 3028 of file chan_sip.c.
References ao2_t_callback, match_and_cleanup_peer_sched(), OBJ_MULTIPLE, OBJ_NODATA, and OBJ_UNLINK.
Referenced by unlink_all_peers_from_tables(), and unlink_marked_peers_from_tables().
03029 { 03030 ao2_t_callback(peers, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, 03031 match_and_cleanup_peer_sched, &flag, "initiating callback to remove marked peers"); 03032 ao2_t_callback(peers_by_ip, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, 03033 match_and_cleanup_peer_sched, &flag, "initiating callback to remove marked peers"); 03034 }
| static int unload_module | ( | void | ) | [static] |
PBX unload module API.
Definition at line 31939 of file chan_sip.c.
References ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ao2_t_ref, ARRAY_LEN, ast_cc_agent_unregister(), ast_cc_monitor_unregister(), ast_channel_unregister(), ast_cli_unregister_multiple(), ast_config_destroy(), ast_context_destroy(), ast_context_find(), ast_custom_function_unregister(), ast_data_unregister, ast_debug, ast_dnsmgr_release(), ast_free, ast_free_ha(), ast_io_remove(), ast_manager_unregister(), ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_rtp_glue_unregister(), ast_sched_dump(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_ssl_teardown(), ast_tcptls_server_stop(), AST_TEST_UNREGISTER, ast_udptl_proto_unregister(), ast_unload_realtime(), ast_unregister_application(), ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, ast_tls_config::cafile, ast_tls_config::capath, ast_tls_config::certfile, ast_tls_config::cipher, cleanup_all_regs(), clear_sip_domains(), destroy_escs(), dialog_unlink_all(), io_context_destroy(), ast_tcptls_session_args::master, network_change_event_unsubscribe(), ast_tls_config::pvtfile, regl, sched_context_destroy(), sip_cfg, sip_epa_unregister_all(), sip_registry_destroy(), sip_reqresp_parser_exit(), sip_subscribe_mwi_destroy(), sip_unregister_tests(), submwil, thread, ast_tcptls_session_args::tls_cfg, and unlink_all_peers_from_tables().
31940 { 31941 struct sip_pvt *p; 31942 struct sip_threadinfo *th; 31943 struct ast_context *con; 31944 struct ao2_iterator i; 31945 int wait_count; 31946 31947 network_change_event_unsubscribe(); 31948 31949 ast_sched_dump(sched); 31950 31951 /* First, take us out of the channel type list */ 31952 ast_channel_unregister(&sip_tech); 31953 31954 /* Unregister dial plan functions */ 31955 ast_custom_function_unregister(&sipchaninfo_function); 31956 ast_custom_function_unregister(&sippeer_function); 31957 ast_custom_function_unregister(&sip_header_function); 31958 ast_custom_function_unregister(&checksipdomain_function); 31959 31960 /* Unregister dial plan applications */ 31961 ast_unregister_application(app_dtmfmode); 31962 ast_unregister_application(app_sipaddheader); 31963 ast_unregister_application(app_sipremoveheader); 31964 31965 #ifdef TEST_FRAMEWORK 31966 AST_TEST_UNREGISTER(test_sip_peers_get); 31967 AST_TEST_UNREGISTER(test_sip_mwi_subscribe_parse); 31968 AST_TEST_UNREGISTER(test_tcp_message_fragmentation); 31969 AST_TEST_UNREGISTER(get_in_brackets_const_test); 31970 #endif 31971 /* Unregister all the AstData providers */ 31972 ast_data_unregister(NULL); 31973 31974 /* Unregister CLI commands */ 31975 ast_cli_unregister_multiple(cli_sip, ARRAY_LEN(cli_sip)); 31976 31977 /* Disconnect from UDPTL */ 31978 ast_udptl_proto_unregister(&sip_udptl); 31979 31980 /* Disconnect from RTP engine */ 31981 ast_rtp_glue_unregister(&sip_rtp_glue); 31982 31983 /* Unregister AMI actions */ 31984 ast_manager_unregister("SIPpeers"); 31985 ast_manager_unregister("SIPshowpeer"); 31986 ast_manager_unregister("SIPqualifypeer"); 31987 ast_manager_unregister("SIPshowregistry"); 31988 ast_manager_unregister("SIPnotify"); 31989 31990 /* Kill TCP/TLS server threads */ 31991 if (sip_tcp_desc.master) { 31992 ast_tcptls_server_stop(&sip_tcp_desc); 31993 } 31994 if (sip_tls_desc.master) { 31995 ast_tcptls_server_stop(&sip_tls_desc); 31996 } 31997 ast_ssl_teardown(sip_tls_desc.tls_cfg); 31998 31999 /* Kill all existing TCP/TLS threads */ 32000 i = ao2_iterator_init(threadt, 0); 32001 while ((th = ao2_t_iterator_next(&i, "iterate through tcp threads for 'sip show tcp'"))) { 32002 pthread_t thread = th->threadid; 32003 th->stop = 1; 32004 pthread_kill(thread, SIGURG); 32005 ao2_t_ref(th, -1, "decrement ref from iterator"); 32006 } 32007 ao2_iterator_destroy(&i); 32008 32009 /* Hangup all dialogs if they have an owner */ 32010 i = ao2_iterator_init(dialogs, 0); 32011 while ((p = ao2_t_iterator_next(&i, "iterate thru dialogs"))) { 32012 if (p->owner) 32013 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 32014 ao2_t_ref(p, -1, "toss dialog ptr from iterator_next"); 32015 } 32016 ao2_iterator_destroy(&i); 32017 32018 unlink_all_peers_from_tables(); 32019 32020 ast_mutex_lock(&monlock); 32021 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 32022 pthread_t th = monitor_thread; 32023 monitor_thread = AST_PTHREADT_STOP; 32024 pthread_cancel(th); 32025 pthread_kill(th, SIGURG); 32026 ast_mutex_unlock(&monlock); 32027 pthread_join(th, NULL); 32028 } else { 32029 monitor_thread = AST_PTHREADT_STOP; 32030 ast_mutex_unlock(&monlock); 32031 } 32032 32033 /* Destroy all the dialogs and free their memory */ 32034 i = ao2_iterator_init(dialogs, 0); 32035 while ((p = ao2_t_iterator_next(&i, "iterate thru dialogs"))) { 32036 dialog_unlink_all(p); 32037 ao2_t_ref(p, -1, "throw away iterator result"); 32038 } 32039 ao2_iterator_destroy(&i); 32040 32041 /* Free memory for local network address mask */ 32042 ast_free_ha(localaddr); 32043 32044 ast_mutex_lock(&authl_lock); 32045 if (authl) { 32046 ao2_t_ref(authl, -1, "Removing global authentication"); 32047 authl = NULL; 32048 } 32049 ast_mutex_unlock(&authl_lock); 32050 32051 sip_epa_unregister_all(); 32052 destroy_escs(); 32053 32054 ast_free(default_tls_cfg.certfile); 32055 ast_free(default_tls_cfg.pvtfile); 32056 ast_free(default_tls_cfg.cipher); 32057 ast_free(default_tls_cfg.cafile); 32058 ast_free(default_tls_cfg.capath); 32059 32060 cleanup_all_regs(); 32061 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 32062 ASTOBJ_CONTAINER_DESTROY(®l); 32063 32064 ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do { 32065 ASTOBJ_WRLOCK(iterator); 32066 if (iterator->dnsmgr) { 32067 ast_dnsmgr_release(iterator->dnsmgr); 32068 iterator->dnsmgr = NULL; 32069 ASTOBJ_UNREF(iterator, sip_subscribe_mwi_destroy); 32070 } 32071 ASTOBJ_UNLOCK(iterator); 32072 } while(0)); 32073 ASTOBJ_CONTAINER_DESTROYALL(&submwil, sip_subscribe_mwi_destroy); 32074 ASTOBJ_CONTAINER_DESTROY(&submwil); 32075 32076 /* 32077 * Wait awhile for the TCP/TLS thread container to become empty. 32078 * 32079 * XXX This is a hack, but the worker threads cannot be created 32080 * joinable. They can die on their own and remove themselves 32081 * from the container thus resulting in a huge memory leak. 32082 */ 32083 wait_count = 1000; 32084 while (ao2_container_count(threadt) && --wait_count) { 32085 sched_yield(); 32086 } 32087 if (!wait_count) { 32088 ast_debug(2, "TCP/TLS thread container did not become empty :(\n"); 32089 } 32090 32091 ao2_t_ref(bogus_peer, -1, "unref the bogus_peer"); 32092 32093 ao2_t_ref(peers, -1, "unref the peers table"); 32094 ao2_t_ref(peers_by_ip, -1, "unref the peers_by_ip table"); 32095 ao2_t_ref(dialogs, -1, "unref the dialogs table"); 32096 ao2_t_ref(dialogs_to_destroy, -1, "unref dialogs_to_destroy"); 32097 ao2_t_ref(threadt, -1, "unref the thread table"); 32098 ao2_t_ref(sip_monitor_instances, -1, "unref the sip_monitor_instances table"); 32099 32100 clear_sip_domains(); 32101 ast_free_ha(sip_cfg.contact_ha); 32102 if (sipsock_read_id) { 32103 ast_io_remove(io, sipsock_read_id); 32104 sipsock_read_id = NULL; 32105 } 32106 close(sipsock); 32107 io_context_destroy(io); 32108 sched_context_destroy(sched); 32109 con = ast_context_find(used_context); 32110 if (con) { 32111 ast_context_destroy(con, "SIP"); 32112 } 32113 ast_unload_realtime("sipregs"); 32114 ast_unload_realtime("sippeers"); 32115 ast_cc_monitor_unregister(&sip_cc_monitor_callbacks); 32116 ast_cc_agent_unregister(&sip_cc_agent_callbacks); 32117 32118 sip_reqresp_parser_exit(); 32119 sip_unregister_tests(); 32120 32121 if (notify_types) { 32122 ast_config_destroy(notify_types); 32123 notify_types = NULL; 32124 } 32125 32126 return 0; 32127 }
| static void* unref_peer | ( | struct sip_peer * | peer, | |
| char * | tag | |||
| ) | [static] |
helper functions to unreference various types of objects. By handling them this way, we don't have to declare the destructor on each call, which removes the chance of errors.
Definition at line 2979 of file chan_sip.c.
References ao2_t_ref.
Referenced by __sip_destroy(), _sip_qualify_peer(), _sip_show_peer(), _sip_show_peers(), _sip_show_peers_one(), build_peer(), check_peer_ok(), complete_sip_peer(), complete_sip_registered_peer(), complete_sip_user(), create_addr(), expire_register(), find_peer(), function_sippeer(), handle_request_invite(), handle_request_notify(), handle_request_subscribe(), handle_response_peerpoke(), match_and_cleanup_peer_sched(), parse_register_contact(), peer_sched_cleanup(), realtime_peer(), reg_source_db(), register_verify(), reload_config(), sip_devicestate(), sip_do_debug_peer(), sip_poke_all_peers(), sip_poke_noanswer(), sip_poke_peer(), sip_poke_peer_s(), sip_prune_realtime(), sip_show_inuse(), sip_show_user(), sip_show_users(), sip_unregister(), transmit_register(), and update_call_counter().
02980 { 02981 ao2_t_ref(peer, -1, tag); 02982 return NULL; 02983 }
| static int update_call_counter | ( | struct sip_pvt * | fup, | |
| int | event | |||
| ) | [static] |
update_call_counter: Handle call_limit for SIP devices Setting a call-limit will cause calls above the limit not to be accepted.
Remember that for a type=friend, there's one limit for the user and another for the peer, not a combined call limit. This will cause unexpected behaviour in subscriptions, since a "friend" is *two* devices in Asterisk, not one.
Thought: For realtime, we should probably update storage with inuse counter...
Definition at line 6143 of file chan_sip.c.
References ao2_lock, ao2_unlock, ast_clear_flag, ast_copy_string(), ast_debug, AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_log(), ast_set_flag, ast_test_flag, FALSE, LOG_ERROR, LOG_NOTICE, name, ref_peer(), sip_cfg, sip_peer_hold(), sip_pvt_lock, sip_pvt_unlock, and unref_peer().
Referenced by __sip_destroy(), handle_request_cancel(), handle_request_invite(), handle_response_invite(), sip_call(), and sip_hangup().
06144 { 06145 char name[256]; 06146 int *inuse = NULL, *call_limit = NULL, *inringing = NULL; 06147 int outgoing = fup->outgoing_call; 06148 struct sip_peer *p = NULL; 06149 06150 ast_debug(3, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming"); 06151 06152 06153 /* Test if we need to check call limits, in order to avoid 06154 realtime lookups if we do not need it */ 06155 if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT) && !ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD)) 06156 return 0; 06157 06158 ast_copy_string(name, fup->username, sizeof(name)); 06159 06160 /* Check the list of devices */ 06161 if (fup->relatedpeer) { 06162 p = ref_peer(fup->relatedpeer, "ref related peer for update_call_counter"); 06163 inuse = &p->inUse; 06164 call_limit = &p->call_limit; 06165 inringing = &p->inRinging; 06166 ast_copy_string(name, fup->peername, sizeof(name)); 06167 } 06168 if (!p) { 06169 ast_debug(2, "%s is not a local device, no call limit\n", name); 06170 return 0; 06171 } 06172 06173 switch(event) { 06174 /* incoming and outgoing affects the inUse counter */ 06175 case DEC_CALL_LIMIT: 06176 /* Decrement inuse count if applicable */ 06177 if (inuse) { 06178 sip_pvt_lock(fup); 06179 ao2_lock(p); 06180 if (*inuse > 0) { 06181 if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) { 06182 (*inuse)--; 06183 ast_clear_flag(&fup->flags[0], SIP_INC_COUNT); 06184 } 06185 } else { 06186 *inuse = 0; 06187 } 06188 ao2_unlock(p); 06189 sip_pvt_unlock(fup); 06190 } 06191 06192 /* Decrement ringing count if applicable */ 06193 if (inringing) { 06194 sip_pvt_lock(fup); 06195 ao2_lock(p); 06196 if (*inringing > 0) { 06197 if (ast_test_flag(&fup->flags[0], SIP_INC_RINGING)) { 06198 (*inringing)--; 06199 ast_clear_flag(&fup->flags[0], SIP_INC_RINGING); 06200 } 06201 } else { 06202 *inringing = 0; 06203 } 06204 ao2_unlock(p); 06205 sip_pvt_unlock(fup); 06206 } 06207 06208 /* Decrement onhold count if applicable */ 06209 sip_pvt_lock(fup); 06210 ao2_lock(p); 06211 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && sip_cfg.notifyhold) { 06212 ast_clear_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD); 06213 ao2_unlock(p); 06214 sip_pvt_unlock(fup); 06215 sip_peer_hold(fup, FALSE); 06216 } else { 06217 ao2_unlock(p); 06218 sip_pvt_unlock(fup); 06219 } 06220 if (sipdebug) 06221 ast_debug(2, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", "peer", name, *call_limit); 06222 break; 06223 06224 case INC_CALL_RINGING: 06225 case INC_CALL_LIMIT: 06226 /* If call limit is active and we have reached the limit, reject the call */ 06227 if (*call_limit > 0 ) { 06228 if (*inuse >= *call_limit) { 06229 ast_log(LOG_NOTICE, "Call %s %s '%s' rejected due to usage limit of %d\n", outgoing ? "to" : "from", "peer", name, *call_limit); 06230 unref_peer(p, "update_call_counter: unref peer p, call limit exceeded"); 06231 return -1; 06232 } 06233 } 06234 if (inringing && (event == INC_CALL_RINGING)) { 06235 sip_pvt_lock(fup); 06236 ao2_lock(p); 06237 if (!ast_test_flag(&fup->flags[0], SIP_INC_RINGING)) { 06238 (*inringing)++; 06239 ast_set_flag(&fup->flags[0], SIP_INC_RINGING); 06240 } 06241 ao2_unlock(p); 06242 sip_pvt_unlock(fup); 06243 } 06244 if (inuse) { 06245 sip_pvt_lock(fup); 06246 ao2_lock(p); 06247 if (!ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) { 06248 (*inuse)++; 06249 ast_set_flag(&fup->flags[0], SIP_INC_COUNT); 06250 } 06251 ao2_unlock(p); 06252 sip_pvt_unlock(fup); 06253 } 06254 if (sipdebug) { 06255 ast_debug(2, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", "peer", name, *inuse, *call_limit); 06256 } 06257 break; 06258 06259 case DEC_CALL_RINGING: 06260 if (inringing) { 06261 sip_pvt_lock(fup); 06262 ao2_lock(p); 06263 if (ast_test_flag(&fup->flags[0], SIP_INC_RINGING)) { 06264 if (*inringing > 0) { 06265 (*inringing)--; 06266 } 06267 ast_clear_flag(&fup->flags[0], SIP_INC_RINGING); 06268 } 06269 ao2_unlock(p); 06270 sip_pvt_unlock(fup); 06271 } 06272 break; 06273 06274 default: 06275 ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event); 06276 } 06277 06278 if (p) { 06279 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", p->name); 06280 unref_peer(p, "update_call_counter: unref_peer from call counter"); 06281 } 06282 return 0; 06283 }
| static void update_connectedline | ( | struct sip_pvt * | p, | |
| const void * | data, | |||
| size_t | datalen | |||
| ) | [static] |
Notify peer that the connected line has changed.
Definition at line 13480 of file chan_sip.c.
References add_header(), add_rpid(), add_sdp(), add_supported_header(), append_history, ast_clear_flag, ast_debug, ast_set_flag, ast_state2str(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, FALSE, initialize_initreq(), is_method_allowed(), reqprep(), respprep(), S_COR, send_request(), send_response(), and TRUE.
Referenced by sip_indicate().
13481 { 13482 13483 if (!ast_test_flag(&p->flags[0], SIP_SENDRPID)) { 13484 return; 13485 } 13486 if (!p->owner->connected.id.number.valid 13487 || ast_strlen_zero(p->owner->connected.id.number.str)) { 13488 return; 13489 } 13490 13491 append_history(p, "ConnectedLine", "%s party is now %s <%s>", 13492 ast_test_flag(&p->flags[0], SIP_OUTGOING) ? "Calling" : "Called", 13493 S_COR(p->owner->connected.id.name.valid, p->owner->connected.id.name.str, ""), 13494 S_COR(p->owner->connected.id.number.valid, p->owner->connected.id.number.str, "")); 13495 13496 if (p->owner->_state == AST_STATE_UP || ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 13497 struct sip_request req; 13498 13499 if (!p->pendinginvite && (p->invitestate == INV_CONFIRMED || p->invitestate == INV_TERMINATED)) { 13500 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 13501 13502 add_header(&req, "Allow", ALLOWED_METHODS); 13503 add_supported_header(p, &req); 13504 add_rpid(&req, p); 13505 add_sdp(&req, p, FALSE, TRUE, FALSE); 13506 13507 initialize_initreq(p, &req); 13508 p->lastinvite = p->ocseq; 13509 ast_set_flag(&p->flags[0], SIP_OUTGOING); 13510 p->invitestate = INV_CALLING; 13511 send_request(p, &req, XMIT_CRITICAL, p->ocseq); 13512 } else if ((is_method_allowed(&p->allowed_methods, SIP_UPDATE)) && (!ast_strlen_zero(p->okcontacturi))) { 13513 reqprep(&req, p, SIP_UPDATE, 0, 1); 13514 add_rpid(&req, p); 13515 add_header(&req, "X-Asterisk-rpid-update", "Yes"); 13516 send_request(p, &req, XMIT_CRITICAL, p->ocseq); 13517 } else { 13518 /* We cannot send the update yet, so we have to wait until we can */ 13519 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 13520 } 13521 } else { 13522 ast_set_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND); 13523 if (ast_test_flag(&p->flags[1], SIP_PAGE2_RPID_IMMEDIATE)) { 13524 struct sip_request resp; 13525 13526 if ((p->owner->_state == AST_STATE_RING) && !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT)) { 13527 ast_clear_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND); 13528 respprep(&resp, p, "180 Ringing", &p->initreq); 13529 add_rpid(&resp, p); 13530 send_response(p, &resp, XMIT_UNRELIABLE, 0); 13531 ast_set_flag(&p->flags[0], SIP_RINGING); 13532 } else if (p->owner->_state == AST_STATE_RINGING) { 13533 ast_clear_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND); 13534 respprep(&resp, p, "183 Session Progress", &p->initreq); 13535 add_rpid(&resp, p); 13536 send_response(p, &resp, XMIT_UNRELIABLE, 0); 13537 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 13538 } else { 13539 ast_debug(1, "Unable able to send update to '%s' in state '%s'\n", p->owner->name, ast_state2str(p->owner->_state)); 13540 } 13541 } 13542 } 13543 }
| static void update_peer | ( | struct sip_peer * | p, | |
| int | expire | |||
| ) | [static] |
Update peer data in database (if used).
Definition at line 4886 of file chan_sip.c.
References ast_test_flag, realtime_update_peer(), and sip_cfg.
Referenced by register_verify().
04887 { 04888 int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 04889 if (sip_cfg.peer_rtupdate && 04890 (p->is_realtime || rtcachefriends)) { 04891 realtime_update_peer(p->name, &p->addr, p->username, p->fullcontact, p->useragent, expire, p->deprecated_username, p->lastms); 04892 } 04893 }
| static void update_peer_lastmsgssent | ( | struct sip_peer * | peer, | |
| int | value, | |||
| int | locked | |||
| ) | [static] |
Definition at line 15259 of file chan_sip.c.
References ao2_lock, and ao2_unlock.
Referenced by register_verify(), and sip_send_mwi_to_peer().
15260 { 15261 if (!locked) { 15262 ao2_lock(peer); 15263 } 15264 peer->lastmsgssent = value; 15265 if (!locked) { 15266 ao2_unlock(peer); 15267 } 15268 }
| static void update_provisional_keepalive | ( | struct sip_pvt * | pvt, | |
| int | with_sdp | |||
| ) | [static] |
Definition at line 4343 of file chan_sip.c.
References ast_sched_add(), AST_SCHED_DEL_UNREF, send_provisional_keepalive(), and send_provisional_keepalive_with_sdp().
Referenced by transmit_provisional_response().
04344 { 04345 AST_SCHED_DEL_UNREF(sched, pvt->provisional_keepalive_sched_id, dialog_unref(pvt, "when you delete the provisional_keepalive_sched_id, you should dec the refcount for the stored dialog ptr")); 04346 04347 pvt->provisional_keepalive_sched_id = ast_sched_add(sched, PROVIS_KEEPALIVE_TIMEOUT, 04348 with_sdp ? send_provisional_keepalive_with_sdp : send_provisional_keepalive, dialog_ref(pvt, "Increment refcount to pass dialog pointer to sched callback")); 04349 }
| static void update_redirecting | ( | struct sip_pvt * | p, | |
| const void * | data, | |||
| size_t | datalen | |||
| ) | [static] |
Send a provisional response indicating that a call was redirected.
Definition at line 13466 of file chan_sip.c.
References add_diversion_header(), AST_STATE_UP, ast_test_flag, respprep(), and send_response().
Referenced by handle_request_invite(), handle_response(), handle_response_invite(), and sip_indicate().
13467 { 13468 struct sip_request resp; 13469 13470 if (p->owner->_state == AST_STATE_UP || ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 13471 return; 13472 } 13473 13474 respprep(&resp, p, "181 Call is being forwarded", &p->initreq); 13475 add_diversion_header(&resp, p); 13476 send_response(p, &resp, XMIT_UNRELIABLE, 0); 13477 }
struct _map_x_s allowoverlapstr[] [static] |
Definition at line 17594 of file chan_sip.c.
int apeerobjs = 0 [static] |
Autocreated peer objects
Definition at line 755 of file chan_sip.c.
char* app_dtmfmode = "SIPDtmfMode" [static] |
Definition at line 30251 of file chan_sip.c.
char* app_sipaddheader = "SIPAddHeader" [static] |
Definition at line 30252 of file chan_sip.c.
char* app_sipremoveheader = "SIPRemoveHeader" [static] |
Definition at line 30253 of file chan_sip.c.
struct sip_auth_container* authl = NULL [static] |
Authentication container for realm authentication.
Definition at line 1124 of file chan_sip.c.
int authlimit = DEFAULT_AUTHLIMIT [static] |
Definition at line 552 of file chan_sip.c.
int authtimeout = DEFAULT_AUTHTIMEOUT [static] |
Definition at line 553 of file chan_sip.c.
| struct ast_sockaddr bindaddr |
UDP: The address we bind to
Definition at line 1146 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), create_addr(), dialog_initialize_rtp(), get_address_family_filter(), initialize_udptl(), reload_config(), sip_show_settings(), and sipsock_read().
struct sip_peer* bogus_peer [static] |
A bogus peer, to be used when authentication should fail.
Definition at line 1103 of file chan_sip.c.
int can_parse_xml [static] |
We use libxml2 in order to parse XML that may appear in the body of a SIP message. Currently, the only usage is for parsing PIDF bodies of incoming PUBLISH requests in the call-completion event package. This variable is set at module load time and may be checked at runtime to determine if XML parsing support was found.
Definition at line 748 of file chan_sip.c.
struct epa_static_data cc_epa_static_data [static] |
Definition at line 887 of file chan_sip.c.
unsigned int chan_idx [static] |
used in naming sip channel
Definition at line 695 of file chan_sip.c.
struct ast_custom_function checksipdomain_function [static] |
{
.name = "CHECKSIPDOMAIN",
.read = func_check_sipdomain,
}
Definition at line 20106 of file chan_sip.c.
struct ast_cli_entry cli_sip[] [static] |
SIP Cli commands definition.
Definition at line 30828 of file chan_sip.c.
const char config[] = "sip.conf" [static] |
Main configuration file
Definition at line 567 of file chan_sip.c.
struct ast_sockaddr debugaddr [static] |
Definition at line 1190 of file chan_sip.c.
Referenced by sip_debug_test_addr(), sip_do_debug(), sip_do_debug_ip(), and sip_do_debug_peer().
char default_callerid[AST_MAX_EXTENSION] [static] |
Default caller ID for sip messages
Definition at line 668 of file chan_sip.c.
char default_engine[256] [static] |
Default RTP engine
Definition at line 679 of file chan_sip.c.
int default_expiry = DEFAULT_DEFAULT_EXPIRY [static] |
Definition at line 548 of file chan_sip.c.
Referenced by AST_TEST_DEFINE().
char default_fromdomain[AST_MAX_EXTENSION] [static] |
Default domain on outound messages
Definition at line 670 of file chan_sip.c.
int default_fromdomainport [static] |
Default domain port on outbound messages
Definition at line 671 of file chan_sip.c.
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled.
Definition at line 557 of file chan_sip.c.
char default_language[MAX_LANGUAGE] [static] |
Default language setting for new channels
Definition at line 667 of file chan_sip.c.
int default_maxcallbitrate [static] |
Maximum bitrate for call
Definition at line 680 of file chan_sip.c.
char default_mohinterpret[MAX_MUSICCLASS] [static] |
Global setting for moh class to use when put on hold
Definition at line 675 of file chan_sip.c.
char default_mohsuggest[MAX_MUSICCLASS] [static] |
Global setting for moh class to suggest when putting a bridged channel on hold
Definition at line 676 of file chan_sip.c.
char default_mwi_from[80] [static] |
Default caller ID for MWI updates
Definition at line 669 of file chan_sip.c.
char default_notifymime[AST_MAX_EXTENSION] [static] |
Default MIME media type for MWI notify messages
Definition at line 672 of file chan_sip.c.
char default_parkinglot[AST_MAX_CONTEXT] [static] |
Parkinglot
Definition at line 678 of file chan_sip.c.
struct ast_codec_pref default_prefs [static] |
Default codec prefs
Definition at line 681 of file chan_sip.c.
Referenced by reload_config(), set_peer_defaults(), sip_alloc(), sip_show_settings(), and temp_peer().
unsigned int default_primary_transport [static] |
Default primary Transport (enum sip_transport) for outbound connections to devices
Definition at line 683 of file chan_sip.c.
const int DEFAULT_PUBLISH_EXPIRES = 3600 [static] |
Definition at line 930 of file chan_sip.c.
int default_qualify [static] |
Default Qualify= setting
Definition at line 674 of file chan_sip.c.
struct ast_tls_config default_tls_cfg [static] |
Default TLS connection configuration.
Definition at line 2193 of file chan_sip.c.
unsigned int default_transports [static] |
Default Transports (enum sip_transport) that are acceptable
Definition at line 682 of file chan_sip.c.
char default_vmexten[AST_MAX_EXTENSION] [static] |
Default From Username on MWI updates
Definition at line 673 of file chan_sip.c.
struct ao2_container* dialogs [static] |
Here we implement the container for dialogs (sip_pvt), defining generic wrapper functions to ease the transition from the current implementation (a single linked list) to a different container. In addition to a reference to the container, we need functions to lock/unlock the container and individual items, and functions to add/remove references to the individual items.
Definition at line 1090 of file chan_sip.c.
| struct ao2_container* dialogs_to_destroy |
This container holds the dialogs that will be destroyed immediately.
Definition at line 1080 of file chan_sip.c.
struct _map_x_s dtmfstr[] [static] |
mapping between dtmf flags and strings
Definition at line 17559 of file chan_sip.c.
Referenced by conf_run(), and send_dtmf().
unsigned int dumphistory [static] |
Dump history to verbose before destroying SIP dialog
Definition at line 719 of file chan_sip.c.
int esc_etag_counter [static] |
Used to create new entity IDs by ESCs.
Definition at line 929 of file chan_sip.c.
const int ESC_MAX_BUCKETS = 37 [static] |
Definition at line 964 of file chan_sip.c.
struct event_state_compositor event_state_compositors[] [static] |
The Event State Compositors.
An Event State Compositor is an entity which accepts PUBLISH requests and acts appropriately based on these requests.
The actual event_state_compositor structure is simply an ao2_container of sip_esc_entrys. When an incoming PUBLISH is received, we can match the appropriate sip_esc_entry using the entity ID of the incoming PUBLISH.
Referenced by destroy_escs(), get_esc(), and initialize_escs().
struct ast_sockaddr externaddr [static] |
our external IP address/port for SIP sessions. externaddr.sin_addr is only set when we know we might be behind a NAT, and this is done using a variety of (mutually exclusive) ways from the config file:
+ with "externaddr = host[:port]" we specify the address/port explicitly. The address is looked up only once when (re)loading the config file;
+ with "externhost = host[:port]" we do a similar thing, but the hostname is stored in externhost, and the hostname->IP mapping is refreshed every 'externrefresh' seconds;
Other variables (externhost, externexpire, externrefresh) are used to support the above functions. External IP address if we are behind NAT
Definition at line 1171 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), reload_config(), and sip_show_settings().
time_t externexpire [static] |
Expiration counter for re-resolving external host name in dynamic DNS
Definition at line 1175 of file chan_sip.c.
char externhost[MAXHOSTNAMELEN] [static] |
External host name
Definition at line 1174 of file chan_sip.c.
int externrefresh = 10 [static] |
Refresh timer for DNS-based external address (dyndns)
Definition at line 1176 of file chan_sip.c.
uint16_t externtcpport [static] |
external tcp port
Definition at line 1177 of file chan_sip.c.
uint16_t externtlsport [static] |
external tls port
Definition at line 1178 of file chan_sip.c.
struct _map_x_s faxecmodes[] [static] |
Definition at line 18047 of file chan_sip.c.
int global_authfailureevents [static] |
Whether we send authentication failure manager events or not. Default no.
Definition at line 723 of file chan_sip.c.
unsigned int global_autoframing [static] |
Turn autoframing on or off.
Definition at line 727 of file chan_sip.c.
int global_callcounter [static] |
Enable call counters for all devices. This is currently enabled by setting the peer call-limit to INT_MAX. When we remove the call-limit from the code, we can make it with just a boolean flag in the device structure
Definition at line 707 of file chan_sip.c.
unsigned int global_cos_audio [static] |
802.1p class of service for audio RTP packets
Definition at line 715 of file chan_sip.c.
unsigned int global_cos_sip [static] |
802.1p class of service for SIP packets
Definition at line 714 of file chan_sip.c.
unsigned int global_cos_text [static] |
802.1p class of service for text RTP packets
Definition at line 717 of file chan_sip.c.
unsigned int global_cos_video [static] |
802.1p class of service for video RTP packets
Definition at line 716 of file chan_sip.c.
int global_dynamic_exclude_static = 0 [static] |
Exclude static peers from contact registrations
Definition at line 739 of file chan_sip.c.
struct ast_flags global_flags[3] = {{0}} [static] |
global SIP_ flags
Definition at line 759 of file chan_sip.c.
struct ast_jb_conf global_jbconf [static] |
Global jitterbuffer configuration
Definition at line 565 of file chan_sip.c.
Referenced by reload_config(), sip_get_rtp_peer(), sip_new(), and sip_show_settings().
int global_match_auth_username [static] |
Match auth username if available instead of From: Default off.
Definition at line 696 of file chan_sip.c.
int global_max_se [static] |
Highest threshold for session refresh interval
Definition at line 735 of file chan_sip.c.
int global_min_se [static] |
Lowest threshold for session refresh interval
Definition at line 734 of file chan_sip.c.
int global_prematuremediafilter [static] |
Enable/disable premature frames in a call (causing 183 early media)
Definition at line 699 of file chan_sip.c.
int global_qualify_gap [static] |
Time between our group of peer pokes
Definition at line 729 of file chan_sip.c.
int global_qualify_peers [static] |
Number of peers to poke at a given time
Definition at line 730 of file chan_sip.c.
int global_qualifyfreq [static] |
Qualify frequency
Definition at line 728 of file chan_sip.c.
int global_reg_retry_403 [static] |
Treat 403 responses to registrations as 401 responses
Definition at line 705 of file chan_sip.c.
int global_reg_timeout [static] |
Global time between attempts for outbound registrations
Definition at line 703 of file chan_sip.c.
int global_regattempts_max [static] |
Registration attempts before giving up
Definition at line 704 of file chan_sip.c.
int global_relaxdtmf [static] |
Relax DTMF
Definition at line 698 of file chan_sip.c.
int global_rtpholdtimeout [static] |
Time out call if no RTP during hold
Definition at line 701 of file chan_sip.c.
int global_rtpkeepalive [static] |
Send RTP keepalives
Definition at line 702 of file chan_sip.c.
int global_rtptimeout [static] |
Time out call if no RTP
Definition at line 700 of file chan_sip.c.
char global_sdpowner[AST_MAX_EXTENSION] [static] |
SDP owner name for the SIP channel
Definition at line 722 of file chan_sip.c.
char global_sdpsession[AST_MAX_EXTENSION] [static] |
SDP session name for the SIP channel
Definition at line 721 of file chan_sip.c.
int global_shrinkcallerid [static] |
enable or disable shrinking of caller id
Definition at line 706 of file chan_sip.c.
enum st_mode global_st_mode [static] |
Mode of operation for Session-Timers
Definition at line 732 of file chan_sip.c.
enum st_refresher_param global_st_refresher [static] |
Session-Timer refresher
Definition at line 733 of file chan_sip.c.
int global_store_sip_cause [static] |
Whether the MASTER_CHANNEL(HASH(SIP_CAUSE,[chan_name])) var should be set
Definition at line 737 of file chan_sip.c.
int global_t1 [static] |
T1 time
Definition at line 724 of file chan_sip.c.
int global_t1min [static] |
T1 roundtrip time minimum
Definition at line 725 of file chan_sip.c.
unsigned int global_t38_maxdatagram [static] |
global T.38 FaxMaxDatagram override
Definition at line 760 of file chan_sip.c.
int global_timer_b [static] |
Timer B - RFC 3261 Section 17.1.1.2
Definition at line 726 of file chan_sip.c.
unsigned int global_tos_audio [static] |
IP type of service for audio RTP packets
Definition at line 711 of file chan_sip.c.
unsigned int global_tos_sip [static] |
IP type of service for SIP packets
Definition at line 710 of file chan_sip.c.
unsigned int global_tos_text [static] |
IP type of service for text RTP packets
Definition at line 713 of file chan_sip.c.
unsigned int global_tos_video [static] |
IP type of service for video RTP packets
Definition at line 712 of file chan_sip.c.
char global_useragent[AST_MAX_EXTENSION] [static] |
Useragent for the SIP channel
Definition at line 720 of file chan_sip.c.
const int HASH_DIALOG_SIZE = 563 [static] |
Definition at line 817 of file chan_sip.c.
const int HASH_PEER_SIZE = 563 [static] |
Size of peer hash table, prime number preferred!
Definition at line 816 of file chan_sip.c.
struct _map_x_s insecurestr[] [static] |
Definition at line 17580 of file chan_sip.c.
struct ast_sockaddr internip [static] |
our (internal) default address/port to put in SIP/SDP messages internip is initialized picking a suitable address from one of the interfaces, and the same port number we bind to. It is used as the default address/port in SIP messages, and as the default address (but not port) in SDP messages.
Definition at line 1154 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), reload_config(), sip_alloc(), transmit_register(), and transmit_response_using_temp().
struct invstate2stringtable invitestate2string[] [static] |
Readable descriptions of device states.
Referenced by show_chanstats_cb().
struct io_context* io [static] |
The IO context
Definition at line 783 of file chan_sip.c.
List of local networks We store "localnet" addresses from the config file into an access list, marked as 'DENY', so the call to ast_apply_ha() will return AST_SENSE_DENY for 'local' addresses, and AST_SENSE_ALLOW for 'non local' (i.e. presumably public) addresses.
List of local networks, on the same side of NAT as this Asterisk
Definition at line 1186 of file chan_sip.c.
int max_expiry = DEFAULT_MAX_EXPIRY [static] |
Maximum accepted registration time
Definition at line 547 of file chan_sip.c.
struct ast_sockaddr media_address [static] |
External RTP IP address if we are behind NAT
Definition at line 1172 of file chan_sip.c.
Referenced by get_our_media_address(), and reload_config().
int min_expiry = DEFAULT_MIN_EXPIRY [static] |
Minimum accepted registration time
Definition at line 546 of file chan_sip.c.
pthread_t monitor_thread = AST_PTHREADT_NULL [static] |
This is the thread for the monitor which checks for input on the channels which are not currently in use.
Definition at line 777 of file chan_sip.c.
int mwi_expiry = DEFAULT_MWI_EXPIRY [static] |
Definition at line 549 of file chan_sip.c.
int network_change_event_sched_id = -1 [static] |
Definition at line 763 of file chan_sip.c.
struct ast_event_sub* network_change_event_subscription [static] |
subscription id for network change events
Definition at line 762 of file chan_sip.c.
const char notify_config[] = "sip_notify.conf" [static] |
Configuration file for sending Notify with CLI commands to reconfigure or reboot phones
Definition at line 568 of file chan_sip.c.
struct ast_config* notify_types = NULL [static] |
The list of manual NOTIFY types we know how to send
Definition at line 1192 of file chan_sip.c.
int ourport_tcp [static] |
The port used for TCP connections
Definition at line 1188 of file chan_sip.c.
int ourport_tls [static] |
The port used for TCP/TLS connections
Definition at line 1189 of file chan_sip.c.
struct ao2_container* peers [static] |
The peer list: Users, Peers and Friends.
Definition at line 1099 of file chan_sip.c.
struct ao2_container* peers_by_ip [static] |
Definition at line 1100 of file chan_sip.c.
struct ast_data_handler peers_data_provider [static] |
{
.version = AST_DATA_HANDLER_VERSION,
.get = peers_data_provider_get
}
Definition at line 31777 of file chan_sip.c.
unsigned int recordhistory [static] |
Record SIP history. Off by default
Definition at line 718 of file chan_sip.c.
struct _map_x_s referstatusstrings[] [static] |
Definition at line 798 of file chan_sip.c.
struct ast_register_list regl [static] |
The register list: Other SIP proxies we register with and receive calls from.
Referenced by cleanup_all_regs(), load_module(), manager_show_registry(), reload_config(), sip_register(), sip_send_all_registers(), sip_show_objects(), sip_show_registry(), and unload_module().
int regobjs = 0 [static] |
Registry objects
Definition at line 756 of file chan_sip.c.
struct _map_x_s regstatestrings[] [static] |
Definition at line 13545 of file chan_sip.c.
int rpeerobjs = 0 [static] |
Realtime peers
Definition at line 754 of file chan_sip.c.
| struct sched_context* sched |
The scheduling context
Definition at line 782 of file chan_sip.c.
Definition at line 821 of file chan_sip.c.
Referenced by cc_generic_monitor_request_cc(), create_addr(), launch_ha_netscript(), service_string_to_service_type(), and sip_cc_monitor_request_cc().
| const char* service_string |
Definition at line 822 of file chan_sip.c.
struct ast_cc_agent_callbacks sip_cc_agent_callbacks [static] |
Definition at line 1642 of file chan_sip.c.
struct ast_cc_monitor_callbacks sip_cc_monitor_callbacks [static] |
Definition at line 1909 of file chan_sip.c.
struct { ... } sip_cc_notify_state_map[] [static] |
Referenced by transmit_cc_notify().
struct { ... } sip_cc_service_map[] [static] |
Referenced by service_string_to_service_type().
struct sip_settings sip_cfg [static] |
SIP configuration data.
Definition at line 686 of file chan_sip.c.
Referenced by __get_header(), __sip_subscribe_mwi_do(), _sip_show_peer(), add_header(), ast_sip_ouraddrfor(), build_peer(), change_hold_state(), check_peer_ok(), check_user_full(), create_addr(), destroy_association(), do_magic_pickup(), find_call(), find_calling_channel(), get_also_info(), get_destination(), get_realm(), get_refer_info(), get_sip_pvt_byid_locked(), handle_incoming(), handle_request_bye(), handle_request_do(), handle_request_invite(), handle_request_options(), handle_request_refer(), handle_request_subscribe(), handle_response_invite(), handle_response_peerpoke(), initreqprep(), obproxy_get(), parse_register_contact(), parse_uri_legacy_check(), proxy_update(), read_raw_content_length(), realtime_peer(), realtime_update_peer(), ref_proxy(), reg_source_db(), register_peer_exten(), register_verify(), reload_config(), set_peer_defaults(), sip_alloc(), sip_new(), sip_poke_noanswer(), sip_request_call(), sip_set_rtp_peer(), sip_show_settings(), state_notify_build_xml(), transmit_register(), unload_module(), update_call_counter(), and update_peer().
struct ast_data_entry sip_data_providers[] [static] |
{
AST_DATA_ENTRY("asterisk/channel/sip/peers", &peers_data_provider),
}
Definition at line 31782 of file chan_sip.c.
struct ast_custom_function sip_header_function [static] |
{
.name = "SIP_HEADER",
.read = func_header_read,
}
Definition at line 20087 of file chan_sip.c.
struct cfsip_methods sip_methods[] [static] |
The core structure to setup dialogs. We parse incoming messages by using structure and then route the messages according to the type.
Referenced by __sip_autodestruct(), __sip_destroy(), __sip_pretend_ack(), __sip_semi_ack(), build_reply_digest(), check_auth(), dialog_initialize_rtp(), dialog_needdestroy(), do_proxy_auth(), find_call(), find_sip_method(), get_destination(), handle_incoming(), handle_request_bye(), handle_request_invite(), handle_request_register(), handle_request_subscribe(), handle_response(), handle_response_info(), handle_response_message(), init_req(), initialize_initreq(), initreqprep(), method_match(), reqprep(), retrans_pkt(), send_request(), send_response(), sip_alloc(), sip_scheddestroy(), and transmit_register().
| struct ao2_container* sip_monitor_instances |
Definition at line 1836 of file chan_sip.c.
struct sip_reasons sip_reason_table[] [static] |
Diversion header reasons.
The core defines a bunch of constants used to define redirecting reasons. This provides a translation table between those and the strings which may be present in a SIP Diversion header
Referenced by sip_reason_code_to_str(), and sip_reason_str_to_code().
int sip_reloading = FALSE [static] |
Flag for avoiding multiple reloads at the same time
Definition at line 779 of file chan_sip.c.
enum channelreloadreason sip_reloadreason [static] |
Reason for last reload/load of configuration
Definition at line 780 of file chan_sip.c.
struct ast_rtp_glue sip_rtp_glue [static] |
Definition at line 30242 of file chan_sip.c.
struct ast_tcptls_session_args sip_tcp_desc [static] |
The TCP server definition.
Definition at line 2196 of file chan_sip.c.
| struct ast_channel_tech sip_tech |
Definition of this channel for PBX channel registration.
Definition at line 1596 of file chan_sip.c.
| 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.
Definition at line 1631 of file chan_sip.c.
Referenced by load_module(), sip_get_rtp_peer(), sip_get_trtp_peer(), sip_get_udptl_peer(), sip_get_vrtp_peer(), and sip_new().
struct ast_tls_config sip_tls_cfg [static] |
Working TLS connection configuration.
Definition at line 2190 of file chan_sip.c.
struct ast_tcptls_session_args sip_tls_desc [static] |
The TCP/TLS server definition.
Definition at line 2207 of file chan_sip.c.
struct ast_udptl_protocol sip_udptl [static] |
{
.type = "SIP",
.get_udptl_info = sip_get_udptl_peer,
.set_udptl_peer = sip_set_udptl_peer,
}
Interface structure with callbacks used to connect to UDPTL module.
Definition at line 3178 of file chan_sip.c.
struct ast_custom_function sipchaninfo_function [static] |
{
.name = "SIPCHANINFO",
.read = function_sipchaninfo_read,
}
Structure to declare a dialplan function: SIPCHANINFO.
Definition at line 20276 of file chan_sip.c.
enum sip_debug_e sipdebug [static] |
Definition at line 790 of file chan_sip.c.
int sipdebug_text [static] |
extra debugging for 'text' related events. At the moment this is set together with sip_debug_console.
Definition at line 796 of file chan_sip.c.
struct ast_custom_function sippeer_function [static] |
{
.name = "SIPPEER",
.read = function_sippeer,
}
Structure to declare a dialplan function: SIPPEER.
Definition at line 20205 of file chan_sip.c.
int sipsock = -1 [static] |
Main socket for UDP SIP communication.
sipsock is shared between the SIP manager thread (which handles reload requests), the udp io handler (sipsock_read()) and the user routines that issue udp writes (using __sip_xmit()). The socket is -1 only when opening fails (this is a permanent condition), or when we are handling a reload() that changes its address (this is a transient situation during which we might have a harmless race, see below). Because the conditions for the race to be possible are extremely rare, we don't want to pay the cost of locking on every I/O. Rather, we remember that when the race may occur, communication is bound to fail anyways, so we just live with this event and let the protocol handle this above us.
Definition at line 1144 of file chan_sip.c.
int* sipsock_read_id [static] |
ID of IO entry for sipsock FD
Definition at line 784 of file chan_sip.c.
int speerobjs = 0 [static] |
Static peers
Definition at line 753 of file chan_sip.c.
| enum sip_cc_notify_state state |
Definition at line 842 of file chan_sip.c.
| const char* state_string |
Definition at line 843 of file chan_sip.c.
Referenced by transmit_cc_notify().
struct _map_x_s stmodes[] [static] |
Report Peer status in character string.
Definition at line 17004 of file chan_sip.c.
struct _map_x_s strefresher_params[] [static] |
Definition at line 17022 of file chan_sip.c.
struct _map_x_s strefreshers[] [static] |
Definition at line 17029 of file chan_sip.c.
struct ast_subscription_mwi_list submwil [static] |
The MWI subscription list.
Referenced by load_module(), sip_send_all_mwi_subscriptions(), sip_show_mwi(), sip_subscribe_mwi(), and unload_module().
struct cfsubscription_types subscription_types[] [static] |
Subscription types that we support. We support
Referenced by find_subscription_type(), and subscription_type2str().
struct ao2_container* threadt [static] |
The table of TCP threads.
Definition at line 1096 of file chan_sip.c.
struct _map_x_s trust_id_outboundstr[] [static] |
Definition at line 17607 of file chan_sip.c.
int unauth_sessions = 0 [static] |
Definition at line 551 of file chan_sip.c.
char used_context[AST_MAX_CONTEXT] [static] |
name of automatically created context for unloading
Definition at line 765 of file chan_sip.c.
1.6.1