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 | 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_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 "%-25.25s %-39.39s %-3.3s %-10.10s %-3.3s %-8s %-10s %s\n" |
| #define | FORMAT2 "%-47.47s %9.9s %6.6s\n" |
| #define | FORMAT2 "%-25.25s %-15.15s %-15.15s \n" |
| #define | FORMAT3 "%-15.15s %-15.15s %-15.15s %-15.15s %-13.13s %-15.15s %-10.10s %-6.6s\n" |
| #define | FORMAT4 "%-15.15s %-15.15s %-15.15s %-15.15s %-13.13s %-15.15s %-10.10s %-6.6d\n" |
| #define | sip_pvt_lock(x) ao2_lock(x) |
| #define | sip_pvt_trylock(x) ao2_trylock(x) |
| #define | sip_pvt_unlock(x) ao2_unlock(x) |
| #define | UNLINK(element, head, prev) |
| enum | match_req_res { SIP_REQ_MATCH, SIP_REQ_NOT_MATCH, SIP_REQ_LOOP_DETECTED } |
| 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 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 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 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 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, 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_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, 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 int | sip_tcp_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 connection. | |
| static void * | sip_tcp_worker_fn (void *data) |
| SIP TCP connection handler. | |
| static void | sip_tcptls_client_args_destructor (void *obj) |
| static int | sip_tcptls_write (struct ast_tcptls_session_instance *tcptls_session, const void *buf, size_t len) |
| used to indicate to a tcptls thread that data is ready to be written | |
| static struct sip_threadinfo * | sip_threadinfo_create (struct ast_tcptls_session_instance *tcptls_session, int transport) |
| creates a sip_threadinfo object and links it into the threadt table. | |
| static void | sip_threadinfo_destructor (void *obj) |
| static int | sip_tls_read (struct sip_request *req, struct sip_request *reqcpy, struct ast_tcptls_session_instance *tcptls_session, int authenticated, time_t start, struct sip_threadinfo *me) |
| Read a SIP request or response from a TLS connection. | |
| 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 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 2226 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 1116 of file chan_sip.c.
Referenced by check_auth(), load_module(), and sip_reload().
| #define CHECK_AUTH_BUF_INITLEN 256 |
Definition at line 14868 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 2309 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 8001 of file chan_sip.c.
Referenced by change_callid_pvt().
| #define DATA_EXPORT_SIP_PEER | ( | MEMBER | ) |
Definition at line 31511 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 18975 of file chan_sip.c.
| #define FORMAT "%-30.30s %-12.12s %-10.10s %-10.10s\n" |
Definition at line 18975 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 18975 of file chan_sip.c.
| #define FORMAT "%-39.39s %-6.6s %-12.12s %8d %-20.20s %-25.25s\n" |
Definition at line 18975 of file chan_sip.c.
| #define FORMAT "%-40.40s %-20.20s %-16.16s\n" |
Definition at line 18975 of file chan_sip.c.
| #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" |
Definition at line 18975 of file chan_sip.c.
| #define FORMAT "%-47.47s %-9.9s %-6.6s\n" |
Definition at line 18975 of file chan_sip.c.
| #define FORMAT "%-25.25s %-15.15s %-15.15s \n" |
Definition at line 18975 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 18974 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 18974 of file chan_sip.c.
| #define FORMAT2 "%-39.39s %-6.6s %-12.12s %8.8s %-20.20s %-25.25s\n" |
Definition at line 18974 of file chan_sip.c.
| #define FORMAT2 "%-25.25s %-39.39s %-3.3s %-10.10s %-3.3s %-8s %-10s %s\n" |
Definition at line 18974 of file chan_sip.c.
| #define FORMAT2 "%-47.47s %9.9s %6.6s\n" |
Definition at line 18974 of file chan_sip.c.
| #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" |
Definition at line 18974 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 18973 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 18972 of file chan_sip.c.
Referenced by show_channels_cb().
| #define SIP_PEDANTIC_DECODE | ( | str | ) |
if (sip_cfg.pedanticsipchecking && !ast_strlen_zero(str)) { \ ast_uri_decode(str); \ } \
Definition at line 702 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 1102 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 1103 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 1104 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 1207 of file chan_sip.c.
Referenced by __sip_ack(), handle_request_cancel(), and retrans_pkt().
| enum match_req_res |
Definition at line 8292 of file chan_sip.c.
08292 { 08293 SIP_REQ_MATCH, 08294 SIP_REQ_NOT_MATCH, 08295 SIP_REQ_LOOP_DETECTED, 08296 };
| 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 2661 of file chan_sip.c.
02661 { 02662 /*! 02663 * The message has an error in it with 02664 * regards to its Content-Length header 02665 */ 02666 MESSAGE_INVALID, 02667 /*! 02668 * The message is incomplete 02669 */ 02670 MESSAGE_FRAGMENT, 02671 /*! 02672 * The data contains a complete message 02673 * plus a fragment of another. 02674 */ 02675 MESSAGE_FRAGMENT_COMPLETE, 02676 /*! 02677 * The message is complete 02678 */ 02679 MESSAGE_COMPLETE, 02680 };
| enum peer_unlink_flag_t |
Definition at line 3153 of file chan_sip.c.
03153 { 03154 SIP_PEERS_MARKED, 03155 SIP_PEERS_ALL, 03156 } peer_unlink_flag_t;
| static const char * __get_header | ( | const struct sip_request * | req, | |
| const char * | name, | |||
| int * | start | |||
| ) | [static] |
Definition at line 7769 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().
07770 { 07771 /* 07772 * Technically you can place arbitrary whitespace both before and after the ':' in 07773 * a header, although RFC3261 clearly says you shouldn't before, and place just 07774 * one afterwards. If you shouldn't do it, what absolute idiot decided it was 07775 * a good idea to say you can do it, and if you can do it, why in the hell would. 07776 * you say you shouldn't. 07777 * Anyways, pedanticsipchecking controls whether we allow spaces before ':', 07778 * and we always allow spaces after that for compatibility. 07779 */ 07780 const char *sname = find_alias(name, NULL); 07781 int x, len = strlen(name), slen = (sname ? 1 : 0); 07782 for (x = *start; x < req->headers; x++) { 07783 const char *header = REQ_OFFSET_TO_STR(req, header[x]); 07784 int smatch = 0, match = !strncasecmp(header, name, len); 07785 if (slen) { 07786 smatch = !strncasecmp(header, sname, slen); 07787 } 07788 if (match || smatch) { 07789 /* skip name */ 07790 const char *r = header + (match ? len : slen ); 07791 if (sip_cfg.pedanticsipchecking) { 07792 r = ast_skip_blanks(r); 07793 } 07794 07795 if (*r == ':') { 07796 *start = x+1; 07797 return ast_skip_blanks(r+1); 07798 } 07799 } 07800 } 07801 07802 /* Don't return NULL, so get_header is always a valid pointer */ 07803 return ""; 07804 }
| static int __set_address_from_contact | ( | const char * | fullcontact, | |
| struct ast_sockaddr * | addr, | |||
| int | tcp | |||
| ) | [static] |
Definition at line 14431 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().
14432 { 14433 char *hostport, *transport; 14434 char contact_buf[256]; 14435 char *contact; 14436 14437 /* Work on a copy */ 14438 ast_copy_string(contact_buf, fullcontact, sizeof(contact_buf)); 14439 contact = contact_buf; 14440 14441 /* 14442 * We have only the part in <brackets> here so we just need to parse a SIP URI. 14443 * 14444 * Note: The outbound proxy could be using UDP between the proxy and Asterisk. 14445 * We still need to be able to send to the remote agent through the proxy. 14446 */ 14447 14448 if (parse_uri_legacy_check(contact, "sip:,sips:", &contact, NULL, &hostport, 14449 &transport)) { 14450 ast_log(LOG_WARNING, "Invalid contact uri %s (missing sip: or sips:), attempting to use anyway\n", fullcontact); 14451 } 14452 14453 /* XXX This could block for a long time XXX */ 14454 /* We should only do this if it's a name, not an IP */ 14455 /* \todo - if there's no PORT number in contact - we are required to check NAPTR/SRV records 14456 to find transport, port address and hostname. If there's a port number, we have to 14457 assume that the hostport part is a host name and only look for an A/AAAA record in DNS. 14458 */ 14459 14460 /* If we took in an invalid URI, hostport may not have been initialized */ 14461 /* ast_sockaddr_resolve requires an initialized hostport string. */ 14462 if (ast_strlen_zero(hostport)) { 14463 ast_log(LOG_WARNING, "Invalid URI: parse_uri failed to acquire hostport\n"); 14464 return -1; 14465 } 14466 14467 if (ast_sockaddr_resolve_first_transport(addr, hostport, 0, get_transport_str2enum(transport))) { 14468 ast_log(LOG_WARNING, "Invalid host name in Contact: (can't " 14469 "resolve in DNS) : '%s'\n", hostport); 14470 return -1; 14471 } 14472 14473 /* set port */ 14474 if (!ast_sockaddr_port(addr)) { 14475 ast_sockaddr_set_port(addr, 14476 (get_transport_str2enum(transport) == 14477 SIP_TRANSPORT_TLS || 14478 !strncasecmp(fullcontact, "sips", 4)) ? 14479 STANDARD_TLS_PORT : STANDARD_SIP_PORT); 14480 } 14481 14482 return 0; 14483 }
| 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 4308 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().
04309 { 04310 struct sip_pkt *cur, *prev = NULL; 04311 const char *msg = "Not Found"; /* used only for debugging */ 04312 int res = FALSE; 04313 04314 /* If we have an outbound proxy for this dialog, then delete it now since 04315 the rest of the requests in this dialog needs to follow the routing. 04316 If obforcing is set, we will keep the outbound proxy during the whole 04317 dialog, regardless of what the SIP rfc says 04318 */ 04319 if (p->outboundproxy && !p->outboundproxy->force){ 04320 ref_proxy(p, NULL); 04321 } 04322 04323 for (cur = p->packets; cur; prev = cur, cur = cur->next) { 04324 if (cur->seqno != seqno || cur->is_resp != resp) { 04325 continue; 04326 } 04327 if (cur->is_resp || cur->method == sipmethod) { 04328 res = TRUE; 04329 msg = "Found"; 04330 if (!resp && (seqno == p->pendinginvite)) { 04331 ast_debug(1, "Acked pending invite %u\n", p->pendinginvite); 04332 p->pendinginvite = 0; 04333 } 04334 if (cur->retransid > -1) { 04335 if (sipdebug) 04336 ast_debug(4, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid); 04337 } 04338 /* This odd section is designed to thwart a 04339 * race condition in the packet scheduler. There are 04340 * two conditions under which deleting the packet from the 04341 * scheduler can fail. 04342 * 04343 * 1. The packet has been removed from the scheduler because retransmission 04344 * is being attempted. The problem is that if the packet is currently attempting 04345 * retransmission and we are at this point in the code, then that MUST mean 04346 * that retrans_pkt is waiting on p's lock. Therefore we will relinquish the 04347 * lock temporarily to allow retransmission. 04348 * 04349 * 2. The packet has reached its maximum number of retransmissions and has 04350 * been permanently removed from the packet scheduler. If this is the case, then 04351 * the packet's retransid will be set to -1. The atomicity of the setting and checking 04352 * of the retransid to -1 is ensured since in both cases p's lock is held. 04353 */ 04354 while (cur->retransid > -1 && ast_sched_del(sched, cur->retransid)) { 04355 sip_pvt_unlock(p); 04356 usleep(1); 04357 sip_pvt_lock(p); 04358 } 04359 UNLINK(cur, p->packets, prev); 04360 dialog_unref(cur->owner, "unref pkt cur->owner dialog from sip ack before freeing pkt"); 04361 if (cur->data) { 04362 ast_free(cur->data); 04363 } 04364 ast_free(cur); 04365 break; 04366 } 04367 } 04368 ast_debug(1, "Stopping retransmission on '%s' of %s %u: Match %s\n", 04369 p->callid, resp ? "Response" : "Request", seqno, msg); 04370 return res; 04371 }
| 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 4171 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().
04172 { 04173 struct sip_pvt *p = (struct sip_pvt *)data; 04174 struct ast_channel *owner; 04175 04176 /* If this is a subscription, tell the phone that we got a timeout */ 04177 if (p->subscribed && p->subscribed != MWI_NOTIFICATION && p->subscribed != CALL_COMPLETION) { 04178 transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE); /* Send last notification */ 04179 p->subscribed = NONE; 04180 append_history(p, "Subscribestatus", "timeout"); 04181 ast_debug(3, "Re-scheduled destruction of SIP subscription %s\n", p->callid ? p->callid : "<unknown>"); 04182 return 10000; /* Reschedule this destruction so that we know that it's gone */ 04183 } 04184 04185 /* If there are packets still waiting for delivery, delay the destruction */ 04186 if (p->packets) { 04187 if (!p->needdestroy) { 04188 char method_str[31]; 04189 ast_debug(3, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>"); 04190 append_history(p, "ReliableXmit", "timeout"); 04191 if (sscanf(p->lastmsg, "Tx: %30s", method_str) == 1 || sscanf(p->lastmsg, "Rx: %30s", method_str) == 1) { 04192 if (p->ongoing_reinvite || method_match(SIP_CANCEL, method_str) || method_match(SIP_BYE, method_str)) { 04193 pvt_set_needdestroy(p, "autodestruct"); 04194 } 04195 } 04196 return 10000; 04197 } else { 04198 /* They've had their chance to respond. Time to bail */ 04199 __sip_pretend_ack(p); 04200 } 04201 } 04202 04203 /* Reset schedule ID */ 04204 p->autokillid = -1; 04205 04206 /* 04207 * Lock both the pvt and the channel safely so that we can queue up a frame. 04208 */ 04209 owner = sip_pvt_lock_full(p); 04210 if (owner) { 04211 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); 04212 ast_queue_hangup_with_cause(owner, AST_CAUSE_PROTOCOL_ERROR); 04213 ast_channel_unlock(owner); 04214 ast_channel_unref(owner); 04215 sip_pvt_unlock(p); 04216 return 10000; 04217 } else if (p->refer && !p->alreadygone) { 04218 ast_debug(3, "Finally hanging up channel after transfer: %s\n", p->callid); 04219 stop_media_flows(p); 04220 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 04221 append_history(p, "ReferBYE", "Sending BYE on transferer call leg %s", p->callid); 04222 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 04223 } else { 04224 append_history(p, "AutoDestroy", "%s", p->callid); 04225 ast_debug(3, "Auto destroying SIP dialog '%s'\n", p->callid); 04226 sip_pvt_unlock(p); 04227 dialog_unlink_all(p); /* once it's unlinked and unrefd everywhere, it'll be freed automagically */ 04228 sip_pvt_lock(p); 04229 /* dialog_unref(p, "unref dialog-- no other matching conditions"); -- unlink all now should finish off the dialog's references and free it. */ 04230 /* sip_destroy(p); */ /* Go ahead and destroy dialog. All attempts to recover is done */ 04231 /* sip_destroy also absorbs the reference */ 04232 } 04233 04234 sip_pvt_unlock(p); 04235 04236 dialog_unref(p, "The ref to a dialog passed to this sched callback is going out of scope; unref it."); 04237 04238 return 0; 04239 }
| void __sip_destroy | ( | struct sip_pvt * | p, | |
| int | lockowner, | |||
| int | lockdialoglist | |||
| ) |
Execute destruction of SIP dialog structure, release memory.
Definition at line 6116 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().
06117 { 06118 struct sip_request *req; 06119 06120 /* Destroy Session-Timers if allocated */ 06121 if (p->stimer) { 06122 p->stimer->quit_flag = 1; 06123 stop_session_timer(p); 06124 ast_free(p->stimer); 06125 p->stimer = NULL; 06126 } 06127 06128 if (sip_debug_test_pvt(p)) 06129 ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 06130 06131 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 06132 update_call_counter(p, DEC_CALL_LIMIT); 06133 ast_debug(2, "This call did not properly clean up call limits. Call ID %s\n", p->callid); 06134 } 06135 06136 /* Unlink us from the owner if we have one */ 06137 if (p->owner) { 06138 if (lockowner) 06139 ast_channel_lock(p->owner); 06140 ast_debug(1, "Detaching from %s\n", p->owner->name); 06141 p->owner->tech_pvt = NULL; 06142 /* Make sure that the channel knows its backend is going away */ 06143 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 06144 if (lockowner) 06145 ast_channel_unlock(p->owner); 06146 /* Give the channel a chance to react before deallocation */ 06147 usleep(1); 06148 } 06149 06150 /* Remove link from peer to subscription of MWI */ 06151 if (p->relatedpeer && p->relatedpeer->mwipvt == p) 06152 p->relatedpeer->mwipvt = dialog_unref(p->relatedpeer->mwipvt, "delete ->relatedpeer->mwipvt"); 06153 if (p->relatedpeer && p->relatedpeer->call == p) 06154 p->relatedpeer->call = dialog_unref(p->relatedpeer->call, "unset the relatedpeer->call field in tandem with relatedpeer field itself"); 06155 06156 if (p->relatedpeer) 06157 p->relatedpeer = unref_peer(p->relatedpeer,"unsetting a dialog relatedpeer field in sip_destroy"); 06158 06159 if (p->registry) { 06160 if (p->registry->call == p) 06161 p->registry->call = dialog_unref(p->registry->call, "nulling out the registry's call dialog field in unlink_all"); 06162 p->registry = registry_unref(p->registry, "delete p->registry"); 06163 } 06164 06165 if (p->mwi) { 06166 p->mwi->call = NULL; 06167 p->mwi = NULL; 06168 } 06169 06170 if (dumphistory) 06171 sip_dump_history(p); 06172 06173 if (p->options) { 06174 if (p->options->outboundproxy) { 06175 ao2_ref(p->options->outboundproxy, -1); 06176 } 06177 ast_free(p->options); 06178 p->options = NULL; 06179 } 06180 06181 if (p->notify) { 06182 ast_variables_destroy(p->notify->headers); 06183 ast_free(p->notify->content); 06184 ast_free(p->notify); 06185 p->notify = NULL; 06186 } 06187 if (p->rtp) { 06188 ast_rtp_instance_destroy(p->rtp); 06189 p->rtp = NULL; 06190 } 06191 if (p->vrtp) { 06192 ast_rtp_instance_destroy(p->vrtp); 06193 p->vrtp = NULL; 06194 } 06195 if (p->trtp) { 06196 ast_rtp_instance_destroy(p->trtp); 06197 p->trtp = NULL; 06198 } 06199 if (p->udptl) { 06200 ast_udptl_destroy(p->udptl); 06201 p->udptl = NULL; 06202 } 06203 if (p->refer) { 06204 if (p->refer->refer_call) { 06205 p->refer->refer_call = dialog_unref(p->refer->refer_call, "unref dialog p->refer->refer_call"); 06206 } 06207 ast_free(p->refer); 06208 p->refer = NULL; 06209 } 06210 if (p->route) { 06211 free_old_route(p->route); 06212 p->route = NULL; 06213 } 06214 deinit_req(&p->initreq); 06215 06216 /* Clear history */ 06217 if (p->history) { 06218 struct sip_history *hist; 06219 while ( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) { 06220 ast_free(hist); 06221 p->history_entries--; 06222 } 06223 ast_free(p->history); 06224 p->history = NULL; 06225 } 06226 06227 while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) { 06228 ast_free(req); 06229 } 06230 06231 if (p->chanvars) { 06232 ast_variables_destroy(p->chanvars); 06233 p->chanvars = NULL; 06234 } 06235 06236 if (p->srtp) { 06237 sip_srtp_destroy(p->srtp); 06238 p->srtp = NULL; 06239 } 06240 06241 if (p->vsrtp) { 06242 sip_srtp_destroy(p->vsrtp); 06243 p->vsrtp = NULL; 06244 } 06245 06246 if (p->tsrtp) { 06247 sip_srtp_destroy(p->tsrtp); 06248 p->tsrtp = NULL; 06249 } 06250 06251 if (p->directmediaha) { 06252 ast_free_ha(p->directmediaha); 06253 p->directmediaha = NULL; 06254 } 06255 06256 ast_string_field_free_memory(p); 06257 06258 ast_cc_config_params_destroy(p->cc_params); 06259 p->cc_params = NULL; 06260 06261 if (p->epa_entry) { 06262 ao2_ref(p->epa_entry, -1); 06263 p->epa_entry = NULL; 06264 } 06265 06266 if (p->socket.tcptls_session) { 06267 ao2_ref(p->socket.tcptls_session, -1); 06268 p->socket.tcptls_session = NULL; 06269 } 06270 06271 if (p->peerauth) { 06272 ao2_t_ref(p->peerauth, -1, "Removing active peer authentication"); 06273 p->peerauth = NULL; 06274 } 06275 }
| static int __sip_do_register | ( | struct sip_registry * | r | ) | [static] |
Register with SIP proxy.
Definition at line 13641 of file chan_sip.c.
References transmit_register().
Referenced by sip_reregister().
13642 { 13643 int res; 13644 13645 res = transmit_register(r, SIP_REGISTER, NULL, NULL); 13646 return res; 13647 }
| void __sip_pretend_ack | ( | struct sip_pvt * | p | ) |
Pretend to ack all packets called with p locked.
Definition at line 4375 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().
04376 { 04377 struct sip_pkt *cur = NULL; 04378 04379 while (p->packets) { 04380 int method; 04381 if (cur == p->packets) { 04382 ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text); 04383 return; 04384 } 04385 cur = p->packets; 04386 method = (cur->method) ? cur->method : find_sip_method(ast_str_buffer(cur->data)); 04387 __sip_ack(p, cur->seqno, cur->is_resp, method); 04388 } 04389 }
| 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 4080 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().
04081 { 04082 struct sip_pkt *pkt = NULL; 04083 int siptimer_a = DEFAULT_RETRANS; 04084 int xmitres = 0; 04085 int respid; 04086 04087 if (sipmethod == SIP_INVITE) { 04088 /* Note this is a pending invite */ 04089 p->pendinginvite = seqno; 04090 } 04091 04092 /* If the transport is something reliable (TCP or TLS) then don't really send this reliably */ 04093 /* I removed the code from retrans_pkt that does the same thing so it doesn't get loaded into the scheduler */ 04094 /*! \todo According to the RFC some packets need to be retransmitted even if its TCP, so this needs to get revisited */ 04095 if (!(p->socket.type & SIP_TRANSPORT_UDP)) { 04096 xmitres = __sip_xmit(p, data); /* Send packet */ 04097 if (xmitres == XMIT_ERROR) { /* Serious network trouble, no need to try again */ 04098 append_history(p, "XmitErr", "%s", fatal ? "(Critical)" : "(Non-critical)"); 04099 return AST_FAILURE; 04100 } else { 04101 return AST_SUCCESS; 04102 } 04103 } 04104 04105 if (!(pkt = ast_calloc(1, sizeof(*pkt)))) { 04106 return AST_FAILURE; 04107 } 04108 /* copy data, add a terminator and save length */ 04109 if (!(pkt->data = ast_str_create(ast_str_strlen(data)))) { 04110 ast_free(pkt); 04111 return AST_FAILURE; 04112 } 04113 ast_str_set(&pkt->data, 0, "%s%s", ast_str_buffer(data), "\0"); 04114 /* copy other parameters from the caller */ 04115 pkt->method = sipmethod; 04116 pkt->seqno = seqno; 04117 pkt->is_resp = resp; 04118 pkt->is_fatal = fatal; 04119 pkt->owner = dialog_ref(p, "__sip_reliable_xmit: setting pkt->owner"); 04120 pkt->next = p->packets; 04121 p->packets = pkt; /* Add it to the queue */ 04122 if (resp) { 04123 /* Parse out the response code */ 04124 if (sscanf(ast_str_buffer(pkt->data), "SIP/2.0 %30u", &respid) == 1) { 04125 pkt->response_code = respid; 04126 } 04127 } 04128 pkt->timer_t1 = p->timer_t1; /* Set SIP timer T1 */ 04129 pkt->retransid = -1; 04130 if (pkt->timer_t1) { 04131 siptimer_a = pkt->timer_t1; 04132 } 04133 04134 pkt->time_sent = ast_tvnow(); /* time packet was sent */ 04135 pkt->retrans_stop_time = 64 * (pkt->timer_t1 ? pkt->timer_t1 : DEFAULT_TIMER_T1); /* time in ms after pkt->time_sent to stop retransmission */ 04136 04137 /* Schedule retransmission */ 04138 AST_SCHED_REPLACE_VARIABLE(pkt->retransid, sched, siptimer_a, retrans_pkt, pkt, 1); 04139 if (sipdebug) { 04140 ast_debug(4, "*** SIP TIMER: Initializing retransmit timer on packet: Id #%d\n", pkt->retransid); 04141 } 04142 04143 xmitres = __sip_xmit(pkt->owner, pkt->data); /* Send packet */ 04144 04145 if (xmitres == XMIT_ERROR) { /* Serious network trouble, no need to try again */ 04146 append_history(pkt->owner, "XmitErr", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)"); 04147 ast_log(LOG_ERROR, "Serious Network Trouble; __sip_xmit returns error for pkt data\n"); 04148 AST_SCHED_DEL(sched, pkt->retransid); 04149 p->packets = pkt->next; 04150 pkt->owner = dialog_unref(pkt->owner,"pkt is being freed, its dialog ref is dead now"); 04151 ast_free(pkt->data); 04152 ast_free(pkt); 04153 return AST_FAILURE; 04154 } else { 04155 /* This is odd, but since the retrans timer starts at 500ms and the do_monitor thread 04156 * only wakes up every 1000ms by default, we have to poke the thread here to make 04157 * sure it successfully detects this must be retransmitted in less time than 04158 * it usually sleeps for. Otherwise it might not retransmit this packet for 1000ms. */ 04159 if (monitor_thread != AST_PTHREADT_NULL) { 04160 pthread_kill(monitor_thread, SIGURG); 04161 } 04162 return AST_SUCCESS; 04163 } 04164 }
| 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 4392 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().
04393 { 04394 struct sip_pkt *cur; 04395 int res = FALSE; 04396 04397 for (cur = p->packets; cur; cur = cur->next) { 04398 if (cur->seqno == seqno && cur->is_resp == resp && 04399 (cur->is_resp || method_match(sipmethod, ast_str_buffer(cur->data)))) { 04400 /* this is our baby */ 04401 if (cur->retransid > -1) { 04402 if (sipdebug) 04403 ast_debug(4, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text); 04404 } 04405 AST_SCHED_DEL(sched, cur->retransid); 04406 res = TRUE; 04407 break; 04408 } 04409 } 04410 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"); 04411 return res; 04412 }
| static int __sip_subscribe_mwi_do | ( | struct sip_subscription_mwi * | mwi | ) | [static] |
Actually setup an MWI subscription or resubscribe.
Definition at line 12941 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().
12942 { 12943 /* If we have no DNS manager let's do a lookup */ 12944 if (!mwi->dnsmgr) { 12945 char transport[MAXHOSTNAMELEN]; 12946 struct sip_subscription_mwi *saved; 12947 snprintf(transport, sizeof(transport), "_%s._%s", get_srv_service(mwi->transport), get_srv_protocol(mwi->transport)); 12948 12949 mwi->us.ss.ss_family = get_address_family_filter(mwi->transport); /* Filter address family */ 12950 saved = ASTOBJ_REF(mwi); 12951 ast_dnsmgr_lookup_cb(mwi->hostname, &mwi->us, &mwi->dnsmgr, sip_cfg.srvlookup ? transport : NULL, on_dns_update_mwi, saved); 12952 if (!mwi->dnsmgr) { 12953 ASTOBJ_UNREF(saved, sip_subscribe_mwi_destroy); /* dnsmgr disabled, remove reference */ 12954 } 12955 } 12956 12957 /* If we already have a subscription up simply send a resubscription */ 12958 if (mwi->call) { 12959 transmit_invite(mwi->call, SIP_SUBSCRIBE, 0, 0, NULL); 12960 return 0; 12961 } 12962 12963 /* Create a dialog that we will use for the subscription */ 12964 if (!(mwi->call = sip_alloc(NULL, NULL, 0, SIP_SUBSCRIBE, NULL))) { 12965 return -1; 12966 } 12967 12968 ref_proxy(mwi->call, obproxy_get(mwi->call, NULL)); 12969 12970 if (!ast_sockaddr_port(&mwi->us) && mwi->portno) { 12971 ast_sockaddr_set_port(&mwi->us, mwi->portno); 12972 } 12973 12974 /* Setup the destination of our subscription */ 12975 if (create_addr(mwi->call, mwi->hostname, &mwi->us, 0)) { 12976 dialog_unlink_all(mwi->call); 12977 mwi->call = dialog_unref(mwi->call, "unref dialog after unlink_all"); 12978 return 0; 12979 } 12980 12981 mwi->call->expiry = mwi_expiry; 12982 12983 if (!mwi->dnsmgr && mwi->portno) { 12984 ast_sockaddr_set_port(&mwi->call->sa, mwi->portno); 12985 ast_sockaddr_set_port(&mwi->call->recv, mwi->portno); 12986 } else { 12987 mwi->portno = ast_sockaddr_port(&mwi->call->sa); 12988 } 12989 12990 /* Set various other information */ 12991 if (!ast_strlen_zero(mwi->authuser)) { 12992 ast_string_field_set(mwi->call, peername, mwi->authuser); 12993 ast_string_field_set(mwi->call, authname, mwi->authuser); 12994 ast_string_field_set(mwi->call, fromuser, mwi->authuser); 12995 } else { 12996 ast_string_field_set(mwi->call, peername, mwi->username); 12997 ast_string_field_set(mwi->call, authname, mwi->username); 12998 ast_string_field_set(mwi->call, fromuser, mwi->username); 12999 } 13000 ast_string_field_set(mwi->call, username, mwi->username); 13001 if (!ast_strlen_zero(mwi->secret)) { 13002 ast_string_field_set(mwi->call, peersecret, mwi->secret); 13003 } 13004 set_socket_transport(&mwi->call->socket, mwi->transport); 13005 mwi->call->socket.port = htons(mwi->portno); 13006 ast_sip_ouraddrfor(&mwi->call->sa, &mwi->call->ourip, mwi->call); 13007 build_contact(mwi->call); 13008 build_via(mwi->call); 13009 13010 /* Change the dialog callid. */ 13011 change_callid_pvt(mwi->call, NULL); 13012 13013 ast_set_flag(&mwi->call->flags[0], SIP_OUTGOING); 13014 13015 /* Associate the call with us */ 13016 mwi->call->mwi = ASTOBJ_REF(mwi); 13017 13018 mwi->call->subscribed = MWI_NOTIFICATION; 13019 13020 /* Actually send the packet */ 13021 transmit_invite(mwi->call, SIP_SUBSCRIBE, 0, 2, NULL); 13022 13023 return 0; 13024 }
| static int __sip_xmit | ( | struct sip_pvt * | p, | |
| struct ast_str * | data | |||
| ) | [static] |
Definition at line 3679 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().
03680 { 03681 int res = 0; 03682 const struct ast_sockaddr *dst = sip_real_dst(p); 03683 03684 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)); 03685 03686 if (sip_prepare_socket(p) < 0) { 03687 return XMIT_ERROR; 03688 } 03689 03690 if (p->socket.type == SIP_TRANSPORT_UDP) { 03691 res = ast_sendto(p->socket.fd, ast_str_buffer(data), ast_str_strlen(data), 0, dst); 03692 } else if (p->socket.tcptls_session) { 03693 res = sip_tcptls_write(p->socket.tcptls_session, ast_str_buffer(data), ast_str_strlen(data)); 03694 } else { 03695 ast_debug(2, "Socket type is TCP but no tcptls_session is present to write to\n"); 03696 return XMIT_ERROR; 03697 } 03698 03699 if (res == -1) { 03700 switch (errno) { 03701 case EBADF: /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */ 03702 case EHOSTUNREACH: /* Host can't be reached */ 03703 case ENETDOWN: /* Interface down */ 03704 case ENETUNREACH: /* Network failure */ 03705 case ECONNREFUSED: /* ICMP port unreachable */ 03706 res = XMIT_ERROR; /* Don't bother with trying to transmit again */ 03707 } 03708 } 03709 if (res != ast_str_strlen(data)) { 03710 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)); 03711 } 03712 03713 return res; 03714 }
| 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 10959 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().
10960 { 10961 struct sip_request resp; 10962 uint32_t seqno = 0; 10963 10964 if (reliable && (sscanf(get_header(req, "CSeq"), "%30u ", &seqno) != 1)) { 10965 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 10966 return -1; 10967 } 10968 respprep(&resp, p, msg, req); 10969 10970 if (ast_test_flag(&p->flags[0], SIP_SENDRPID) 10971 && ast_test_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND) 10972 && (!strncmp(msg, "180", 3) || !strncmp(msg, "183", 3))) { 10973 ast_clear_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND); 10974 add_rpid(&resp, p); 10975 } 10976 if (ast_test_flag(&p->flags[0], SIP_OFFER_CC)) { 10977 add_cc_call_info_to_response(p, &resp); 10978 } 10979 10980 /* If we are sending a 302 Redirect we can add a diversion header if the redirect information is set */ 10981 if (!strncmp(msg, "302", 3)) { 10982 add_diversion_header(&resp, p); 10983 } 10984 10985 /* If we are cancelling an incoming invite for some reason, add information 10986 about the reason why we are doing this in clear text */ 10987 if (p->method == SIP_INVITE && msg[0] != '1') { 10988 char buf[20]; 10989 10990 if (ast_test_flag(&p->flags[1], SIP_PAGE2_Q850_REASON)) { 10991 int hangupcause = 0; 10992 10993 if (p->owner && p->owner->hangupcause) { 10994 hangupcause = p->owner->hangupcause; 10995 } else if (p->hangupcause) { 10996 hangupcause = p->hangupcause; 10997 } else { 10998 int respcode; 10999 if (sscanf(msg, "%30d ", &respcode)) 11000 hangupcause = hangup_sip2cause(respcode); 11001 } 11002 11003 if (hangupcause) { 11004 sprintf(buf, "Q.850;cause=%i", hangupcause & 0x7f); 11005 add_header(&resp, "Reason", buf); 11006 } 11007 } 11008 11009 if (p->owner && p->owner->hangupcause) { 11010 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 11011 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 11012 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 11013 } 11014 } 11015 return send_response(p, &resp, reliable, seqno); 11016 }
| 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 17973 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().
17974 { 17975 struct sip_peer *peer; 17976 int load_realtime; 17977 17978 if (argc < 4) 17979 return CLI_SHOWUSAGE; 17980 17981 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 17982 if ((peer = find_peer(argv[3], NULL, load_realtime, FINDPEERS, FALSE, 0))) { 17983 sip_poke_peer(peer, 1); 17984 unref_peer(peer, "qualify: done with peer"); 17985 } else if (type == 0) { 17986 ast_cli(fd, "Peer '%s' not found\n", argv[3]); 17987 } else { 17988 astman_send_error(s, m, "Peer not found"); 17989 } 17990 return CLI_SUCCESS; 17991 }
| 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 18058 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, unref_peer(), and ast_variable::value.
Referenced by manager_sip_show_peer(), and sip_show_peer().
18059 { 18060 char status[30] = ""; 18061 char cbuf[256]; 18062 struct sip_peer *peer; 18063 char codec_buf[512]; 18064 struct ast_codec_pref *pref; 18065 struct ast_variable *v; 18066 int x = 0, load_realtime; 18067 format_t codec = 0; 18068 int realtimepeers; 18069 18070 realtimepeers = ast_check_realtime("sippeers"); 18071 18072 if (argc < 4) 18073 return CLI_SHOWUSAGE; 18074 18075 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 18076 peer = find_peer(argv[3], NULL, load_realtime, FINDPEERS, FALSE, 0); 18077 18078 if (s) { /* Manager */ 18079 if (peer) { 18080 const char *id = astman_get_header(m, "ActionID"); 18081 18082 astman_append(s, "Response: Success\r\n"); 18083 if (!ast_strlen_zero(id)) 18084 astman_append(s, "ActionID: %s\r\n", id); 18085 } else { 18086 snprintf (cbuf, sizeof(cbuf), "Peer %s not found.", argv[3]); 18087 astman_send_error(s, m, cbuf); 18088 return CLI_SUCCESS; 18089 } 18090 } 18091 if (peer && type==0 ) { /* Normal listing */ 18092 struct ast_str *mailbox_str = ast_str_alloca(512); 18093 struct sip_auth_container *credentials; 18094 18095 ao2_lock(peer); 18096 credentials = peer->auth; 18097 if (credentials) { 18098 ao2_t_ref(credentials, +1, "Ref peer auth for show"); 18099 } 18100 ao2_unlock(peer); 18101 18102 ast_cli(fd, "\n\n"); 18103 ast_cli(fd, " * Name : %s\n", peer->name); 18104 if (realtimepeers) { /* Realtime is enabled */ 18105 ast_cli(fd, " Realtime peer: %s\n", peer->is_realtime ? "Yes, cached" : "No"); 18106 } 18107 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 18108 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>"); 18109 ast_cli(fd, " Remote Secret: %s\n", ast_strlen_zero(peer->remotesecret)?"<Not set>":"<Set>"); 18110 if (credentials) { 18111 struct sip_auth *auth; 18112 18113 AST_LIST_TRAVERSE(&credentials->list, auth, node) { 18114 ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s %s\n", 18115 auth->realm, 18116 auth->username, 18117 !ast_strlen_zero(auth->secret) 18118 ? "<Secret set>" 18119 : (!ast_strlen_zero(auth->md5secret) 18120 ? "<MD5secret set>" : "<Not set>")); 18121 } 18122 ao2_t_ref(credentials, -1, "Unref peer auth for show"); 18123 } 18124 ast_cli(fd, " Context : %s\n", peer->context); 18125 ast_cli(fd, " Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") ); 18126 ast_cli(fd, " Language : %s\n", peer->language); 18127 if (!ast_strlen_zero(peer->accountcode)) 18128 ast_cli(fd, " Accountcode : %s\n", peer->accountcode); 18129 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(peer->amaflags)); 18130 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(peer->allowtransfer)); 18131 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres)); 18132 if (!ast_strlen_zero(peer->fromuser)) 18133 ast_cli(fd, " FromUser : %s\n", peer->fromuser); 18134 if (!ast_strlen_zero(peer->fromdomain)) 18135 ast_cli(fd, " FromDomain : %s Port %d\n", peer->fromdomain, (peer->fromdomainport) ? peer->fromdomainport : STANDARD_SIP_PORT); 18136 ast_cli(fd, " Callgroup : "); 18137 print_group(fd, peer->callgroup, 0); 18138 ast_cli(fd, " Pickupgroup : "); 18139 print_group(fd, peer->pickupgroup, 0); 18140 peer_mailboxes_to_str(&mailbox_str, peer); 18141 ast_cli(fd, " MOH Suggest : %s\n", peer->mohsuggest); 18142 ast_cli(fd, " Mailbox : %s\n", ast_str_buffer(mailbox_str)); 18143 ast_cli(fd, " VM Extension : %s\n", peer->vmexten); 18144 ast_cli(fd, " LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff); 18145 ast_cli(fd, " Call limit : %d\n", peer->call_limit); 18146 ast_cli(fd, " Max forwards : %d\n", peer->maxforwards); 18147 if (peer->busy_level) 18148 ast_cli(fd, " Busy level : %d\n", peer->busy_level); 18149 ast_cli(fd, " Dynamic : %s\n", AST_CLI_YESNO(peer->host_dynamic)); 18150 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 18151 ast_cli(fd, " MaxCallBR : %d kbps\n", peer->maxcallbitrate); 18152 ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, peer->expire)); 18153 ast_cli(fd, " Insecure : %s\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE))); 18154 ast_cli(fd, " Force rport : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT))); 18155 ast_cli(fd, " ACL : %s\n", AST_CLI_YESNO(peer->ha != NULL)); 18156 ast_cli(fd, " DirectMedACL : %s\n", AST_CLI_YESNO(peer->directmediaha != NULL)); 18157 ast_cli(fd, " T.38 support : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT))); 18158 ast_cli(fd, " T.38 EC mode : %s\n", faxec2str(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT))); 18159 ast_cli(fd, " T.38 MaxDtgrm: %d\n", peer->t38_maxdatagram); 18160 ast_cli(fd, " DirectMedia : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_DIRECT_MEDIA))); 18161 ast_cli(fd, " PromiscRedir : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR))); 18162 ast_cli(fd, " User=Phone : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_USEREQPHONE))); 18163 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))); 18164 ast_cli(fd, " Text Support : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT))); 18165 ast_cli(fd, " Ign SDP ver : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_IGNORESDPVERSION))); 18166 ast_cli(fd, " Trust RPID : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_TRUSTRPID))); 18167 ast_cli(fd, " Send RPID : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_SENDRPID))); 18168 ast_cli(fd, " Subscriptions: %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))); 18169 ast_cli(fd, " Overlap dial : %s\n", allowoverlap2str(ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP))); 18170 if (peer->outboundproxy) 18171 ast_cli(fd, " Outb. proxy : %s %s\n", ast_strlen_zero(peer->outboundproxy->name) ? "<not set>" : peer->outboundproxy->name, 18172 peer->outboundproxy->force ? "(forced)" : ""); 18173 18174 /* - is enumerated */ 18175 ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 18176 ast_cli(fd, " Timer T1 : %d\n", peer->timer_t1); 18177 ast_cli(fd, " Timer B : %d\n", peer->timer_b); 18178 ast_cli(fd, " ToHost : %s\n", peer->tohost); 18179 ast_cli(fd, " Addr->IP : %s\n", ast_sockaddr_stringify(&peer->addr)); 18180 ast_cli(fd, " Defaddr->IP : %s\n", ast_sockaddr_stringify(&peer->defaddr)); 18181 ast_cli(fd, " Prim.Transp. : %s\n", get_transport(peer->socket.type)); 18182 ast_cli(fd, " Allowed.Trsp : %s\n", get_transport_list(peer->transports)); 18183 if (!ast_strlen_zero(sip_cfg.regcontext)) 18184 ast_cli(fd, " Reg. exten : %s\n", peer->regexten); 18185 ast_cli(fd, " Def. Username: %s\n", peer->username); 18186 ast_cli(fd, " SIP Options : "); 18187 if (peer->sipoptions) { 18188 int lastoption = -1; 18189 for (x = 0 ; x < ARRAY_LEN(sip_options); x++) { 18190 if (sip_options[x].id != lastoption) { 18191 if (peer->sipoptions & sip_options[x].id) 18192 ast_cli(fd, "%s ", sip_options[x].text); 18193 lastoption = x; 18194 } 18195 } 18196 } else 18197 ast_cli(fd, "(none)"); 18198 18199 ast_cli(fd, "\n"); 18200 ast_cli(fd, " Codecs : "); 18201 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 18202 ast_cli(fd, "%s\n", codec_buf); 18203 ast_cli(fd, " Codec Order : ("); 18204 print_codec_to_cli(fd, &peer->prefs); 18205 ast_cli(fd, ")\n"); 18206 18207 ast_cli(fd, " Auto-Framing : %s \n", AST_CLI_YESNO(peer->autoframing)); 18208 ast_cli(fd, " Status : "); 18209 peer_status(peer, status, sizeof(status)); 18210 ast_cli(fd, "%s\n", status); 18211 ast_cli(fd, " Useragent : %s\n", peer->useragent); 18212 ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); 18213 ast_cli(fd, " Qualify Freq : %d ms\n", peer->qualifyfreq); 18214 if (peer->chanvars) { 18215 ast_cli(fd, " Variables :\n"); 18216 for (v = peer->chanvars ; v ; v = v->next) 18217 ast_cli(fd, " %s = %s\n", v->name, v->value); 18218 } 18219 18220 ast_cli(fd, " Sess-Timers : %s\n", stmode2str(peer->stimer.st_mode_oper)); 18221 ast_cli(fd, " Sess-Refresh : %s\n", strefresherparam2str(peer->stimer.st_ref)); 18222 ast_cli(fd, " Sess-Expires : %d secs\n", peer->stimer.st_max_se); 18223 ast_cli(fd, " Min-Sess : %d secs\n", peer->stimer.st_min_se); 18224 ast_cli(fd, " RTP Engine : %s\n", peer->engine); 18225 ast_cli(fd, " Parkinglot : %s\n", peer->parkinglot); 18226 ast_cli(fd, " Use Reason : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_Q850_REASON))); 18227 ast_cli(fd, " Encryption : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_USE_SRTP))); 18228 ast_cli(fd, "\n"); 18229 peer = unref_peer(peer, "sip_show_peer: unref_peer: done with peer ptr"); 18230 } else if (peer && type == 1) { /* manager listing */ 18231 char buffer[256]; 18232 struct ast_str *mailbox_str = ast_str_alloca(512); 18233 astman_append(s, "Channeltype: SIP\r\n"); 18234 astman_append(s, "ObjectName: %s\r\n", peer->name); 18235 astman_append(s, "ChanObjectType: peer\r\n"); 18236 astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y"); 18237 astman_append(s, "RemoteSecretExist: %s\r\n", ast_strlen_zero(peer->remotesecret)?"N":"Y"); 18238 astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y"); 18239 astman_append(s, "Context: %s\r\n", peer->context); 18240 astman_append(s, "Language: %s\r\n", peer->language); 18241 if (!ast_strlen_zero(peer->accountcode)) 18242 astman_append(s, "Accountcode: %s\r\n", peer->accountcode); 18243 astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags)); 18244 astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres)); 18245 if (!ast_strlen_zero(peer->fromuser)) 18246 astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser); 18247 if (!ast_strlen_zero(peer->fromdomain)) 18248 astman_append(s, "SIP-FromDomain: %s\r\nSip-FromDomain-Port: %d\r\n", peer->fromdomain, (peer->fromdomainport) ? peer->fromdomainport : STANDARD_SIP_PORT); 18249 astman_append(s, "Callgroup: "); 18250 astman_append(s, "%s\r\n", ast_print_group(buffer, sizeof(buffer), peer->callgroup)); 18251 astman_append(s, "Pickupgroup: "); 18252 astman_append(s, "%s\r\n", ast_print_group(buffer, sizeof(buffer), peer->pickupgroup)); 18253 astman_append(s, "MOHSuggest: %s\r\n", peer->mohsuggest); 18254 peer_mailboxes_to_str(&mailbox_str, peer); 18255 astman_append(s, "VoiceMailbox: %s\r\n", ast_str_buffer(mailbox_str)); 18256 astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer)); 18257 astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent); 18258 astman_append(s, "Maxforwards: %d\r\n", peer->maxforwards); 18259 astman_append(s, "Call-limit: %d\r\n", peer->call_limit); 18260 astman_append(s, "Busy-level: %d\r\n", peer->busy_level); 18261 astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate); 18262 astman_append(s, "Dynamic: %s\r\n", peer->host_dynamic?"Y":"N"); 18263 astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); 18264 astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched, peer->expire)); 18265 astman_append(s, "SIP-AuthInsecure: %s\r\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE))); 18266 astman_append(s, "SIP-Forcerport: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT)?"Y":"N")); 18267 astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N")); 18268 astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_DIRECT_MEDIA)?"Y":"N")); 18269 astman_append(s, "SIP-DirectMedia: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_DIRECT_MEDIA)?"Y":"N")); 18270 astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N")); 18271 astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N")); 18272 astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N")); 18273 astman_append(s, "SIP-TextSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT)?"Y":"N")); 18274 astman_append(s, "SIP-T.38Support: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT)?"Y":"N")); 18275 astman_append(s, "SIP-T.38EC: %s\r\n", faxec2str(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT))); 18276 astman_append(s, "SIP-T.38MaxDtgrm: %d\r\n", peer->t38_maxdatagram); 18277 astman_append(s, "SIP-Sess-Timers: %s\r\n", stmode2str(peer->stimer.st_mode_oper)); 18278 astman_append(s, "SIP-Sess-Refresh: %s\r\n", strefresherparam2str(peer->stimer.st_ref)); 18279 astman_append(s, "SIP-Sess-Expires: %d\r\n", peer->stimer.st_max_se); 18280 astman_append(s, "SIP-Sess-Min: %d\r\n", peer->stimer.st_min_se); 18281 astman_append(s, "SIP-RTP-Engine: %s\r\n", peer->engine); 18282 astman_append(s, "SIP-Encryption: %s\r\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_USE_SRTP) ? "Y" : "N"); 18283 18284 /* - is enumerated */ 18285 astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 18286 astman_append(s, "ToHost: %s\r\n", peer->tohost); 18287 astman_append(s, "Address-IP: %s\r\nAddress-Port: %d\r\n", ast_sockaddr_stringify_addr(&peer->addr), ast_sockaddr_port(&peer->addr)); 18288 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)); 18289 astman_append(s, "Default-Username: %s\r\n", peer->username); 18290 if (!ast_strlen_zero(sip_cfg.regcontext)) 18291 astman_append(s, "RegExtension: %s\r\n", peer->regexten); 18292 astman_append(s, "Codecs: "); 18293 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 18294 astman_append(s, "%s\r\n", codec_buf); 18295 astman_append(s, "CodecOrder: "); 18296 pref = &peer->prefs; 18297 for(x = 0; x < 64 ; x++) { 18298 codec = ast_codec_pref_index(pref, x); 18299 if (!codec) 18300 break; 18301 astman_append(s, "%s", ast_getformatname(codec)); 18302 if (x < 63 && ast_codec_pref_index(pref, x+1)) 18303 astman_append(s, ","); 18304 } 18305 18306 astman_append(s, "\r\n"); 18307 astman_append(s, "Status: "); 18308 peer_status(peer, status, sizeof(status)); 18309 astman_append(s, "%s\r\n", status); 18310 astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent); 18311 astman_append(s, "Reg-Contact: %s\r\n", peer->fullcontact); 18312 astman_append(s, "QualifyFreq: %d ms\r\n", peer->qualifyfreq); 18313 astman_append(s, "Parkinglot: %s\r\n", peer->parkinglot); 18314 if (peer->chanvars) { 18315 for (v = peer->chanvars ; v ; v = v->next) { 18316 astman_append(s, "ChanVariable: %s=%s\r\n", v->name, v->value); 18317 } 18318 } 18319 astman_append(s, "SIP-Use-Reason-Header: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_Q850_REASON)) ? "Y" : "N"); 18320 18321 peer = unref_peer(peer, "sip_show_peer: unref_peer: done with peer"); 18322 18323 } else { 18324 ast_cli(fd, "Peer %s not found.\n", argv[3]); 18325 ast_cli(fd, "\n"); 18326 } 18327 18328 return CLI_SUCCESS; 18329 }
| 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 17314 of file chan_sip.c.
References ao2_callback, ao2_container_count(), ao2_iterator_destroy(), ao2_lock, ao2_t_iterator_next, ao2_unlock, ast_calloc, ast_check_realtime(), ast_cli(), ast_copy_string(), ast_free, ast_log(), AST_LOG_ERROR, ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_sockaddr_stringify_port(), ast_strdupa, ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), CLI_FAILURE, CLI_SHOWUSAGE, CLI_SUCCESS, FALSE, FORMAT2, id, name, OBJ_MULTIPLE, peer_status(), peercomparefunc(), status, TRUE, and unref_peer().
Referenced by manager_sip_show_peers(), and sip_show_peers().
17315 { 17316 regex_t regexbuf; 17317 int havepattern = FALSE; 17318 struct sip_peer *peer; 17319 struct ao2_iterator* it_peers; 17320 17321 /* the last argument is left-aligned, so we don't need a size anyways */ 17322 #define FORMAT2 "%-25.25s %-39.39s %-3.3s %-10.10s %-3.3s %-8s %-10s %s\n" 17323 17324 char name[256]; 17325 int total_peers = 0; 17326 int peers_mon_online = 0; 17327 int peers_mon_offline = 0; 17328 int peers_unmon_offline = 0; 17329 int peers_unmon_online = 0; 17330 const char *id; 17331 char idtext[256] = ""; 17332 int realtimepeers; 17333 struct sip_peer **peerarray; 17334 int k; 17335 17336 realtimepeers = ast_check_realtime("sippeers"); 17337 17338 if (s) { /* Manager - get ActionID */ 17339 id = astman_get_header(m, "ActionID"); 17340 if (!ast_strlen_zero(id)) 17341 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 17342 } 17343 17344 switch (argc) { 17345 case 5: 17346 if (!strcasecmp(argv[3], "like")) { 17347 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 17348 return CLI_SHOWUSAGE; 17349 havepattern = TRUE; 17350 } else 17351 return CLI_SHOWUSAGE; 17352 case 3: 17353 break; 17354 default: 17355 return CLI_SHOWUSAGE; 17356 } 17357 17358 if (!s) { 17359 /* Normal list */ 17360 ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Forcerport", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : "")); 17361 } 17362 17363 ao2_lock(peers); 17364 if (!(it_peers = ao2_callback(peers, OBJ_MULTIPLE, NULL, NULL))) { 17365 ast_log(AST_LOG_ERROR, "Unable to create iterator for peers container for sip show peers\n"); 17366 ao2_unlock(peers); 17367 return CLI_FAILURE; 17368 } 17369 if (!(peerarray = ast_calloc(sizeof(struct sip_peer *), ao2_container_count(peers)))) { 17370 ast_log(AST_LOG_ERROR, "Unable to allocate peer array for sip show peers\n"); 17371 ao2_iterator_destroy(it_peers); 17372 ao2_unlock(peers); 17373 return CLI_FAILURE; 17374 } 17375 ao2_unlock(peers); 17376 17377 while ((peer = ao2_t_iterator_next(it_peers, "iterate thru peers table"))) { 17378 ao2_lock(peer); 17379 17380 if (!(peer->type & SIP_TYPE_PEER)) { 17381 ao2_unlock(peer); 17382 unref_peer(peer, "unref peer because it's actually a user"); 17383 continue; 17384 } 17385 17386 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) { 17387 ao2_unlock(peer); 17388 unref_peer(peer, "toss iterator peer ptr before continue"); 17389 continue; 17390 } 17391 17392 peerarray[total_peers++] = peer; 17393 ao2_unlock(peer); 17394 } 17395 ao2_iterator_destroy(it_peers); 17396 17397 qsort(peerarray, total_peers, sizeof(struct sip_peer *), peercomparefunc); 17398 17399 for(k=0; k < total_peers; k++) { 17400 char status[20] = ""; 17401 char srch[2000]; 17402 char pstatus; 17403 17404 /* 17405 * tmp_port and tmp_host store copies of ast_sockaddr_stringify strings since the 17406 * string pointers for that function aren't valid between subsequent calls to 17407 * ast_sockaddr_stringify functions 17408 */ 17409 char *tmp_port; 17410 char *tmp_host; 17411 17412 peer = peerarray[k]; 17413 17414 tmp_port = ast_sockaddr_isnull(&peer->addr) ? 17415 "0" : ast_strdupa(ast_sockaddr_stringify_port(&peer->addr)); 17416 17417 tmp_host = ast_sockaddr_isnull(&peer->addr) ? 17418 "(Unspecified)" : ast_strdupa(ast_sockaddr_stringify_addr(&peer->addr)); 17419 17420 ao2_lock(peer); 17421 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) { 17422 ao2_unlock(peer); 17423 peer = peerarray[k] = unref_peer(peer, "toss iterator peer ptr before continue"); 17424 continue; 17425 } 17426 17427 if (!ast_strlen_zero(peer->username) && !s) 17428 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 17429 else 17430 ast_copy_string(name, peer->name, sizeof(name)); 17431 17432 pstatus = peer_status(peer, status, sizeof(status)); 17433 if (pstatus == 1) 17434 peers_mon_online++; 17435 else if (pstatus == 0) 17436 peers_mon_offline++; 17437 else { 17438 if (ast_sockaddr_isnull(&peer->addr) || 17439 !ast_sockaddr_port(&peer->addr)) { 17440 peers_unmon_offline++; 17441 } else { 17442 peers_unmon_online++; 17443 } 17444 } 17445 17446 snprintf(srch, sizeof(srch), FORMAT2, name, 17447 tmp_host, 17448 peer->host_dynamic ? " D " : " ", /* Dynamic or not? */ 17449 ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? " N " : " ", /* NAT=yes? */ 17450 peer->ha ? " A " : " ", /* permit/deny */ 17451 tmp_port, status, 17452 realtimepeers ? (peer->is_realtime ? "Cached RT":"") : ""); 17453 17454 if (!s) {/* Normal CLI list */ 17455 ast_cli(fd, FORMAT2, name, 17456 tmp_host, 17457 peer->host_dynamic ? " D " : " ", /* Dynamic or not? */ 17458 ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? " N " : " ", /* NAT=yes? */ 17459 peer->ha ? " A " : " ", /* permit/deny */ 17460 tmp_port, status, 17461 realtimepeers ? (peer->is_realtime ? "Cached RT":"") : ""); 17462 } else { /* Manager format */ 17463 /* The names here need to be the same as other channels */ 17464 astman_append(s, 17465 "Event: PeerEntry\r\n%s" 17466 "Channeltype: SIP\r\n" 17467 "ObjectName: %s\r\n" 17468 "ChanObjectType: peer\r\n" /* "peer" or "user" */ 17469 "IPaddress: %s\r\n" 17470 "IPport: %s\r\n" 17471 "Dynamic: %s\r\n" 17472 "Forcerport: %s\r\n" 17473 "VideoSupport: %s\r\n" 17474 "TextSupport: %s\r\n" 17475 "ACL: %s\r\n" 17476 "Status: %s\r\n" 17477 "RealtimeDevice: %s\r\n\r\n", 17478 idtext, 17479 peer->name, 17480 ast_sockaddr_isnull(&peer->addr) ? "-none-" : tmp_host, 17481 ast_sockaddr_isnull(&peer->addr) ? "0" : tmp_port, 17482 peer->host_dynamic ? "yes" : "no", /* Dynamic or not? */ 17483 ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? "yes" : "no", /* NAT=yes? */ 17484 ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */ 17485 ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT) ? "yes" : "no", /* TEXTSUPPORT=yes? */ 17486 peer->ha ? "yes" : "no", /* permit/deny */ 17487 status, 17488 realtimepeers ? (peer->is_realtime ? "yes":"no") : "no"); 17489 } 17490 ao2_unlock(peer); 17491 peer = peerarray[k] = unref_peer(peer, "toss iterator peer ptr"); 17492 } 17493 17494 if (!s) 17495 ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n", 17496 total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline); 17497 17498 if (havepattern) 17499 regfree(®exbuf); 17500 17501 if (total) 17502 *total = total_peers; 17503 17504 ast_free(peerarray); 17505 17506 return CLI_SUCCESS; 17507 #undef FORMAT2 17508 }
| 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 2882 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(), 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_tcp_read(), sip_threadinfo_create(), sip_tls_read(), and ast_tcptls_session_instance::ssl.
Referenced by sip_tcp_worker_fn().
02883 { 02884 int res, timeout = -1, authenticated = 0, flags; 02885 time_t start; 02886 struct sip_request req = { 0, } , reqcpy = { 0, }; 02887 struct sip_threadinfo *me = NULL; 02888 char buf[1024] = ""; 02889 struct pollfd fds[2] = { { 0 }, { 0 }, }; 02890 struct ast_tcptls_session_args *ca = NULL; 02891 02892 /* If this is a server session, then the connection has already been 02893 * setup. Check if the authlimit has been reached and if not create the 02894 * threadinfo object so we can access this thread for writing. 02895 * 02896 * if this is a client connection more work must be done. 02897 * 1. We own the parent session args for a client connection. This pointer needs 02898 * to be held on to so we can decrement it's ref count on thread destruction. 02899 * 2. The threadinfo object was created before this thread was launched, however 02900 * it must be found within the threadt table. 02901 * 3. Last, the tcptls_session must be started. 02902 */ 02903 if (!tcptls_session->client) { 02904 if (ast_atomic_fetchadd_int(&unauth_sessions, +1) >= authlimit) { 02905 /* unauth_sessions is decremented in the cleanup code */ 02906 goto cleanup; 02907 } 02908 02909 if ((flags = fcntl(tcptls_session->fd, F_GETFL)) == -1) { 02910 ast_log(LOG_ERROR, "error setting socket to non blocking mode, fcntl() failed: %s\n", strerror(errno)); 02911 goto cleanup; 02912 } 02913 02914 flags |= O_NONBLOCK; 02915 if (fcntl(tcptls_session->fd, F_SETFL, flags) == -1) { 02916 ast_log(LOG_ERROR, "error setting socket to non blocking mode, fcntl() failed: %s\n", strerror(errno)); 02917 goto cleanup; 02918 } 02919 02920 if (!(me = sip_threadinfo_create(tcptls_session, tcptls_session->ssl ? SIP_TRANSPORT_TLS : SIP_TRANSPORT_TCP))) { 02921 goto cleanup; 02922 } 02923 ao2_t_ref(me, +1, "Adding threadinfo ref for tcp_helper_thread"); 02924 } else { 02925 struct sip_threadinfo tmp = { 02926 .tcptls_session = tcptls_session, 02927 }; 02928 02929 if ((!(ca = tcptls_session->parent)) || 02930 (!(me = ao2_t_find(threadt, &tmp, OBJ_POINTER, "ao2_find, getting sip_threadinfo in tcp helper thread"))) || 02931 (!(tcptls_session = ast_tcptls_client_start(tcptls_session)))) { 02932 goto cleanup; 02933 } 02934 } 02935 02936 flags = 1; 02937 if (setsockopt(tcptls_session->fd, SOL_SOCKET, SO_KEEPALIVE, &flags, sizeof(flags))) { 02938 ast_log(LOG_ERROR, "error enabling TCP keep-alives on sip socket: %s\n", strerror(errno)); 02939 goto cleanup; 02940 } 02941 02942 me->threadid = pthread_self(); 02943 ast_debug(2, "Starting thread for %s server\n", tcptls_session->ssl ? "TLS" : "TCP"); 02944 02945 /* set up pollfd to watch for reads on both the socket and the alert_pipe */ 02946 fds[0].fd = tcptls_session->fd; 02947 fds[1].fd = me->alert_pipe[0]; 02948 fds[0].events = fds[1].events = POLLIN | POLLPRI; 02949 02950 if (!(req.data = ast_str_create(SIP_MIN_PACKET))) { 02951 goto cleanup; 02952 } 02953 if (!(reqcpy.data = ast_str_create(SIP_MIN_PACKET))) { 02954 goto cleanup; 02955 } 02956 02957 if(time(&start) == -1) { 02958 ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno)); 02959 goto cleanup; 02960 } 02961 02962 for (;;) { 02963 struct ast_str *str_save; 02964 02965 if (!tcptls_session->client && req.authenticated && !authenticated) { 02966 authenticated = 1; 02967 ast_atomic_fetchadd_int(&unauth_sessions, -1); 02968 } 02969 02970 /* calculate the timeout for unauthenticated server sessions */ 02971 if (!tcptls_session->client && !authenticated ) { 02972 if ((timeout = sip_check_authtimeout(start)) < 0) { 02973 goto cleanup; 02974 } 02975 02976 if (timeout == 0) { 02977 ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "TLS": "TCP"); 02978 goto cleanup; 02979 } 02980 } else { 02981 timeout = -1; 02982 } 02983 02984 if (ast_str_strlen(tcptls_session->overflow_buf) == 0) { 02985 res = ast_poll(fds, 2, timeout); /* polls for both socket and alert_pipe */ 02986 if (res < 0) { 02987 ast_debug(2, "SIP %s server :: ast_wait_for_input returned %d\n", tcptls_session->ssl ? "TLS": "TCP", res); 02988 goto cleanup; 02989 } else if (res == 0) { 02990 /* timeout */ 02991 ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "TLS": "TCP"); 02992 goto cleanup; 02993 } 02994 } 02995 02996 /* 02997 * handle the socket event, check for both reads from the socket fd or TCP overflow buffer, 02998 * and writes from alert_pipe fd. 02999 */ 03000 if (fds[0].revents || (ast_str_strlen(tcptls_session->overflow_buf) > 0)) { /* there is data on the socket to be read */ 03001 fds[0].revents = 0; 03002 03003 /* clear request structure */ 03004 str_save = req.data; 03005 memset(&req, 0, sizeof(req)); 03006 req.data = str_save; 03007 ast_str_reset(req.data); 03008 03009 str_save = reqcpy.data; 03010 memset(&reqcpy, 0, sizeof(reqcpy)); 03011 reqcpy.data = str_save; 03012 ast_str_reset(reqcpy.data); 03013 03014 memset(buf, 0, sizeof(buf)); 03015 03016 if (tcptls_session->ssl) { 03017 set_socket_transport(&req.socket, SIP_TRANSPORT_TLS); 03018 req.socket.port = htons(ourport_tls); 03019 } else { 03020 set_socket_transport(&req.socket, SIP_TRANSPORT_TCP); 03021 req.socket.port = htons(ourport_tcp); 03022 } 03023 req.socket.fd = tcptls_session->fd; 03024 03025 if (tcptls_session->ssl) { 03026 res = sip_tls_read(&req, &reqcpy, tcptls_session, authenticated, start, me); 03027 } else { 03028 res = sip_tcp_read(&req, tcptls_session, authenticated, start); 03029 } 03030 03031 if (res < 0) { 03032 goto cleanup; 03033 } 03034 03035 req.socket.tcptls_session = tcptls_session; 03036 handle_request_do(&req, &tcptls_session->remote_address); 03037 } 03038 03039 if (fds[1].revents) { /* alert_pipe indicates there is data in the send queue to be sent */ 03040 enum sip_tcptls_alert alert; 03041 struct tcptls_packet *packet; 03042 03043 fds[1].revents = 0; 03044 03045 if (read(me->alert_pipe[0], &alert, sizeof(alert)) == -1) { 03046 ast_log(LOG_ERROR, "read() failed: %s\n", strerror(errno)); 03047 continue; 03048 } 03049 03050 switch (alert) { 03051 case TCPTLS_ALERT_STOP: 03052 goto cleanup; 03053 case TCPTLS_ALERT_DATA: 03054 ao2_lock(me); 03055 if (!(packet = AST_LIST_REMOVE_HEAD(&me->packet_q, entry))) { 03056 ast_log(LOG_WARNING, "TCPTLS thread alert_pipe indicated packet should be sent, but frame_q is empty\n"); 03057 } 03058 ao2_unlock(me); 03059 03060 if (packet) { 03061 if (ast_tcptls_server_write(tcptls_session, ast_str_buffer(packet->data), packet->len) == -1) { 03062 ast_log(LOG_WARNING, "Failure to write to tcp/tls socket\n"); 03063 } 03064 ao2_t_ref(packet, -1, "tcptls packet sent, this is no longer needed"); 03065 } 03066 break; 03067 default: 03068 ast_log(LOG_ERROR, "Unknown tcptls thread alert '%d'\n", alert); 03069 } 03070 } 03071 } 03072 03073 ast_debug(2, "Shutting down thread for %s server\n", tcptls_session->ssl ? "TLS" : "TCP"); 03074 03075 cleanup: 03076 if (tcptls_session && !tcptls_session->client && !authenticated) { 03077 ast_atomic_fetchadd_int(&unauth_sessions, -1); 03078 } 03079 03080 if (me) { 03081 ao2_t_unlink(threadt, me, "Removing tcptls helper thread, thread is closing"); 03082 ao2_t_ref(me, -1, "Removing tcp_helper_threads threadinfo ref"); 03083 } 03084 deinit_req(&reqcpy); 03085 deinit_req(&req); 03086 03087 /* if client, we own the parent session arguments and must decrement ref */ 03088 if (ca) { 03089 ao2_t_ref(ca, -1, "closing tcptls thread, getting rid of client tcptls_session arguments"); 03090 } 03091 03092 if (tcptls_session) { 03093 ast_mutex_lock(&tcptls_session->lock); 03094 ast_tcptls_close_session_file(tcptls_session); 03095 tcptls_session->parent = NULL; 03096 ast_mutex_unlock(&tcptls_session->lock); 03097 03098 ao2_ref(tcptls_session, -1); 03099 tcptls_session = NULL; 03100 } 03101 return NULL; 03102 }
| static void add_blank | ( | struct sip_request * | req | ) | [static] |
add a blank line if no body
Definition at line 4423 of file chan_sip.c.
References ast_str_append().
Referenced by send_request(), and send_response().
04424 { 04425 if (!req->lines) { 04426 /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */ 04427 ast_str_append(&req->data, 0, "\r\n"); 04428 } 04429 }
| static void add_cc_call_info_to_response | ( | struct sip_pvt * | p, | |
| struct sip_request * | resp | |||
| ) | [static] |
Definition at line 12224 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().
12225 { 12226 char uri[SIPBUFSIZE]; 12227 struct ast_str *header = ast_str_alloca(SIPBUFSIZE); 12228 struct ast_cc_agent *agent = find_sip_cc_agent_by_original_callid(p); 12229 struct sip_cc_agent_pvt *agent_pvt; 12230 12231 if (!agent) { 12232 /* Um, what? How could the SIP_OFFER_CC flag be set but there not be an 12233 * agent? Oh well, we'll just warn and return without adding the header. 12234 */ 12235 ast_log(LOG_WARNING, "Can't find SIP CC agent for call '%s' even though OFFER_CC flag was set?\n", p->callid); 12236 return; 12237 } 12238 12239 agent_pvt = agent->private_data; 12240 12241 if (!ast_strlen_zero(agent_pvt->subscribe_uri)) { 12242 ast_copy_string(uri, agent_pvt->subscribe_uri, sizeof(uri)); 12243 } else { 12244 generate_uri(p, uri, sizeof(uri)); 12245 ast_copy_string(agent_pvt->subscribe_uri, uri, sizeof(agent_pvt->subscribe_uri)); 12246 } 12247 /* XXX Hardcode "NR" as the m reason for now. This should perhaps be changed 12248 * to be more accurate. This parameter has no bearing on the actual operation 12249 * of the feature; it's just there for informational purposes. 12250 */ 12251 ast_str_set(&header, 0, "<%s>;purpose=call-completion;m=%s", uri, "NR"); 12252 add_header(resp, "Call-Info", ast_str_buffer(header)); 12253 ao2_ref(agent, -1); 12254 }
| 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 11472 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().
11475 { 11476 int rtp_code; 11477 struct ast_format_list fmt; 11478 11479 11480 if (debug) 11481 ast_verbose("Adding codec 0x%" PRIx64 " (%s) to SDP\n", codec, ast_getformatname(codec)); 11482 if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->rtp), 1, codec)) == -1) 11483 return; 11484 11485 if (p->rtp) { 11486 struct ast_codec_pref *pref = &ast_rtp_instance_get_codecs(p->rtp)->pref; 11487 fmt = ast_codec_pref_getsize(pref, codec); 11488 } 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 */ 11489 return; 11490 ast_str_append(m_buf, 0, " %d", rtp_code); 11491 ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code, 11492 ast_rtp_lookup_mime_subtype2(1, codec, 11493 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0), 11494 ast_rtp_lookup_sample_rate2(1, codec)); 11495 11496 switch (codec) { 11497 case AST_FORMAT_G729A: 11498 /* Indicate that we don't support VAD (G.729 annex B) */ 11499 ast_str_append(a_buf, 0, "a=fmtp:%d annexb=no\r\n", rtp_code); 11500 break; 11501 case AST_FORMAT_G723_1: 11502 /* Indicate that we don't support VAD (G.723.1 annex A) */ 11503 ast_str_append(a_buf, 0, "a=fmtp:%d annexa=no\r\n", rtp_code); 11504 break; 11505 case AST_FORMAT_ILBC: 11506 /* Add information about us using only 20/30 ms packetization */ 11507 ast_str_append(a_buf, 0, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms); 11508 break; 11509 case AST_FORMAT_SIREN7: 11510 /* Indicate that we only expect 32Kbps */ 11511 ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=32000\r\n", rtp_code); 11512 break; 11513 case AST_FORMAT_SIREN14: 11514 /* Indicate that we only expect 48Kbps */ 11515 ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=48000\r\n", rtp_code); 11516 break; 11517 case AST_FORMAT_G719: 11518 /* Indicate that we only expect 64Kbps */ 11519 ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=64000\r\n", rtp_code); 11520 break; 11521 } 11522 11523 if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size)) 11524 *min_packet_size = fmt.cur_ms; 11525 11526 /* Our first codec packetization processed cannot be zero */ 11527 if ((*min_packet_size)==0 && fmt.cur_ms) 11528 *min_packet_size = fmt.cur_ms; 11529 }
| static int add_content | ( | struct sip_request * | req, | |
| const char * | line | |||
| ) | [static] |
Add content (not header) to SIP message.
Definition at line 10392 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().
10393 { 10394 if (req->lines) { 10395 ast_log(LOG_WARNING, "Can't add more content when the content has been finalized\n"); 10396 return -1; 10397 } 10398 10399 ast_str_append(&req->content, 0, "%s", line); 10400 return 0; 10401 }
| 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 11330 of file chan_sip.c.
References add_content(), and add_header().
Referenced by transmit_info_with_digit().
11331 { 11332 char tmp[256]; 11333 int event; 11334 if (mode) { 11335 /* Application/dtmf short version used by some implementations */ 11336 if ('0' <= digit && digit <= '9') { 11337 event = digit - '0'; 11338 } else if (digit == '*') { 11339 event = 10; 11340 } else if (digit == '#') { 11341 event = 11; 11342 } else if ('A' <= digit && digit <= 'D') { 11343 event = 12 + digit - 'A'; 11344 } else if ('a' <= digit && digit <= 'd') { 11345 event = 12 + digit - 'a'; 11346 } else { 11347 /* Unknown digit */ 11348 event = 0; 11349 } 11350 snprintf(tmp, sizeof(tmp), "%d\r\n", event); 11351 add_header(req, "Content-Type", "application/dtmf"); 11352 add_content(req, tmp); 11353 } else { 11354 /* Application/dtmf-relay as documented by Cisco */ 11355 snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration); 11356 add_header(req, "Content-Type", "application/dtmf-relay"); 11357 add_content(req, tmp); 11358 } 11359 return 0; 11360 }
| 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 12611 of file chan_sip.c.
References add_header(), ast_sockaddr_stringify_host_remote(), ast_strlen_zero(), and sip_reason_code_to_str().
Referenced by __transmit_response(), transmit_invite(), and update_redirecting().
12612 { 12613 const char *diverting_number; 12614 const char *diverting_name; 12615 const char *reason; 12616 char header_text[256]; 12617 12618 if (!pvt->owner) { 12619 return; 12620 } 12621 12622 diverting_number = pvt->owner->redirecting.from.number.str; 12623 if (!pvt->owner->redirecting.from.number.valid 12624 || ast_strlen_zero(diverting_number)) { 12625 return; 12626 } 12627 12628 reason = sip_reason_code_to_str(pvt->owner->redirecting.reason); 12629 12630 /* We at least have a number to place in the Diversion header, which is enough */ 12631 diverting_name = pvt->owner->redirecting.from.name.str; 12632 if (!pvt->owner->redirecting.from.name.valid 12633 || ast_strlen_zero(diverting_name)) { 12634 snprintf(header_text, sizeof(header_text), "<sip:%s@%s>;reason=%s", diverting_number, 12635 ast_sockaddr_stringify_host_remote(&pvt->ourip), reason); 12636 } else { 12637 snprintf(header_text, sizeof(header_text), "\"%s\" <sip:%s@%s>;reason=%s", 12638 diverting_name, diverting_number, 12639 ast_sockaddr_stringify_host_remote(&pvt->ourip), reason); 12640 } 12641 12642 add_header(req, "Diversion", header_text); 12643 }
| static int add_header | ( | struct sip_request * | req, | |
| const char * | var, | |||
| const char * | value | |||
| ) | [static] |
Add header to SIP message.
Definition at line 10334 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().
10335 { 10336 if (req->headers == SIP_MAX_HEADERS) { 10337 ast_log(LOG_WARNING, "Out of SIP header space\n"); 10338 return -1; 10339 } 10340 10341 if (req->lines) { 10342 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 10343 return -1; 10344 } 10345 10346 if (sip_cfg.compactheaders) { 10347 var = find_alias(var, var); 10348 } 10349 10350 ast_str_append(&req->data, 0, "%s: %s\r\n", var, value); 10351 req->header[req->headers] = ast_str_strlen(req->data); 10352 10353 req->headers++; 10354 10355 return 0; 10356 }
| 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 10362 of file chan_sip.c.
References add_header().
Referenced by initreqprep(), reqprep(), and transmit_register().
10363 { 10364 char clen[10]; 10365 10366 snprintf(clen, sizeof(clen), "%d", dialog->maxforwards); 10367 10368 return add_header(req, "Max-Forwards", clen); 10369 }
| 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 11610 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().
11613 { 11614 int rtp_code; 11615 11616 if (debug) 11617 ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype2(0, format, 0)); 11618 if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->rtp), 0, format)) == -1) 11619 return; 11620 11621 ast_str_append(m_buf, 0, " %d", rtp_code); 11622 ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code, 11623 ast_rtp_lookup_mime_subtype2(0, format, 0), 11624 ast_rtp_lookup_sample_rate2(0, format)); 11625 if (format == AST_RTP_DTMF) /* Indicate we support DTMF and FLASH... */ 11626 ast_str_append(a_buf, 0, "a=fmtp:%d 0-16\r\n", rtp_code); 11627 }
| static void add_peer_mailboxes | ( | struct sip_peer * | peer, | |
| const char * | value | |||
| ) | [static] |
Definition at line 27918 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().
27919 { 27920 char *next, *mbox, *context; 27921 27922 next = ast_strdupa(value); 27923 27924 while ((mbox = context = strsep(&next, ","))) { 27925 struct sip_mailbox *mailbox; 27926 int duplicate = 0; 27927 /* remove leading/trailing whitespace from mailbox string */ 27928 mbox = ast_strip(mbox); 27929 strsep(&context, "@"); 27930 27931 if (ast_strlen_zero(mbox)) { 27932 continue; 27933 } 27934 27935 /* Check whether the mailbox is already in the list */ 27936 AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { 27937 if (!strcmp(mailbox->mailbox, mbox) && !strcmp(S_OR(mailbox->context, ""), S_OR(context, ""))) { 27938 duplicate = 1; 27939 break; 27940 } 27941 } 27942 if (duplicate) { 27943 continue; 27944 } 27945 27946 if (!(mailbox = ast_calloc(1, sizeof(*mailbox) + strlen(mbox) + strlen(S_OR(context, ""))))) { 27947 continue; 27948 } 27949 27950 if (!ast_strlen_zero(context)) { 27951 mailbox->context = mailbox->mailbox + strlen(mbox) + 1; 27952 strcpy(mailbox->context, context); /* SAFE */ 27953 } 27954 strcpy(mailbox->mailbox, mbox); /* SAFE */ 27955 27956 AST_LIST_INSERT_TAIL(&peer->mailboxes, mailbox, entry); 27957 } 27958 }
| static void add_peer_mwi_subs | ( | struct sip_peer * | peer | ) | [static] |
Definition at line 25190 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().
25191 { 25192 struct sip_mailbox *mailbox; 25193 25194 AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { 25195 if (mailbox->event_sub) { 25196 ast_event_unsubscribe(mailbox->event_sub); 25197 } 25198 25199 mailbox->event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "SIP mbox event", peer, 25200 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox->mailbox, 25201 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, S_OR(mailbox->context, "default"), 25202 AST_EVENT_IE_END); 25203 } 25204 }
| static void add_realm_authentication | ( | struct sip_auth_container ** | credentials, | |
| const char * | configuration, | |||
| int | lineno | |||
| ) | [static] |
Definition at line 27722 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().
27723 { 27724 char *authcopy; 27725 char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; 27726 struct sip_auth *auth; 27727 27728 if (ast_strlen_zero(configuration)) { 27729 /* Nothing to add */ 27730 return; 27731 } 27732 27733 ast_debug(1, "Auth config :: %s\n", configuration); 27734 27735 authcopy = ast_strdupa(configuration); 27736 username = authcopy; 27737 27738 /* split user[:secret] and relm */ 27739 realm = strrchr(username, '@'); 27740 if (realm) 27741 *realm++ = '\0'; 27742 if (ast_strlen_zero(username) || ast_strlen_zero(realm)) { 27743 ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno); 27744 return; 27745 } 27746 27747 /* parse username at ':' for secret, or '#" for md5secret */ 27748 if ((secret = strchr(username, ':'))) { 27749 *secret++ = '\0'; 27750 } else if ((md5secret = strchr(username, '#'))) { 27751 *md5secret++ = '\0'; 27752 } 27753 27754 /* Create the continer if needed. */ 27755 if (!*credentials) { 27756 *credentials = ao2_t_alloc(sizeof(**credentials), destroy_realm_authentication, 27757 "Create realm auth container."); 27758 if (!*credentials) { 27759 /* Failed to create the credentials container. */ 27760 return; 27761 } 27762 } 27763 27764 /* Create the authentication credential entry. */ 27765 auth = ast_calloc(1, sizeof(*auth)); 27766 if (!auth) { 27767 return; 27768 } 27769 ast_copy_string(auth->realm, realm, sizeof(auth->realm)); 27770 ast_copy_string(auth->username, username, sizeof(auth->username)); 27771 if (secret) 27772 ast_copy_string(auth->secret, secret, sizeof(auth->secret)); 27773 if (md5secret) 27774 ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret)); 27775 27776 /* Add credential to container list. */ 27777 AST_LIST_INSERT_TAIL(&(*credentials)->list, auth, node); 27778 27779 ast_verb(3, "Added authentication for realm %s\n", realm); 27780 }
| static void add_required_respheader | ( | struct sip_request * | req | ) | [static] |
Definition at line 4500 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().
04501 { 04502 struct ast_str *str; 04503 int i; 04504 04505 if (!req->reqsipoptions) { 04506 return; 04507 } 04508 04509 str = ast_str_create(32); 04510 04511 for (i = 0; i < ARRAY_LEN(sip_options); ++i) { 04512 if (!(req->reqsipoptions & sip_options[i].id)) { 04513 continue; 04514 } 04515 if (ast_str_strlen(str) > 0) { 04516 ast_str_append(&str, 0, ", "); 04517 } 04518 ast_str_append(&str, 0, "%s", sip_options[i].text); 04519 } 04520 04521 if (ast_str_strlen(str) > 0) { 04522 add_header(req, "Require", ast_str_buffer(str)); 04523 } 04524 04525 ast_free(str); 04526 }
| static void add_route | ( | struct sip_request * | req, | |
| struct sip_route * | route | |||
| ) | [static] |
Add route header into request per learned route.
Definition at line 10503 of file chan_sip.c.
References add_header(), and ast_copy_string().
Referenced by initreqprep(), and reqprep().
10504 { 10505 char r[SIPBUFSIZE*2], *p; 10506 int n, rem = sizeof(r); 10507 10508 if (!route) 10509 return; 10510 10511 p = r; 10512 for (;route ; route = route->next) { 10513 n = strlen(route->hop); 10514 if (rem < n+3) /* we need room for ",<route>" */ 10515 break; 10516 if (p != r) { /* add a separator after fist route */ 10517 *p++ = ','; 10518 --rem; 10519 } 10520 *p++ = '<'; 10521 ast_copy_string(p, route->hop, rem); /* cannot fail */ 10522 p += n; 10523 *p++ = '>'; 10524 rem -= (n+2); 10525 } 10526 *p = '\0'; 10527 add_header(req, "Route", r); 10528 }
| static int add_rpid | ( | struct sip_request * | req, | |
| struct sip_pvt * | p | |||
| ) | [static] |
Add Remote-Party-ID header to SIP message.
Definition at line 11366 of file chan_sip.c.
References add_header(), ast_party_id_presentation(), AST_PRES_ALLOWED, AST_PRES_ALLOWED_NETWORK_NUMBER, AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, AST_PRES_PROHIB_NETWORK_NUMBER, AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, AST_PRES_RESTRICTION, ast_sockaddr_stringify_host_remote(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_set(), ast_strlen_zero(), ast_test_flag, ast_uri_encode(), and S_OR.
Referenced by __transmit_response(), transmit_invite(), transmit_reinvite_with_sdp(), transmit_response_with_sdp(), and update_connectedline().
11367 { 11368 struct ast_str *tmp = ast_str_alloca(256); 11369 char tmp2[256]; 11370 char *lid_num = NULL; 11371 char *lid_name = NULL; 11372 int lid_pres; 11373 const char *fromdomain; 11374 const char *privacy = NULL; 11375 const char *screen = NULL; 11376 const char *anonymous_string = "\"Anonymous\" <sip:anonymous@anonymous.invalid>"; 11377 11378 if (!ast_test_flag(&p->flags[0], SIP_SENDRPID)) { 11379 return 0; 11380 } 11381 11382 if (p->owner && p->owner->connected.id.number.valid 11383 && p->owner->connected.id.number.str) { 11384 lid_num = p->owner->connected.id.number.str; 11385 } 11386 if (p->owner && p->owner->connected.id.name.valid 11387 && p->owner->connected.id.name.str) { 11388 lid_name = p->owner->connected.id.name.str; 11389 } 11390 lid_pres = (p->owner) ? ast_party_id_presentation(&p->owner->connected.id) : AST_PRES_NUMBER_NOT_AVAILABLE; 11391 11392 if (ast_strlen_zero(lid_num)) 11393 return 0; 11394 if (ast_strlen_zero(lid_name)) 11395 lid_name = lid_num; 11396 fromdomain = S_OR(p->fromdomain, ast_sockaddr_stringify_host_remote(&p->ourip)); 11397 11398 lid_num = ast_uri_encode(lid_num, tmp2, sizeof(tmp2), 0); 11399 11400 if (ast_test_flag(&p->flags[0], SIP_SENDRPID_PAI)) { 11401 if ((lid_pres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) { 11402 ast_str_set(&tmp, -1, "%s", anonymous_string); 11403 } else { 11404 ast_str_set(&tmp, -1, "\"%s\" <sip:%s@%s>", lid_name, lid_num, fromdomain); 11405 } 11406 add_header(req, "P-Asserted-Identity", ast_str_buffer(tmp)); 11407 } else { 11408 ast_str_set(&tmp, -1, "\"%s\" <sip:%s@%s>;party=%s", lid_name, lid_num, fromdomain, p->outgoing_call ? "calling" : "called"); 11409 11410 switch (lid_pres) { 11411 case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 11412 case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 11413 privacy = "off"; 11414 screen = "no"; 11415 break; 11416 case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 11417 case AST_PRES_ALLOWED_NETWORK_NUMBER: 11418 privacy = "off"; 11419 screen = "yes"; 11420 break; 11421 case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 11422 case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 11423 privacy = "full"; 11424 screen = "no"; 11425 break; 11426 case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 11427 case AST_PRES_PROHIB_NETWORK_NUMBER: 11428 privacy = "full"; 11429 screen = "yes"; 11430 break; 11431 case AST_PRES_NUMBER_NOT_AVAILABLE: 11432 break; 11433 default: 11434 if ((lid_pres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) { 11435 privacy = "full"; 11436 } 11437 else 11438 privacy = "off"; 11439 screen = "no"; 11440 break; 11441 } 11442 11443 if (!ast_strlen_zero(privacy) && !ast_strlen_zero(screen)) { 11444 ast_str_append(&tmp, -1, ";privacy=%s;screen=%s", privacy, screen); 11445 } 11446 11447 add_header(req, "Remote-Party-ID", ast_str_buffer(tmp)); 11448 } 11449 return 0; 11450 }
| 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 11748 of file chan_sip.c.
References add_codec_to_sdp(), add_content(), add_header(), add_noncodec_to_sdp(), add_tcodec_to_sdp(), add_vcodec_to_sdp(), ast_codec_pref_index(), ast_debug, AST_FORMAT_AUDIO_MASK, AST_FORMAT_TEXT_MASK, AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_internal_timing_enabled(), ast_log(), ast_random(), AST_RTP_MAX, ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_is_ipv4_mapped(), ast_sockaddr_is_ipv6(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_sockaddr_stringify_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().
11749 { 11750 format_t alreadysent = 0; 11751 int doing_directmedia = FALSE; 11752 11753 struct ast_sockaddr addr = { {0,} }; 11754 struct ast_sockaddr vaddr = { {0,} }; 11755 struct ast_sockaddr taddr = { {0,} }; 11756 struct ast_sockaddr udptladdr = { {0,} }; 11757 struct ast_sockaddr dest = { {0,} }; 11758 struct ast_sockaddr vdest = { {0,} }; 11759 struct ast_sockaddr tdest = { {0,} }; 11760 struct ast_sockaddr udptldest = { {0,} }; 11761 11762 /* SDP fields */ 11763 char *version = "v=0\r\n"; /* Protocol version */ 11764 char subject[256]; /* Subject of the session */ 11765 char owner[256]; /* Session owner/creator */ 11766 char connection[256]; /* Connection data */ 11767 char *session_time = "t=0 0\r\n"; /* Time the session is active */ 11768 char bandwidth[256] = ""; /* Max bitrate */ 11769 char *hold = ""; 11770 struct ast_str *m_audio = ast_str_alloca(256); /* Media declaration line for audio */ 11771 struct ast_str *m_video = ast_str_alloca(256); /* Media declaration line for video */ 11772 struct ast_str *m_text = ast_str_alloca(256); /* Media declaration line for text */ 11773 struct ast_str *m_modem = ast_str_alloca(256); /* Media declaration line for modem */ 11774 struct ast_str *a_audio = ast_str_alloca(1024); /* Attributes for audio */ 11775 struct ast_str *a_video = ast_str_alloca(1024); /* Attributes for video */ 11776 struct ast_str *a_text = ast_str_alloca(1024); /* Attributes for text */ 11777 struct ast_str *a_modem = ast_str_alloca(1024); /* Attributes for modem */ 11778 const char *a_crypto = NULL; 11779 const char *v_a_crypto = NULL; 11780 const char *t_a_crypto = NULL; 11781 11782 format_t x; 11783 format_t capability = 0; 11784 int needaudio = FALSE; 11785 int needvideo = FALSE; 11786 int needtext = FALSE; 11787 int debug = sip_debug_test_pvt(p); 11788 int min_audio_packet_size = 0; 11789 int min_video_packet_size = 0; 11790 int min_text_packet_size = 0; 11791 11792 char codecbuf[SIPBUFSIZE]; 11793 char buf[SIPBUFSIZE]; 11794 char dummy_answer[256]; 11795 11796 /* Set the SDP session name */ 11797 snprintf(subject, sizeof(subject), "s=%s\r\n", ast_strlen_zero(global_sdpsession) ? "-" : global_sdpsession); 11798 11799 if (!p->rtp) { 11800 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 11801 return AST_FAILURE; 11802 } 11803 /* XXX We should not change properties in the SIP dialog until 11804 we have acceptance of the offer if this is a re-invite */ 11805 11806 /* Set RTP Session ID and version */ 11807 if (!p->sessionid) { 11808 p->sessionid = (int)ast_random(); 11809 p->sessionversion = p->sessionid; 11810 } else { 11811 if (oldsdp == FALSE) 11812 p->sessionversion++; 11813 } 11814 11815 if (add_audio) { 11816 doing_directmedia = (!ast_sockaddr_isnull(&p->redirip) && p->redircodecs) ? TRUE : FALSE; 11817 /* Check if we need video in this call */ 11818 if ((p->jointcapability & AST_FORMAT_VIDEO_MASK) && !p->novideo) { 11819 if (doing_directmedia && !(p->jointcapability & AST_FORMAT_VIDEO_MASK & p->redircodecs)) { 11820 ast_debug(2, "This call needs video offers, but caller probably did not offer it!\n"); 11821 } else if (p->vrtp) { 11822 needvideo = TRUE; 11823 ast_debug(2, "This call needs video offers!\n"); 11824 } else { 11825 ast_debug(2, "This call needs video offers, but there's no video support enabled!\n"); 11826 } 11827 } 11828 /* Check if we need text in this call */ 11829 if ((p->jointcapability & AST_FORMAT_TEXT_MASK) && !p->notext) { 11830 if (sipdebug_text) 11831 ast_verbose("We think we can do text\n"); 11832 if (p->trtp) { 11833 if (sipdebug_text) { 11834 ast_verbose("And we have a text rtp object\n"); 11835 } 11836 needtext = TRUE; 11837 ast_debug(2, "This call needs text offers! \n"); 11838 } else { 11839 ast_debug(2, "This call needs text offers, but there's no text support enabled ! \n"); 11840 } 11841 } 11842 } 11843 11844 get_our_media_address(p, needvideo, needtext, &addr, &vaddr, &taddr, &dest, &vdest, &tdest); 11845 11846 snprintf(owner, sizeof(owner), "o=%s %d %d IN %s %s\r\n", 11847 ast_strlen_zero(global_sdpowner) ? "-" : global_sdpowner, 11848 p->sessionid, p->sessionversion, 11849 (ast_sockaddr_is_ipv6(&dest) && !ast_sockaddr_is_ipv4_mapped(&dest)) ? 11850 "IP6" : "IP4", 11851 ast_sockaddr_stringify_addr_remote(&dest)); 11852 11853 snprintf(connection, sizeof(connection), "c=IN %s %s\r\n", 11854 (ast_sockaddr_is_ipv6(&dest) && !ast_sockaddr_is_ipv4_mapped(&dest)) ? 11855 "IP6" : "IP4", 11856 ast_sockaddr_stringify_addr_remote(&dest)); 11857 11858 if (add_audio) { 11859 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR) { 11860 hold = "a=recvonly\r\n"; 11861 doing_directmedia = FALSE; 11862 } else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE) { 11863 hold = "a=inactive\r\n"; 11864 doing_directmedia = FALSE; 11865 } else { 11866 hold = "a=sendrecv\r\n"; 11867 } 11868 11869 capability = p->jointcapability; 11870 11871 /* XXX note, Video and Text are negated - 'true' means 'no' */ 11872 ast_debug(1, "** Our capability: %s Video flag: %s Text flag: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), capability), 11873 p->novideo ? "True" : "False", p->notext ? "True" : "False"); 11874 ast_debug(1, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec)); 11875 11876 if (doing_directmedia) { 11877 capability &= p->redircodecs; 11878 ast_debug(1, "** Our native-bridge filtered capablity: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), capability)); 11879 } 11880 11881 /* Check if we need audio */ 11882 if (capability & AST_FORMAT_AUDIO_MASK) 11883 needaudio = TRUE; 11884 11885 if (debug) { 11886 ast_verbose("Audio is at %s\n", ast_sockaddr_stringify_port(&addr)); 11887 } 11888 11889 /* Ok, we need video. Let's add what we need for video and set codecs. 11890 Video is handled differently than audio since we can not transcode. */ 11891 if (needvideo) { 11892 get_crypto_attrib(p->vsrtp, &v_a_crypto); 11893 ast_str_append(&m_video, 0, "m=video %d RTP/%s", ast_sockaddr_port(&vdest), 11894 v_a_crypto ? "SAVP" : "AVP"); 11895 11896 /* Build max bitrate string */ 11897 if (p->maxcallbitrate) 11898 snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate); 11899 if (debug) { 11900 ast_verbose("Video is at %s\n", ast_sockaddr_stringify(&vdest)); 11901 } 11902 } 11903 11904 /* Ok, we need text. Let's add what we need for text and set codecs. 11905 Text is handled differently than audio since we can not transcode. */ 11906 if (needtext) { 11907 if (sipdebug_text) 11908 ast_verbose("Lets set up the text sdp\n"); 11909 get_crypto_attrib(p->tsrtp, &t_a_crypto); 11910 ast_str_append(&m_text, 0, "m=text %d RTP/%s", ast_sockaddr_port(&tdest), 11911 t_a_crypto ? "SAVP" : "AVP"); 11912 if (debug) { /* XXX should I use tdest below ? */ 11913 ast_verbose("Text is at %s\n", ast_sockaddr_stringify(&taddr)); 11914 } 11915 } 11916 11917 /* Start building generic SDP headers */ 11918 11919 /* We break with the "recommendation" and send our IP, in order that our 11920 peer doesn't have to ast_gethostbyname() us */ 11921 11922 get_crypto_attrib(p->srtp, &a_crypto); 11923 ast_str_append(&m_audio, 0, "m=audio %d RTP/%s", ast_sockaddr_port(&dest), 11924 a_crypto ? "SAVP" : "AVP"); 11925 11926 /* Now, start adding audio codecs. These are added in this order: 11927 - First what was requested by the calling channel 11928 - Then preferences in order from sip.conf device config for this peer/user 11929 - Then other codecs in capabilities, including video 11930 */ 11931 11932 /* Prefer the audio codec we were requested to use, first, no matter what 11933 Note that p->prefcodec can include video codecs, so mask them out 11934 */ 11935 if (capability & p->prefcodec) { 11936 format_t codec = p->prefcodec & AST_FORMAT_AUDIO_MASK; 11937 11938 add_codec_to_sdp(p, codec, &m_audio, &a_audio, debug, &min_audio_packet_size); 11939 alreadysent |= codec; 11940 } 11941 11942 /* Start by sending our preferred audio/video codecs */ 11943 for (x = 0; x < 64; x++) { 11944 format_t codec; 11945 11946 if (!(codec = ast_codec_pref_index(&p->prefs, x))) 11947 break; 11948 11949 if (!(capability & codec)) 11950 continue; 11951 11952 if (alreadysent & codec) 11953 continue; 11954 11955 add_codec_to_sdp(p, codec, &m_audio, &a_audio, debug, &min_audio_packet_size); 11956 alreadysent |= codec; 11957 } 11958 11959 /* Now send any other common audio and video codecs, and non-codec formats: */ 11960 for (x = 1ULL; x <= (needtext ? AST_FORMAT_TEXT_MASK : (needvideo ? AST_FORMAT_VIDEO_MASK : AST_FORMAT_AUDIO_MASK)); x <<= 1) { 11961 if (!(capability & x)) /* Codec not requested */ 11962 continue; 11963 11964 if (alreadysent & x) /* Already added to SDP */ 11965 continue; 11966 11967 if (x & AST_FORMAT_AUDIO_MASK) 11968 add_codec_to_sdp(p, x, &m_audio, &a_audio, debug, &min_audio_packet_size); 11969 else if (x & AST_FORMAT_VIDEO_MASK) 11970 add_vcodec_to_sdp(p, x, &m_video, &a_video, debug, &min_video_packet_size); 11971 else if (x & AST_FORMAT_TEXT_MASK) 11972 add_tcodec_to_sdp(p, x, &m_text, &a_text, debug, &min_text_packet_size); 11973 } 11974 11975 /* Now add DTMF RFC2833 telephony-event as a codec */ 11976 for (x = 1LL; x <= AST_RTP_MAX; x <<= 1) { 11977 if (!(p->jointnoncodeccapability & x)) 11978 continue; 11979 11980 add_noncodec_to_sdp(p, x, &m_audio, &a_audio, debug); 11981 } 11982 11983 ast_debug(3, "-- Done with adding codecs to SDP\n"); 11984 11985 if (!p->owner || !ast_internal_timing_enabled(p->owner)) 11986 ast_str_append(&a_audio, 0, "a=silenceSupp:off - - - -\r\n"); 11987 11988 if (min_audio_packet_size) 11989 ast_str_append(&a_audio, 0, "a=ptime:%d\r\n", min_audio_packet_size); 11990 11991 /* XXX don't think you can have ptime for video */ 11992 if (min_video_packet_size) 11993 ast_str_append(&a_video, 0, "a=ptime:%d\r\n", min_video_packet_size); 11994 11995 /* XXX don't think you can have ptime for text */ 11996 if (min_text_packet_size) 11997 ast_str_append(&a_text, 0, "a=ptime:%d\r\n", min_text_packet_size); 11998 11999 if (ast_str_size(m_audio) - ast_str_strlen(m_audio) < 2 || ast_str_size(m_video) - ast_str_strlen(m_video) < 2 || 12000 ast_str_size(m_text) - ast_str_strlen(m_text) < 2 || ast_str_size(a_text) - ast_str_strlen(a_text) < 2 || 12001 ast_str_size(a_audio) - ast_str_strlen(a_audio) < 2 || ast_str_size(a_video) - ast_str_strlen(a_video) < 2) 12002 ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n"); 12003 } 12004 12005 if (add_t38) { 12006 /* Our T.38 end is */ 12007 ast_udptl_get_us(p->udptl, &udptladdr); 12008 12009 /* Determine T.38 UDPTL destination */ 12010 if (!ast_sockaddr_isnull(&p->udptlredirip)) { 12011 ast_sockaddr_copy(&udptldest, &p->udptlredirip); 12012 } else { 12013 ast_sockaddr_copy(&udptldest, &p->ourip); 12014 ast_sockaddr_set_port(&udptldest, ast_sockaddr_port(&udptladdr)); 12015 } 12016 12017 if (debug) { 12018 ast_debug(1, "T.38 UDPTL is at %s port %d\n", ast_sockaddr_stringify_addr(&p->ourip), ast_sockaddr_port(&udptladdr)); 12019 } 12020 12021 /* We break with the "recommendation" and send our IP, in order that our 12022 peer doesn't have to ast_gethostbyname() us */ 12023 12024 ast_str_append(&m_modem, 0, "m=image %d udptl t38\r\n", ast_sockaddr_port(&udptldest)); 12025 12026 if (!ast_sockaddr_cmp(&udptldest, &dest)) { 12027 ast_str_append(&m_modem, 0, "c=IN %s %s\r\n", 12028 (ast_sockaddr_is_ipv6(&dest) && !ast_sockaddr_is_ipv4_mapped(&dest)) ? 12029 "IP6" : "IP4", ast_sockaddr_stringify_addr_remote(&udptldest)); 12030 } 12031 12032 ast_str_append(&a_modem, 0, "a=T38FaxVersion:%d\r\n", p->t38.our_parms.version); 12033 ast_str_append(&a_modem, 0, "a=T38MaxBitRate:%d\r\n", t38_get_rate(p->t38.our_parms.rate)); 12034 if (p->t38.our_parms.fill_bit_removal) { 12035 ast_str_append(&a_modem, 0, "a=T38FaxFillBitRemoval\r\n"); 12036 } 12037 if (p->t38.our_parms.transcoding_mmr) { 12038 ast_str_append(&a_modem, 0, "a=T38FaxTranscodingMMR\r\n"); 12039 } 12040 if (p->t38.our_parms.transcoding_jbig) { 12041 ast_str_append(&a_modem, 0, "a=T38FaxTranscodingJBIG\r\n"); 12042 } 12043 switch (p->t38.our_parms.rate_management) { 12044 case AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF: 12045 ast_str_append(&a_modem, 0, "a=T38FaxRateManagement:transferredTCF\r\n"); 12046 break; 12047 case AST_T38_RATE_MANAGEMENT_LOCAL_TCF: 12048 ast_str_append(&a_modem, 0, "a=T38FaxRateManagement:localTCF\r\n"); 12049 break; 12050 } 12051 ast_str_append(&a_modem, 0, "a=T38FaxMaxDatagram:%u\r\n", ast_udptl_get_local_max_datagram(p->udptl)); 12052 switch (ast_udptl_get_error_correction_scheme(p->udptl)) { 12053 case UDPTL_ERROR_CORRECTION_NONE: 12054 break; 12055 case UDPTL_ERROR_CORRECTION_FEC: 12056 ast_str_append(&a_modem, 0, "a=T38FaxUdpEC:t38UDPFEC\r\n"); 12057 break; 12058 case UDPTL_ERROR_CORRECTION_REDUNDANCY: 12059 ast_str_append(&a_modem, 0, "a=T38FaxUdpEC:t38UDPRedundancy\r\n"); 12060 break; 12061 } 12062 } 12063 12064 if (needaudio) 12065 ast_str_append(&m_audio, 0, "\r\n"); 12066 if (needvideo) 12067 ast_str_append(&m_video, 0, "\r\n"); 12068 if (needtext) 12069 ast_str_append(&m_text, 0, "\r\n"); 12070 12071 add_header(resp, "Content-Type", "application/sdp"); 12072 add_content(resp, version); 12073 add_content(resp, owner); 12074 add_content(resp, subject); 12075 add_content(resp, connection); 12076 /* only if video response is appropriate */ 12077 if (needvideo) { 12078 add_content(resp, bandwidth); 12079 } 12080 add_content(resp, session_time); 12081 /* if this is a response to an invite, order our offers properly */ 12082 if (p->offered_media[SDP_AUDIO].order_offered || 12083 p->offered_media[SDP_VIDEO].order_offered || 12084 p->offered_media[SDP_TEXT].order_offered || 12085 p->offered_media[SDP_IMAGE].order_offered) { 12086 int i; 12087 /* we have up to 3 streams as limited by process_sdp */ 12088 for (i = 1; i <= 3; i++) { 12089 if (p->offered_media[SDP_AUDIO].order_offered == i) { 12090 if (needaudio) { 12091 add_content(resp, ast_str_buffer(m_audio)); 12092 add_content(resp, ast_str_buffer(a_audio)); 12093 add_content(resp, hold); 12094 if (a_crypto) { 12095 add_content(resp, a_crypto); 12096 } 12097 } else { 12098 snprintf(dummy_answer, sizeof(dummy_answer), "m=audio 0 RTP/AVP %s\r\n", p->offered_media[SDP_AUDIO].codecs); 12099 add_content(resp, dummy_answer); 12100 } 12101 } else if (p->offered_media[SDP_VIDEO].order_offered == i) { 12102 if (needvideo) { /* only if video response is appropriate */ 12103 add_content(resp, ast_str_buffer(m_video)); 12104 add_content(resp, ast_str_buffer(a_video)); 12105 add_content(resp, hold); /* Repeat hold for the video stream */ 12106 if (v_a_crypto) { 12107 add_content(resp, v_a_crypto); 12108 } 12109 } else { 12110 snprintf(dummy_answer, sizeof(dummy_answer), "m=video 0 RTP/AVP %s\r\n", p->offered_media[SDP_VIDEO].codecs); 12111 add_content(resp, dummy_answer); 12112 } 12113 } else if (p->offered_media[SDP_TEXT].order_offered == i) { 12114 if (needtext) { /* only if text response is appropriate */ 12115 add_content(resp, ast_str_buffer(m_text)); 12116 add_content(resp, ast_str_buffer(a_text)); 12117 add_content(resp, hold); /* Repeat hold for the text stream */ 12118 if (t_a_crypto) { 12119 add_content(resp, t_a_crypto); 12120 } 12121 } else { 12122 snprintf(dummy_answer, sizeof(dummy_answer), "m=text 0 RTP/AVP %s\r\n", p->offered_media[SDP_TEXT].codecs); 12123 add_content(resp, dummy_answer); 12124 } 12125 } else if (p->offered_media[SDP_IMAGE].order_offered == i) { 12126 if (add_t38) { 12127 add_content(resp, ast_str_buffer(m_modem)); 12128 add_content(resp, ast_str_buffer(a_modem)); 12129 } else { 12130 add_content(resp, "m=image 0 udptl t38\r\n"); 12131 } 12132 } 12133 } 12134 } else { 12135 /* generate new SDP from scratch, no offers */ 12136 if (needaudio) { 12137 add_content(resp, ast_str_buffer(m_audio)); 12138 add_content(resp, ast_str_buffer(a_audio)); 12139 add_content(resp, hold); 12140 if (a_crypto) { 12141 add_content(resp, a_crypto); 12142 } 12143 } 12144 if (needvideo) { /* only if video response is appropriate */ 12145 add_content(resp, ast_str_buffer(m_video)); 12146 add_content(resp, ast_str_buffer(a_video)); 12147 add_content(resp, hold); /* Repeat hold for the video stream */ 12148 if (v_a_crypto) { 12149 add_content(resp, v_a_crypto); 12150 } 12151 } 12152 if (needtext) { /* only if text response is appropriate */ 12153 add_content(resp, ast_str_buffer(m_text)); 12154 add_content(resp, ast_str_buffer(a_text)); 12155 add_content(resp, hold); /* Repeat hold for the text stream */ 12156 if (t_a_crypto) { 12157 add_content(resp, t_a_crypto); 12158 } 12159 } 12160 if (add_t38) { 12161 add_content(resp, ast_str_buffer(m_modem)); 12162 add_content(resp, ast_str_buffer(a_modem)); 12163 } 12164 } 12165 12166 /* Update lastrtprx when we send our SDP */ 12167 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 12168 12169 ast_debug(3, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, capability)); 12170 12171 return AST_SUCCESS; 12172 }
| 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 27631 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().
27632 { 27633 struct domain *d; 27634 27635 if (ast_strlen_zero(domain)) { 27636 ast_log(LOG_WARNING, "Zero length domain.\n"); 27637 return 1; 27638 } 27639 27640 if (!(d = ast_calloc(1, sizeof(*d)))) 27641 return 0; 27642 27643 ast_copy_string(d->domain, domain, sizeof(d->domain)); 27644 27645 if (!ast_strlen_zero(context)) 27646 ast_copy_string(d->context, context, sizeof(d->context)); 27647 27648 d->mode = mode; 27649 27650 AST_LIST_LOCK(&domain_list); 27651 AST_LIST_INSERT_TAIL(&domain_list, d, list); 27652 AST_LIST_UNLOCK(&domain_list); 27653 27654 if (sipdebug) 27655 ast_debug(1, "Added local SIP domain '%s'\n", domain); 27656 27657 return 1; 27658 }
| 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 10322 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().
10323 { 10324 int res; 10325 if (st_get_mode(pvt, 0) != SESSION_TIMER_MODE_REFUSE) { 10326 res = add_header(req, "Supported", "replaces, timer"); 10327 } else { 10328 res = add_header(req, "Supported", "replaces"); 10329 } 10330 return res; 10331 }
| 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 11556 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().
11559 { 11560 int rtp_code; 11561 11562 if (!p->trtp) 11563 return; 11564 11565 if (debug) 11566 ast_verbose("Adding text codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec)); 11567 11568 if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->trtp), 1, codec)) == -1) 11569 return; 11570 11571 ast_str_append(m_buf, 0, " %d", rtp_code); 11572 ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code, 11573 ast_rtp_lookup_mime_subtype2(1, codec, 0), 11574 ast_rtp_lookup_sample_rate2(1, codec)); 11575 /* Add fmtp code here */ 11576 11577 if (codec == AST_FORMAT_T140RED) { 11578 int t140code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->trtp), 1, AST_FORMAT_T140); 11579 ast_str_append(a_buf, 0, "a=fmtp:%d %d/%d/%d\r\n", rtp_code, 11580 t140code, 11581 t140code, 11582 t140code); 11583 11584 } 11585 }
| static int add_text | ( | struct sip_request * | req, | |
| const char * | text | |||
| ) | [static] |
Add text body to SIP message.
Definition at line 11318 of file chan_sip.c.
References add_content(), and add_header().
Referenced by transmit_message_with_text().
11319 { 11320 /* XXX Convert \n's to \r\n's XXX */ 11321 add_header(req, "Content-Type", "text/plain;charset=UTF-8"); 11322 add_content(req, text); 11323 return 0; 11324 }
| static struct ast_variable* add_var | ( | const char * | buf, | |
| struct ast_variable * | list | |||
| ) | [static, read] |
implement the setvar config line
Definition at line 27811 of file chan_sip.c.
References ast_strdupa, ast_variable_new(), and ast_variable::next.
Referenced by build_peer().
27812 { 27813 struct ast_variable *tmpvar = NULL; 27814 char *varname = ast_strdupa(buf), *varval = NULL; 27815 27816 if ((varval = strchr(varname, '='))) { 27817 *varval++ = '\0'; 27818 if ((tmpvar = ast_variable_new(varname, varval, ""))) { 27819 tmpvar->next = list; 27820 list = tmpvar; 27821 } 27822 } 27823 return list; 27824 }
| 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 11533 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().
11536 { 11537 int rtp_code; 11538 11539 if (!p->vrtp) 11540 return; 11541 11542 if (debug) 11543 ast_verbose("Adding video codec 0x%" PRIx64 " (%s) to SDP\n", codec, ast_getformatname(codec)); 11544 11545 if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->vrtp), 1, codec)) == -1) 11546 return; 11547 11548 ast_str_append(m_buf, 0, " %d", rtp_code); 11549 ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code, 11550 ast_rtp_lookup_mime_subtype2(1, codec, 0), 11551 ast_rtp_lookup_sample_rate2(1, codec)); 11552 /* Add fmtp code here */ 11553 }
| static int add_vidupdate | ( | struct sip_request * | req | ) | [static] |
add XML encoded media control with update
Definition at line 11454 of file chan_sip.c.
References add_content(), and add_header().
Referenced by transmit_info_with_vidupdate().
11455 { 11456 const char *xml_is_a_huge_waste_of_space = 11457 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" 11458 " <media_control>\r\n" 11459 " <vc_primitive>\r\n" 11460 " <to_encoder>\r\n" 11461 " <picture_fast_update>\r\n" 11462 " </picture_fast_update>\r\n" 11463 " </to_encoder>\r\n" 11464 " </vc_primitive>\r\n" 11465 " </media_control>\r\n"; 11466 add_header(req, "Content-Type", "application/media_control+xml"); 11467 add_content(req, xml_is_a_huge_waste_of_space); 11468 return 0; 11469 }
| 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 8227 of file chan_sip.c.
References ast_sockaddr_ipv4().
Referenced by process_via().
08228 { 08229 return ((ast_sockaddr_ipv4(addr) & 0xf0000000) == 0xe0000000); 08230 }
| static const char * allowoverlap2str | ( | int | mode | ) | [static] |
Convert AllowOverlap setting to printable string.
Definition at line 17612 of file chan_sip.c.
References map_x_s().
Referenced by _sip_show_peer(), and sip_show_settings().
17613 { 17614 return map_x_s(allowoverlapstr, mode, "<error>"); 17615 }
| static void append_date | ( | struct sip_request * | req | ) | [static] |
Append date to SIP message.
Definition at line 11141 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().
11142 { 11143 char tmpdat[256]; 11144 struct tm tm; 11145 time_t t = time(NULL); 11146 11147 gmtime_r(&t, &tm); 11148 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm); 11149 add_header(req, "Date", tmpdat); 11150 }
| static void append_history_full | ( | struct sip_pvt * | p, | |
| const char * | fmt, | |||
| ... | ||||
| ) | [static] |
Append to SIP dialog history with arg list.
Definition at line 3868 of file chan_sip.c.
References append_history_va().
03869 { 03870 va_list ap; 03871 03872 if (!p) { 03873 return; 03874 } 03875 03876 if (!p->do_history && !recordhistory && !dumphistory) { 03877 return; 03878 } 03879 03880 va_start(ap, fmt); 03881 append_history_va(p, fmt, ap); 03882 va_end(ap); 03883 03884 return; 03885 }
| 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 3840 of file chan_sip.c.
References ast_calloc, ast_free, AST_LIST_INSERT_TAIL, and AST_LIST_REMOVE_HEAD.
Referenced by append_history_full().
03841 { 03842 char buf[80], *c = buf; /* max history length */ 03843 struct sip_history *hist; 03844 int l; 03845 03846 vsnprintf(buf, sizeof(buf), fmt, ap); 03847 strsep(&c, "\r\n"); /* Trim up everything after \r or \n */ 03848 l = strlen(buf) + 1; 03849 if (!(hist = ast_calloc(1, sizeof(*hist) + l))) { 03850 return; 03851 } 03852 if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) { 03853 ast_free(hist); 03854 return; 03855 } 03856 memcpy(hist->event, buf, l); 03857 if (p->history_entries == MAX_HISTORY_ENTRIES) { 03858 struct sip_history *oldest; 03859 oldest = AST_LIST_REMOVE_HEAD(p->history, list); 03860 p->history_entries--; 03861 ast_free(oldest); 03862 } 03863 AST_LIST_INSERT_TAIL(p->history, hist, list); 03864 p->history_entries++; 03865 }
| static int apply_directmedia_ha | ( | struct sip_pvt * | p1, | |
| struct sip_pvt * | p2, | |||
| const char * | op | |||
| ) | [static] |
Definition at line 29731 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().
29732 { 29733 struct ast_sockaddr us = { { 0, }, }, them = { { 0, }, }; 29734 int res = AST_SENSE_ALLOW; 29735 29736 ast_rtp_instance_get_remote_address(p1->rtp, &them); 29737 ast_rtp_instance_get_local_address(p1->rtp, &us); 29738 29739 /* If p2 is a guest call, there will be no peer. If there is no peer, there 29740 * is no directmediaha, so go ahead and allow it */ 29741 if (!p2->relatedpeer) { 29742 return res; 29743 } 29744 29745 if ((res = ast_apply_ha(p2->relatedpeer->directmediaha, &them)) == AST_SENSE_DENY) { 29746 const char *us_addr = ast_strdupa(ast_sockaddr_stringify(&us)); 29747 const char *them_addr = ast_strdupa(ast_sockaddr_stringify(&them)); 29748 29749 ast_debug(3, "Reinvite %s to %s denied by directmedia ACL on %s\n", 29750 op, them_addr, us_addr); 29751 } 29752 29753 return res; 29754 }
| 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 22275 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().
22276 { 22277 if (chan && chan->_state == AST_STATE_UP) { 22278 if (ast_test_flag(chan, AST_FLAG_MOH)) 22279 ast_moh_stop(chan); 22280 else if (chan->generatordata) 22281 ast_deactivate_generator(chan); 22282 } 22283 }
| 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 3736 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().
03737 { 03738 struct ast_sockaddr theirs; 03739 03740 /* Set want_remap to non-zero if we want to remap 'us' to an externally 03741 * reachable IP address and port. This is done if: 03742 * 1. we have a localaddr list (containing 'internal' addresses marked 03743 * as 'deny', so ast_apply_ha() will return AST_SENSE_DENY on them, 03744 * and AST_SENSE_ALLOW on 'external' ones); 03745 * 2. externaddr is set, so we know what to use as the 03746 * externally visible address; 03747 * 3. the remote address, 'them', is external; 03748 * 4. the address returned by ast_ouraddrfor() is 'internal' (AST_SENSE_DENY 03749 * when passed to ast_apply_ha() so it does need to be remapped. 03750 * This fourth condition is checked later. 03751 */ 03752 int want_remap = 0; 03753 03754 ast_sockaddr_copy(us, &internip); /* starting guess for the internal address */ 03755 /* now ask the system what would it use to talk to 'them' */ 03756 ast_ouraddrfor(them, us); 03757 ast_sockaddr_copy(&theirs, them); 03758 03759 if (ast_sockaddr_is_ipv6(&theirs)) { 03760 if (localaddr && !ast_sockaddr_isnull(&externaddr) && !ast_sockaddr_is_any(&bindaddr)) { 03761 ast_log(LOG_WARNING, "Address remapping activated in sip.conf " 03762 "but we're using IPv6, which doesn't need it. Please " 03763 "remove \"localnet\" and/or \"externaddr\" settings.\n"); 03764 } 03765 } else { 03766 want_remap = localaddr && 03767 !ast_sockaddr_isnull(&externaddr) && 03768 ast_apply_ha(localaddr, &theirs) == AST_SENSE_ALLOW ; 03769 } 03770 03771 if (want_remap && 03772 (!sip_cfg.matchexternaddrlocally || !ast_apply_ha(localaddr, us)) ) { 03773 /* if we used externhost, see if it is time to refresh the info */ 03774 if (externexpire && time(NULL) >= externexpire) { 03775 if (ast_sockaddr_resolve_first(&externaddr, externhost, 0)) { 03776 ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost); 03777 } 03778 externexpire = time(NULL) + externrefresh; 03779 } 03780 if (!ast_sockaddr_isnull(&externaddr)) { 03781 ast_sockaddr_copy(us, &externaddr); 03782 switch (p->socket.type) { 03783 case SIP_TRANSPORT_TCP: 03784 if (!externtcpport && ast_sockaddr_port(&externaddr)) { 03785 /* for consistency, default to the externaddr port */ 03786 externtcpport = ast_sockaddr_port(&externaddr); 03787 } 03788 ast_sockaddr_set_port(us, externtcpport); 03789 break; 03790 case SIP_TRANSPORT_TLS: 03791 ast_sockaddr_set_port(us, externtlsport); 03792 break; 03793 case SIP_TRANSPORT_UDP: 03794 if (!ast_sockaddr_port(&externaddr)) { 03795 ast_sockaddr_set_port(us, ast_sockaddr_port(&bindaddr)); 03796 } 03797 break; 03798 default: 03799 break; 03800 } 03801 } 03802 ast_debug(1, "Target address %s is not local, substituting externaddr\n", 03803 ast_sockaddr_stringify(them)); 03804 } else { 03805 /* no remapping, but we bind to a specific address, so use it. */ 03806 switch (p->socket.type) { 03807 case SIP_TRANSPORT_TCP: 03808 if (!ast_sockaddr_is_any(&sip_tcp_desc.local_address)) { 03809 ast_sockaddr_copy(us, 03810 &sip_tcp_desc.local_address); 03811 } else { 03812 ast_sockaddr_set_port(us, 03813 ast_sockaddr_port(&sip_tcp_desc.local_address)); 03814 } 03815 break; 03816 case SIP_TRANSPORT_TLS: 03817 if (!ast_sockaddr_is_any(&sip_tls_desc.local_address)) { 03818 ast_sockaddr_copy(us, 03819 &sip_tls_desc.local_address); 03820 } else { 03821 ast_sockaddr_set_port(us, 03822 ast_sockaddr_port(&sip_tls_desc.local_address)); 03823 } 03824 break; 03825 case SIP_TRANSPORT_UDP: 03826 /* fall through on purpose */ 03827 default: 03828 if (!ast_sockaddr_is_any(&bindaddr)) { 03829 ast_sockaddr_copy(us, &bindaddr); 03830 } 03831 if (!ast_sockaddr_port(us)) { 03832 ast_sockaddr_set_port(us, ast_sockaddr_port(&bindaddr)); 03833 } 03834 } 03835 } 03836 ast_debug(3, "Setting SIP_TRANSPORT_%s with address %s\n", get_transport(p->socket.type), ast_sockaddr_stringify(us)); 03837 }
| 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 30569 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().
30571 { 30572 return ast_sockaddr_resolve_first_af(addr, name, flag, get_address_family_filter(SIP_TRANSPORT_UDP)); 30573 }
| 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 30545 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().
30547 { 30548 struct ast_sockaddr *addrs; 30549 int addrs_cnt; 30550 30551 addrs_cnt = ast_sockaddr_resolve(&addrs, name, flag, family); 30552 if (addrs_cnt <= 0) { 30553 return 1; 30554 } 30555 if (addrs_cnt > 1) { 30556 ast_debug(1, "Multiple addresses, using the first one only\n"); 30557 } 30558 30559 ast_sockaddr_copy(addr, &addrs[0]); 30560 30561 ast_free(addrs); 30562 return 0; 30563 }
| 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 30579 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().
30581 { 30582 return ast_sockaddr_resolve_first_af(addr, name, flag, get_address_family_filter(transport)); 30583 }
| 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 22287 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().
22288 { 22289 int res = 0; 22290 struct ast_channel *peera = NULL, 22291 *peerb = NULL, 22292 *peerc = NULL, 22293 *peerd = NULL; 22294 22295 22296 /* We will try to connect the transferee with the target and hangup 22297 all channels to the transferer */ 22298 ast_debug(4, "Sip transfer:--------------------\n"); 22299 if (transferer->chan1) 22300 ast_debug(4, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state)); 22301 else 22302 ast_debug(4, "-- No transferer first channel - odd??? \n"); 22303 if (target->chan1) 22304 ast_debug(4, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state)); 22305 else 22306 ast_debug(4, "-- No target first channel ---\n"); 22307 if (transferer->chan2) 22308 ast_debug(4, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state)); 22309 else 22310 ast_debug(4, "-- No bridged call to transferee\n"); 22311 if (target->chan2) 22312 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)"); 22313 else 22314 ast_debug(4, "-- No target second channel ---\n"); 22315 ast_debug(4, "-- END Sip transfer:--------------------\n"); 22316 if (transferer->chan2) { /* We have a bridge on the transferer's channel */ 22317 peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */ 22318 peerb = target->chan1; /* Transferer - PBX -> target channel - This will get lost in masq */ 22319 peerc = transferer->chan2; /* Asterisk to Transferee */ 22320 peerd = target->chan2; /* Asterisk to Target */ 22321 ast_debug(3, "SIP transfer: Four channels to handle\n"); 22322 } else if (target->chan2) { /* Transferer has no bridge (IVR), but transferee */ 22323 peera = target->chan1; /* Transferer to PBX -> target channel */ 22324 peerb = transferer->chan1; /* Transferer to IVR*/ 22325 peerc = target->chan2; /* Asterisk to Target */ 22326 peerd = transferer->chan2; /* Nothing */ 22327 ast_debug(3, "SIP transfer: Three channels to handle\n"); 22328 } 22329 22330 if (peera && peerb && peerc && (peerb != peerc)) { 22331 ast_quiet_chan(peera); /* Stop generators */ 22332 ast_quiet_chan(peerb); 22333 ast_quiet_chan(peerc); 22334 if (peerd) 22335 ast_quiet_chan(peerd); 22336 22337 ast_debug(4, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name); 22338 if (ast_channel_masquerade(peerb, peerc)) { 22339 ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); 22340 res = -1; 22341 } else 22342 ast_debug(4, "SIP transfer: Succeeded to masquerade channels.\n"); 22343 return res; 22344 } else { 22345 ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n"); 22346 if (transferer->chan1) 22347 ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV); 22348 if (target->chan1) 22349 ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV); 22350 return -1; 22351 } 22352 return 0; 22353 }
| 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 14173 of file chan_sip.c.
References ast_verbose.
Referenced by check_auth(), do_proxy_auth(), do_register_auth(), and transmit_request_with_auth().
14174 { 14175 if (code == WWW_AUTH) { /* 401 */ 14176 *header = "WWW-Authenticate"; 14177 *respheader = "Authorization"; 14178 } else if (code == PROXY_AUTH) { /* 407 */ 14179 *header = "Proxy-Authenticate"; 14180 *respheader = "Proxy-Authorization"; 14181 } else { 14182 ast_verbose("-- wrong response code %d\n", code); 14183 *header = *respheader = "Invalid"; 14184 } 14185 }
| 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 5886 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().
05887 { 05888 struct sip_pvt *p = (struct sip_pvt *)arg; 05889 05890 sip_pvt_lock(p); 05891 p->initid = -1; /* event gone, will not be rescheduled */ 05892 if (p->owner) { 05893 /* XXX fails on possible deadlock */ 05894 if (!ast_channel_trylock(p->owner)) { 05895 append_history(p, "Cong", "Auto-congesting (timer)"); 05896 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 05897 ast_channel_unlock(p->owner); 05898 } 05899 05900 /* Give the channel a chance to act before we proceed with destruction */ 05901 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 05902 } 05903 sip_pvt_unlock(p); 05904 dialog_unref(p, "unreffing arg passed into auto_congest callback (p->initid)"); 05905 return 0; 05906 }
| static void build_callid_pvt | ( | struct sip_pvt * | pvt | ) | [static] |
Build SIP Call-ID value for a non-REGISTER transaction.
Definition at line 7992 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().
07993 { 07994 char buf[33]; 07995 const char *host = S_OR(pvt->fromdomain, ast_sockaddr_stringify_remote(&pvt->ourip)); 07996 07997 ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 07998 }
| 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 8047 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().
08048 { 08049 char buf[33]; 08050 08051 const char *host = S_OR(fromdomain, ast_sockaddr_stringify_host_remote(ourip)); 08052 08053 ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 08054 }
| static void build_contact | ( | struct sip_pvt * | p | ) | [static] |
Build contact header - the contact header we send out.
Definition at line 12419 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().
12420 { 12421 char tmp[SIPBUFSIZE]; 12422 char *user = ast_uri_encode(p->exten, tmp, sizeof(tmp), 0); 12423 12424 if (p->socket.type == SIP_TRANSPORT_UDP) { 12425 ast_string_field_build(p, our_contact, "<sip:%s%s%s>", user, 12426 ast_strlen_zero(user) ? "" : "@", ast_sockaddr_stringify_remote(&p->ourip)); 12427 } else { 12428 ast_string_field_build(p, our_contact, "<sip:%s%s%s;transport=%s>", user, 12429 ast_strlen_zero(user) ? "" : "@", ast_sockaddr_stringify_remote(&p->ourip), 12430 get_transport(p->socket.type)); 12431 } 12432 }
| 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 27961 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().
27962 { 27963 struct sip_peer *peer = NULL; 27964 struct ast_ha *oldha = NULL; 27965 struct ast_ha *olddirectmediaha = NULL; 27966 int found = 0; 27967 int firstpass = 1; 27968 uint16_t port = 0; 27969 int format = 0; /* Ama flags */ 27970 int timerb_set = 0, timert1_set = 0; 27971 time_t regseconds = 0; 27972 struct ast_flags peerflags[3] = {{(0)}}; 27973 struct ast_flags mask[3] = {{(0)}}; 27974 char callback[256] = ""; 27975 struct sip_peer tmp_peer; 27976 const char *srvlookup = NULL; 27977 static int deprecation_warning = 1; 27978 int alt_fullcontact = alt ? 1 : 0, headercount = 0; 27979 struct ast_str *fullcontact = ast_str_alloca(512); 27980 27981 if (!realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 27982 /* Note we do NOT use find_peer here, to avoid realtime recursion */ 27983 /* We also use a case-sensitive comparison (unlike find_peer) so 27984 that case changes made to the peer name will be properly handled 27985 during reload 27986 */ 27987 ast_copy_string(tmp_peer.name, name, sizeof(tmp_peer.name)); 27988 peer = ao2_t_find(peers, &tmp_peer, OBJ_POINTER | OBJ_UNLINK, "find and unlink peer from peers table"); 27989 } 27990 27991 if (peer) { 27992 /* Already in the list, remove it and it will be added back (or FREE'd) */ 27993 found++; 27994 /* we've unlinked the peer from the peers container but not unlinked from the peers_by_ip container yet 27995 this leads to a wrong refcounter and the peer object is never destroyed */ 27996 if (!ast_sockaddr_isnull(&peer->addr)) { 27997 ao2_t_unlink(peers_by_ip, peer, "ao2_unlink peer from peers_by_ip table"); 27998 } 27999 if (!(peer->the_mark)) 28000 firstpass = 0; 28001 } else { 28002 if (!(peer = ao2_t_alloc(sizeof(*peer), sip_destroy_peer_fn, "allocate a peer struct"))) 28003 return NULL; 28004 28005 if (ast_string_field_init(peer, 512)) { 28006 ao2_t_ref(peer, -1, "failed to string_field_init, drop peer"); 28007 return NULL; 28008 } 28009 28010 if (!(peer->cc_params = ast_cc_config_params_init())) { 28011 ao2_t_ref(peer, -1, "failed to allocate cc_params for peer"); 28012 return NULL; 28013 } 28014 28015 if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 28016 ast_atomic_fetchadd_int(&rpeerobjs, 1); 28017 ast_debug(3, "-REALTIME- peer built. Name: %s. Peer objects: %d\n", name, rpeerobjs); 28018 } else 28019 ast_atomic_fetchadd_int(&speerobjs, 1); 28020 } 28021 28022 /* Note that our peer HAS had its reference count increased */ 28023 if (firstpass) { 28024 peer->lastmsgssent = -1; 28025 oldha = peer->ha; 28026 peer->ha = NULL; 28027 olddirectmediaha = peer->directmediaha; 28028 peer->directmediaha = NULL; 28029 set_peer_defaults(peer); /* Set peer defaults */ 28030 peer->type = 0; 28031 } 28032 28033 /* in case the case of the peer name has changed, update the name */ 28034 ast_copy_string(peer->name, name, sizeof(peer->name)); 28035 28036 /* If we have channel variables, remove them (reload) */ 28037 if (peer->chanvars) { 28038 ast_variables_destroy(peer->chanvars); 28039 peer->chanvars = NULL; 28040 /* XXX should unregister ? */ 28041 } 28042 28043 if (found) 28044 peer->portinuri = 0; 28045 28046 /* If we have realm authentication information, remove them (reload) */ 28047 ao2_lock(peer); 28048 if (peer->auth) { 28049 ao2_t_ref(peer->auth, -1, "Removing old peer authentication"); 28050 peer->auth = NULL; 28051 } 28052 ao2_unlock(peer); 28053 28054 /* clear the transport information. We will detect if a default value is required after parsing the config */ 28055 peer->default_outbound_transport = 0; 28056 peer->transports = 0; 28057 28058 if (!devstate_only) { 28059 struct sip_mailbox *mailbox; 28060 AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { 28061 mailbox->delme = 1; 28062 } 28063 } 28064 28065 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 28066 if (!devstate_only) { 28067 if (handle_common_options(&peerflags[0], &mask[0], v)) { 28068 continue; 28069 } 28070 if (handle_t38_options(&peerflags[0], &mask[0], v, &peer->t38_maxdatagram)) { 28071 continue; 28072 } 28073 if (!strcasecmp(v->name, "transport")) { 28074 char *val = ast_strdupa(v->value); 28075 char *trans; 28076 28077 peer->transports = peer->default_outbound_transport = 0; 28078 while ((trans = strsep(&val, ","))) { 28079 trans = ast_skip_blanks(trans); 28080 28081 if (!strncasecmp(trans, "udp", 3)) { 28082 peer->transports |= SIP_TRANSPORT_UDP; 28083 } else if (sip_cfg.tcp_enabled && !strncasecmp(trans, "tcp", 3)) { 28084 peer->transports |= SIP_TRANSPORT_TCP; 28085 } else if (default_tls_cfg.enabled && !strncasecmp(trans, "tls", 3)) { 28086 peer->transports |= SIP_TRANSPORT_TLS; 28087 } else if (!strncasecmp(trans, "tcp", 3) || !strncasecmp(trans, "tls", 3)) { 28088 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); 28089 } else { 28090 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); 28091 } 28092 28093 if (!peer->default_outbound_transport) { /*!< The first transport listed should be default outbound */ 28094 peer->default_outbound_transport = peer->transports; 28095 } 28096 } 28097 } else if (realtime && !strcasecmp(v->name, "regseconds")) { 28098 ast_get_time_t(v->value, ®seconds, 0, NULL); 28099 } else if (realtime && !strcasecmp(v->name, "name")) { 28100 ast_copy_string(peer->name, v->value, sizeof(peer->name)); 28101 } else if (realtime && !strcasecmp(v->name, "useragent")) { 28102 ast_string_field_set(peer, useragent, v->value); 28103 } else if (!strcasecmp(v->name, "type")) { 28104 if (!strcasecmp(v->value, "peer")) { 28105 peer->type |= SIP_TYPE_PEER; 28106 } else if (!strcasecmp(v->value, "user")) { 28107 peer->type |= SIP_TYPE_USER; 28108 } else if (!strcasecmp(v->value, "friend")) { 28109 peer->type = SIP_TYPE_USER | SIP_TYPE_PEER; 28110 } 28111 } else if (!strcasecmp(v->name, "remotesecret")) { 28112 ast_string_field_set(peer, remotesecret, v->value); 28113 } else if (!strcasecmp(v->name, "secret")) { 28114 ast_string_field_set(peer, secret, v->value); 28115 } else if (!strcasecmp(v->name, "md5secret")) { 28116 ast_string_field_set(peer, md5secret, v->value); 28117 } else if (!strcasecmp(v->name, "auth")) { 28118 add_realm_authentication(&peer->auth, v->value, v->lineno); 28119 } else if (!strcasecmp(v->name, "callerid")) { 28120 char cid_name[80] = { '\0' }, cid_num[80] = { '\0' }; 28121 28122 ast_callerid_split(v->value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num)); 28123 ast_string_field_set(peer, cid_name, cid_name); 28124 ast_string_field_set(peer, cid_num, cid_num); 28125 } else if (!strcasecmp(v->name, "mwi_from")) { 28126 ast_string_field_set(peer, mwi_from, v->value); 28127 } else if (!strcasecmp(v->name, "fullname")) { 28128 ast_string_field_set(peer, cid_name, v->value); 28129 } else if (!strcasecmp(v->name, "trunkname")) { 28130 /* This is actually for a trunk, so we don't want to override callerid */ 28131 ast_string_field_set(peer, cid_name, ""); 28132 } else if (!strcasecmp(v->name, "cid_number")) { 28133 ast_string_field_set(peer, cid_num, v->value); 28134 } else if (!strcasecmp(v->name, "cid_tag")) { 28135 ast_string_field_set(peer, cid_tag, v->value); 28136 } else if (!strcasecmp(v->name, "context")) { 28137 ast_string_field_set(peer, context, v->value); 28138 ast_set_flag(&peer->flags[1], SIP_PAGE2_HAVEPEERCONTEXT); 28139 } else if (!strcasecmp(v->name, "subscribecontext")) { 28140 ast_string_field_set(peer, subscribecontext, v->value); 28141 } else if (!strcasecmp(v->name, "fromdomain")) { 28142 char *fromdomainport; 28143 ast_string_field_set(peer, fromdomain, v->value); 28144 if ((fromdomainport = strchr(peer->fromdomain, ':'))) { 28145 *fromdomainport++ = '\0'; 28146 if (!(peer->fromdomainport = port_str2int(fromdomainport, 0))) { 28147 ast_log(LOG_NOTICE, "'%s' is not a valid port number for fromdomain.\n",fromdomainport); 28148 } 28149 } else { 28150 peer->fromdomainport = STANDARD_SIP_PORT; 28151 } 28152 } else if (!strcasecmp(v->name, "usereqphone")) { 28153 ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE); 28154 } else if (!strcasecmp(v->name, "fromuser")) { 28155 ast_string_field_set(peer, fromuser, v->value); 28156 } else if (!strcasecmp(v->name, "outboundproxy")) { 28157 struct sip_proxy *proxy; 28158 if (ast_strlen_zero(v->value)) { 28159 ast_log(LOG_WARNING, "no value given for outbound proxy on line %d of sip.conf\n", v->lineno); 28160 continue; 28161 } 28162 proxy = proxy_from_config(v->value, v->lineno, peer->outboundproxy); 28163 if (!proxy) { 28164 ast_log(LOG_WARNING, "failure parsing the outbound proxy on line %d of sip.conf.\n", v->lineno); 28165 continue; 28166 } 28167 peer->outboundproxy = proxy; 28168 } else if (!strcasecmp(v->name, "host")) { 28169 if (!strcasecmp(v->value, "dynamic")) { 28170 /* They'll register with us */ 28171 if ((!found && !realtime) || !peer->host_dynamic) { 28172 /* Initialize stuff if this is a new peer, or if it used to 28173 * not be dynamic before the reload. */ 28174 ast_sockaddr_setnull(&peer->addr); 28175 } 28176 peer->host_dynamic = TRUE; 28177 } else { 28178 /* Non-dynamic. Make sure we become that way if we're not */ 28179 AST_SCHED_DEL_UNREF(sched, peer->expire, 28180 unref_peer(peer, "removing register expire ref")); 28181 peer->host_dynamic = FALSE; 28182 srvlookup = v->value; 28183 } 28184 } else if (!strcasecmp(v->name, "defaultip")) { 28185 if (!ast_strlen_zero(v->value) && ast_get_ip(&peer->defaddr, v->value)) { 28186 unref_peer(peer, "unref_peer: from build_peer defaultip"); 28187 return NULL; 28188 } 28189 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 28190 int ha_error = 0; 28191 if (!ast_strlen_zero(v->value)) { 28192 peer->ha = ast_append_ha(v->name, v->value, peer->ha, &ha_error); 28193 } 28194 if (ha_error) { 28195 ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value); 28196 } 28197 } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) { 28198 int ha_error = 0; 28199 if (!ast_strlen_zero(v->value)) { 28200 peer->contactha = ast_append_ha(v->name + 7, v->value, peer->contactha, &ha_error); 28201 } 28202 if (ha_error) { 28203 ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value); 28204 } 28205 } else if (!strcasecmp(v->name, "directmediapermit") || !strcasecmp(v->name, "directmediadeny")) { 28206 int ha_error = 0; 28207 peer->directmediaha = ast_append_ha(v->name + 11, v->value, peer->directmediaha, &ha_error); 28208 if (ha_error) { 28209 ast_log(LOG_ERROR, "Bad directmedia ACL entry in configuration line %d : %s\n", v->lineno, v->value); 28210 } 28211 } else if (!strcasecmp(v->name, "port")) { 28212 peer->portinuri = 1; 28213 if (!(port = port_str2int(v->value, 0))) { 28214 if (realtime) { 28215 /* If stored as integer, could be 0 for some DBs (notably MySQL) */ 28216 peer->portinuri = 0; 28217 } else { 28218 ast_log(LOG_WARNING, "Invalid peer port configuration at line %d : %s\n", v->lineno, v->value); 28219 } 28220 } 28221 } else if (!strcasecmp(v->name, "callingpres")) { 28222 peer->callingpres = ast_parse_caller_presentation(v->value); 28223 if (peer->callingpres == -1) { 28224 peer->callingpres = atoi(v->value); 28225 } 28226 } else if (!strcasecmp(v->name, "username") || !strcmp(v->name, "defaultuser")) { /* "username" is deprecated */ 28227 ast_string_field_set(peer, username, v->value); 28228 if (!strcasecmp(v->name, "username")) { 28229 if (deprecation_warning) { 28230 ast_log(LOG_NOTICE, "The 'username' field for sip peers has been deprecated in favor of the term 'defaultuser'\n"); 28231 deprecation_warning = 0; 28232 } 28233 peer->deprecated_username = 1; 28234 } 28235 } else if (!strcasecmp(v->name, "language")) { 28236 ast_string_field_set(peer, language, v->value); 28237 } else if (!strcasecmp(v->name, "regexten")) { 28238 ast_string_field_set(peer, regexten, v->value); 28239 } else if (!strcasecmp(v->name, "callbackextension")) { 28240 ast_copy_string(callback, v->value, sizeof(callback)); 28241 } else if (!strcasecmp(v->name, "amaflags")) { 28242 format = ast_cdr_amaflags2int(v->value); 28243 if (format < 0) { 28244 ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno); 28245 } else { 28246 peer->amaflags = format; 28247 } 28248 } else if (!strcasecmp(v->name, "maxforwards")) { 28249 if (sscanf(v->value, "%30d", &peer->maxforwards) != 1 28250 || peer->maxforwards < 1 || 255 < peer->maxforwards) { 28251 ast_log(LOG_WARNING, "'%s' is not a valid maxforwards value at line %d. Using default.\n", v->value, v->lineno); 28252 peer->maxforwards = sip_cfg.default_max_forwards; 28253 } 28254 } else if (!strcasecmp(v->name, "accountcode")) { 28255 ast_string_field_set(peer, accountcode, v->value); 28256 } else if (!strcasecmp(v->name, "mohinterpret")) { 28257 ast_string_field_set(peer, mohinterpret, v->value); 28258 } else if (!strcasecmp(v->name, "mohsuggest")) { 28259 ast_string_field_set(peer, mohsuggest, v->value); 28260 } else if (!strcasecmp(v->name, "parkinglot")) { 28261 ast_string_field_set(peer, parkinglot, v->value); 28262 } else if (!strcasecmp(v->name, "rtp_engine")) { 28263 ast_string_field_set(peer, engine, v->value); 28264 } else if (!strcasecmp(v->name, "mailbox")) { 28265 add_peer_mailboxes(peer, v->value); 28266 } else if (!strcasecmp(v->name, "hasvoicemail")) { 28267 /* People expect that if 'hasvoicemail' is set, that the mailbox will 28268 * be also set, even if not explicitly specified. */ 28269 if (ast_true(v->value) && AST_LIST_EMPTY(&peer->mailboxes)) { 28270 add_peer_mailboxes(peer, name); 28271 } 28272 } else if (!strcasecmp(v->name, "subscribemwi")) { 28273 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY); 28274 } else if (!strcasecmp(v->name, "vmexten")) { 28275 ast_string_field_set(peer, vmexten, v->value); 28276 } else if (!strcasecmp(v->name, "callgroup")) { 28277 peer->callgroup = ast_get_group(v->value); 28278 } else if (!strcasecmp(v->name, "allowtransfer")) { 28279 peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 28280 } else if (!strcasecmp(v->name, "pickupgroup")) { 28281 peer->pickupgroup = ast_get_group(v->value); 28282 } else if (!strcasecmp(v->name, "allow")) { 28283 int error = ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, TRUE); 28284 if (error) { 28285 ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value); 28286 } 28287 } else if (!strcasecmp(v->name, "disallow")) { 28288 int error = ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, FALSE); 28289 if (error) { 28290 ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value); 28291 } 28292 } else if (!strcasecmp(v->name, "preferred_codec_only")) { 28293 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_PREFERRED_CODEC); 28294 } else if (!strcasecmp(v->name, "autoframing")) { 28295 peer->autoframing = ast_true(v->value); 28296 } else if (!strcasecmp(v->name, "rtptimeout")) { 28297 if ((sscanf(v->value, "%30d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) { 28298 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 28299 peer->rtptimeout = global_rtptimeout; 28300 } 28301 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 28302 if ((sscanf(v->value, "%30d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) { 28303 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 28304 peer->rtpholdtimeout = global_rtpholdtimeout; 28305 } 28306 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 28307 if ((sscanf(v->value, "%30d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) { 28308 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 28309 peer->rtpkeepalive = global_rtpkeepalive; 28310 } 28311 } else if (!strcasecmp(v->name, "timert1")) { 28312 if ((sscanf(v->value, "%30d", &peer->timer_t1) != 1) || (peer->timer_t1 < 200) || (peer->timer_t1 < global_t1min)) { 28313 ast_log(LOG_WARNING, "'%s' is not a valid T1 time at line %d. Using default.\n", v->value, v->lineno); 28314 peer->timer_t1 = global_t1min; 28315 } 28316 timert1_set = 1; 28317 } else if (!strcasecmp(v->name, "timerb")) { 28318 if ((sscanf(v->value, "%30d", &peer->timer_b) != 1) || (peer->timer_b < 200)) { 28319 ast_log(LOG_WARNING, "'%s' is not a valid Timer B time at line %d. Using default.\n", v->value, v->lineno); 28320 peer->timer_b = global_timer_b; 28321 } 28322 timerb_set = 1; 28323 } else if (!strcasecmp(v->name, "setvar")) { 28324 peer->chanvars = add_var(v->value, peer->chanvars); 28325 } else if (!strcasecmp(v->name, "header")) { 28326 char tmp[4096]; 28327 snprintf(tmp, sizeof(tmp), "__SIPADDHEADERpre%2d=%s", ++headercount, v->value); 28328 peer->chanvars = add_var(tmp, peer->chanvars); 28329 } else if (!strcasecmp(v->name, "qualifyfreq")) { 28330 int i; 28331 if (sscanf(v->value, "%30d", &i) == 1) { 28332 peer->qualifyfreq = i * 1000; 28333 } else { 28334 ast_log(LOG_WARNING, "Invalid qualifyfreq number '%s' at line %d of %s\n", v->value, v->lineno, config); 28335 peer->qualifyfreq = global_qualifyfreq; 28336 } 28337 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 28338 peer->maxcallbitrate = atoi(v->value); 28339 if (peer->maxcallbitrate < 0) { 28340 peer->maxcallbitrate = default_maxcallbitrate; 28341 } 28342 } else if (!strcasecmp(v->name, "session-timers")) { 28343 int i = (int) str2stmode(v->value); 28344 if (i < 0) { 28345 ast_log(LOG_WARNING, "Invalid session-timers '%s' at line %d of %s\n", v->value, v->lineno, config); 28346 peer->stimer.st_mode_oper = global_st_mode; 28347 } else { 28348 peer->stimer.st_mode_oper = i; 28349 } 28350 } else if (!strcasecmp(v->name, "session-expires")) { 28351 if (sscanf(v->value, "%30d", &peer->stimer.st_max_se) != 1) { 28352 ast_log(LOG_WARNING, "Invalid session-expires '%s' at line %d of %s\n", v->value, v->lineno, config); 28353 peer->stimer.st_max_se = global_max_se; 28354 } 28355 } else if (!strcasecmp(v->name, "session-minse")) { 28356 if (sscanf(v->value, "%30d", &peer->stimer.st_min_se) != 1) { 28357 ast_log(LOG_WARNING, "Invalid session-minse '%s' at line %d of %s\n", v->value, v->lineno, config); 28358 peer->stimer.st_min_se = global_min_se; 28359 } 28360 if (peer->stimer.st_min_se < DEFAULT_MIN_SE) { 28361 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); 28362 peer->stimer.st_min_se = global_min_se; 28363 } 28364 } else if (!strcasecmp(v->name, "session-refresher")) { 28365 int i = (int) str2strefresherparam(v->value); 28366 if (i < 0) { 28367 ast_log(LOG_WARNING, "Invalid session-refresher '%s' at line %d of %s\n", v->value, v->lineno, config); 28368 peer->stimer.st_ref = global_st_refresher; 28369 } else { 28370 peer->stimer.st_ref = i; 28371 } 28372 } else if (!strcasecmp(v->name, "disallowed_methods")) { 28373 char *disallow = ast_strdupa(v->value); 28374 mark_parsed_methods(&peer->disallowed_methods, disallow); 28375 } else if (!strcasecmp(v->name, "unsolicited_mailbox")) { 28376 ast_string_field_set(peer, unsolicited_mailbox, v->value); 28377 } else if (!strcasecmp(v->name, "use_q850_reason")) { 28378 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_Q850_REASON); 28379 } else if (!strcasecmp(v->name, "encryption")) { 28380 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_USE_SRTP); 28381 } else if (!strcasecmp(v->name, "snom_aoc_enabled")) { 28382 ast_set2_flag(&peer->flags[2], ast_true(v->value), SIP_PAGE3_SNOM_AOC); 28383 } 28384 } 28385 28386 /* These apply to devstate lookups */ 28387 if (realtime && !strcasecmp(v->name, "lastms")) { 28388 sscanf(v->value, "%30d", &peer->lastms); 28389 } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) { 28390 ast_sockaddr_parse(&peer->addr, v->value, PARSE_PORT_FORBID); 28391 } else if (realtime && !strcasecmp(v->name, "fullcontact")) { 28392 if (alt_fullcontact && !alt) { 28393 /* Reset, because the alternate also has a fullcontact and we 28394 * do NOT want the field value to be doubled. It might be 28395 * tempting to skip this, but the first table might not have 28396 * fullcontact and since we're here, we know that the alternate 28397 * absolutely does. */ 28398 alt_fullcontact = 0; 28399 ast_str_reset(fullcontact); 28400 } 28401 /* Reconstruct field, because realtime separates our value at the ';' */ 28402 if (ast_str_strlen(fullcontact) > 0) { 28403 ast_str_append(&fullcontact, 0, ";%s", v->value); 28404 } else { 28405 ast_str_set(&fullcontact, 0, "%s", v->value); 28406 } 28407 } else if (!strcasecmp(v->name, "qualify")) { 28408 if (!strcasecmp(v->value, "no")) { 28409 peer->maxms = 0; 28410 } else if (!strcasecmp(v->value, "yes")) { 28411 peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS; 28412 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) { 28413 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); 28414 peer->maxms = 0; 28415 } 28416 if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && peer->maxms > 0) { 28417 /* This would otherwise cause a network storm, where the 28418 * qualify response refreshes the peer from the database, 28419 * which in turn causes another qualify to be sent, ad 28420 * infinitum. */ 28421 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); 28422 peer->maxms = 0; 28423 } 28424 } else if (!strcasecmp(v->name, "callcounter")) { 28425 peer->call_limit = ast_true(v->value) ? INT_MAX : 0; 28426 } else if (!strcasecmp(v->name, "call-limit")) { 28427 peer->call_limit = atoi(v->value); 28428 if (peer->call_limit < 0) { 28429 peer->call_limit = 0; 28430 } 28431 } else if (!strcasecmp(v->name, "busylevel")) { 28432 peer->busy_level = atoi(v->value); 28433 if (peer->busy_level < 0) { 28434 peer->busy_level = 0; 28435 } 28436 } else if (ast_cc_is_config_param(v->name)) { 28437 ast_cc_set_param(peer->cc_params, v->name, v->value); 28438 } 28439 } 28440 28441 if (!devstate_only) { 28442 struct sip_mailbox *mailbox; 28443 AST_LIST_TRAVERSE_SAFE_BEGIN(&peer->mailboxes, mailbox, entry) { 28444 if (mailbox->delme) { 28445 AST_LIST_REMOVE_CURRENT(entry); 28446 destroy_mailbox(mailbox); 28447 } 28448 } 28449 AST_LIST_TRAVERSE_SAFE_END; 28450 } 28451 28452 if (!can_parse_xml && (ast_get_cc_agent_policy(peer->cc_params) == AST_CC_AGENT_NATIVE)) { 28453 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); 28454 ast_set_cc_agent_policy(peer->cc_params, AST_CC_AGENT_NEVER); 28455 } 28456 28457 /* Note that Timer B is dependent upon T1 and MUST NOT be lower 28458 * than T1 * 64, according to RFC 3261, Section 17.1.1.2 */ 28459 if (peer->timer_b < peer->timer_t1 * 64) { 28460 if (timerb_set && timert1_set) { 28461 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); 28462 } else if (timerb_set) { 28463 if ((peer->timer_t1 = peer->timer_b / 64) < global_t1min) { 28464 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); 28465 peer->timer_t1 = global_t1min; 28466 peer->timer_b = peer->timer_t1 * 64; 28467 } 28468 peer->timer_t1 = peer->timer_b / 64; 28469 } else { 28470 peer->timer_b = peer->timer_t1 * 64; 28471 } 28472 } 28473 28474 if (!peer->default_outbound_transport) { 28475 /* Set default set of transports */ 28476 peer->transports = default_transports; 28477 /* Set default primary transport */ 28478 peer->default_outbound_transport = default_primary_transport; 28479 } 28480 28481 /* The default transport type set during build_peer should only replace the socket.type when... 28482 * 1. Registration is not present and the socket.type and default transport types are different. 28483 * 2. The socket.type is not an acceptable transport type after rebuilding peer. 28484 * 3. The socket.type is not set yet. */ 28485 if (((peer->socket.type != peer->default_outbound_transport) && (peer->expire == -1)) || 28486 !(peer->socket.type & peer->transports) || !(peer->socket.type)) { 28487 28488 set_socket_transport(&peer->socket, peer->default_outbound_transport); 28489 } 28490 28491 if (ast_str_strlen(fullcontact)) { 28492 ast_string_field_set(peer, fullcontact, ast_str_buffer(fullcontact)); 28493 peer->rt_fromcontact = TRUE; 28494 /* We have a hostname in the fullcontact, but if we don't have an 28495 * address listed on the entry (or if it's 'dynamic'), then we need to 28496 * parse the entry to obtain the IP address, so a dynamic host can be 28497 * contacted immediately after reload (as opposed to waiting for it to 28498 * register once again). But if we have an address for this peer and NAT was 28499 * specified, use that address instead. */ 28500 /* XXX May need to revisit the final argument; does the realtime DB store whether 28501 * the original contact was over TLS or not? XXX */ 28502 if (!ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) || ast_sockaddr_isnull(&peer->addr)) { 28503 __set_address_from_contact(ast_str_buffer(fullcontact), &peer->addr, 0); 28504 } 28505 } 28506 28507 if (srvlookup && peer->dnsmgr == NULL) { 28508 char transport[MAXHOSTNAMELEN]; 28509 char _srvlookup[MAXHOSTNAMELEN]; 28510 char *params; 28511 28512 ast_copy_string(_srvlookup, srvlookup, sizeof(_srvlookup)); 28513 if ((params = strchr(_srvlookup, ';'))) { 28514 *params++ = '\0'; 28515 } 28516 28517 snprintf(transport, sizeof(transport), "_%s._%s", get_srv_service(peer->socket.type), get_srv_protocol(peer->socket.type)); 28518 28519 peer->addr.ss.ss_family = get_address_family_filter(peer->socket.type); /* Filter address family */ 28520 if (ast_dnsmgr_lookup_cb(_srvlookup, &peer->addr, &peer->dnsmgr, sip_cfg.srvlookup && !peer->portinuri ? transport : NULL, 28521 on_dns_update_peer, ref_peer(peer, "Store peer on dnsmgr"))) { 28522 ast_log(LOG_ERROR, "srvlookup failed for host: %s, on peer %s, removing peer\n", _srvlookup, peer->name); 28523 unref_peer(peer, "dnsmgr lookup failed, getting rid of peer dnsmgr ref"); 28524 unref_peer(peer, "getting rid of a peer pointer"); 28525 return NULL; 28526 } 28527 if (!peer->dnsmgr) { 28528 /* dnsmgr refresh disabeld, release reference */ 28529 unref_peer(peer, "dnsmgr disabled, unref peer"); 28530 } 28531 28532 ast_string_field_set(peer, tohost, srvlookup); 28533 28534 if (global_dynamic_exclude_static && !ast_sockaddr_isnull(&peer->addr)) { 28535 int ha_error = 0; 28536 sip_cfg.contact_ha = ast_append_ha("deny", ast_sockaddr_stringify_addr(&peer->addr), 28537 sip_cfg.contact_ha, &ha_error); 28538 if (ha_error) { 28539 ast_log(LOG_ERROR, "Bad or unresolved host/IP entry in configuration for peer %s, cannot add to contact ACL\n", peer->name); 28540 } 28541 } 28542 } else if (peer->dnsmgr && !peer->host_dynamic) { 28543 /* force a refresh here on reload if dnsmgr already exists and host is set. */ 28544 ast_dnsmgr_refresh(peer->dnsmgr); 28545 } 28546 28547 if (port && !realtime && peer->host_dynamic) { 28548 ast_sockaddr_set_port(&peer->defaddr, port); 28549 } else if (port) { 28550 ast_sockaddr_set_port(&peer->addr, port); 28551 } 28552 28553 if (ast_sockaddr_port(&peer->addr) == 0) { 28554 ast_sockaddr_set_port(&peer->addr, 28555 (peer->socket.type & SIP_TRANSPORT_TLS) ? 28556 STANDARD_TLS_PORT : STANDARD_SIP_PORT); 28557 } 28558 if (ast_sockaddr_port(&peer->defaddr) == 0) { 28559 ast_sockaddr_set_port(&peer->defaddr, 28560 (peer->socket.type & SIP_TRANSPORT_TLS) ? 28561 STANDARD_TLS_PORT : STANDARD_SIP_PORT); 28562 } 28563 if (!peer->socket.port) { 28564 peer->socket.port = htons(((peer->socket.type & SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT)); 28565 } 28566 28567 if (!sip_cfg.ignore_regexpire && peer->host_dynamic && realtime) { 28568 time_t nowtime = time(NULL); 28569 28570 if ((nowtime - regseconds) > 0) { 28571 destroy_association(peer); 28572 memset(&peer->addr, 0, sizeof(peer->addr)); 28573 peer->lastms = -1; 28574 ast_debug(1, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 28575 } 28576 } 28577 28578 /* Startup regular pokes */ 28579 if (!devstate_only && realtime && peer->lastms > 0) { 28580 ref_peer(peer, "schedule qualify"); 28581 sip_poke_peer(peer, 0); 28582 } 28583 28584 ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags); 28585 ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags); 28586 ast_copy_flags(&peer->flags[2], &peerflags[2], mask[2].flags); 28587 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) { 28588 sip_cfg.allowsubscribe = TRUE; /* No global ban any more */ 28589 } 28590 /* If read-only RT backend, then refresh from local DB cache */ 28591 if (peer->host_dynamic && (!peer->is_realtime || !sip_cfg.peer_rtupdate)) { 28592 reg_source_db(peer); 28593 } 28594 28595 /* If they didn't request that MWI is sent *only* on subscribe, go ahead and 28596 * subscribe to it now. */ 28597 if (!devstate_only && !ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) && 28598 !AST_LIST_EMPTY(&peer->mailboxes)) { 28599 add_peer_mwi_subs(peer); 28600 /* Send MWI from the event cache only. This is so we can send initial 28601 * MWI if app_voicemail got loaded before chan_sip. If it is the other 28602 * way, then we will get events when app_voicemail gets loaded. */ 28603 sip_send_mwi_to_peer(peer, 1); 28604 } 28605 28606 peer->the_mark = 0; 28607 28608 ast_free_ha(oldha); 28609 ast_free_ha(olddirectmediaha); 28610 if (!ast_strlen_zero(callback)) { /* build string from peer info */ 28611 char *reg_string; 28612 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) { 28613 sip_register(reg_string, 0); /* XXX TODO: count in registry_count */ 28614 ast_free(reg_string); 28615 } 28616 } 28617 return peer; 28618 }
| static int build_reply_digest | ( | struct sip_pvt * | p, | |
| int | method, | |||
| char * | digest, | |||
| int | digest_len | |||
| ) | [static] |
Build reply digest.
Definition at line 19901 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().
19902 { 19903 char a1[256]; 19904 char a2[256]; 19905 char a1_hash[256]; 19906 char a2_hash[256]; 19907 char resp[256]; 19908 char resp_hash[256]; 19909 char uri[256]; 19910 char opaque[256] = ""; 19911 char cnonce[80]; 19912 const char *username; 19913 const char *secret; 19914 const char *md5secret; 19915 struct sip_auth *auth; /* Realm authentication credential */ 19916 struct sip_auth_container *credentials; 19917 19918 if (!ast_strlen_zero(p->domain)) 19919 snprintf(uri, sizeof(uri), "%s:%s", p->socket.type == SIP_TRANSPORT_TLS ? "sips" : "sip", p->domain); 19920 else if (!ast_strlen_zero(p->uri)) 19921 ast_copy_string(uri, p->uri, sizeof(uri)); 19922 else 19923 snprintf(uri, sizeof(uri), "%s:%s@%s", p->socket.type == SIP_TRANSPORT_TLS ? "sips" : "sip", p->username, ast_sockaddr_stringify_host_remote(&p->sa)); 19924 19925 snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random()); 19926 19927 /* Check if we have peer credentials */ 19928 ao2_lock(p); 19929 credentials = p->peerauth; 19930 if (credentials) { 19931 ao2_t_ref(credentials, +1, "Ref peer auth for digest"); 19932 } 19933 ao2_unlock(p); 19934 auth = find_realm_authentication(credentials, p->realm); 19935 if (!auth) { 19936 /* If not, check global credentials */ 19937 if (credentials) { 19938 ao2_t_ref(credentials, -1, "Unref peer auth for digest"); 19939 } 19940 ast_mutex_lock(&authl_lock); 19941 credentials = authl; 19942 if (credentials) { 19943 ao2_t_ref(credentials, +1, "Ref global auth for digest"); 19944 } 19945 ast_mutex_unlock(&authl_lock); 19946 auth = find_realm_authentication(credentials, p->realm); 19947 } 19948 19949 if (auth) { 19950 ast_debug(3, "use realm [%s] from peer [%s][%s]\n", auth->username, p->peername, p->username); 19951 username = auth->username; 19952 secret = auth->secret; 19953 md5secret = auth->md5secret; 19954 if (sipdebug) 19955 ast_debug(1, "Using realm %s authentication for call %s\n", p->realm, p->callid); 19956 } else { 19957 /* No authentication, use peer or register= config */ 19958 username = p->authname; 19959 secret = p->relatedpeer 19960 && !ast_strlen_zero(p->relatedpeer->remotesecret) 19961 ? p->relatedpeer->remotesecret : p->peersecret; 19962 md5secret = p->peermd5secret; 19963 } 19964 if (ast_strlen_zero(username)) { 19965 /* We have no authentication */ 19966 if (credentials) { 19967 ao2_t_ref(credentials, -1, "Unref auth for digest"); 19968 } 19969 return -1; 19970 } 19971 19972 /* Calculate SIP digest response */ 19973 snprintf(a1, sizeof(a1), "%s:%s:%s", username, p->realm, secret); 19974 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[method].text, uri); 19975 if (!ast_strlen_zero(md5secret)) 19976 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 19977 else 19978 ast_md5_hash(a1_hash, a1); 19979 ast_md5_hash(a2_hash, a2); 19980 19981 p->noncecount++; 19982 if (!ast_strlen_zero(p->qop)) 19983 snprintf(resp, sizeof(resp), "%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash); 19984 else 19985 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, p->nonce, a2_hash); 19986 ast_md5_hash(resp_hash, resp); 19987 19988 /* only include the opaque string if it's set */ 19989 if (!ast_strlen_zero(p->opaque)) { 19990 snprintf(opaque, sizeof(opaque), ", opaque=\"%s\"", p->opaque); 19991 } 19992 19993 /* XXX We hard code our qop to "auth" for now. XXX */ 19994 if (!ast_strlen_zero(p->qop)) 19995 snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\"%s, qop=auth, cnonce=\"%s\", nc=%08x", username, p->realm, uri, p->nonce, resp_hash, opaque, cnonce, p->noncecount); 19996 else 19997 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); 19998 19999 append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount); 20000 20001 if (credentials) { 20002 ao2_t_ref(credentials, -1, "Unref auth for digest"); 20003 } 20004 return 0; 20005 }
| 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 14735 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().
14736 { 14737 struct sip_route *thishop, *head, *tail; 14738 int start = 0; 14739 int len; 14740 const char *rr, *c; 14741 14742 /* Once a persistent route is set, don't fool with it */ 14743 if (p->route && p->route_persistent) { 14744 ast_debug(1, "build_route: Retaining previous route: <%s>\n", p->route->hop); 14745 return; 14746 } 14747 14748 if (p->route) { 14749 free_old_route(p->route); 14750 p->route = NULL; 14751 } 14752 14753 /* We only want to create the route set the first time this is called except 14754 it is called from a provisional response.*/ 14755 if ((resp < 100) || (resp > 199)) { 14756 p->route_persistent = 1; 14757 } 14758 14759 /* Build a tailq, then assign it to p->route when done. 14760 * If backwards, we add entries from the head so they end up 14761 * in reverse order. However, we do need to maintain a correct 14762 * tail pointer because the contact is always at the end. 14763 */ 14764 head = NULL; 14765 tail = head; 14766 /* 1st we pass through all the hops in any Record-Route headers */ 14767 for (;;) { 14768 /* Each Record-Route header */ 14769 int len = 0; 14770 const char *uri; 14771 rr = __get_header(req, "Record-Route", &start); 14772 if (*rr == '\0') { 14773 break; 14774 } 14775 while (!get_in_brackets_const(rr, &uri, &len)) { 14776 len++; 14777 rr = strchr(rr, ','); 14778 if(rr >= uri && rr < (uri + len)) { 14779 /* comma inside brackets*/ 14780 const char *next_br = strchr(rr, '<'); 14781 if (next_br && next_br < (uri + len)) { 14782 rr++; 14783 continue; 14784 } 14785 continue; 14786 } 14787 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 14788 ast_copy_string(thishop->hop, uri, len); 14789 ast_debug(2, "build_route: Record-Route hop: <%s>\n", thishop->hop); 14790 /* Link in */ 14791 if (backwards) { 14792 /* Link in at head so they end up in reverse order */ 14793 thishop->next = head; 14794 head = thishop; 14795 /* If this was the first then it'll be the tail */ 14796 if (!tail) { 14797 tail = thishop; 14798 } 14799 } else { 14800 thishop->next = NULL; 14801 /* Link in at the end */ 14802 if (tail) { 14803 tail->next = thishop; 14804 } else { 14805 head = thishop; 14806 } 14807 tail = thishop; 14808 } 14809 } 14810 rr = strchr(uri + len, ','); 14811 if (rr == NULL) { 14812 /* No more field-values, we're done with this header */ 14813 break; 14814 } 14815 /* Advance past comma */ 14816 rr++; 14817 } 14818 } 14819 14820 /* Only append the contact if we are dealing with a strict router */ 14821 if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop, ";lr") == NULL) ) { 14822 /* 2nd append the Contact: if there is one */ 14823 /* Can be multiple Contact headers, comma separated values - we just take the first */ 14824 char *contact = ast_strdupa(get_header(req, "Contact")); 14825 if (!ast_strlen_zero(contact)) { 14826 ast_debug(2, "build_route: Contact hop: %s\n", contact); 14827 /* Look for <: delimited address */ 14828 c = get_in_brackets(contact); 14829 len = strlen(c) + 1; 14830 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 14831 /* ast_calloc is not needed because all fields are initialized in this block */ 14832 ast_copy_string(thishop->hop, c, len); 14833 thishop->next = NULL; 14834 /* Goes at the end */ 14835 if (tail) { 14836 tail->next = thishop; 14837 } else { 14838 head = thishop; 14839 } 14840 } 14841 } 14842 } 14843 14844 /* Store as new route */ 14845 p->route = head; 14846 14847 /* For debugging dump what we ended up with */ 14848 if (sip_debug_test_pvt(p)) { 14849 list_route(p->route); 14850 } 14851 }
| static void build_via | ( | struct sip_pvt * | p | ) | [static] |
Build a Via header for a request.
Definition at line 3717 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().
03718 { 03719 /* Work around buggy UNIDEN UIP200 firmware */ 03720 const char *rport = (ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT) || ast_test_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT)) ? ";rport" : ""; 03721 03722 /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ 03723 snprintf(p->via, sizeof(p->via), "SIP/2.0/%s %s;branch=z9hG4bK%08x%s", 03724 get_transport_pvt(p), 03725 ast_sockaddr_stringify_remote(&p->ourip), 03726 (int) p->branch, rport); 03727 }
| static int cb_extensionstate | ( | char * | context, | |
| char * | exten, | |||
| int | state, | |||
| void * | data | |||
| ) | [static] |
Callback for the devicestate notification (SUBSCRIBE) support subsystem.
Definition at line 15133 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().
15134 { 15135 struct sip_pvt *p = data; 15136 15137 sip_pvt_lock(p); 15138 15139 switch(state) { 15140 case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ 15141 case AST_EXTENSION_REMOVED: /* Extension is gone */ 15142 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); /* Delete subscription in 32 secs */ 15143 ast_verb(2, "Extension state: Watcher for hint %s %s. Notify User %s\n", exten, state == AST_EXTENSION_DEACTIVATED ? "deactivated" : "removed", p->username); 15144 p->subscribed = NONE; 15145 append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated"); 15146 break; 15147 default: /* Tell user */ 15148 p->laststate = state; 15149 break; 15150 } 15151 if (p->subscribed != NONE) { /* Only send state NOTIFY if we know the format */ 15152 if (!p->pendinginvite) { 15153 transmit_state_notify(p, state, 1, FALSE); 15154 } else { 15155 /* We already have a NOTIFY sent that is not answered. Queue the state up. 15156 if many state changes happen meanwhile, we will only send a notification of the last one */ 15157 ast_set_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 15158 } 15159 } 15160 ast_verb(2, "Extension Changed %s[%s] new state %s for Notify User %s %s\n", exten, context, ast_extension_state2str(state), p->username, 15161 ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE) ? "(queued)" : ""); 15162 15163 sip_pvt_unlock(p); 15164 15165 return 0; 15166 }
| static void cb_extensionstate_destroy | ( | int | id, | |
| void * | data | |||
| ) | [static] |
Definition at line 15123 of file chan_sip.c.
Referenced by handle_request_subscribe().
| static void cc_epa_destructor | ( | void * | data | ) | [static] |
Definition at line 891 of file chan_sip.c.
References ast_free.
00892 { 00893 struct sip_epa_entry *epa_entry = data; 00894 struct cc_epa_entry *cc_entry = epa_entry->instance_data; 00895 ast_free(cc_entry); 00896 }
| 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 20524 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().
20525 { 20526 struct cc_epa_entry *cc_entry = epa_entry->instance_data; 20527 struct sip_monitor_instance *monitor_instance = ao2_callback(sip_monitor_instances, 0, 20528 find_sip_monitor_instance_by_suspension_entry, epa_entry); 20529 const char *min_expires; 20530 20531 if (!monitor_instance) { 20532 ast_log(LOG_WARNING, "Can't find monitor_instance corresponding to epa_entry %p.\n", epa_entry); 20533 return; 20534 } 20535 20536 if (resp != 423) { 20537 ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->device_name, 20538 "Received error response to our PUBLISH"); 20539 ao2_ref(monitor_instance, -1); 20540 return; 20541 } 20542 20543 /* Allrighty, the other end doesn't like our Expires value. They think it's 20544 * too small, so let's see if they've provided a more sensible value. If they 20545 * haven't, then we'll just double our Expires value and see if they like that 20546 * instead. 20547 * 20548 * XXX Ideally this logic could be placed into its own function so that SUBSCRIBE, 20549 * PUBLISH, and REGISTER could all benefit from the same shared code. 20550 */ 20551 min_expires = get_header(req, "Min-Expires"); 20552 if (ast_strlen_zero(min_expires)) { 20553 pvt->expiry *= 2; 20554 if (pvt->expiry < 0) { 20555 /* You dork! You overflowed! */ 20556 ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->device_name, 20557 "PUBLISH expiry overflowed"); 20558 ao2_ref(monitor_instance, -1); 20559 return; 20560 } 20561 } else if (sscanf(min_expires, "%d", &pvt->expiry) != 1) { 20562 ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->device_name, 20563 "Min-Expires has non-numeric value"); 20564 ao2_ref(monitor_instance, -1); 20565 return; 20566 } 20567 /* At this point, we have most certainly changed pvt->expiry, so try transmitting 20568 * again 20569 */ 20570 transmit_invite(pvt, SIP_PUBLISH, FALSE, 0, NULL); 20571 ao2_ref(monitor_instance, -1); 20572 }
| static void change_callid_pvt | ( | struct sip_pvt * | pvt, | |
| const char * | callid | |||
| ) | [static] |
Definition at line 8023 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().
08024 { 08025 int in_dialog_container; 08026 char *oldid = ast_strdupa(pvt->callid); 08027 08028 ao2_lock(dialogs); 08029 in_dialog_container = CONTAINER_UNLINK(dialogs, pvt, 08030 "About to change the callid -- remove the old name"); 08031 if (callid) { 08032 ast_string_field_set(pvt, callid, callid); 08033 } else { 08034 build_callid_pvt(pvt); 08035 } 08036 if (in_dialog_container) { 08037 ao2_t_link(dialogs, pvt, "New dialog callid -- inserted back into table"); 08038 } 08039 ao2_unlock(dialogs); 08040 08041 if (strcmp(oldid, pvt->callid)) { 08042 ast_debug(1, "SIP call-id changed from '%s' to '%s'\n", oldid, pvt->callid); 08043 } 08044 }
| 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 9106 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().
09107 { 09108 if (sip_cfg.notifyhold && (!holdstate || !ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD))) 09109 sip_peer_hold(dialog, holdstate); 09110 if (sip_cfg.callevents) 09111 manager_event(EVENT_FLAG_CALL, "Hold", 09112 "Status: %s\r\n" 09113 "Channel: %s\r\n" 09114 "Uniqueid: %s\r\n", 09115 holdstate ? "On" : "Off", 09116 dialog->owner->name, 09117 dialog->owner->uniqueid); 09118 append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", ast_str_buffer(req->data)); 09119 if (!holdstate) { /* Put off remote hold */ 09120 ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */ 09121 return; 09122 } 09123 /* No address for RTP, we're on hold */ 09124 09125 /* Ensure hold flags are cleared so that overlapping flags do not conflict */ 09126 ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD); 09127 09128 if (sendonly == 1) /* One directional hold (sendonly/recvonly) */ 09129 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR); 09130 else if (sendonly == 2) /* Inactive stream */ 09131 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE); 09132 else 09133 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE); 09134 return; 09135 }
| 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 20253 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().
20256 { 20257 char *redirecting_from_name = NULL; 20258 char *redirecting_from_number = NULL; 20259 char *redirecting_to_name = NULL; 20260 char *redirecting_to_number = NULL; 20261 int reason = AST_REDIRECTING_REASON_UNCONDITIONAL; 20262 int is_response = req->method == SIP_RESPONSE; 20263 int res = 0; 20264 20265 res = get_rdnis(p, req, &redirecting_from_name, &redirecting_from_number, &reason); 20266 if (res == -1) { 20267 if (is_response) { 20268 get_name_and_number(get_header(req, "TO"), &redirecting_from_name, &redirecting_from_number); 20269 } else { 20270 return; 20271 } 20272 } 20273 20274 /* At this point, all redirecting "from" info should be filled in appropriately 20275 * on to the "to" info 20276 */ 20277 20278 if (is_response) { 20279 parse_moved_contact(p, req, &redirecting_to_name, &redirecting_to_number, set_call_forward); 20280 } else { 20281 get_name_and_number(get_header(req, "TO"), &redirecting_to_name, &redirecting_to_number); 20282 } 20283 20284 if (!ast_strlen_zero(redirecting_from_number)) { 20285 ast_debug(3, "Got redirecting from number %s\n", redirecting_from_number); 20286 update_redirecting->from.number = 1; 20287 redirecting->from.number.valid = 1; 20288 ast_free(redirecting->from.number.str); 20289 redirecting->from.number.str = redirecting_from_number; 20290 } 20291 if (!ast_strlen_zero(redirecting_from_name)) { 20292 ast_debug(3, "Got redirecting from name %s\n", redirecting_from_name); 20293 update_redirecting->from.name = 1; 20294 redirecting->from.name.valid = 1; 20295 ast_free(redirecting->from.name.str); 20296 redirecting->from.name.str = redirecting_from_name; 20297 } 20298 if (!ast_strlen_zero(p->cid_tag)) { 20299 ast_free(redirecting->from.tag); 20300 redirecting->from.tag = ast_strdup(p->cid_tag); 20301 ast_free(redirecting->to.tag); 20302 redirecting->to.tag = ast_strdup(p->cid_tag); 20303 } 20304 if (!ast_strlen_zero(redirecting_to_number)) { 20305 ast_debug(3, "Got redirecting to number %s\n", redirecting_to_number); 20306 update_redirecting->to.number = 1; 20307 redirecting->to.number.valid = 1; 20308 ast_free(redirecting->to.number.str); 20309 redirecting->to.number.str = redirecting_to_number; 20310 } 20311 if (!ast_strlen_zero(redirecting_to_name)) { 20312 ast_debug(3, "Got redirecting to name %s\n", redirecting_from_number); 20313 update_redirecting->to.name = 1; 20314 redirecting->to.name.valid = 1; 20315 ast_free(redirecting->to.name.str); 20316 redirecting->to.name.str = redirecting_to_name; 20317 } 20318 redirecting->reason = reason; 20319 }
| static void change_t38_state | ( | struct sip_pvt * | p, | |
| int | state | |||
| ) | [static] |
Change the T38 state on a SIP dialog.
Definition at line 5490 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().
05491 { 05492 int old = p->t38.state; 05493 struct ast_channel *chan = p->owner; 05494 struct ast_control_t38_parameters parameters = { .request_response = 0 }; 05495 05496 /* Don't bother changing if we are already in the state wanted */ 05497 if (old == state) 05498 return; 05499 05500 p->t38.state = state; 05501 ast_debug(2, "T38 state changed to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>"); 05502 05503 /* If no channel was provided we can't send off a control frame */ 05504 if (!chan) 05505 return; 05506 05507 /* Given the state requested and old state determine what control frame we want to queue up */ 05508 switch (state) { 05509 case T38_PEER_REINVITE: 05510 parameters = p->t38.their_parms; 05511 parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl); 05512 parameters.request_response = AST_T38_REQUEST_NEGOTIATE; 05513 ast_udptl_set_tag(p->udptl, "%s", chan->name); 05514 break; 05515 case T38_ENABLED: 05516 parameters = p->t38.their_parms; 05517 parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl); 05518 parameters.request_response = AST_T38_NEGOTIATED; 05519 ast_udptl_set_tag(p->udptl, "%s", chan->name); 05520 break; 05521 case T38_DISABLED: 05522 if (old == T38_ENABLED) { 05523 parameters.request_response = AST_T38_TERMINATED; 05524 } else if (old == T38_LOCAL_REINVITE) { 05525 parameters.request_response = AST_T38_REFUSED; 05526 } 05527 break; 05528 case T38_LOCAL_REINVITE: 05529 /* wait until we get a peer response before responding to local reinvite */ 05530 break; 05531 } 05532 05533 /* Woot we got a message, create a control frame and send it on! */ 05534 if (parameters.request_response) 05535 ast_queue_control_data(chan, AST_CONTROL_T38_PARAMETERS, ¶meters, sizeof(parameters)); 05536 }
| 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 14875 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().
14878 { 14879 const char *response; 14880 char *reqheader, *respheader; 14881 const char *authtoken; 14882 char a1_hash[256]; 14883 char resp_hash[256]=""; 14884 char *c; 14885 int is_bogus_peer = 0; 14886 int wrongnonce = FALSE; 14887 int good_response; 14888 const char *usednonce = p->randdata; 14889 struct ast_str *buf; 14890 int res; 14891 14892 /* table of recognised keywords, and their value in the digest */ 14893 enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST }; 14894 struct x { 14895 const char *key; 14896 const char *s; 14897 } *i, keys[] = { 14898 [K_RESP] = { "response=", "" }, 14899 [K_URI] = { "uri=", "" }, 14900 [K_USER] = { "username=", "" }, 14901 [K_NONCE] = { "nonce=", "" }, 14902 [K_LAST] = { NULL, NULL} 14903 }; 14904 14905 /* Always OK if no secret */ 14906 if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret)) 14907 return AUTH_SUCCESSFUL; 14908 14909 /* Always auth with WWW-auth since we're NOT a proxy */ 14910 /* Using proxy-auth in a B2BUA may block proxy authorization in the same transaction */ 14911 response = "401 Unauthorized"; 14912 14913 /* 14914 * Note the apparent swap of arguments below, compared to other 14915 * usages of auth_headers(). 14916 */ 14917 auth_headers(WWW_AUTH, &respheader, &reqheader); 14918 14919 authtoken = get_header(req, reqheader); 14920 if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 14921 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 14922 information */ 14923 if (!reliable) { 14924 /* Resend message if this was NOT a reliable delivery. Otherwise the 14925 retransmission should get it */ 14926 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 14927 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 14928 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14929 } 14930 return AUTH_CHALLENGE_SENT; 14931 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 14932 /* We have no auth, so issue challenge and request authentication */ 14933 set_nonce_randdata(p, 1); /* Create nonce for challenge */ 14934 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 14935 /* Schedule auto destroy in 32 seconds */ 14936 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14937 return AUTH_CHALLENGE_SENT; 14938 } 14939 14940 /* --- We have auth, so check it */ 14941 14942 /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting 14943 an example in the spec of just what it is you're doing a hash on. */ 14944 14945 if (!(buf = ast_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) { 14946 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 14947 } 14948 14949 /* Make a copy of the response and parse it */ 14950 res = ast_str_set(&buf, 0, "%s", authtoken); 14951 14952 if (res == AST_DYNSTR_BUILD_FAILED) { 14953 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 14954 } 14955 14956 c = buf->str; 14957 14958 while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */ 14959 for (i = keys; i->key != NULL; i++) { 14960 const char *separator = ","; /* default */ 14961 14962 if (strncasecmp(c, i->key, strlen(i->key)) != 0) { 14963 continue; 14964 } 14965 /* Found. Skip keyword, take text in quotes or up to the separator. */ 14966 c += strlen(i->key); 14967 if (*c == '"') { /* in quotes. Skip first and look for last */ 14968 c++; 14969 separator = "\""; 14970 } 14971 i->s = c; 14972 strsep(&c, separator); 14973 break; 14974 } 14975 if (i->key == NULL) { /* not found, jump after space or comma */ 14976 strsep(&c, " ,"); 14977 } 14978 } 14979 14980 /* We cannot rely on the bogus_peer having a bad md5 value. Someone could 14981 * use it to construct valid auth. */ 14982 if (md5secret && strcmp(md5secret, BOGUS_PEER_MD5SECRET) == 0) { 14983 is_bogus_peer = 1; 14984 } 14985 14986 /* Verify that digest username matches the username we auth as */ 14987 if (strcmp(username, keys[K_USER].s) && !is_bogus_peer) { 14988 ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n", 14989 username, keys[K_USER].s); 14990 /* Oops, we're trying something here */ 14991 return AUTH_USERNAME_MISMATCH; 14992 } 14993 14994 /* Verify nonce from request matches our nonce, and the nonce has not already been responded to. 14995 * If this check fails, send 401 with new nonce */ 14996 if (strcasecmp(p->randdata, keys[K_NONCE].s) || p->stalenonce) { /* XXX it was 'n'casecmp ? */ 14997 wrongnonce = TRUE; 14998 usednonce = keys[K_NONCE].s; 14999 } else { 15000 p->stalenonce = 1; /* now, since the nonce has a response, mark it as stale so it can't be sent or responded to again */ 15001 } 15002 15003 if (!ast_strlen_zero(md5secret)) { 15004 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 15005 } else { 15006 char a1[256]; 15007 15008 snprintf(a1, sizeof(a1), "%s:%s:%s", username, p->realm, secret); 15009 ast_md5_hash(a1_hash, a1); 15010 } 15011 15012 /* compute the expected response to compare with what we received */ 15013 { 15014 char a2[256]; 15015 char a2_hash[256]; 15016 char resp[256]; 15017 15018 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, 15019 S_OR(keys[K_URI].s, uri)); 15020 ast_md5_hash(a2_hash, a2); 15021 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash); 15022 ast_md5_hash(resp_hash, resp); 15023 } 15024 15025 good_response = keys[K_RESP].s && 15026 !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash)) && 15027 !is_bogus_peer; /* lastly, check that the peer isn't the fake peer */ 15028 if (wrongnonce) { 15029 if (good_response) { 15030 if (sipdebug) 15031 ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "From")); 15032 /* We got working auth token, based on stale nonce . */ 15033 set_nonce_randdata(p, 0); 15034 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE); 15035 } else { 15036 /* Everything was wrong, so give the device one more try with a new challenge */ 15037 if (!req->ignore) { 15038 if (sipdebug) { 15039 ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To")); 15040 } 15041 set_nonce_randdata(p, 1); 15042 } else { 15043 if (sipdebug) { 15044 ast_log(LOG_NOTICE, "Duplicate authentication received from '%s'\n", get_header(req, "To")); 15045 } 15046 } 15047 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 15048 } 15049 15050 /* Schedule auto destroy in 32 seconds */ 15051 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15052 return AUTH_CHALLENGE_SENT; 15053 } 15054 if (good_response) { 15055 append_history(p, "AuthOK", "Auth challenge successful for %s", username); 15056 return AUTH_SUCCESSFUL; 15057 } 15058 15059 /* Ok, we have a bad username/secret pair */ 15060 /* Tell the UAS not to re-send this authentication data, because 15061 it will continue to fail 15062 */ 15063 15064 return AUTH_SECRET_FAILED; 15065 }
| 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 2749 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_tcp_read().
02750 { 02751 char *message = ast_str_buffer(*request); 02752 char *body; 02753 int content_length; 02754 int message_len = ast_str_strlen(*request); 02755 int body_len; 02756 02757 /* Important pieces to search for in a SIP request are \r\n\r\n. This 02758 * marks either 02759 * 1) The division between the headers and body 02760 * 2) The end of the SIP request 02761 */ 02762 body = strstr(message, "\r\n\r\n"); 02763 if (!body) { 02764 /* This is clearly a partial message since we haven't reached an end 02765 * yet. 02766 */ 02767 return MESSAGE_FRAGMENT; 02768 } 02769 body += sizeof("\r\n\r\n") - 1; 02770 body_len = message_len - (body - message); 02771 02772 body[-1] = '\0'; 02773 content_length = read_raw_content_length(message); 02774 body[-1] = '\n'; 02775 02776 if (content_length < 0) { 02777 return MESSAGE_INVALID; 02778 } else if (content_length == 0) { 02779 /* We've definitely received an entire message. We need 02780 * to check if there's also a fragment of another message 02781 * in addition. 02782 */ 02783 if (body_len == 0) { 02784 return MESSAGE_COMPLETE; 02785 } else { 02786 ast_str_append(overflow, 0, "%s", body); 02787 ast_str_truncate(*request, message_len - body_len); 02788 return MESSAGE_FRAGMENT_COMPLETE; 02789 } 02790 } 02791 /* Positive content length. Let's see what sort of 02792 * message body we're dealing with. 02793 */ 02794 if (body_len < content_length) { 02795 /* We don't have the full message body yet */ 02796 return MESSAGE_FRAGMENT; 02797 } else if (body_len > content_length) { 02798 /* We have the full message plus a fragment of a further 02799 * message 02800 */ 02801 ast_str_append(overflow, 0, "%s", body + content_length); 02802 ast_str_truncate(*request, message_len - (body_len - content_length)); 02803 return MESSAGE_FRAGMENT_COMPLETE; 02804 } else { 02805 /* Yay! Full message with no extra content */ 02806 return MESSAGE_COMPLETE; 02807 } 02808 }
| 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 16537 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().
16541 { 16542 enum check_auth_result res; 16543 int debug = sip_debug_test_addr(addr); 16544 struct sip_peer *peer; 16545 16546 if (sipmethod == SIP_SUBSCRIBE) { 16547 /* For subscribes, match on device name only; for other methods, 16548 * match on IP address-port of the incoming request. 16549 */ 16550 peer = find_peer(of, NULL, TRUE, FINDALLDEVICES, FALSE, 0); 16551 } else { 16552 /* First find devices based on username (avoid all type=peer's) */ 16553 peer = find_peer(of, NULL, TRUE, FINDUSERS, FALSE, 0); 16554 16555 /* Then find devices based on IP */ 16556 if (!peer) { 16557 peer = find_peer(NULL, &p->recv, TRUE, FINDPEERS, FALSE, p->socket.type); 16558 } 16559 } 16560 16561 if (!peer) { 16562 if (debug) { 16563 ast_verbose("No matching peer for '%s' from '%s'\n", 16564 of, ast_sockaddr_stringify(&p->recv)); 16565 } 16566 16567 /* If you don't mind, we can return 404s for devices that do 16568 * not exist: username disclosure. If we allow guests, there 16569 * is no way around that. */ 16570 if (sip_cfg.allowguest || !sip_cfg.alwaysauthreject) { 16571 return AUTH_DONT_KNOW; 16572 } 16573 16574 /* If you do mind, we use a peer that will never authenticate. 16575 * This ensures that we follow the same code path as regular 16576 * auth: less chance for username disclosure. */ 16577 peer = bogus_peer; 16578 ref_peer(peer, "ref_peer: check_peer_ok: must ref bogus_peer so unreffing it does not fail"); 16579 } 16580 16581 if (!ast_apply_ha(peer->ha, addr)) { 16582 ast_debug(2, "Found peer '%s' for '%s', but fails host access\n", peer->name, of); 16583 unref_peer(peer, "unref_peer: check_peer_ok: from find_peer call, early return of AUTH_ACL_FAILED"); 16584 return AUTH_ACL_FAILED; 16585 } 16586 if (debug && peer != bogus_peer) { 16587 ast_verbose("Found peer '%s' for '%s' from %s\n", 16588 peer->name, of, ast_sockaddr_stringify(&p->recv)); 16589 } 16590 16591 /* XXX what about p->prefs = peer->prefs; ? */ 16592 /* Set Frame packetization */ 16593 if (p->rtp) { 16594 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &peer->prefs); 16595 p->autoframing = peer->autoframing; 16596 } 16597 16598 /* Take the peer */ 16599 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 16600 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 16601 ast_copy_flags(&p->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY); 16602 16603 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) && p->udptl) { 16604 p->t38_maxdatagram = peer->t38_maxdatagram; 16605 set_t38_capabilities(p); 16606 } 16607 16608 /* Copy SIP extensions profile to peer */ 16609 /* XXX is this correct before a successful auth ? */ 16610 if (p->sipoptions) 16611 peer->sipoptions = p->sipoptions; 16612 16613 do_setnat(p); 16614 16615 ast_string_field_set(p, peersecret, peer->secret); 16616 ast_string_field_set(p, peermd5secret, peer->md5secret); 16617 ast_string_field_set(p, subscribecontext, peer->subscribecontext); 16618 ast_string_field_set(p, mohinterpret, peer->mohinterpret); 16619 ast_string_field_set(p, mohsuggest, peer->mohsuggest); 16620 if (!ast_strlen_zero(peer->parkinglot)) { 16621 ast_string_field_set(p, parkinglot, peer->parkinglot); 16622 } 16623 ast_string_field_set(p, engine, peer->engine); 16624 p->disallowed_methods = peer->disallowed_methods; 16625 set_pvt_allowed_methods(p, req); 16626 ast_cc_copy_config_params(p->cc_params, peer->cc_params); 16627 if (peer->callingpres) /* Peer calling pres setting will override RPID */ 16628 p->callingpres = peer->callingpres; 16629 if (peer->maxms && peer->lastms) 16630 p->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 16631 else 16632 p->timer_t1 = peer->timer_t1; 16633 16634 /* Set timer B to control transaction timeouts */ 16635 if (peer->timer_b) 16636 p->timer_b = peer->timer_b; 16637 else 16638 p->timer_b = 64 * p->timer_t1; 16639 16640 p->allowtransfer = peer->allowtransfer; 16641 16642 if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) { 16643 /* Pretend there is no required authentication */ 16644 ast_string_field_set(p, peersecret, NULL); 16645 ast_string_field_set(p, peermd5secret, NULL); 16646 } 16647 if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, req->ignore))) { 16648 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 16649 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 16650 ast_copy_flags(&p->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY); 16651 /* If we have a call limit, set flag */ 16652 if (peer->call_limit) 16653 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 16654 ast_string_field_set(p, peername, peer->name); 16655 ast_string_field_set(p, authname, peer->name); 16656 16657 if (sipmethod == SIP_INVITE) { 16658 /* destroy old channel vars and copy in new ones. */ 16659 ast_variables_destroy(p->chanvars); 16660 p->chanvars = copy_vars(peer->chanvars); 16661 } 16662 16663 if (authpeer) { 16664 ao2_t_ref(peer, 1, "copy pointer into (*authpeer)"); 16665 (*authpeer) = peer; /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */ 16666 } 16667 16668 if (!ast_strlen_zero(peer->username)) { 16669 ast_string_field_set(p, username, peer->username); 16670 /* Use the default username for authentication on outbound calls */ 16671 /* XXX this takes the name from the caller... can we override ? */ 16672 ast_string_field_set(p, authname, peer->username); 16673 } 16674 if (!get_rpid(p, req)) { 16675 if (!ast_strlen_zero(peer->cid_num)) { 16676 char *tmp = ast_strdupa(peer->cid_num); 16677 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) 16678 ast_shrink_phone_number(tmp); 16679 ast_string_field_set(p, cid_num, tmp); 16680 } 16681 if (!ast_strlen_zero(peer->cid_name)) 16682 ast_string_field_set(p, cid_name, peer->cid_name); 16683 if (peer->callingpres) 16684 p->callingpres = peer->callingpres; 16685 } 16686 if (!ast_strlen_zero(peer->cid_tag)) { 16687 ast_string_field_set(p, cid_tag, peer->cid_tag); 16688 } 16689 ast_string_field_set(p, fullcontact, peer->fullcontact); 16690 16691 if (!ast_strlen_zero(peer->context)) { 16692 ast_string_field_set(p, context, peer->context); 16693 } 16694 if (!ast_strlen_zero(peer->mwi_from)) { 16695 ast_string_field_set(p, mwi_from, peer->mwi_from); 16696 } 16697 16698 ast_string_field_set(p, peersecret, peer->secret); 16699 ast_string_field_set(p, peermd5secret, peer->md5secret); 16700 ast_string_field_set(p, language, peer->language); 16701 ast_string_field_set(p, accountcode, peer->accountcode); 16702 p->amaflags = peer->amaflags; 16703 p->callgroup = peer->callgroup; 16704 p->pickupgroup = peer->pickupgroup; 16705 p->capability = peer->capability; 16706 p->prefs = peer->prefs; 16707 p->jointcapability = peer->capability; 16708 if (peer->maxforwards > 0) { 16709 p->maxforwards = peer->maxforwards; 16710 } 16711 if (p->peercapability) 16712 p->jointcapability &= p->peercapability; 16713 p->maxcallbitrate = peer->maxcallbitrate; 16714 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 16715 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 16716 p->noncodeccapability |= AST_RTP_DTMF; 16717 else 16718 p->noncodeccapability &= ~AST_RTP_DTMF; 16719 p->jointnoncodeccapability = p->noncodeccapability; 16720 p->rtptimeout = peer->rtptimeout; 16721 p->rtpholdtimeout = peer->rtpholdtimeout; 16722 p->rtpkeepalive = peer->rtpkeepalive; 16723 if (!dialog_initialize_rtp(p)) { 16724 if (p->rtp) { 16725 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &peer->prefs); 16726 p->autoframing = peer->autoframing; 16727 } 16728 } else { 16729 res = AUTH_RTP_FAILED; 16730 } 16731 } 16732 unref_peer(peer, "check_peer_ok: unref_peer: tossing temp ptr to peer from find_peer"); 16733 return res; 16734 }
| static void check_pendings | ( | struct sip_pvt * | p | ) | [static] |
Check pending actions on SIP call.
Definition at line 20439 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().
20440 { 20441 if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 20442 if (p->reinviteid > -1) { 20443 /* Outstanding p->reinviteid timeout, so wait... */ 20444 return; 20445 } else if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) { 20446 /* if we can't BYE, then this is really a pending CANCEL */ 20447 p->invitestate = INV_CANCELLED; 20448 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 20449 /* If the cancel occurred on an initial invite, cancel the pending BYE */ 20450 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) { 20451 ast_clear_flag(&p->flags[0], SIP_PENDINGBYE); 20452 } 20453 /* Actually don't destroy us yet, wait for the 487 on our original 20454 INVITE, but do set an autodestruct just in case we never get it. */ 20455 } else { 20456 /* We have a pending outbound invite, don't send something 20457 * new in-transaction, unless it is a pending reinvite, then 20458 * by the time we are called here, we should probably just hang up. */ 20459 if (p->pendinginvite && !p->ongoing_reinvite) 20460 return; 20461 20462 if (p->owner) { 20463 ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV); 20464 } 20465 /* Perhaps there is an SD change INVITE outstanding */ 20466 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE); 20467 ast_clear_flag(&p->flags[0], SIP_PENDINGBYE); 20468 } 20469 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 20470 } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) { 20471 /* if we can't REINVITE, hold it for later */ 20472 if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) { 20473 ast_debug(2, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid); 20474 } else { 20475 ast_debug(2, "Sending pending reinvite on '%s'\n", p->callid); 20476 /* Didn't get to reinvite yet, so do it now */ 20477 transmit_reinvite_with_sdp(p, (p->t38.state == T38_LOCAL_REINVITE ? TRUE : FALSE), FALSE); 20478 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 20479 } 20480 } 20481 }
| 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 26464 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().
26465 { 26466 /* If we have no RTP or no active owner, no need to check timers */ 26467 if (!dialog->rtp || !dialog->owner) 26468 return; 26469 /* If the call is not in UP state or redirected outside Asterisk, no need to check timers */ 26470 26471 if (dialog->owner->_state != AST_STATE_UP || !ast_sockaddr_isnull(&dialog->redirip)) 26472 return; 26473 26474 /* If the call is involved in a T38 fax session do not check RTP timeout */ 26475 if (dialog->t38.state == T38_ENABLED) 26476 return; 26477 26478 /* If we have no timers set, return now */ 26479 if (!ast_rtp_instance_get_keepalive(dialog->rtp) && !ast_rtp_instance_get_timeout(dialog->rtp) && !ast_rtp_instance_get_hold_timeout(dialog->rtp)) { 26480 return; 26481 } 26482 26483 /* Check AUDIO RTP keepalives */ 26484 if (dialog->lastrtptx && ast_rtp_instance_get_keepalive(dialog->rtp) && 26485 (t > dialog->lastrtptx + ast_rtp_instance_get_keepalive(dialog->rtp))) { 26486 /* Need to send an empty RTP packet */ 26487 dialog->lastrtptx = time(NULL); 26488 ast_rtp_instance_sendcng(dialog->rtp, 0); 26489 } 26490 26491 /*! \todo Check video RTP keepalives 26492 26493 Do we need to move the lastrtptx to the RTP structure to have one for audio and one 26494 for video? It really does belong to the RTP structure. 26495 */ 26496 26497 /* Check AUDIO RTP timers */ 26498 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))) { 26499 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)))) { 26500 /* Needs a hangup */ 26501 if (ast_rtp_instance_get_timeout(dialog->rtp)) { 26502 if (!dialog->owner || ast_channel_trylock(dialog->owner)) { 26503 /* 26504 * Don't block, just try again later. 26505 * If there was no owner, the call is dead already. 26506 */ 26507 return; 26508 } 26509 ast_log(LOG_NOTICE, "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", 26510 dialog->owner->name, (long) (t - dialog->lastrtprx)); 26511 /* Issue a softhangup */ 26512 ast_softhangup_nolock(dialog->owner, AST_SOFTHANGUP_DEV); 26513 ast_channel_unlock(dialog->owner); 26514 /* forget the timeouts for this call, since a hangup 26515 has already been requested and we don't want to 26516 repeatedly request hangups 26517 */ 26518 ast_rtp_instance_set_timeout(dialog->rtp, 0); 26519 ast_rtp_instance_set_hold_timeout(dialog->rtp, 0); 26520 if (dialog->vrtp) { 26521 ast_rtp_instance_set_timeout(dialog->vrtp, 0); 26522 ast_rtp_instance_set_hold_timeout(dialog->vrtp, 0); 26523 } 26524 } 26525 } 26526 } 26527 }
| 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 27661 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().
27662 { 27663 struct domain *d; 27664 int result = 0; 27665 27666 AST_LIST_LOCK(&domain_list); 27667 AST_LIST_TRAVERSE(&domain_list, d, list) { 27668 if (strcasecmp(d->domain, domain)) { 27669 continue; 27670 } 27671 27672 if (len && !ast_strlen_zero(d->context)) 27673 ast_copy_string(context, d->context, len); 27674 27675 result = 1; 27676 break; 27677 } 27678 AST_LIST_UNLOCK(&domain_list); 27679 27680 return result; 27681 }
| 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 16872 of file chan_sip.c.
References check_user_full().
Referenced by handle_request_options(), and handle_request_publish().
16873 { 16874 return check_user_full(p, req, sipmethod, uri, reliable, addr, NULL); 16875 }
| 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 16742 of file chan_sip.c.
References ast_copy_string(), ast_is_shrinkable_phonenumber(), ast_log(), ast_set_flag, ast_shrink_phone_number(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, build_contact(), check_peer_ok(), cid_name, cid_num, dialog_initialize_rtp(), exten, extract_host_from_hostport(), get_calleridname(), get_header(), get_in_brackets(), get_rpid(), LOG_ERROR, LOG_NOTICE, name, parse_uri_legacy_check(), sip_cfg, SIP_PEDANTIC_DECODE, and terminate_uri().
Referenced by check_user(), handle_request_invite(), and handle_request_subscribe().
16745 { 16746 char from[256] = "", *of, *name, *unused_password, *domain; 16747 enum check_auth_result res = AUTH_DONT_KNOW; 16748 char calleridname[50]; 16749 char *uri2 = ast_strdupa(uri); 16750 16751 terminate_uri(uri2); /* trim extra stuff */ 16752 16753 ast_copy_string(from, get_header(req, "From"), sizeof(from)); 16754 /* XXX here tries to map the username for invite things */ 16755 16756 /* strip the display-name portion off the beginning of the FROM header. */ 16757 if (!(of = (char *) get_calleridname(from, calleridname, sizeof(calleridname)))) { 16758 ast_log(LOG_ERROR, "FROM header can not be parsed \n"); 16759 return res; 16760 } 16761 16762 if (calleridname[0]) { 16763 ast_string_field_set(p, cid_name, calleridname); 16764 } 16765 16766 if (ast_strlen_zero(p->exten)) { 16767 char *t = uri2; 16768 if (!strncasecmp(t, "sip:", 4)) 16769 t+= 4; 16770 else if (!strncasecmp(t, "sips:", 5)) 16771 t += 5; 16772 ast_string_field_set(p, exten, t); 16773 t = strchr(p->exten, '@'); 16774 if (t) 16775 *t = '\0'; 16776 16777 if (ast_strlen_zero(p->our_contact)) 16778 build_contact(p); 16779 } 16780 16781 of = get_in_brackets(of); 16782 16783 /* save the URI part of the From header */ 16784 ast_string_field_set(p, from, of); 16785 16786 if (parse_uri_legacy_check(of, "sip:,sips:", &name, &unused_password, &domain, NULL)) { 16787 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 16788 } 16789 16790 SIP_PEDANTIC_DECODE(name); 16791 SIP_PEDANTIC_DECODE(domain); 16792 16793 extract_host_from_hostport(&domain); 16794 16795 if (ast_strlen_zero(domain)) { 16796 /* <sip:name@[EMPTY]>, never good */ 16797 ast_log(LOG_ERROR, "Empty domain name in FROM header\n"); 16798 return res; 16799 } 16800 16801 if (ast_strlen_zero(name)) { 16802 /* <sip:[EMPTY][@]hostport>. Asterisk 1.4 and 1.6 have always 16803 * treated that as a username, so we continue the tradition: 16804 * uri is now <sip:host@hostport>. */ 16805 name = domain; 16806 } else { 16807 /* Non-empty name, try to get caller id from it */ 16808 char *tmp = ast_strdupa(name); 16809 /* We need to be able to handle from-headers looking like 16810 <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43> 16811 */ 16812 tmp = strsep(&tmp, ";"); 16813 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) { 16814 ast_shrink_phone_number(tmp); 16815 } 16816 ast_string_field_set(p, cid_num, tmp); 16817 } 16818 16819 if (global_match_auth_username) { 16820 /* 16821 * XXX This is experimental code to grab the search key from the 16822 * Auth header's username instead of the 'From' name, if available. 16823 * Do not enable this block unless you understand the side effects (if any!) 16824 * Note, the search for "username" should be done in a more robust way. 16825 * Note2, at the moment we check both fields, though maybe we should 16826 * pick one or another depending on the request ? XXX 16827 */ 16828 const char *hdr = get_header(req, "Authorization"); 16829 if (ast_strlen_zero(hdr)) { 16830 hdr = get_header(req, "Proxy-Authorization"); 16831 } 16832 16833 if (!ast_strlen_zero(hdr) && (hdr = strstr(hdr, "username=\""))) { 16834 ast_copy_string(from, hdr + strlen("username=\""), sizeof(from)); 16835 name = from; 16836 name = strsep(&name, "\""); 16837 } 16838 } 16839 16840 res = check_peer_ok(p, name, req, sipmethod, addr, 16841 authpeer, reliable, calleridname, uri2); 16842 if (res != AUTH_DONT_KNOW) { 16843 return res; 16844 } 16845 16846 /* Finally, apply the guest policy */ 16847 if (sip_cfg.allowguest) { 16848 /* Ignore check_return warning from Coverity for get_rpid below. */ 16849 get_rpid(p, req); 16850 p->rtptimeout = global_rtptimeout; 16851 p->rtpholdtimeout = global_rtpholdtimeout; 16852 p->rtpkeepalive = global_rtpkeepalive; 16853 if (!dialog_initialize_rtp(p)) { 16854 res = AUTH_SUCCESSFUL; 16855 } else { 16856 res = AUTH_RTP_FAILED; 16857 } 16858 } else { 16859 res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */ 16860 } 16861 16862 if (ast_test_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT)) { 16863 ast_set_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT); 16864 } 16865 16866 return res; 16867 }
| static void check_via | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
check Via: header for hostname, port and rport request/answer
Definition at line 16472 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().
16473 { 16474 char via[512]; 16475 char *c, *maddr; 16476 struct ast_sockaddr tmp = { { 0, } }; 16477 uint16_t port; 16478 16479 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 16480 16481 /* Work on the leftmost value of the topmost Via header */ 16482 c = strchr(via, ','); 16483 if (c) 16484 *c = '\0'; 16485 16486 /* Check for rport */ 16487 c = strstr(via, ";rport"); 16488 if (c && (c[6] != '=')) { /* rport query, not answer */ 16489 ast_set_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT); 16490 ast_set_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT); 16491 } 16492 16493 /* Check for maddr */ 16494 maddr = strstr(via, "maddr="); 16495 if (maddr) { 16496 maddr += 6; 16497 c = maddr + strspn(maddr, "abcdefghijklmnopqrstuvwxyz" 16498 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.:[]"); 16499 *c = '\0'; 16500 } 16501 16502 c = strchr(via, ';'); 16503 if (c) 16504 *c = '\0'; 16505 16506 c = strchr(via, ' '); 16507 if (c) { 16508 *c = '\0'; 16509 c = ast_skip_blanks(c+1); 16510 if (strcasecmp(via, "SIP/2.0/UDP") && strcasecmp(via, "SIP/2.0/TCP") && strcasecmp(via, "SIP/2.0/TLS")) { 16511 ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via); 16512 return; 16513 } 16514 16515 if (maddr && ast_sockaddr_resolve_first(&p->sa, maddr, 0)) { 16516 p->sa = p->recv; 16517 } 16518 16519 if (ast_sockaddr_resolve_first(&tmp, c, 0)) { 16520 ast_log(LOG_WARNING, "Could not resolve socket address for '%s'\n", c); 16521 port = STANDARD_SIP_PORT; 16522 } else if (!(port = ast_sockaddr_port(&tmp))) { 16523 port = STANDARD_SIP_PORT; 16524 } 16525 16526 ast_sockaddr_set_port(&p->sa, port); 16527 16528 if (sip_debug_test_pvt(p)) { 16529 ast_verbose("Sending to %s (%s)\n", 16530 ast_sockaddr_stringify(sip_real_dst(p)), 16531 sip_nat_mode(p)); 16532 } 16533 } 16534 }
| 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 16442 of file chan_sip.c.
References ast_copy_string(), ast_parse_arg(), ast_sockaddr_set_port, get_header(), and PARSE_ADDR.
16443 { 16444 char via[256]; 16445 char *cur, *opts; 16446 16447 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 16448 16449 /* Work on the leftmost value of the topmost Via header */ 16450 opts = strchr(via, ','); 16451 if (opts) 16452 *opts = '\0'; 16453 16454 /* parse all relevant options */ 16455 opts = strchr(via, ';'); 16456 if (!opts) 16457 return; /* no options to parse */ 16458 *opts++ = '\0'; 16459 while ( (cur = strsep(&opts, ";")) ) { 16460 if (!strncmp(cur, "rport=", 6)) { 16461 int port = strtol(cur+6, NULL, 10); 16462 /* XXX add error checking */ 16463 ast_sockaddr_set_port(&p->ourip, port); 16464 } else if (!strncmp(cur, "received=", 9)) { 16465 if (ast_parse_arg(cur + 9, PARSE_ADDR, &p->ourip)) 16466 ; /* XXX add error checking */ 16467 } 16468 } 16469 }
| static void cleanup_all_regs | ( | void | ) | [static] |
Definition at line 28639 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().
28640 { 28641 /* First, destroy all outstanding registry calls */ 28642 /* This is needed, since otherwise active registry entries will not be destroyed */ 28643 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { /* regl is locked */ 28644 ASTOBJ_WRLOCK(iterator); /* now regl is locked, and the object is also locked */ 28645 if (iterator->call) { 28646 ast_debug(3, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname); 28647 /* This will also remove references to the registry */ 28648 dialog_unlink_all(iterator->call); 28649 iterator->call = dialog_unref(iterator->call, "remove iterator->call from registry traversal"); 28650 } 28651 if (iterator->expire > -1) { 28652 AST_SCHED_DEL_UNREF(sched, iterator->expire, registry_unref(iterator, "reg ptr unref from reload config")); 28653 } 28654 if (iterator->timeout > -1) { 28655 AST_SCHED_DEL_UNREF(sched, iterator->timeout, registry_unref(iterator, "reg ptr unref from reload config")); 28656 } 28657 if (iterator->dnsmgr) { 28658 ast_dnsmgr_release(iterator->dnsmgr); 28659 iterator->dnsmgr = NULL; 28660 registry_unref(iterator, "reg ptr unref from dnsmgr"); 28661 } 28662 ASTOBJ_UNLOCK(iterator); 28663 } while(0)); 28664 }
| 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 17620 of file chan_sip.c.
References ast_context_destroy(), ast_context_find(), ast_copy_string(), and AST_MAX_CONTEXT.
Referenced by reload_config().
17621 { 17622 char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT]; 17623 17624 while ((oldcontext = strsep(&old, "&"))) { 17625 stalecontext = '\0'; 17626 ast_copy_string(newlist, new, sizeof(newlist)); 17627 stringp = newlist; 17628 while ((newcontext = strsep(&stringp, "&"))) { 17629 if (!strcmp(newcontext, oldcontext)) { 17630 /* This is not the context you're looking for */ 17631 stalecontext = '\0'; 17632 break; 17633 } else if (strcmp(newcontext, oldcontext)) { 17634 stalecontext = oldcontext; 17635 } 17636 17637 } 17638 if (stalecontext) 17639 ast_context_destroy(ast_context_find(stalecontext), "SIP"); 17640 } 17641 }
| static void clear_peer_mailboxes | ( | struct sip_peer * | peer | ) | [static] |
Destroy all peer-related mailbox subscriptions
Definition at line 4963 of file chan_sip.c.
References AST_LIST_REMOVE_HEAD, destroy_mailbox(), and mailbox.
Referenced by set_peer_defaults(), and sip_destroy_peer().
04964 { 04965 struct sip_mailbox *mailbox; 04966 04967 while ((mailbox = AST_LIST_REMOVE_HEAD(&peer->mailboxes, entry))) 04968 destroy_mailbox(mailbox); 04969 }
| static void clear_sip_domains | ( | void | ) | [static] |
Clear our domain list (at reload).
Definition at line 27684 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().
27685 { 27686 struct domain *d; 27687 27688 AST_LIST_LOCK(&domain_list); 27689 while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list))) 27690 ast_free(d); 27691 AST_LIST_UNLOCK(&domain_list); 27692 }
| static char * complete_sip_peer | ( | const char * | word, | |
| int | state, | |||
| int | flags2 | |||
| ) | [static] |
Do completion on peer name.
Definition at line 19102 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().
19103 { 19104 char *result = NULL; 19105 int wordlen = strlen(word); 19106 int which = 0; 19107 struct ao2_iterator i = ao2_iterator_init(peers, 0); 19108 struct sip_peer *peer; 19109 19110 while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) { 19111 /* locking of the object is not required because only the name and flags are being compared */ 19112 if (!strncasecmp(word, peer->name, wordlen) && 19113 (!flags2 || ast_test_flag(&peer->flags[1], flags2)) && 19114 ++which > state) 19115 result = ast_strdup(peer->name); 19116 unref_peer(peer, "toss iterator peer ptr before break"); 19117 if (result) { 19118 break; 19119 } 19120 } 19121 ao2_iterator_destroy(&i); 19122 return result; 19123 }
| static char * complete_sip_registered_peer | ( | const char * | word, | |
| int | state, | |||
| int | flags2 | |||
| ) | [static] |
Do completion on registered peer name.
Definition at line 19126 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().
19127 { 19128 char *result = NULL; 19129 int wordlen = strlen(word); 19130 int which = 0; 19131 struct ao2_iterator i; 19132 struct sip_peer *peer; 19133 19134 i = ao2_iterator_init(peers, 0); 19135 while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) { 19136 if (!strncasecmp(word, peer->name, wordlen) && 19137 (!flags2 || ast_test_flag(&peer->flags[1], flags2)) && 19138 ++which > state && peer->expire > 0) 19139 result = ast_strdup(peer->name); 19140 if (result) { 19141 unref_peer(peer, "toss iterator peer ptr before break"); 19142 break; 19143 } 19144 unref_peer(peer, "toss iterator peer ptr"); 19145 } 19146 ao2_iterator_destroy(&i); 19147 return result; 19148 }
| 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 19151 of file chan_sip.c.
References complete_sipch().
Referenced by sip_show_history().
19152 { 19153 if (pos == 3) 19154 return complete_sipch(line, word, pos, state); 19155 19156 return NULL; 19157 }
| 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 19160 of file chan_sip.c.
References complete_sip_peer().
Referenced by sip_qualify_peer(), and sip_show_peer().
19161 { 19162 if (pos == 3) { 19163 return complete_sip_peer(word, state, 0); 19164 } 19165 19166 return NULL; 19167 }
| 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 18362 of file chan_sip.c.
References complete_sip_user().
Referenced by sip_show_user().
18363 { 18364 if (pos == 3) 18365 return complete_sip_user(word, state); 18366 18367 return NULL; 18368 }
| 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 19170 of file chan_sip.c.
References complete_sip_registered_peer().
Referenced by sip_unregister().
19171 { 19172 if (pos == 2) 19173 return complete_sip_registered_peer(word, state, 0); 19174 19175 return NULL; 19176 }
| static char* complete_sip_user | ( | const char * | word, | |
| int | state | |||
| ) | [static] |
Do completion on user name.
Definition at line 18332 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().
18333 { 18334 char *result = NULL; 18335 int wordlen = strlen(word); 18336 int which = 0; 18337 struct ao2_iterator user_iter; 18338 struct sip_peer *user; 18339 18340 user_iter = ao2_iterator_init(peers, 0); 18341 while ((user = ao2_t_iterator_next(&user_iter, "iterate thru peers table"))) { 18342 ao2_lock(user); 18343 if (!(user->type & SIP_TYPE_USER)) { 18344 ao2_unlock(user); 18345 unref_peer(user, "complete sip user"); 18346 continue; 18347 } 18348 /* locking of the object is not required because only the name and flags are being compared */ 18349 if (!strncasecmp(word, user->name, wordlen) && ++which > state) { 18350 result = ast_strdup(user->name); 18351 } 18352 ao2_unlock(user); 18353 unref_peer(user, "complete sip user"); 18354 if (result) { 18355 break; 18356 } 18357 } 18358 ao2_iterator_destroy(&user_iter); 18359 return result; 18360 }
| 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 19072 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().
19073 { 19074 int which=0; 19075 struct sip_pvt *cur; 19076 char *c = NULL; 19077 int wordlen = strlen(word); 19078 struct ao2_iterator i; 19079 19080 if (pos != 3) { 19081 return NULL; 19082 } 19083 19084 i = ao2_iterator_init(dialogs, 0); 19085 while ((cur = ao2_t_iterator_next(&i, "iterate thru dialogs"))) { 19086 sip_pvt_lock(cur); 19087 if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) { 19088 c = ast_strdup(cur->callid); 19089 sip_pvt_unlock(cur); 19090 dialog_unref(cur, "drop ref in iterator loop break"); 19091 break; 19092 } 19093 sip_pvt_unlock(cur); 19094 dialog_unref(cur, "drop ref in iterator loop"); 19095 } 19096 ao2_iterator_destroy(&i); 19097 return c; 19098 }
| static char * complete_sipnotify | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Support routine for 'sip notify' CLI.
Definition at line 19179 of file chan_sip.c.
References ast_category_browse(), ast_strdup, and complete_sip_peer().
Referenced by sip_cli_notify().
19180 { 19181 char *c = NULL; 19182 19183 if (pos == 2) { 19184 int which = 0; 19185 char *cat = NULL; 19186 int wordlen = strlen(word); 19187 19188 /* do completion for notify type */ 19189 19190 if (!notify_types) 19191 return NULL; 19192 19193 while ( (cat = ast_category_browse(notify_types, cat)) ) { 19194 if (!strncasecmp(word, cat, wordlen) && ++which > state) { 19195 c = ast_strdup(cat); 19196 break; 19197 } 19198 } 19199 return c; 19200 } 19201 19202 if (pos > 2) 19203 return complete_sip_peer(word, state, 0); 19204 19205 return NULL; 19206 }
| static int construct_pidf_body | ( | enum sip_cc_publish_state | state, | |
| char * | pidf_body, | |||
| size_t | size, | |||
| const char * | presentity | |||
| ) | [static] |
Definition at line 1957 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().
01958 { 01959 struct ast_str *body = ast_str_alloca(size); 01960 char tuple_id[32]; 01961 01962 generate_random_string(tuple_id, sizeof(tuple_id)); 01963 01964 /* We'll make this a bare-bones pidf body. In state_notify_build_xml, the PIDF 01965 * body gets a lot more extra junk that isn't necessary, so we'll leave it out here. 01966 */ 01967 ast_str_append(&body, 0, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); 01968 /* XXX The entity attribute is currently set to the peer name associated with the 01969 * dialog. This is because we currently only call this function for call-completion 01970 * PUBLISH bodies. In such cases, the entity is completely disregarded. For other 01971 * event packages, it may be crucial to have a proper URI as the presentity so this 01972 * should be revisited as support is expanded. 01973 */ 01974 ast_str_append(&body, 0, "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" entity=\"%s\">\n", presentity); 01975 ast_str_append(&body, 0, "<tuple id=\"%s\">\n", tuple_id); 01976 ast_str_append(&body, 0, "<status><basic>%s</basic></status>\n", state == CC_OPEN ? "open" : "closed"); 01977 ast_str_append(&body, 0, "</tuple>\n"); 01978 ast_str_append(&body, 0, "</presence>\n"); 01979 ast_copy_string(pidf_body, ast_str_buffer(body), size); 01980 return 0; 01981 }
| 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 10415 of file chan_sip.c.
References __get_header(), add_header(), and ast_strlen_zero().
Referenced by respprep().
10416 { 10417 int start = 0; 10418 int copied = 0; 10419 for (;;) { 10420 const char *tmp = __get_header(orig, field, &start); 10421 10422 if (ast_strlen_zero(tmp)) 10423 break; 10424 /* Add what we're responding to */ 10425 add_header(req, field, tmp); 10426 copied++; 10427 } 10428 return copied ? 0 : -1; 10429 }
| 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 10404 of file chan_sip.c.
References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE.
Referenced by reqprep(), and respprep().
10405 { 10406 const char *tmp = get_header(orig, field); 10407 10408 if (!ast_strlen_zero(tmp)) /* Add what we're responding to */ 10409 return add_header(req, field, tmp); 10410 ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field); 10411 return -1; 10412 }
| 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 12195 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(), sip_park(), and sip_tls_read().
12196 { 12197 /* XXX this function can encounter memory allocation errors, perhaps it 12198 * should return a value */ 12199 12200 struct ast_str *duplicate = dst->data; 12201 struct ast_str *duplicate_content = dst->content; 12202 12203 /* copy the entire request then restore the original data and content 12204 * members from the dst request */ 12205 *dst = *src; 12206 dst->data = duplicate; 12207 dst->content = duplicate_content; 12208 12209 /* copy the data into the dst request */ 12210 if (!dst->data && !(dst->data = ast_str_create(ast_str_strlen(src->data) + 1))) { 12211 return; 12212 } 12213 ast_str_copy_string(&dst->data, src->data); 12214 12215 /* copy the content into the dst request (if it exists) */ 12216 if (src->content) { 12217 if (!dst->content && !(dst->content = ast_str_create(ast_str_strlen(src->content) + 1))) { 12218 return; 12219 } 12220 ast_str_copy_string(&dst->content, src->content); 12221 } 12222 }
| static void copy_socket_data | ( | struct sip_socket * | to_sock, | |
| const struct sip_socket * | from_sock | |||
| ) | [static] |
Definition at line 5552 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 2336 of file chan_sip.c.
References ast_variable_new(), and ast_variable::next.
Referenced by check_peer_ok(), and create_addr_from_peer().
02337 { 02338 struct ast_variable *res = NULL, *tmp, *v = NULL; 02339 02340 for (v = src ; v ; v = v->next) { 02341 if ((tmp = ast_variable_new(v->name, v->value, v->file))) { 02342 tmp->next = res; 02343 res = tmp; 02344 } 02345 } 02346 return res; 02347 }
| 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 10439 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().
10440 { 10441 int copied = 0; 10442 int start = 0; 10443 10444 for (;;) { 10445 char new[512]; 10446 const char *oh = __get_header(orig, field, &start); 10447 10448 if (ast_strlen_zero(oh)) 10449 break; 10450 10451 if (!copied) { /* Only check for empty rport in topmost via header */ 10452 char leftmost[512], *others, *rport; 10453 10454 /* Only work on leftmost value */ 10455 ast_copy_string(leftmost, oh, sizeof(leftmost)); 10456 others = strchr(leftmost, ','); 10457 if (others) 10458 *others++ = '\0'; 10459 10460 /* Find ;rport; (empty request) */ 10461 rport = strstr(leftmost, ";rport"); 10462 if (rport && *(rport+6) == '=') 10463 rport = NULL; /* We already have a parameter to rport */ 10464 10465 if (((ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT)) || (rport && ast_test_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT)))) { 10466 /* We need to add received port - rport */ 10467 char *end; 10468 10469 rport = strstr(leftmost, ";rport"); 10470 10471 if (rport) { 10472 end = strchr(rport + 1, ';'); 10473 if (end) 10474 memmove(rport, end, strlen(end) + 1); 10475 else 10476 *rport = '\0'; 10477 } 10478 10479 /* Add rport to first VIA header if requested */ 10480 snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s", 10481 leftmost, ast_sockaddr_stringify_addr_remote(&p->recv), 10482 ast_sockaddr_port(&p->recv), 10483 others ? "," : "", others ? others : ""); 10484 } else { 10485 /* We should *always* add a received to the topmost via */ 10486 snprintf(new, sizeof(new), "%s;received=%s%s%s", 10487 leftmost, ast_sockaddr_stringify_addr_remote(&p->recv), 10488 others ? "," : "", others ? others : ""); 10489 } 10490 oh = new; /* the header to copy */ 10491 } /* else add the following via headers untouched */ 10492 add_header(req, field, oh); 10493 copied++; 10494 } 10495 if (!copied) { 10496 ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field); 10497 return -1; 10498 } 10499 return 0; 10500 }
| 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 5781 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().
05782 { 05783 struct sip_peer *peer; 05784 char *peername, *peername2, *hostn; 05785 char host[MAXHOSTNAMELEN]; 05786 char service[MAXHOSTNAMELEN]; 05787 int srv_ret = 0; 05788 int tportno; 05789 05790 AST_DECLARE_APP_ARGS(hostport, 05791 AST_APP_ARG(host); 05792 AST_APP_ARG(port); 05793 ); 05794 05795 peername = ast_strdupa(opeer); 05796 peername2 = ast_strdupa(opeer); 05797 AST_NONSTANDARD_RAW_ARGS(hostport, peername2, ':'); 05798 05799 if (hostport.port) 05800 dialog->portinuri = 1; 05801 05802 dialog->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */ 05803 dialog->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */ 05804 peer = find_peer(peername, NULL, TRUE, FINDPEERS, FALSE, 0); 05805 05806 if (peer) { 05807 int res; 05808 if (newdialog) { 05809 set_socket_transport(&dialog->socket, 0); 05810 } 05811 res = create_addr_from_peer(dialog, peer); 05812 dialog->relatedpeer = ref_peer(peer, "create_addr: setting dialog's relatedpeer pointer"); 05813 unref_peer(peer, "create_addr: unref peer from find_peer hashtab lookup"); 05814 return res; 05815 } else if (ast_check_digits(peername)) { 05816 /* Although an IPv4 hostname *could* be represented as a 32-bit integer, it is uncommon and 05817 * it makes dialing SIP/${EXTEN} for a peer that isn't defined resolve to an IP that is 05818 * almost certainly not intended. It is much better to just reject purely numeric hostnames */ 05819 ast_log(LOG_WARNING, "Purely numeric hostname (%s), and not a peer--rejecting!\n", peername); 05820 return -1; 05821 } else { 05822 dialog->rtptimeout = global_rtptimeout; 05823 dialog->rtpholdtimeout = global_rtpholdtimeout; 05824 dialog->rtpkeepalive = global_rtpkeepalive; 05825 if (dialog_initialize_rtp(dialog)) { 05826 return -1; 05827 } 05828 } 05829 05830 ast_string_field_set(dialog, tohost, hostport.host); 05831 dialog->allowed_methods &= ~sip_cfg.disallowed_methods; 05832 05833 /* Get the outbound proxy information */ 05834 ref_proxy(dialog, obproxy_get(dialog, NULL)); 05835 05836 if (addr) { 05837 /* This address should be updated using dnsmgr */ 05838 ast_sockaddr_copy(&dialog->sa, addr); 05839 } else { 05840 05841 /* Let's see if we can find the host in DNS. First try DNS SRV records, 05842 then hostname lookup */ 05843 /*! \todo Fix this function. When we ask for SRV, we should check all transports 05844 In the future, we should first check NAPTR to find out transport preference 05845 */ 05846 hostn = peername; 05847 /* Section 4.2 of RFC 3263 specifies that if a port number is specified, then 05848 * an A record lookup should be used instead of SRV. 05849 */ 05850 if (!hostport.port && sip_cfg.srvlookup) { 05851 snprintf(service, sizeof(service), "_%s._%s.%s", 05852 get_srv_service(dialog->socket.type), 05853 get_srv_protocol(dialog->socket.type), peername); 05854 if ((srv_ret = ast_get_srv(NULL, host, sizeof(host), &tportno, 05855 service)) > 0) { 05856 hostn = host; 05857 } 05858 } 05859 05860 if (ast_sockaddr_resolve_first_transport(&dialog->sa, hostn, 0, dialog->socket.type ? dialog->socket.type : SIP_TRANSPORT_UDP)) { 05861 ast_log(LOG_WARNING, "No such host: %s\n", peername); 05862 return -1; 05863 } 05864 05865 if (srv_ret > 0) { 05866 ast_sockaddr_set_port(&dialog->sa, tportno); 05867 } 05868 } 05869 05870 if (!dialog->socket.type) 05871 set_socket_transport(&dialog->socket, SIP_TRANSPORT_UDP); 05872 if (!dialog->socket.port) { 05873 dialog->socket.port = htons(ast_sockaddr_port(&bindaddr)); 05874 } 05875 05876 if (!ast_sockaddr_port(&dialog->sa)) { 05877 ast_sockaddr_set_port(&dialog->sa, default_sip_port(dialog->socket.type)); 05878 } 05879 ast_sockaddr_copy(&dialog->recv, &dialog->sa); 05880 return 0; 05881 }
| 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 5627 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().
05628 { 05629 struct sip_auth_container *credentials; 05630 05631 /* this checks that the dialog is contacting the peer on a valid 05632 * transport type based on the peers transport configuration, 05633 * otherwise, this function bails out */ 05634 if (dialog->socket.type && check_request_transport(peer, dialog)) 05635 return -1; 05636 copy_socket_data(&dialog->socket, &peer->socket); 05637 05638 if (!(ast_sockaddr_isnull(&peer->addr) && ast_sockaddr_isnull(&peer->defaddr)) && 05639 (!peer->maxms || ((peer->lastms >= 0) && (peer->lastms <= peer->maxms)))) { 05640 dialog->sa = ast_sockaddr_isnull(&peer->addr) ? peer->defaddr : peer->addr; 05641 dialog->recv = dialog->sa; 05642 } else 05643 return -1; 05644 05645 /* XXX TODO: get flags directly from peer only as they are needed using dialog->relatedpeer */ 05646 ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 05647 ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 05648 ast_copy_flags(&dialog->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY); 05649 dialog->capability = peer->capability; 05650 dialog->prefs = peer->prefs; 05651 dialog->amaflags = peer->amaflags; 05652 05653 ast_string_field_set(dialog, engine, peer->engine); 05654 05655 dialog->rtptimeout = peer->rtptimeout; 05656 dialog->rtpholdtimeout = peer->rtpholdtimeout; 05657 dialog->rtpkeepalive = peer->rtpkeepalive; 05658 if (dialog_initialize_rtp(dialog)) { 05659 return -1; 05660 } 05661 05662 if (dialog->rtp) { /* Audio */ 05663 ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 05664 ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 05665 /* Set Frame packetization */ 05666 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(dialog->rtp), dialog->rtp, &dialog->prefs); 05667 dialog->autoframing = peer->autoframing; 05668 } 05669 05670 /* XXX TODO: get fields directly from peer only as they are needed using dialog->relatedpeer */ 05671 ast_string_field_set(dialog, peername, peer->name); 05672 ast_string_field_set(dialog, authname, peer->username); 05673 ast_string_field_set(dialog, username, peer->username); 05674 ast_string_field_set(dialog, peersecret, peer->secret); 05675 ast_string_field_set(dialog, peermd5secret, peer->md5secret); 05676 ast_string_field_set(dialog, mohsuggest, peer->mohsuggest); 05677 ast_string_field_set(dialog, mohinterpret, peer->mohinterpret); 05678 ast_string_field_set(dialog, tohost, peer->tohost); 05679 ast_string_field_set(dialog, fullcontact, peer->fullcontact); 05680 ast_string_field_set(dialog, accountcode, peer->accountcode); 05681 ast_string_field_set(dialog, context, peer->context); 05682 ast_string_field_set(dialog, cid_num, peer->cid_num); 05683 ast_string_field_set(dialog, cid_name, peer->cid_name); 05684 ast_string_field_set(dialog, cid_tag, peer->cid_tag); 05685 ast_string_field_set(dialog, mwi_from, peer->mwi_from); 05686 if (!ast_strlen_zero(peer->parkinglot)) { 05687 ast_string_field_set(dialog, parkinglot, peer->parkinglot); 05688 } 05689 ast_string_field_set(dialog, engine, peer->engine); 05690 ref_proxy(dialog, obproxy_get(dialog, peer)); 05691 dialog->callgroup = peer->callgroup; 05692 dialog->pickupgroup = peer->pickupgroup; 05693 dialog->allowtransfer = peer->allowtransfer; 05694 dialog->jointnoncodeccapability = dialog->noncodeccapability; 05695 05696 /* Update dialog authorization credentials */ 05697 ao2_lock(peer); 05698 credentials = peer->auth; 05699 if (credentials) { 05700 ao2_t_ref(credentials, +1, "Ref peer auth for dialog"); 05701 } 05702 ao2_unlock(peer); 05703 ao2_lock(dialog); 05704 if (dialog->peerauth) { 05705 ao2_t_ref(dialog->peerauth, -1, "Unref old dialog peer auth"); 05706 } 05707 dialog->peerauth = credentials; 05708 ao2_unlock(dialog); 05709 05710 dialog->maxcallbitrate = peer->maxcallbitrate; 05711 dialog->disallowed_methods = peer->disallowed_methods; 05712 ast_cc_copy_config_params(dialog->cc_params, peer->cc_params); 05713 if (ast_strlen_zero(dialog->tohost)) 05714 ast_string_field_set(dialog, tohost, ast_sockaddr_stringify_host_remote(&dialog->sa)); 05715 if (!ast_strlen_zero(peer->fromdomain)) { 05716 ast_string_field_set(dialog, fromdomain, peer->fromdomain); 05717 if (!dialog->initreq.headers) { 05718 char *new_callid; 05719 char *tmpcall = ast_strdupa(dialog->callid); 05720 /* this sure looks to me like we are going to change the callid on this dialog!! */ 05721 new_callid = strchr(tmpcall, '@'); 05722 if (new_callid) { 05723 int callid_size; 05724 05725 *new_callid = '\0'; 05726 05727 /* Change the dialog callid. */ 05728 callid_size = strlen(tmpcall) + strlen(peer->fromdomain) + 2; 05729 new_callid = ast_alloca(callid_size); 05730 snprintf(new_callid, callid_size, "%s@%s", tmpcall, peer->fromdomain); 05731 change_callid_pvt(dialog, new_callid); 05732 } 05733 } 05734 } 05735 if (!ast_strlen_zero(peer->fromuser)) 05736 ast_string_field_set(dialog, fromuser, peer->fromuser); 05737 if (!ast_strlen_zero(peer->language)) 05738 ast_string_field_set(dialog, language, peer->language); 05739 /* Set timer T1 to RTT for this peer (if known by qualify=) */ 05740 /* Minimum is settable or default to 100 ms */ 05741 /* If there is a maxms and lastms from a qualify use that over a manual T1 05742 value. Otherwise, use the peer's T1 value. */ 05743 if (peer->maxms && peer->lastms) 05744 dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 05745 else 05746 dialog->timer_t1 = peer->timer_t1; 05747 05748 /* Set timer B to control transaction timeouts, the peer setting is the default and overrides 05749 the known timer */ 05750 if (peer->timer_b) 05751 dialog->timer_b = peer->timer_b; 05752 else 05753 dialog->timer_b = 64 * dialog->timer_t1; 05754 05755 if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 05756 (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 05757 dialog->noncodeccapability |= AST_RTP_DTMF; 05758 else 05759 dialog->noncodeccapability &= ~AST_RTP_DTMF; 05760 dialog->directmediaha = ast_duplicate_ha_list(peer->directmediaha); 05761 if (peer->call_limit) 05762 ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT); 05763 if (!dialog->portinuri) 05764 dialog->portinuri = peer->portinuri; 05765 dialog->chanvars = copy_vars(peer->chanvars); 05766 if (peer->fromdomainport) 05767 dialog->fromdomainport = peer->fromdomainport; 05768 05769 return 0; 05770 }
| static struct sip_epa_entry* create_epa_entry | ( | const char *const | event_package, | |
| const char *const | destination | |||
| ) | [static, read] |
Definition at line 919 of file chan_sip.c.
References ao2_t_alloc, ast_copy_string(), and find_static_data().
Referenced by sip_cc_monitor_suspend().
00920 { 00921 struct sip_epa_entry *epa_entry; 00922 const struct epa_static_data *static_data; 00923 00924 if (!(static_data = find_static_data(event_package))) { 00925 return NULL; 00926 } 00927 00928 if (!(epa_entry = ao2_t_alloc(sizeof(*epa_entry), static_data->destructor, "Allocate new EPA entry"))) { 00929 return NULL; 00930 } 00931 00932 epa_entry->static_data = static_data; 00933 ast_copy_string(epa_entry->destination, destination, sizeof(epa_entry->destination)); 00934 return epa_entry; 00935 }
| 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 1045 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().
01046 { 01047 struct sip_esc_entry *esc_entry; 01048 int expires_ms; 01049 01050 if (!(esc_entry = ao2_alloc(sizeof(*esc_entry), esc_entry_destructor))) { 01051 return NULL; 01052 } 01053 01054 esc_entry->event = esc->name; 01055 01056 expires_ms = expires * 1000; 01057 /* Bump refcount for scheduler */ 01058 ao2_ref(esc_entry, +1); 01059 esc_entry->sched_id = ast_sched_add(sched, expires_ms, publish_expire, esc_entry); 01060 01061 /* Note: This links the esc_entry into the ESC properly */ 01062 create_new_sip_etag(esc_entry, 0); 01063 01064 return esc_entry; 01065 }
| static void create_new_sip_etag | ( | struct sip_esc_entry * | esc_entry, | |
| int | is_linked | |||
| ) | [static] |
Definition at line 1032 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().
01033 { 01034 int new_etag = ast_atomic_fetchadd_int(&esc_etag_counter, +1); 01035 struct event_state_compositor *esc = get_esc(esc_entry->event); 01036 01037 ast_assert(esc != NULL); 01038 if (is_linked) { 01039 ao2_unlink(esc->compositor, esc_entry); 01040 } 01041 snprintf(esc_entry->entity_tag, sizeof(esc_entry->entity_tag), "%d", new_etag); 01042 ao2_link(esc->compositor, esc_entry); 01043 }
| static int default_sip_port | ( | enum sip_transport | type | ) | [inline, static] |
The default sip port for the given transport.
Definition at line 5773 of file chan_sip.c.
Referenced by create_addr(), on_dns_update_peer(), and parse_register_contact().
05774 { 05775 return type == SIP_TRANSPORT_TLS ? STANDARD_TLS_PORT : STANDARD_SIP_PORT; 05776 }
| static void deinit_req | ( | struct sip_request * | req | ) | [static] |
Deinitialize SIP response/request.
Definition at line 10656 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 14225 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().
14226 { 14227 int realtimeregs = ast_check_realtime("sipregs"); 14228 char *tablename = (realtimeregs) ? "sipregs" : "sippeers"; 14229 14230 if (!sip_cfg.ignore_regexpire) { 14231 if (peer->rt_fromcontact && sip_cfg.peer_rtupdate) { 14232 ast_update_realtime(tablename, "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "regserver", "", "useragent", "", "lastms", "0", SENTINEL); 14233 } else { 14234 ast_db_del("SIP/Registry", peer->name); 14235 ast_db_del("SIP/PeerMethods", peer->name); 14236 } 14237 } 14238 }
| static void destroy_escs | ( | void | ) | [static] |
Definition at line 1079 of file chan_sip.c.
References ao2_ref, ARRAY_LEN, and event_state_compositors.
Referenced by unload_module().
01080 { 01081 int i; 01082 for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) { 01083 ao2_ref(event_state_compositors[i].compositor, -1); 01084 } 01085 }
| static void destroy_mailbox | ( | struct sip_mailbox * | mailbox | ) | [static] |
Destroy mailbox subscriptions
Definition at line 4955 of file chan_sip.c.
References ast_event_unsubscribe(), and ast_free.
Referenced by build_peer(), and clear_peer_mailboxes().
04956 { 04957 if (mailbox->event_sub) 04958 ast_event_unsubscribe(mailbox->event_sub); 04959 ast_free(mailbox); 04960 }
| static void destroy_realm_authentication | ( | void * | obj | ) | [static] |
Definition at line 27702 of file chan_sip.c.
References ast_free, and AST_LIST_REMOVE_HEAD.
Referenced by add_realm_authentication().
27703 { 27704 struct sip_auth_container *credentials = obj; 27705 struct sip_auth *auth; 27706 27707 while ((auth = AST_LIST_REMOVE_HEAD(&credentials->list, node))) { 27708 ast_free(auth); 27709 } 27710 }
| static int determine_firstline_parts | ( | struct sip_request * | req | ) | [static] |
Parse first line of incoming SIP request.
Definition at line 12295 of file chan_sip.c.
References ast_debug, ast_skip_blanks(), ast_skip_nonblanks(), and ast_trim_blanks().
Referenced by parse_request().
12296 { 12297 char *e = ast_skip_blanks(req->data->str); /* there shouldn't be any */ 12298 char *local_rlPart1; 12299 12300 if (!*e) 12301 return -1; 12302 req->rlPart1 = e - req->data->str; /* method or protocol */ 12303 local_rlPart1 = e; 12304 e = ast_skip_nonblanks(e); 12305 if (*e) 12306 *e++ = '\0'; 12307 /* Get URI or status code */ 12308 e = ast_skip_blanks(e); 12309 if ( !*e ) 12310 return -1; 12311 ast_trim_blanks(e); 12312 12313 if (!strcasecmp(local_rlPart1, "SIP/2.0") ) { /* We have a response */ 12314 if (strlen(e) < 3) /* status code is 3 digits */ 12315 return -1; 12316 req->rlPart2 = e - req->data->str; 12317 } else { /* We have a request */ 12318 if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */ 12319 ast_debug(3, "Oops. Bogus uri in <> %s\n", e); 12320 e++; 12321 if (!*e) 12322 return -1; 12323 } 12324 req->rlPart2 = e - req->data->str; /* URI */ 12325 e = ast_skip_nonblanks(e); 12326 if (*e) 12327 *e++ = '\0'; 12328 e = ast_skip_blanks(e); 12329 if (strcasecmp(e, "SIP/2.0") ) { 12330 ast_debug(3, "Skipping packet - Bad request protocol %s\n", e); 12331 return -1; 12332 } 12333 } 12334 return 1; 12335 }
| 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 24682 of file chan_sip.c.
References ast_assert, and ast_strlen_zero().
Referenced by handle_request_publish().
24683 { 24684 int etag_present = !ast_strlen_zero(etag); 24685 int body_present = req->lines > 0; 24686 24687 ast_assert(expires_int != NULL); 24688 24689 if (ast_strlen_zero(expires)) { 24690 /* Section 6, item 4, second bullet point of RFC 3903 says to 24691 * use a locally-configured default expiration if none is provided 24692 * in the request 24693 */ 24694 *expires_int = DEFAULT_PUBLISH_EXPIRES; 24695 } else if (sscanf(expires, "%30d", expires_int) != 1) { 24696 return SIP_PUBLISH_UNKNOWN; 24697 } 24698 24699 if (*expires_int == 0) { 24700 return SIP_PUBLISH_REMOVE; 24701 } else if (!etag_present && body_present) { 24702 return SIP_PUBLISH_INITIAL; 24703 } else if (etag_present && !body_present) { 24704 return SIP_PUBLISH_REFRESH; 24705 } else if (etag_present && body_present) { 24706 return SIP_PUBLISH_MODIFY; 24707 } 24708 24709 return SIP_PUBLISH_UNKNOWN; 24710 }
| static int dialog_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 dialog_dump_func | ( | void * | userobj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 17521 of file chan_sip.c.
References ao2_t_ref, ast_cli(), and ast_cli_args::fd.
Referenced by sip_show_objects().
17522 { 17523 struct sip_pvt *pvt = userobj; 17524 int refc = ao2_t_ref(userobj, 0, ""); 17525 struct ast_cli_args *a = (struct ast_cli_args *) arg; 17526 17527 ast_cli(a->fd, "name: %s\ntype: dialog\nobjflags: %d\nrefcount: %d\n\n", 17528 pvt->callid, 0, refc); 17529 return 0; 17530 }
| static int dialog_find_multiple | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 30699 of file chan_sip.c.
References CMP_MATCH.
Referenced by find_call().
30700 { 30701 struct sip_pvt *pvt = obj, *pvt2 = arg; 30702 30703 return !strcasecmp(pvt->callid, pvt2->callid) ? CMP_MATCH : 0; 30704 }
| static int dialog_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 30689 of file chan_sip.c.
References ast_str_case_hash().
Referenced by load_module().
30690 { 30691 const struct sip_pvt *pvt = obj; 30692 30693 return ast_str_case_hash(pvt->callid); 30694 }
| static int dialog_initialize_rtp | ( | struct sip_pvt * | dialog | ) | [static] |
Initialize RTP portion of a dialog.
Definition at line 5569 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().
05570 { 05571 struct ast_sockaddr bindaddr_tmp; 05572 05573 if (!sip_methods[dialog->method].need_rtp) { 05574 return 0; 05575 } 05576 05577 ast_sockaddr_copy(&bindaddr_tmp, &bindaddr); 05578 if (!(dialog->rtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) { 05579 return -1; 05580 } 05581 05582 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS) || 05583 (ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) && (dialog->capability & AST_FORMAT_VIDEO_MASK))) { 05584 if (!(dialog->vrtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) { 05585 return -1; 05586 } 05587 ast_rtp_instance_set_timeout(dialog->vrtp, dialog->rtptimeout); 05588 ast_rtp_instance_set_hold_timeout(dialog->vrtp, dialog->rtpholdtimeout); 05589 ast_rtp_instance_set_keepalive(dialog->vrtp, dialog->rtpkeepalive); 05590 05591 ast_rtp_instance_set_prop(dialog->vrtp, AST_RTP_PROPERTY_RTCP, 1); 05592 ast_rtp_instance_set_qos(dialog->vrtp, global_tos_video, global_cos_video, "SIP VIDEO"); 05593 } 05594 05595 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_TEXTSUPPORT)) { 05596 if (!(dialog->trtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) { 05597 return -1; 05598 } 05599 /* Do not timeout text as its not constant*/ 05600 ast_rtp_instance_set_keepalive(dialog->trtp, dialog->rtpkeepalive); 05601 05602 ast_rtp_instance_set_prop(dialog->trtp, AST_RTP_PROPERTY_RTCP, 1); 05603 } 05604 05605 ast_rtp_instance_set_timeout(dialog->rtp, dialog->rtptimeout); 05606 ast_rtp_instance_set_hold_timeout(dialog->rtp, dialog->rtpholdtimeout); 05607 ast_rtp_instance_set_keepalive(dialog->rtp, dialog->rtpkeepalive); 05608 05609 ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_RTCP, 1); 05610 ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 05611 ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 05612 05613 ast_rtp_instance_set_qos(dialog->rtp, global_tos_audio, global_cos_audio, "SIP RTP"); 05614 05615 do_setnat(dialog); 05616 05617 return 0; 05618 }
| 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 17653 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().
17654 { 17655 struct sip_pvt *dialog = dialogobj; 17656 time_t *t = arg; 17657 17658 if (sip_pvt_trylock(dialog)) { 17659 /* Don't block the monitor thread. This function is called often enough 17660 * that we can wait for the next time around. */ 17661 return 0; 17662 } 17663 17664 /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */ 17665 check_rtp_timeout(dialog, *t); 17666 17667 /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */ 17668 if (dialog->rtp && ast_rtp_instance_get_bridged(dialog->rtp)) { 17669 ast_debug(2, "Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text); 17670 sip_pvt_unlock(dialog); 17671 return 0; 17672 } 17673 17674 if (dialog->vrtp && ast_rtp_instance_get_bridged(dialog->vrtp)) { 17675 ast_debug(2, "Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text); 17676 sip_pvt_unlock(dialog); 17677 return 0; 17678 } 17679 17680 /* If we have sessions that needs to be destroyed, do it now */ 17681 /* Check if we have outstanding requests not responsed to or an active call 17682 - if that's the case, wait with destruction */ 17683 if (dialog->needdestroy && !dialog->packets && !dialog->owner) { 17684 /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */ 17685 if (dialog->rtp && ast_rtp_instance_get_bridged(dialog->rtp)) { 17686 ast_debug(2, "Bridge still active. Delaying destruction of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text); 17687 sip_pvt_unlock(dialog); 17688 return 0; 17689 } 17690 17691 if (dialog->vrtp && ast_rtp_instance_get_bridged(dialog->vrtp)) { 17692 ast_debug(2, "Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text); 17693 sip_pvt_unlock(dialog); 17694 return 0; 17695 } 17696 17697 sip_pvt_unlock(dialog); 17698 17699 /* This dialog needs to be destroyed. */ 17700 ao2_t_link(dialogs_to_destroy, dialog, "Link dialog for destruction"); 17701 return 0; 17702 } 17703 17704 sip_pvt_unlock(dialog); 17705 17706 return 0; 17707 }
| struct sip_pvt* dialog_ref_debug | ( | struct sip_pvt * | p, | |
| char * | tag, | |||
| char * | file, | |||
| int | line, | |||
| const char * | func | |||
| ) | [read] |
Definition at line 2228 of file chan_sip.c.
References __ao2_ref_debug(), ao2_ref, ast_log(), and LOG_ERROR.
02229 { 02230 if (p) 02231 #ifdef REF_DEBUG 02232 __ao2_ref_debug(p, 1, tag, file, line, func); 02233 #else 02234 ao2_ref(p, 1); 02235 #endif 02236 else 02237 ast_log(LOG_ERROR, "Attempt to Ref a null pointer\n"); 02238 return p; 02239 }
| 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 3238 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().
03239 { 03240 struct sip_pkt *cp; 03241 struct ast_channel *owner; 03242 03243 dialog_ref(dialog, "Let's bump the count in the unlink so it doesn't accidentally become dead before we are done"); 03244 03245 ao2_t_unlink(dialogs, dialog, "unlinking dialog via ao2_unlink"); 03246 03247 /* Unlink us from the owner (channel) if we have one */ 03248 owner = sip_pvt_lock_full(dialog); 03249 if (owner) { 03250 ast_debug(1, "Detaching from channel %s\n", owner->name); 03251 owner->tech_pvt = dialog_unref(owner->tech_pvt, "resetting channel dialog ptr in unlink_all"); 03252 ast_channel_unlock(owner); 03253 ast_channel_unref(owner); 03254 dialog->owner = NULL; 03255 } 03256 sip_pvt_unlock(dialog); 03257 03258 if (dialog->registry) { 03259 if (dialog->registry->call == dialog) { 03260 dialog->registry->call = dialog_unref(dialog->registry->call, "nulling out the registry's call dialog field in unlink_all"); 03261 } 03262 dialog->registry = registry_unref(dialog->registry, "delete dialog->registry"); 03263 } 03264 if (dialog->stateid != -1) { 03265 ast_extension_state_del(dialog->stateid, cb_extensionstate); 03266 dialog->stateid = -1; 03267 } 03268 /* Remove link from peer to subscription of MWI */ 03269 if (dialog->relatedpeer && dialog->relatedpeer->mwipvt == dialog) { 03270 dialog->relatedpeer->mwipvt = dialog_unref(dialog->relatedpeer->mwipvt, "delete ->relatedpeer->mwipvt"); 03271 } 03272 if (dialog->relatedpeer && dialog->relatedpeer->call == dialog) { 03273 dialog->relatedpeer->call = dialog_unref(dialog->relatedpeer->call, "unset the relatedpeer->call field in tandem with relatedpeer field itself"); 03274 } 03275 03276 /* remove all current packets in this dialog */ 03277 while((cp = dialog->packets)) { 03278 dialog->packets = dialog->packets->next; 03279 AST_SCHED_DEL(sched, cp->retransid); 03280 dialog_unref(cp->owner, "remove all current packets in this dialog, and the pointer to the dialog too as part of __sip_destroy"); 03281 if (cp->data) { 03282 ast_free(cp->data); 03283 } 03284 ast_free(cp); 03285 } 03286 03287 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")); 03288 03289 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")); 03290 03291 if (dialog->autokillid > -1) { 03292 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")); 03293 } 03294 03295 if (dialog->request_queue_sched_id > -1) { 03296 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")); 03297 } 03298 03299 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")); 03300 03301 if (dialog->t38id > -1) { 03302 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")); 03303 } 03304 03305 if (dialog->stimer) { 03306 stop_session_timer(dialog); 03307 } 03308 03309 dialog_unref(dialog, "Let's unbump the count in the unlink so the poor pvt can disappear if it is time"); 03310 }
| static int dialog_unlink_callback | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 17719 of file chan_sip.c.
References CMP_MATCH, and dialog_unlink_all().
Referenced by do_monitor().
17720 { 17721 struct sip_pvt *dialog = obj; 17722 17723 dialog_unlink_all(dialog); 17724 17725 return CMP_MATCH; 17726 }
| struct sip_pvt* dialog_unref_debug | ( | struct sip_pvt * | p, | |
| char * | tag, | |||
| char * | file, | |||
| int | line, | |||
| const char * | func | |||
| ) | [read] |
Definition at line 2241 of file chan_sip.c.
References __ao2_ref_debug(), and ao2_ref.
02242 { 02243 if (p) 02244 #ifdef REF_DEBUG 02245 __ao2_ref_debug(p, -1, tag, file, line, func); 02246 #else 02247 ao2_ref(p, -1); 02248 #endif 02249 return NULL; 02250 }
| static void disable_dsp_detect | ( | struct sip_pvt * | p | ) | [static] |
Definition at line 4638 of file chan_sip.c.
References ast_dsp_free().
Referenced by sip_dtmfmode(), sip_hangup(), and sip_setoption().
04639 { 04640 if (p->dsp) { 04641 ast_dsp_free(p->dsp); 04642 p->dsp = NULL; 04643 } 04644 }
| static void display_nat_warning | ( | const char * | cat, | |
| int | reason, | |||
| struct ast_flags * | flags | |||
| ) | [static] |
Definition at line 28627 of file chan_sip.c.
References AST_CLI_YESNO, ast_log(), ast_test_flag, CHANNEL_MODULE_LOAD, and LOG_WARNING.
Referenced by reload_config().
28627 { 28628 int global_nat, specific_nat; 28629 28630 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))) { 28631 ast_log(LOG_WARNING, "!!! PLEASE NOTE: Setting 'nat' for a peer/user that differs from the global setting can make\n"); 28632 ast_log(LOG_WARNING, "!!! the name of that peer/user discoverable by an attacker. Replies for non-existent peers/users\n"); 28633 ast_log(LOG_WARNING, "!!! will be sent to a different port than replies for an existing peer/user. If at all possible,\n"); 28634 ast_log(LOG_WARNING, "!!! use the global 'nat' setting and do not set 'nat' per peer/user.\n"); 28635 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)); 28636 } 28637 }
| static int do_magic_pickup | ( | struct ast_channel * | channel, | |
| const char * | extension, | |||
| const char * | context | |||
| ) | [static] |
Definition at line 22814 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().
22815 { 22816 struct ast_str *str = ast_str_alloca(AST_MAX_EXTENSION + AST_MAX_CONTEXT + 2); 22817 struct ast_app *pickup = pbx_findapp("Pickup"); 22818 22819 if (!pickup) { 22820 ast_log(LOG_ERROR, "Unable to perform pickup: Application 'Pickup' not loaded (app_directed_pickup.so).\n"); 22821 return -1; 22822 } 22823 22824 ast_str_set(&str, 0, "%s@%s", extension, sip_cfg.notifycid == IGNORE_CONTEXT ? "PICKUPMARK" : context); 22825 22826 ast_debug(2, "About to call Pickup(%s)\n", ast_str_buffer(str)); 22827 22828 /* There is no point in capturing the return value since pickup_exec 22829 doesn't return anything meaningful unless the passed data is an empty 22830 string (which in our case it will not be) */ 22831 pbx_exec(channel, pickup, ast_str_buffer(str)); 22832 22833 return 0; 22834 }
| static void * do_monitor | ( | void * | data | ) | [static] |
The SIP monitoring thread.
Definition at line 26533 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().
26534 { 26535 int res; 26536 time_t t; 26537 int reloading; 26538 26539 /* Add an I/O event to our SIP UDP socket */ 26540 if (sipsock > -1) 26541 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 26542 26543 /* From here on out, we die whenever asked */ 26544 for(;;) { 26545 /* Check for a reload request */ 26546 ast_mutex_lock(&sip_reload_lock); 26547 reloading = sip_reloading; 26548 sip_reloading = FALSE; 26549 ast_mutex_unlock(&sip_reload_lock); 26550 if (reloading) { 26551 ast_verb(1, "Reloading SIP\n"); 26552 sip_do_reload(sip_reloadreason); 26553 26554 /* Change the I/O fd of our UDP socket */ 26555 if (sipsock > -1) { 26556 if (sipsock_read_id) 26557 sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL); 26558 else 26559 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 26560 } else if (sipsock_read_id) { 26561 ast_io_remove(io, sipsock_read_id); 26562 sipsock_read_id = NULL; 26563 } 26564 } 26565 26566 /* Check for dialogs needing to be killed */ 26567 t = time(NULL); 26568 /* don't scan the dialogs list if it hasn't been a reasonable period 26569 of time since the last time we did it (when MWI is being sent, we can 26570 get back to this point every millisecond or less) 26571 */ 26572 /* 26573 * We cannot hold the dialogs container lock when we destroy a 26574 * dialog because of potential deadlocks. Instead we link the 26575 * doomed dialog into dialogs_to_destroy and then iterate over 26576 * that container destroying the dialogs. 26577 */ 26578 ao2_t_callback(dialogs, OBJ_NODATA | OBJ_MULTIPLE, dialog_needdestroy, &t, 26579 "callback to monitor dialog status"); 26580 if (ao2_container_count(dialogs_to_destroy)) { 26581 /* Now destroy the found dialogs that need to be destroyed. */ 26582 ao2_t_callback(dialogs_to_destroy, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, 26583 dialog_unlink_callback, NULL, "callback to dialog_unlink_all"); 26584 } 26585 26586 /* XXX TODO The scheduler usage in this module does not have sufficient 26587 * synchronization being done between running the scheduler and places 26588 * scheduling tasks. As it is written, any scheduled item may not run 26589 * any sooner than about 1 second, regardless of whether a sooner time 26590 * was asked for. */ 26591 26592 pthread_testcancel(); 26593 /* Wait for sched or io */ 26594 res = ast_sched_wait(sched); 26595 if ((res < 0) || (res > 1000)) 26596 res = 1000; 26597 res = ast_io_wait(io, res); 26598 if (res > 20) 26599 ast_debug(1, "chan_sip: ast_io_wait ran %d all at once\n", res); 26600 ast_mutex_lock(&monlock); 26601 res = ast_sched_runq(sched); 26602 if (res >= 20) 26603 ast_debug(1, "chan_sip: ast_sched_runq ran %d all at once\n", res); 26604 if (global_store_sip_cause && res >= 100) 26605 ast_log(LOG_WARNING, "scheduler delays detected, setting 'storesipcause' to 'no' in %s will improve performance\n", config); 26606 ast_mutex_unlock(&monlock); 26607 } 26608 26609 /* Never reached */ 26610 return NULL; 26611 }
| 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 19801 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().
19802 { 19803 char *header, *respheader; 19804 char digest[1024]; 19805 19806 if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options)))) 19807 return -2; 19808 19809 p->authtries++; 19810 auth_headers(code, &header, &respheader); 19811 ast_debug(2, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text); 19812 memset(digest, 0, sizeof(digest)); 19813 if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) { 19814 /* No way to authenticate */ 19815 return -1; 19816 } 19817 /* Now we have a reply digest */ 19818 p->options->auth = digest; 19819 p->options->authheader = respheader; 19820 return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init, NULL); 19821 }
| 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 19777 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().
19778 { 19779 char *header, *respheader; 19780 char digest[1024]; 19781 19782 p->authtries++; 19783 auth_headers(code, &header, &respheader); 19784 memset(digest, 0, sizeof(digest)); 19785 if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) { 19786 /* There's nothing to use for authentication */ 19787 /* No digest challenge in request */ 19788 if (sip_debug_test_pvt(p) && p->registry) 19789 ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); 19790 /* No old challenge */ 19791 return -1; 19792 } 19793 if (p->do_history) 19794 append_history(p, "RegistryAuth", "Try: %d", p->authtries); 19795 if (sip_debug_test_pvt(p) && p->registry) 19796 ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); 19797 return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 19798 }
| static void do_setnat | ( | struct sip_pvt * | p | ) | [static] |
Set nat mode on the various data sockets.
Definition at line 5463 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().
05464 { 05465 const char *mode; 05466 int natflags; 05467 05468 natflags = ast_test_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP); 05469 mode = natflags ? "On" : "Off"; 05470 05471 if (p->rtp) { 05472 ast_debug(1, "Setting NAT on RTP to %s\n", mode); 05473 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_NAT, natflags); 05474 } 05475 if (p->vrtp) { 05476 ast_debug(1, "Setting NAT on VRTP to %s\n", mode); 05477 ast_rtp_instance_set_prop(p->vrtp, AST_RTP_PROPERTY_NAT, natflags); 05478 } 05479 if (p->udptl) { 05480 ast_debug(1, "Setting NAT on UDPTL to %s\n", mode); 05481 ast_udptl_setnat(p->udptl, natflags); 05482 } 05483 if (p->trtp) { 05484 ast_debug(1, "Setting NAT on TRTP to %s\n", mode); 05485 ast_rtp_instance_set_prop(p->trtp, AST_RTP_PROPERTY_NAT, natflags); 05486 } 05487 }
| static const char * domain_mode_to_text | ( | const enum domain_mode | mode | ) | [static] |
Print domain mode to cli.
Definition at line 17888 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 17579 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 4604 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().
04605 { 04606 int features = 0; 04607 04608 if (p->dsp) { 04609 return; 04610 } 04611 04612 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || 04613 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) { 04614 if (p->rtp) { 04615 ast_rtp_instance_dtmf_mode_set(p->rtp, AST_RTP_DTMF_MODE_INBAND); 04616 } 04617 features |= DSP_FEATURE_DIGIT_DETECT; 04618 } 04619 04620 if (ast_test_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_CNG)) { 04621 features |= DSP_FEATURE_FAX_DETECT; 04622 } 04623 04624 if (!features) { 04625 return; 04626 } 04627 04628 if (!(p->dsp = ast_dsp_new())) { 04629 return; 04630 } 04631 04632 ast_dsp_set_features(p->dsp, features); 04633 if (global_relaxdtmf) { 04634 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); 04635 } 04636 }
| static int esc_cmp_fn | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 991 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 977 of file chan_sip.c.
References AST_SCHED_DEL.
Referenced by create_esc_entry().
00978 { 00979 struct sip_esc_entry *esc_entry = obj; 00980 if (esc_entry->sched_id > -1) { 00981 AST_SCHED_DEL(sched, esc_entry->sched_id); 00982 } 00983 }
| static int esc_hash_fn | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 985 of file chan_sip.c.
References ast_str_hash().
Referenced by initialize_escs().
00986 { 00987 const struct sip_esc_entry *entry = obj; 00988 return ast_str_hash(entry->entity_tag); 00989 }
| static int expire_register | ( | const void * | data | ) | [static] |
Expire registration of SIP peer.
Definition at line 14254 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().
14255 { 14256 struct sip_peer *peer = (struct sip_peer *)data; 14257 14258 if (!peer) { /* Hmmm. We have no peer. Weird. */ 14259 return 0; 14260 } 14261 14262 peer->expire = -1; 14263 peer->portinuri = 0; 14264 14265 destroy_association(peer); /* remove registration data from storage */ 14266 set_socket_transport(&peer->socket, peer->default_outbound_transport); 14267 14268 if (peer->socket.tcptls_session) { 14269 ao2_ref(peer->socket.tcptls_session, -1); 14270 peer->socket.tcptls_session = NULL; 14271 } 14272 14273 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 14274 register_peer_exten(peer, FALSE); /* Remove regexten */ 14275 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", peer->name); 14276 14277 /* Do we need to release this peer from memory? 14278 Only for realtime peers and autocreated peers 14279 */ 14280 if (peer->is_realtime) { 14281 ast_debug(3, "-REALTIME- peer expired registration. Name: %s. Realtime peer objects now %d\n", peer->name, rpeerobjs); 14282 } 14283 14284 if (peer->selfdestruct || 14285 ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 14286 unlink_peer_from_tables(peer); 14287 } else if (!ast_sockaddr_isnull(&peer->addr)) { 14288 /* If we aren't self-destructing a temp_peer, we still need to unlink the peer 14289 * from the peers_by_ip table, otherwise we end up with multiple copies hanging 14290 * around each time a registration expires and the peer re-registers. */ 14291 ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table"); 14292 } 14293 14294 /* Only clear the addr after we check for destruction. The addr must remain 14295 * in order to unlink from the peers_by_ip container correctly */ 14296 memset(&peer->addr, 0, sizeof(peer->addr)); 14297 14298 unref_peer(peer, "removing peer ref for expire_register"); 14299 14300 return 0; 14301 }
| 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 15288 of file chan_sip.c.
References ast_sockaddr_split_hostport(), and PARSE_PORT_IGNORE.
Referenced by check_user_full(), get_destination(), and register_verify().
15289 { 15290 char *dont_care; 15291 ast_sockaddr_split_hostport(*hostport, hostport, &dont_care, PARSE_PORT_IGNORE); 15292 }
| static void extract_uri | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Check Contact: URI of SIP message.
Definition at line 12403 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().
12404 { 12405 char stripped[SIPBUFSIZE]; 12406 char *c; 12407 12408 ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped)); 12409 c = get_in_brackets(stripped); 12410 /* Cut the URI at the at sign after the @, not in the username part */ 12411 c = remove_uri_parameters(c); 12412 if (!ast_strlen_zero(c)) { 12413 ast_string_field_set(p, uri, c); 12414 } 12415 12416 }
| static const char* faxec2str | ( | int | faxec | ) | [static] |
Definition at line 18052 of file chan_sip.c.
References map_x_s().
Referenced by _sip_show_peer(), and sip_show_settings().
18053 { 18054 return map_x_s(faxecmodes, faxec, "Unknown"); 18055 }
| static int finalize_content | ( | struct sip_request * | req | ) | [static] |
Add 'Content-Length' header and content to SIP message.
Definition at line 10372 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().
10373 { 10374 char clen[10]; 10375 10376 if (req->lines) { 10377 ast_log(LOG_WARNING, "finalize_content() called on a message that has already been finalized\n"); 10378 return -1; 10379 } 10380 10381 snprintf(clen, sizeof(clen), "%zd", ast_str_strlen(req->content)); 10382 add_header(req, "Content-Length", clen); 10383 10384 if (ast_str_strlen(req->content)) { 10385 ast_str_append(&req->data, 0, "\r\n%s", ast_str_buffer(req->content)); 10386 } 10387 req->lines = ast_str_strlen(req->content) ? 1 : 0; 10388 return 0; 10389 }
| 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 7731 of file chan_sip.c.
References aliases, and ARRAY_LEN.
Referenced by __get_header(), and add_header().
07732 { 07733 /*! \brief Structure for conversion between compressed SIP and "normal" SIP */ 07734 static const struct cfalias { 07735 char * const fullname; 07736 char * const shortname; 07737 } aliases[] = { 07738 { "Content-Type", "c" }, 07739 { "Content-Encoding", "e" }, 07740 { "From", "f" }, 07741 { "Call-ID", "i" }, 07742 { "Contact", "m" }, 07743 { "Content-Length", "l" }, 07744 { "Subject", "s" }, 07745 { "To", "t" }, 07746 { "Supported", "k" }, 07747 { "Refer-To", "r" }, 07748 { "Referred-By", "b" }, 07749 { "Allow-Events", "u" }, 07750 { "Event", "o" }, 07751 { "Via", "v" }, 07752 { "Accept-Contact", "a" }, 07753 { "Reject-Contact", "j" }, 07754 { "Request-Disposition", "d" }, 07755 { "Session-Expires", "x" }, 07756 { "Identity", "y" }, 07757 { "Identity-Info", "n" }, 07758 }; 07759 int x; 07760 07761 for (x = 0; x < ARRAY_LEN(aliases); x++) { 07762 if (!strcasecmp(aliases[x].fullname, name)) 07763 return aliases[x].shortname; 07764 } 07765 07766 return _default; 07767 }
| static int find_by_callid_helper | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1691 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().
01692 { 01693 struct ast_cc_agent *agent = obj; 01694 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01695 struct sip_pvt *call_pvt = arg; 01696 01697 return !strcmp(agent_pvt->original_callid, call_pvt->callid) ? CMP_MATCH | CMP_STOP : 0; 01698 }
| static int find_by_name | ( | void * | obj, | |
| void * | arg, | |||
| void * | data, | |||
| int | flags | |||
| ) | [static] |
Definition at line 5374 of file chan_sip.c.
References CMP_MATCH, CMP_STOP, and match().
Referenced by find_peer().
05375 { 05376 struct sip_peer *search = obj, *match = arg; 05377 int *which_objects = data; 05378 05379 /* Usernames in SIP uri's are case sensitive. Domains are not */ 05380 if (strcmp(search->name, match->name)) { 05381 return 0; 05382 } 05383 05384 switch (*which_objects) { 05385 case FINDUSERS: 05386 if (!(search->type & SIP_TYPE_USER)) { 05387 return 0; 05388 } 05389 break; 05390 case FINDPEERS: 05391 if (!(search->type & SIP_TYPE_PEER)) { 05392 return 0; 05393 } 05394 break; 05395 case FINDALLDEVICES: 05396 break; 05397 } 05398 05399 return CMP_MATCH | CMP_STOP; 05400 }
| static int find_by_notify_uri_helper | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1661 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().
01662 { 01663 struct ast_cc_agent *agent = obj; 01664 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01665 const char *uri = arg; 01666 01667 return !sip_uri_cmp(agent_pvt->notify_uri, uri) ? CMP_MATCH | CMP_STOP : 0; 01668 }
| static int find_by_subscribe_uri_helper | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1676 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().
01677 { 01678 struct ast_cc_agent *agent = obj; 01679 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01680 const char *uri = arg; 01681 01682 return !sip_uri_cmp(agent_pvt->subscribe_uri, uri) ? CMP_MATCH | CMP_STOP : 0; 01683 }
| 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 8501 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().
08502 { 08503 char totag[128]; 08504 char fromtag[128]; 08505 const char *callid = get_header(req, "Call-ID"); 08506 const char *from = get_header(req, "From"); 08507 const char *to = get_header(req, "To"); 08508 const char *cseq = get_header(req, "Cseq"); 08509 struct sip_pvt *sip_pvt_ptr; 08510 uint32_t seqno; 08511 /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */ 08512 /* get_header always returns non-NULL so we must use ast_strlen_zero() */ 08513 if (ast_strlen_zero(callid) || ast_strlen_zero(to) || 08514 ast_strlen_zero(from) || ast_strlen_zero(cseq) || 08515 (sscanf(cseq, "%30u", &seqno) != 1)) { 08516 08517 /* RFC 3261 section 24.4.1. Send a 400 Bad Request if the request is malformed. */ 08518 if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) { 08519 transmit_response_using_temp(callid, addr, 1, intended_method, 08520 req, "400 Bad Request"); 08521 } 08522 return NULL; /* Invalid packet */ 08523 } 08524 08525 if (sip_cfg.pedanticsipchecking) { 08526 /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy 08527 we need more to identify a branch - so we have to check branch, from 08528 and to tags to identify a call leg. 08529 For Asterisk to behave correctly, you need to turn on pedanticsipchecking 08530 in sip.conf 08531 */ 08532 if (gettag(req, "To", totag, sizeof(totag))) 08533 req->has_to_tag = 1; /* Used in handle_request/response */ 08534 gettag(req, "From", fromtag, sizeof(fromtag)); 08535 08536 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); 08537 08538 /* All messages must always have From: tag */ 08539 if (ast_strlen_zero(fromtag)) { 08540 ast_debug(5, "%s request has no from tag, dropping callid: %s from: %s\n", sip_methods[req->method].text , callid, from ); 08541 return NULL; 08542 } 08543 /* reject requests that must always have a To: tag */ 08544 if (ast_strlen_zero(totag) && (req->method == SIP_ACK || req->method == SIP_BYE || req->method == SIP_INFO )) { 08545 ast_debug(5, "%s must have a to tag. dropping callid: %s from: %s\n", sip_methods[req->method].text , callid, from ); 08546 return NULL; 08547 } 08548 } 08549 08550 if (!sip_cfg.pedanticsipchecking) { 08551 struct sip_pvt tmp_dialog = { 08552 .callid = callid, 08553 }; 08554 sip_pvt_ptr = ao2_t_find(dialogs, &tmp_dialog, OBJ_POINTER, "ao2_find in dialogs"); 08555 if (sip_pvt_ptr) { /* well, if we don't find it-- what IS in there? */ 08556 /* Found the call */ 08557 return sip_pvt_ptr; 08558 } 08559 } else { /* in pedantic mode! -- do the fancy search */ 08560 struct sip_pvt tmp_dialog = { 08561 .callid = callid, 08562 }; 08563 struct match_req_args args = { 0, }; 08564 int found; 08565 struct ao2_iterator *iterator = ao2_t_callback(dialogs, 08566 OBJ_POINTER | OBJ_MULTIPLE, 08567 dialog_find_multiple, 08568 &tmp_dialog, 08569 "pedantic ao2_find in dialogs"); 08570 struct sip_via *via = NULL; 08571 08572 args.method = req->method; 08573 args.callid = NULL; /* we already matched this. */ 08574 args.totag = totag; 08575 args.fromtag = fromtag; 08576 args.seqno = seqno; 08577 08578 /* If this is a Request, set the Via and Authorization header arguments */ 08579 if (req->method != SIP_RESPONSE) { 08580 args.ruri = REQ_OFFSET_TO_STR(req, rlPart2); 08581 via = parse_via(get_header(req, "Via")); 08582 if (via) { 08583 args.viasentby = via->sent_by; 08584 args.viabranch = via->branch; 08585 } 08586 if (!ast_strlen_zero(get_header(req, "Authorization")) || 08587 !ast_strlen_zero(get_header(req, "Proxy-Authorization"))) { 08588 args.authentication_present = 1; 08589 } 08590 } 08591 08592 /* Iterate a list of dialogs already matched by Call-id */ 08593 while (iterator && (sip_pvt_ptr = ao2_iterator_next(iterator))) { 08594 sip_pvt_lock(sip_pvt_ptr); 08595 found = match_req_to_dialog(sip_pvt_ptr, &args); 08596 sip_pvt_unlock(sip_pvt_ptr); 08597 08598 switch (found) { 08599 case SIP_REQ_MATCH: 08600 ao2_iterator_destroy(iterator); 08601 free_via(via); 08602 return sip_pvt_ptr; /* return pvt with ref */ 08603 case SIP_REQ_LOOP_DETECTED: 08604 /* This is likely a forked Request that somehow resulted in us receiving multiple parts of the fork. 08605 * RFC 3261 section 8.2.2.2, Indicate that we want to merge requests by sending a 482 response. */ 08606 transmit_response_using_temp(callid, addr, 1, intended_method, req, "482 (Loop Detected)"); 08607 dialog_unref(sip_pvt_ptr, "pvt did not match incoming SIP msg, unref from search."); 08608 ao2_iterator_destroy(iterator); 08609 free_via(via); 08610 return NULL; 08611 case SIP_REQ_NOT_MATCH: 08612 default: 08613 dialog_unref(sip_pvt_ptr, "pvt did not match incoming SIP msg, unref from search"); 08614 break; 08615 } 08616 } 08617 if (iterator) { 08618 ao2_iterator_destroy(iterator); 08619 } 08620 08621 free_via(via); 08622 } /* end of pedantic mode Request/Reponse to Dialog matching */ 08623 08624 /* See if the method is capable of creating a dialog */ 08625 if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) { 08626 struct sip_pvt *p = NULL; 08627 08628 if (intended_method == SIP_REFER) { 08629 /* We do support REFER, but not outside of a dialog yet */ 08630 transmit_response_using_temp(callid, addr, 1, intended_method, req, "603 Declined (no dialog)"); 08631 08632 /* Ok, time to create a new SIP dialog object, a pvt */ 08633 } else if (!(p = sip_alloc(callid, addr, 1, intended_method, req))) { 08634 /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not 08635 getting a dialog from sip_alloc. 08636 08637 Without a dialog we can't retransmit and handle ACKs and all that, but at least 08638 send an error message. 08639 08640 Sorry, we apologize for the inconvienience 08641 */ 08642 transmit_response_using_temp(callid, addr, 1, intended_method, req, "500 Server internal error"); 08643 ast_debug(4, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n"); 08644 } 08645 return p; /* can be NULL */ 08646 } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) { 08647 /* A method we do not support, let's take it on the volley */ 08648 transmit_response_using_temp(callid, addr, 1, intended_method, req, "501 Method Not Implemented"); 08649 ast_debug(2, "Got a request with unsupported SIP method.\n"); 08650 } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) { 08651 /* This is a request outside of a dialog that we don't know about */ 08652 transmit_response_using_temp(callid, addr, 1, intended_method, req, "481 Call leg/transaction does not exist"); 08653 ast_debug(2, "That's odd... Got a request in unknown dialog. Callid %s\n", callid ? callid : "<unknown>"); 08654 } 08655 /* We do not respond to responses for dialogs that we don't know about, we just drop 08656 the session quickly */ 08657 if (intended_method == SIP_RESPONSE) 08658 ast_debug(2, "That's odd... Got a response on a call we don't know about. Callid %s\n", callid ? callid : "<unknown>"); 08659 08660 return NULL; 08661 }
| 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 13027 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().
13028 { 13029 struct ast_channel *c = obj; 13030 struct sip_pvt *p = data; 13031 int res; 13032 13033 ast_channel_lock(c); 13034 13035 res = (c->pbx && 13036 (!strcasecmp(c->macroexten, p->exten) || !strcasecmp(c->exten, p->exten)) && 13037 (sip_cfg.notifycid == IGNORE_CONTEXT || !strcasecmp(c->context, p->context))); 13038 13039 ast_channel_unlock(c); 13040 13041 return res ? CMP_MATCH | CMP_STOP : 0; 13042 }
| 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 4779 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 5415 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().
05416 { 05417 struct sip_peer *p = NULL; 05418 struct sip_peer tmp_peer; 05419 05420 if (peer) { 05421 ast_copy_string(tmp_peer.name, peer, sizeof(tmp_peer.name)); 05422 p = ao2_t_callback_data(peers, OBJ_POINTER, find_by_name, &tmp_peer, &which_objects, "ao2_find in peers table"); 05423 } else if (addr) { /* search by addr? */ 05424 ast_sockaddr_copy(&tmp_peer.addr, addr); 05425 tmp_peer.flags[0].flags = 0; 05426 tmp_peer.transports = transport; 05427 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); */ 05428 if (!p) { 05429 ast_set_flag(&tmp_peer.flags[0], SIP_INSECURE_PORT); 05430 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); */ 05431 if (p) { 05432 return p; 05433 } 05434 } 05435 } 05436 05437 if (!p && (realtime || devstate_only)) { 05438 p = realtime_peer(peer, addr, devstate_only, which_objects); 05439 if (p) { 05440 switch (which_objects) { 05441 case FINDUSERS: 05442 if (!(p->type & SIP_TYPE_USER)) { 05443 unref_peer(p, "Wrong type of realtime SIP endpoint"); 05444 return NULL; 05445 } 05446 break; 05447 case FINDPEERS: 05448 if (!(p->type & SIP_TYPE_PEER)) { 05449 unref_peer(p, "Wrong type of realtime SIP endpoint"); 05450 return NULL; 05451 } 05452 break; 05453 case FINDALLDEVICES: 05454 break; 05455 } 05456 } 05457 } 05458 05459 return p; 05460 }
| static struct sip_auth * find_realm_authentication | ( | struct sip_auth_container * | credentials, | |
| const char * | realm | |||
| ) | [static, read] |
Definition at line 27791 of file chan_sip.c.
References AST_LIST_TRAVERSE.
Referenced by build_reply_digest().
27792 { 27793 struct sip_auth *auth; 27794 27795 if (credentials) { 27796 AST_LIST_TRAVERSE(&credentials->list, auth, node) { 27797 if (!strcasecmp(auth->realm, realm)) { 27798 break; 27799 } 27800 } 27801 } else { 27802 auth = NULL; 27803 } 27804 27805 return auth; 27806 }
| 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 9013 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().
09014 { 09015 const char *content_type; 09016 const char *content_length; 09017 const char *search; 09018 char *boundary; 09019 unsigned int x; 09020 int boundaryisquoted = FALSE; 09021 int found_application_sdp = FALSE; 09022 int found_end_of_headers = FALSE; 09023 09024 content_length = get_header(req, "Content-Length"); 09025 09026 if (!ast_strlen_zero(content_length)) { 09027 if (sscanf(content_length, "%30u", &x) != 1) { 09028 ast_log(LOG_WARNING, "Invalid Content-Length: %s\n", content_length); 09029 return 0; 09030 } 09031 09032 /* Content-Length of zero means there can't possibly be an 09033 SDP here, even if the Content-Type says there is */ 09034 if (x == 0) 09035 return 0; 09036 } 09037 09038 content_type = get_header(req, "Content-Type"); 09039 09040 /* if the body contains only SDP, this is easy */ 09041 if (!strncasecmp(content_type, "application/sdp", 15)) { 09042 req->sdp_start = 0; 09043 req->sdp_count = req->lines; 09044 return req->lines ? 1 : 0; 09045 } 09046 09047 /* if it's not multipart/mixed, there cannot be an SDP */ 09048 if (strncasecmp(content_type, "multipart/mixed", 15)) 09049 return 0; 09050 09051 /* if there is no boundary marker, it's invalid */ 09052 if ((search = strcasestr(content_type, ";boundary="))) 09053 search += 10; 09054 else if ((search = strcasestr(content_type, "; boundary="))) 09055 search += 11; 09056 else 09057 return 0; 09058 09059 if (ast_strlen_zero(search)) 09060 return 0; 09061 09062 /* If the boundary is quoted with ", remove quote */ 09063 if (*search == '\"') { 09064 search++; 09065 boundaryisquoted = TRUE; 09066 } 09067 09068 /* make a duplicate of the string, with two extra characters 09069 at the beginning */ 09070 boundary = ast_strdupa(search - 2); 09071 boundary[0] = boundary[1] = '-'; 09072 /* Remove final quote */ 09073 if (boundaryisquoted) 09074 boundary[strlen(boundary) - 1] = '\0'; 09075 09076 /* search for the boundary marker, the empty line delimiting headers from 09077 sdp part and the end boundry if it exists */ 09078 09079 for (x = 0; x < (req->lines); x++) { 09080 const char *line = REQ_OFFSET_TO_STR(req, line[x]); 09081 if (!strncasecmp(line, boundary, strlen(boundary))){ 09082 if (found_application_sdp && found_end_of_headers) { 09083 req->sdp_count = (x - 1) - req->sdp_start; 09084 return 1; 09085 } 09086 found_application_sdp = FALSE; 09087 } 09088 if (!strcasecmp(line, "Content-Type: application/sdp")) 09089 found_application_sdp = TRUE; 09090 09091 if (ast_strlen_zero(line)) { 09092 if (found_application_sdp && !found_end_of_headers){ 09093 req->sdp_start = x; 09094 found_end_of_headers = TRUE; 09095 } 09096 } 09097 } 09098 if (found_application_sdp && found_end_of_headers) { 09099 req->sdp_count = x - req->sdp_start; 09100 return TRUE; 09101 } 09102 return FALSE; 09103 }
| static struct ast_cc_agent* find_sip_cc_agent_by_notify_uri | ( | const char *const | uri | ) | [static, read] |
Definition at line 1670 of file chan_sip.c.
References ast_cc_agent_callback(), and find_by_notify_uri_helper().
Referenced by get_destination().
01671 { 01672 struct ast_cc_agent *agent = ast_cc_agent_callback(0, find_by_notify_uri_helper, (char *)uri, "SIP"); 01673 return agent; 01674 }
| static struct ast_cc_agent* find_sip_cc_agent_by_original_callid | ( | struct sip_pvt * | pvt | ) | [static, read] |
Definition at line 1700 of file chan_sip.c.
References ast_cc_agent_callback(), and find_by_callid_helper().
Referenced by add_cc_call_info_to_response().
01701 { 01702 struct ast_cc_agent *agent = ast_cc_agent_callback(0, find_by_callid_helper, pvt, "SIP"); 01703 return agent; 01704 }
| static struct ast_cc_agent* find_sip_cc_agent_by_subscribe_uri | ( | const char *const | uri | ) | [static, read] |
Definition at line 1685 of file chan_sip.c.
References ast_cc_agent_callback(), and find_by_subscribe_uri_helper().
Referenced by handle_cc_subscribe().
01686 { 01687 struct ast_cc_agent *agent = ast_cc_agent_callback(0, find_by_subscribe_uri_helper, (char *)uri, "SIP"); 01688 return agent; 01689 }
| static int find_sip_method | ( | const char * | msg | ) | [static] |
find_sip_method: Find SIP method from header
Definition at line 3505 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().
03506 { 03507 int i, res = 0; 03508 03509 if (ast_strlen_zero(msg)) { 03510 return 0; 03511 } 03512 for (i = 1; i < ARRAY_LEN(sip_methods) && !res; i++) { 03513 if (method_match(i, msg)) { 03514 res = sip_methods[i].id; 03515 } 03516 } 03517 return res; 03518 }
| static int find_sip_monitor_instance_by_subscription_pvt | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1898 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 1904 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 905 of file chan_sip.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, and AST_LIST_UNLOCK.
Referenced by create_epa_entry().
00906 { 00907 const struct epa_backend *backend = NULL; 00908 00909 AST_LIST_LOCK(&epa_static_data_list); 00910 AST_LIST_TRAVERSE(&epa_static_data_list, backend, next) { 00911 if (!strcmp(backend->static_data->name, event_package)) { 00912 break; 00913 } 00914 } 00915 AST_LIST_UNLOCK(&epa_static_data_list); 00916 return backend ? backend->static_data : NULL; 00917 }
| static struct cfsubscription_types * find_subscription_type | ( | enum subscriptiontype | subtype | ) | [static, read] |
Find subscription type in array.
Definition at line 18953 of file chan_sip.c.
References ARRAY_LEN, subscription_types, and type.
Referenced by transmit_state_notify().
18954 { 18955 int i; 18956 18957 for (i = 1; i < ARRAY_LEN(subscription_types); i++) { 18958 if (subscription_types[i].type == subtype) { 18959 return &subscription_types[i]; 18960 } 18961 } 18962 return &subscription_types[0]; 18963 }
| static void free_old_route | ( | struct sip_route * | route | ) | [static] |
Remove route from route list.
Definition at line 14711 of file chan_sip.c.
References ast_free.
Referenced by __sip_destroy(), and build_route().
14712 { 14713 struct sip_route *next; 14714 14715 while (route) { 14716 next = route->next; 14717 ast_free(route); 14718 route = next; 14719 } 14720 }
| 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 20067 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_strlen_zero(), check_sip_domain(), and LOG_WARNING.
20068 { 20069 if (ast_strlen_zero(data)) { 20070 ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n"); 20071 return -1; 20072 } 20073 if (check_sip_domain(data, NULL, 0)) 20074 ast_copy_string(buf, data, len); 20075 else 20076 buf[0] = '\0'; 20077 return 0; 20078 }
| 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 20008 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.
20009 { 20010 struct sip_pvt *p; 20011 const char *content = NULL; 20012 AST_DECLARE_APP_ARGS(args, 20013 AST_APP_ARG(header); 20014 AST_APP_ARG(number); 20015 ); 20016 int i, number, start = 0; 20017 20018 if (ast_strlen_zero(data)) { 20019 ast_log(LOG_WARNING, "This function requires a header name.\n"); 20020 return -1; 20021 } 20022 20023 ast_channel_lock(chan); 20024 if (!IS_SIP_TECH(chan->tech)) { 20025 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 20026 ast_channel_unlock(chan); 20027 return -1; 20028 } 20029 20030 AST_STANDARD_APP_ARGS(args, data); 20031 if (!args.number) { 20032 number = 1; 20033 } else { 20034 sscanf(args.number, "%30d", &number); 20035 if (number < 1) 20036 number = 1; 20037 } 20038 20039 p = chan->tech_pvt; 20040 20041 /* If there is no private structure, this channel is no longer alive */ 20042 if (!p) { 20043 ast_channel_unlock(chan); 20044 return -1; 20045 } 20046 20047 for (i = 0; i < number; i++) 20048 content = __get_header(&p->initreq, args.header, &start); 20049 20050 if (ast_strlen_zero(content)) { 20051 ast_channel_unlock(chan); 20052 return -1; 20053 } 20054 20055 ast_copy_string(buf, content, len); 20056 ast_channel_unlock(chan); 20057 20058 return 0; 20059 }
| 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 20185 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.
20186 { 20187 struct sip_pvt *p; 20188 static int deprecated = 0; 20189 20190 *buf = 0; 20191 20192 if (!data) { 20193 ast_log(LOG_WARNING, "This function requires a parameter name.\n"); 20194 return -1; 20195 } 20196 20197 ast_channel_lock(chan); 20198 if (!IS_SIP_TECH(chan->tech)) { 20199 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 20200 ast_channel_unlock(chan); 20201 return -1; 20202 } 20203 20204 if (deprecated++ % 20 == 0) { 20205 /* Deprecated in 1.6.1 */ 20206 ast_log(LOG_WARNING, "SIPCHANINFO() is deprecated. Please transition to using CHANNEL().\n"); 20207 } 20208 20209 p = chan->tech_pvt; 20210 20211 /* If there is no private structure, this channel is no longer alive */ 20212 if (!p) { 20213 ast_channel_unlock(chan); 20214 return -1; 20215 } 20216 20217 if (!strcasecmp(data, "peerip")) { 20218 ast_copy_string(buf, ast_sockaddr_stringify_addr(&p->sa), len); 20219 } else if (!strcasecmp(data, "recvip")) { 20220 ast_copy_string(buf, ast_sockaddr_stringify_addr(&p->recv), len); 20221 } else if (!strcasecmp(data, "from")) { 20222 ast_copy_string(buf, p->from, len); 20223 } else if (!strcasecmp(data, "uri")) { 20224 ast_copy_string(buf, p->uri, len); 20225 } else if (!strcasecmp(data, "useragent")) { 20226 ast_copy_string(buf, p->useragent, len); 20227 } else if (!strcasecmp(data, "peername")) { 20228 ast_copy_string(buf, p->peername, len); 20229 } else if (!strcasecmp(data, "t38passthrough")) { 20230 if (p->t38.state == T38_DISABLED) { 20231 ast_copy_string(buf, "0", len); 20232 } else { /* T38 is offered or enabled in this call */ 20233 ast_copy_string(buf, "1", len); 20234 } 20235 } else { 20236 ast_channel_unlock(chan); 20237 return -1; 20238 } 20239 ast_channel_unlock(chan); 20240 20241 return 0; 20242 }
| 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 20086 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.
20087 { 20088 struct sip_peer *peer; 20089 char *colname; 20090 20091 if ((colname = strchr(data, ':'))) { /*! \todo Will be deprecated after 1.4 */ 20092 static int deprecation_warning = 0; 20093 *colname++ = '\0'; 20094 if (deprecation_warning++ % 10 == 0) 20095 ast_log(LOG_WARNING, "SIPPEER(): usage of ':' to separate arguments is deprecated. Please use ',' instead.\n"); 20096 } else if ((colname = strchr(data, ','))) 20097 *colname++ = '\0'; 20098 else 20099 colname = "ip"; 20100 20101 if (!(peer = find_peer(data, NULL, TRUE, FINDPEERS, FALSE, 0))) 20102 return -1; 20103 20104 if (!strcasecmp(colname, "ip")) { 20105 ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len); 20106 } else if (!strcasecmp(colname, "port")) { 20107 snprintf(buf, len, "%d", ast_sockaddr_port(&peer->addr)); 20108 } else if (!strcasecmp(colname, "status")) { 20109 peer_status(peer, buf, len); 20110 } else if (!strcasecmp(colname, "language")) { 20111 ast_copy_string(buf, peer->language, len); 20112 } else if (!strcasecmp(colname, "regexten")) { 20113 ast_copy_string(buf, peer->regexten, len); 20114 } else if (!strcasecmp(colname, "limit")) { 20115 snprintf(buf, len, "%d", peer->call_limit); 20116 } else if (!strcasecmp(colname, "busylevel")) { 20117 snprintf(buf, len, "%d", peer->busy_level); 20118 } else if (!strcasecmp(colname, "curcalls")) { 20119 snprintf(buf, len, "%d", peer->inUse); 20120 } else if (!strcasecmp(colname, "maxforwards")) { 20121 snprintf(buf, len, "%d", peer->maxforwards); 20122 } else if (!strcasecmp(colname, "accountcode")) { 20123 ast_copy_string(buf, peer->accountcode, len); 20124 } else if (!strcasecmp(colname, "callgroup")) { 20125 ast_print_group(buf, len, peer->callgroup); 20126 } else if (!strcasecmp(colname, "pickupgroup")) { 20127 ast_print_group(buf, len, peer->pickupgroup); 20128 } else if (!strcasecmp(colname, "useragent")) { 20129 ast_copy_string(buf, peer->useragent, len); 20130 } else if (!strcasecmp(colname, "mailbox")) { 20131 struct ast_str *mailbox_str = ast_str_alloca(512); 20132 peer_mailboxes_to_str(&mailbox_str, peer); 20133 ast_copy_string(buf, ast_str_buffer(mailbox_str), len); 20134 } else if (!strcasecmp(colname, "context")) { 20135 ast_copy_string(buf, peer->context, len); 20136 } else if (!strcasecmp(colname, "expire")) { 20137 snprintf(buf, len, "%d", peer->expire); 20138 } else if (!strcasecmp(colname, "dynamic")) { 20139 ast_copy_string(buf, peer->host_dynamic ? "yes" : "no", len); 20140 } else if (!strcasecmp(colname, "callerid_name")) { 20141 ast_copy_string(buf, peer->cid_name, len); 20142 } else if (!strcasecmp(colname, "callerid_num")) { 20143 ast_copy_string(buf, peer->cid_num, len); 20144 } else if (!strcasecmp(colname, "codecs")) { 20145 ast_getformatname_multiple(buf, len -1, peer->capability); 20146 } else if (!strcasecmp(colname, "encryption")) { 20147 snprintf(buf, len, "%d", ast_test_flag(&peer->flags[1], SIP_PAGE2_USE_SRTP)); 20148 } else if (!strncasecmp(colname, "chanvar[", 8)) { 20149 char *chanvar=colname + 8; 20150 struct ast_variable *v; 20151 20152 chanvar = strsep(&chanvar, "]"); 20153 for (v = peer->chanvars ; v ; v = v->next) { 20154 if (!strcasecmp(v->name, chanvar)) { 20155 ast_copy_string(buf, v->value, len); 20156 } 20157 } 20158 } else if (!strncasecmp(colname, "codec[", 6)) { 20159 char *codecnum; 20160 format_t codec = 0; 20161 20162 codecnum = colname + 6; /* move past the '[' */ 20163 codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */ 20164 if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) { 20165 ast_copy_string(buf, ast_getformatname(codec), len); 20166 } else { 20167 buf[0] = '\0'; 20168 } 20169 } else { 20170 buf[0] = '\0'; 20171 } 20172 20173 unref_peer(peer, "unref_peer from function_sippeer, just before return"); 20174 20175 return 0; 20176 }
| static char * generate_random_string | ( | char * | buf, | |
| size_t | size | |||
| ) | [static] |
Generate 32 byte random string for callid's etc.
Definition at line 7960 of file chan_sip.c.
References ast_random().
Referenced by build_callid_pvt(), build_callid_registry(), construct_pidf_body(), and generate_uri().
07961 { 07962 long val[4]; 07963 int x; 07964 07965 for (x=0; x<4; x++) 07966 val[x] = ast_random(); 07967 snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]); 07968 07969 return buf; 07970 }
| static char* generate_uri | ( | struct sip_pvt * | pvt, | |
| char * | buf, | |||
| size_t | size | |||
| ) | [static] |
Definition at line 7972 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().
07973 { 07974 struct ast_str *uri = ast_str_alloca(size); 07975 ast_str_set(&uri, 0, "%s", pvt->socket.type == SIP_TRANSPORT_TLS ? "sips:" : "sip:"); 07976 /* Here would be a great place to generate a UUID, but for now we'll 07977 * use the handy random string generation function we already have 07978 */ 07979 ast_str_append(&uri, 0, "%s", generate_random_string(buf, size)); 07980 ast_str_append(&uri, 0, "@%s", ast_sockaddr_stringify_remote(&pvt->ourip)); 07981 ast_copy_string(buf, ast_str_buffer(uri), size); 07982 return buf; 07983 }
| int get_address_family_filter | ( | unsigned int | transport | ) | [static] |
Helper for dns resolution to filter by address family.
Definition at line 26182 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().
26183 { 26184 const struct ast_sockaddr *addr = NULL; 26185 26186 if ((transport == SIP_TRANSPORT_UDP) || !transport) { 26187 addr = &bindaddr; 26188 } 26189 else if (transport == SIP_TRANSPORT_TCP) { 26190 addr = &sip_tcp_desc.local_address; 26191 } 26192 else if (transport == SIP_TRANSPORT_TLS) { 26193 addr = &sip_tls_desc.local_address; 26194 } 26195 26196 if (ast_sockaddr_is_ipv6(addr) && ast_sockaddr_is_any(addr)) { 26197 return 0; 26198 } 26199 26200 return addr->ss.ss_family; 26201 }
| 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 16378 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().
16379 { 16380 char tmp[256] = "", *c, *a; 16381 struct sip_request *req = oreq ? oreq : &p->initreq; 16382 struct sip_refer *referdata = NULL; 16383 const char *transfer_context = NULL; 16384 16385 if (!p->refer && !sip_refer_allocate(p)) 16386 return -1; 16387 16388 referdata = p->refer; 16389 16390 ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp)); 16391 c = get_in_brackets(tmp); 16392 16393 if (parse_uri_legacy_check(c, "sip:,sips:", &c, NULL, &a, NULL)) { 16394 ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c); 16395 return -1; 16396 } 16397 16398 SIP_PEDANTIC_DECODE(c); 16399 SIP_PEDANTIC_DECODE(a); 16400 16401 if (!ast_strlen_zero(a)) { 16402 ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain)); 16403 } 16404 16405 if (sip_debug_test_pvt(p)) 16406 ast_verbose("Looking for %s in %s\n", c, p->context); 16407 16408 if (p->owner) /* Mimic behaviour in res_features.c */ 16409 transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT"); 16410 16411 /* By default, use the context in the channel sending the REFER */ 16412 if (ast_strlen_zero(transfer_context)) { 16413 transfer_context = S_OR(p->owner->macrocontext, 16414 S_OR(p->context, sip_cfg.default_context)); 16415 } 16416 if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) { 16417 /* This is a blind transfer */ 16418 ast_debug(1, "SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context); 16419 ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to)); 16420 ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by)); 16421 ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact)); 16422 /* Set new context */ 16423 ast_string_field_set(p, context, transfer_context); 16424 return 0; 16425 } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) { 16426 return 1; 16427 } 16428 16429 return -1; 16430 }
| static char* get_body | ( | struct sip_request * | req, | |
| char * | name, | |||
| char | delimiter | |||
| ) | [static] |
Get a specific line from the message body.
Definition at line 7715 of file chan_sip.c.
References get_body_by_line(), and len().
Referenced by handle_cc_notify(), handle_request_info(), and handle_request_notify().
07716 { 07717 int x; 07718 int len = strlen(name); 07719 char *r; 07720 07721 for (x = 0; x < req->lines; x++) { 07722 r = get_body_by_line(REQ_OFFSET_TO_STR(req, line[x]), name, len, delimiter); 07723 if (r[0] != '\0') 07724 return r; 07725 } 07726 07727 return ""; 07728 }
| 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 7660 of file chan_sip.c.
References ast_skip_blanks().
Referenced by get_body(), and get_sdp_iterate().
07661 { 07662 if (!strncasecmp(line, name, nameLen) && line[nameLen] == delimiter) 07663 return ast_skip_blanks(line + nameLen + 1); 07664 07665 return ""; 07666 }
| static int get_cached_mwi | ( | struct sip_peer * | peer, | |
| int * | new, | |||
| int * | old | |||
| ) | [static] |
Get cached MWI info.
Definition at line 26337 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().
26338 { 26339 struct sip_mailbox *mailbox; 26340 int in_cache; 26341 26342 in_cache = 0; 26343 AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { 26344 struct ast_event *event; 26345 event = ast_event_get_cached(AST_EVENT_MWI, 26346 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox->mailbox, 26347 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, S_OR(mailbox->context, "default"), 26348 AST_EVENT_IE_END); 26349 if (!event) 26350 continue; 26351 *new += ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS); 26352 *old += ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS); 26353 ast_event_destroy(event); 26354 in_cache = 1; 26355 } 26356 26357 return in_cache; 26358 }
| static void get_crypto_attrib | ( | struct sip_srtp * | srtp, | |
| const char ** | a_crypto | |||
| ) | [static] |
Definition at line 11725 of file chan_sip.c.
References ast_log(), LOG_WARNING, sdp_crypto_attrib(), sdp_crypto_offer(), and sdp_crypto_setup().
Referenced by add_sdp().
11726 { 11727 /* Set encryption properties */ 11728 if (srtp) { 11729 if (!srtp->crypto) { 11730 srtp->crypto = sdp_crypto_setup(); 11731 } 11732 if (srtp->crypto && (sdp_crypto_offer(srtp->crypto) >= 0)) { 11733 *a_crypto = sdp_crypto_attrib(srtp->crypto); 11734 } 11735 11736 if (!*a_crypto) { 11737 ast_log(LOG_WARNING, "No SRTP key management enabled\n"); 11738 } 11739 } 11740 }
| 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 15925 of file chan_sip.c.
References ao2_ref, ast_canmatch_extension(), ast_cc_agent_recalling(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_get_hint(), AST_LIST_EMPTY, ast_log(), AST_MAX_EXTENSION, ast_pickup_ext(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_verbose, check_sip_domain(), context, ast_cc_agent::core_id, ast_cc_agent::device_name, 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, 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().
15926 { 15927 char tmp[256] = "", *uri, *unused_password, *domain; 15928 char tmpf[256] = "", *from = NULL; 15929 struct sip_request *req; 15930 char *decoded_uri; 15931 15932 req = oreq; 15933 if (!req) { 15934 req = &p->initreq; 15935 } 15936 15937 /* Find the request URI */ 15938 if (req->rlPart2) 15939 ast_copy_string(tmp, REQ_OFFSET_TO_STR(req, rlPart2), sizeof(tmp)); 15940 15941 uri = ast_strdupa(get_in_brackets(tmp)); 15942 15943 if (parse_uri_legacy_check(uri, "sip:,sips:", &uri, &unused_password, &domain, NULL)) { 15944 ast_log(LOG_WARNING, "Not a SIP header (%s)?\n", uri); 15945 return SIP_GET_DEST_INVALID_URI; 15946 } 15947 15948 SIP_PEDANTIC_DECODE(domain); 15949 SIP_PEDANTIC_DECODE(uri); 15950 15951 extract_host_from_hostport(&domain); 15952 15953 if (ast_strlen_zero(uri)) { 15954 /* 15955 * Either there really was no extension found or the request 15956 * URI had encoded nulls that made the string "empty". Use "s" 15957 * as the extension. 15958 */ 15959 uri = "s"; 15960 } 15961 15962 ast_string_field_set(p, domain, domain); 15963 15964 /* Now find the From: caller ID and name */ 15965 /* XXX Why is this done in get_destination? Isn't it already done? 15966 Needs to be checked 15967 */ 15968 ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf)); 15969 if (!ast_strlen_zero(tmpf)) { 15970 from = get_in_brackets(tmpf); 15971 if (parse_uri_legacy_check(from, "sip:,sips:", &from, NULL, &domain, NULL)) { 15972 ast_log(LOG_WARNING, "Not a SIP header (%s)?\n", from); 15973 return SIP_GET_DEST_INVALID_URI; 15974 } 15975 15976 SIP_PEDANTIC_DECODE(from); 15977 SIP_PEDANTIC_DECODE(domain); 15978 15979 extract_host_from_hostport(&domain); 15980 15981 ast_string_field_set(p, fromdomain, domain); 15982 } 15983 15984 if (!AST_LIST_EMPTY(&domain_list)) { 15985 char domain_context[AST_MAX_EXTENSION]; 15986 15987 domain_context[0] = '\0'; 15988 if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) { 15989 if (!sip_cfg.allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) { 15990 ast_debug(1, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain); 15991 return SIP_GET_DEST_REFUSED; 15992 } 15993 } 15994 /* If we don't have a peer (i.e. we're a guest call), 15995 * overwrite the original context */ 15996 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_HAVEPEERCONTEXT) && !ast_strlen_zero(domain_context)) { 15997 ast_string_field_set(p, context, domain_context); 15998 } 15999 } 16000 16001 /* If the request coming in is a subscription and subscribecontext has been specified use it */ 16002 if (req->method == SIP_SUBSCRIBE && !ast_strlen_zero(p->subscribecontext)) { 16003 ast_string_field_set(p, context, p->subscribecontext); 16004 } 16005 16006 if (sip_debug_test_pvt(p)) { 16007 ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain); 16008 } 16009 16010 /* Since extensions.conf can have unescaped characters, try matching a 16011 * decoded uri in addition to the non-decoded uri. */ 16012 decoded_uri = ast_strdupa(uri); 16013 ast_uri_decode(decoded_uri); 16014 16015 /* If this is a subscription we actually just need to see if a hint exists for the extension */ 16016 if (req->method == SIP_SUBSCRIBE) { 16017 char hint[AST_MAX_EXTENSION]; 16018 int which = 0; 16019 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, uri) || 16020 (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, decoded_uri) && (which = 1))) { 16021 if (!oreq) { 16022 ast_string_field_set(p, exten, which ? decoded_uri : uri); 16023 } 16024 return SIP_GET_DEST_EXTEN_FOUND; 16025 } else { 16026 return SIP_GET_DEST_EXTEN_NOT_FOUND; 16027 } 16028 } else { 16029 struct ast_cc_agent *agent; 16030 /* Check the dialplan for the username part of the request URI, 16031 the domain will be stored in the SIPDOMAIN variable 16032 Return 0 if we have a matching extension */ 16033 if (ast_exists_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from))) { 16034 if (!oreq) { 16035 ast_string_field_set(p, exten, uri); 16036 } 16037 return SIP_GET_DEST_EXTEN_FOUND; 16038 } 16039 if (ast_exists_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from)) 16040 || !strcmp(decoded_uri, ast_pickup_ext())) { 16041 if (!oreq) { 16042 ast_string_field_set(p, exten, decoded_uri); 16043 } 16044 return SIP_GET_DEST_EXTEN_FOUND; 16045 } 16046 if ((agent = find_sip_cc_agent_by_notify_uri(tmp))) { 16047 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 16048 /* This is a CC recall. We can set p's extension to the exten from 16049 * the original INVITE 16050 */ 16051 ast_string_field_set(p, exten, agent_pvt->original_exten); 16052 /* And we need to let the CC core know that the caller is attempting 16053 * his recall 16054 */ 16055 ast_cc_agent_recalling(agent->core_id, "SIP caller %s is attempting recall", 16056 agent->device_name); 16057 if (cc_recall_core_id) { 16058 *cc_recall_core_id = agent->core_id; 16059 } 16060 ao2_ref(agent, -1); 16061 return SIP_GET_DEST_EXTEN_FOUND; 16062 } 16063 } 16064 16065 if (ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) 16066 && (ast_canmatch_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from)) 16067 || ast_canmatch_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from)) 16068 || !strncmp(decoded_uri, ast_pickup_ext(), strlen(decoded_uri)))) { 16069 /* Overlap dialing is enabled and we need more digits to match an extension. */ 16070 return SIP_GET_DEST_EXTEN_MATCHMORE; 16071 } 16072 16073 return SIP_GET_DEST_EXTEN_NOT_FOUND; 16074 }
| static int get_domain | ( | const char * | str, | |
| char * | domain, | |||
| int | len | |||
| ) | [static] |
Extract domain from SIP To/From header.
Definition at line 11220 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_strlen_zero(), get_in_brackets(), and LOG_WARNING.
Referenced by get_realm().
11221 { 11222 char tmpf[256]; 11223 char *a, *from; 11224 11225 *domain = '\0'; 11226 ast_copy_string(tmpf, str, sizeof(tmpf)); 11227 from = get_in_brackets(tmpf); 11228 if (!ast_strlen_zero(from)) { 11229 if (strncasecmp(from, "sip:", 4)) { 11230 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from); 11231 return -1; 11232 } 11233 from += 4; 11234 } else 11235 from = NULL; 11236 11237 if (from) { 11238 int bracket = 0; 11239 11240 /* Strip any params or options from user */ 11241 if ((a = strchr(from, ';'))) 11242 *a = '\0'; 11243 /* Strip port from domain if present */ 11244 for (a = from; *a != '\0'; ++a) { 11245 if (*a == ':' && bracket == 0) { 11246 *a = '\0'; 11247 break; 11248 } else if (*a == '[') { 11249 ++bracket; 11250 } else if (*a == ']') { 11251 --bracket; 11252 } 11253 } 11254 if ((a = strchr(from, '@'))) { 11255 *a = '\0'; 11256 ast_copy_string(domain, a + 1, len); 11257 } else 11258 ast_copy_string(domain, from, len); 11259 } 11260 11261 return ast_strlen_zero(domain); 11262 }
| static struct event_state_compositor* get_esc | ( | const char *const | event_package | ) | [static, read] |
Definition at line 999 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().
00999 { 01000 int i; 01001 for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) { 01002 if (!strcasecmp(event_package, event_state_compositors[i].name)) { 01003 return &event_state_compositors[i]; 01004 } 01005 } 01006 return NULL; 01007 }
| static struct sip_esc_entry* get_esc_entry | ( | const char * | entity_tag, | |
| struct event_state_compositor * | esc | |||
| ) | [static, read] |
Definition at line 1009 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().
01009 { 01010 struct sip_esc_entry *entry; 01011 struct sip_esc_entry finder; 01012 01013 ast_copy_string(finder.entity_tag, entity_tag, sizeof(finder.entity_tag)); 01014 01015 entry = ao2_find(esc->compositor, &finder, OBJ_POINTER); 01016 01017 return entry; 01018 }
| static const char * get_header | ( | const struct sip_request * | req, | |
| const char * | name | |||
| ) | [static] |
Get header from SIP request.
Definition at line 7809 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_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(), sip_tls_read(), transmit_fake_auth_response(), transmit_refer(), transmit_response_with_auth(), transmit_response_with_sdp(), transmit_response_with_t38_sdp(), and transmit_state_notify().
07810 { 07811 int start = 0; 07812 return __get_header(req, name, &start); 07813 }
| static struct ast_variable * get_insecure_variable_from_config | ( | struct ast_config * | config | ) | [static, read] |
Definition at line 5044 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().
05045 { 05046 struct ast_variable *var = NULL; 05047 struct ast_flags flags = {0}; 05048 char *cat = NULL; 05049 const char *insecure; 05050 while ((cat = ast_category_browse(cfg, cat))) { 05051 insecure = ast_variable_retrieve(cfg, cat, "insecure"); 05052 set_insecure_flags(&flags, insecure, -1); 05053 if (ast_test_flag(&flags, SIP_INSECURE_PORT)) { 05054 var = ast_category_root(cfg, cat); 05055 break; 05056 } 05057 } 05058 return var; 05059 }
| static struct ast_variable* get_insecure_variable_from_sippeers | ( | const char * | column, | |
| const char * | value | |||
| ) | [static, read] |
Definition at line 5061 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().
05062 { 05063 struct ast_config *peerlist; 05064 struct ast_variable *var = NULL; 05065 if ((peerlist = ast_load_realtime_multientry("sippeers", column, value, "insecure LIKE", "%port%", SENTINEL))) { 05066 if ((var = get_insecure_variable_from_config(peerlist))) { 05067 /* Must clone, because var will get freed along with 05068 * peerlist. */ 05069 var = ast_variables_dup(var); 05070 } 05071 ast_config_destroy(peerlist); 05072 } 05073 return var; 05074 }
| static struct ast_variable* get_insecure_variable_from_sipregs | ( | const char * | column, | |
| const char * | value, | |||
| struct ast_variable ** | var | |||
| ) | [static, read] |
Definition at line 5081 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().
05082 { 05083 struct ast_variable *varregs = NULL; 05084 struct ast_config *regs, *peers; 05085 char *regscat; 05086 const char *regname; 05087 05088 if (!(regs = ast_load_realtime_multientry("sipregs", column, value, SENTINEL))) { 05089 return NULL; 05090 } 05091 05092 /* Load *all* peers that are probably insecure=port */ 05093 if (!(peers = ast_load_realtime_multientry("sippeers", "insecure LIKE", "%port%", SENTINEL))) { 05094 ast_config_destroy(regs); 05095 return NULL; 05096 } 05097 05098 /* Loop over the sipregs that match IP address and attempt to find an 05099 * insecure=port match to it in sippeers. */ 05100 regscat = NULL; 05101 while ((regscat = ast_category_browse(regs, regscat)) && (regname = ast_variable_retrieve(regs, regscat, "name"))) { 05102 char *peerscat; 05103 const char *peername; 05104 05105 peerscat = NULL; 05106 while ((peerscat = ast_category_browse(peers, peerscat)) && (peername = ast_variable_retrieve(peers, peerscat, "name"))) { 05107 if (!strcasecmp(regname, peername)) { 05108 /* Ensure that it really is insecure=port and 05109 * not something else. */ 05110 const char *insecure = ast_variable_retrieve(peers, peerscat, "insecure"); 05111 struct ast_flags flags = {0}; 05112 set_insecure_flags(&flags, insecure, -1); 05113 if (ast_test_flag(&flags, SIP_INSECURE_PORT)) { 05114 /* ENOMEM checks till the bitter end. */ 05115 if ((varregs = ast_variables_dup(ast_category_root(regs, regscat)))) { 05116 if (!(*var = ast_variables_dup(ast_category_root(peers, peerscat)))) { 05117 ast_variables_destroy(varregs); 05118 varregs = NULL; 05119 } 05120 } 05121 goto done; 05122 } 05123 } 05124 } 05125 } 05126 05127 done: 05128 ast_config_destroy(regs); 05129 ast_config_destroy(peers); 05130 return varregs; 05131 }
| 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 9138 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().
09139 { 09140 const char *m; 09141 const char *c; 09142 int miterator = req->sdp_start; 09143 int citerator = req->sdp_start; 09144 int x = 0; 09145 int numberofports; 09146 int len; 09147 int af; 09148 char proto[4], host[258] = ""; /*Initialize to empty so we will know if we have any input */ 09149 09150 c = get_sdp_iterate(&citerator, req, "c"); 09151 if (sscanf(c, "IN %3s %256s", proto, host) != 2) { 09152 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 09153 /* Continue since there may be a valid host in a c= line specific to the audio stream */ 09154 } 09155 /* We only want the m and c lines for audio */ 09156 for (m = get_sdp_iterate(&miterator, req, "m"); !ast_strlen_zero(m); m = get_sdp_iterate(&miterator, req, "m")) { 09157 if ((media == SDP_AUDIO && ((sscanf(m, "audio %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 09158 (sscanf(m, "audio %30u RTP/AVP %n", &x, &len) == 1 && len > 0))) || 09159 (media == SDP_VIDEO && ((sscanf(m, "video %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 09160 (sscanf(m, "video %30u RTP/AVP %n", &x, &len) == 1 && len > 0)))) { 09161 /* See if there's a c= line for this media stream. 09162 * XXX There is no guarantee that we'll be grabbing the c= line for this 09163 * particular media stream here. However, this is the same logic used in process_sdp. 09164 */ 09165 c = get_sdp_iterate(&citerator, req, "c"); 09166 if (!ast_strlen_zero(c)) { 09167 sscanf(c, "IN %3s %256s", proto, host); 09168 } 09169 break; 09170 } 09171 } 09172 09173 if (!strcmp("IP4", proto)) { 09174 af = AF_INET; 09175 } else if (!strcmp("IP6", proto)) { 09176 af = AF_INET6; 09177 } else { 09178 ast_log(LOG_WARNING, "Unknown protocol '%s'.\n", proto); 09179 return -1; 09180 } 09181 09182 if (ast_strlen_zero(host) || x == 0) { 09183 ast_log(LOG_WARNING, "Failed to read an alternate host or port in SDP. Expect %s problems\n", media == SDP_AUDIO ? "audio" : "video"); 09184 return -1; 09185 } 09186 09187 if (ast_sockaddr_resolve_first_af(addr, host, 0, af)) { 09188 ast_log(LOG_WARNING, "Could not look up IP address of alternate hostname. Expect %s problems\n", media == SDP_AUDIO? "audio" : "video"); 09189 return -1; 09190 } 09191 09192 return 0; 09193 }
| 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 16885 of file chan_sip.c.
Referenced by handle_request_info(), handle_request_notify(), and receive_message().
16886 { 16887 int x; 16888 int linelen; 16889 16890 buf[0] = '\0'; 16891 --len; /* reserve strncat null */ 16892 for (x = 0; len && x < req->lines; ++x) { 16893 const char *line = REQ_OFFSET_TO_STR(req, line[x]); 16894 strncat(buf, line, len); /* safe */ 16895 linelen = strlen(buf); 16896 buf += linelen; 16897 len -= linelen; 16898 if (len) { 16899 strcat(buf, "\n"); /* safe */ 16900 ++buf; 16901 --len; 16902 } 16903 } 16904 return 0; 16905 }
| static const char * get_name_from_variable | ( | const struct ast_variable * | var | ) | [static] |
Definition at line 5133 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().
05134 { 05135 /* Don't expect this to return non-NULL. Both NULL and empty 05136 * values can cause the option to get removed from the variable 05137 * list. This is called on ast_variables gotten from both 05138 * ast_load_realtime and ast_load_realtime_multientry. 05139 * - ast_load_realtime removes options with empty values 05140 * - ast_load_realtime_multientry does not! 05141 * For consistent behaviour, we check for the empty name and 05142 * return NULL instead. */ 05143 const struct ast_variable *tmp; 05144 for (tmp = var; tmp; tmp = tmp->next) { 05145 if (!strcasecmp(tmp->name, "name")) { 05146 if (!ast_strlen_zero(tmp->value)) { 05147 return tmp->value; 05148 } 05149 break; 05150 } 05151 } 05152 return NULL; 05153 }
| 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 11632 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().
11636 { 11637 int use_externip = 0; 11638 11639 /* First, get our address */ 11640 ast_rtp_instance_get_local_address(p->rtp, addr); 11641 if (p->vrtp) { 11642 ast_rtp_instance_get_local_address(p->vrtp, vaddr); 11643 } 11644 if (p->trtp) { 11645 ast_rtp_instance_get_local_address(p->trtp, taddr); 11646 } 11647 11648 /* If our real IP differs from the local address returned by the RTP engine, use it. */ 11649 /* The premise is that if we are already using that IP to communicate with the client, */ 11650 /* we should be using it for RTP too. */ 11651 use_externip = ast_sockaddr_cmp_addr(&p->ourip, addr); 11652 11653 /* Now, try to figure out where we want them to send data */ 11654 /* Is this a re-invite to move the media out, then use the original offer from caller */ 11655 if (!ast_sockaddr_isnull(&p->redirip)) { /* If we have a redirection IP, use it */ 11656 ast_sockaddr_copy(dest, &p->redirip); 11657 } else { 11658 /* 11659 * Audio Destination IP: 11660 * 11661 * 1. Specifically configured media address. 11662 * 2. Local address as specified by the RTP engine. 11663 * 3. The local IP as defined by chan_sip. 11664 * 11665 * Audio Destination Port: 11666 * 11667 * 1. Provided by the RTP engine. 11668 */ 11669 ast_sockaddr_copy(dest, 11670 !ast_sockaddr_isnull(&media_address) ? &media_address : 11671 !ast_sockaddr_is_any(addr) && !use_externip ? addr : 11672 &p->ourip); 11673 ast_sockaddr_set_port(dest, ast_sockaddr_port(addr)); 11674 } 11675 11676 if (needvideo) { 11677 /* Determine video destination */ 11678 if (!ast_sockaddr_isnull(&p->vredirip)) { 11679 ast_sockaddr_copy(vdest, &p->vredirip); 11680 } else { 11681 /* 11682 * Video Destination IP: 11683 * 11684 * 1. Specifically configured media address. 11685 * 2. Local address as specified by the RTP engine. 11686 * 3. The local IP as defined by chan_sip. 11687 * 11688 * Video Destination Port: 11689 * 11690 * 1. Provided by the RTP engine. 11691 */ 11692 ast_sockaddr_copy(vdest, 11693 !ast_sockaddr_isnull(&media_address) ? &media_address : 11694 !ast_sockaddr_is_any(vaddr) && !use_externip ? vaddr : 11695 &p->ourip); 11696 ast_sockaddr_set_port(vdest, ast_sockaddr_port(vaddr)); 11697 } 11698 } 11699 11700 if (needtext) { 11701 /* Determine text destination */ 11702 if (!ast_sockaddr_isnull(&p->tredirip)) { 11703 ast_sockaddr_copy(tdest, &p->tredirip); 11704 } else { 11705 /* 11706 * Text Destination IP: 11707 * 11708 * 1. Specifically configured media address. 11709 * 2. Local address as specified by the RTP engine. 11710 * 3. The local IP as defined by chan_sip. 11711 * 11712 * Text Destination Port: 11713 * 11714 * 1. Provided by the RTP engine. 11715 */ 11716 ast_sockaddr_copy(tdest, 11717 !ast_sockaddr_isnull(&media_address) ? &media_address : 11718 !ast_sockaddr_is_any(taddr) && !use_externip ? taddr : 11719 &p->ourip); 11720 ast_sockaddr_set_port(tdest, ast_sockaddr_port(taddr)); 11721 } 11722 } 11723 }
| 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 15632 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().
15633 { 15634 char pai[256]; 15635 char privacy[64]; 15636 char *cid_num = NULL; 15637 char *cid_name = NULL; 15638 char emptyname[1] = ""; 15639 int callingpres = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 15640 char *uri = NULL; 15641 int is_anonymous = 0, do_update = 1, no_name = 0; 15642 15643 ast_copy_string(pai, get_header(req, "P-Asserted-Identity"), sizeof(pai)); 15644 15645 if (ast_strlen_zero(pai)) { 15646 return 0; 15647 } 15648 15649 /* use the reqresp_parser function get_name_and_number*/ 15650 if (get_name_and_number(pai, &cid_name, &cid_num)) { 15651 return 0; 15652 } 15653 15654 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(cid_num)) { 15655 ast_shrink_phone_number(cid_num); 15656 } 15657 15658 uri = get_in_brackets(pai); 15659 if (!strncasecmp(uri, "sip:anonymous@anonymous.invalid", 31)) { 15660 callingpres = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 15661 /*XXX Assume no change in cid_num. Perhaps it should be 15662 * blanked? 15663 */ 15664 ast_free(cid_num); 15665 is_anonymous = 1; 15666 cid_num = (char *)p->cid_num; 15667 } 15668 15669 ast_copy_string(privacy, get_header(req, "Privacy"), sizeof(privacy)); 15670 if (!ast_strlen_zero(privacy) && !strncmp(privacy, "id", 2)) { 15671 callingpres = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 15672 } 15673 if (!cid_name) { 15674 no_name = 1; 15675 cid_name = (char *)emptyname; 15676 } 15677 /* Only return true if the supplied caller id is different */ 15678 if (!strcasecmp(p->cid_num, cid_num) && !strcasecmp(p->cid_name, cid_name) && p->callingpres == callingpres) { 15679 do_update = 0; 15680 } else { 15681 15682 ast_string_field_set(p, cid_num, cid_num); 15683 ast_string_field_set(p, cid_name, cid_name); 15684 p->callingpres = callingpres; 15685 15686 if (p->owner) { 15687 ast_set_callerid(p->owner, cid_num, cid_name, NULL); 15688 p->owner->caller.id.name.presentation = callingpres; 15689 p->owner->caller.id.number.presentation = callingpres; 15690 } 15691 } 15692 15693 /* get_name_and_number allocates memory for cid_num and cid_name so we have to free it */ 15694 if (!is_anonymous) { 15695 ast_free(cid_num); 15696 } 15697 if (!no_name) { 15698 ast_free(cid_name); 15699 } 15700 15701 return do_update; 15702 }
| 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 15825 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().
15826 { 15827 char tmp[256], *exten, *rexten, *rdomain, *rname = NULL; 15828 char *params, *reason_param = NULL; 15829 struct sip_request *req; 15830 15831 req = oreq ? oreq : &p->initreq; 15832 15833 ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp)); 15834 if (ast_strlen_zero(tmp)) 15835 return -1; 15836 15837 if ((params = strchr(tmp, '>'))) { 15838 params = strchr(params, ';'); 15839 } 15840 15841 exten = get_in_brackets(tmp); 15842 if (!strncasecmp(exten, "sip:", 4)) { 15843 exten += 4; 15844 } else if (!strncasecmp(exten, "sips:", 5)) { 15845 exten += 5; 15846 } else { 15847 ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", exten); 15848 return -1; 15849 } 15850 15851 /* Get diversion-reason param if present */ 15852 if (params) { 15853 *params = '\0'; /* Cut off parameters */ 15854 params++; 15855 while (*params == ';' || *params == ' ') 15856 params++; 15857 /* Check if we have a reason parameter */ 15858 if ((reason_param = strcasestr(params, "reason="))) { 15859 char *end; 15860 reason_param+=7; 15861 if ((end = strchr(reason_param, ';'))) { 15862 *end = '\0'; 15863 } 15864 /* Remove enclosing double-quotes */ 15865 if (*reason_param == '"') 15866 reason_param = ast_strip_quoted(reason_param, "\"", "\""); 15867 if (!ast_strlen_zero(reason_param)) { 15868 sip_set_redirstr(p, reason_param); 15869 if (p->owner) { 15870 pbx_builtin_setvar_helper(p->owner, "__PRIREDIRECTREASON", p->redircause); 15871 pbx_builtin_setvar_helper(p->owner, "__SIPREDIRECTREASON", reason_param); 15872 } 15873 } 15874 } 15875 } 15876 15877 rdomain = exten; 15878 rexten = strsep(&rdomain, "@"); /* trim anything after @ */ 15879 if (p->owner) 15880 pbx_builtin_setvar_helper(p->owner, "__SIPRDNISDOMAIN", rdomain); 15881 15882 if (sip_debug_test_pvt(p)) 15883 ast_verbose("RDNIS for this call is %s (reason %s)\n", exten, S_OR(reason_param, "")); 15884 15885 /*ast_string_field_set(p, rdnis, rexten);*/ 15886 15887 if (*tmp == '\"') { 15888 char *end_quote; 15889 rname = tmp + 1; 15890 end_quote = strchr(rname, '\"'); 15891 if (end_quote) { 15892 *end_quote = '\0'; 15893 } 15894 } 15895 15896 if (number) { 15897 *number = ast_strdup(rexten); 15898 } 15899 15900 if (name && rname) { 15901 *name = ast_strdup(rname); 15902 } 15903 15904 if (reason && !ast_strlen_zero(reason_param)) { 15905 *reason = sip_reason_str_to_code(reason_param); 15906 } 15907 15908 return 0; 15909 }
| 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 11268 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().
11269 { 11270 char domain[MAXHOSTNAMELEN]; 11271 11272 if (!ast_strlen_zero(p->realm)) 11273 return; 11274 11275 if (sip_cfg.domainsasrealm && 11276 !AST_LIST_EMPTY(&domain_list)) 11277 { 11278 /* Check From header first */ 11279 if (!get_domain(get_header(req, "From"), domain, sizeof(domain))) { 11280 if (check_sip_domain(domain, NULL, 0)) { 11281 ast_string_field_set(p, realm, domain); 11282 return; 11283 } 11284 } 11285 /* Check To header */ 11286 if (!get_domain(get_header(req, "To"), domain, sizeof(domain))) { 11287 if (check_sip_domain(domain, NULL, 0)) { 11288 ast_string_field_set(p, realm, domain); 11289 return; 11290 } 11291 } 11292 } 11293 11294 /* Use default realm from config file */ 11295 ast_string_field_set(p, realm, sip_cfg.realm); 11296 }
| 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 16171 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().
16172 { 16173 16174 const char *p_referred_by = NULL; 16175 char *h_refer_to = NULL; 16176 char *h_referred_by = NULL; 16177 char *refer_to; 16178 const char *p_refer_to; 16179 char *referred_by_uri = NULL; 16180 char *ptr; 16181 struct sip_request *req = NULL; 16182 const char *transfer_context = NULL; 16183 struct sip_refer *referdata; 16184 16185 16186 req = outgoing_req; 16187 referdata = transferer->refer; 16188 16189 if (!req) { 16190 req = &transferer->initreq; 16191 } 16192 16193 p_refer_to = get_header(req, "Refer-To"); 16194 if (ast_strlen_zero(p_refer_to)) { 16195 ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n"); 16196 return -2; /* Syntax error */ 16197 } 16198 h_refer_to = ast_strdupa(p_refer_to); 16199 refer_to = get_in_brackets(h_refer_to); 16200 if (!strncasecmp(refer_to, "sip:", 4)) { 16201 refer_to += 4; /* Skip sip: */ 16202 } else if (!strncasecmp(refer_to, "sips:", 5)) { 16203 refer_to += 5; 16204 } else { 16205 ast_log(LOG_WARNING, "Can't transfer to non-sip: URI. (Refer-to: %s)?\n", refer_to); 16206 return -3; 16207 } 16208 16209 /* Get referred by header if it exists */ 16210 p_referred_by = get_header(req, "Referred-By"); 16211 16212 /* Give useful transfer information to the dialplan */ 16213 if (transferer->owner) { 16214 struct ast_channel *peer = ast_bridged_channel(transferer->owner); 16215 if (peer) { 16216 pbx_builtin_setvar_helper(peer, "SIPREFERRINGCONTEXT", transferer->context); 16217 pbx_builtin_setvar_helper(peer, "SIPREFERREDBYHDR", p_referred_by); 16218 } 16219 } 16220 16221 if (!ast_strlen_zero(p_referred_by)) { 16222 char *lessthan; 16223 h_referred_by = ast_strdupa(p_referred_by); 16224 16225 /* Store referrer's caller ID name */ 16226 ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name)); 16227 if ((lessthan = strchr(referdata->referred_by_name, '<'))) { 16228 *(lessthan - 1) = '\0'; /* Space */ 16229 } 16230 16231 referred_by_uri = get_in_brackets(h_referred_by); 16232 16233 if (!strncasecmp(referred_by_uri, "sip:", 4)) { 16234 referred_by_uri += 4; /* Skip sip: */ 16235 } else if (!strncasecmp(referred_by_uri, "sips:", 5)) { 16236 referred_by_uri += 5; /* Skip sips: */ 16237 } else { 16238 ast_log(LOG_WARNING, "Huh? Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri); 16239 referred_by_uri = NULL; 16240 } 16241 } 16242 16243 /* Check for arguments in the refer_to header */ 16244 if ((ptr = strcasestr(refer_to, "replaces="))) { 16245 char *to = NULL, *from = NULL; 16246 16247 /* This is an attended transfer */ 16248 referdata->attendedtransfer = 1; 16249 ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid)); 16250 ast_uri_decode(referdata->replaces_callid); 16251 if ((ptr = strchr(referdata->replaces_callid, ';'))) /* Find options */ { 16252 *ptr++ = '\0'; 16253 } 16254 16255 if (ptr) { 16256 /* Find the different tags before we destroy the string */ 16257 to = strcasestr(ptr, "to-tag="); 16258 from = strcasestr(ptr, "from-tag="); 16259 } 16260 16261 /* Grab the to header */ 16262 if (to) { 16263 ptr = to + 7; 16264 if ((to = strchr(ptr, '&'))) { 16265 *to = '\0'; 16266 } 16267 if ((to = strchr(ptr, ';'))) { 16268 *to = '\0'; 16269 } 16270 ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag)); 16271 } 16272 16273 if (from) { 16274 ptr = from + 9; 16275 if ((to = strchr(ptr, '&'))) { 16276 *to = '\0'; 16277 } 16278 if ((to = strchr(ptr, ';'))) { 16279 *to = '\0'; 16280 } 16281 ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag)); 16282 } 16283 16284 if (!strcmp(referdata->replaces_callid, transferer->callid) && 16285 (!sip_cfg.pedanticsipchecking || 16286 (!strcmp(referdata->replaces_callid_fromtag, transferer->theirtag) && 16287 !strcmp(referdata->replaces_callid_totag, transferer->tag)))) { 16288 ast_log(LOG_WARNING, "Got an attempt to replace own Call-ID on %s\n", transferer->callid); 16289 return -4; 16290 } 16291 16292 if (!sip_cfg.pedanticsipchecking) { 16293 ast_debug(2, "Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid ); 16294 } else { 16295 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>" ); 16296 } 16297 } 16298 16299 if ((ptr = strchr(refer_to, '@'))) { /* Separate domain */ 16300 char *urioption = NULL, *domain; 16301 int bracket = 0; 16302 *ptr++ = '\0'; 16303 16304 if ((urioption = strchr(ptr, ';'))) { /* Separate urioptions */ 16305 *urioption++ = '\0'; 16306 } 16307 16308 domain = ptr; 16309 16310 /* Remove :port */ 16311 for (; *ptr != '\0'; ++ptr) { 16312 if (*ptr == ':' && bracket == 0) { 16313 *ptr = '\0'; 16314 break; 16315 } else if (*ptr == '[') { 16316 ++bracket; 16317 } else if (*ptr == ']') { 16318 --bracket; 16319 } 16320 } 16321 16322 SIP_PEDANTIC_DECODE(domain); 16323 SIP_PEDANTIC_DECODE(urioption); 16324 16325 /* Save the domain for the dial plan */ 16326 ast_copy_string(referdata->refer_to_domain, domain, sizeof(referdata->refer_to_domain)); 16327 if (urioption) { 16328 ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption)); 16329 } 16330 } 16331 16332 if ((ptr = strchr(refer_to, ';'))) /* Remove options */ 16333 *ptr = '\0'; 16334 16335 SIP_PEDANTIC_DECODE(refer_to); 16336 ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to)); 16337 16338 if (referred_by_uri) { 16339 if ((ptr = strchr(referred_by_uri, ';'))) /* Remove options */ 16340 *ptr = '\0'; 16341 SIP_PEDANTIC_DECODE(referred_by_uri); 16342 ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by)); 16343 } else { 16344 referdata->referred_by[0] = '\0'; 16345 } 16346 16347 /* Determine transfer context */ 16348 if (transferer->owner) /* Mimic behaviour in res_features.c */ 16349 transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT"); 16350 16351 /* By default, use the context in the channel sending the REFER */ 16352 if (ast_strlen_zero(transfer_context)) { 16353 transfer_context = S_OR(transferer->owner->macrocontext, 16354 S_OR(transferer->context, sip_cfg.default_context)); 16355 } 16356 16357 ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context)); 16358 16359 /* Either an existing extension or the parking extension */ 16360 if (referdata->attendedtransfer || ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) { 16361 if (sip_debug_test_pvt(transferer)) { 16362 ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri); 16363 } 16364 /* We are ready to transfer to the extension */ 16365 return 0; 16366 } 16367 if (sip_debug_test_pvt(transferer)) 16368 ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context); 16369 16370 /* Failure, we can't find this extension */ 16371 return -1; 16372 }
| 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 15708 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().
15709 { 15710 char tmp[256]; 15711 struct sip_request *req; 15712 char *cid_num = ""; 15713 char *cid_name = ""; 15714 int callingpres = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 15715 char *privacy = ""; 15716 char *screen = ""; 15717 char *start, *end; 15718 15719 if (!ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) 15720 return 0; 15721 req = oreq; 15722 if (!req) 15723 req = &p->initreq; 15724 ast_copy_string(tmp, get_header(req, "Remote-Party-ID"), sizeof(tmp)); 15725 if (ast_strlen_zero(tmp)) { 15726 return get_pai(p, req); 15727 } 15728 15729 /* 15730 * RPID is not: 15731 * rpid = (name-addr / addr-spec) *(SEMI rpi-token) 15732 * But it is: 15733 * rpid = [display-name] LAQUOT addr-spec RAQUOT *(SEMI rpi-token) 15734 * Ergo, calling parse_name_andor_addr() on it wouldn't be 15735 * correct because that would allow addr-spec style too. 15736 */ 15737 start = tmp; 15738 /* Quoted (note that we're not dealing with escapes properly) */ 15739 if (*start == '"') { 15740 *start++ = '\0'; 15741 end = strchr(start, '"'); 15742 if (!end) 15743 return 0; 15744 *end++ = '\0'; 15745 cid_name = start; 15746 start = ast_skip_blanks(end); 15747 /* Unquoted */ 15748 } else { 15749 cid_name = start; 15750 start = end = strchr(start, '<'); 15751 if (!start) { 15752 return 0; 15753 } 15754 /* trim blanks if there are any. the mandatory NUL is done below */ 15755 while (--end >= cid_name && *end < 33) { 15756 *end = '\0'; 15757 } 15758 } 15759 15760 if (*start != '<') 15761 return 0; 15762 *start++ = '\0'; 15763 end = strchr(start, '@'); 15764 if (!end) 15765 return 0; 15766 *end++ = '\0'; 15767 if (strncasecmp(start, "sip:", 4)) 15768 return 0; 15769 cid_num = start + 4; 15770 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(cid_num)) 15771 ast_shrink_phone_number(cid_num); 15772 start = end; 15773 15774 end = strchr(start, '>'); 15775 if (!end) 15776 return 0; 15777 *end++ = '\0'; 15778 if (*end) { 15779 start = end; 15780 if (*start != ';') 15781 return 0; 15782 *start++ = '\0'; 15783 while (!ast_strlen_zero(start)) { 15784 end = strchr(start, ';'); 15785 if (end) 15786 *end++ = '\0'; 15787 if (!strncasecmp(start, "privacy=", 8)) 15788 privacy = start + 8; 15789 else if (!strncasecmp(start, "screen=", 7)) 15790 screen = start + 7; 15791 start = end; 15792 } 15793 15794 if (!strcasecmp(privacy, "full")) { 15795 if (!strcasecmp(screen, "yes")) 15796 callingpres = AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN; 15797 else if (!strcasecmp(screen, "no")) 15798 callingpres = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 15799 } else { 15800 if (!strcasecmp(screen, "yes")) 15801 callingpres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 15802 else if (!strcasecmp(screen, "no")) 15803 callingpres = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 15804 } 15805 } 15806 15807 /* Only return true if the supplied caller id is different */ 15808 if (!strcasecmp(p->cid_num, cid_num) && !strcasecmp(p->cid_name, cid_name) && p->callingpres == callingpres) 15809 return 0; 15810 15811 ast_string_field_set(p, cid_num, cid_num); 15812 ast_string_field_set(p, cid_name, cid_name); 15813 p->callingpres = callingpres; 15814 15815 if (p->owner) { 15816 ast_set_callerid(p->owner, cid_num, cid_name, NULL); 15817 p->owner->caller.id.name.presentation = callingpres; 15818 p->owner->caller.id.number.presentation = callingpres; 15819 } 15820 15821 return 1; 15822 }
| 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 7672 of file chan_sip.c.
References get_body_by_line(), and len().
Referenced by get_ip_and_port_from_sdp(), and process_sdp().
07673 { 07674 int len = strlen(name); 07675 07676 while (*start < (req->sdp_start + req->sdp_count)) { 07677 const char *r = get_body_by_line(REQ_OFFSET_TO_STR(req, line[(*start)++]), name, len, '='); 07678 if (r[0] != '\0') 07679 return r; 07680 } 07681 07682 /* if the line was not found, ensure that *start points past the SDP */ 07683 (*start)++; 07684 07685 return ""; 07686 }
| 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 7693 of file chan_sip.c.
References ast_skip_blanks(), and type.
Referenced by process_sdp().
07694 { 07695 char type = '\0'; 07696 const char *line = NULL; 07697 07698 if (stop > (req->sdp_start + req->sdp_count)) { 07699 stop = req->sdp_start + req->sdp_count; 07700 } 07701 07702 while (*start < stop) { 07703 line = REQ_OFFSET_TO_STR(req, line[(*start)++]); 07704 if (line[1] == '=') { 07705 type = line[0]; 07706 *value = ast_skip_blanks(line + 2); 07707 break; 07708 } 07709 } 07710 07711 return type; 07712 }
| 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 16079 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().
16080 { 16081 struct sip_pvt *sip_pvt_ptr; 16082 struct sip_pvt tmp_dialog = { 16083 .callid = callid, 16084 }; 16085 16086 if (totag) { 16087 ast_debug(4, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>"); 16088 } 16089 16090 /* Search dialogs and find the match */ 16091 16092 sip_pvt_ptr = ao2_t_find(dialogs, &tmp_dialog, OBJ_POINTER, "ao2_find of dialog in dialogs table"); 16093 if (sip_pvt_ptr) { 16094 /* Go ahead and lock it (and its owner) before returning */ 16095 sip_pvt_lock(sip_pvt_ptr); 16096 if (sip_cfg.pedanticsipchecking) { 16097 unsigned char frommismatch = 0, tomismatch = 0; 16098 16099 if (ast_strlen_zero(fromtag)) { 16100 sip_pvt_unlock(sip_pvt_ptr); 16101 ast_debug(4, "Matched %s call for callid=%s - no from tag specified, pedantic check fails\n", 16102 sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid); 16103 return NULL; 16104 } 16105 16106 if (ast_strlen_zero(totag)) { 16107 sip_pvt_unlock(sip_pvt_ptr); 16108 ast_debug(4, "Matched %s call for callid=%s - no to tag specified, pedantic check fails\n", 16109 sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid); 16110 return NULL; 16111 } 16112 /* RFC 3891 16113 * > 3. User Agent Server Behavior: Receiving a Replaces Header 16114 * > The Replaces header contains information used to match an existing 16115 * > SIP dialog (call-id, to-tag, and from-tag). Upon receiving an INVITE 16116 * > with a Replaces header, the User Agent (UA) attempts to match this 16117 * > information with a confirmed or early dialog. The User Agent Server 16118 * > (UAS) matches the to-tag and from-tag parameters as if they were tags 16119 * > present in an incoming request. In other words, the to-tag parameter 16120 * > is compared to the local tag, and the from-tag parameter is compared 16121 * > to the remote tag. 16122 * 16123 * Thus, the totag is always compared to the local tag, regardless if 16124 * this our call is an incoming or outgoing call. 16125 */ 16126 frommismatch = !!strcmp(fromtag, sip_pvt_ptr->theirtag); 16127 tomismatch = !!strcmp(totag, sip_pvt_ptr->tag); 16128 16129 /* Don't check from if the dialog is not established, due to multi forking the from 16130 * can change when the call is not answered yet. 16131 */ 16132 if ((frommismatch && ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) || tomismatch) { 16133 sip_pvt_unlock(sip_pvt_ptr); 16134 if (frommismatch) { 16135 ast_debug(4, "Matched %s call for callid=%s - pedantic from tag check fails; their tag is %s our tag is %s\n", 16136 sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid, 16137 fromtag, sip_pvt_ptr->theirtag); 16138 } 16139 if (tomismatch) { 16140 ast_debug(4, "Matched %s call for callid=%s - pedantic to tag check fails; their tag is %s our tag is %s\n", 16141 sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid, 16142 totag, sip_pvt_ptr->tag); 16143 } 16144 return NULL; 16145 } 16146 } 16147 16148 if (totag) 16149 ast_debug(4, "Matched %s call - their tag is %s Our tag is %s\n", 16150 sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", 16151 sip_pvt_ptr->theirtag, sip_pvt_ptr->tag); 16152 16153 /* deadlock avoidance... */ 16154 while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) { 16155 sip_pvt_unlock(sip_pvt_ptr); 16156 usleep(1); 16157 sip_pvt_lock(sip_pvt_ptr); 16158 } 16159 } 16160 16161 return sip_pvt_ptr; 16162 }
| static const char* get_srv_protocol | ( | enum sip_transport | t | ) | [inline, static] |
Return protocol string for srv dns query.
Definition at line 3627 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 3641 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 3612 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 3591 of file chan_sip.c.
Referenced by _sip_show_peer(), peers_data_provider_get(), and sip_show_settings().
03591 { 03592 switch (transports) { 03593 case SIP_TRANSPORT_UDP: 03594 return "UDP"; 03595 case SIP_TRANSPORT_TCP: 03596 return "TCP"; 03597 case SIP_TRANSPORT_TLS: 03598 return "TLS"; 03599 case SIP_TRANSPORT_UDP | SIP_TRANSPORT_TCP: 03600 return "TCP,UDP"; 03601 case SIP_TRANSPORT_UDP | SIP_TRANSPORT_TLS: 03602 return "TLS,UDP"; 03603 case SIP_TRANSPORT_TCP | SIP_TRANSPORT_TLS: 03604 return "TLS,TCP"; 03605 default: 03606 return transports ? 03607 "TLS,TCP,UDP" : "UNKNOWN"; 03608 } 03609 }
| static const char* get_transport_pvt | ( | struct sip_pvt * | p | ) | [inline, static] |
Return transport of dialog.
Definition at line 3659 of file chan_sip.c.
References get_transport(), and set_socket_transport().
Referenced by __sip_xmit(), and build_via().
03660 { 03661 if (p->outboundproxy && p->outboundproxy->transport) { 03662 set_socket_transport(&p->socket, p->outboundproxy->transport); 03663 } 03664 03665 return get_transport(p->socket.type); 03666 }
| 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 3569 of file chan_sip.c.
References ast_strlen_zero().
Referenced by __set_address_from_contact(), and parse_register_contact().
03570 { 03571 int res = 0; 03572 03573 if (ast_strlen_zero(transport)) { 03574 return res; 03575 } 03576 03577 if (!strcasecmp(transport, "udp")) { 03578 res |= SIP_TRANSPORT_UDP; 03579 } 03580 if (!strcasecmp(transport, "tcp")) { 03581 res |= SIP_TRANSPORT_TCP; 03582 } 03583 if (!strcasecmp(transport, "tls")) { 03584 res |= SIP_TRANSPORT_TLS; 03585 } 03586 03587 return res; 03588 }
| static const char * gettag | ( | const struct sip_request * | req, | |
| const char * | header, | |||
| char * | tagbuf, | |||
| int | tagbufsize | |||
| ) | [static] |
Get tag from packet.
Definition at line 22360 of file chan_sip.c.
References ast_copy_string(), and get_header().
Referenced by find_call(), handle_incoming(), handle_request_subscribe(), and handle_response().
22361 { 22362 const char *thetag; 22363 22364 if (!tagbuf) 22365 return NULL; 22366 tagbuf[0] = '\0'; /* reset the buffer */ 22367 thetag = get_header(req, header); 22368 thetag = strcasestr(thetag, ";tag="); 22369 if (thetag) { 22370 thetag += 5; 22371 ast_copy_string(tagbuf, thetag, tagbufsize); 22372 return strsep(&tagbuf, ";"); 22373 } 22374 return NULL; 22375 }
| static int handle_cc_notify | ( | struct sip_pvt * | pvt, | |
| struct sip_request * | req | |||
| ) | [static] |
Definition at line 22377 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().
22378 { 22379 struct sip_monitor_instance *monitor_instance = ao2_callback(sip_monitor_instances, 0, 22380 find_sip_monitor_instance_by_subscription_pvt, pvt); 22381 const char *status = get_body(req, "cc-state", ':'); 22382 struct cc_epa_entry *cc_entry; 22383 char *uri; 22384 22385 if (!monitor_instance) { 22386 transmit_response(pvt, "400 Bad Request", req); 22387 return -1; 22388 } 22389 22390 if (ast_strlen_zero(status)) { 22391 ao2_ref(monitor_instance, -1); 22392 transmit_response(pvt, "400 Bad Request", req); 22393 return -1; 22394 } 22395 22396 if (!strcmp(status, "queued")) { 22397 /* We've been told that we're queued. This is the endpoint's way of telling 22398 * us that it has accepted our CC request. We need to alert the core of this 22399 * development 22400 */ 22401 ast_cc_monitor_request_acked(monitor_instance->core_id, "SIP endpoint %s accepted request", monitor_instance->device_name); 22402 transmit_response(pvt, "200 OK", req); 22403 ao2_ref(monitor_instance, -1); 22404 return 0; 22405 } 22406 22407 /* It's open! Yay! */ 22408 uri = get_body(req, "cc-URI", ':'); 22409 if (ast_strlen_zero(uri)) { 22410 uri = get_in_brackets((char *)get_header(req, "From")); 22411 } 22412 22413 ast_string_field_set(monitor_instance, notify_uri, uri); 22414 if (monitor_instance->suspension_entry) { 22415 cc_entry = monitor_instance->suspension_entry->instance_data; 22416 if (cc_entry->current_state == CC_CLOSED) { 22417 /* If we've created a suspension entry and the current state is closed, then that means 22418 * we got a notice from the CC core earlier to suspend monitoring, but because this particular 22419 * call leg had not yet notified us that it was ready for recall, it meant that we 22420 * could not yet send a PUBLISH. Now, however, we can. 22421 */ 22422 construct_pidf_body(CC_CLOSED, monitor_instance->suspension_entry->body, 22423 sizeof(monitor_instance->suspension_entry->body), monitor_instance->peername); 22424 transmit_publish(monitor_instance->suspension_entry, SIP_PUBLISH_INITIAL, monitor_instance->notify_uri); 22425 } else { 22426 ast_cc_monitor_callee_available(monitor_instance->core_id, "SIP monitored callee has become available"); 22427 } 22428 } else { 22429 ast_cc_monitor_callee_available(monitor_instance->core_id, "SIP monitored callee has become available"); 22430 } 22431 ao2_ref(monitor_instance, -1); 22432 transmit_response(pvt, "200 OK", req); 22433 22434 return 0; 22435 }
| static int handle_cc_subscribe | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Definition at line 25206 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().
25207 { 25208 const char *uri = REQ_OFFSET_TO_STR(req, rlPart2); 25209 char *param_separator; 25210 struct ast_cc_agent *agent; 25211 struct sip_cc_agent_pvt *agent_pvt; 25212 const char *expires_str = get_header(req, "Expires"); 25213 int expires = -1; /* Just need it to be non-zero */ 25214 25215 if (!ast_strlen_zero(expires_str)) { 25216 sscanf(expires_str, "%d", &expires); 25217 } 25218 25219 if ((param_separator = strchr(uri, ';'))) { 25220 *param_separator = '\0'; 25221 } 25222 25223 p->subscribed = CALL_COMPLETION; 25224 25225 if (!(agent = find_sip_cc_agent_by_subscribe_uri(uri))) { 25226 if (!expires) { 25227 /* Typically, if a 0 Expires reaches us and we can't find 25228 * the corresponding agent, it means that the CC transaction 25229 * has completed and so the calling side is just trying to 25230 * clean up its subscription. We'll just respond with a 25231 * 200 OK and be done with it 25232 */ 25233 transmit_response(p, "200 OK", req); 25234 return 0; 25235 } 25236 ast_log(LOG_WARNING, "Invalid URI '%s' in CC subscribe\n", uri); 25237 transmit_response(p, "404 Not Found", req); 25238 return -1; 25239 } 25240 25241 agent_pvt = agent->private_data; 25242 25243 if (!expires) { 25244 /* We got sent a SUBSCRIBE and found an agent. This means that CC 25245 * is being canceled. 25246 */ 25247 ast_cc_failed(agent->core_id, "CC is being canceled by %s", agent->device_name); 25248 transmit_response(p, "200 OK", req); 25249 ao2_ref(agent, -1); 25250 return 0; 25251 } 25252 25253 agent_pvt->subscribe_pvt = dialog_ref(p, "SIP CC agent gains reference to subscription dialog"); 25254 ast_cc_agent_accept_request(agent->core_id, "SIP caller %s has requested CC via SUBSCRIBE", 25255 agent->device_name); 25256 25257 /* We don't send a response here. That is done in the agent's ack callback or in the 25258 * agent destructor, should a failure occur before we have responded 25259 */ 25260 ao2_ref(agent, -1); 25261 return 0; 25262 }
| 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 27474 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().
27475 { 27476 int res = 1; 27477 27478 if (!strcasecmp(v->name, "trustrpid")) { 27479 ast_set_flag(&mask[0], SIP_TRUSTRPID); 27480 ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID); 27481 } else if (!strcasecmp(v->name, "sendrpid")) { 27482 ast_set_flag(&mask[0], SIP_SENDRPID); 27483 if (!strcasecmp(v->value, "pai")) { 27484 ast_set_flag(&flags[0], SIP_SENDRPID_PAI); 27485 } else if (!strcasecmp(v->value, "rpid")) { 27486 ast_set_flag(&flags[0], SIP_SENDRPID_RPID); 27487 } else if (ast_true(v->value)) { 27488 ast_set_flag(&flags[0], SIP_SENDRPID_RPID); 27489 } 27490 } else if (!strcasecmp(v->name, "rpid_update")) { 27491 ast_set_flag(&mask[1], SIP_PAGE2_RPID_UPDATE); 27492 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RPID_UPDATE); 27493 } else if (!strcasecmp(v->name, "rpid_immediate")) { 27494 ast_set_flag(&mask[1], SIP_PAGE2_RPID_IMMEDIATE); 27495 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RPID_IMMEDIATE); 27496 } else if (!strcasecmp(v->name, "g726nonstandard")) { 27497 ast_set_flag(&mask[0], SIP_G726_NONSTANDARD); 27498 ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD); 27499 } else if (!strcasecmp(v->name, "useclientcode")) { 27500 ast_set_flag(&mask[0], SIP_USECLIENTCODE); 27501 ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE); 27502 } else if (!strcasecmp(v->name, "dtmfmode")) { 27503 ast_set_flag(&mask[0], SIP_DTMF); 27504 ast_clear_flag(&flags[0], SIP_DTMF); 27505 if (!strcasecmp(v->value, "inband")) 27506 ast_set_flag(&flags[0], SIP_DTMF_INBAND); 27507 else if (!strcasecmp(v->value, "rfc2833")) 27508 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 27509 else if (!strcasecmp(v->value, "info")) 27510 ast_set_flag(&flags[0], SIP_DTMF_INFO); 27511 else if (!strcasecmp(v->value, "shortinfo")) 27512 ast_set_flag(&flags[0], SIP_DTMF_SHORTINFO); 27513 else if (!strcasecmp(v->value, "auto")) 27514 ast_set_flag(&flags[0], SIP_DTMF_AUTO); 27515 else { 27516 ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno); 27517 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 27518 } 27519 } else if (!strcasecmp(v->name, "nat")) { 27520 ast_set_flag(&mask[0], SIP_NAT_FORCE_RPORT); 27521 ast_set_flag(&flags[0], SIP_NAT_FORCE_RPORT); /* Default to "force_rport" */ 27522 if (!strcasecmp(v->value, "no")) { 27523 ast_clear_flag(&flags[0], SIP_NAT_FORCE_RPORT); 27524 } else if (!strcasecmp(v->value, "yes")) { 27525 /* We've already defaulted to force_rport */ 27526 ast_set_flag(&mask[1], SIP_PAGE2_SYMMETRICRTP); 27527 ast_set_flag(&flags[1], SIP_PAGE2_SYMMETRICRTP); 27528 } else if (!strcasecmp(v->value, "comedia")) { 27529 ast_clear_flag(&flags[0], SIP_NAT_FORCE_RPORT); 27530 ast_set_flag(&mask[1], SIP_PAGE2_SYMMETRICRTP); 27531 ast_set_flag(&flags[1], SIP_PAGE2_SYMMETRICRTP); 27532 } 27533 } else if (!strcasecmp(v->name, "directmedia") || !strcasecmp(v->name, "canreinvite")) { 27534 ast_set_flag(&mask[0], SIP_REINVITE); 27535 ast_clear_flag(&flags[0], SIP_REINVITE); 27536 if (ast_true(v->value)) { 27537 ast_set_flag(&flags[0], SIP_DIRECT_MEDIA | SIP_DIRECT_MEDIA_NAT); 27538 } else if (!ast_false(v->value)) { 27539 char buf[64]; 27540 char *word, *next = buf; 27541 27542 ast_copy_string(buf, v->value, sizeof(buf)); 27543 while ((word = strsep(&next, ","))) { 27544 if (!strcasecmp(word, "update")) { 27545 ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_DIRECT_MEDIA); 27546 } else if (!strcasecmp(word, "nonat")) { 27547 ast_set_flag(&flags[0], SIP_DIRECT_MEDIA); 27548 ast_clear_flag(&flags[0], SIP_DIRECT_MEDIA_NAT); 27549 } else if (!strcasecmp(word, "outgoing")) { 27550 ast_set_flag(&flags[0], SIP_DIRECT_MEDIA); 27551 ast_set_flag(&mask[2], SIP_PAGE3_DIRECT_MEDIA_OUTGOING); 27552 ast_set_flag(&flags[2], SIP_PAGE3_DIRECT_MEDIA_OUTGOING); 27553 } else { 27554 ast_log(LOG_WARNING, "Unknown directmedia mode '%s' on line %d\n", v->value, v->lineno); 27555 } 27556 } 27557 } 27558 } else if (!strcasecmp(v->name, "insecure")) { 27559 ast_set_flag(&mask[0], SIP_INSECURE); 27560 ast_clear_flag(&flags[0], SIP_INSECURE); 27561 set_insecure_flags(&flags[0], v->value, v->lineno); 27562 } else if (!strcasecmp(v->name, "progressinband")) { 27563 ast_set_flag(&mask[0], SIP_PROG_INBAND); 27564 ast_clear_flag(&flags[0], SIP_PROG_INBAND); 27565 if (ast_true(v->value)) 27566 ast_set_flag(&flags[0], SIP_PROG_INBAND_YES); 27567 else if (strcasecmp(v->value, "never")) 27568 ast_set_flag(&flags[0], SIP_PROG_INBAND_NO); 27569 } else if (!strcasecmp(v->name, "promiscredir")) { 27570 ast_set_flag(&mask[0], SIP_PROMISCREDIR); 27571 ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR); 27572 } else if (!strcasecmp(v->name, "videosupport")) { 27573 if (!strcasecmp(v->value, "always")) { 27574 ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS); 27575 ast_set_flag(&flags[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS); 27576 } else { 27577 ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT); 27578 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT); 27579 } 27580 } else if (!strcasecmp(v->name, "textsupport")) { 27581 ast_set_flag(&mask[1], SIP_PAGE2_TEXTSUPPORT); 27582 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_TEXTSUPPORT); 27583 res = 1; 27584 } else if (!strcasecmp(v->name, "allowoverlap")) { 27585 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP); 27586 ast_clear_flag(&flags[1], SIP_PAGE2_ALLOWOVERLAP); 27587 if (ast_true(v->value)) { 27588 ast_set_flag(&flags[1], SIP_PAGE2_ALLOWOVERLAP_YES); 27589 } else if (!strcasecmp(v->value, "dtmf")){ 27590 ast_set_flag(&flags[1], SIP_PAGE2_ALLOWOVERLAP_DTMF); 27591 } 27592 } else if (!strcasecmp(v->name, "allowsubscribe")) { 27593 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE); 27594 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE); 27595 } else if (!strcasecmp(v->name, "ignoresdpversion")) { 27596 ast_set_flag(&mask[1], SIP_PAGE2_IGNORESDPVERSION); 27597 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_IGNORESDPVERSION); 27598 } else if (!strcasecmp(v->name, "faxdetect")) { 27599 ast_set_flag(&mask[1], SIP_PAGE2_FAX_DETECT); 27600 if (ast_true(v->value)) { 27601 ast_set_flag(&flags[1], SIP_PAGE2_FAX_DETECT_BOTH); 27602 } else if (ast_false(v->value)) { 27603 ast_clear_flag(&flags[1], SIP_PAGE2_FAX_DETECT_BOTH); 27604 } else { 27605 char *buf = ast_strdupa(v->value); 27606 char *word, *next = buf; 27607 27608 while ((word = strsep(&next, ","))) { 27609 if (!strcasecmp(word, "cng")) { 27610 ast_set_flag(&flags[1], SIP_PAGE2_FAX_DETECT_CNG); 27611 } else if (!strcasecmp(word, "t38")) { 27612 ast_set_flag(&flags[1], SIP_PAGE2_FAX_DETECT_T38); 27613 } else { 27614 ast_log(LOG_WARNING, "Unknown faxdetect mode '%s' on line %d.\n", word, v->lineno); 27615 } 27616 } 27617 } 27618 } else if (!strcasecmp(v->name, "rfc2833compensate")) { 27619 ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE); 27620 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE); 27621 } else if (!strcasecmp(v->name, "buggymwi")) { 27622 ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI); 27623 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI); 27624 } else 27625 res = 0; 27626 27627 return res; 27628 }
| 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 25718 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().
25719 { 25720 /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things 25721 relatively static */ 25722 const char *cmd; 25723 const char *cseq; 25724 const char *useragent; 25725 const char *via; 25726 const char *callid; 25727 int via_pos = 0; 25728 uint32_t seqno; 25729 int len; 25730 int respid; 25731 int res = 0; 25732 int debug = sip_debug_test_pvt(p); 25733 const char *e; 25734 int error = 0; 25735 int oldmethod = p->method; 25736 int acked = 0; 25737 25738 /* RFC 3261 - 8.1.1 A valid SIP request must contain To, From, CSeq, Call-ID and Via. 25739 * 8.2.6.2 Response must have To, From, Call-ID CSeq, and Via related to the request, 25740 * so we can check to make sure these fields exist for all requests and responses */ 25741 cseq = get_header(req, "Cseq"); 25742 cmd = REQ_OFFSET_TO_STR(req, header[0]); 25743 /* Save the via_pos so we can check later that responses only have 1 Via header */ 25744 via = __get_header(req, "Via", &via_pos); 25745 /* This must exist already because we've called find_call by now */ 25746 callid = get_header(req, "Call-ID"); 25747 25748 /* Must have Cseq */ 25749 if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq) || ast_strlen_zero(via)) { 25750 ast_log(LOG_ERROR, "Dropping this SIP message with Call-ID '%s', it's incomplete.\n", callid); 25751 error = 1; 25752 } 25753 if (!error && sscanf(cseq, "%30u%n", &seqno, &len) != 1) { 25754 ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd); 25755 error = 1; 25756 } 25757 if (error) { 25758 if (!p->initreq.headers) { /* New call */ 25759 pvt_set_needdestroy(p, "no headers"); 25760 } 25761 return -1; 25762 } 25763 /* Get the command XXX */ 25764 25765 cmd = REQ_OFFSET_TO_STR(req, rlPart1); 25766 e = ast_skip_blanks(REQ_OFFSET_TO_STR(req, rlPart2)); 25767 25768 /* Save useragent of the client */ 25769 useragent = get_header(req, "User-Agent"); 25770 if (!ast_strlen_zero(useragent)) 25771 ast_string_field_set(p, useragent, useragent); 25772 25773 /* Find out SIP method for incoming request */ 25774 if (req->method == SIP_RESPONSE) { /* Response to our request */ 25775 /* ignore means "don't do anything with it" but still have to 25776 * respond appropriately. 25777 * But in this case this is a response already, so we really 25778 * have nothing to do with this message, and even setting the 25779 * ignore flag is pointless. 25780 */ 25781 if (ast_strlen_zero(e)) { 25782 return 0; 25783 } 25784 if (sscanf(e, "%30d %n", &respid, &len) != 1) { 25785 ast_log(LOG_WARNING, "Invalid response: '%s'\n", e); 25786 return 0; 25787 } 25788 if (respid <= 0) { 25789 ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid); 25790 return 0; 25791 } 25792 /* RFC 3261 - 8.1.3.3 If more than one Via header field value is present in a reponse 25793 * the UAC SHOULD discard the message. This is not perfect, as it will not catch multiple 25794 * headers joined with a comma. Fixing that would pretty much involve writing a new parser */ 25795 if (!ast_strlen_zero(__get_header(req, "via", &via_pos))) { 25796 ast_log(LOG_WARNING, "Misrouted SIP response '%s' with Call-ID '%s', too many vias\n", e, callid); 25797 return 0; 25798 } 25799 if (p->ocseq && (p->ocseq < seqno)) { 25800 ast_debug(1, "Ignoring out of order response %u (expecting %u)\n", seqno, p->ocseq); 25801 return -1; 25802 } else { 25803 char causevar[256], causeval[256]; 25804 25805 if ((respid == 200) || ((respid >= 300) && (respid <= 399))) { 25806 extract_uri(p, req); 25807 } 25808 25809 handle_response(p, respid, e + len, req, seqno); 25810 25811 if (global_store_sip_cause && p->owner) { 25812 struct ast_channel *owner = p->owner; 25813 25814 snprintf(causevar, sizeof(causevar), "MASTER_CHANNEL(HASH(SIP_CAUSE,%s))", owner->name); 25815 snprintf(causeval, sizeof(causeval), "SIP %s", REQ_OFFSET_TO_STR(req, rlPart2)); 25816 25817 ast_channel_ref(owner); 25818 sip_pvt_unlock(p); 25819 ast_channel_unlock(owner); 25820 *nounlock = 1; 25821 pbx_builtin_setvar_helper(owner, causevar, causeval); 25822 ast_channel_unref(owner); 25823 sip_pvt_lock(p); 25824 } 25825 } 25826 return 0; 25827 } 25828 25829 /* New SIP request coming in 25830 (could be new request in existing SIP dialog as well...) 25831 */ 25832 25833 p->method = req->method; /* Find out which SIP method they are using */ 25834 ast_debug(4, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 25835 25836 if (p->icseq && (p->icseq > seqno) ) { 25837 if (p->pendinginvite && seqno == p->pendinginvite && (req->method == SIP_ACK || req->method == SIP_CANCEL)) { 25838 ast_debug(2, "Got CANCEL or ACK on INVITE with transactions in between.\n"); 25839 } else { 25840 ast_debug(1, "Ignoring too old SIP packet packet %u (expecting >= %u)\n", seqno, p->icseq); 25841 if (req->method == SIP_INVITE) { 25842 unsigned int ran = (ast_random() % 10) + 1; 25843 char seconds[4]; 25844 snprintf(seconds, sizeof(seconds), "%u", ran); 25845 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 */ 25846 } else if (req->method != SIP_ACK) { 25847 transmit_response(p, "500 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */ 25848 } 25849 return -1; 25850 } 25851 } else if (p->icseq && 25852 p->icseq == seqno && 25853 req->method != SIP_ACK && 25854 (p->method != SIP_CANCEL || p->alreadygone)) { 25855 /* ignore means "don't do anything with it" but still have to 25856 respond appropriately. We do this if we receive a repeat of 25857 the last sequence number */ 25858 req->ignore = 1; 25859 ast_debug(3, "Ignoring SIP message because of retransmit (%s Seqno %u, ours %u)\n", sip_methods[p->method].text, p->icseq, seqno); 25860 } 25861 25862 /* RFC 3261 section 9. "CANCEL has no effect on a request to which a UAS has 25863 * already given a final response." */ 25864 if (!p->pendinginvite && (req->method == SIP_CANCEL)) { 25865 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 25866 return res; 25867 } 25868 25869 if (seqno >= p->icseq) 25870 /* Next should follow monotonically (but not necessarily 25871 incrementally -- thanks again to the genius authors of SIP -- 25872 increasing */ 25873 p->icseq = seqno; 25874 25875 /* Find their tag if we haven't got it */ 25876 if (ast_strlen_zero(p->theirtag)) { 25877 char tag[128]; 25878 25879 gettag(req, "From", tag, sizeof(tag)); 25880 ast_string_field_set(p, theirtag, tag); 25881 } 25882 snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd); 25883 25884 if (sip_cfg.pedanticsipchecking) { 25885 /* If this is a request packet without a from tag, it's not 25886 correct according to RFC 3261 */ 25887 /* Check if this a new request in a new dialog with a totag already attached to it, 25888 RFC 3261 - section 12.2 - and we don't want to mess with recovery */ 25889 if (!p->initreq.headers && req->has_to_tag) { 25890 /* If this is a first request and it got a to-tag, it is not for us */ 25891 if (!req->ignore && req->method == SIP_INVITE) { 25892 /* Just because we think this is a dialog-starting INVITE with a to-tag 25893 * doesn't mean it actually is. It could be a reinvite for an established, but 25894 * unknown dialog. In such a case, we need to change our tag to the 25895 * incoming INVITE's to-tag so that they will recognize the 481 we send and 25896 * so that we will properly match their incoming ACK. 25897 */ 25898 char totag[128]; 25899 gettag(req, "To", totag, sizeof(totag)); 25900 ast_string_field_set(p, tag, totag); 25901 p->pendinginvite = p->icseq; 25902 transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req); 25903 /* Will cease to exist after ACK */ 25904 return res; 25905 } else if (req->method != SIP_ACK) { 25906 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 25907 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 25908 return res; 25909 } 25910 /* Otherwise, this is an ACK. It will always have a to-tag */ 25911 } 25912 } 25913 25914 if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY || p->method == SIP_PUBLISH)) { 25915 transmit_response(p, "400 Bad request", req); 25916 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 25917 return -1; 25918 } 25919 25920 /* Handle various incoming SIP methods in requests */ 25921 switch (p->method) { 25922 case SIP_OPTIONS: 25923 res = handle_request_options(p, req, addr, e); 25924 break; 25925 case SIP_INVITE: 25926 res = handle_request_invite(p, req, debug, seqno, addr, recount, e, nounlock); 25927 break; 25928 case SIP_REFER: 25929 res = handle_request_refer(p, req, debug, seqno, nounlock); 25930 break; 25931 case SIP_CANCEL: 25932 res = handle_request_cancel(p, req); 25933 break; 25934 case SIP_BYE: 25935 res = handle_request_bye(p, req); 25936 break; 25937 case SIP_MESSAGE: 25938 res = handle_request_message(p, req); 25939 break; 25940 case SIP_PUBLISH: 25941 res = handle_request_publish(p, req, addr, seqno, e); 25942 break; 25943 case SIP_SUBSCRIBE: 25944 res = handle_request_subscribe(p, req, addr, seqno, e); 25945 break; 25946 case SIP_REGISTER: 25947 res = handle_request_register(p, req, addr, e); 25948 break; 25949 case SIP_INFO: 25950 if (req->debug) 25951 ast_verbose("Receiving INFO!\n"); 25952 if (!req->ignore) 25953 handle_request_info(p, req); 25954 else /* if ignoring, transmit response */ 25955 transmit_response(p, "200 OK", req); 25956 break; 25957 case SIP_NOTIFY: 25958 res = handle_request_notify(p, req, addr, seqno, e); 25959 break; 25960 case SIP_UPDATE: 25961 res = handle_request_update(p, req); 25962 break; 25963 case SIP_ACK: 25964 /* Make sure we don't ignore this */ 25965 if (seqno == p->pendinginvite) { 25966 p->invitestate = INV_TERMINATED; 25967 p->pendinginvite = 0; 25968 acked = __sip_ack(p, seqno, 1 /* response */, 0); 25969 if (find_sdp(req)) { 25970 if (process_sdp(p, req, SDP_T38_NONE)) { 25971 return -1; 25972 } 25973 if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) { 25974 ast_queue_control(p->owner, AST_CONTROL_SRCCHANGE); 25975 } 25976 } 25977 check_pendings(p); 25978 } else if (p->glareinvite == seqno) { 25979 /* handle ack for the 491 pending sent for glareinvite */ 25980 p->glareinvite = 0; 25981 acked = __sip_ack(p, seqno, 1, 0); 25982 } 25983 if (!acked) { 25984 /* Got an ACK that did not match anything. Ignore 25985 * silently and restore previous method */ 25986 p->method = oldmethod; 25987 } 25988 if (!p->lastinvite && ast_strlen_zero(p->randdata)) { 25989 pvt_set_needdestroy(p, "unmatched ACK"); 25990 } 25991 break; 25992 default: 25993 transmit_response_with_allow(p, "501 Method Not Implemented", req, 0); 25994 ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 25995 cmd, ast_sockaddr_stringify(&p->sa)); 25996 /* If this is some new method, and we don't have a call, destroy it now */ 25997 if (!p->initreq.headers) { 25998 pvt_set_needdestroy(p, "unimplemented method"); 25999 } 26000 break; 26001 } 26002 return res; 26003 }
| 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 22690 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_lock, ast_channel_masquerade(), ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_debug, ast_do_masquerade(), ast_hangup(), ast_log(), ast_quiet_chan(), ast_set_flag, ast_setstate(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, FALSE, ast_channel::hangupcause, LOG_ERROR, LOG_NOTICE, LOG_WARNING, 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().
22691 { 22692 int earlyreplace = 0; 22693 int oneleggedreplace = 0; /* Call with no bridge, propably IVR or voice message */ 22694 struct ast_channel *c = p->owner; /* Our incoming call */ 22695 struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */ 22696 struct ast_channel *targetcall; /* The bridge to the take-over target */ 22697 22698 /* Check if we're in ring state */ 22699 if (replacecall->_state == AST_STATE_RING) 22700 earlyreplace = 1; 22701 22702 /* Check if we have a bridge */ 22703 if (!(targetcall = ast_bridged_channel(replacecall))) { 22704 /* We have no bridge */ 22705 if (!earlyreplace) { 22706 ast_debug(2, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name); 22707 oneleggedreplace = 1; 22708 } 22709 } 22710 if (targetcall && targetcall->_state == AST_STATE_RINGING) 22711 ast_debug(4, "SIP transfer: Target channel is in ringing state\n"); 22712 22713 if (targetcall) 22714 ast_debug(4, "SIP transfer: Invite Replace incoming channel should bridge to channel %s while hanging up channel %s\n", targetcall->name, replacecall->name); 22715 else 22716 ast_debug(4, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name); 22717 22718 if (req->ignore) { 22719 ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n"); 22720 /* We should answer something here. If we are here, the 22721 call we are replacing exists, so an accepted 22722 can't harm */ 22723 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE, FALSE, FALSE); 22724 /* Do something more clever here */ 22725 if (c) { 22726 *nounlock = 1; 22727 ast_channel_unlock(c); 22728 } 22729 ast_channel_unlock(replacecall); 22730 sip_pvt_unlock(p->refer->refer_call); 22731 return 1; 22732 } 22733 if (!c) { 22734 /* What to do if no channel ??? */ 22735 ast_log(LOG_ERROR, "Unable to create new channel. Invite/replace failed.\n"); 22736 transmit_response_reliable(p, "503 Service Unavailable", req); 22737 append_history(p, "Xfer", "INVITE/Replace Failed. No new channel."); 22738 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22739 ast_channel_unlock(replacecall); 22740 sip_pvt_unlock(p->refer->refer_call); 22741 return 1; 22742 } 22743 append_history(p, "Xfer", "INVITE/Replace received"); 22744 /* We have three channels to play with 22745 channel c: New incoming call 22746 targetcall: Call from PBX to target 22747 p->refer->refer_call: SIP pvt dialog from transferer to pbx. 22748 replacecall: The owner of the previous 22749 We need to masq C into refer_call to connect to 22750 targetcall; 22751 If we are talking to internal audio stream, target call is null. 22752 */ 22753 22754 /* Fake call progress */ 22755 transmit_response(p, "100 Trying", req); 22756 ast_setstate(c, AST_STATE_RING); 22757 22758 /* Masquerade the new call into the referred call to connect to target call 22759 Targetcall is not touched by the masq */ 22760 22761 /* Answer the incoming call and set channel to UP state */ 22762 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE, FALSE, FALSE); 22763 22764 ast_setstate(c, AST_STATE_UP); 22765 22766 /* Stop music on hold and other generators */ 22767 ast_quiet_chan(replacecall); 22768 ast_quiet_chan(targetcall); 22769 ast_debug(4, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name); 22770 22771 /* Make sure that the masq does not free our PVT for the old call */ 22772 if (! earlyreplace && ! oneleggedreplace ) 22773 ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 22774 22775 /* Prepare the masquerade - if this does not happen, we will be gone */ 22776 if(ast_channel_masquerade(replacecall, c)) 22777 ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n"); 22778 else 22779 ast_debug(4, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name); 22780 22781 /* C should now be in place of replacecall. all channel locks and pvt locks should be removed 22782 * before issuing the masq. Since we are unlocking both the pvt (p) and its owner channel (c) 22783 * it is possible for channel c to be destroyed on us. To prevent this, we must give c a reference 22784 * before any unlocking takes place and remove it only once we are completely done with it */ 22785 ast_channel_ref(c); 22786 ast_channel_unlock(replacecall); 22787 ast_channel_unlock(c); 22788 sip_pvt_unlock(p->refer->refer_call); 22789 sip_pvt_unlock(p); 22790 if (ast_do_masquerade(replacecall)) { 22791 ast_log(LOG_WARNING, "Failed to perform masquerade with INVITE replaces\n"); 22792 } 22793 ast_channel_lock(c); 22794 if (earlyreplace || oneleggedreplace ) { 22795 c->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 22796 } 22797 ast_setstate(c, AST_STATE_DOWN); 22798 ast_channel_unlock(c); 22799 22800 /* The call should be down with no ast_channel, so hang it up */ 22801 c->tech_pvt = dialog_unref(c->tech_pvt, "unref dialog c->tech_pvt"); 22802 22803 /* c and c's tech pvt must be unlocked at this point for ast_hangup */ 22804 ast_hangup(c); 22805 /* this indicates to handle_request_do that the owner channel has already been unlocked */ 22806 *nounlock = 1; 22807 /* lock PVT structure again after hangup */ 22808 sip_pvt_lock(p); 22809 ast_channel_unref(c); 22810 return 0; 22811 }
| static int handle_request_bye | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Handle incoming BYE request.
Definition at line 24523 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().
24524 { 24525 struct ast_channel *c=NULL; 24526 int res; 24527 struct ast_channel *bridged_to; 24528 const char *required; 24529 24530 /* If we have an INCOMING invite that we haven't answered, terminate that transaction */ 24531 if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !req->ignore) { 24532 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 24533 } 24534 24535 __sip_pretend_ack(p); 24536 24537 p->invitestate = INV_TERMINATED; 24538 24539 copy_request(&p->initreq, req); 24540 if (sipdebug) 24541 ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid); 24542 check_via(p, req); 24543 sip_alreadygone(p); 24544 24545 /* Get RTCP quality before end of call */ 24546 if (p->do_history || p->owner) { 24547 char quality_buf[AST_MAX_USER_FIELD], *quality; 24548 struct ast_channel *bridge = p->owner ? ast_bridged_channel(p->owner) : NULL; 24549 24550 /* We need to get the lock on bridge because ast_rtp_instance_set_stats_vars will attempt 24551 * to lock the bridge. This may get hairy... 24552 */ 24553 while (bridge && ast_channel_trylock(bridge)) { 24554 ast_channel_unlock(p->owner); 24555 do { 24556 /* Can't use DEADLOCK_AVOIDANCE since p is an ao2 object */ 24557 sip_pvt_unlock(p); 24558 usleep(1); 24559 sip_pvt_lock(p); 24560 } while (p->owner && ast_channel_trylock(p->owner)); 24561 bridge = p->owner ? ast_bridged_channel(p->owner) : NULL; 24562 } 24563 24564 24565 if (p->rtp && (quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) { 24566 if (p->do_history) { 24567 append_history(p, "RTCPaudio", "Quality:%s", quality); 24568 24569 if ((quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_JITTER, quality_buf, sizeof(quality_buf)))) { 24570 append_history(p, "RTCPaudioJitter", "Quality:%s", quality); 24571 } 24572 if ((quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_LOSS, quality_buf, sizeof(quality_buf)))) { 24573 append_history(p, "RTCPaudioLoss", "Quality:%s", quality); 24574 } 24575 if ((quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_RTT, quality_buf, sizeof(quality_buf)))) { 24576 append_history(p, "RTCPaudioRTT", "Quality:%s", quality); 24577 } 24578 } 24579 24580 if (p->owner) { 24581 ast_rtp_instance_set_stats_vars(p->owner, p->rtp); 24582 } 24583 24584 } 24585 24586 if (bridge) { 24587 struct sip_pvt *q = bridge->tech_pvt; 24588 24589 if (IS_SIP_TECH(bridge->tech) && q && q->rtp) { 24590 ast_rtp_instance_set_stats_vars(bridge, q->rtp); 24591 } 24592 ast_channel_unlock(bridge); 24593 } 24594 24595 if (p->vrtp && (quality = ast_rtp_instance_get_quality(p->vrtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) { 24596 if (p->do_history) { 24597 append_history(p, "RTCPvideo", "Quality:%s", quality); 24598 } 24599 if (p->owner) { 24600 pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", quality); 24601 } 24602 } 24603 if (p->trtp && (quality = ast_rtp_instance_get_quality(p->trtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) { 24604 if (p->do_history) { 24605 append_history(p, "RTCPtext", "Quality:%s", quality); 24606 } 24607 if (p->owner) { 24608 pbx_builtin_setvar_helper(p->owner, "RTPTEXTQOS", quality); 24609 } 24610 } 24611 } 24612 24613 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 24614 stop_session_timer(p); /* Stop Session-Timer */ 24615 24616 if (!ast_strlen_zero(get_header(req, "Also"))) { 24617 ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n", 24618 ast_sockaddr_stringify(&p->recv)); 24619 if (ast_strlen_zero(p->context)) 24620 ast_string_field_set(p, context, sip_cfg.default_context); 24621 res = get_also_info(p, req); 24622 if (!res) { 24623 c = p->owner; 24624 if (c) { 24625 bridged_to = ast_bridged_channel(c); 24626 if (bridged_to) { 24627 /* Don't actually hangup here... */ 24628 ast_queue_control(c, AST_CONTROL_UNHOLD); 24629 ast_channel_unlock(c); /* async_goto can do a masquerade, no locks can be held during a masq */ 24630 ast_async_goto(bridged_to, p->context, p->refer->refer_to, 1); 24631 ast_channel_lock(c); 24632 } else 24633 ast_queue_hangup(p->owner); 24634 } 24635 } else { 24636 ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_sockaddr_stringify(&p->recv)); 24637 if (p->owner) 24638 ast_queue_hangup_with_cause(p->owner, AST_CAUSE_PROTOCOL_ERROR); 24639 } 24640 } else if (p->owner) { 24641 sip_queue_hangup_cause(p, 0); 24642 sip_scheddestroy_final(p, DEFAULT_TRANS_TIMEOUT); 24643 ast_debug(3, "Received bye, issuing owner hangup\n"); 24644 } else { 24645 sip_scheddestroy_final(p, DEFAULT_TRANS_TIMEOUT); 24646 ast_debug(3, "Received bye, no owner, selfdestruct soon.\n"); 24647 } 24648 ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 24649 24650 /* Find out what they require */ 24651 required = get_header(req, "Require"); 24652 if (!ast_strlen_zero(required)) { 24653 char unsupported[256] = { 0, }; 24654 parse_sip_options(required, unsupported, ARRAY_LEN(unsupported)); 24655 /* If there are any options required that we do not support, 24656 * then send a 420 with only those unsupported options listed */ 24657 if (!ast_strlen_zero(unsupported)) { 24658 transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, unsupported); 24659 ast_log(LOG_WARNING, "Received SIP BYE with unsupported required extension: required:%s unsupported:%s\n", required, unsupported); 24660 } else { 24661 transmit_response(p, "200 OK", req); 24662 } 24663 } else { 24664 transmit_response(p, "200 OK", req); 24665 } 24666 24667 return 1; 24668 }
| static int handle_request_cancel | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Handle incoming CANCEL request.
Definition at line 24455 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().
24456 { 24457 24458 check_via(p, req); 24459 sip_alreadygone(p); 24460 24461 if (p->owner && p->owner->_state == AST_STATE_UP) { 24462 /* This call is up, cancel is ignored, we need a bye */ 24463 transmit_response(p, "200 OK", req); 24464 ast_debug(1, "Got CANCEL on an answered call. Ignoring... \n"); 24465 return 0; 24466 } 24467 24468 /* At this point, we could have cancelled the invite at the same time 24469 as the other side sends a CANCEL. Our final reply with error code 24470 might not have been received by the other side before the CANCEL 24471 was sent, so let's just give up retransmissions and waiting for 24472 ACK on our error code. The call is hanging up any way. */ 24473 if (p->invitestate == INV_TERMINATED || p->invitestate == INV_COMPLETED) { 24474 __sip_pretend_ack(p); 24475 } 24476 if (p->invitestate != INV_TERMINATED) 24477 p->invitestate = INV_CANCELLED; 24478 24479 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 24480 update_call_counter(p, DEC_CALL_LIMIT); 24481 24482 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 24483 if (p->owner) { 24484 sip_queue_hangup_cause(p, 0); 24485 } else { 24486 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 24487 } 24488 if (ast_str_strlen(p->initreq.data) > 0) { 24489 struct sip_pkt *pkt, *prev_pkt; 24490 /* If the CANCEL we are receiving is a retransmission, and we already have scheduled 24491 * a reliable 487, then we don't want to schedule another one on top of the previous 24492 * one. 24493 * 24494 * As odd as this may sound, we can't rely on the previously-transmitted "reliable" 24495 * response in this situation. What if we've sent all of our reliable responses 24496 * already and now all of a sudden, we get this second CANCEL? 24497 * 24498 * The only way to do this correctly is to cancel our previously-scheduled reliably- 24499 * transmitted response and send a new one in its place. 24500 */ 24501 for (pkt = p->packets, prev_pkt = NULL; pkt; prev_pkt = pkt, pkt = pkt->next) { 24502 if (pkt->seqno == p->lastinvite && pkt->response_code == 487) { 24503 AST_SCHED_DEL(sched, pkt->retransid); 24504 UNLINK(pkt, p->packets, prev_pkt); 24505 dialog_unref(pkt->owner, "unref packet->owner from dialog"); 24506 if (pkt->data) { 24507 ast_free(pkt->data); 24508 } 24509 ast_free(pkt); 24510 break; 24511 } 24512 } 24513 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 24514 transmit_response(p, "200 OK", req); 24515 return 1; 24516 } else { 24517 transmit_response(p, "481 Call Leg Does Not Exist", req); 24518 return 0; 24519 } 24520 }
| 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 26055 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().
26056 { 26057 struct sip_pvt *p; 26058 struct ast_channel *owner_chan_ref = NULL; 26059 int recount = 0; 26060 int nounlock = 0; 26061 26062 if (sip_debug_test_addr(addr)) /* Set the debug flag early on packet level */ 26063 req->debug = 1; 26064 if (sip_cfg.pedanticsipchecking) 26065 lws2sws(req->data); /* Fix multiline headers */ 26066 if (req->debug) { 26067 ast_verbose("\n<--- SIP read from %s:%s --->\n%s\n<------------->\n", 26068 get_transport(req->socket.type), ast_sockaddr_stringify(addr), ast_str_buffer(req->data)); 26069 } 26070 26071 if (parse_request(req) == -1) { /* Bad packet, can't parse */ 26072 ast_str_reset(req->data); /* nulling this out is NOT a good idea here. */ 26073 return 1; 26074 } 26075 req->method = find_sip_method(REQ_OFFSET_TO_STR(req, rlPart1)); 26076 26077 if (req->debug) 26078 ast_verbose("--- (%d headers %d lines)%s ---\n", req->headers, req->lines, (req->headers + req->lines == 0) ? " Nat keepalive" : ""); 26079 26080 if (req->headers < 2) { /* Must have at least two headers */ 26081 ast_str_reset(req->data); /* nulling this out is NOT a good idea here. */ 26082 return 1; 26083 } 26084 26085 /* Process request, with netlock held, and with usual deadlock avoidance */ 26086 ast_mutex_lock(&netlock); 26087 26088 /* Find the active SIP dialog or create a new one */ 26089 p = find_call(req, addr, req->method); /* returns p with a reference only. _NOT_ locked*/ 26090 if (p == NULL) { 26091 ast_debug(1, "Invalid SIP message - rejected , no callid, len %zu\n", ast_str_strlen(req->data)); 26092 ast_mutex_unlock(&netlock); 26093 return 1; 26094 } 26095 26096 /* Lock both the pvt and the owner if owner is present. This will 26097 * not fail. */ 26098 owner_chan_ref = sip_pvt_lock_full(p); 26099 26100 copy_socket_data(&p->socket, &req->socket); 26101 ast_sockaddr_copy(&p->recv, addr); 26102 26103 /* if we have an owner, then this request has been authenticated */ 26104 if (p->owner) { 26105 req->authenticated = 1; 26106 } 26107 26108 if (p->do_history) /* This is a request or response, note what it was for */ 26109 append_history(p, "Rx", "%s / %s / %s", ast_str_buffer(req->data), get_header(req, "CSeq"), REQ_OFFSET_TO_STR(req, rlPart2)); 26110 26111 if (handle_incoming(p, req, addr, &recount, &nounlock) == -1) { 26112 /* Request failed */ 26113 ast_debug(1, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 26114 } 26115 26116 if (recount) { 26117 ast_update_use_count(); 26118 } 26119 26120 if (p->owner && !nounlock) { 26121 ast_channel_unlock(p->owner); 26122 } 26123 if (owner_chan_ref) { 26124 ast_channel_unref(owner_chan_ref); 26125 } 26126 sip_pvt_unlock(p); 26127 ao2_t_ref(p, -1, "throw away dialog ptr from find_call at end of routine"); /* p is gone after the return */ 26128 ast_mutex_unlock(&netlock); 26129 26130 return 1; 26131 }
| static void handle_request_info | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Receive SIP INFO Message.
Definition at line 19417 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().
19418 { 19419 char buf[1024] = ""; 19420 unsigned int event; 19421 const char *c = get_header(req, "Content-Type"); 19422 19423 /* Need to check the media/type */ 19424 if (!strcasecmp(c, "application/dtmf-relay") || 19425 !strcasecmp(c, "application/vnd.nortelnetworks.digits") || 19426 !strcasecmp(c, "application/dtmf")) { 19427 unsigned int duration = 0; 19428 19429 if (!p->owner) { /* not a PBX call */ 19430 transmit_response(p, "481 Call leg/transaction does not exist", req); 19431 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 19432 return; 19433 } 19434 19435 /* If dtmf-relay or vnd.nortelnetworks.digits, parse the signal and duration; 19436 * otherwise use the body as the signal */ 19437 if (strcasecmp(c, "application/dtmf")) { 19438 const char *msg_body; 19439 19440 if ( ast_strlen_zero(msg_body = get_body(req, "Signal", '=')) 19441 && ast_strlen_zero(msg_body = get_body(req, "d", '='))) { 19442 ast_log(LOG_WARNING, "Unable to retrieve DTMF signal for INFO message on " 19443 "call %s\n", p->callid); 19444 transmit_response(p, "200 OK", req); 19445 return; 19446 } 19447 ast_copy_string(buf, msg_body, sizeof(buf)); 19448 19449 if (!ast_strlen_zero((msg_body = get_body(req, "Duration", '=')))) { 19450 sscanf(msg_body, "%30u", &duration); 19451 } 19452 } else { 19453 /* Type is application/dtmf, simply use what's in the message body */ 19454 get_msg_text(buf, sizeof(buf), req); 19455 } 19456 19457 /* An empty message body requires us to send a 200 OK */ 19458 if (ast_strlen_zero(buf)) { 19459 transmit_response(p, "200 OK", req); 19460 return; 19461 } 19462 19463 if (!duration) { 19464 duration = 100; /* 100 ms */ 19465 } 19466 19467 if (buf[0] == '*') { 19468 event = 10; 19469 } else if (buf[0] == '#') { 19470 event = 11; 19471 } else if (buf[0] == '!') { 19472 event = 16; 19473 } else if ('A' <= buf[0] && buf[0] <= 'D') { 19474 event = 12 + buf[0] - 'A'; 19475 } else if ('a' <= buf[0] && buf[0] <= 'd') { 19476 event = 12 + buf[0] - 'a'; 19477 } else if ((sscanf(buf, "%30u", &event) != 1) || event > 16) { 19478 ast_log(AST_LOG_WARNING, "Unable to convert DTMF event signal code to a valid " 19479 "value for INFO message on call %s\n", p->callid); 19480 transmit_response(p, "200 OK", req); 19481 return; 19482 } 19483 19484 if (event == 16) { 19485 /* send a FLASH event */ 19486 struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_FLASH, } }; 19487 ast_queue_frame(p->owner, &f); 19488 if (sipdebug) { 19489 ast_verbose("* DTMF-relay event received: FLASH\n"); 19490 } 19491 } else { 19492 /* send a DTMF event */ 19493 struct ast_frame f = { AST_FRAME_DTMF, }; 19494 if (event < 10) { 19495 f.subclass.integer = '0' + event; 19496 } else if (event == 10) { 19497 f.subclass.integer = '*'; 19498 } else if (event == 11) { 19499 f.subclass.integer = '#'; 19500 } else { 19501 f.subclass.integer = 'A' + (event - 12); 19502 } 19503 f.len = duration; 19504 ast_queue_frame(p->owner, &f); 19505 if (sipdebug) { 19506 ast_verbose("* DTMF-relay event received: %c\n", (int) f.subclass.integer); 19507 } 19508 } 19509 transmit_response(p, "200 OK", req); 19510 return; 19511 } else if (!strcasecmp(c, "application/media_control+xml")) { 19512 /* Eh, we'll just assume it's a fast picture update for now */ 19513 if (p->owner) 19514 ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE); 19515 transmit_response(p, "200 OK", req); 19516 return; 19517 } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) { 19518 /* Client code (from SNOM phone) */ 19519 if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) { 19520 if (p->owner && p->owner->cdr) 19521 ast_cdr_setuserfield(p->owner, c); 19522 if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr) 19523 ast_cdr_setuserfield(ast_bridged_channel(p->owner), c); 19524 transmit_response(p, "200 OK", req); 19525 } else { 19526 transmit_response(p, "403 Forbidden", req); 19527 } 19528 return; 19529 } else if (!ast_strlen_zero(c = get_header(req, "Record"))) { 19530 /* INFO messages generated by some phones to start/stop recording 19531 on phone calls. 19532 OEJ: I think this should be something that is enabled/disabled 19533 per device. I don't want incoming callers to record calls in my 19534 pbx. 19535 */ 19536 19537 struct ast_call_feature *feat; 19538 int j; 19539 struct ast_frame f = { AST_FRAME_DTMF, }; 19540 19541 if (!p->owner) { /* not a PBX call */ 19542 transmit_response(p, "481 Call leg/transaction does not exist", req); 19543 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 19544 return; 19545 } 19546 19547 /* first, get the feature string, if it exists */ 19548 ast_rdlock_call_features(); 19549 feat = ast_find_call_feature("automon"); 19550 if (!feat || ast_strlen_zero(feat->exten)) { 19551 ast_log(LOG_WARNING, "Recording requested, but no One Touch Monitor registered. (See features.conf)\n"); 19552 /* 403 means that we don't support this feature, so don't request it again */ 19553 transmit_response(p, "403 Forbidden", req); 19554 ast_unlock_call_features(); 19555 return; 19556 } 19557 /* Send the feature code to the PBX as DTMF, just like the handset had sent it */ 19558 f.len = 100; 19559 for (j=0; j < strlen(feat->exten); j++) { 19560 f.subclass.integer = feat->exten[j]; 19561 ast_queue_frame(p->owner, &f); 19562 if (sipdebug) 19563 ast_verbose("* DTMF-relay event faked: %c\n", f.subclass.integer); 19564 } 19565 ast_unlock_call_features(); 19566 19567 ast_debug(1, "Got a Request to Record the channel, state %s\n", c); 19568 transmit_response(p, "200 OK", req); 19569 return; 19570 } else if (ast_strlen_zero(c = get_header(req, "Content-Length")) || !strcasecmp(c, "0")) { 19571 /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */ 19572 transmit_response(p, "200 OK", req); 19573 return; 19574 } 19575 19576 /* Other type of INFO message, not really understood by Asterisk */ 19577 /* if (get_msg_text(buf, sizeof(buf), req)) { */ 19578 19579 ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf); 19580 transmit_response(p, "415 Unsupported media type", req); 19581 return; 19582 }
| 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 22910 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(), ast_channel::hangupcause, ast_party_connected_line::id, ast_set_party_connected_line::id, LOG_ERROR, LOG_NOTICE, LOG_WARNING, make_our_tag(), MAX, ast_party_id::name, ast_set_party_id::name, ast_party_id::number, ast_set_party_id::number, parse_minse(), parse_ok_contact(), parse_session_expires(), parse_sip_options(), ast_party_name::presentation, ast_party_number::presentation, process_sdp(), 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_st_alloc(), sip_t38_abort(), sip_uri_cmp(), ast_party_connected_line::source, st_get_mode(), st_get_refresher(), st_get_se(), start_session_timer(), ast_party_name::str, ast_party_number::str, ast_party_id::tag, cfsip_methods::text, transmit_provisional_response(), transmit_response(), transmit_response_reliable(), transmit_response_with_minse(), transmit_response_with_sdp(), transmit_response_with_t38_sdp(), transmit_response_with_unsupported(), TRUE, unref_peer(), update_call_counter(), update_redirecting(), ast_party_name::valid, and ast_party_number::valid.
Referenced by handle_incoming().
22911 { 22912 int res = 1; 22913 int gotdest; 22914 const char *p_replaces; 22915 char *replace_id = NULL; 22916 int refer_locked = 0; 22917 const char *required; 22918 unsigned int required_profile = 0; 22919 struct ast_channel *c = NULL; /* New channel */ 22920 struct sip_peer *authpeer = NULL; /* Matching Peer */ 22921 int reinvite = 0; 22922 int rtn; 22923 struct ast_party_redirecting redirecting; 22924 struct ast_set_party_redirecting update_redirecting; 22925 22926 const char *p_uac_se_hdr; /* UAC's Session-Expires header string */ 22927 const char *p_uac_min_se; /* UAC's requested Min-SE interval (char string) */ 22928 int uac_max_se = -1; /* UAC's Session-Expires in integer format */ 22929 int uac_min_se = -1; /* UAC's Min-SE in integer format */ 22930 int st_active = FALSE; /* Session-Timer on/off boolean */ 22931 int st_interval = 0; /* Session-Timer negotiated refresh interval */ 22932 enum st_refresher tmp_st_ref = SESSION_TIMER_REFRESHER_AUTO; /* Session-Timer refresher */ 22933 int dlg_min_se = -1; 22934 int dlg_max_se = global_max_se; 22935 struct { 22936 char exten[AST_MAX_EXTENSION]; 22937 char context[AST_MAX_CONTEXT]; 22938 } pickup = { 22939 .exten = "", 22940 }; 22941 22942 /* Find out what they support */ 22943 if (!p->sipoptions) { 22944 const char *supported = get_header(req, "Supported"); 22945 if (!ast_strlen_zero(supported)) { 22946 p->sipoptions = parse_sip_options(supported, NULL, 0); 22947 } 22948 } 22949 22950 /* Find out what they require */ 22951 required = get_header(req, "Require"); 22952 if (!ast_strlen_zero(required)) { 22953 char unsupported[256] = { 0, }; 22954 required_profile = parse_sip_options(required, unsupported, ARRAY_LEN(unsupported)); 22955 22956 /* If there are any options required that we do not support, 22957 * then send a 420 with only those unsupported options listed */ 22958 if (!ast_strlen_zero(unsupported)) { 22959 transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, unsupported); 22960 ast_log(LOG_WARNING, "Received SIP INVITE with unsupported required extension: required:%s unsupported:%s\n", required, unsupported); 22961 p->invitestate = INV_COMPLETED; 22962 if (!p->lastinvite) 22963 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22964 res = -1; 22965 goto request_invite_cleanup; 22966 } 22967 } 22968 22969 /* The option tags may be present in Supported: or Require: headers. 22970 Include the Require: option tags for further processing as well */ 22971 p->sipoptions |= required_profile; 22972 p->reqsipoptions = required_profile; 22973 22974 /* Check if this is a loop */ 22975 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) { 22976 /* This is a call to ourself. Send ourselves an error code and stop 22977 processing immediately, as SIP really has no good mechanism for 22978 being able to call yourself */ 22979 /* If pedantic is on, we need to check the tags. If they're different, this is 22980 in fact a forked call through a SIP proxy somewhere. */ 22981 int different; 22982 const char *initial_rlPart2 = REQ_OFFSET_TO_STR(&p->initreq, rlPart2); 22983 const char *this_rlPart2 = REQ_OFFSET_TO_STR(req, rlPart2); 22984 if (sip_cfg.pedanticsipchecking) 22985 different = sip_uri_cmp(initial_rlPart2, this_rlPart2); 22986 else 22987 different = strcmp(initial_rlPart2, this_rlPart2); 22988 if (!different) { 22989 transmit_response(p, "482 Loop Detected", req); 22990 p->invitestate = INV_COMPLETED; 22991 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22992 res = 0; 22993 goto request_invite_cleanup; 22994 } else { 22995 /*! This is a spiral. What we need to do is to just change the outgoing INVITE 22996 * so that it now routes to the new Request URI. Since we created the INVITE ourselves 22997 * that should be all we need to do. 22998 * 22999 * \todo XXX This needs to be reviewed. YOu don't change the request URI really, you route the packet 23000 * correctly instead... 23001 */ 23002 char *uri = ast_strdupa(this_rlPart2); 23003 char *at = strchr(uri, '@'); 23004 char *peerorhost; 23005 ast_debug(2, "Potential spiral detected. Original RURI was %s, new RURI is %s\n", initial_rlPart2, this_rlPart2); 23006 transmit_response(p, "100 Trying", req); 23007 if (at) { 23008 *at = '\0'; 23009 } 23010 /* Parse out "sip:" */ 23011 if ((peerorhost = strchr(uri, ':'))) { 23012 *peerorhost++ = '\0'; 23013 } 23014 ast_string_field_set(p, theirtag, NULL); 23015 /* Treat this as if there were a call forward instead... 23016 */ 23017 ast_string_field_set(p->owner, call_forward, peerorhost); 23018 ast_queue_control(p->owner, AST_CONTROL_BUSY); 23019 res = 0; 23020 goto request_invite_cleanup; 23021 } 23022 } 23023 23024 if (!req->ignore && p->pendinginvite) { 23025 if (!ast_test_flag(&p->flags[0], SIP_OUTGOING) && (p->invitestate == INV_COMPLETED || p->invitestate == INV_TERMINATED)) { 23026 /* What do these circumstances mean? We have received an INVITE for an "incoming" dialog for which we 23027 * have sent a final response. We have not yet received an ACK, though (which is why p->pendinginvite is non-zero). 23028 * We also know that the INVITE is not a retransmission, because otherwise the "ignore" flag would be set. 23029 * This means that either we are receiving a reinvite for a terminated dialog, or we are receiving an INVITE with 23030 * credentials based on one we challenged earlier. 23031 * 23032 * The action to take in either case is to treat the INVITE as though it contains an implicit ACK for the previous 23033 * transaction. Calling __sip_ack will take care of this by clearing the p->pendinginvite and removing the response 23034 * from the previous transaction from the list of outstanding packets. 23035 */ 23036 __sip_ack(p, p->pendinginvite, 1, 0); 23037 } else { 23038 /* We already have a pending invite. Sorry. You are on hold. */ 23039 p->glareinvite = seqno; 23040 if (p->rtp && find_sdp(req)) { 23041 struct ast_sockaddr addr; 23042 if (get_ip_and_port_from_sdp(req, SDP_AUDIO, &addr)) { 23043 ast_log(LOG_WARNING, "Failed to set an alternate media source on glared reinvite. Audio may not work properly on this call.\n"); 23044 } else { 23045 ast_rtp_instance_set_alt_remote_address(p->rtp, &addr); 23046 } 23047 if (p->vrtp) { 23048 if (get_ip_and_port_from_sdp(req, SDP_VIDEO, &addr)) { 23049 ast_log(LOG_WARNING, "Failed to set an alternate media source on glared reinvite. Video may not work properly on this call.\n"); 23050 } else { 23051 ast_rtp_instance_set_alt_remote_address(p->vrtp, &addr); 23052 } 23053 } 23054 } 23055 transmit_response_reliable(p, "491 Request Pending", req); 23056 check_via(p, req); 23057 ast_debug(1, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid); 23058 /* Don't destroy dialog here */ 23059 res = 0; 23060 goto request_invite_cleanup; 23061 } 23062 } 23063 23064 p_replaces = get_header(req, "Replaces"); 23065 if (!ast_strlen_zero(p_replaces)) { 23066 /* We have a replaces header */ 23067 char *ptr; 23068 char *fromtag = NULL; 23069 char *totag = NULL; 23070 char *start, *to; 23071 int error = 0; 23072 23073 if (p->owner) { 23074 ast_debug(3, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid); 23075 transmit_response_reliable(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 23076 check_via(p, req); 23077 copy_request(&p->initreq, req); 23078 /* Do not destroy existing call */ 23079 res = -1; 23080 goto request_invite_cleanup; 23081 } 23082 23083 if (sipdebug) 23084 ast_debug(3, "INVITE part of call transfer. Replaces [%s]\n", p_replaces); 23085 /* Create a buffer we can manipulate */ 23086 replace_id = ast_strdupa(p_replaces); 23087 ast_uri_decode(replace_id); 23088 23089 if (!p->refer && !sip_refer_allocate(p)) { 23090 transmit_response_reliable(p, "500 Server Internal Error", req); 23091 append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory."); 23092 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23093 p->invitestate = INV_COMPLETED; 23094 check_via(p, req); 23095 copy_request(&p->initreq, req); 23096 res = -1; 23097 goto request_invite_cleanup; 23098 } 23099 23100 /* Todo: (When we find phones that support this) 23101 if the replaces header contains ";early-only" 23102 we can only replace the call in early 23103 stage, not after it's up. 23104 23105 If it's not in early mode, 486 Busy. 23106 */ 23107 23108 /* Skip leading whitespace */ 23109 replace_id = ast_skip_blanks(replace_id); 23110 23111 start = replace_id; 23112 while ( (ptr = strsep(&start, ";")) ) { 23113 ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */ 23114 if ( (to = strcasestr(ptr, "to-tag=") ) ) 23115 totag = to + 7; /* skip the keyword */ 23116 else if ( (to = strcasestr(ptr, "from-tag=") ) ) { 23117 fromtag = to + 9; /* skip the keyword */ 23118 fromtag = strsep(&fromtag, "&"); /* trim what ? */ 23119 } 23120 } 23121 23122 if (sipdebug) 23123 ast_debug(4, "Invite/replaces: Will use Replace-Call-ID : %s Fromtag: %s Totag: %s\n", 23124 replace_id, 23125 fromtag ? fromtag : "<no from tag>", 23126 totag ? totag : "<no to tag>"); 23127 23128 /* Try to find call that we are replacing. 23129 If we have a Replaces header, we need to cancel that call if we succeed with this call. 23130 First we cheat a little and look for a magic call-id from phones that support 23131 dialog-info+xml so we can do technology independent pickup... */ 23132 if (strncmp(replace_id, "pickup-", 7) == 0) { 23133 struct sip_pvt *subscription = NULL; 23134 replace_id += 7; /* Worst case we are looking at \0 */ 23135 23136 if ((subscription = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) { 23137 ast_log(LOG_NOTICE, "Unable to find subscription with call-id: %s\n", replace_id); 23138 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replaces)", req); 23139 error = 1; 23140 } else { 23141 ast_log(LOG_NOTICE, "Trying to pick up %s@%s\n", subscription->exten, subscription->context); 23142 ast_copy_string(pickup.exten, subscription->exten, sizeof(pickup.exten)); 23143 ast_copy_string(pickup.context, subscription->context, sizeof(pickup.context)); 23144 sip_pvt_unlock(subscription); 23145 if (subscription->owner) { 23146 ast_channel_unlock(subscription->owner); 23147 } 23148 subscription = dialog_unref(subscription, "unref dialog subscription"); 23149 } 23150 } 23151 23152 /* This locks both refer_call pvt and refer_call pvt's owner!!!*/ 23153 if (!error && ast_strlen_zero(pickup.exten) && (p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) { 23154 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id); 23155 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replaces)", req); 23156 error = 1; 23157 } else { 23158 refer_locked = 1; 23159 } 23160 23161 /* The matched call is the call from the transferer to Asterisk . 23162 We want to bridge the bridged part of the call to the 23163 incoming invite, thus taking over the refered call */ 23164 23165 if (p->refer->refer_call == p) { 23166 ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid); 23167 transmit_response_reliable(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 23168 error = 1; 23169 } 23170 23171 if (!error && ast_strlen_zero(pickup.exten) && !p->refer->refer_call->owner) { 23172 /* Oops, someting wrong anyway, no owner, no call */ 23173 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id); 23174 /* Check for better return code */ 23175 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replace)", req); 23176 error = 1; 23177 } 23178 23179 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) { 23180 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id); 23181 transmit_response_reliable(p, "603 Declined (Replaces)", req); 23182 error = 1; 23183 } 23184 23185 if (error) { /* Give up this dialog */ 23186 append_history(p, "Xfer", "INVITE/Replace Failed."); 23187 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23188 sip_pvt_unlock(p); 23189 if (p->refer->refer_call) { 23190 sip_pvt_unlock(p->refer->refer_call); 23191 if (p->refer->refer_call->owner) { 23192 ast_channel_unlock(p->refer->refer_call->owner); 23193 } 23194 p->refer->refer_call = dialog_unref(p->refer->refer_call, "unref dialog p->refer->refer_call"); 23195 } 23196 refer_locked = 0; 23197 p->invitestate = INV_COMPLETED; 23198 check_via(p, req); 23199 copy_request(&p->initreq, req); 23200 res = -1; 23201 goto request_invite_cleanup; 23202 } 23203 } 23204 23205 /* Check if this is an INVITE that sets up a new dialog or 23206 a re-invite in an existing dialog */ 23207 23208 if (!req->ignore) { 23209 int newcall = (p->initreq.headers ? TRUE : FALSE); 23210 23211 if (sip_cancel_destroy(p)) 23212 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 23213 /* This also counts as a pending invite */ 23214 p->pendinginvite = seqno; 23215 check_via(p, req); 23216 23217 copy_request(&p->initreq, req); /* Save this INVITE as the transaction basis */ 23218 if (sipdebug) 23219 ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid); 23220 if (!p->owner) { /* Not a re-invite */ 23221 if (debug) 23222 ast_verbose("Using INVITE request as basis request - %s\n", p->callid); 23223 if (newcall) 23224 append_history(p, "Invite", "New call: %s", p->callid); 23225 parse_ok_contact(p, req); 23226 } else { /* Re-invite on existing call */ 23227 ast_clear_flag(&p->flags[0], SIP_OUTGOING); /* This is now an inbound dialog */ 23228 if (get_rpid(p, req)) { 23229 struct ast_party_connected_line connected; 23230 struct ast_set_party_connected_line update_connected; 23231 23232 ast_party_connected_line_init(&connected); 23233 memset(&update_connected, 0, sizeof(update_connected)); 23234 23235 update_connected.id.number = 1; 23236 connected.id.number.valid = 1; 23237 connected.id.number.str = (char *) p->cid_num; 23238 connected.id.number.presentation = p->callingpres; 23239 23240 update_connected.id.name = 1; 23241 connected.id.name.valid = 1; 23242 connected.id.name.str = (char *) p->cid_name; 23243 connected.id.name.presentation = p->callingpres; 23244 23245 connected.id.tag = (char *) p->cid_tag; 23246 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER; 23247 ast_channel_queue_connected_line_update(p->owner, &connected, 23248 &update_connected); 23249 } 23250 /* Handle SDP here if we already have an owner */ 23251 if (find_sdp(req)) { 23252 if (process_sdp(p, req, SDP_T38_INITIATE)) { 23253 if (!ast_strlen_zero(get_header(req, "Content-Encoding"))) { 23254 /* Asterisk does not yet support any Content-Encoding methods. Always 23255 * attempt to process the sdp, but return a 415 if a Content-Encoding header 23256 * was present after processing failed. */ 23257 transmit_response_reliable(p, "415 Unsupported Media type", req); 23258 } else { 23259 transmit_response_reliable(p, "488 Not acceptable here", req); 23260 } 23261 if (!p->lastinvite) 23262 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23263 res = -1; 23264 goto request_invite_cleanup; 23265 } 23266 ast_queue_control(p->owner, AST_CONTROL_SRCUPDATE); 23267 } else { 23268 p->jointcapability = p->capability; 23269 ast_debug(1, "Hm.... No sdp for the moment\n"); 23270 /* Some devices signal they want to be put off hold by sending a re-invite 23271 *without* an SDP, which is supposed to mean "Go back to your state" 23272 and since they put os on remote hold, we go back to off hold */ 23273 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 23274 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 23275 /* Activate a re-invite */ 23276 ast_queue_frame(p->owner, &ast_null_frame); 23277 change_hold_state(p, req, FALSE, 0); 23278 } 23279 } 23280 if (p->do_history) /* This is a response, note what it was for */ 23281 append_history(p, "ReInv", "Re-invite received"); 23282 } 23283 } else if (debug) 23284 ast_verbose("Ignoring this INVITE request\n"); 23285 23286 if (!p->lastinvite && !req->ignore && !p->owner) { 23287 /* This is a new invite */ 23288 /* Handle authentication if this is our first invite */ 23289 int cc_recall_core_id = -1; 23290 set_pvt_allowed_methods(p, req); 23291 res = check_user_full(p, req, SIP_INVITE, e, XMIT_RELIABLE, addr, &authpeer); 23292 if (res == AUTH_CHALLENGE_SENT) { 23293 p->invitestate = INV_COMPLETED; /* Needs to restart in another INVITE transaction */ 23294 res = 0; 23295 goto request_invite_cleanup; 23296 } 23297 if (res < 0) { /* Something failed in authentication */ 23298 ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From")); 23299 transmit_response_reliable(p, "403 Forbidden", req); 23300 p->invitestate = INV_COMPLETED; 23301 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23302 res = 0; 23303 goto request_invite_cleanup; 23304 } 23305 23306 /* Successful authentication and peer matching so record the peer related to this pvt (for easy access to peer settings) */ 23307 if (p->relatedpeer) { 23308 p->relatedpeer = unref_peer(p->relatedpeer,"unsetting the relatedpeer field in the dialog, before it is set to something else."); 23309 } 23310 if (authpeer) { 23311 p->relatedpeer = ref_peer(authpeer, "setting dialog's relatedpeer pointer"); 23312 } 23313 23314 req->authenticated = 1; 23315 23316 /* We have a successful authentication, process the SDP portion if there is one */ 23317 if (find_sdp(req)) { 23318 if (process_sdp(p, req, SDP_T38_INITIATE)) { 23319 /* Asterisk does not yet support any Content-Encoding methods. Always 23320 * attempt to process the sdp, but return a 415 if a Content-Encoding header 23321 * was present after processing fails. */ 23322 if (!ast_strlen_zero(get_header(req, "Content-Encoding"))) { 23323 transmit_response_reliable(p, "415 Unsupported Media type", req); 23324 } else { 23325 /* Unacceptable codecs */ 23326 transmit_response_reliable(p, "488 Not acceptable here", req); 23327 } 23328 p->invitestate = INV_COMPLETED; 23329 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23330 ast_debug(1, "No compatible codecs for this SIP call.\n"); 23331 res = -1; 23332 goto request_invite_cleanup; 23333 } 23334 } else { /* No SDP in invite, call control session */ 23335 p->jointcapability = p->capability; 23336 ast_debug(2, "No SDP in Invite, third party call control\n"); 23337 } 23338 23339 /* Queue NULL frame to prod ast_rtp_bridge if appropriate */ 23340 /* This seems redundant ... see !p-owner above */ 23341 if (p->owner) 23342 ast_queue_frame(p->owner, &ast_null_frame); 23343 23344 23345 /* Initialize the context if it hasn't been already */ 23346 if (ast_strlen_zero(p->context)) 23347 ast_string_field_set(p, context, sip_cfg.default_context); 23348 23349 23350 /* Check number of concurrent calls -vs- incoming limit HERE */ 23351 ast_debug(1, "Checking SIP call limits for device %s\n", p->username); 23352 if ((res = update_call_counter(p, INC_CALL_LIMIT))) { 23353 if (res < 0) { 23354 ast_log(LOG_NOTICE, "Failed to place call for device %s, too many calls\n", p->username); 23355 transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req); 23356 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23357 p->invitestate = INV_COMPLETED; 23358 } 23359 res = 0; 23360 goto request_invite_cleanup; 23361 } 23362 gotdest = get_destination(p, NULL, &cc_recall_core_id); /* Get destination right away */ 23363 extract_uri(p, req); /* Get the Contact URI */ 23364 build_contact(p); /* Build our contact header */ 23365 23366 if (p->rtp) { 23367 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 23368 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 23369 } 23370 23371 if (!replace_id && (gotdest != SIP_GET_DEST_EXTEN_FOUND)) { /* No matching extension found */ 23372 switch(gotdest) { 23373 case SIP_GET_DEST_INVALID_URI: 23374 transmit_response_reliable(p, "416 Unsupported URI scheme", req); 23375 break; 23376 case SIP_GET_DEST_EXTEN_MATCHMORE: 23377 if (ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP) 23378 == SIP_PAGE2_ALLOWOVERLAP_YES) { 23379 transmit_response_reliable(p, "484 Address Incomplete", req); 23380 break; 23381 } 23382 /* 23383 * XXX We would have to implement collecting more digits in 23384 * chan_sip for any other schemes of overlap dialing. 23385 * 23386 * For SIP_PAGE2_ALLOWOVERLAP_DTMF it is better to do this in 23387 * the dialplan using the Incomplete application rather than 23388 * having the channel driver do it. 23389 */ 23390 /* Fall through */ 23391 case SIP_GET_DEST_EXTEN_NOT_FOUND: 23392 { 23393 char *decoded_exten = ast_strdupa(p->exten); 23394 transmit_response_reliable(p, "404 Not Found", req); 23395 ast_uri_decode(decoded_exten); 23396 ast_log(LOG_NOTICE, "Call from '%s' (%s) to extension" 23397 " '%s' rejected because extension not found in context '%s'.\n", 23398 S_OR(p->username, p->peername), ast_sockaddr_stringify(&p->recv), decoded_exten, p->context); 23399 } 23400 break; 23401 case SIP_GET_DEST_REFUSED: 23402 default: 23403 transmit_response_reliable(p, "403 Forbidden", req); 23404 } /* end switch */ 23405 23406 p->invitestate = INV_COMPLETED; 23407 update_call_counter(p, DEC_CALL_LIMIT); 23408 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23409 res = 0; 23410 goto request_invite_cleanup; 23411 } else { 23412 23413 /* If no extension was specified, use the s one */ 23414 /* Basically for calling to IP/Host name only */ 23415 if (ast_strlen_zero(p->exten)) 23416 ast_string_field_set(p, exten, "s"); 23417 /* Initialize our tag */ 23418 23419 make_our_tag(p); 23420 /* First invitation - create the channel. Allocation 23421 * failures are handled below. */ 23422 c = sip_new(p, AST_STATE_DOWN, S_OR(p->peername, NULL), NULL); 23423 if (cc_recall_core_id != -1) { 23424 ast_setup_cc_recall_datastore(c, cc_recall_core_id); 23425 ast_cc_agent_set_interfaces_chanvar(c); 23426 } 23427 *recount = 1; 23428 23429 /* Save Record-Route for any later requests we make on this dialogue */ 23430 build_route(p, req, 0, 0); 23431 23432 if (c) { 23433 ast_party_redirecting_init(&redirecting); 23434 memset(&update_redirecting, 0, sizeof(update_redirecting)); 23435 change_redirecting_information(p, req, &redirecting, &update_redirecting, 23436 FALSE); /*Will return immediately if no Diversion header is present */ 23437 ast_channel_set_redirecting(c, &redirecting, &update_redirecting); 23438 ast_party_redirecting_free(&redirecting); 23439 } 23440 } 23441 } else { 23442 ast_party_redirecting_init(&redirecting); 23443 memset(&update_redirecting, 0, sizeof(update_redirecting)); 23444 if (sipdebug) { 23445 if (!req->ignore) 23446 ast_debug(2, "Got a SIP re-invite for call %s\n", p->callid); 23447 else 23448 ast_debug(2, "Got a SIP re-transmit of INVITE for call %s\n", p->callid); 23449 } 23450 if (!req->ignore) 23451 reinvite = 1; 23452 c = p->owner; 23453 change_redirecting_information(p, req, &redirecting, &update_redirecting, FALSE); /*Will return immediately if no Diversion header is present */ 23454 if (c) { 23455 ast_channel_set_redirecting(c, &redirecting, &update_redirecting); 23456 } 23457 ast_party_redirecting_free(&redirecting); 23458 } 23459 23460 /* Session-Timers */ 23461 if ((p->sipoptions & SIP_OPT_TIMER)) { 23462 enum st_refresher_param st_ref_param = SESSION_TIMER_REFRESHER_PARAM_UNKNOWN; 23463 23464 /* The UAC has requested session-timers for this session. Negotiate 23465 the session refresh interval and who will be the refresher */ 23466 ast_debug(2, "Incoming INVITE with 'timer' option supported\n"); 23467 23468 /* Allocate Session-Timers struct w/in the dialog */ 23469 if (!p->stimer) 23470 sip_st_alloc(p); 23471 23472 /* Parse the Session-Expires header */ 23473 p_uac_se_hdr = get_header(req, "Session-Expires"); 23474 if (!ast_strlen_zero(p_uac_se_hdr)) { 23475 ast_debug(2, "INVITE also has \"Session-Expires\" header.\n"); 23476 rtn = parse_session_expires(p_uac_se_hdr, &uac_max_se, &st_ref_param); 23477 tmp_st_ref = (st_ref_param == SESSION_TIMER_REFRESHER_PARAM_UAC) ? SESSION_TIMER_REFRESHER_THEM : SESSION_TIMER_REFRESHER_US; 23478 if (rtn != 0) { 23479 transmit_response_reliable(p, "400 Session-Expires Invalid Syntax", req); 23480 p->invitestate = INV_COMPLETED; 23481 if (!p->lastinvite) { 23482 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23483 } 23484 res = -1; 23485 goto request_invite_cleanup; 23486 } 23487 } 23488 23489 /* Parse the Min-SE header */ 23490 p_uac_min_se = get_header(req, "Min-SE"); 23491 if (!ast_strlen_zero(p_uac_min_se)) { 23492 ast_debug(2, "INVITE also has \"Min-SE\" header.\n"); 23493 rtn = parse_minse(p_uac_min_se, &uac_min_se); 23494 if (rtn != 0) { 23495 transmit_response_reliable(p, "400 Min-SE Invalid Syntax", req); 23496 p->invitestate = INV_COMPLETED; 23497 if (!p->lastinvite) { 23498 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23499 } 23500 res = -1; 23501 goto request_invite_cleanup; 23502 } 23503 } 23504 23505 dlg_min_se = st_get_se(p, FALSE); 23506 switch (st_get_mode(p, 1)) { 23507 case SESSION_TIMER_MODE_ACCEPT: 23508 case SESSION_TIMER_MODE_ORIGINATE: 23509 if (uac_max_se > 0 && uac_max_se < dlg_min_se) { 23510 transmit_response_with_minse(p, "422 Session Interval Too Small", req, dlg_min_se); 23511 p->invitestate = INV_COMPLETED; 23512 if (!p->lastinvite) { 23513 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23514 } 23515 res = -1; 23516 goto request_invite_cleanup; 23517 } 23518 23519 p->stimer->st_active_peer_ua = TRUE; 23520 st_active = TRUE; 23521 if (st_ref_param == SESSION_TIMER_REFRESHER_PARAM_UNKNOWN) { 23522 tmp_st_ref = st_get_refresher(p); 23523 } 23524 23525 dlg_max_se = st_get_se(p, TRUE); 23526 if (uac_max_se > 0) { 23527 if (dlg_max_se >= uac_min_se) { 23528 st_interval = (uac_max_se < dlg_max_se) ? uac_max_se : dlg_max_se; 23529 } else { 23530 st_interval = uac_max_se; 23531 } 23532 } else if (uac_min_se > 0) { 23533 st_interval = MAX(dlg_max_se, uac_min_se); 23534 } else { 23535 st_interval = dlg_max_se; 23536 } 23537 break; 23538 23539 case SESSION_TIMER_MODE_REFUSE: 23540 if (p->reqsipoptions & SIP_OPT_TIMER) { 23541 transmit_response_with_unsupported(p, "420 Option Disabled", req, required); 23542 ast_log(LOG_WARNING, "Received SIP INVITE with supported but disabled option: %s\n", required); 23543 p->invitestate = INV_COMPLETED; 23544 if (!p->lastinvite) { 23545 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23546 } 23547 res = -1; 23548 goto request_invite_cleanup; 23549 } 23550 break; 23551 23552 default: 23553 ast_log(LOG_ERROR, "Internal Error %d at %s:%d\n", st_get_mode(p, 1), __FILE__, __LINE__); 23554 break; 23555 } 23556 } else { 23557 /* The UAC did not request session-timers. Asterisk (UAS), will now decide 23558 (based on session-timer-mode in sip.conf) whether to run session-timers for 23559 this session or not. */ 23560 switch (st_get_mode(p, 1)) { 23561 case SESSION_TIMER_MODE_ORIGINATE: 23562 st_active = TRUE; 23563 st_interval = st_get_se(p, TRUE); 23564 tmp_st_ref = SESSION_TIMER_REFRESHER_US; 23565 p->stimer->st_active_peer_ua = (p->sipoptions & SIP_OPT_TIMER) ? TRUE : FALSE; 23566 break; 23567 23568 default: 23569 break; 23570 } 23571 } 23572 23573 if (reinvite == 0) { 23574 /* Session-Timers: Start session refresh timer based on negotiation/config */ 23575 if (st_active == TRUE) { 23576 p->stimer->st_active = TRUE; 23577 p->stimer->st_interval = st_interval; 23578 p->stimer->st_ref = tmp_st_ref; 23579 start_session_timer(p); 23580 } 23581 } else { 23582 if (p->stimer->st_active == TRUE) { 23583 /* Session-Timers: A re-invite request sent within a dialog will serve as 23584 a refresh request, no matter whether the re-invite was sent for refreshing 23585 the session or modifying it.*/ 23586 ast_debug (2, "Restarting session-timers on a refresh - %s\n", p->callid); 23587 23588 /* The UAC may be adjusting the session-timers mid-session */ 23589 if (st_interval > 0) { 23590 p->stimer->st_interval = st_interval; 23591 p->stimer->st_ref = tmp_st_ref; 23592 } 23593 23594 restart_session_timer(p); 23595 if (p->stimer->st_expirys > 0) { 23596 p->stimer->st_expirys--; 23597 } 23598 } 23599 } 23600 23601 if (!req->ignore && p) 23602 p->lastinvite = seqno; 23603 23604 if (c && replace_id) { /* Attended transfer or call pickup - we're the target */ 23605 if (!ast_strlen_zero(pickup.exten)) { 23606 append_history(p, "Xfer", "INVITE/Replace received"); 23607 23608 /* Let the caller know we're giving it a shot */ 23609 transmit_response(p, "100 Trying", req); 23610 p->invitestate = INV_PROCEEDING; 23611 ast_setstate(c, AST_STATE_RING); 23612 23613 /* Do the pickup itself */ 23614 ast_channel_unlock(c); 23615 *nounlock = 1; 23616 23617 /* since p->owner (c) is unlocked, we need to go ahead and unlock pvt for both 23618 * magic pickup and ast_hangup. Both of these functions will attempt to lock 23619 * p->owner again, which can cause a deadlock if we already hold a lock on p. 23620 * Locking order is, channel then pvt. Dead lock avoidance must be used if 23621 * called the other way around. */ 23622 sip_pvt_unlock(p); 23623 do_magic_pickup(c, pickup.exten, pickup.context); 23624 /* Now we're either masqueraded or we failed to pickup, in either case we... */ 23625 ast_hangup(c); 23626 sip_pvt_lock(p); /* pvt is expected to remain locked on return, so re-lock it */ 23627 23628 res = 0; 23629 goto request_invite_cleanup; 23630 } else { 23631 /* Go and take over the target call */ 23632 if (sipdebug) 23633 ast_debug(4, "Sending this call to the invite/replcaes handler %s\n", p->callid); 23634 res = handle_invite_replaces(p, req, debug, seqno, addr, nounlock); 23635 refer_locked = 0; 23636 goto request_invite_cleanup; 23637 } 23638 } 23639 23640 23641 if (c) { /* We have a call -either a new call or an old one (RE-INVITE) */ 23642 enum ast_channel_state c_state = c->_state; 23643 23644 if (c_state != AST_STATE_UP && reinvite && 23645 (p->invitestate == INV_TERMINATED || p->invitestate == INV_CONFIRMED)) { 23646 /* If these conditions are true, and the channel is still in the 'ringing' 23647 * state, then this likely means that we have a situation where the initial 23648 * INVITE transaction has completed *but* the channel's state has not yet been 23649 * changed to UP. The reason this could happen is if the reinvite is received 23650 * on the SIP socket prior to an application calling ast_read on this channel 23651 * to read the answer frame we earlier queued on it. In this case, the reinvite 23652 * is completely legitimate so we need to handle this the same as if the channel 23653 * were already UP. Thus we are purposely falling through to the AST_STATE_UP case. 23654 */ 23655 c_state = AST_STATE_UP; 23656 } 23657 23658 switch(c_state) { 23659 case AST_STATE_DOWN: 23660 ast_debug(2, "%s: New call is still down.... Trying... \n", c->name); 23661 transmit_provisional_response(p, "100 Trying", req, 0); 23662 p->invitestate = INV_PROCEEDING; 23663 ast_setstate(c, AST_STATE_RING); 23664 if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */ 23665 enum ast_pbx_result result; 23666 23667 result = ast_pbx_start(c); 23668 23669 switch(result) { 23670 case AST_PBX_FAILED: 23671 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 23672 p->invitestate = INV_COMPLETED; 23673 transmit_response_reliable(p, "503 Unavailable", req); 23674 break; 23675 case AST_PBX_CALL_LIMIT: 23676 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n"); 23677 p->invitestate = INV_COMPLETED; 23678 transmit_response_reliable(p, "480 Temporarily Unavailable", req); 23679 break; 23680 case AST_PBX_SUCCESS: 23681 /* nothing to do */ 23682 break; 23683 } 23684 23685 if (result) { 23686 23687 /* Unlock locks so ast_hangup can do its magic */ 23688 ast_channel_unlock(c); 23689 *nounlock = 1; 23690 sip_pvt_unlock(p); 23691 ast_hangup(c); 23692 sip_pvt_lock(p); 23693 c = NULL; 23694 } 23695 } else { /* Pickup call in call group */ 23696 if (sip_pickup(c)) { 23697 ast_log(LOG_WARNING, "Failed to start Group pickup by %s\n", c->name); 23698 transmit_response_reliable(p, "480 Temporarily Unavailable", req); 23699 sip_alreadygone(p); 23700 c->hangupcause = AST_CAUSE_FAILURE; 23701 23702 /* Unlock locks so ast_hangup can do its magic */ 23703 ast_channel_unlock(c); 23704 *nounlock = 1; 23705 23706 p->invitestate = INV_COMPLETED; 23707 sip_pvt_unlock(p); 23708 ast_hangup(c); 23709 sip_pvt_lock(p); 23710 c = NULL; 23711 } 23712 } 23713 break; 23714 case AST_STATE_RING: 23715 transmit_provisional_response(p, "100 Trying", req, 0); 23716 p->invitestate = INV_PROCEEDING; 23717 break; 23718 case AST_STATE_RINGING: 23719 transmit_provisional_response(p, "180 Ringing", req, 0); 23720 p->invitestate = INV_PROCEEDING; 23721 break; 23722 case AST_STATE_UP: 23723 ast_debug(2, "%s: This call is UP.... \n", c->name); 23724 23725 transmit_response(p, "100 Trying", req); 23726 23727 if (p->t38.state == T38_PEER_REINVITE) { 23728 if (p->t38id > -1) { 23729 /* reset t38 abort timer */ 23730 AST_SCHED_DEL_UNREF(sched, p->t38id, dialog_unref(p, "remove ref for t38id")); 23731 } 23732 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.")); 23733 } else if (p->t38.state == T38_ENABLED) { 23734 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 23735 transmit_response_with_t38_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (req->ignore ? XMIT_UNRELIABLE : XMIT_CRITICAL))); 23736 } else if (p->t38.state == T38_DISABLED) { 23737 /* If this is not a re-invite or something to ignore - it's critical */ 23738 if (p->srtp && !ast_test_flag(p->srtp, SRTP_CRYPTO_OFFER_OK)) { 23739 ast_log(LOG_WARNING, "Target does not support required crypto\n"); 23740 transmit_response_reliable(p, "488 Not Acceptable Here (crypto)", req); 23741 } else { 23742 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 23743 transmit_response_with_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (req->ignore ? XMIT_UNRELIABLE : XMIT_CRITICAL)), p->session_modify == TRUE ? FALSE : TRUE, FALSE); 23744 ast_queue_control(p->owner, AST_CONTROL_UPDATE_RTP_PEER); 23745 } 23746 } 23747 23748 p->invitestate = INV_TERMINATED; 23749 break; 23750 default: 23751 ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state); 23752 transmit_response(p, "100 Trying", req); 23753 break; 23754 } 23755 } else { 23756 if (p && (p->autokillid == -1)) { 23757 const char *msg; 23758 23759 if (!p->jointcapability) 23760 msg = "488 Not Acceptable Here (codec error)"; 23761 else { 23762 ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n"); 23763 msg = "503 Unavailable"; 23764 } 23765 transmit_response_reliable(p, msg, req); 23766 p->invitestate = INV_COMPLETED; 23767 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23768 } 23769 } 23770 23771 request_invite_cleanup: 23772 23773 if (refer_locked && p->refer && p->refer->refer_call) { 23774 sip_pvt_unlock(p->refer->refer_call); 23775 if (p->refer->refer_call->owner) { 23776 ast_channel_unlock(p->refer->refer_call->owner); 23777 } 23778 p->refer->refer_call = dialog_unref(p->refer->refer_call, "unref dialog p->refer->refer_call"); 23779 } 23780 if (authpeer) { 23781 authpeer = unref_peer(authpeer, "unref_peer, from handle_request_invite authpeer"); 23782 } 23783 23784 return res; 23785 }
| static int handle_request_message | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Handle incoming MESSAGE request.
Definition at line 24671 of file chan_sip.c.
References ast_verbose, receive_message(), and transmit_response().
Referenced by handle_incoming().
24672 { 24673 if (!req->ignore) { 24674 if (req->debug) 24675 ast_verbose("Receiving message!\n"); 24676 receive_message(p, req); 24677 } else 24678 transmit_response(p, "202 Accepted", req); 24679 return 1; 24680 }
| 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 22438 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().
22439 { 22440 /* This is mostly a skeleton for future improvements */ 22441 /* Mostly created to return proper answers on notifications on outbound REFER's */ 22442 int res = 0; 22443 const char *event = get_header(req, "Event"); 22444 char *sep; 22445 22446 if( (sep = strchr(event, ';')) ) { /* XXX bug here - overwriting string ? */ 22447 *sep++ = '\0'; 22448 } 22449 22450 if (sipdebug) 22451 ast_debug(2, "Got NOTIFY Event: %s\n", event); 22452 22453 if (!strcmp(event, "refer")) { 22454 /* Save nesting depth for now, since there might be other events we will 22455 support in the future */ 22456 22457 /* Handle REFER notifications */ 22458 22459 char buf[1024]; 22460 char *cmd, *code; 22461 int respcode; 22462 int success = TRUE; 22463 22464 /* EventID for each transfer... EventID is basically the REFER cseq 22465 22466 We are getting notifications on a call that we transfered 22467 We should hangup when we are getting a 200 OK in a sipfrag 22468 Check if we have an owner of this event */ 22469 22470 /* Check the content type */ 22471 if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) { 22472 /* We need a sipfrag */ 22473 transmit_response(p, "400 Bad request", req); 22474 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22475 return -1; 22476 } 22477 22478 /* Get the text of the attachment */ 22479 if (get_msg_text(buf, sizeof(buf), req)) { 22480 ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid); 22481 transmit_response(p, "400 Bad request", req); 22482 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22483 return -1; 22484 } 22485 22486 /* 22487 From the RFC... 22488 A minimal, but complete, implementation can respond with a single 22489 NOTIFY containing either the body: 22490 SIP/2.0 100 Trying 22491 22492 if the subscription is pending, the body: 22493 SIP/2.0 200 OK 22494 if the reference was successful, the body: 22495 SIP/2.0 503 Service Unavailable 22496 if the reference failed, or the body: 22497 SIP/2.0 603 Declined 22498 22499 if the REFER request was accepted before approval to follow the 22500 reference could be obtained and that approval was subsequently denied 22501 (see Section 2.4.7). 22502 22503 If there are several REFERs in the same dialog, we need to 22504 match the ID of the event header... 22505 */ 22506 ast_debug(3, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf); 22507 cmd = ast_skip_blanks(buf); 22508 code = cmd; 22509 /* We are at SIP/2.0 */ 22510 while(*code && (*code > 32)) { /* Search white space */ 22511 code++; 22512 } 22513 *code++ = '\0'; 22514 code = ast_skip_blanks(code); 22515 sep = code; 22516 sep++; 22517 while(*sep && (*sep > 32)) { /* Search white space */ 22518 sep++; 22519 } 22520 *sep++ = '\0'; /* Response string */ 22521 respcode = atoi(code); 22522 switch (respcode) { 22523 case 200: /* OK: The new call is up, hangup this call */ 22524 /* Hangup the call that we are replacing */ 22525 break; 22526 case 301: /* Moved permenantly */ 22527 case 302: /* Moved temporarily */ 22528 /* Do we get the header in the packet in this case? */ 22529 success = FALSE; 22530 break; 22531 case 503: /* Service Unavailable: The new call failed */ 22532 case 603: /* Declined: Not accepted */ 22533 /* Cancel transfer, continue the current call */ 22534 success = FALSE; 22535 break; 22536 case 0: /* Parse error */ 22537 /* Cancel transfer, continue the current call */ 22538 ast_log(LOG_NOTICE, "Error parsing sipfrag in NOTIFY in response to REFER.\n"); 22539 success = FALSE; 22540 break; 22541 default: 22542 if (respcode < 200) { 22543 /* ignore provisional responses */ 22544 success = -1; 22545 } else { 22546 ast_log(LOG_NOTICE, "Got unknown code '%d' in NOTIFY in response to REFER.\n", respcode); 22547 success = FALSE; 22548 } 22549 break; 22550 } 22551 if (success == FALSE) { 22552 ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n"); 22553 } 22554 22555 if (p->owner && success != -1) { 22556 enum ast_control_transfer message = success ? AST_TRANSFER_SUCCESS : AST_TRANSFER_FAILED; 22557 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 22558 } 22559 /* Confirm that we received this packet */ 22560 transmit_response(p, "200 OK", req); 22561 } else if (!strcmp(event, "message-summary")) { 22562 const char *mailbox = NULL; 22563 char *c = ast_strdupa(get_body(req, "Voice-Message", ':')); 22564 22565 if (!p->mwi) { 22566 struct sip_peer *peer = find_peer(NULL, &p->recv, TRUE, FINDPEERS, FALSE, p->socket.type); 22567 22568 if (peer) { 22569 mailbox = ast_strdupa(peer->unsolicited_mailbox); 22570 unref_peer(peer, "removing unsolicited mwi ref"); 22571 } 22572 } else { 22573 mailbox = p->mwi->mailbox; 22574 } 22575 22576 if (!ast_strlen_zero(mailbox) && !ast_strlen_zero(c)) { 22577 char *old = strsep(&c, " "); 22578 char *new = strsep(&old, "/"); 22579 struct ast_event *event; 22580 22581 if ((event = ast_event_new(AST_EVENT_MWI, 22582 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 22583 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, "SIP_Remote", 22584 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, atoi(new), 22585 AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, atoi(old), 22586 AST_EVENT_IE_END))) { 22587 ast_event_queue_and_cache(event); 22588 } 22589 transmit_response(p, "200 OK", req); 22590 } else { 22591 transmit_response(p, "489 Bad event", req); 22592 res = -1; 22593 } 22594 } else if (!strcmp(event, "keep-alive")) { 22595 /* Used by Sipura/Linksys for NAT pinhole, 22596 * just confirm that we received the packet. */ 22597 transmit_response(p, "200 OK", req); 22598 } else if (!strcmp(event, "call-completion")) { 22599 res = handle_cc_notify(p, req); 22600 } else { 22601 /* We don't understand this event. */ 22602 transmit_response(p, "489 Bad event", req); 22603 res = -1; 22604 } 22605 22606 if (!p->lastinvite) 22607 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22608 22609 return res; 22610 }
| 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 22615 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().
22616 { 22617 const char *msg; 22618 enum sip_get_dest_result gotdest; 22619 int res; 22620 22621 if (p->lastinvite) { 22622 /* if this is a request in an active dialog, just confirm that the dialog exists. */ 22623 transmit_response_with_allow(p, "200 OK", req, 0); 22624 return 0; 22625 } 22626 22627 if (sip_cfg.auth_options_requests) { 22628 /* Do authentication if this OPTIONS request began the dialog */ 22629 copy_request(&p->initreq, req); 22630 set_pvt_allowed_methods(p, req); 22631 res = check_user(p, req, SIP_OPTIONS, e, XMIT_UNRELIABLE, addr); 22632 if (res == AUTH_CHALLENGE_SENT) { 22633 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22634 return 0; 22635 } 22636 if (res < 0) { /* Something failed in authentication */ 22637 ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From")); 22638 transmit_response(p, "403 Forbidden", req); 22639 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22640 return 0; 22641 } 22642 } 22643 22644 /* must go through authentication before getting here */ 22645 gotdest = get_destination(p, req, NULL); 22646 build_contact(p); 22647 22648 if (ast_strlen_zero(p->context)) 22649 ast_string_field_set(p, context, sip_cfg.default_context); 22650 22651 if (ast_shutting_down()) { 22652 msg = "503 Unavailable"; 22653 } else { 22654 msg = "404 Not Found"; 22655 switch (gotdest) { 22656 case SIP_GET_DEST_INVALID_URI: 22657 msg = "416 Unsupported URI scheme"; 22658 break; 22659 case SIP_GET_DEST_EXTEN_MATCHMORE: 22660 case SIP_GET_DEST_REFUSED: 22661 case SIP_GET_DEST_EXTEN_NOT_FOUND: 22662 //msg = "404 Not Found"; 22663 break; 22664 case SIP_GET_DEST_EXTEN_FOUND: 22665 msg = "200 OK"; 22666 break; 22667 } 22668 } 22669 transmit_response_with_allow(p, msg, req, 0); 22670 22671 /* Destroy if this OPTIONS was the opening request, but not if 22672 it's in the middle of a normal call flow. */ 22673 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22674 22675 return 0; 22676 }
| 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 25103 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().
25104 { 25105 const char *etag = get_header(req, "SIP-If-Match"); 25106 const char *event = get_header(req, "Event"); 25107 struct event_state_compositor *esc; 25108 enum sip_publish_type publish_type; 25109 const char *expires_str = get_header(req, "Expires"); 25110 int expires_int; 25111 int auth_result; 25112 int handler_result = -1; 25113 25114 if (ast_strlen_zero(event)) { 25115 transmit_response(p, "489 Bad Event", req); 25116 pvt_set_needdestroy(p, "missing Event: header"); 25117 return -1; 25118 } 25119 25120 if (!(esc = get_esc(event))) { 25121 transmit_response(p, "489 Bad Event", req); 25122 pvt_set_needdestroy(p, "unknown event package in publish"); 25123 return -1; 25124 } 25125 25126 auth_result = check_user(p, req, SIP_PUBLISH, uri, XMIT_UNRELIABLE, addr); 25127 if (auth_result == AUTH_CHALLENGE_SENT) { 25128 p->lastinvite = seqno; 25129 return 0; 25130 } else if (auth_result < 0) { 25131 ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From")); 25132 transmit_response(p, "403 Forbidden", req); 25133 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 25134 ast_string_field_set(p, theirtag, NULL); 25135 return 0; 25136 } else if (auth_result == AUTH_SUCCESSFUL && p->lastinvite) { 25137 /* We need to stop retransmitting the 401 */ 25138 __sip_ack(p, p->lastinvite, 1, 0); 25139 } 25140 25141 publish_type = determine_sip_publish_type(req, event, etag, expires_str, &expires_int); 25142 25143 if (expires_int > max_expiry) { 25144 expires_int = max_expiry; 25145 } else if (expires_int < min_expiry && expires_int > 0) { 25146 transmit_response_with_minexpires(p, "423 Interval too small", req); 25147 pvt_set_needdestroy(p, "Expires is less that the min expires allowed."); 25148 return 0; 25149 } 25150 p->expiry = expires_int; 25151 25152 /* It is the responsibility of these handlers to formulate any response 25153 * sent for a PUBLISH 25154 */ 25155 switch (publish_type) { 25156 case SIP_PUBLISH_UNKNOWN: 25157 transmit_response(p, "400 Bad Request", req); 25158 break; 25159 case SIP_PUBLISH_INITIAL: 25160 handler_result = handle_sip_publish_initial(p, req, esc, expires_int); 25161 break; 25162 case SIP_PUBLISH_REFRESH: 25163 handler_result = handle_sip_publish_refresh(p, req, esc, etag, expires_int); 25164 break; 25165 case SIP_PUBLISH_MODIFY: 25166 handler_result = handle_sip_publish_modify(p, req, esc, etag, expires_int); 25167 break; 25168 case SIP_PUBLISH_REMOVE: 25169 handler_result = handle_sip_publish_remove(p, req, esc, etag); 25170 break; 25171 default: 25172 transmit_response(p, "400 Impossible Condition", req); 25173 break; 25174 } 25175 if (!handler_result && p->expiry > 0) { 25176 sip_scheddestroy(p, (p->expiry + 10) * 1000); 25177 } else { 25178 pvt_set_needdestroy(p, "forcing expiration"); 25179 } 25180 25181 return handler_result; 25182 }
| 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 24061 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().
24062 { 24063 /*! 24064 * Chan1: Call between asterisk and transferer 24065 * Chan2: Call between asterisk and transferee 24066 */ 24067 struct sip_dual current = { 0, }; 24068 struct ast_channel *chans[2] = { 0, }; 24069 char *refer_to = NULL; 24070 char *refer_to_domain = NULL; 24071 char *refer_to_context = NULL; 24072 char *referred_by = NULL; 24073 char *callid = NULL; 24074 int localtransfer = 0; 24075 int attendedtransfer = 0; 24076 int res = 0; 24077 24078 if (req->debug) { 24079 ast_verbose("Call %s got a SIP call transfer from %s: (REFER)!\n", 24080 p->callid, 24081 ast_test_flag(&p->flags[0], SIP_OUTGOING) ? "callee" : "caller"); 24082 } 24083 24084 if (!p->owner) { 24085 /* This is a REFER outside of an existing SIP dialog */ 24086 /* We can't handle that, so decline it */ 24087 ast_debug(3, "Call %s: Declined REFER, outside of dialog...\n", p->callid); 24088 transmit_response(p, "603 Declined (No dialog)", req); 24089 if (!req->ignore) { 24090 append_history(p, "Xfer", "Refer failed. Outside of dialog."); 24091 sip_alreadygone(p); 24092 pvt_set_needdestroy(p, "outside of dialog"); 24093 } 24094 res = 0; 24095 goto handle_refer_cleanup; 24096 } 24097 24098 /* Check if transfer is allowed from this device */ 24099 if (p->allowtransfer == TRANSFER_CLOSED ) { 24100 /* Transfer not allowed, decline */ 24101 transmit_response(p, "603 Declined (policy)", req); 24102 append_history(p, "Xfer", "Refer failed. Allowtransfer == closed."); 24103 /* Do not destroy SIP session */ 24104 res = 0; 24105 goto handle_refer_cleanup; 24106 } 24107 24108 if (!req->ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 24109 /* Already have a pending REFER */ 24110 transmit_response(p, "491 Request pending", req); 24111 append_history(p, "Xfer", "Refer failed. Request pending."); 24112 res = 0; 24113 goto handle_refer_cleanup; 24114 } 24115 24116 /* Allocate memory for call transfer data */ 24117 if (!p->refer && !sip_refer_allocate(p)) { 24118 transmit_response(p, "500 Internal Server Error", req); 24119 append_history(p, "Xfer", "Refer failed. Memory allocation error."); 24120 res = -3; 24121 goto handle_refer_cleanup; 24122 } 24123 24124 res = get_refer_info(p, req); /* Extract headers */ 24125 24126 p->refer->status = REFER_SENT; 24127 24128 if (res != 0) { 24129 switch (res) { 24130 case -2: /* Syntax error */ 24131 transmit_response(p, "400 Bad Request (Refer-to missing)", req); 24132 append_history(p, "Xfer", "Refer failed. Refer-to missing."); 24133 if (req->debug) { 24134 ast_debug(1, "SIP transfer to black hole can't be handled (no refer-to: )\n"); 24135 } 24136 break; 24137 case -3: 24138 transmit_response(p, "603 Declined (Non sip: uri)", req); 24139 append_history(p, "Xfer", "Refer failed. Non SIP uri"); 24140 if (req->debug) { 24141 ast_debug(1, "SIP transfer to non-SIP uri denied\n"); 24142 } 24143 break; 24144 default: 24145 /* Refer-to extension not found, fake a failed transfer */ 24146 transmit_response(p, "202 Accepted", req); 24147 append_history(p, "Xfer", "Refer failed. Bad extension."); 24148 transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE); 24149 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 24150 if (req->debug) { 24151 ast_debug(1, "SIP transfer to bad extension: %s\n", p->refer->refer_to); 24152 } 24153 break; 24154 } 24155 res = 0; 24156 goto handle_refer_cleanup; 24157 } 24158 if (ast_strlen_zero(p->context)) { 24159 ast_string_field_set(p, context, sip_cfg.default_context); 24160 } 24161 24162 /* If we do not support SIP domains, all transfers are local */ 24163 if (sip_cfg.allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 24164 p->refer->localtransfer = 1; 24165 if (sipdebug) { 24166 ast_debug(3, "This SIP transfer is local : %s\n", p->refer->refer_to_domain); 24167 } 24168 } else if (AST_LIST_EMPTY(&domain_list) || check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 24169 /* This PBX doesn't bother with SIP domains or domain is local, so this transfer is local */ 24170 p->refer->localtransfer = 1; 24171 } else if (sipdebug) { 24172 ast_debug(3, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain); 24173 } 24174 24175 /* Is this a repeat of a current request? Ignore it */ 24176 /* Don't know what else to do right now. */ 24177 if (req->ignore) { 24178 goto handle_refer_cleanup; 24179 } 24180 24181 /* If this is a blind transfer, we have the following 24182 channels to work with: 24183 - chan1, chan2: The current call between transferer and transferee (2 channels) 24184 - target_channel: A new call from the transferee to the target (1 channel) 24185 We need to stay tuned to what happens in order to be able 24186 to bring back the call to the transferer */ 24187 24188 /* If this is a attended transfer, we should have all call legs within reach: 24189 - chan1, chan2: The call between the transferer and transferee (2 channels) 24190 - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels) 24191 We want to bridge chan2 with targetcall_pvt! 24192 24193 The replaces call id in the refer message points 24194 to the call leg between Asterisk and the transferer. 24195 So we need to connect the target and the transferee channel 24196 and hangup the two other channels silently 24197 24198 If the target is non-local, the call ID could be on a remote 24199 machine and we need to send an INVITE with replaces to the 24200 target. We basically handle this as a blind transfer 24201 and let the sip_call function catch that we need replaces 24202 header in the INVITE. 24203 */ 24204 24205 /* Get the transferer's channel */ 24206 chans[0] = current.chan1 = p->owner; 24207 24208 /* Find the other part of the bridge (2) - transferee */ 24209 chans[1] = current.chan2 = ast_bridged_channel(current.chan1); 24210 24211 ast_channel_ref(current.chan1); 24212 if (current.chan2) { 24213 ast_channel_ref(current.chan2); 24214 } 24215 24216 if (sipdebug) { 24217 ast_debug(3, "SIP %s transfer: Transferer channel %s, transferee channel %s\n", 24218 p->refer->attendedtransfer ? "attended" : "blind", 24219 current.chan1->name, 24220 current.chan2 ? current.chan2->name : "<none>"); 24221 } 24222 24223 if (!current.chan2 && !p->refer->attendedtransfer) { 24224 /* No bridged channel, propably IVR or echo or similar... */ 24225 /* Guess we should masquerade or something here */ 24226 /* Until we figure it out, refuse transfer of such calls */ 24227 if (sipdebug) { 24228 ast_debug(3, "Refused SIP transfer on non-bridged channel.\n"); 24229 } 24230 p->refer->status = REFER_FAILED; 24231 append_history(p, "Xfer", "Refer failed. Non-bridged channel."); 24232 transmit_response(p, "603 Declined", req); 24233 res = -1; 24234 goto handle_refer_cleanup; 24235 } 24236 24237 if (current.chan2) { 24238 if (sipdebug) { 24239 ast_debug(4, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name); 24240 } 24241 ast_queue_control(current.chan1, AST_CONTROL_UNHOLD); 24242 } 24243 24244 ast_set_flag(&p->flags[0], SIP_GOTREFER); 24245 24246 /* From here on failures will be indicated with NOTIFY requests */ 24247 transmit_response(p, "202 Accepted", req); 24248 24249 /* Attended transfer: Find all call legs and bridge transferee with target*/ 24250 if (p->refer->attendedtransfer) { 24251 /* both p and p->owner _MUST_ be locked while calling local_attended_transfer */ 24252 if ((res = local_attended_transfer(p, ¤t, req, seqno, nounlock))) { 24253 goto handle_refer_cleanup; /* We're done with the transfer */ 24254 } 24255 /* Fall through for remote transfers that we did not find locally */ 24256 if (sipdebug) { 24257 ast_debug(4, "SIP attended transfer: Still not our call - generating INVITE with replaces\n"); 24258 } 24259 /* Fallthrough if we can't find the call leg internally */ 24260 } 24261 24262 /* Copy data we can not safely access after letting the pvt lock go. */ 24263 refer_to = ast_strdupa(p->refer->refer_to); 24264 refer_to_domain = ast_strdupa(p->refer->refer_to_domain); 24265 refer_to_context = ast_strdupa(p->refer->refer_to_context); 24266 referred_by = ast_strdupa(p->refer->referred_by); 24267 callid = ast_strdupa(p->callid); 24268 localtransfer = p->refer->localtransfer; 24269 attendedtransfer = p->refer->attendedtransfer; 24270 24271 if (!*nounlock) { 24272 ast_channel_unlock(p->owner); 24273 *nounlock = 1; 24274 } 24275 sip_pvt_unlock(p); 24276 24277 /* Parking a call. DO NOT hold any locks while calling ast_parking_ext_valid() */ 24278 if (localtransfer && ast_parking_ext_valid(refer_to, current.chan1, refer_to_context)) { 24279 sip_pvt_lock(p); 24280 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 24281 p->refer->status = REFER_200OK; 24282 append_history(p, "Xfer", "REFER to call parking."); 24283 sip_pvt_unlock(p); 24284 24285 ast_manager_event_multichan(EVENT_FLAG_CALL, "Transfer", 2, chans, 24286 "TransferMethod: SIP\r\n" 24287 "TransferType: Blind\r\n" 24288 "Channel: %s\r\n" 24289 "Uniqueid: %s\r\n" 24290 "SIP-Callid: %s\r\n" 24291 "TargetChannel: %s\r\n" 24292 "TargetUniqueid: %s\r\n" 24293 "TransferExten: %s\r\n" 24294 "Transfer2Parking: Yes\r\n", 24295 current.chan1->name, 24296 current.chan1->uniqueid, 24297 callid, 24298 current.chan2->name, 24299 current.chan2->uniqueid, 24300 refer_to); 24301 24302 if (sipdebug) { 24303 ast_debug(4, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name); 24304 } 24305 24306 /* DO NOT hold any locks while calling sip_park */ 24307 if (sip_park(current.chan2, current.chan1, req, seqno, refer_to, refer_to_context)) { 24308 sip_pvt_lock(p); 24309 transmit_notify_with_sipfrag(p, seqno, "500 Internal Server Error", TRUE); 24310 } else { 24311 sip_pvt_lock(p); 24312 } 24313 goto handle_refer_cleanup; 24314 } 24315 24316 /* Blind transfers and remote attended xfers. 24317 * Locks should not be held while calling pbx_builtin_setvar_helper. This function 24318 * locks the channel being passed into it.*/ 24319 if (current.chan1 && current.chan2) { 24320 ast_debug(3, "chan1->name: %s\n", current.chan1->name); 24321 pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name); 24322 } 24323 24324 if (current.chan2) { 24325 pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name); 24326 pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", refer_to_domain); 24327 pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes"); 24328 /* One for the new channel */ 24329 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes"); 24330 /* Attended transfer to remote host, prepare headers for the INVITE */ 24331 if (!ast_strlen_zero(referred_by)) { 24332 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", referred_by); 24333 } 24334 } 24335 24336 sip_pvt_lock(p); 24337 /* Generate a Replaces string to be used in the INVITE during attended transfer */ 24338 if (!ast_strlen_zero(p->refer->replaces_callid)) { 24339 char tempheader[SIPBUFSIZE]; 24340 snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid, 24341 p->refer->replaces_callid_totag ? ";to-tag=" : "", 24342 p->refer->replaces_callid_totag, 24343 p->refer->replaces_callid_fromtag ? ";from-tag=" : "", 24344 p->refer->replaces_callid_fromtag); 24345 24346 if (current.chan2) { 24347 sip_pvt_unlock(p); 24348 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader); 24349 sip_pvt_lock(p); 24350 } 24351 } 24352 24353 /* Connect the call */ 24354 24355 /* FAKE ringing if not attended transfer */ 24356 if (!p->refer->attendedtransfer) { 24357 transmit_notify_with_sipfrag(p, seqno, "180 Ringing", FALSE); 24358 } 24359 24360 /* For blind transfer, this will lead to a new call */ 24361 /* For attended transfer to remote host, this will lead to 24362 a new SIP call with a replaces header, if the dial plan allows it 24363 */ 24364 if (!current.chan2) { 24365 /* We have no bridge, so we're talking with Asterisk somehow */ 24366 /* We need to masquerade this call */ 24367 /* What to do to fix this situation: 24368 * Set up the new call in a new channel 24369 * Let the new channel masq into this channel 24370 Please add that code here :-) 24371 */ 24372 p->refer->status = REFER_FAILED; 24373 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE); 24374 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 24375 append_history(p, "Xfer", "Refer failed (only bridged calls)."); 24376 res = -1; 24377 goto handle_refer_cleanup; 24378 } 24379 ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 24380 24381 /* Do not hold the pvt lock during the indicate and async_goto. Those functions 24382 * lock channels which will invalidate locking order if the pvt lock is held.*/ 24383 /* For blind transfers, move the call to the new extensions. For attended transfers on multiple 24384 * servers - generate an INVITE with Replaces. Either way, let the dial plan decided 24385 * indicate before masquerade so the indication actually makes it to the real channel 24386 * when using local channels with MOH passthru */ 24387 sip_pvt_unlock(p); 24388 ast_indicate(current.chan2, AST_CONTROL_UNHOLD); 24389 res = ast_async_goto(current.chan2, refer_to_context, refer_to, 1); 24390 24391 if (!res) { 24392 ast_manager_event_multichan(EVENT_FLAG_CALL, "Transfer", 2, chans, 24393 "TransferMethod: SIP\r\n" 24394 "TransferType: Blind\r\n" 24395 "Channel: %s\r\n" 24396 "Uniqueid: %s\r\n" 24397 "SIP-Callid: %s\r\n" 24398 "TargetChannel: %s\r\n" 24399 "TargetUniqueid: %s\r\n" 24400 "TransferExten: %s\r\n" 24401 "TransferContext: %s\r\n", 24402 current.chan1->name, 24403 current.chan1->uniqueid, 24404 callid, 24405 current.chan2->name, 24406 current.chan2->uniqueid, 24407 refer_to, 24408 refer_to_context); 24409 /* Success - we have a new channel */ 24410 ast_debug(3, "%s transfer succeeded. Telling transferer.\n", attendedtransfer? "Attended" : "Blind"); 24411 24412 /* XXX - what to we put in CEL 'extra' for attended transfers to external systems? NULL for now */ 24413 ast_channel_lock(current.chan1); 24414 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); 24415 ast_channel_unlock(current.chan1); 24416 24417 sip_pvt_lock(p); 24418 transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE); 24419 if (p->refer->localtransfer) { 24420 p->refer->status = REFER_200OK; 24421 } 24422 if (p->owner) { 24423 p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING; 24424 } 24425 append_history(p, "Xfer", "Refer succeeded."); 24426 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 24427 /* Do not hangup call, the other side do that when we say 200 OK */ 24428 /* We could possibly implement a timer here, auto congestion */ 24429 res = 0; 24430 } else { 24431 sip_pvt_lock(p); 24432 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */ 24433 ast_debug(3, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 24434 append_history(p, "Xfer", "Refer failed."); 24435 /* Failure of some kind */ 24436 p->refer->status = REFER_FAILED; 24437 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE); 24438 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 24439 res = -1; 24440 } 24441 24442 handle_refer_cleanup: 24443 if (current.chan1) { 24444 ast_channel_unref(current.chan1); 24445 } 24446 if (current.chan2) { 24447 ast_channel_unref(current.chan2); 24448 } 24449 24450 /* Make sure we exit with the pvt locked */ 24451 return res; 24452 }
| 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 25649 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().
25650 { 25651 enum check_auth_result res; 25652 25653 /* If this is not the intial request, and the initial request isn't 25654 * a register, something screwy happened, so bail */ 25655 if (p->initreq.headers && p->initreq.method != SIP_REGISTER) { 25656 ast_log(LOG_WARNING, "Ignoring spurious REGISTER with Call-ID: %s\n", p->callid); 25657 return -1; 25658 } 25659 25660 /* Use this as the basis */ 25661 copy_request(&p->initreq, req); 25662 if (sipdebug) 25663 ast_debug(4, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid); 25664 check_via(p, req); 25665 if ((res = register_verify(p, addr, req, e)) < 0) { 25666 const char *reason; 25667 25668 switch (res) { 25669 case AUTH_SECRET_FAILED: 25670 reason = "Wrong password"; 25671 break; 25672 case AUTH_USERNAME_MISMATCH: 25673 reason = "Username/auth name mismatch"; 25674 break; 25675 case AUTH_NOT_FOUND: 25676 reason = "No matching peer found"; 25677 break; 25678 case AUTH_UNKNOWN_DOMAIN: 25679 reason = "Not a local domain"; 25680 break; 25681 case AUTH_PEER_NOT_DYNAMIC: 25682 reason = "Peer is not supposed to register"; 25683 break; 25684 case AUTH_ACL_FAILED: 25685 reason = "Device does not match ACL"; 25686 break; 25687 case AUTH_BAD_TRANSPORT: 25688 reason = "Device not configured to use this transport type"; 25689 break; 25690 default: 25691 reason = "Unknown failure"; 25692 break; 25693 } 25694 ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n", 25695 get_header(req, "To"), ast_sockaddr_stringify(addr), 25696 reason); 25697 append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason); 25698 } else { 25699 req->authenticated = 1; 25700 append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To")); 25701 } 25702 25703 if (res < 1) { 25704 /* Destroy the session, but keep us around for just a bit in case they don't 25705 get our 200 OK */ 25706 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 25707 } 25708 return res; 25709 }
| 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 25265 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().
25266 { 25267 int gotdest = 0; 25268 int res = 0; 25269 int firststate; 25270 struct sip_peer *authpeer = NULL; 25271 const char *eventheader = get_header(req, "Event"); /* Get Event package name */ 25272 int resubscribe = (p->subscribed != NONE) && !req->ignore; 25273 char *event_end; 25274 ptrdiff_t event_len = 0; 25275 25276 if (p->initreq.headers) { 25277 /* We already have a dialog */ 25278 if (p->initreq.method != SIP_SUBSCRIBE) { 25279 /* This is a SUBSCRIBE within another SIP dialog, which we do not support */ 25280 /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */ 25281 transmit_response(p, "403 Forbidden (within dialog)", req); 25282 /* Do not destroy session, since we will break the call if we do */ 25283 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); 25284 return 0; 25285 } else if (req->debug) { 25286 if (resubscribe) 25287 ast_debug(1, "Got a re-subscribe on existing subscription %s\n", p->callid); 25288 else 25289 ast_debug(1, "Got a new subscription %s (possibly with auth) or retransmission\n", p->callid); 25290 } 25291 } 25292 25293 /* Check if we have a global disallow setting on subscriptions. 25294 if so, we don't have to check peer settings after auth, which saves a lot of processing 25295 */ 25296 if (!sip_cfg.allowsubscribe) { 25297 transmit_response(p, "403 Forbidden (policy)", req); 25298 pvt_set_needdestroy(p, "forbidden"); 25299 return 0; 25300 } 25301 25302 if (!req->ignore && !resubscribe) { /* Set up dialog, new subscription */ 25303 const char *to = get_header(req, "To"); 25304 char totag[128]; 25305 set_pvt_allowed_methods(p, req); 25306 25307 /* Check to see if a tag was provided, if so this is actually a resubscription of a dialog we no longer know about */ 25308 if (!ast_strlen_zero(to) && gettag(req, "To", totag, sizeof(totag))) { 25309 if (req->debug) 25310 ast_verbose("Received resubscription for a dialog we no longer know about. Telling remote side to subscribe again.\n"); 25311 transmit_response(p, "481 Subscription does not exist", req); 25312 pvt_set_needdestroy(p, "subscription does not exist"); 25313 return 0; 25314 } 25315 25316 /* Use this as the basis */ 25317 if (req->debug) 25318 ast_verbose("Creating new subscription\n"); 25319 25320 copy_request(&p->initreq, req); 25321 if (sipdebug) 25322 ast_debug(4, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid); 25323 check_via(p, req); 25324 build_route(p, req, 0, 0); 25325 } else if (req->debug && req->ignore) 25326 ast_verbose("Ignoring this SUBSCRIBE request\n"); 25327 25328 /* Find parameters to Event: header value and remove them for now */ 25329 if (ast_strlen_zero(eventheader)) { 25330 transmit_response(p, "489 Bad Event", req); 25331 ast_debug(2, "Received SIP subscribe for unknown event package: <none>\n"); 25332 pvt_set_needdestroy(p, "unknown event package in subscribe"); 25333 return 0; 25334 } 25335 25336 event_end = strchr(eventheader, ';'); 25337 if (event_end) { 25338 event_len = event_end - eventheader; 25339 } 25340 25341 /* Handle authentication if we're new and not a retransmission. We can't just 25342 * use if !req->ignore, because then we'll end up sending 25343 * a 200 OK if someone retransmits without sending auth */ 25344 if (p->subscribed == NONE || resubscribe) { 25345 res = check_user_full(p, req, SIP_SUBSCRIBE, e, XMIT_UNRELIABLE, addr, &authpeer); 25346 25347 /* if an authentication response was sent, we are done here */ 25348 if (res == AUTH_CHALLENGE_SENT) /* authpeer = NULL here */ 25349 return 0; 25350 if (res != AUTH_SUCCESSFUL) { 25351 ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From")); 25352 transmit_response(p, "403 Forbidden", req); 25353 25354 pvt_set_needdestroy(p, "authentication failed"); 25355 return 0; 25356 } 25357 } 25358 25359 /* At this point, we hold a reference to authpeer (if not NULL). It 25360 * must be released when done. 25361 */ 25362 25363 /* Check if this device is allowed to subscribe at all */ 25364 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) { 25365 transmit_response(p, "403 Forbidden (policy)", req); 25366 pvt_set_needdestroy(p, "subscription not allowed"); 25367 if (authpeer) { 25368 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 1)"); 25369 } 25370 return 0; 25371 } 25372 25373 if (strncmp(eventheader, "message-summary", MAX(event_len, 15)) && strncmp(eventheader, "call-completion", MAX(event_len, 15))) { 25374 /* Get destination right away */ 25375 gotdest = get_destination(p, NULL, NULL); 25376 } 25377 25378 /* Get full contact header - this needs to be used as a request URI in NOTIFY's */ 25379 parse_ok_contact(p, req); 25380 25381 build_contact(p); 25382 if (gotdest != SIP_GET_DEST_EXTEN_FOUND) { 25383 if (gotdest == SIP_GET_DEST_INVALID_URI) { 25384 transmit_response(p, "416 Unsupported URI scheme", req); 25385 } else { 25386 transmit_response(p, "404 Not Found", req); 25387 } 25388 pvt_set_needdestroy(p, "subscription target not found"); 25389 if (authpeer) { 25390 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 2)"); 25391 } 25392 return 0; 25393 } 25394 25395 /* Initialize tag for new subscriptions */ 25396 if (ast_strlen_zero(p->tag)) 25397 make_our_tag(p); 25398 25399 if (!strncmp(eventheader, "presence", MAX(event_len, 8)) || !strncmp(eventheader, "dialog", MAX(event_len, 6))) { /* Presence, RFC 3842 */ 25400 unsigned int pidf_xml; 25401 const char *accept; 25402 int start = 0; 25403 enum subscriptiontype subscribed = NONE; 25404 const char *unknown_acceptheader = NULL; 25405 25406 /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */ 25407 accept = __get_header(req, "Accept", &start); 25408 while ((subscribed == NONE) && !ast_strlen_zero(accept)) { 25409 pidf_xml = strstr(accept, "application/pidf+xml") ? 1 : 0; 25410 25411 /* Older versions of Polycom firmware will claim pidf+xml, but really 25412 * they only support xpidf+xml. */ 25413 if (pidf_xml && strstr(p->useragent, "Polycom")) { 25414 subscribed = XPIDF_XML; 25415 } else if (pidf_xml) { 25416 subscribed = PIDF_XML; /* RFC 3863 format */ 25417 } else if (strstr(accept, "application/dialog-info+xml")) { 25418 subscribed = DIALOG_INFO_XML; 25419 /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */ 25420 } else if (strstr(accept, "application/cpim-pidf+xml")) { 25421 subscribed = CPIM_PIDF_XML; /* RFC 3863 format */ 25422 } else if (strstr(accept, "application/xpidf+xml")) { 25423 subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */ 25424 } else { 25425 unknown_acceptheader = accept; 25426 } 25427 /* check to see if there is another Accept header present */ 25428 accept = __get_header(req, "Accept", &start); 25429 } 25430 25431 if (!start) { 25432 if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */ 25433 transmit_response(p, "489 Bad Event", req); 25434 ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: " 25435 "stateid: %d, laststate: %d, dialogver: %u, subscribecont: " 25436 "'%s', subscribeuri: '%s'\n", 25437 p->stateid, 25438 p->laststate, 25439 p->dialogver, 25440 p->subscribecontext, 25441 p->subscribeuri); 25442 pvt_set_needdestroy(p, "no Accept header"); 25443 if (authpeer) { 25444 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 2)"); 25445 } 25446 return 0; 25447 } 25448 /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least. 25449 so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */ 25450 } else if (subscribed == NONE) { 25451 /* Can't find a format for events that we know about */ 25452 char mybuf[200]; 25453 if (!ast_strlen_zero(unknown_acceptheader)) { 25454 snprintf(mybuf, sizeof(mybuf), "489 Bad Event (format %s)", unknown_acceptheader); 25455 } else { 25456 snprintf(mybuf, sizeof(mybuf), "489 Bad Event"); 25457 } 25458 transmit_response(p, mybuf, req); 25459 ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format:" 25460 "'%s' pvt: subscribed: %d, stateid: %d, laststate: %d," 25461 "dialogver: %u, subscribecont: '%s', subscribeuri: '%s'\n", 25462 unknown_acceptheader, 25463 (int)p->subscribed, 25464 p->stateid, 25465 p->laststate, 25466 p->dialogver, 25467 p->subscribecontext, 25468 p->subscribeuri); 25469 pvt_set_needdestroy(p, "unrecognized format"); 25470 if (authpeer) { 25471 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 2)"); 25472 } 25473 return 0; 25474 } else { 25475 p->subscribed = subscribed; 25476 } 25477 } else if (!strncmp(eventheader, "message-summary", MAX(event_len, 15))) { 25478 int start = 0; 25479 int found_supported = 0; 25480 const char *acceptheader; 25481 25482 acceptheader = __get_header(req, "Accept", &start); 25483 while (!found_supported && !ast_strlen_zero(acceptheader)) { 25484 found_supported = strcmp(acceptheader, "application/simple-message-summary") ? 0 : 1; 25485 if (!found_supported && (option_debug > 2)) { 25486 ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", acceptheader); 25487 } 25488 acceptheader = __get_header(req, "Accept", &start); 25489 } 25490 if (start && !found_supported) { 25491 /* Format requested that we do not support */ 25492 transmit_response(p, "406 Not Acceptable", req); 25493 ast_debug(2, "Received SIP mailbox subscription for unknown format: %s\n", acceptheader); 25494 pvt_set_needdestroy(p, "unknown format"); 25495 if (authpeer) { 25496 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 3)"); 25497 } 25498 return 0; 25499 } 25500 /* Looks like they actually want a mailbox status 25501 This version of Asterisk supports mailbox subscriptions 25502 The subscribed URI needs to exist in the dial plan 25503 In most devices, this is configurable to the voicemailmain extension you use 25504 */ 25505 if (!authpeer || AST_LIST_EMPTY(&authpeer->mailboxes)) { 25506 if (!authpeer) { 25507 transmit_response(p, "404 Not found", req); 25508 } else { 25509 transmit_response(p, "404 Not found (no mailbox)", req); 25510 ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", S_OR(authpeer->name, "")); 25511 } 25512 pvt_set_needdestroy(p, "received 404 response"); 25513 if (authpeer) { 25514 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 3)"); 25515 } 25516 return 0; 25517 } 25518 25519 p->subscribed = MWI_NOTIFICATION; 25520 if (ast_test_flag(&authpeer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY)) { 25521 ao2_unlock(p); 25522 add_peer_mwi_subs(authpeer); 25523 ao2_lock(p); 25524 } 25525 if (authpeer->mwipvt != p) { /* Destroy old PVT if this is a new one */ 25526 /* We only allow one subscription per peer */ 25527 if (authpeer->mwipvt) { 25528 dialog_unlink_all(authpeer->mwipvt); 25529 authpeer->mwipvt = dialog_unref(authpeer->mwipvt, "unref dialog authpeer->mwipvt"); 25530 } 25531 authpeer->mwipvt = dialog_ref(p, "setting peers' mwipvt to p"); 25532 } 25533 if (p->relatedpeer != authpeer) { 25534 if (p->relatedpeer) { 25535 unref_peer(p->relatedpeer, "Unref previously stored relatedpeer ptr"); 25536 } 25537 p->relatedpeer = ref_peer(authpeer, "setting dialog's relatedpeer pointer"); 25538 } 25539 /* Do not release authpeer here */ 25540 } else if (!strncmp(eventheader, "call-completion", MAX(event_len, 15))) { 25541 handle_cc_subscribe(p, req); 25542 } else { /* At this point, Asterisk does not understand the specified event */ 25543 transmit_response(p, "489 Bad Event", req); 25544 ast_debug(2, "Received SIP subscribe for unknown event package: %s\n", eventheader); 25545 pvt_set_needdestroy(p, "unknown event package"); 25546 if (authpeer) { 25547 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 5)"); 25548 } 25549 return 0; 25550 } 25551 25552 /* Add subscription for extension state from the PBX core */ 25553 if (p->subscribed != MWI_NOTIFICATION && p->subscribed != CALL_COMPLETION && !resubscribe) { 25554 if (p->stateid != -1) { 25555 ast_extension_state_del(p->stateid, cb_extensionstate); 25556 } 25557 dialog_ref(p, "copying dialog ptr into extension state struct"); 25558 p->stateid = ast_extension_state_add_destroy(p->context, p->exten, 25559 cb_extensionstate, cb_extensionstate_destroy, p); 25560 if (p->stateid == -1) { 25561 dialog_unref(p, "copying dialog ptr into extension state struct failed"); 25562 } 25563 } 25564 25565 if (!req->ignore) { 25566 p->lastinvite = seqno; 25567 } 25568 if (!p->needdestroy) { 25569 p->expiry = atoi(get_header(req, "Expires")); 25570 25571 /* check if the requested expiry-time is within the approved limits from sip.conf */ 25572 if (p->expiry > max_expiry) { 25573 p->expiry = max_expiry; 25574 } else if (p->expiry < min_expiry && p->expiry > 0) { 25575 transmit_response_with_minexpires(p, "423 Interval too small", req); 25576 ast_log(LOG_WARNING, "Received subscription for extension \"%s\" context \"%s\" " 25577 "with Expire header less that 'minexpire' limit. Received \"Expire: %d\" min is %d\n", 25578 p->exten, p->context, p->expiry, min_expiry); 25579 pvt_set_needdestroy(p, "Expires is less that the min expires allowed."); 25580 if (authpeer) { 25581 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 6)"); 25582 } 25583 return 0; 25584 } 25585 25586 if (sipdebug) { 25587 const char *action = p->expiry > 0 ? "Adding" : "Removing"; 25588 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) { 25589 ast_debug(2, "%s subscription for mailbox notification - peer %s\n", 25590 action, p->relatedpeer->name); 25591 } else if (p->subscribed == CALL_COMPLETION) { 25592 ast_debug(2, "%s CC subscription for peer %s\n", action, p->username); 25593 } else { 25594 ast_debug(2, "%s subscription for extension %s context %s for peer %s\n", 25595 action, p->exten, p->context, p->username); 25596 } 25597 } 25598 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 25599 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 25600 if (p->expiry > 0) 25601 sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */ 25602 25603 if (p->subscribed == MWI_NOTIFICATION) { 25604 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 25605 transmit_response(p, "200 OK", req); 25606 if (p->relatedpeer) { /* Send first notification */ 25607 struct sip_peer *peer = p->relatedpeer; 25608 ref_peer(peer, "ensure a peer ref is held during MWI sending"); 25609 ao2_unlock(p); 25610 sip_send_mwi_to_peer(peer, 0); 25611 ao2_lock(p); 25612 unref_peer(peer, "release a peer ref now that MWI is sent"); 25613 } 25614 } else if (p->subscribed != CALL_COMPLETION) { 25615 sip_pvt_unlock(p); 25616 firststate = ast_extension_state(NULL, p->context, p->exten); 25617 sip_pvt_lock(p); 25618 25619 if (firststate < 0) { 25620 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)); 25621 transmit_response(p, "404 Not found", req); 25622 pvt_set_needdestroy(p, "no extension for SUBSCRIBE"); 25623 if (authpeer) { 25624 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 6)"); 25625 } 25626 return 0; 25627 } 25628 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 25629 transmit_response(p, "200 OK", req); 25630 transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */ 25631 append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate)); 25632 /* hide the 'complete' exten/context in the refer_to field for later display */ 25633 ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context); 25634 /* Deleted the slow iteration of all sip dialogs to find old subscribes from this peer for exten@context */ 25635 25636 } 25637 if (!p->expiry) { 25638 pvt_set_needdestroy(p, "forcing expiration"); 25639 } 25640 } 25641 25642 if (authpeer) { 25643 unref_peer(authpeer, "unref pointer into (*authpeer)"); 25644 } 25645 return 1; 25646 }
| 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 22868 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().
22869 { 22870 if (ast_strlen_zero(get_header(req, "X-Asterisk-rpid-update"))) { 22871 transmit_response(p, "501 Method Not Implemented", req); 22872 return 0; 22873 } 22874 if (!p->owner) { 22875 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 22876 return 0; 22877 } 22878 if (get_rpid(p, req)) { 22879 struct ast_party_connected_line connected; 22880 struct ast_set_party_connected_line update_connected; 22881 22882 ast_party_connected_line_init(&connected); 22883 memset(&update_connected, 0, sizeof(update_connected)); 22884 22885 update_connected.id.number = 1; 22886 connected.id.number.valid = 1; 22887 connected.id.number.str = (char *) p->cid_num; 22888 connected.id.number.presentation = p->callingpres; 22889 22890 update_connected.id.name = 1; 22891 connected.id.name.valid = 1; 22892 connected.id.name.str = (char *) p->cid_name; 22893 connected.id.name.presentation = p->callingpres; 22894 22895 connected.id.tag = (char *) p->cid_tag; 22896 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER; 22897 ast_channel_queue_connected_line_update(p->owner, &connected, &update_connected); 22898 } 22899 transmit_response(p, "200 OK", req); 22900 return 0; 22901 }
| 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 21653 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().
21654 { 21655 struct ast_channel *owner; 21656 int sipmethod; 21657 const char *c = get_header(req, "Cseq"); 21658 /* 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 */ 21659 char *c_copy = ast_strdupa(c); 21660 /* Skip the Cseq and its subsequent spaces */ 21661 const char *msg = ast_skip_blanks(ast_skip_nonblanks(c_copy)); 21662 21663 if (!msg) 21664 msg = ""; 21665 21666 sipmethod = find_sip_method(msg); 21667 21668 owner = p->owner; 21669 if (owner) { 21670 const char *rp = NULL, *rh = NULL; 21671 21672 owner->hangupcause = 0; 21673 if (ast_test_flag(&p->flags[1], SIP_PAGE2_Q850_REASON) && (rh = get_header(req, "Reason"))) { 21674 rh = ast_skip_blanks(rh); 21675 if (!strncasecmp(rh, "Q.850", 5)) { 21676 rp = strstr(rh, "cause="); 21677 if (rp && sscanf(rp + 6, "%30d", &owner->hangupcause) == 1) { 21678 owner->hangupcause &= 0x7f; 21679 if (req->debug) 21680 ast_verbose("Using Reason header for cause code: %d\n", owner->hangupcause); 21681 } 21682 } 21683 } 21684 21685 if (!owner->hangupcause) 21686 owner->hangupcause = hangup_sip2cause(resp); 21687 } 21688 21689 if (p->socket.type == SIP_TRANSPORT_UDP) { 21690 int ack_res = FALSE; 21691 21692 /* Acknowledge whatever it is destined for */ 21693 if ((resp >= 100) && (resp <= 199)) { 21694 /* NON-INVITE messages do not ack a 1XX response. RFC 3261 section 17.1.2.2 */ 21695 if (sipmethod == SIP_INVITE) { 21696 ack_res = __sip_semi_ack(p, seqno, 0, sipmethod); 21697 } 21698 } else { 21699 ack_res = __sip_ack(p, seqno, 0, sipmethod); 21700 } 21701 21702 if (ack_res == FALSE) { 21703 /* RFC 3261 13.2.2.4 and 17.1.1.2 - We must re-send ACKs to re-transmitted final responses */ 21704 if (sipmethod == SIP_INVITE && resp >= 200) { 21705 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, resp < 300 ? TRUE: FALSE); 21706 } 21707 21708 append_history(p, "Ignore", "Ignoring this retransmit\n"); 21709 return; 21710 } 21711 } 21712 21713 /* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */ 21714 if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite) { 21715 p->pendinginvite = 0; 21716 } 21717 21718 /* Get their tag if we haven't already */ 21719 if (ast_strlen_zero(p->theirtag) || (resp >= 200)) { 21720 char tag[128]; 21721 21722 gettag(req, "To", tag, sizeof(tag)); 21723 ast_string_field_set(p, theirtag, tag); 21724 } 21725 /* This needs to be configurable on a channel/peer level, 21726 not mandatory for all communication. Sadly enough, NAT implementations 21727 are not so stable so we can always rely on these headers. 21728 Temporarily disabled, while waiting for fix. 21729 Fix assigned to Rizzo :-) 21730 */ 21731 /* check_via_response(p, req); */ 21732 21733 /* RFC 3261 Section 15 specifies that if we receive a 408 or 481 21734 * in response to a BYE, then we should end the current dialog 21735 * and session. It is known that at least one phone manufacturer 21736 * potentially will send a 404 in response to a BYE, so we'll be 21737 * liberal in what we accept and end the dialog and session if we 21738 * receive any of those responses to a BYE. 21739 */ 21740 if ((resp == 404 || resp == 408 || resp == 481) && sipmethod == SIP_BYE) { 21741 pvt_set_needdestroy(p, "received 4XX response to a BYE"); 21742 return; 21743 } 21744 21745 if (p->relatedpeer && sipmethod == SIP_OPTIONS) { 21746 /* We don't really care what the response is, just that it replied back. 21747 Well, as long as it's not a 100 response... since we might 21748 need to hang around for something more "definitive" */ 21749 if (resp != 100) 21750 handle_response_peerpoke(p, resp, req); 21751 } else if (sipmethod == SIP_REFER && resp >= 200) { 21752 handle_response_refer(p, resp, rest, req, seqno); 21753 } else if (sipmethod == SIP_PUBLISH) { 21754 /* SIP PUBLISH transcends this morass of doodoo and instead 21755 * we just always call the response handler. Good gravy! 21756 */ 21757 handle_response_publish(p, resp, rest, req, seqno); 21758 } else if (sipmethod == SIP_INFO) { 21759 /* More good gravy! */ 21760 handle_response_info(p, resp, rest, req, seqno); 21761 } else if (sipmethod == SIP_MESSAGE) { 21762 /* More good gravy! */ 21763 handle_response_message(p, resp, rest, req, seqno); 21764 } else if (sipmethod == SIP_NOTIFY) { 21765 /* The gravy train continues to roll */ 21766 handle_response_notify(p, resp, rest, req, seqno); 21767 } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 21768 switch(resp) { 21769 case 100: /* 100 Trying */ 21770 case 101: /* 101 Dialog establishment */ 21771 case 183: /* 183 Session Progress */ 21772 case 180: /* 180 Ringing */ 21773 case 182: /* 182 Queued */ 21774 case 181: /* 181 Call Is Being Forwarded */ 21775 if (sipmethod == SIP_INVITE) 21776 handle_response_invite(p, resp, rest, req, seqno); 21777 break; 21778 case 200: /* 200 OK */ 21779 p->authtries = 0; /* Reset authentication counter */ 21780 if (sipmethod == SIP_INVITE) { 21781 handle_response_invite(p, resp, rest, req, seqno); 21782 } else if (sipmethod == SIP_REGISTER) { 21783 handle_response_register(p, resp, rest, req, seqno); 21784 } else if (sipmethod == SIP_SUBSCRIBE) { 21785 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 21786 handle_response_subscribe(p, resp, rest, req, seqno); 21787 } else if (sipmethod == SIP_BYE) { /* Ok, we're ready to go */ 21788 pvt_set_needdestroy(p, "received 200 response"); 21789 ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 21790 } 21791 break; 21792 case 401: /* Not www-authorized on SIP method */ 21793 case 407: /* Proxy auth required */ 21794 if (sipmethod == SIP_INVITE) 21795 handle_response_invite(p, resp, rest, req, seqno); 21796 else if (sipmethod == SIP_SUBSCRIBE) 21797 handle_response_subscribe(p, resp, rest, req, seqno); 21798 else if (p->registry && sipmethod == SIP_REGISTER) 21799 handle_response_register(p, resp, rest, req, seqno); 21800 else if (sipmethod == SIP_UPDATE) { 21801 handle_response_update(p, resp, rest, req, seqno); 21802 } else if (sipmethod == SIP_BYE) { 21803 if (p->options) 21804 p->options->auth_type = resp; 21805 if (ast_strlen_zero(p->authname)) { 21806 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s but we have no matching peer!\n", 21807 msg, ast_sockaddr_stringify(&p->recv)); 21808 pvt_set_needdestroy(p, "unable to authenticate BYE"); 21809 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, resp, sipmethod, 0)) { 21810 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 21811 pvt_set_needdestroy(p, "failed to authenticate BYE"); 21812 } 21813 } else { 21814 ast_log(LOG_WARNING, "Got authentication request (%d) on %s to '%s'\n", resp, sip_methods[sipmethod].text, get_header(req, "To")); 21815 pvt_set_needdestroy(p, "received 407 response"); 21816 } 21817 break; 21818 case 403: /* Forbidden - we failed authentication */ 21819 if (sipmethod == SIP_INVITE) 21820 handle_response_invite(p, resp, rest, req, seqno); 21821 else if (sipmethod == SIP_SUBSCRIBE) 21822 handle_response_subscribe(p, resp, rest, req, seqno); 21823 else if (p->registry && sipmethod == SIP_REGISTER) 21824 handle_response_register(p, resp, rest, req, seqno); 21825 else { 21826 ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg); 21827 pvt_set_needdestroy(p, "received 403 response"); 21828 } 21829 break; 21830 case 404: /* Not found */ 21831 if (p->registry && sipmethod == SIP_REGISTER) 21832 handle_response_register(p, resp, rest, req, seqno); 21833 else if (sipmethod == SIP_INVITE) 21834 handle_response_invite(p, resp, rest, req, seqno); 21835 else if (sipmethod == SIP_SUBSCRIBE) 21836 handle_response_subscribe(p, resp, rest, req, seqno); 21837 else if (owner) 21838 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 21839 break; 21840 case 423: /* Interval too brief */ 21841 if (sipmethod == SIP_REGISTER) 21842 handle_response_register(p, resp, rest, req, seqno); 21843 break; 21844 case 408: /* Request timeout - terminate dialog */ 21845 if (sipmethod == SIP_INVITE) 21846 handle_response_invite(p, resp, rest, req, seqno); 21847 else if (sipmethod == SIP_REGISTER) 21848 handle_response_register(p, resp, rest, req, seqno); 21849 else if (sipmethod == SIP_BYE) { 21850 pvt_set_needdestroy(p, "received 408 response"); 21851 ast_debug(4, "Got timeout on bye. Thanks for the answer. Now, kill this call\n"); 21852 } else { 21853 if (owner) 21854 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 21855 pvt_set_needdestroy(p, "received 408 response"); 21856 } 21857 break; 21858 21859 case 428: 21860 case 422: /* Session-Timers: Session Interval Too Small */ 21861 if (sipmethod == SIP_INVITE) { 21862 handle_response_invite(p, resp, rest, req, seqno); 21863 } 21864 break; 21865 21866 case 481: /* Call leg does not exist */ 21867 if (sipmethod == SIP_INVITE) { 21868 handle_response_invite(p, resp, rest, req, seqno); 21869 } else if (sipmethod == SIP_SUBSCRIBE) { 21870 handle_response_subscribe(p, resp, rest, req, seqno); 21871 } else if (sipmethod == SIP_BYE) { 21872 /* The other side has no transaction to bye, 21873 just assume it's all right then */ 21874 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 21875 } else if (sipmethod == SIP_CANCEL) { 21876 /* The other side has no transaction to cancel, 21877 just assume it's all right then */ 21878 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 21879 } else { 21880 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 21881 /* Guessing that this is not an important request */ 21882 } 21883 break; 21884 case 487: 21885 if (sipmethod == SIP_INVITE) 21886 handle_response_invite(p, resp, rest, req, seqno); 21887 break; 21888 case 415: /* Unsupported media type */ 21889 case 488: /* Not acceptable here - codec error */ 21890 case 606: /* Not Acceptable */ 21891 if (sipmethod == SIP_INVITE) 21892 handle_response_invite(p, resp, rest, req, seqno); 21893 break; 21894 case 491: /* Pending */ 21895 if (sipmethod == SIP_INVITE) 21896 handle_response_invite(p, resp, rest, req, seqno); 21897 else { 21898 ast_debug(1, "Got 491 on %s, unsupported. Call ID %s\n", sip_methods[sipmethod].text, p->callid); 21899 pvt_set_needdestroy(p, "received 491 response"); 21900 } 21901 break; 21902 case 405: /* Method not allowed */ 21903 case 501: /* Not Implemented */ 21904 mark_method_unallowed(&p->allowed_methods, sipmethod); 21905 if (p->relatedpeer) { 21906 mark_method_allowed(&p->relatedpeer->disallowed_methods, sipmethod); 21907 } 21908 if (sipmethod == SIP_INVITE) 21909 handle_response_invite(p, resp, rest, req, seqno); 21910 else 21911 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_sockaddr_stringify(&p->sa), msg); 21912 break; 21913 default: 21914 if ((resp >= 300) && (resp < 700)) { 21915 /* Fatal response */ 21916 if ((resp != 487)) 21917 ast_verb(3, "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_sockaddr_stringify(&p->sa)); 21918 21919 if (sipmethod == SIP_INVITE) 21920 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 21921 21922 /* XXX Locking issues?? XXX */ 21923 switch(resp) { 21924 case 300: /* Multiple Choices */ 21925 case 301: /* Moved permanently */ 21926 case 302: /* Moved temporarily */ 21927 case 305: /* Use Proxy */ 21928 if (p->owner) { 21929 struct ast_party_redirecting redirecting; 21930 struct ast_set_party_redirecting update_redirecting; 21931 21932 ast_party_redirecting_init(&redirecting); 21933 memset(&update_redirecting, 0, sizeof(update_redirecting)); 21934 change_redirecting_information(p, req, &redirecting, 21935 &update_redirecting, TRUE); 21936 ast_channel_set_redirecting(p->owner, &redirecting, 21937 &update_redirecting); 21938 ast_party_redirecting_free(&redirecting); 21939 } 21940 /* Fall through */ 21941 case 486: /* Busy here */ 21942 case 600: /* Busy everywhere */ 21943 case 603: /* Decline */ 21944 if (p->owner) { 21945 sip_handle_cc(p, req, AST_CC_CCBS); 21946 ast_queue_control(p->owner, AST_CONTROL_BUSY); 21947 } 21948 break; 21949 case 482: /* Loop Detected */ 21950 case 480: /* Temporarily Unavailable */ 21951 case 404: /* Not Found */ 21952 case 410: /* Gone */ 21953 case 400: /* Bad Request */ 21954 case 500: /* Server error */ 21955 if (sipmethod == SIP_SUBSCRIBE) { 21956 handle_response_subscribe(p, resp, rest, req, seqno); 21957 break; 21958 } 21959 /* Fall through */ 21960 case 502: /* Bad gateway */ 21961 case 503: /* Service Unavailable */ 21962 case 504: /* Server Timeout */ 21963 if (owner) 21964 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 21965 break; 21966 case 484: /* Address Incomplete */ 21967 if (owner && sipmethod != SIP_BYE) { 21968 switch (ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) { 21969 case SIP_PAGE2_ALLOWOVERLAP_YES: 21970 ast_queue_hangup_with_cause(p->owner, hangup_sip2cause(resp)); 21971 break; 21972 default: 21973 ast_queue_hangup_with_cause(p->owner, hangup_sip2cause(404)); 21974 break; 21975 } 21976 } 21977 break; 21978 default: 21979 /* Send hangup */ 21980 if (owner && sipmethod != SIP_BYE) 21981 ast_queue_hangup_with_cause(p->owner, hangup_sip2cause(resp)); 21982 break; 21983 } 21984 /* ACK on invite */ 21985 if (sipmethod == SIP_INVITE) 21986 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 21987 sip_alreadygone(p); 21988 if (!p->owner) { 21989 pvt_set_needdestroy(p, "transaction completed"); 21990 } 21991 } else if ((resp >= 100) && (resp < 200)) { 21992 if (sipmethod == SIP_INVITE) { 21993 if (!req->ignore && sip_cancel_destroy(p)) 21994 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 21995 if (find_sdp(req)) 21996 process_sdp(p, req, SDP_T38_NONE); 21997 if (p->owner) { 21998 /* Queue a progress frame */ 21999 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 22000 } 22001 } 22002 } else 22003 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)); 22004 } 22005 } else { 22006 /* Responses to OUTGOING SIP requests on INCOMING calls 22007 get handled here. As well as out-of-call message responses */ 22008 if (req->debug) 22009 ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg); 22010 22011 if (sipmethod == SIP_INVITE && resp == 200) { 22012 /* Tags in early session is replaced by the tag in 200 OK, which is 22013 the final reply to our INVITE */ 22014 char tag[128]; 22015 22016 gettag(req, "To", tag, sizeof(tag)); 22017 ast_string_field_set(p, theirtag, tag); 22018 } 22019 22020 switch(resp) { 22021 case 200: 22022 if (sipmethod == SIP_INVITE) { 22023 handle_response_invite(p, resp, rest, req, seqno); 22024 } else if (sipmethod == SIP_CANCEL) { 22025 ast_debug(1, "Got 200 OK on CANCEL\n"); 22026 22027 /* Wait for 487, then destroy */ 22028 } else if (sipmethod == SIP_BYE) { 22029 pvt_set_needdestroy(p, "transaction completed"); 22030 } 22031 break; 22032 case 401: /* www-auth */ 22033 case 407: 22034 if (sipmethod == SIP_INVITE) 22035 handle_response_invite(p, resp, rest, req, seqno); 22036 else if (sipmethod == SIP_BYE) { 22037 if (p->authtries == MAX_AUTHTRIES || do_proxy_auth(p, req, resp, sipmethod, 0)) { 22038 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 22039 pvt_set_needdestroy(p, "failed to authenticate BYE"); 22040 } 22041 } 22042 break; 22043 case 481: /* Call leg does not exist */ 22044 if (sipmethod == SIP_INVITE) { 22045 /* Re-invite failed */ 22046 handle_response_invite(p, resp, rest, req, seqno); 22047 } else if (sipmethod == SIP_BYE) { 22048 pvt_set_needdestroy(p, "received 481 response"); 22049 } else if (sipdebug) { 22050 ast_debug(1, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid); 22051 } 22052 break; 22053 case 501: /* Not Implemented */ 22054 if (sipmethod == SIP_INVITE) 22055 handle_response_invite(p, resp, rest, req, seqno); 22056 break; 22057 default: /* Errors without handlers */ 22058 if ((resp >= 100) && (resp < 200)) { 22059 if (sipmethod == SIP_INVITE) { /* re-invite */ 22060 if (!req->ignore && sip_cancel_destroy(p)) 22061 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 22062 } 22063 } 22064 if ((resp >= 300) && (resp < 700)) { 22065 if ((resp != 487)) 22066 ast_verb(3, "Incoming call: Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_sockaddr_stringify(&p->sa)); 22067 switch(resp) { 22068 case 415: /* Unsupported media type */ 22069 case 488: /* Not acceptable here - codec error */ 22070 case 603: /* Decline */ 22071 case 500: /* Server error */ 22072 case 502: /* Bad gateway */ 22073 case 503: /* Service Unavailable */ 22074 case 504: /* Server timeout */ 22075 22076 /* re-invite failed */ 22077 if (sipmethod == SIP_INVITE && sip_cancel_destroy(p)) 22078 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 22079 break; 22080 } 22081 } 22082 break; 22083 } 22084 } 22085 }
| 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 21567 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().
21568 { 21569 int sipmethod = SIP_INFO; 21570 21571 switch (resp) { 21572 case 401: /* Not www-authorized on SIP method */ 21573 case 407: /* Proxy auth required */ 21574 ast_log(LOG_WARNING, "Host '%s' requests authentication (%d) for '%s'\n", 21575 ast_sockaddr_stringify(&p->sa), resp, sip_methods[sipmethod].text); 21576 break; 21577 case 405: /* Method not allowed */ 21578 case 501: /* Not Implemented */ 21579 mark_method_unallowed(&p->allowed_methods, sipmethod); 21580 if (p->relatedpeer) { 21581 mark_method_allowed(&p->relatedpeer->disallowed_methods, sipmethod); 21582 } 21583 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", 21584 ast_sockaddr_stringify(&p->sa), sip_methods[sipmethod].text); 21585 break; 21586 default: 21587 if (300 <= resp && resp < 700) { 21588 ast_verb(3, "Got SIP %s response %d \"%s\" back from host '%s'\n", 21589 sip_methods[sipmethod].text, resp, rest, ast_sockaddr_stringify(&p->sa)); 21590 } 21591 break; 21592 } 21593 }
| 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 20660 of file chan_sip.c.
References append_history, AST_CAUSE_NORMAL_CLEARING, AST_CC_CCNR, ast_channel_queue_connected_line_update(), ast_channel_queue_redirecting_update(), AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER, AST_CONTROL_ANSWER, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_UPDATE_RTP_PEER, ast_debug, ast_log(), ast_null_frame, ast_party_connected_line_init(), ast_party_redirecting_free(), ast_party_redirecting_init(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, ast_queue_control(), ast_queue_frame(), ast_queue_hangup_with_cause(), ast_random(), ast_rtp_instance_activate(), ast_sched_add(), AST_SCHED_DEL_UNREF, ast_set_flag, ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_string_field_set, ast_strlen_zero(), ast_test_flag, build_route(), change_redirecting_information(), change_t38_state(), check_pendings(), connected, do_proxy_auth(), EVENT_FLAG_SYSTEM, FALSE, find_sdp(), get_header(), get_rpid(), 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().
20661 { 20662 int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING); 20663 int res = 0; 20664 int xmitres = 0; 20665 int reinvite = ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 20666 char *p_hdrval; 20667 int rtn; 20668 struct ast_party_connected_line connected; 20669 struct ast_set_party_connected_line update_connected; 20670 20671 if (reinvite) 20672 ast_debug(4, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid); 20673 else 20674 ast_debug(4, "SIP response %d to standard invite\n", resp); 20675 20676 if (p->alreadygone) { /* This call is already gone */ 20677 ast_debug(1, "Got response on call that is already terminated: %s (ignoring)\n", p->callid); 20678 return; 20679 } 20680 20681 /* Acknowledge sequence number - This only happens on INVITE from SIP-call */ 20682 /* Don't auto congest anymore since we've gotten something useful back */ 20683 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")); 20684 20685 /* RFC3261 says we must treat every 1xx response (but not 100) 20686 that we don't recognize as if it was 183. 20687 */ 20688 if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 181 && resp != 182 && resp != 183) 20689 resp = 183; 20690 20691 /* Any response between 100 and 199 is PROCEEDING */ 20692 if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING) 20693 p->invitestate = INV_PROCEEDING; 20694 20695 /* Final response, not 200 ? */ 20696 if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA )) 20697 p->invitestate = INV_COMPLETED; 20698 20699 if ((resp >= 200 && reinvite)) { 20700 p->ongoing_reinvite = 0; 20701 if (p->reinviteid > -1) { 20702 AST_SCHED_DEL_UNREF(sched, p->reinviteid, dialog_unref(p, "unref dialog for reinvite timeout because of a final response")); 20703 } 20704 } 20705 20706 /* Final response, clear out pending invite */ 20707 if ((resp == 200 || resp >= 300) && p->pendinginvite && seqno == p->pendinginvite) { 20708 p->pendinginvite = 0; 20709 } 20710 20711 /* If this is a response to our initial INVITE, we need to set what we can use 20712 * for this peer. 20713 */ 20714 if (!reinvite) { 20715 set_pvt_allowed_methods(p, req); 20716 } 20717 20718 switch (resp) { 20719 case 100: /* Trying */ 20720 case 101: /* Dialog establishment */ 20721 if (!req->ignore && p->invitestate != INV_CANCELLED && sip_cancel_destroy(p)) 20722 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 20723 check_pendings(p); 20724 break; 20725 20726 case 180: /* 180 Ringing */ 20727 case 182: /* 182 Queued */ 20728 if (!req->ignore && p->invitestate != INV_CANCELLED && sip_cancel_destroy(p)) 20729 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 20730 /* Store Route-set from provisional SIP responses so 20731 * early-dialog request can be routed properly 20732 * */ 20733 parse_ok_contact(p, req); 20734 if (!reinvite) { 20735 build_route(p, req, 1, resp); 20736 } 20737 if (!req->ignore && p->owner) { 20738 if (get_rpid(p, req)) { 20739 /* Queue a connected line update */ 20740 ast_party_connected_line_init(&connected); 20741 memset(&update_connected, 0, sizeof(update_connected)); 20742 20743 update_connected.id.number = 1; 20744 connected.id.number.valid = 1; 20745 connected.id.number.str = (char *) p->cid_num; 20746 connected.id.number.presentation = p->callingpres; 20747 20748 update_connected.id.name = 1; 20749 connected.id.name.valid = 1; 20750 connected.id.name.str = (char *) p->cid_name; 20751 connected.id.name.presentation = p->callingpres; 20752 20753 connected.id.tag = (char *) p->cid_tag; 20754 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; 20755 ast_channel_queue_connected_line_update(p->owner, &connected, 20756 &update_connected); 20757 } 20758 sip_handle_cc(p, req, AST_CC_CCNR); 20759 ast_queue_control(p->owner, AST_CONTROL_RINGING); 20760 if (p->owner->_state != AST_STATE_UP) { 20761 ast_setstate(p->owner, AST_STATE_RINGING); 20762 } 20763 } 20764 if (find_sdp(req)) { 20765 if (p->invitestate != INV_CANCELLED) 20766 p->invitestate = INV_EARLY_MEDIA; 20767 res = process_sdp(p, req, SDP_T38_NONE); 20768 if (!req->ignore && p->owner) { 20769 /* Queue a progress frame only if we have SDP in 180 or 182 */ 20770 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 20771 } 20772 ast_rtp_instance_activate(p->rtp); 20773 } 20774 check_pendings(p); 20775 break; 20776 20777 case 181: /* Call Is Being Forwarded */ 20778 if (!req->ignore && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 20779 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 20780 /* Store Route-set from provisional SIP responses so 20781 * early-dialog request can be routed properly 20782 * */ 20783 parse_ok_contact(p, req); 20784 if (!reinvite) { 20785 build_route(p, req, 1, resp); 20786 } 20787 if (!req->ignore && p->owner) { 20788 struct ast_party_redirecting redirecting; 20789 struct ast_set_party_redirecting update_redirecting; 20790 20791 ast_party_redirecting_init(&redirecting); 20792 memset(&update_redirecting, 0, sizeof(update_redirecting)); 20793 change_redirecting_information(p, req, &redirecting, &update_redirecting, 20794 FALSE); 20795 ast_channel_queue_redirecting_update(p->owner, &redirecting, 20796 &update_redirecting); 20797 ast_party_redirecting_free(&redirecting); 20798 sip_handle_cc(p, req, AST_CC_CCNR); 20799 } 20800 check_pendings(p); 20801 break; 20802 20803 case 183: /* Session progress */ 20804 if (!req->ignore && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 20805 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 20806 /* Store Route-set from provisional SIP responses so 20807 * early-dialog request can be routed properly 20808 * */ 20809 parse_ok_contact(p, req); 20810 if (!reinvite) { 20811 build_route(p, req, 1, resp); 20812 } 20813 if (!req->ignore && p->owner) { 20814 if (get_rpid(p, req)) { 20815 /* Queue a connected line update */ 20816 ast_party_connected_line_init(&connected); 20817 memset(&update_connected, 0, sizeof(update_connected)); 20818 20819 update_connected.id.number = 1; 20820 connected.id.number.valid = 1; 20821 connected.id.number.str = (char *) p->cid_num; 20822 connected.id.number.presentation = p->callingpres; 20823 20824 update_connected.id.name = 1; 20825 connected.id.name.valid = 1; 20826 connected.id.name.str = (char *) p->cid_name; 20827 connected.id.name.presentation = p->callingpres; 20828 20829 connected.id.tag = (char *) p->cid_tag; 20830 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; 20831 ast_channel_queue_connected_line_update(p->owner, &connected, 20832 &update_connected); 20833 } 20834 sip_handle_cc(p, req, AST_CC_CCNR); 20835 } 20836 if (find_sdp(req)) { 20837 if (p->invitestate != INV_CANCELLED) 20838 p->invitestate = INV_EARLY_MEDIA; 20839 res = process_sdp(p, req, SDP_T38_NONE); 20840 if (!req->ignore && p->owner) { 20841 /* Queue a progress frame */ 20842 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 20843 } 20844 ast_rtp_instance_activate(p->rtp); 20845 } else { 20846 /* Alcatel PBXs are known to send 183s with no SDP after sending 20847 * a 100 Trying response. We're just going to treat this sort of thing 20848 * the same as we would treat a 180 Ringing 20849 */ 20850 if (!req->ignore && p->owner) { 20851 ast_queue_control(p->owner, AST_CONTROL_RINGING); 20852 } 20853 } 20854 check_pendings(p); 20855 break; 20856 20857 case 200: /* 200 OK on invite - someone's answering our call */ 20858 if (!req->ignore && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 20859 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 20860 p->authtries = 0; 20861 if (find_sdp(req)) { 20862 if ((res = process_sdp(p, req, SDP_T38_ACCEPT)) && !req->ignore) 20863 if (!reinvite) { 20864 /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */ 20865 /* For re-invites, we try to recover */ 20866 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 20867 } 20868 ast_rtp_instance_activate(p->rtp); 20869 } 20870 20871 if (!req->ignore && p->owner) { 20872 int rpid_changed; 20873 20874 rpid_changed = get_rpid(p, req); 20875 if (rpid_changed || !reinvite) { 20876 /* Queue a connected line update */ 20877 ast_party_connected_line_init(&connected); 20878 memset(&update_connected, 0, sizeof(update_connected)); 20879 if (rpid_changed 20880 || !ast_strlen_zero(p->cid_num) 20881 || (p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) { 20882 update_connected.id.number = 1; 20883 connected.id.number.valid = 1; 20884 connected.id.number.str = (char *) p->cid_num; 20885 connected.id.number.presentation = p->callingpres; 20886 } 20887 if (rpid_changed 20888 || !ast_strlen_zero(p->cid_name) 20889 || (p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) { 20890 update_connected.id.name = 1; 20891 connected.id.name.valid = 1; 20892 connected.id.name.str = (char *) p->cid_name; 20893 connected.id.name.presentation = p->callingpres; 20894 } 20895 if (update_connected.id.number || update_connected.id.name) { 20896 connected.id.tag = (char *) p->cid_tag; 20897 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; 20898 ast_channel_queue_connected_line_update(p->owner, &connected, 20899 &update_connected); 20900 } 20901 } 20902 } 20903 20904 /* Parse contact header for continued conversation */ 20905 /* When we get 200 OK, we know which device (and IP) to contact for this call */ 20906 /* This is important when we have a SIP proxy between us and the phone */ 20907 if (outgoing) { 20908 update_call_counter(p, DEC_CALL_RINGING); 20909 parse_ok_contact(p, req); 20910 /* Save Record-Route for any later requests we make on this dialogue */ 20911 if (!reinvite) { 20912 build_route(p, req, 1, resp); 20913 } 20914 if(set_address_from_contact(p)) { 20915 /* Bad contact - we don't know how to reach this device */ 20916 /* We need to ACK, but then send a bye */ 20917 if (!p->route && !req->ignore) 20918 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 20919 } 20920 20921 } 20922 20923 if (!req->ignore && p->owner) { 20924 if (!reinvite) { 20925 ast_queue_control(p->owner, AST_CONTROL_ANSWER); 20926 if (sip_cfg.callevents) 20927 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", 20928 "Channel: %s\r\nChanneltype: %s\r\nUniqueid: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\nPeername: %s\r\n", 20929 p->owner->name, "SIP", p->owner->uniqueid, p->callid, p->fullcontact, p->peername); 20930 } else { /* RE-invite */ 20931 if (p->t38.state == T38_DISABLED) { 20932 ast_queue_control(p->owner, AST_CONTROL_UPDATE_RTP_PEER); 20933 } else { 20934 ast_queue_frame(p->owner, &ast_null_frame); 20935 } 20936 } 20937 } else { 20938 /* It's possible we're getting an 200 OK after we've tried to disconnect 20939 by sending CANCEL */ 20940 /* First send ACK, then send bye */ 20941 if (!req->ignore) 20942 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 20943 } 20944 20945 /* Check for Session-Timers related headers */ 20946 if (st_get_mode(p, 0) != SESSION_TIMER_MODE_REFUSE && p->outgoing_call == TRUE && !reinvite) { 20947 p_hdrval = (char*)get_header(req, "Session-Expires"); 20948 if (!ast_strlen_zero(p_hdrval)) { 20949 /* UAS supports Session-Timers */ 20950 enum st_refresher_param st_ref_param; 20951 int tmp_st_interval = 0; 20952 rtn = parse_session_expires(p_hdrval, &tmp_st_interval, &st_ref_param); 20953 if (rtn != 0) { 20954 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 20955 } else if (tmp_st_interval < st_get_se(p, FALSE)) { 20956 ast_log(LOG_WARNING, "Got Session-Expires less than local Min-SE in 200 OK, tearing down call\n"); 20957 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 20958 } 20959 if (st_ref_param == SESSION_TIMER_REFRESHER_PARAM_UAC) { 20960 p->stimer->st_ref = SESSION_TIMER_REFRESHER_US; 20961 } else if (st_ref_param == SESSION_TIMER_REFRESHER_PARAM_UAS) { 20962 p->stimer->st_ref = SESSION_TIMER_REFRESHER_THEM; 20963 } else { 20964 ast_log(LOG_WARNING, "Unknown refresher on %s\n", p->callid); 20965 } 20966 if (tmp_st_interval) { 20967 p->stimer->st_interval = tmp_st_interval; 20968 } 20969 p->stimer->st_active = TRUE; 20970 p->stimer->st_active_peer_ua = TRUE; 20971 start_session_timer(p); 20972 } else { 20973 /* UAS doesn't support Session-Timers */ 20974 if (st_get_mode(p, 0) == SESSION_TIMER_MODE_ORIGINATE) { 20975 p->stimer->st_ref = SESSION_TIMER_REFRESHER_US; 20976 p->stimer->st_active_peer_ua = FALSE; 20977 start_session_timer(p); 20978 } 20979 } 20980 } 20981 20982 20983 /* If I understand this right, the branch is different for a non-200 ACK only */ 20984 p->invitestate = INV_TERMINATED; 20985 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 20986 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE); 20987 check_pendings(p); 20988 break; 20989 20990 case 407: /* Proxy authentication */ 20991 case 401: /* Www auth */ 20992 /* First we ACK */ 20993 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 20994 if (p->options) 20995 p->options->auth_type = resp; 20996 20997 /* Then we AUTH */ 20998 ast_string_field_set(p, theirtag, NULL); /* forget their old tag, so we don't match tags when getting response */ 20999 if (!req->ignore) { 21000 if (p->authtries < MAX_AUTHTRIES) 21001 p->invitestate = INV_CALLING; 21002 if (p->authtries == MAX_AUTHTRIES || do_proxy_auth(p, req, resp, SIP_INVITE, 1)) { 21003 ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); 21004 pvt_set_needdestroy(p, "failed to authenticate on INVITE"); 21005 sip_alreadygone(p); 21006 if (p->owner) 21007 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 21008 } 21009 } 21010 break; 21011 21012 case 403: /* Forbidden */ 21013 /* First we ACK */ 21014 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 21015 ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From")); 21016 if (!req->ignore && p->owner) { 21017 sip_queue_hangup_cause(p, hangup_sip2cause(resp)); 21018 } 21019 break; 21020 21021 case 404: /* Not found */ 21022 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 21023 if (p->owner && !req->ignore) { 21024 sip_queue_hangup_cause(p, hangup_sip2cause(resp)); 21025 } 21026 break; 21027 21028 case 481: /* Call leg does not exist */ 21029 /* Could be REFER caused INVITE with replaces */ 21030 ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid); 21031 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 21032 if (p->owner) { 21033 ast_queue_hangup_with_cause(p->owner, hangup_sip2cause(resp)); 21034 } 21035 break; 21036 21037 case 422: /* Session-Timers: Session interval too small */ 21038 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 21039 ast_string_field_set(p, theirtag, NULL); 21040 proc_422_rsp(p, req); 21041 break; 21042 21043 case 428: /* Use identity header - rfc 4474 - not supported by Asterisk yet */ 21044 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 21045 append_history(p, "Identity", "SIP identity is required. Not supported by Asterisk."); 21046 ast_log(LOG_WARNING, "SIP identity required by proxy. SIP dialog '%s'. Giving up.\n", p->callid); 21047 if (p->owner && !req->ignore) { 21048 ast_queue_hangup_with_cause(p->owner, hangup_sip2cause(resp)); 21049 } 21050 break; 21051 21052 case 487: /* Cancelled transaction */ 21053 /* We have sent CANCEL on an outbound INVITE 21054 This transaction is already scheduled to be killed by sip_hangup(). 21055 */ 21056 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 21057 if (p->owner && !req->ignore) { 21058 ast_queue_hangup_with_cause(p->owner, AST_CAUSE_NORMAL_CLEARING); 21059 append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request"); 21060 } else if (!req->ignore) { 21061 update_call_counter(p, DEC_CALL_LIMIT); 21062 append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog."); 21063 } 21064 check_pendings(p); 21065 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 21066 break; 21067 case 415: /* Unsupported media type */ 21068 case 488: /* Not acceptable here */ 21069 case 606: /* Not Acceptable */ 21070 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 21071 if (p->udptl && p->t38.state == T38_LOCAL_REINVITE) { 21072 change_t38_state(p, T38_DISABLED); 21073 /* Try to reset RTP timers */ 21074 //ast_rtp_set_rtptimers_onhold(p->rtp); 21075 21076 /* Trigger a reinvite back to audio */ 21077 transmit_reinvite_with_sdp(p, FALSE, FALSE); 21078 } else { 21079 /* We can't set up this call, so give up */ 21080 if (p->owner && !req->ignore) { 21081 ast_queue_hangup_with_cause(p->owner, hangup_sip2cause(resp)); 21082 } 21083 } 21084 break; 21085 case 491: /* Pending */ 21086 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 21087 if (p->owner && !req->ignore) { 21088 if (p->owner->_state != AST_STATE_UP) { 21089 ast_queue_hangup_with_cause(p->owner, hangup_sip2cause(resp)); 21090 } else { 21091 /* This is a re-invite that failed. */ 21092 /* Reset the flag after a while 21093 */ 21094 int wait; 21095 /* RFC 3261, if owner of call, wait between 2.1 to 4 seconds, 21096 * if not owner of call, wait 0 to 2 seconds */ 21097 if (p->outgoing_call) { 21098 wait = 2100 + ast_random() % 2000; 21099 } else { 21100 wait = ast_random() % 2000; 21101 } 21102 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.")); 21103 ast_log(LOG_WARNING, "just did sched_add waitid(%d) for sip_reinvite_retry for dialog %s in handle_response_invite\n", p->waitid, p->callid); 21104 ast_debug(2, "Reinvite race. Waiting %d secs before retry\n", wait); 21105 } 21106 } 21107 break; 21108 21109 case 408: /* Request timeout */ 21110 case 405: /* Not allowed */ 21111 case 501: /* Not implemented */ 21112 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 21113 if (p->owner) { 21114 ast_queue_hangup_with_cause(p->owner, hangup_sip2cause(resp)); 21115 } 21116 break; 21117 } 21118 if (xmitres == XMIT_ERROR) 21119 ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid); 21120 }
| 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 21603 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().
21604 { 21605 int sipmethod = SIP_MESSAGE; 21606 /* Out-of-dialog MESSAGE currently not supported. */ 21607 //int in_dialog = ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 21608 21609 switch (resp) { 21610 case 401: /* Not www-authorized on SIP method */ 21611 case 407: /* Proxy auth required */ 21612 ast_log(LOG_WARNING, "Host '%s' requests authentication (%d) for '%s'\n", 21613 ast_sockaddr_stringify(&p->sa), resp, sip_methods[sipmethod].text); 21614 break; 21615 case 405: /* Method not allowed */ 21616 case 501: /* Not Implemented */ 21617 mark_method_unallowed(&p->allowed_methods, sipmethod); 21618 if (p->relatedpeer) { 21619 mark_method_allowed(&p->relatedpeer->disallowed_methods, sipmethod); 21620 } 21621 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", 21622 ast_sockaddr_stringify(&p->sa), sip_methods[sipmethod].text); 21623 break; 21624 default: 21625 if (100 <= resp && resp < 200) { 21626 /* Must allow provisional responses for out-of-dialog requests. */ 21627 } else if (200 <= resp && resp < 300) { 21628 p->authtries = 0; /* Reset authentication counter */ 21629 } else if (300 <= resp && resp < 700) { 21630 ast_verb(3, "Got SIP %s response %d \"%s\" back from host '%s'\n", 21631 sip_methods[sipmethod].text, resp, rest, ast_sockaddr_stringify(&p->sa)); 21632 } 21633 break; 21634 } 21635 }
| 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 21125 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().
21126 { 21127 switch (resp) { 21128 case 200: /* Notify accepted */ 21129 /* They got the notify, this is the end */ 21130 if (p->owner) { 21131 if (p->refer) { 21132 ast_log(LOG_NOTICE, "Got OK on REFER Notify message\n"); 21133 } else { 21134 ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name); 21135 } 21136 } else { 21137 if (p->subscribed == NONE && !p->refer) { 21138 ast_debug(4, "Got 200 accepted on NOTIFY %s\n", p->callid); 21139 pvt_set_needdestroy(p, "received 200 response"); 21140 } 21141 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 21142 /* Ready to send the next state we have on queue */ 21143 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 21144 cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p); 21145 } 21146 } 21147 break; 21148 case 401: /* Not www-authorized on SIP method */ 21149 case 407: /* Proxy auth */ 21150 if (!p->notify) { 21151 break; /* Only device notify can use NOTIFY auth */ 21152 } 21153 ast_string_field_set(p, theirtag, NULL); 21154 if (ast_strlen_zero(p->authname)) { 21155 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)); 21156 pvt_set_needdestroy(p, "unable to authenticate NOTIFY"); 21157 } 21158 if (p->authtries > 1 || do_proxy_auth(p, req, resp, SIP_NOTIFY, 0)) { 21159 ast_log(LOG_NOTICE, "Failed to authenticate on NOTIFY to '%s'\n", get_header(&p->initreq, "From")); 21160 pvt_set_needdestroy(p, "failed to authenticate NOTIFY"); 21161 } 21162 break; 21163 case 481: /* Call leg does not exist */ 21164 pvt_set_needdestroy(p, "Received 481 response for NOTIFY"); 21165 break; 21166 } 21167 }
| static void handle_response_peerpoke | ( | struct sip_pvt * | p, | |
| int | resp, | |||
| struct sip_request * | req | |||
| ) | [static] |
Handle qualification responses (OPTIONS).
Definition at line 21500 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().
21501 { 21502 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! */ 21503 int statechanged, is_reachable, was_reachable; 21504 int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps); 21505 21506 /* 21507 * Compute the response time to a ping (goes in peer->lastms.) 21508 * -1 means did not respond, 0 means unknown, 21509 * 1..maxms is a valid response, >maxms means late response. 21510 */ 21511 if (pingtime < 1) { /* zero = unknown, so round up to 1 */ 21512 pingtime = 1; 21513 } 21514 21515 if (!peer->maxms) { /* this should never happens */ 21516 pvt_set_needdestroy(p, "got OPTIONS response but qualify is not enabled"); 21517 return; 21518 } 21519 21520 /* Now determine new state and whether it has changed. 21521 * Use some helper variables to simplify the writing 21522 * of the expressions. 21523 */ 21524 was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms; 21525 is_reachable = pingtime <= peer->maxms; 21526 statechanged = peer->lastms == 0 /* yes, unknown before */ 21527 || was_reachable != is_reachable; 21528 21529 peer->lastms = pingtime; 21530 peer->call = dialog_unref(peer->call, "unref dialog peer->call"); 21531 if (statechanged) { 21532 const char *s = is_reachable ? "Reachable" : "Lagged"; 21533 char str_lastms[20]; 21534 snprintf(str_lastms, sizeof(str_lastms), "%d", pingtime); 21535 21536 ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n", 21537 peer->name, s, pingtime, peer->maxms); 21538 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", peer->name); 21539 if (sip_cfg.peer_rtupdate) { 21540 ast_update_realtime(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", "name", peer->name, "lastms", str_lastms, SENTINEL); 21541 } 21542 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 21543 "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n", 21544 peer->name, s, pingtime); 21545 if (is_reachable && sip_cfg.regextenonqualify) 21546 register_peer_exten(peer, TRUE); 21547 } 21548 21549 pvt_set_needdestroy(p, "got OPTIONS response"); 21550 21551 /* Try again eventually */ 21552 AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, 21553 is_reachable ? peer->qualifyfreq : DEFAULT_FREQ_NOTOK, 21554 sip_poke_peer_s, peer, 21555 unref_peer(_data, "removing poke peer ref"), 21556 unref_peer(peer, "removing poke peer ref"), 21557 ref_peer(peer, "adding poke peer ref")); 21558 }
| 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 20574 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().
20575 { 20576 struct sip_epa_entry *epa_entry = p->epa_entry; 20577 const char *etag = get_header(req, "Sip-ETag"); 20578 20579 ast_assert(epa_entry != NULL); 20580 20581 if (resp == 401 || resp == 407) { 20582 ast_string_field_set(p, theirtag, NULL); 20583 if (p->options) { 20584 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 20585 } 20586 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, resp, SIP_PUBLISH, 0)) { 20587 ast_log(LOG_NOTICE, "Failed to authenticate on PUBLISH to '%s'\n", get_header(&p->initreq, "From")); 20588 pvt_set_needdestroy(p, "Failed to authenticate on PUBLISH"); 20589 sip_alreadygone(p); 20590 } 20591 return; 20592 } 20593 20594 if (resp == 501 || resp == 405) { 20595 mark_method_unallowed(&p->allowed_methods, SIP_PUBLISH); 20596 } 20597 20598 if (resp == 200) { 20599 p->authtries = 0; 20600 /* If I've read section 6, item 6 of RFC 3903 correctly, 20601 * an ESC will only generate a new etag when it sends a 200 OK 20602 */ 20603 if (!ast_strlen_zero(etag)) { 20604 ast_copy_string(epa_entry->entity_tag, etag, sizeof(epa_entry->entity_tag)); 20605 } 20606 /* The nominal case. Everything went well. Everybody is happy. 20607 * Each EPA will have a specific action to take as a result of this 20608 * development, so ... callbacks! 20609 */ 20610 if (epa_entry->static_data->handle_ok) { 20611 epa_entry->static_data->handle_ok(p, req, epa_entry); 20612 } 20613 } else { 20614 /* Rather than try to make individual callbacks for each error 20615 * type, there is just a single error callback. The callback 20616 * can distinguish between error messages and do what it needs to 20617 */ 20618 if (epa_entry->static_data->handle_error) { 20619 epa_entry->static_data->handle_error(p, resp, req, epa_entry); 20620 } 20621 } 20622 }
| 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 21256 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().
21257 { 21258 enum ast_control_transfer message = AST_TRANSFER_FAILED; 21259 21260 /* If no refer structure exists, then do nothing */ 21261 if (!p->refer) 21262 return; 21263 21264 switch (resp) { 21265 case 202: /* Transfer accepted */ 21266 /* We need to do something here */ 21267 /* The transferee is now sending INVITE to target */ 21268 p->refer->status = REFER_ACCEPTED; 21269 /* Now wait for next message */ 21270 ast_debug(3, "Got 202 accepted on transfer\n"); 21271 /* We should hang along, waiting for NOTIFY's here */ 21272 break; 21273 21274 case 401: /* Not www-authorized on SIP method */ 21275 case 407: /* Proxy auth */ 21276 if (ast_strlen_zero(p->authname)) { 21277 ast_log(LOG_WARNING, "Asked to authenticate REFER to %s but we have no matching peer or realm auth!\n", 21278 ast_sockaddr_stringify(&p->recv)); 21279 if (p->owner) { 21280 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 21281 } 21282 pvt_set_needdestroy(p, "unable to authenticate REFER"); 21283 } 21284 if (p->authtries > 1 || do_proxy_auth(p, req, resp, SIP_REFER, 0)) { 21285 ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From")); 21286 p->refer->status = REFER_NOAUTH; 21287 if (p->owner) { 21288 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 21289 } 21290 pvt_set_needdestroy(p, "failed to authenticate REFER"); 21291 } 21292 break; 21293 21294 case 405: /* Method not allowed */ 21295 /* Return to the current call onhold */ 21296 /* Status flag needed to be reset */ 21297 ast_log(LOG_NOTICE, "SIP transfer to %s failed, REFER not allowed. \n", p->refer->refer_to); 21298 pvt_set_needdestroy(p, "received 405 response"); 21299 p->refer->status = REFER_FAILED; 21300 if (p->owner) { 21301 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 21302 } 21303 break; 21304 21305 case 481: /* Call leg does not exist */ 21306 21307 /* A transfer with Replaces did not work */ 21308 /* OEJ: We should Set flag, cancel the REFER, go back 21309 to original call - but right now we can't */ 21310 ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid); 21311 if (p->owner) 21312 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 21313 pvt_set_needdestroy(p, "received 481 response"); 21314 break; 21315 21316 case 500: /* Server error */ 21317 case 501: /* Method not implemented */ 21318 /* Return to the current call onhold */ 21319 /* Status flag needed to be reset */ 21320 ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to); 21321 pvt_set_needdestroy(p, "received 500/501 response"); 21322 p->refer->status = REFER_FAILED; 21323 if (p->owner) { 21324 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 21325 } 21326 break; 21327 case 603: /* Transfer declined */ 21328 ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to); 21329 p->refer->status = REFER_FAILED; 21330 pvt_set_needdestroy(p, "received 603 response"); 21331 if (p->owner) { 21332 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 21333 } 21334 break; 21335 default: 21336 /* We should treat unrecognized 9xx as 900. 400 is actually 21337 specified as a possible response, but any 4-6xx is 21338 theoretically possible. */ 21339 21340 if (resp < 299) { /* 1xx cases don't get here */ 21341 ast_log(LOG_WARNING, "SIP transfer to %s had unxpected 2xx response (%d), confusion is possible. \n", p->refer->refer_to, resp); 21342 } else { 21343 ast_log(LOG_WARNING, "SIP transfer to %s with response (%d). \n", p->refer->refer_to, resp); 21344 } 21345 21346 p->refer->status = REFER_FAILED; 21347 pvt_set_needdestroy(p, "received failure response"); 21348 if (p->owner) { 21349 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 21350 } 21351 break; 21352 } 21353 }
| 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 21356 of file chan_sip.c.
References __get_header(), ast_debug, ast_log(), AST_SCHED_DEL_UNREF, AST_SCHED_REPLACE_UNREF, ast_strlen_zero(), ast_tvnow(), do_register_auth(), EVENT_FLAG_SYSTEM, get_header(), LOG_NOTICE, LOG_WARNING, manager_event, MAX, pvt_set_needdestroy(), REG_STATE_NOAUTH, REG_STATE_REGISTERED, REG_STATE_REJECTED, REG_STATE_UNREGISTERED, registry_addref(), registry_unref(), regstate2str(), S_OR, sip_reregister(), sip_scheddestroy(), and transmit_register().
Referenced by handle_response().
21357 { 21358 int expires, expires_ms; 21359 struct sip_registry *r; 21360 r=p->registry; 21361 21362 switch (resp) { 21363 case 401: /* Unauthorized */ 21364 if (p->authtries == MAX_AUTHTRIES || do_register_auth(p, req, resp)) { 21365 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries); 21366 pvt_set_needdestroy(p, "failed to authenticate REGISTER"); 21367 } 21368 break; 21369 case 403: /* Forbidden */ 21370 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); 21371 AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 403")); 21372 r->regstate = REG_STATE_NOAUTH; 21373 pvt_set_needdestroy(p, "received 403 response"); 21374 break; 21375 case 404: /* Not found */ 21376 ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username, p->registry->hostname); 21377 pvt_set_needdestroy(p, "received 404 response"); 21378 if (r->call) 21379 r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 404"); 21380 r->regstate = REG_STATE_REJECTED; 21381 AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 404")); 21382 break; 21383 case 407: /* Proxy auth */ 21384 if (p->authtries == MAX_AUTHTRIES || do_register_auth(p, req, resp)) { 21385 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries); 21386 pvt_set_needdestroy(p, "failed to authenticate REGISTER"); 21387 } 21388 break; 21389 case 408: /* Request timeout */ 21390 /* Got a timeout response, so reset the counter of failed responses */ 21391 if (r) { 21392 r->regattempts = 0; 21393 } else { 21394 ast_log(LOG_WARNING, "Got a 408 response to our REGISTER on call %s after we had destroyed the registry object\n", p->callid); 21395 } 21396 break; 21397 case 423: /* Interval too brief */ 21398 r->expiry = atoi(get_header(req, "Min-Expires")); 21399 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); 21400 AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 423")); 21401 if (r->call) { 21402 r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 423"); 21403 pvt_set_needdestroy(p, "received 423 response"); 21404 } 21405 if (r->expiry > max_expiry) { 21406 ast_log(LOG_WARNING, "Required expiration time from %s@%s is too high, giving up\n", p->registry->username, p->registry->hostname); 21407 r->expiry = r->configured_expiry; 21408 r->regstate = REG_STATE_REJECTED; 21409 } else { 21410 r->regstate = REG_STATE_UNREGISTERED; 21411 transmit_register(r, SIP_REGISTER, NULL, NULL); 21412 } 21413 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)); 21414 break; 21415 case 479: /* SER: Not able to process the URI - address is wrong in register*/ 21416 ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username, p->registry->hostname); 21417 pvt_set_needdestroy(p, "received 479 response"); 21418 if (r->call) 21419 r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 479"); 21420 r->regstate = REG_STATE_REJECTED; 21421 AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 479")); 21422 break; 21423 case 200: /* 200 OK */ 21424 if (!r) { 21425 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)); 21426 pvt_set_needdestroy(p, "received erroneous 200 response"); 21427 return 0; 21428 } 21429 21430 r->regstate = REG_STATE_REGISTERED; 21431 r->regtime = ast_tvnow(); /* Reset time of last successful registration */ 21432 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)); 21433 r->regattempts = 0; 21434 ast_debug(1, "Registration successful\n"); 21435 if (r->timeout > -1) { 21436 ast_debug(1, "Cancelling timeout %d\n", r->timeout); 21437 } 21438 AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 200")); 21439 if (r->call) 21440 r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 200"); 21441 p->registry = registry_unref(p->registry, "unref registry entry p->registry"); 21442 /* Let this one hang around until we have all the responses */ 21443 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 21444 /* p->needdestroy = 1; */ 21445 21446 /* set us up for re-registering 21447 * figure out how long we got registered for 21448 * according to section 6.13 of RFC, contact headers override 21449 * expires headers, so check those first */ 21450 expires = 0; 21451 21452 /* XXX todo: try to save the extra call */ 21453 if (!ast_strlen_zero(get_header(req, "Contact"))) { 21454 const char *contact = NULL; 21455 const char *tmptmp = NULL; 21456 int start = 0; 21457 for(;;) { 21458 contact = __get_header(req, "Contact", &start); 21459 /* this loop ensures we get a contact header about our register request */ 21460 if(!ast_strlen_zero(contact)) { 21461 if( (tmptmp=strstr(contact, p->our_contact))) { 21462 contact=tmptmp; 21463 break; 21464 } 21465 } else 21466 break; 21467 } 21468 tmptmp = strcasestr(contact, "expires="); 21469 if (tmptmp) { 21470 if (sscanf(tmptmp + 8, "%30d;", &expires) != 1) 21471 expires = 0; 21472 } 21473 21474 } 21475 if (!expires) 21476 expires=atoi(get_header(req, "expires")); 21477 if (!expires) 21478 expires=default_expiry; 21479 21480 expires_ms = expires * 1000; 21481 if (expires <= EXPIRY_GUARD_LIMIT) 21482 expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT), EXPIRY_GUARD_MIN); 21483 else 21484 expires_ms -= EXPIRY_GUARD_SECS * 1000; 21485 if (sipdebug) 21486 ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 21487 21488 r->refresh= (int) expires_ms / 1000; 21489 21490 /* Schedule re-registration before we expire */ 21491 AST_SCHED_REPLACE_UNREF(r->expire, sched, expires_ms, sip_reregister, r, 21492 registry_unref(_data,"unref in REPLACE del fail"), 21493 registry_unref(r,"unref in REPLACE add fail"), 21494 registry_addref(r,"The Addition side of REPLACE")); 21495 } 21496 return 1; 21497 }
| 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 21170 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().
21171 { 21172 if (p->subscribed == CALL_COMPLETION) { 21173 struct sip_monitor_instance *monitor_instance; 21174 21175 if (resp < 300) { 21176 return; 21177 } 21178 21179 /* Final failure response received. */ 21180 monitor_instance = ao2_callback(sip_monitor_instances, 0, 21181 find_sip_monitor_instance_by_subscription_pvt, p); 21182 if (monitor_instance) { 21183 ast_cc_monitor_failed(monitor_instance->core_id, 21184 monitor_instance->device_name, 21185 "Received error response to our SUBSCRIBE"); 21186 } 21187 return; 21188 } 21189 21190 if (p->subscribed != MWI_NOTIFICATION) { 21191 return; 21192 } 21193 if (!p->mwi) { 21194 return; 21195 } 21196 21197 switch (resp) { 21198 case 200: /* Subscription accepted */ 21199 ast_debug(3, "Got 200 OK on subscription for MWI\n"); 21200 set_pvt_allowed_methods(p, req); 21201 if (p->options) { 21202 if (p->options->outboundproxy) { 21203 ao2_ref(p->options->outboundproxy, -1); 21204 } 21205 ast_free(p->options); 21206 p->options = NULL; 21207 } 21208 p->mwi->subscribed = 1; 21209 if ((p->mwi->resub = ast_sched_add(sched, mwi_expiry * 1000, sip_subscribe_mwi_do, ASTOBJ_REF(p->mwi))) < 0) { 21210 ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); 21211 } 21212 break; 21213 case 401: 21214 case 407: 21215 ast_string_field_set(p, theirtag, NULL); 21216 if (p->authtries > 1 || do_proxy_auth(p, req, resp, SIP_SUBSCRIBE, 0)) { 21217 ast_log(LOG_NOTICE, "Failed to authenticate on SUBSCRIBE to '%s'\n", get_header(&p->initreq, "From")); 21218 p->mwi->call = NULL; 21219 ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); 21220 pvt_set_needdestroy(p, "failed to authenticate SUBSCRIBE"); 21221 } 21222 break; 21223 case 403: 21224 transmit_response_with_date(p, "200 OK", req); 21225 ast_log(LOG_WARNING, "Authentication failed while trying to subscribe for MWI.\n"); 21226 p->mwi->call = NULL; 21227 ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); 21228 pvt_set_needdestroy(p, "received 403 response"); 21229 sip_alreadygone(p); 21230 break; 21231 case 404: 21232 ast_log(LOG_WARNING, "Subscription failed for MWI. The remote side said that a mailbox may not have been configured.\n"); 21233 p->mwi->call = NULL; 21234 ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); 21235 pvt_set_needdestroy(p, "received 404 response"); 21236 break; 21237 case 481: 21238 ast_log(LOG_WARNING, "Subscription failed for MWI. The remote side said that our dialog did not exist.\n"); 21239 p->mwi->call = NULL; 21240 ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); 21241 pvt_set_needdestroy(p, "received 481 response"); 21242 break; 21243 case 500: 21244 case 501: 21245 ast_log(LOG_WARNING, "Subscription failed for MWI. The remote side may have suffered a heart attack.\n"); 21246 p->mwi->call = NULL; 21247 ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); 21248 pvt_set_needdestroy(p, "received 500/501 response"); 21249 break; 21250 } 21251 }
| 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 20514 of file chan_sip.c.
References ast_log(), do_proxy_auth(), get_header(), and LOG_NOTICE.
Referenced by handle_response().
20515 { 20516 if (p->options) { 20517 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 20518 } 20519 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, resp, SIP_UPDATE, 1)) { 20520 ast_log(LOG_NOTICE, "Failed to authenticate on UPDATE to '%s'\n", get_header(&p->initreq, "From")); 20521 } 20522 }
| 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 24997 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().
24998 { 24999 struct sip_esc_entry *esc_entry = create_esc_entry(esc, req, expires); 25000 int res = 0; 25001 25002 if (!esc_entry) { 25003 transmit_response(p, "503 Internal Server Failure", req); 25004 return -1; 25005 } 25006 25007 if (esc->callbacks->initial_handler) { 25008 res = esc->callbacks->initial_handler(p, req, esc, esc_entry); 25009 } 25010 25011 if (!res) { 25012 transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 0); 25013 } 25014 25015 ao2_ref(esc_entry, -1); 25016 return res; 25017 }
| 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 25047 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().
25048 { 25049 struct sip_esc_entry *esc_entry = get_esc_entry(etag, esc); 25050 int expires_ms = expires * 1000; 25051 int res = 0; 25052 25053 if (!esc_entry) { 25054 transmit_response(p, "412 Conditional Request Failed", req); 25055 return -1; 25056 } 25057 25058 AST_SCHED_REPLACE_UNREF(esc_entry->sched_id, sched, expires_ms, publish_expire, esc_entry, 25059 ao2_ref(_data, -1), 25060 ao2_ref(esc_entry, -1), 25061 ao2_ref(esc_entry, +1)); 25062 25063 if (esc->callbacks->modify_handler) { 25064 res = esc->callbacks->modify_handler(p, req, esc, esc_entry); 25065 } 25066 25067 if (!res) { 25068 transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 1); 25069 } 25070 25071 ao2_ref(esc_entry, -1); 25072 return res; 25073 }
| 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 25019 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().
25020 { 25021 struct sip_esc_entry *esc_entry = get_esc_entry(etag, esc); 25022 int expires_ms = expires * 1000; 25023 int res = 0; 25024 25025 if (!esc_entry) { 25026 transmit_response(p, "412 Conditional Request Failed", req); 25027 return -1; 25028 } 25029 25030 AST_SCHED_REPLACE_UNREF(esc_entry->sched_id, sched, expires_ms, publish_expire, esc_entry, 25031 ao2_ref(_data, -1), 25032 ao2_ref(esc_entry, -1), 25033 ao2_ref(esc_entry, +1)); 25034 25035 if (esc->callbacks->refresh_handler) { 25036 res = esc->callbacks->refresh_handler(p, req, esc, esc_entry); 25037 } 25038 25039 if (!res) { 25040 transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 1); 25041 } 25042 25043 ao2_ref(esc_entry, -1); 25044 return res; 25045 }
| 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 25075 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().
25076 { 25077 struct sip_esc_entry *esc_entry = get_esc_entry(etag, esc); 25078 int res = 0; 25079 25080 if (!esc_entry) { 25081 transmit_response(p, "412 Conditional Request Failed", req); 25082 return -1; 25083 } 25084 25085 AST_SCHED_DEL(sched, esc_entry->sched_id); 25086 /* Scheduler's ref of the esc_entry */ 25087 ao2_ref(esc_entry, -1); 25088 25089 if (esc->callbacks->remove_handler) { 25090 res = esc->callbacks->remove_handler(p, req, esc, esc_entry); 25091 } 25092 25093 if (!res) { 25094 transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 1); 25095 } 25096 25097 /* Ref from finding the esc_entry earlier in function */ 25098 ao2_unlink(esc->compositor, esc_entry); 25099 ao2_ref(esc_entry, -1); 25100 return res; 25101 }
| static int handle_t38_options | ( | struct ast_flags * | flags, | |
| struct ast_flags * | mask, | |||
| struct ast_variable * | v, | |||
| int * | maxdatagram | |||
| ) | [static] |
Handle T.38 configuration options common to users and peers.
Definition at line 27429 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().
27431 { 27432 int res = 1; 27433 27434 if (!strcasecmp(v->name, "t38pt_udptl")) { 27435 char *buf = ast_strdupa(v->value); 27436 char *word, *next = buf; 27437 27438 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT); 27439 27440 while ((word = strsep(&next, ","))) { 27441 if (ast_true(word) || !strcasecmp(word, "fec")) { 27442 ast_clear_flag(&flags[1], SIP_PAGE2_T38SUPPORT); 27443 ast_set_flag(&flags[1], SIP_PAGE2_T38SUPPORT_UDPTL_FEC); 27444 } else if (!strcasecmp(word, "redundancy")) { 27445 ast_clear_flag(&flags[1], SIP_PAGE2_T38SUPPORT); 27446 ast_set_flag(&flags[1], SIP_PAGE2_T38SUPPORT_UDPTL_REDUNDANCY); 27447 } else if (!strcasecmp(word, "none")) { 27448 ast_clear_flag(&flags[1], SIP_PAGE2_T38SUPPORT); 27449 ast_set_flag(&flags[1], SIP_PAGE2_T38SUPPORT_UDPTL); 27450 } else if (!strncasecmp(word, "maxdatagram=", 12)) { 27451 if (sscanf(&word[12], "%30u", maxdatagram) != 1) { 27452 ast_log(LOG_WARNING, "Invalid maxdatagram '%s' at line %d of %s\n", v->value, v->lineno, config); 27453 *maxdatagram = global_t38_maxdatagram; 27454 } 27455 } 27456 } 27457 } else if (!strcasecmp(v->name, "t38pt_usertpsource")) { 27458 ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION); 27459 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION); 27460 } else { 27461 res = 0; 27462 } 27463 27464 return res; 27465 }
| 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 6574 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().
06575 { 06576 switch (cause) { 06577 case AST_CAUSE_UNALLOCATED: /* 1 */ 06578 case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */ 06579 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */ 06580 return "404 Not Found"; 06581 case AST_CAUSE_CONGESTION: /* 34 */ 06582 case AST_CAUSE_SWITCH_CONGESTION: /* 42 */ 06583 return "503 Service Unavailable"; 06584 case AST_CAUSE_NO_USER_RESPONSE: /* 18 */ 06585 return "408 Request Timeout"; 06586 case AST_CAUSE_NO_ANSWER: /* 19 */ 06587 case AST_CAUSE_UNREGISTERED: /* 20 */ 06588 return "480 Temporarily unavailable"; 06589 case AST_CAUSE_CALL_REJECTED: /* 21 */ 06590 return "403 Forbidden"; 06591 case AST_CAUSE_NUMBER_CHANGED: /* 22 */ 06592 return "410 Gone"; 06593 case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */ 06594 return "480 Temporarily unavailable"; 06595 case AST_CAUSE_INVALID_NUMBER_FORMAT: 06596 return "484 Address incomplete"; 06597 case AST_CAUSE_USER_BUSY: 06598 return "486 Busy here"; 06599 case AST_CAUSE_FAILURE: 06600 return "500 Server internal failure"; 06601 case AST_CAUSE_FACILITY_REJECTED: /* 29 */ 06602 return "501 Not Implemented"; 06603 case AST_CAUSE_CHAN_NOT_IMPLEMENTED: 06604 return "503 Service Unavailable"; 06605 /* Used in chan_iax2 */ 06606 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 06607 return "502 Bad Gateway"; 06608 case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */ 06609 return "488 Not Acceptable Here"; 06610 06611 case AST_CAUSE_NOTDEFINED: 06612 default: 06613 ast_debug(1, "AST hangup cause %d (no match found in SIP)\n", cause); 06614 return NULL; 06615 } 06616 06617 /* Never reached */ 06618 return 0; 06619 }
| int hangup_sip2cause | ( | int | cause | ) |
Convert SIP hangup causes to Asterisk hangup causes.
Definition at line 6452 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().
06453 { 06454 /* Possible values taken from causes.h */ 06455 06456 switch(cause) { 06457 case 401: /* Unauthorized */ 06458 return AST_CAUSE_CALL_REJECTED; 06459 case 403: /* Not found */ 06460 return AST_CAUSE_CALL_REJECTED; 06461 case 404: /* Not found */ 06462 return AST_CAUSE_UNALLOCATED; 06463 case 405: /* Method not allowed */ 06464 return AST_CAUSE_INTERWORKING; 06465 case 407: /* Proxy authentication required */ 06466 return AST_CAUSE_CALL_REJECTED; 06467 case 408: /* No reaction */ 06468 return AST_CAUSE_NO_USER_RESPONSE; 06469 case 409: /* Conflict */ 06470 return AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 06471 case 410: /* Gone */ 06472 return AST_CAUSE_NUMBER_CHANGED; 06473 case 411: /* Length required */ 06474 return AST_CAUSE_INTERWORKING; 06475 case 413: /* Request entity too large */ 06476 return AST_CAUSE_INTERWORKING; 06477 case 414: /* Request URI too large */ 06478 return AST_CAUSE_INTERWORKING; 06479 case 415: /* Unsupported media type */ 06480 return AST_CAUSE_INTERWORKING; 06481 case 420: /* Bad extension */ 06482 return AST_CAUSE_NO_ROUTE_DESTINATION; 06483 case 480: /* No answer */ 06484 return AST_CAUSE_NO_ANSWER; 06485 case 481: /* No answer */ 06486 return AST_CAUSE_INTERWORKING; 06487 case 482: /* Loop detected */ 06488 return AST_CAUSE_INTERWORKING; 06489 case 483: /* Too many hops */ 06490 return AST_CAUSE_NO_ANSWER; 06491 case 484: /* Address incomplete */ 06492 return AST_CAUSE_INVALID_NUMBER_FORMAT; 06493 case 485: /* Ambiguous */ 06494 return AST_CAUSE_UNALLOCATED; 06495 case 486: /* Busy everywhere */ 06496 return AST_CAUSE_BUSY; 06497 case 487: /* Request terminated */ 06498 return AST_CAUSE_INTERWORKING; 06499 case 488: /* No codecs approved */ 06500 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 06501 case 491: /* Request pending */ 06502 return AST_CAUSE_INTERWORKING; 06503 case 493: /* Undecipherable */ 06504 return AST_CAUSE_INTERWORKING; 06505 case 500: /* Server internal failure */ 06506 return AST_CAUSE_FAILURE; 06507 case 501: /* Call rejected */ 06508 return AST_CAUSE_FACILITY_REJECTED; 06509 case 502: 06510 return AST_CAUSE_DESTINATION_OUT_OF_ORDER; 06511 case 503: /* Service unavailable */ 06512 return AST_CAUSE_CONGESTION; 06513 case 504: /* Gateway timeout */ 06514 return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE; 06515 case 505: /* SIP version not supported */ 06516 return AST_CAUSE_INTERWORKING; 06517 case 600: /* Busy everywhere */ 06518 return AST_CAUSE_USER_BUSY; 06519 case 603: /* Decline */ 06520 return AST_CAUSE_CALL_REJECTED; 06521 case 604: /* Does not exist anywhere */ 06522 return AST_CAUSE_UNALLOCATED; 06523 case 606: /* Not acceptable */ 06524 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 06525 default: 06526 if (cause < 500 && cause >= 400) { 06527 /* 4xx class error that is unknown - someting wrong with our request */ 06528 return AST_CAUSE_INTERWORKING; 06529 } else if (cause < 600 && cause >= 500) { 06530 /* 5xx class error - problem in the remote end */ 06531 return AST_CAUSE_CONGESTION; 06532 } else if (cause < 700 && cause >= 600) { 06533 /* 6xx - global errors in the 4xx class */ 06534 return AST_CAUSE_INTERWORKING; 06535 } 06536 return AST_CAUSE_NORMAL; 06537 } 06538 /* Never reached */ 06539 return 0; 06540 }
| static int init_req | ( | struct sip_request * | req, | |
| int | sipmethod, | |||
| const char * | recip | |||
| ) | [static] |
Initialize SIP request.
Definition at line 10634 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().
10635 { 10636 /* Initialize a request */ 10637 memset(req, 0, sizeof(*req)); 10638 if (!(req->data = ast_str_create(SIP_MIN_PACKET))) 10639 goto e_return; 10640 if (!(req->content = ast_str_create(SIP_MIN_PACKET))) 10641 goto e_free_data; 10642 req->method = sipmethod; 10643 req->header[0] = 0; 10644 ast_str_set(&req->data, 0, "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip); 10645 req->headers++; 10646 return 0; 10647 10648 e_free_data: 10649 ast_free(req->data); 10650 req->data = NULL; 10651 e_return: 10652 return -1; 10653 }
| static int init_resp | ( | struct sip_request * | resp, | |
| const char * | msg | |||
| ) | [static] |
Initialize SIP response, based on SIP request.
Definition at line 10612 of file chan_sip.c.
References ast_free, ast_str_create(), and ast_str_set().
Referenced by respprep().
10613 { 10614 /* Initialize a response */ 10615 memset(resp, 0, sizeof(*resp)); 10616 resp->method = SIP_RESPONSE; 10617 if (!(resp->data = ast_str_create(SIP_MIN_PACKET))) 10618 goto e_return; 10619 if (!(resp->content = ast_str_create(SIP_MIN_PACKET))) 10620 goto e_free_data; 10621 resp->header[0] = 0; 10622 ast_str_set(&resp->data, 0, "SIP/2.0 %s\r\n", msg); 10623 resp->headers++; 10624 return 0; 10625 10626 e_free_data: 10627 ast_free(resp->data); 10628 resp->data = NULL; 10629 e_return: 10630 return -1; 10631 }
| static int initialize_escs | ( | void | ) | [static] |
Definition at line 1067 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().
01068 { 01069 int i, res = 0; 01070 for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) { 01071 if (!((event_state_compositors[i].compositor) = 01072 ao2_container_alloc(ESC_MAX_BUCKETS, esc_hash_fn, esc_cmp_fn))) { 01073 res = -1; 01074 } 01075 } 01076 return res; 01077 }
| 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 3355 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().
03356 { 03357 if (p->initreq.headers) { 03358 ast_debug(1, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid); 03359 } else { 03360 ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid); 03361 } 03362 /* Use this as the basis */ 03363 copy_request(&p->initreq, req); 03364 parse_request(&p->initreq); 03365 if (req->debug) { 03366 ast_verbose("Initreq: %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 03367 } 03368 }
| static int initialize_udptl | ( | struct sip_pvt * | p | ) | [static] |
Definition at line 7202 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().
07203 { 07204 int natflags = ast_test_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP); 07205 07206 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) { 07207 return 1; 07208 } 07209 07210 /* If we've already initialized T38, don't take any further action */ 07211 if (p->udptl) { 07212 return 0; 07213 } 07214 07215 /* T38 can be supported by this dialog, create it and set the derived properties */ 07216 if ((p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, &bindaddr))) { 07217 if (p->owner) { 07218 ast_channel_set_fd(p->owner, 5, ast_udptl_fd(p->udptl)); 07219 } 07220 07221 ast_udptl_setqos(p->udptl, global_tos_audio, global_cos_audio); 07222 p->t38_maxdatagram = p->relatedpeer ? p->relatedpeer->t38_maxdatagram : global_t38_maxdatagram; 07223 set_t38_capabilities(p); 07224 07225 ast_debug(1, "Setting NAT on UDPTL to %s\n", natflags ? "On" : "Off"); 07226 ast_udptl_setnat(p->udptl, natflags); 07227 } else { 07228 ast_log(AST_LOG_WARNING, "UDPTL creation failed - disabling T38 for this dialog\n"); 07229 ast_clear_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT); 07230 return 1; 07231 } 07232 07233 return 0; 07234 }
| 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 12435 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, S_OR, sip_cfg, sip_methods, sip_standard_port(), and cfsip_methods::text.
Referenced by transmit_invite(), and transmit_notify_with_mwi().
12436 { 12437 struct ast_str *invite = ast_str_alloca(256); 12438 char from[256]; 12439 char to[256]; 12440 char tmp_n[SIPBUFSIZE/2]; /* build a local copy of 'n' if needed */ 12441 char tmp_l[SIPBUFSIZE/2]; /* build a local copy of 'l' if needed */ 12442 const char *l = NULL; /* XXX what is this, exactly ? */ 12443 const char *n = NULL; /* XXX what is this, exactly ? */ 12444 const char *d = NULL; /* domain in from header */ 12445 const char *urioptions = ""; 12446 int ourport; 12447 12448 if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) { 12449 const char *s = p->username; /* being a string field, cannot be NULL */ 12450 12451 /* Test p->username against allowed characters in AST_DIGIT_ANY 12452 If it matches the allowed characters list, then sipuser = ";user=phone" 12453 If not, then sipuser = "" 12454 */ 12455 /* + is allowed in first position in a tel: uri */ 12456 if (*s == '+') 12457 s++; 12458 for (; *s; s++) { 12459 if (!strchr(AST_DIGIT_ANYNUM, *s) ) 12460 break; 12461 } 12462 /* If we have only digits, add ;user=phone to the uri */ 12463 if (!*s) 12464 urioptions = ";user=phone"; 12465 } 12466 12467 12468 snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text); 12469 12470 d = S_OR(p->fromdomain, ast_sockaddr_stringify_host_remote(&p->ourip)); 12471 if (p->owner) { 12472 if ((ast_party_id_presentation(&p->owner->connected.id) & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED) { 12473 l = p->owner->connected.id.number.valid ? p->owner->connected.id.number.str : NULL; 12474 n = p->owner->connected.id.name.valid ? p->owner->connected.id.name.str : NULL; 12475 } else { 12476 /* Even if we are using RPID, we shouldn't leak information in the From if the user wants 12477 * their callerid restricted */ 12478 l = "anonymous"; 12479 n = CALLERID_UNKNOWN; 12480 d = FROMDOMAIN_INVALID; 12481 } 12482 } 12483 12484 /* Hey, it's a NOTIFY! See if they've configured a mwi_from. 12485 * XXX Right now, this logic works because the only place that mwi_from 12486 * is set on the sip_pvt is in sip_send_mwi_to_peer. If things changed, then 12487 * we might end up putting the mwi_from setting into other types of NOTIFY 12488 * messages as well. 12489 */ 12490 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->mwi_from)) { 12491 l = p->mwi_from; 12492 } 12493 12494 if (ast_strlen_zero(l)) 12495 l = default_callerid; 12496 if (ast_strlen_zero(n)) 12497 n = l; 12498 /* Allow user to be overridden */ 12499 if (!ast_strlen_zero(p->fromuser)) 12500 l = p->fromuser; 12501 else /* Save for any further attempts */ 12502 ast_string_field_set(p, fromuser, l); 12503 12504 /* Allow user to be overridden */ 12505 if (!ast_strlen_zero(p->fromname)) 12506 n = p->fromname; 12507 else /* Save for any further attempts */ 12508 ast_string_field_set(p, fromname, n); 12509 12510 ast_copy_string(tmp_l, l, sizeof(tmp_l)); 12511 if (sip_cfg.pedanticsipchecking) { 12512 ast_escape_quoted(n, tmp_n, sizeof(tmp_n)); 12513 n = tmp_n; 12514 ast_uri_encode(l, tmp_l, sizeof(tmp_l), 0); 12515 } 12516 12517 ourport = (p->fromdomainport) ? p->fromdomainport : ast_sockaddr_port(&p->ourip); 12518 if (!sip_standard_port(p->socket.type, ourport)) { 12519 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%s", n, tmp_l, d, ourport, p->tag); 12520 } else { 12521 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, tmp_l, d, p->tag); 12522 } 12523 12524 if (!ast_strlen_zero(explicit_uri)) { 12525 ast_str_set(&invite, 0, "%s", explicit_uri); 12526 } else { 12527 /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */ 12528 if (!ast_strlen_zero(p->fullcontact)) { 12529 /* If we have full contact, trust it */ 12530 ast_str_append(&invite, 0, "%s", p->fullcontact); 12531 } else { 12532 /* Otherwise, use the username while waiting for registration */ 12533 ast_str_append(&invite, 0, "sip:"); 12534 if (!ast_strlen_zero(p->username)) { 12535 n = p->username; 12536 if (sip_cfg.pedanticsipchecking) { 12537 ast_uri_encode(n, tmp_n, sizeof(tmp_n), 0); 12538 n = tmp_n; 12539 } 12540 ast_str_append(&invite, 0, "%s@", n); 12541 } 12542 ast_str_append(&invite, 0, "%s", p->tohost); 12543 if (p->portinuri) { 12544 ast_str_append(&invite, 0, ":%d", ast_sockaddr_port(&p->sa)); 12545 } 12546 ast_str_append(&invite, 0, "%s", urioptions); 12547 } 12548 } 12549 12550 /* If custom URI options have been provided, append them */ 12551 if (p->options && !ast_strlen_zero(p->options->uri_options)) 12552 ast_str_append(&invite, 0, ";%s", p->options->uri_options); 12553 12554 /* This is the request URI, which is the next hop of the call 12555 which may or may not be the destination of the call 12556 */ 12557 ast_string_field_set(p, uri, ast_str_buffer(invite)); 12558 12559 if (!ast_strlen_zero(p->todnid)) { 12560 /*! \todo Need to add back the VXML URL here at some point, possibly use build_string for all this junk */ 12561 if (!strchr(p->todnid, '@')) { 12562 /* We have no domain in the dnid */ 12563 snprintf(to, sizeof(to), "<sip:%s@%s>%s%s", p->todnid, p->tohost, ast_strlen_zero(p->theirtag) ? "" : ";tag=", p->theirtag); 12564 } else { 12565 snprintf(to, sizeof(to), "<sip:%s>%s%s", p->todnid, ast_strlen_zero(p->theirtag) ? "" : ";tag=", p->theirtag); 12566 } 12567 } else { 12568 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 12569 /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ 12570 snprintf(to, sizeof(to), "<%s%s>;tag=%s", (strncasecmp(p->uri, "sip:", 4) ? "sip:" : ""), p->uri, p->theirtag); 12571 } else if (p->options && p->options->vxml_url) { 12572 /* If there is a VXML URL append it to the SIP URL */ 12573 snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); 12574 } else { 12575 snprintf(to, sizeof(to), "<%s>", p->uri); 12576 } 12577 } 12578 12579 init_req(req, sipmethod, p->uri); 12580 /* now tmp_n is available so reuse it to build the CSeq */ 12581 snprintf(tmp_n, sizeof(tmp_n), "%u %s", ++p->ocseq, sip_methods[sipmethod].text); 12582 12583 add_header(req, "Via", p->via); 12584 add_header_max_forwards(p, req); 12585 /* This will be a no-op most of the time. However, under certain circumstances, 12586 * NOTIFY messages will use this function for preparing the request and should 12587 * have Route headers present. 12588 */ 12589 add_route(req, p->route); 12590 12591 add_header(req, "From", from); 12592 add_header(req, "To", to); 12593 ast_string_field_set(p, exten, l); 12594 build_contact(p); 12595 add_header(req, "Contact", p->our_contact); 12596 add_header(req, "Call-ID", p->callid); 12597 add_header(req, "CSeq", tmp_n); 12598 if (!ast_strlen_zero(global_useragent)) { 12599 add_header(req, "User-Agent", global_useragent); 12600 } 12601 }
| static const char * insecure2str | ( | int | mode | ) | [static] |
Convert Insecure setting to printable string.
Definition at line 17599 of file chan_sip.c.
References map_x_s().
Referenced by _sip_show_peer().
17600 { 17601 return map_x_s(insecurestr, mode, "<error>"); 17602 }
| 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 7110 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().
07111 { 07112 int res = 0; 07113 07114 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) || !p->udptl) { 07115 return -1; 07116 } 07117 switch (parameters->request_response) { 07118 case AST_T38_NEGOTIATED: 07119 case AST_T38_REQUEST_NEGOTIATE: /* Request T38 */ 07120 /* Negotiation can not take place without a valid max_ifp value. */ 07121 if (!parameters->max_ifp) { 07122 change_t38_state(p, T38_DISABLED); 07123 if (p->t38.state == T38_PEER_REINVITE) { 07124 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")); 07125 transmit_response_reliable(p, "488 Not acceptable here", &p->initreq); 07126 } 07127 break; 07128 } else if (p->t38.state == T38_PEER_REINVITE) { 07129 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")); 07130 p->t38.our_parms = *parameters; 07131 /* modify our parameters to conform to the peer's parameters, 07132 * based on the rules in the ITU T.38 recommendation 07133 */ 07134 if (!p->t38.their_parms.fill_bit_removal) { 07135 p->t38.our_parms.fill_bit_removal = FALSE; 07136 } 07137 if (!p->t38.their_parms.transcoding_mmr) { 07138 p->t38.our_parms.transcoding_mmr = FALSE; 07139 } 07140 if (!p->t38.their_parms.transcoding_jbig) { 07141 p->t38.our_parms.transcoding_jbig = FALSE; 07142 } 07143 p->t38.our_parms.version = MIN(p->t38.our_parms.version, p->t38.their_parms.version); 07144 p->t38.our_parms.rate_management = p->t38.their_parms.rate_management; 07145 ast_udptl_set_local_max_ifp(p->udptl, p->t38.our_parms.max_ifp); 07146 change_t38_state(p, T38_ENABLED); 07147 transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 07148 } else if (p->t38.state != T38_ENABLED) { 07149 p->t38.our_parms = *parameters; 07150 ast_udptl_set_local_max_ifp(p->udptl, p->t38.our_parms.max_ifp); 07151 change_t38_state(p, T38_LOCAL_REINVITE); 07152 if (!p->pendinginvite) { 07153 transmit_reinvite_with_sdp(p, TRUE, FALSE); 07154 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 07155 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 07156 } 07157 } 07158 break; 07159 case AST_T38_TERMINATED: 07160 case AST_T38_REFUSED: 07161 case AST_T38_REQUEST_TERMINATE: /* Shutdown T38 */ 07162 if (p->t38.state == T38_PEER_REINVITE) { 07163 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")); 07164 change_t38_state(p, T38_DISABLED); 07165 transmit_response_reliable(p, "488 Not acceptable here", &p->initreq); 07166 } else if (p->t38.state == T38_ENABLED) 07167 transmit_reinvite_with_sdp(p, FALSE, FALSE); 07168 break; 07169 case AST_T38_REQUEST_PARMS: { /* Application wants remote's parameters re-sent */ 07170 struct ast_control_t38_parameters parameters = p->t38.their_parms; 07171 07172 if (p->t38.state == T38_PEER_REINVITE) { 07173 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")); 07174 parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl); 07175 parameters.request_response = AST_T38_REQUEST_NEGOTIATE; 07176 ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, ¶meters, sizeof(parameters)); 07177 /* we need to return a positive value here, so that applications that 07178 * send this request can determine conclusively whether it was accepted or not... 07179 * older versions of chan_sip would just silently accept it and return zero. 07180 */ 07181 res = AST_T38_REQUEST_PARMS; 07182 } 07183 break; 07184 } 07185 default: 07186 res = -1; 07187 break; 07188 } 07189 07190 return res; 07191 }
| 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 8777 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 14723 of file chan_sip.c.
References ast_verbose.
Referenced by build_route().
14724 { 14725 if (!route) { 14726 ast_verbose("list_route: no route\n"); 14727 } else { 14728 for (;route; route = route->next) 14729 ast_verbose("list_route: hop: <%s>\n", route->hop); 14730 } 14731 }
| static int load_module | ( | void | ) | [static] |
PBX load module - initialization.
Definition at line 31676 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().
31677 { 31678 ast_verbose("SIP channel loading...\n"); 31679 31680 /* the fact that ao2_containers can't resize automatically is a major worry! */ 31681 /* if the number of objects gets above MAX_XXX_BUCKETS, things will slow down */ 31682 peers = ao2_t_container_alloc(HASH_PEER_SIZE, peer_hash_cb, peer_cmp_cb, "allocate peers"); 31683 peers_by_ip = ao2_t_container_alloc(HASH_PEER_SIZE, peer_iphash_cb, peer_ipcmp_cb, "allocate peers_by_ip"); 31684 dialogs = ao2_t_container_alloc(HASH_DIALOG_SIZE, dialog_hash_cb, dialog_cmp_cb, "allocate dialogs"); 31685 dialogs_to_destroy = ao2_t_container_alloc(1, NULL, NULL, "allocate dialogs_to_destroy"); 31686 threadt = ao2_t_container_alloc(HASH_DIALOG_SIZE, threadt_hash_cb, threadt_cmp_cb, "allocate threadt table"); 31687 if (!peers || !peers_by_ip || !dialogs || !dialogs_to_destroy || !threadt) { 31688 ast_log(LOG_ERROR, "Unable to create primary SIP container(s)\n"); 31689 return AST_MODULE_LOAD_FAILURE; 31690 } 31691 31692 ASTOBJ_CONTAINER_INIT(®l); /* Registry object list -- not searched for anything */ 31693 ASTOBJ_CONTAINER_INIT(&submwil); /* MWI subscription object list */ 31694 31695 if (!(sched = sched_context_create())) { 31696 ast_log(LOG_ERROR, "Unable to create scheduler context\n"); 31697 return AST_MODULE_LOAD_FAILURE; 31698 } 31699 31700 if (!(io = io_context_create())) { 31701 ast_log(LOG_ERROR, "Unable to create I/O context\n"); 31702 sched_context_destroy(sched); 31703 return AST_MODULE_LOAD_FAILURE; 31704 } 31705 31706 sip_reloadreason = CHANNEL_MODULE_LOAD; 31707 31708 can_parse_xml = sip_is_xml_parsable(); 31709 if (reload_config(sip_reloadreason)) { /* Load the configuration from sip.conf */ 31710 return AST_MODULE_LOAD_DECLINE; 31711 } 31712 31713 /* Initialize bogus peer. Can be done first after reload_config() */ 31714 if (!(bogus_peer = temp_peer("(bogus_peer)"))) { 31715 ast_log(LOG_ERROR, "Unable to create bogus_peer for authentication\n"); 31716 io_context_destroy(io); 31717 sched_context_destroy(sched); 31718 return AST_MODULE_LOAD_FAILURE; 31719 } 31720 /* Make sure the auth will always fail. */ 31721 ast_string_field_set(bogus_peer, md5secret, BOGUS_PEER_MD5SECRET); 31722 ast_clear_flag(&bogus_peer->flags[0], SIP_INSECURE); 31723 31724 /* Prepare the version that does not require DTMF BEGIN frames. 31725 * We need to use tricks such as memcpy and casts because the variable 31726 * has const fields. 31727 */ 31728 memcpy(&sip_tech_info, &sip_tech, sizeof(sip_tech)); 31729 memset((void *) &sip_tech_info.send_digit_begin, 0, sizeof(sip_tech_info.send_digit_begin)); 31730 31731 /* Make sure we can register our sip channel type */ 31732 if (ast_channel_register(&sip_tech)) { 31733 ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n"); 31734 ao2_t_ref(bogus_peer, -1, "unref the bogus_peer"); 31735 io_context_destroy(io); 31736 sched_context_destroy(sched); 31737 return AST_MODULE_LOAD_FAILURE; 31738 } 31739 31740 #ifdef TEST_FRAMEWORK 31741 AST_TEST_REGISTER(test_sip_peers_get); 31742 AST_TEST_REGISTER(test_sip_mwi_subscribe_parse); 31743 AST_TEST_REGISTER(test_tcp_message_fragmentation); 31744 AST_TEST_REGISTER(get_in_brackets_const_test); 31745 #endif 31746 31747 /* Register AstData providers */ 31748 ast_data_register_multiple(sip_data_providers, ARRAY_LEN(sip_data_providers)); 31749 31750 /* Register all CLI functions for SIP */ 31751 ast_cli_register_multiple(cli_sip, ARRAY_LEN(cli_sip)); 31752 31753 /* Tell the UDPTL subdriver that we're here */ 31754 ast_udptl_proto_register(&sip_udptl); 31755 31756 /* Tell the RTP engine about our RTP glue */ 31757 ast_rtp_glue_register(&sip_rtp_glue); 31758 31759 /* Register dialplan applications */ 31760 ast_register_application_xml(app_dtmfmode, sip_dtmfmode); 31761 ast_register_application_xml(app_sipaddheader, sip_addheader); 31762 ast_register_application_xml(app_sipremoveheader, sip_removeheader); 31763 31764 /* Register dialplan functions */ 31765 ast_custom_function_register(&sip_header_function); 31766 ast_custom_function_register(&sippeer_function); 31767 ast_custom_function_register(&sipchaninfo_function); 31768 ast_custom_function_register(&checksipdomain_function); 31769 31770 /* Register manager commands */ 31771 ast_manager_register_xml("SIPpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_sip_show_peers); 31772 ast_manager_register_xml("SIPshowpeer", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_sip_show_peer); 31773 ast_manager_register_xml("SIPqualifypeer", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_sip_qualify_peer); 31774 ast_manager_register_xml("SIPshowregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_show_registry); 31775 ast_manager_register_xml("SIPnotify", EVENT_FLAG_SYSTEM, manager_sipnotify); 31776 sip_poke_all_peers(); 31777 sip_send_all_registers(); 31778 sip_send_all_mwi_subscriptions(); 31779 initialize_escs(); 31780 31781 if (sip_epa_register(&cc_epa_static_data)) { 31782 return AST_MODULE_LOAD_DECLINE; 31783 } 31784 31785 if (sip_reqresp_parser_init() == -1) { 31786 ast_log(LOG_ERROR, "Unable to initialize the SIP request and response parser\n"); 31787 return AST_MODULE_LOAD_DECLINE; 31788 } 31789 31790 if (can_parse_xml) { 31791 /* SIP CC agents require the ability to parse XML PIDF bodies 31792 * in incoming PUBLISH requests 31793 */ 31794 if (ast_cc_agent_register(&sip_cc_agent_callbacks)) { 31795 return AST_MODULE_LOAD_DECLINE; 31796 } 31797 } 31798 if (ast_cc_monitor_register(&sip_cc_monitor_callbacks)) { 31799 return AST_MODULE_LOAD_DECLINE; 31800 } 31801 if (!(sip_monitor_instances = ao2_container_alloc(37, sip_monitor_instance_hash_fn, sip_monitor_instance_cmp_fn))) { 31802 return AST_MODULE_LOAD_DECLINE; 31803 } 31804 31805 /* And start the monitor for the first time */ 31806 restart_monitor(); 31807 31808 ast_realtime_require_field(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", 31809 "name", RQ_CHAR, 10, 31810 "ipaddr", RQ_CHAR, INET6_ADDRSTRLEN - 1, 31811 "port", RQ_UINTEGER2, 5, 31812 "regseconds", RQ_INTEGER4, 11, 31813 "defaultuser", RQ_CHAR, 10, 31814 "fullcontact", RQ_CHAR, 35, 31815 "regserver", RQ_CHAR, 20, 31816 "useragent", RQ_CHAR, 20, 31817 "lastms", RQ_INTEGER4, 11, 31818 SENTINEL); 31819 31820 31821 sip_register_tests(); 31822 network_change_event_subscribe(); 31823 31824 return AST_MODULE_LOAD_SUCCESS; 31825 }
| 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 23800 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().
23801 { 23802 struct sip_dual target; /* Chan 1: Call from tranferer to Asterisk */ 23803 /* Chan 2: Call from Asterisk to target */ 23804 int res = 0; 23805 struct sip_pvt *targetcall_pvt; 23806 struct ast_party_connected_line connected_to_transferee; 23807 struct ast_party_connected_line connected_to_target; 23808 char transferer_linkedid[32]; 23809 struct ast_channel *chans[2]; 23810 23811 /* Check if the call ID of the replaces header does exist locally */ 23812 if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 23813 transferer->refer->replaces_callid_fromtag))) { 23814 if (transferer->refer->localtransfer) { 23815 /* We did not find the refered call. Sorry, can't accept then */ 23816 /* Let's fake a response from someone else in order 23817 to follow the standard */ 23818 transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE); 23819 append_history(transferer, "Xfer", "Refer failed"); 23820 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 23821 transferer->refer->status = REFER_FAILED; 23822 return -1; 23823 } 23824 /* Fall through for remote transfers that we did not find locally */ 23825 ast_debug(3, "SIP attended transfer: Not our call - generating INVITE with replaces\n"); 23826 return 0; 23827 } 23828 23829 /* Ok, we can accept this transfer */ 23830 append_history(transferer, "Xfer", "Refer accepted"); 23831 if (!targetcall_pvt->owner) { /* No active channel */ 23832 ast_debug(4, "SIP attended transfer: Error: No owner of target call\n"); 23833 /* Cancel transfer */ 23834 transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE); 23835 append_history(transferer, "Xfer", "Refer failed"); 23836 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 23837 transferer->refer->status = REFER_FAILED; 23838 sip_pvt_unlock(targetcall_pvt); 23839 if (targetcall_pvt) 23840 ao2_t_ref(targetcall_pvt, -1, "Drop targetcall_pvt pointer"); 23841 return -1; 23842 } 23843 23844 /* We have a channel, find the bridge */ 23845 target.chan1 = ast_channel_ref(targetcall_pvt->owner); /* Transferer to Asterisk */ 23846 target.chan2 = ast_bridged_channel(targetcall_pvt->owner); /* Asterisk to target */ 23847 if (target.chan2) { 23848 ast_channel_ref(target.chan2); 23849 } 23850 23851 if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) { 23852 /* Wrong state of new channel */ 23853 if (target.chan2) 23854 ast_debug(4, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state)); 23855 else if (target.chan1->_state != AST_STATE_RING) 23856 ast_debug(4, "SIP attended transfer: Error: No target channel\n"); 23857 else 23858 ast_debug(4, "SIP attended transfer: Attempting transfer in ringing state\n"); 23859 } 23860 23861 /* Transfer */ 23862 if (sipdebug) { 23863 if (current->chan2) /* We have two bridges */ 23864 ast_debug(4, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name); 23865 else /* One bridge, propably transfer of IVR/voicemail etc */ 23866 ast_debug(4, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name); 23867 } 23868 23869 ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 23870 23871 ast_copy_string(transferer_linkedid, transferer->owner->linkedid, sizeof(transferer_linkedid)); 23872 23873 /* Perform the transfer */ 23874 chans[0] = transferer->owner; 23875 chans[1] = target.chan1; 23876 ast_manager_event_multichan(EVENT_FLAG_CALL, "Transfer", 2, chans, 23877 "TransferMethod: SIP\r\n" 23878 "TransferType: Attended\r\n" 23879 "Channel: %s\r\n" 23880 "Uniqueid: %s\r\n" 23881 "SIP-Callid: %s\r\n" 23882 "TargetChannel: %s\r\n" 23883 "TargetUniqueid: %s\r\n", 23884 transferer->owner->name, 23885 transferer->owner->uniqueid, 23886 transferer->callid, 23887 target.chan1->name, 23888 target.chan1->uniqueid); 23889 ast_party_connected_line_init(&connected_to_transferee); 23890 ast_party_connected_line_init(&connected_to_target); 23891 /* No need to lock current->chan1 here since it was locked in sipsock_read */ 23892 ast_party_connected_line_copy(&connected_to_transferee, ¤t->chan1->connected); 23893 /* No need to lock target.chan1 here since it was locked in get_sip_pvt_byid_locked */ 23894 ast_party_connected_line_copy(&connected_to_target, &target.chan1->connected); 23895 connected_to_target.source = connected_to_transferee.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER; 23896 res = attempt_transfer(current, &target); 23897 if (res) { 23898 /* Failed transfer */ 23899 transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE); 23900 append_history(transferer, "Xfer", "Refer failed"); 23901 ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); 23902 /* if transfer failed, go ahead and unlock targetcall_pvt and it's owner channel */ 23903 sip_pvt_unlock(targetcall_pvt); 23904 ast_channel_unlock(target.chan1); 23905 } else { 23906 /* Transfer succeeded! */ 23907 const char *xfersound = pbx_builtin_getvar_helper(target.chan1, "ATTENDED_TRANSFER_COMPLETE_SOUND"); 23908 23909 /* target.chan1 was locked in get_sip_pvt_byid_locked, do not unlock target.chan1 before this */ 23910 ast_cel_report_event(target.chan1, AST_CEL_ATTENDEDTRANSFER, NULL, transferer_linkedid, target.chan2); 23911 23912 /* Tell transferer that we're done. */ 23913 transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE); 23914 append_history(transferer, "Xfer", "Refer succeeded"); 23915 transferer->refer->status = REFER_200OK; 23916 if (target.chan2 && !ast_strlen_zero(xfersound) && ast_streamfile(target.chan2, xfersound, target.chan2->language) >= 0) { 23917 ast_waitstream(target.chan2, ""); 23918 } 23919 23920 /* By forcing the masquerade, we know that target.chan1 and target.chan2 are bridged. We then 23921 * can queue connected line updates where they need to go. 23922 * 23923 * before a masquerade, all channel and pvt locks must be unlocked. Any recursive 23924 * channel locks held before this function invalidates channel container locking order. 23925 * Since we are unlocking both the pvt (transferer) and its owner channel (current.chan1) 23926 * it is possible for current.chan1 to be destroyed in the pbx thread. To prevent this 23927 * we must give c a reference before any unlocking takes place. 23928 */ 23929 23930 ast_channel_ref(current->chan1); 23931 ast_channel_unlock(current->chan1); /* current.chan1 is p->owner before the masq, it was locked by socket_read()*/ 23932 ast_channel_unlock(target.chan1); 23933 *nounlock = 1; /* we just unlocked the dialog's channel and have no plans of locking it again. */ 23934 sip_pvt_unlock(targetcall_pvt); 23935 sip_pvt_unlock(transferer); 23936 23937 ast_do_masquerade(target.chan1); 23938 23939 ast_indicate(target.chan1, AST_CONTROL_UNHOLD); 23940 if (target.chan2) { 23941 ast_indicate(target.chan2, AST_CONTROL_UNHOLD); 23942 } 23943 23944 if (current->chan2 && current->chan2->_state == AST_STATE_RING) { 23945 ast_indicate(target.chan1, AST_CONTROL_RINGING); 23946 } 23947 23948 if (target.chan2) { 23949 ast_channel_queue_connected_line_update(target.chan1, &connected_to_transferee, NULL); 23950 ast_channel_queue_connected_line_update(target.chan2, &connected_to_target, NULL); 23951 } else { 23952 /* Since target.chan1 isn't actually connected to another channel, there is no way for us 23953 * to queue a frame so that its connected line status will be updated. 23954 * 23955 * Instead, we use the somewhat hackish approach of using a special control frame type that 23956 * instructs ast_read to perform a specific action. In this case, the frame we queue tells 23957 * ast_read to call the connected line interception macro configured for target.chan1. 23958 */ 23959 struct ast_control_read_action_payload *frame_payload; 23960 int payload_size; 23961 int frame_size; 23962 unsigned char connected_line_data[1024]; 23963 payload_size = ast_connected_line_build_data(connected_line_data, 23964 sizeof(connected_line_data), &connected_to_target, NULL); 23965 frame_size = payload_size + sizeof(*frame_payload); 23966 if (payload_size != -1) { 23967 frame_payload = ast_alloca(frame_size); 23968 frame_payload->payload_size = payload_size; 23969 memcpy(frame_payload->payload, connected_line_data, payload_size); 23970 frame_payload->action = AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO; 23971 ast_queue_control_data(target.chan1, AST_CONTROL_READ_ACTION, frame_payload, frame_size); 23972 } 23973 /* In addition to queueing the read action frame so that target.chan1's connected line info 23974 * will be updated, we also are going to queue a plain old connected line update on target.chan1. This 23975 * way, either Dial or Queue can apply this connected line update to the outgoing ringing channel. 23976 */ 23977 ast_channel_queue_connected_line_update(target.chan1, &connected_to_transferee, NULL); 23978 23979 } 23980 sip_pvt_lock(transferer); /* the transferer pvt is expected to remain locked on return */ 23981 23982 ast_channel_unref(current->chan1); 23983 } 23984 23985 /* at this point if the transfer is successful only the transferer pvt should be locked. */ 23986 ast_party_connected_line_free(&connected_to_target); 23987 ast_party_connected_line_free(&connected_to_transferee); 23988 ast_channel_unref(target.chan1); 23989 if (target.chan2) { 23990 ast_channel_unref(target.chan2); 23991 } 23992 if (targetcall_pvt) 23993 ao2_t_ref(targetcall_pvt, -1, "drop targetcall_pvt"); 23994 return 1; 23995 }
| 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 8865 of file chan_sip.c.
References ast_str_strlen(), and len().
Referenced by handle_request_do(), and read_raw_content_length().
08866 { 08867 char *msgbuf = data->str; 08868 int len = ast_str_strlen(data); 08869 int h = 0, t = 0; 08870 int lws = 0; 08871 08872 for (; h < len;) { 08873 /* Eliminate all CRs */ 08874 if (msgbuf[h] == '\r') { 08875 h++; 08876 continue; 08877 } 08878 /* Check for end-of-line */ 08879 if (msgbuf[h] == '\n') { 08880 /* Check for end-of-message */ 08881 if (h + 1 == len) 08882 break; 08883 /* Check for a continuation line */ 08884 if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 08885 /* Merge continuation line */ 08886 h++; 08887 continue; 08888 } 08889 /* Propagate LF and start new line */ 08890 msgbuf[t++] = msgbuf[h++]; 08891 lws = 0; 08892 continue; 08893 } 08894 if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 08895 if (lws) { 08896 h++; 08897 continue; 08898 } 08899 msgbuf[t++] = msgbuf[h++]; 08900 lws = 1; 08901 continue; 08902 } 08903 msgbuf[t++] = msgbuf[h++]; 08904 if (lws) 08905 lws = 0; 08906 } 08907 msgbuf[t] = '\0'; 08908 data->used = t; 08909 }
| static void make_our_tag | ( | struct sip_pvt * | pvt | ) | [static] |
Make our SIP dialog tag.
Definition at line 8057 of file chan_sip.c.
References ast_random(), and ast_string_field_build.
Referenced by handle_request_invite(), handle_request_subscribe(), sip_alloc(), transmit_register(), and transmit_response_using_temp().
08058 { 08059 ast_string_field_build(pvt, tag, "as%08lx", ast_random()); 08060 }
| static int manager_show_registry | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Show SIP registrations in the manager API.
Definition at line 17212 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().
17213 { 17214 const char *id = astman_get_header(m, "ActionID"); 17215 char idtext[256] = ""; 17216 int total = 0; 17217 17218 if (!ast_strlen_zero(id)) 17219 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 17220 17221 astman_send_listack(s, m, "Registrations will follow", "start"); 17222 17223 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 17224 ASTOBJ_RDLOCK(iterator); 17225 astman_append(s, 17226 "Event: RegistryEntry\r\n" 17227 "%s" 17228 "Host: %s\r\n" 17229 "Port: %d\r\n" 17230 "Username: %s\r\n" 17231 "Domain: %s\r\n" 17232 "DomainPort: %d\r\n" 17233 "Refresh: %d\r\n" 17234 "State: %s\r\n" 17235 "RegistrationTime: %ld\r\n" 17236 "\r\n", 17237 idtext, 17238 iterator->hostname, 17239 iterator->portno ? iterator->portno : STANDARD_SIP_PORT, 17240 iterator->username, 17241 S_OR(iterator->regdomain,iterator->hostname), 17242 iterator->regdomainport ? iterator->regdomainport : STANDARD_SIP_PORT, 17243 iterator->refresh, 17244 regstate2str(iterator->regstate), 17245 (long) iterator->regtime.tv_sec); 17246 ASTOBJ_UNLOCK(iterator); 17247 total++; 17248 } while(0)); 17249 17250 astman_append(s, 17251 "Event: RegistrationsComplete\r\n" 17252 "EventList: Complete\r\n" 17253 "ListItems: %d\r\n" 17254 "%s" 17255 "\r\n", total, idtext); 17256 17257 return 0; 17258 }
| static int manager_sip_qualify_peer | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Qualify SIP peers in the manager API.
Definition at line 17994 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().
17995 { 17996 const char *a[4]; 17997 const char *peer; 17998 17999 peer = astman_get_header(m, "Peer"); 18000 if (ast_strlen_zero(peer)) { 18001 astman_send_error(s, m, "Peer: <name> missing."); 18002 return 0; 18003 } 18004 a[0] = "sip"; 18005 a[1] = "qualify"; 18006 a[2] = "peer"; 18007 a[3] = peer; 18008 18009 _sip_qualify_peer(1, -1, s, m, 4, a); 18010 astman_append(s, "\r\n\r\n" ); 18011 return 0; 18012 }
| static int manager_sip_show_peer | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Show SIP peers in the manager API.
Definition at line 17935 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().
17936 { 17937 const char *a[4]; 17938 const char *peer; 17939 17940 peer = astman_get_header(m, "Peer"); 17941 if (ast_strlen_zero(peer)) { 17942 astman_send_error(s, m, "Peer: <name> missing."); 17943 return 0; 17944 } 17945 a[0] = "sip"; 17946 a[1] = "show"; 17947 a[2] = "peer"; 17948 a[3] = peer; 17949 17950 _sip_show_peer(1, -1, s, m, 4, a); 17951 astman_append(s, "\r\n" ); 17952 return 0; 17953 }
| static int manager_sip_show_peers | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Show SIP peers in the manager API.
Definition at line 17262 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().
17263 { 17264 const char *id = astman_get_header(m, "ActionID"); 17265 const char *a[] = {"sip", "show", "peers"}; 17266 char idtext[256] = ""; 17267 int total = 0; 17268 17269 if (!ast_strlen_zero(id)) 17270 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 17271 17272 astman_send_listack(s, m, "Peer status list will follow", "start"); 17273 /* List the peers in separate manager events */ 17274 _sip_show_peers(-1, &total, s, m, 3, a); 17275 /* Send final confirmation */ 17276 astman_append(s, 17277 "Event: PeerlistComplete\r\n" 17278 "EventList: Complete\r\n" 17279 "ListItems: %d\r\n" 17280 "%s" 17281 "\r\n", total, idtext); 17282 return 0; 17283 }
| static int manager_sipnotify | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 13449 of file chan_sip.c.
References ast_log(), ast_set_flag, ast_str_append(), ast_str_strlen(), ast_strlen_zero(), ast_variable_new(), ast_variables_destroy(), astman_get_header(), astman_get_variables(), astman_send_ack(), astman_send_error(), create_addr(), dialog_unlink_all(), LOG_WARNING, ast_variable::name, ast_variable::next, sip_alloc(), sip_notify_allocate(), sip_scheddestroy(), transmit_invite(), ast_variable::value, and var.
Referenced by load_module().
13450 { 13451 const char *channame = astman_get_header(m, "Channel"); 13452 struct ast_variable *vars = astman_get_variables(m); 13453 struct sip_pvt *p; 13454 struct ast_variable *header, *var; 13455 13456 if (ast_strlen_zero(channame)) { 13457 astman_send_error(s, m, "SIPNotify requires a channel name"); 13458 return 0; 13459 } 13460 13461 if (!strncasecmp(channame, "sip/", 4)) { 13462 channame += 4; 13463 } 13464 13465 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) { 13466 astman_send_error(s, m, "Unable to build sip pvt data for notify (memory/socket error)"); 13467 return 0; 13468 } 13469 13470 if (create_addr(p, channame, NULL, 0)) { 13471 /* Maybe they're not registered, etc. */ 13472 dialog_unlink_all(p); 13473 dialog_unref(p, "unref dialog inside for loop" ); 13474 /* sip_destroy(p); */ 13475 astman_send_error(s, m, "Could not create address"); 13476 return 0; 13477 } 13478 13479 /* Notify is outgoing call */ 13480 ast_set_flag(&p->flags[0], SIP_OUTGOING); 13481 sip_notify_allocate(p); 13482 13483 p->notify->headers = header = ast_variable_new("Subscription-State", "terminated", ""); 13484 13485 for (var = vars; var; var = var->next) { 13486 if (!strcasecmp(var->name, "Content")) { 13487 if (ast_str_strlen(p->notify->content)) 13488 ast_str_append(&p->notify->content, 0, "\r\n"); 13489 ast_str_append(&p->notify->content, 0, "%s", var->value); 13490 } else if (!strcasecmp(var->name, "Content-Length")) { 13491 ast_log(LOG_WARNING, "it is not necessary to specify Content-Length, ignoring\n"); 13492 } else { 13493 header->next = ast_variable_new(var->name, var->value, ""); 13494 header = header->next; 13495 } 13496 } 13497 13498 sip_scheddestroy(p, SIP_TRANS_TIMEOUT); 13499 transmit_invite(p, SIP_NOTIFY, 0, 2, NULL); 13500 dialog_unref(p, "bump down the count of p since we're done with it."); 13501 13502 astman_send_ack(s, m, "Notify Sent"); 13503 ast_variables_destroy(vars); 13504 return 0; 13505 }
| 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 2268 of file chan_sip.c.
Referenced by str2dtmfmode(), str2stmode(), and str2strefresherparam().
02269 { 02270 const struct _map_x_s *cur; 02271 02272 for (cur = table; cur->s; cur++) 02273 if (!strcasecmp(cur->s, s)) 02274 return cur->x; 02275 return errorvalue; 02276 }
| 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 2255 of file chan_sip.c.
Referenced by allowoverlap2str(), dtmfmode2str(), faxec2str(), insecure2str(), referstatus2str(), regstate2str(), stmode2str(), strefresher2str(), and strefresherparam2str().
02256 { 02257 const struct _map_x_s *cur; 02258 02259 for (cur = table; cur->s; cur++) 02260 if (cur->x == x) 02261 return cur->s; 02262 return errorstring; 02263 }
| static void mark_method_allowed | ( | unsigned int * | allowed_methods, | |
| enum sipmethod | method | |||
| ) | [static] |
Definition at line 8766 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 8771 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 8782 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().
08783 { 08784 char *method; 08785 for (method = strsep(&methods_str, ","); !ast_strlen_zero(method); method = strsep(&methods_str, ",")) { 08786 int id = find_sip_method(ast_skip_blanks(method)); 08787 if (id == SIP_UNKNOWN) { 08788 continue; 08789 } 08790 mark_method_allowed(methods, id); 08791 } 08792 }
| static int match_and_cleanup_peer_sched | ( | void * | peerobj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 3160 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().
03161 { 03162 struct sip_peer *peer = peerobj; 03163 peer_unlink_flag_t which = *(peer_unlink_flag_t *)arg; 03164 03165 if (which == SIP_PEERS_ALL || peer->the_mark) { 03166 peer_sched_cleanup(peer); 03167 if (peer->dnsmgr) { 03168 ast_dnsmgr_release(peer->dnsmgr); 03169 peer->dnsmgr = NULL; 03170 unref_peer(peer, "Release peer from dnsmgr"); 03171 } 03172 return CMP_MATCH; 03173 } 03174 return 0; 03175 }
| static enum match_req_res match_req_to_dialog | ( | struct sip_pvt * | sip_pvt_ptr, | |
| struct match_req_args * | arg | |||
| ) | [static] |
Definition at line 8303 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().
08304 { 08305 const char *init_ruri = NULL; 08306 if (sip_pvt_ptr->initreq.headers) { 08307 init_ruri = REQ_OFFSET_TO_STR(&sip_pvt_ptr->initreq, rlPart2); 08308 } 08309 08310 /* 08311 * Match Tags and call-id to Dialog 08312 */ 08313 if (!ast_strlen_zero(arg->callid) && strcmp(sip_pvt_ptr->callid, arg->callid)) { 08314 /* call-id does not match. */ 08315 return SIP_REQ_NOT_MATCH; 08316 } 08317 if (arg->method == SIP_RESPONSE) { 08318 /* Verify totag if we have one stored for this dialog, but never be strict about this for 08319 * a response until the dialog is established */ 08320 if (!ast_strlen_zero(sip_pvt_ptr->theirtag) && ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) { 08321 if (ast_strlen_zero(arg->totag)) { 08322 /* missing totag when they already gave us one earlier */ 08323 return SIP_REQ_NOT_MATCH; 08324 } 08325 if (strcmp(arg->totag, sip_pvt_ptr->theirtag)) { 08326 /* The totag of the response does not match the one we have stored */ 08327 return SIP_REQ_NOT_MATCH; 08328 } 08329 } 08330 /* Verify fromtag of response matches the tag we gave them. */ 08331 if (strcmp(arg->fromtag, sip_pvt_ptr->tag)) { 08332 /* fromtag from response does not match our tag */ 08333 return SIP_REQ_NOT_MATCH; 08334 } 08335 } else { 08336 /* Verify the fromtag of Request matches the tag they provided earlier. 08337 * If this is a Request with authentication credentials, forget their old 08338 * tag as it is not valid after the 401 or 407 response. */ 08339 if (!arg->authentication_present && strcmp(arg->fromtag, sip_pvt_ptr->theirtag)) { 08340 /* their tag does not match the one was have stored for them */ 08341 return SIP_REQ_NOT_MATCH; 08342 } 08343 /* Verify if totag is present in Request, that it matches what we gave them as our tag earlier */ 08344 if (!ast_strlen_zero(arg->totag) && (strcmp(arg->totag, sip_pvt_ptr->tag))) { 08345 /* totag from Request does not match our tag */ 08346 return SIP_REQ_NOT_MATCH; 08347 } 08348 } 08349 08350 /* 08351 * Compare incoming request against initial transaction. 08352 * 08353 * This is a best effort attempt at distinguishing forked requests from 08354 * our initial transaction. If all the elements are NOT in place to evaluate 08355 * this, this block is ignored and the dialog match is made regardless. 08356 * Once the totag is established after the dialog is confirmed, this is not necessary. 08357 * 08358 * CRITERIA required for initial transaction matching. 08359 * 08360 * 1. Is a Request 08361 * 2. Callid and theirtag match (this is done in the dialog matching block) 08362 * 3. totag is NOT present 08363 * 4. CSeq matchs our initial transaction's cseq number 08364 * 5. pvt has init via branch parameter stored 08365 */ 08366 if ((arg->method != SIP_RESPONSE) && /* must be a Request */ 08367 ast_strlen_zero(arg->totag) && /* must not have a totag */ 08368 (sip_pvt_ptr->init_icseq == arg->seqno) && /* the cseq must be the same as this dialogs initial cseq */ 08369 !ast_strlen_zero(sip_pvt_ptr->initviabranch) && /* The dialog must have started with a RFC3261 compliant branch tag */ 08370 init_ruri) { /* the dialog must have an initial request uri associated with it */ 08371 /* This Request matches all the criteria required for Loop/Merge detection. 08372 * Now we must go down the path of comparing VIA's and RURIs. */ 08373 if (ast_strlen_zero(arg->viabranch) || 08374 strcmp(arg->viabranch, sip_pvt_ptr->initviabranch) || 08375 ast_strlen_zero(arg->viasentby) || 08376 strcmp(arg->viasentby, sip_pvt_ptr->initviasentby)) { 08377 /* At this point, this request does not match this Dialog.*/ 08378 08379 /* if methods are different this is just a mismatch */ 08380 if ((sip_pvt_ptr->method != arg->method)) { 08381 return SIP_REQ_NOT_MATCH; 08382 } 08383 08384 /* If RUIs are different, this is a forked request to a separate URI. 08385 * Returning a mismatch allows this Request to be processed separately. */ 08386 if (sip_uri_cmp(init_ruri, arg->ruri)) { 08387 /* not a match, request uris are different */ 08388 return SIP_REQ_NOT_MATCH; 08389 } 08390 08391 /* Loop/Merge Detected 08392 * 08393 * ---Current Matches to Initial Request--- 08394 * request uri 08395 * Call-id 08396 * their-tag 08397 * no totag present 08398 * method 08399 * cseq 08400 * 08401 * --- Does not Match Initial Request --- 08402 * Top Via 08403 * 08404 * Without the same Via, this can not match our initial transaction for this dialog, 08405 * but given that this Request matches everything else associated with that initial 08406 * Request this is most certainly a Forked request in which we have already received 08407 * part of the fork. 08408 */ 08409 return SIP_REQ_LOOP_DETECTED; 08410 } 08411 } /* end of Request Via check */ 08412 08413 /* Match Authentication Request. 08414 * 08415 * A Request with an Authentication header must come back with the 08416 * same Request URI. Otherwise it is not a match. 08417 */ 08418 if ((arg->method != SIP_RESPONSE) && /* Must be a Request type to even begin checking this */ 08419 ast_strlen_zero(arg->totag) && /* no totag is present to match */ 08420 arg->authentication_present && /* Authentication header is present in Request */ 08421 sip_uri_cmp(init_ruri, arg->ruri)) { /* Compare the Request URI of both the last Request and this new one */ 08422 08423 /* Authentication was provided, but the Request URI did not match the last one on this dialog. */ 08424 return SIP_REQ_NOT_MATCH; 08425 } 08426 08427 return SIP_REQ_MATCH; 08428 }
| 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 3495 of file chan_sip.c.
References len(), sip_methods, and text.
Referenced by __sip_autodestruct(), __sip_semi_ack(), and find_sip_method().
03496 { 03497 int len = strlen(sip_methods[id].text); 03498 int l_name = name ? strlen(name) : 0; 03499 /* true if the string is long enough, and ends with whitespace, and matches */ 03500 return (l_name >= len && name && name[len] < 33 && 03501 !strncasecmp(sip_methods[id].text, name, len)); 03502 }
| static void mwi_event_cb | ( | const struct ast_event * | event, | |
| void * | userdata | |||
| ) | [static] |
Receive MWI events that we have subscribed to.
Definition at line 15085 of file chan_sip.c.
References sip_send_mwi_to_peer().
Referenced by add_peer_mwi_subs().
15086 { 15087 struct sip_peer *peer = userdata; 15088 15089 sip_send_mwi_to_peer(peer, 0); 15090 }
| static void network_change_event_cb | ( | const struct ast_event * | event, | |
| void * | userdata | |||
| ) | [static] |
Definition at line 15115 of file chan_sip.c.
References ast_debug, ast_sched_add(), and network_change_event_sched_cb().
Referenced by network_change_event_subscribe().
15116 { 15117 ast_debug(1, "SIP, got a network change event, renewing all SIP registrations.\n"); 15118 if (network_change_event_sched_id == -1) { 15119 network_change_event_sched_id = ast_sched_add(sched, 1000, network_change_event_sched_cb, NULL); 15120 } 15121 }
| static int network_change_event_sched_cb | ( | const void * | data | ) | [static] |
Definition at line 15107 of file chan_sip.c.
References sip_send_all_mwi_subscriptions(), and sip_send_all_registers().
Referenced by network_change_event_cb().
15108 { 15109 network_change_event_sched_id = -1; 15110 sip_send_all_registers(); 15111 sip_send_all_mwi_subscriptions(); 15112 return 0; 15113 }
| static void network_change_event_subscribe | ( | void | ) | [static] |
Definition at line 15092 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().
15093 { 15094 if (!network_change_event_subscription) { 15095 network_change_event_subscription = ast_event_subscribe(AST_EVENT_NETWORK_CHANGE, 15096 network_change_event_cb, "SIP Network Change", NULL, AST_EVENT_IE_END); 15097 } 15098 }
| static void network_change_event_unsubscribe | ( | void | ) | [static] |
Definition at line 15100 of file chan_sip.c.
References ast_event_unsubscribe().
Referenced by reload_config(), and unload_module().
15101 { 15102 if (network_change_event_subscription) { 15103 network_change_event_subscription = ast_event_unsubscribe(network_change_event_subscription); 15104 } 15105 }
| 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 3460 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().
03461 { 03462 if (dialog && dialog->options && dialog->options->outboundproxy) { 03463 if (sipdebug) { 03464 ast_debug(1, "OBPROXY: Applying dialplan set OBproxy to this call\n"); 03465 } 03466 append_history(dialog, "OBproxy", "Using dialplan obproxy %s", dialog->options->outboundproxy->name); 03467 return dialog->options->outboundproxy; 03468 } 03469 if (peer && peer->outboundproxy) { 03470 if (sipdebug) { 03471 ast_debug(1, "OBPROXY: Applying peer OBproxy to this call\n"); 03472 } 03473 append_history(dialog, "OBproxy", "Using peer obproxy %s", peer->outboundproxy->name); 03474 return peer->outboundproxy; 03475 } 03476 if (sip_cfg.outboundproxy.name[0]) { 03477 if (sipdebug) { 03478 ast_debug(1, "OBPROXY: Applying global OBproxy to this call\n"); 03479 } 03480 append_history(dialog, "OBproxy", "Using global obproxy %s", sip_cfg.outboundproxy.name); 03481 return &sip_cfg.outboundproxy; 03482 } 03483 if (sipdebug) { 03484 ast_debug(1, "OBPROXY: Not applying OBproxy to this call\n"); 03485 } 03486 return NULL; 03487 }
| static void on_dns_update_mwi | ( | struct ast_sockaddr * | old, | |
| struct ast_sockaddr * | new, | |||
| void * | data | |||
| ) | [static] |
Definition at line 12924 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().
12925 { 12926 struct sip_subscription_mwi *mwi = data; 12927 const char *old_str; 12928 12929 /* This shouldn't happen, but just in case */ 12930 if (ast_sockaddr_isnull(new)) { 12931 ast_debug(1, "Empty sockaddr change...ignoring!\n"); 12932 return; 12933 } 12934 12935 old_str = ast_strdupa(ast_sockaddr_stringify(old)); 12936 ast_debug(1, "Changing mwi %s from %s to %s\n", mwi->hostname, old_str, ast_sockaddr_stringify(new)); 12937 ast_sockaddr_copy(&mwi->us, new); 12938 }
| static void on_dns_update_peer | ( | struct ast_sockaddr * | old, | |
| struct ast_sockaddr * | new, | |||
| void * | data | |||
| ) | [static] |
Definition at line 12895 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().
12896 { 12897 struct sip_peer *peer = data; 12898 const char *old_str; 12899 12900 /* This shouldn't happen, but just in case */ 12901 if (ast_sockaddr_isnull(new)) { 12902 ast_debug(1, "Empty sockaddr change...ignoring!\n"); 12903 return; 12904 } 12905 12906 if (!ast_sockaddr_isnull(&peer->addr)) { 12907 ao2_unlink(peers_by_ip, peer); 12908 } 12909 12910 if (!ast_sockaddr_port(new)) { 12911 ast_sockaddr_set_port(new, default_sip_port(peer->socket.type)); 12912 } 12913 12914 old_str = ast_strdupa(ast_sockaddr_stringify(old)); 12915 ast_debug(1, "Changing peer %s address from %s to %s\n", peer->name, old_str, ast_sockaddr_stringify(new)); 12916 12917 ao2_lock(peer); 12918 ast_sockaddr_copy(&peer->addr, new); 12919 ao2_unlock(peer); 12920 12921 ao2_link(peers_by_ip, peer); 12922 }
| static void on_dns_update_registry | ( | struct ast_sockaddr * | old, | |
| struct ast_sockaddr * | new, | |||
| void * | data | |||
| ) | [static] |
Definition at line 12874 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().
12875 { 12876 struct sip_registry *reg = data; 12877 const char *old_str; 12878 12879 /* This shouldn't happen, but just in case */ 12880 if (ast_sockaddr_isnull(new)) { 12881 ast_debug(1, "Empty sockaddr change...ignoring!\n"); 12882 return; 12883 } 12884 12885 if (!ast_sockaddr_port(new)) { 12886 ast_sockaddr_set_port(new, reg->portno); 12887 } 12888 12889 old_str = ast_strdupa(ast_sockaddr_stringify(old)); 12890 12891 ast_debug(1, "Changing registry %s from %s to %s\n", S_OR(reg->peername, reg->hostname), old_str, ast_sockaddr_stringify(new)); 12892 ast_sockaddr_copy(®->us, new); 12893 }
| 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 8809 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().
08810 { 08811 char *allow = ast_strdupa(get_header(req, "Allow")); 08812 unsigned int allowed_methods = SIP_UNKNOWN; 08813 08814 if (ast_strlen_zero(allow)) { 08815 /* I have witnessed that REGISTER requests from Polycom phones do not 08816 * place the phone's allowed methods in an Allow header. Instead, they place the 08817 * allowed methods in a methods= parameter in the Contact header. 08818 */ 08819 char *contact = ast_strdupa(get_header(req, "Contact")); 08820 char *methods = strstr(contact, ";methods="); 08821 08822 if (ast_strlen_zero(methods)) { 08823 /* RFC 3261 states: 08824 * 08825 * "The absence of an Allow header field MUST NOT be 08826 * interpreted to mean that the UA sending the message supports no 08827 * methods. Rather, it implies that the UA is not providing any 08828 * information on what methods it supports." 08829 * 08830 * For simplicity, we'll assume that the peer allows all known 08831 * SIP methods if they have no Allow header. We can then clear out the necessary 08832 * bits if the peer lets us know that we have sent an unsupported method. 08833 */ 08834 return UINT_MAX; 08835 } 08836 allow = ast_strip_quoted(methods + 9, "\"", "\""); 08837 } 08838 mark_parsed_methods(&allowed_methods, allow); 08839 return allowed_methods; 08840 }
| static void parse_copy | ( | struct sip_request * | dst, | |
| const struct sip_request * | src | |||
| ) | [static] |
Copy SIP request, parse it.
Definition at line 4416 of file chan_sip.c.
References copy_request(), and parse_request().
Referenced by send_request(), and send_response().
04417 { 04418 copy_request(dst, src); 04419 parse_request(dst); 04420 }
| int parse_minse | ( | const char * | p_hdrval, | |
| int *const | p_interval | |||
| ) | [static] |
Session-Timers: Function for parsing Min-SE header.
Definition at line 26774 of file chan_sip.c.
References ast_debug, ast_log(), ast_skip_blanks(), ast_strlen_zero(), and LOG_WARNING.
Referenced by handle_request_invite(), and proc_422_rsp().
26775 { 26776 if (ast_strlen_zero(p_hdrval)) { 26777 ast_log(LOG_WARNING, "Null Min-SE header\n"); 26778 return -1; 26779 } 26780 26781 *p_interval = 0; 26782 p_hdrval = ast_skip_blanks(p_hdrval); 26783 if (!sscanf(p_hdrval, "%30d", p_interval)) { 26784 ast_log(LOG_WARNING, "Parsing of Min-SE header failed %s\n", p_hdrval); 26785 return -1; 26786 } 26787 26788 ast_debug(2, "Received Min-SE: %d\n", *p_interval); 26789 return 0; 26790 }
| 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 20327 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().
20328 { 20329 char contact[SIPBUFSIZE]; 20330 char *contact_name = NULL; 20331 char *contact_number = NULL; 20332 char *separator, *trans; 20333 char *domain; 20334 enum sip_transport transport = SIP_TRANSPORT_UDP; 20335 20336 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 20337 if ((separator = strchr(contact, ','))) 20338 *separator = '\0'; 20339 20340 contact_number = get_in_brackets(contact); 20341 if ((trans = strcasestr(contact_number, ";transport="))) { 20342 trans += 11; 20343 20344 if ((separator = strchr(trans, ';'))) 20345 *separator = '\0'; 20346 20347 if (!strncasecmp(trans, "tcp", 3)) 20348 transport = SIP_TRANSPORT_TCP; 20349 else if (!strncasecmp(trans, "tls", 3)) 20350 transport = SIP_TRANSPORT_TLS; 20351 else { 20352 if (strncasecmp(trans, "udp", 3)) 20353 ast_debug(1, "received contact with an invalid transport, '%s'\n", contact_number); 20354 /* This will assume UDP for all unknown transports */ 20355 transport = SIP_TRANSPORT_UDP; 20356 } 20357 } 20358 contact_number = remove_uri_parameters(contact_number); 20359 20360 if (p->socket.tcptls_session) { 20361 ao2_ref(p->socket.tcptls_session, -1); 20362 p->socket.tcptls_session = NULL; 20363 } 20364 20365 set_socket_transport(&p->socket, transport); 20366 20367 if (set_call_forward && ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) { 20368 char *host = NULL; 20369 if (!strncasecmp(contact_number, "sip:", 4)) 20370 contact_number += 4; 20371 else if (!strncasecmp(contact_number, "sips:", 5)) 20372 contact_number += 5; 20373 separator = strchr(contact_number, '/'); 20374 if (separator) 20375 *separator = '\0'; 20376 if ((host = strchr(contact_number, '@'))) { 20377 *host++ = '\0'; 20378 ast_debug(2, "Found promiscuous redirection to 'SIP/%s::::%s@%s'\n", contact_number, get_transport(transport), host); 20379 if (p->owner) 20380 ast_string_field_build(p->owner, call_forward, "SIP/%s::::%s@%s", contact_number, get_transport(transport), host); 20381 } else { 20382 ast_debug(2, "Found promiscuous redirection to 'SIP/::::%s@%s'\n", get_transport(transport), contact_number); 20383 if (p->owner) 20384 ast_string_field_build(p->owner, call_forward, "SIP/::::%s@%s", get_transport(transport), contact_number); 20385 } 20386 } else { 20387 separator = strchr(contact, '@'); 20388 if (separator) { 20389 *separator++ = '\0'; 20390 domain = separator; 20391 } else { 20392 /* No username part */ 20393 domain = contact; 20394 } 20395 separator = strchr(contact, '/'); /* WHEN do we hae a forward slash in the URI? */ 20396 if (separator) 20397 *separator = '\0'; 20398 20399 if (!strncasecmp(contact_number, "sip:", 4)) 20400 contact_number += 4; 20401 else if (!strncasecmp(contact_number, "sips:", 5)) 20402 contact_number += 5; 20403 separator = strchr(contact_number, ';'); /* And username ; parameters? */ 20404 if (separator) 20405 *separator = '\0'; 20406 ast_uri_decode(contact_number); 20407 if (set_call_forward) { 20408 ast_debug(2, "Received 302 Redirect to extension '%s' (domain %s)\n", contact_number, domain); 20409 if (p->owner) { 20410 pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain); 20411 ast_string_field_set(p->owner, call_forward, contact_number); 20412 } 20413 } 20414 } 20415 20416 /* We've gotten the number for the contact, now get the name */ 20417 20418 if (*contact == '\"') { 20419 contact_name = contact + 1; 20420 if (!(separator = (char *)find_closing_quote(contact_name, NULL))) { 20421 ast_log(LOG_NOTICE, "No closing quote on name in Contact header? %s\n", contact); 20422 } 20423 *separator = '\0'; 20424 } 20425 20426 if (name && !ast_strlen_zero(contact_name)) { 20427 *name = ast_strdup(contact_name); 20428 } 20429 if (number) { 20430 *number = ast_strdup(contact_number); 20431 } 20432 }
| 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 14393 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().
14394 { 14395 char contact[SIPBUFSIZE]; 14396 char *c; 14397 14398 /* Look for brackets */ 14399 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 14400 c = get_in_brackets(contact); 14401 14402 /* Save full contact to call pvt for later bye or re-invite */ 14403 ast_string_field_set(pvt, fullcontact, c); 14404 14405 /* Save URI for later ACKs, BYE or RE-invites */ 14406 ast_string_field_set(pvt, okcontacturi, c); 14407 14408 /* We should return false for URI:s we can't handle, 14409 like tel:, mailto:,ldap: etc */ 14410 return TRUE; 14411 }
| 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 14500 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().
14501 { 14502 char contact[SIPBUFSIZE]; 14503 char data[SIPBUFSIZE]; 14504 const char *expires = get_header(req, "Expires"); 14505 int expire = atoi(expires); 14506 char *curi = NULL, *hostport = NULL, *transport = NULL; 14507 int transport_type; 14508 const char *useragent; 14509 struct ast_sockaddr oldsin, testsa; 14510 char *firstcuri = NULL; 14511 int start = 0; 14512 int wildcard_found = 0; 14513 int single_binding_found = 0; 14514 14515 ast_copy_string(contact, __get_header(req, "Contact", &start), sizeof(contact)); 14516 14517 if (ast_strlen_zero(expires)) { /* No expires header, try look in Contact: */ 14518 char *s = strcasestr(contact, ";expires="); 14519 if (s) { 14520 expires = strsep(&s, ";"); /* trim ; and beyond */ 14521 if (sscanf(expires + 9, "%30d", &expire) != 1) { 14522 expire = default_expiry; 14523 } 14524 } else { 14525 /* Nothing has been specified */ 14526 expire = default_expiry; 14527 } 14528 } 14529 14530 copy_socket_data(&pvt->socket, &req->socket); 14531 14532 do { 14533 /* Look for brackets */ 14534 curi = contact; 14535 if (strchr(contact, '<') == NULL) /* No <, check for ; and strip it */ 14536 strsep(&curi, ";"); /* This is Header options, not URI options */ 14537 curi = get_in_brackets(contact); 14538 if (!firstcuri) { 14539 firstcuri = ast_strdupa(curi); 14540 } 14541 14542 if (!strcasecmp(curi, "*")) { 14543 wildcard_found = 1; 14544 } else { 14545 single_binding_found = 1; 14546 } 14547 14548 if (wildcard_found && (ast_strlen_zero(expires) || expire != 0 || single_binding_found)) { 14549 /* Contact header parameter "*" detected, so punt if: Expires header is missing, 14550 * Expires value is not zero, or another Contact header is present. */ 14551 return PARSE_REGISTER_FAILED; 14552 } 14553 14554 ast_copy_string(contact, __get_header(req, "Contact", &start), sizeof(contact)); 14555 } while (!ast_strlen_zero(contact)); 14556 curi = firstcuri; 14557 14558 /* if they did not specify Contact: or Expires:, they are querying 14559 what we currently have stored as their contact address, so return 14560 it 14561 */ 14562 if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) { 14563 /* If we have an active registration, tell them when the registration is going to expire */ 14564 if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact)) { 14565 pvt->expiry = ast_sched_when(sched, peer->expire); 14566 } 14567 return PARSE_REGISTER_QUERY; 14568 } else if (!strcasecmp(curi, "*") || !expire) { /* Unregister this peer */ 14569 /* This means remove all registrations and return OK */ 14570 AST_SCHED_DEL_UNREF(sched, peer->expire, 14571 unref_peer(peer, "remove register expire ref")); 14572 ast_verb(3, "Unregistered SIP '%s'\n", peer->name); 14573 expire_register(ref_peer(peer,"add ref for explicit expire_register")); 14574 return PARSE_REGISTER_UPDATE; 14575 } 14576 14577 /* Store whatever we got as a contact from the client */ 14578 ast_string_field_set(peer, fullcontact, curi); 14579 14580 /* For the 200 OK, we should use the received contact */ 14581 ast_string_field_build(pvt, our_contact, "<%s>", curi); 14582 14583 /* Make sure it's a SIP URL */ 14584 if (ast_strlen_zero(curi) || parse_uri_legacy_check(curi, "sip:,sips:", &curi, NULL, &hostport, &transport)) { 14585 ast_log(LOG_NOTICE, "Not a valid SIP contact (missing sip:/sips:) trying to use anyway\n"); 14586 } 14587 14588 /* handle the transport type specified in Contact header. */ 14589 if (!(transport_type = get_transport_str2enum(transport))) { 14590 transport_type = pvt->socket.type; 14591 } 14592 14593 /* if the peer's socket type is different than the Registration 14594 * transport type, change it. If it got this far, it is a 14595 * supported type, but check just in case */ 14596 if ((peer->socket.type != transport_type) && (peer->transports & transport_type)) { 14597 set_socket_transport(&peer->socket, transport_type); 14598 } 14599 14600 oldsin = peer->addr; 14601 14602 /* If we were already linked into the peers_by_ip container unlink ourselves so nobody can find us */ 14603 if (!ast_sockaddr_isnull(&peer->addr) && (!peer->is_realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS))) { 14604 ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table"); 14605 } 14606 14607 if (!ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) && !ast_test_flag(&peer->flags[0], SIP_NAT_RPORT_PRESENT)) { 14608 /* use the data provided in the Contact header for call routing */ 14609 ast_debug(1, "Store REGISTER's Contact header for call routing.\n"); 14610 /* XXX This could block for a long time XXX */ 14611 /*! \todo Check NAPTR/SRV if we have not got a port in the URI */ 14612 if (ast_sockaddr_resolve_first_transport(&testsa, hostport, 0, peer->socket.type)) { 14613 ast_log(LOG_WARNING, "Invalid hostport '%s'\n", hostport); 14614 ast_string_field_set(peer, fullcontact, ""); 14615 ast_string_field_set(pvt, our_contact, ""); 14616 return PARSE_REGISTER_FAILED; 14617 } 14618 14619 /* If we have a port number in the given URI, make sure we do remember to not check for NAPTR/SRV records. 14620 The hostport part is actually a host. */ 14621 peer->portinuri = ast_sockaddr_port(&testsa) ? TRUE : FALSE; 14622 14623 if (!ast_sockaddr_port(&testsa)) { 14624 ast_sockaddr_set_port(&testsa, default_sip_port(transport_type)); 14625 } 14626 14627 ast_sockaddr_copy(&peer->addr, &testsa); 14628 } else { 14629 /* Don't trust the contact field. Just use what they came to us 14630 with */ 14631 ast_debug(1, "Store REGISTER's src-IP:port for call routing.\n"); 14632 peer->addr = pvt->recv; 14633 } 14634 14635 /* Check that they're allowed to register at this IP */ 14636 if (ast_apply_ha(sip_cfg.contact_ha, &peer->addr) != AST_SENSE_ALLOW || 14637 ast_apply_ha(peer->contactha, &peer->addr) != AST_SENSE_ALLOW) { 14638 ast_log(LOG_WARNING, "Domain '%s' disallowed by contact ACL (violating IP %s)\n", hostport, 14639 ast_sockaddr_stringify_addr(&testsa)); 14640 ast_string_field_set(peer, fullcontact, ""); 14641 ast_string_field_set(pvt, our_contact, ""); 14642 return PARSE_REGISTER_DENIED; 14643 } 14644 14645 /* if the Contact header information copied into peer->addr matches the 14646 * received address, and the transport types are the same, then copy socket 14647 * data into the peer struct */ 14648 if ((peer->socket.type == pvt->socket.type) && 14649 !ast_sockaddr_cmp(&peer->addr, &pvt->recv)) { 14650 copy_socket_data(&peer->socket, &pvt->socket); 14651 } 14652 14653 /* Now that our address has been updated put ourselves back into the container for lookups */ 14654 if (!peer->is_realtime || ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 14655 ao2_t_link(peers_by_ip, peer, "ao2_link into peers_by_ip table"); 14656 } 14657 14658 /* Save SIP options profile */ 14659 peer->sipoptions = pvt->sipoptions; 14660 14661 if (!ast_strlen_zero(curi) && ast_strlen_zero(peer->username)) { 14662 ast_string_field_set(peer, username, curi); 14663 } 14664 14665 AST_SCHED_DEL_UNREF(sched, peer->expire, 14666 unref_peer(peer, "remove register expire ref")); 14667 14668 if (expire > max_expiry) { 14669 expire = max_expiry; 14670 } 14671 if (expire < min_expiry) { 14672 expire = min_expiry; 14673 } 14674 if (peer->is_realtime && !ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 14675 peer->expire = -1; 14676 } else { 14677 peer->expire = ast_sched_add(sched, (expire + 10) * 1000, expire_register, 14678 ref_peer(peer, "add registration ref")); 14679 if (peer->expire == -1) { 14680 unref_peer(peer, "remote registration ref"); 14681 } 14682 } 14683 pvt->expiry = expire; 14684 snprintf(data, sizeof(data), "%s:%d:%s:%s", ast_sockaddr_stringify(&peer->addr), 14685 expire, peer->username, peer->fullcontact); 14686 /* We might not immediately be able to reconnect via TCP, but try caching it anyhow */ 14687 if (!peer->rt_fromcontact || !sip_cfg.peer_rtupdate) 14688 ast_db_put("SIP/Registry", peer->name, data); 14689 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)); 14690 14691 /* Is this a new IP address for us? */ 14692 if (VERBOSITY_ATLEAST(2) && ast_sockaddr_cmp(&peer->addr, &oldsin)) { 14693 ast_verbose(VERBOSE_PREFIX_3 "Registered SIP '%s' at %s\n", peer->name, 14694 ast_sockaddr_stringify(&peer->addr)); 14695 } 14696 sip_pvt_unlock(pvt); 14697 sip_poke_peer(peer, 0); 14698 sip_pvt_lock(pvt); 14699 register_peer_exten(peer, 1); 14700 14701 /* Save User agent */ 14702 useragent = get_header(req, "User-Agent"); 14703 if (strcasecmp(useragent, peer->useragent)) { 14704 ast_string_field_set(peer, useragent, useragent); 14705 ast_verb(4, "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name); 14706 } 14707 return PARSE_REGISTER_UPDATE; 14708 }
| static int parse_request | ( | struct sip_request * | req | ) | [static] |
Parse a SIP message.
Definition at line 8914 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(), parse_copy(), and sip_tls_read().
08915 { 08916 char *c = req->data->str; 08917 ptrdiff_t *dst = req->header; 08918 int i = 0, lim = SIP_MAX_HEADERS - 1; 08919 unsigned int skipping_headers = 0; 08920 ptrdiff_t current_header_offset = 0; 08921 char *previous_header = ""; 08922 08923 req->header[0] = 0; 08924 req->headers = -1; /* mark that we are working on the header */ 08925 for (; *c; c++) { 08926 if (*c == '\r') { /* remove \r */ 08927 *c = '\0'; 08928 } else if (*c == '\n') { /* end of this line */ 08929 *c = '\0'; 08930 current_header_offset = (c + 1) - ast_str_buffer(req->data); 08931 previous_header = ast_str_buffer(req->data) + dst[i]; 08932 if (skipping_headers) { 08933 /* check to see if this line is blank; if so, turn off 08934 the skipping flag, so the next line will be processed 08935 as a body line */ 08936 if (ast_strlen_zero(previous_header)) { 08937 skipping_headers = 0; 08938 } 08939 dst[i] = current_header_offset; /* record start of next line */ 08940 continue; 08941 } 08942 if (sipdebug) { 08943 ast_debug(4, "%7s %2d [%3d]: %s\n", 08944 req->headers < 0 ? "Header" : "Body", 08945 i, (int) strlen(previous_header), previous_header); 08946 } 08947 if (ast_strlen_zero(previous_header) && req->headers < 0) { 08948 req->headers = i; /* record number of header lines */ 08949 dst = req->line; /* start working on the body */ 08950 i = 0; 08951 lim = SIP_MAX_LINES - 1; 08952 } else { /* move to next line, check for overflows */ 08953 if (i++ == lim) { 08954 /* if we're processing headers, then skip any remaining 08955 headers and move on to processing the body, otherwise 08956 we're done */ 08957 if (req->headers != -1) { 08958 break; 08959 } else { 08960 req->headers = i; 08961 dst = req->line; 08962 i = 0; 08963 lim = SIP_MAX_LINES - 1; 08964 skipping_headers = 1; 08965 } 08966 } 08967 } 08968 dst[i] = current_header_offset; /* record start of next line */ 08969 } 08970 } 08971 08972 /* Check for last header or body line without CRLF. The RFC for SDP requires CRLF, 08973 but since some devices send without, we'll be generous in what we accept. However, 08974 if we've already reached the maximum number of lines for portion of the message 08975 we were parsing, we can't accept any more, so just ignore it. 08976 */ 08977 previous_header = ast_str_buffer(req->data) + dst[i]; 08978 if ((i < lim) && !ast_strlen_zero(previous_header)) { 08979 if (sipdebug) { 08980 ast_debug(4, "%7s %2d [%3d]: %s\n", 08981 req->headers < 0 ? "Header" : "Body", 08982 i, (int) strlen(previous_header), previous_header ); 08983 } 08984 i++; 08985 } 08986 08987 /* update count of header or body lines */ 08988 if (req->headers >= 0) { /* we are in the body */ 08989 req->lines = i; 08990 } else { /* no body */ 08991 req->headers = i; 08992 req->lines = 0; 08993 /* req->data->used will be a NULL byte */ 08994 req->line[0] = ast_str_strlen(req->data); 08995 } 08996 08997 if (*c) { 08998 ast_log(LOG_WARNING, "Too many lines, skipping <%s>\n", c); 08999 } 09000 09001 /* Split up the first line parts */ 09002 return determine_firstline_parts(req); 09003 }
| 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 26794 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(), and handle_response_invite().
26795 { 26796 char *p_token; 26797 int ref_idx; 26798 char *p_se_hdr; 26799 26800 if (ast_strlen_zero(p_hdrval)) { 26801 ast_log(LOG_WARNING, "Null Session-Expires header\n"); 26802 return -1; 26803 } 26804 26805 *p_ref = SESSION_TIMER_REFRESHER_PARAM_UNKNOWN; 26806 *p_interval = 0; 26807 26808 p_se_hdr = ast_strdupa(p_hdrval); 26809 p_se_hdr = ast_skip_blanks(p_se_hdr); 26810 26811 while ((p_token = strsep(&p_se_hdr, ";"))) { 26812 p_token = ast_skip_blanks(p_token); 26813 if (!sscanf(p_token, "%30d", p_interval)) { 26814 ast_log(LOG_WARNING, "Parsing of Session-Expires failed\n"); 26815 return -1; 26816 } 26817 26818 ast_debug(2, "Session-Expires: %d\n", *p_interval); 26819 26820 if (!p_se_hdr) 26821 continue; 26822 26823 p_se_hdr = ast_skip_blanks(p_se_hdr); 26824 ref_idx = strlen("refresher="); 26825 if (!strncasecmp(p_se_hdr, "refresher=", ref_idx)) { 26826 p_se_hdr += ref_idx; 26827 p_se_hdr = ast_skip_blanks(p_se_hdr); 26828 26829 if (!strncasecmp(p_se_hdr, "uac", strlen("uac"))) { 26830 *p_ref = SESSION_TIMER_REFRESHER_PARAM_UAC; 26831 ast_debug(2, "Refresher: UAC\n"); 26832 } else if (!strncasecmp(p_se_hdr, "uas", strlen("uas"))) { 26833 *p_ref = SESSION_TIMER_REFRESHER_PARAM_UAS; 26834 ast_debug(2, "Refresher: UAS\n"); 26835 } else { 26836 ast_log(LOG_WARNING, "Invalid refresher value %s\n", p_se_hdr); 26837 return -1; 26838 } 26839 break; 26840 } 26841 } 26842 return 0; 26843 }
| 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 14419 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().
14420 { 14421 int ret = parse_uri(uri, scheme, user, pass, hostport, transport); 14422 if (sip_cfg.legacy_useroption_parsing) { /* if legacy mode is active, strip semis from the user field */ 14423 char *p; 14424 if ((p = strchr(uri, (int)';'))) { 14425 *p = '\0'; 14426 } 14427 } 14428 return ret; 14429 }
| static int peer_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 30598 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 17510 of file chan_sip.c.
References ao2_t_ref, ast_cli(), and ast_cli_args::fd.
Referenced by sip_show_objects().
17511 { 17512 struct sip_peer *peer = userobj; 17513 int refc = ao2_t_ref(userobj, 0, ""); 17514 struct ast_cli_args *a = (struct ast_cli_args *) arg; 17515 17516 ast_cli(a->fd, "name: %s\ntype: peer\nobjflags: %d\nrefcount: %d\n\n", 17517 peer->name, 0, refc); 17518 return 0; 17519 }
| static int peer_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 30588 of file chan_sip.c.
References ast_str_case_hash().
Referenced by load_module().
30589 { 30590 const struct sip_peer *peer = obj; 30591 30592 return ast_str_case_hash(peer->name); 30593 }
| 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 30646 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().
30647 { 30648 struct sip_peer *peer = obj, *peer2 = arg; 30649 30650 if (ast_sockaddr_cmp_addr(&peer->addr, &peer2->addr)) { 30651 /* IP doesn't match */ 30652 return 0; 30653 } 30654 30655 /* We matched the IP, check to see if we need to match by port as well. */ 30656 if ((peer->transports & peer2->transports) & (SIP_TRANSPORT_TLS | SIP_TRANSPORT_TCP)) { 30657 /* peer matching on port is not possible with TCP/TLS */ 30658 return CMP_MATCH | CMP_STOP; 30659 } else if (ast_test_flag(&peer2->flags[0], SIP_INSECURE_PORT)) { 30660 /* We are allowing match without port for peers configured that 30661 * way in this pass through the peers. */ 30662 return ast_test_flag(&peer->flags[0], SIP_INSECURE_PORT) ? 30663 (CMP_MATCH | CMP_STOP) : 0; 30664 } 30665 30666 /* Now only return a match if the port matches, as well. */ 30667 return ast_sockaddr_port(&peer->addr) == ast_sockaddr_port(&peer2->addr) ? 30668 (CMP_MATCH | CMP_STOP) : 0; 30669 }
| 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 30610 of file chan_sip.c.
References ast_log(), ast_sockaddr_hash(), ast_sockaddr_isnull(), and LOG_ERROR.
Referenced by load_module().
30611 { 30612 const struct sip_peer *peer = obj; 30613 int ret = 0; 30614 30615 if (ast_sockaddr_isnull(&peer->addr)) { 30616 ast_log(LOG_ERROR, "Empty address\n"); 30617 } 30618 30619 ret = ast_sockaddr_hash(&peer->addr); 30620 30621 if (ret < 0) { 30622 ret = -ret; 30623 } 30624 30625 return ret; 30626 }
| static void peer_mailboxes_to_str | ( | struct ast_str ** | mailbox_str, | |
| struct sip_peer * | peer | |||
| ) | [static] |
list peer mailboxes to CLI
Definition at line 18032 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().
18033 { 18034 struct sip_mailbox *mailbox; 18035 18036 AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { 18037 ast_str_append(mailbox_str, 0, "%s%s%s%s", 18038 mailbox->mailbox, 18039 ast_strlen_zero(mailbox->context) ? "" : "@", 18040 S_OR(mailbox->context, ""), 18041 AST_LIST_NEXT(mailbox, entry) ? "," : ""); 18042 } 18043 }
| static int peer_markall_func | ( | void * | device, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 28620 of file chan_sip.c.
Referenced by reload_config().
| static void peer_sched_cleanup | ( | struct sip_peer * | peer | ) | [static] |
Definition at line 3141 of file chan_sip.c.
References AST_SCHED_DEL_UNREF, and unref_peer().
Referenced by match_and_cleanup_peer_sched().
03142 { 03143 if (peer->pokeexpire != -1) { 03144 AST_SCHED_DEL_UNREF(sched, peer->pokeexpire, 03145 unref_peer(peer, "removing poke peer ref")); 03146 } 03147 if (peer->expire != -1) { 03148 AST_SCHED_DEL_UNREF(sched, peer->expire, 03149 unref_peer(peer, "remove register expire ref")); 03150 } 03151 }
| static int peer_status | ( | struct sip_peer * | peer, | |
| char * | status, | |||
| int | statuslen | |||
| ) | [static] |
Definition at line 17077 of file chan_sip.c.
References ast_copy_string().
Referenced by _sip_show_peer(), _sip_show_peers(), and function_sippeer().
17078 { 17079 int res = 0; 17080 if (peer->maxms) { 17081 if (peer->lastms < 0) { 17082 ast_copy_string(status, "UNREACHABLE", statuslen); 17083 } else if (peer->lastms > peer->maxms) { 17084 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 17085 res = 1; 17086 } else if (peer->lastms) { 17087 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 17088 res = 1; 17089 } else { 17090 ast_copy_string(status, "UNKNOWN", statuslen); 17091 } 17092 } else { 17093 ast_copy_string(status, "Unmonitored", statuslen); 17094 /* Checking if port is 0 */ 17095 res = -1; 17096 } 17097 return res; 17098 }
| int peercomparefunc | ( | const void * | a, | |
| const void * | b | |||
| ) |
Definition at line 17305 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 31556 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().
31558 { 31559 struct sip_peer *peer; 31560 struct ao2_iterator i; 31561 struct ast_data *data_peer, *data_peer_mailboxes = NULL, *data_peer_mailbox, *enum_node; 31562 struct ast_data *data_sip_options; 31563 int total_mailboxes, x; 31564 struct sip_mailbox *mailbox; 31565 31566 i = ao2_iterator_init(peers, 0); 31567 while ((peer = ao2_iterator_next(&i))) { 31568 ao2_lock(peer); 31569 31570 data_peer = ast_data_add_node(data_root, "peer"); 31571 if (!data_peer) { 31572 ao2_unlock(peer); 31573 ao2_ref(peer, -1); 31574 continue; 31575 } 31576 31577 ast_data_add_structure(sip_peer, data_peer, peer); 31578 31579 /* transfer mode */ 31580 enum_node = ast_data_add_node(data_peer, "allowtransfer"); 31581 if (!enum_node) { 31582 ao2_unlock(peer); 31583 ao2_ref(peer, -1); 31584 continue; 31585 } 31586 ast_data_add_str(enum_node, "text", transfermode2str(peer->allowtransfer)); 31587 ast_data_add_int(enum_node, "value", peer->allowtransfer); 31588 31589 /* transports */ 31590 ast_data_add_str(data_peer, "transports", get_transport_list(peer->transports)); 31591 31592 /* peer type */ 31593 if ((peer->type & SIP_TYPE_USER) && (peer->type & SIP_TYPE_PEER)) { 31594 ast_data_add_str(data_peer, "type", "friend"); 31595 } else if (peer->type & SIP_TYPE_PEER) { 31596 ast_data_add_str(data_peer, "type", "peer"); 31597 } else if (peer->type & SIP_TYPE_USER) { 31598 ast_data_add_str(data_peer, "type", "user"); 31599 } 31600 31601 /* mailboxes */ 31602 total_mailboxes = 0; 31603 AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { 31604 if (!total_mailboxes) { 31605 data_peer_mailboxes = ast_data_add_node(data_peer, "mailboxes"); 31606 if (!data_peer_mailboxes) { 31607 break; 31608 } 31609 total_mailboxes++; 31610 } 31611 31612 data_peer_mailbox = ast_data_add_node(data_peer_mailboxes, "mailbox"); 31613 if (!data_peer_mailbox) { 31614 continue; 31615 } 31616 ast_data_add_str(data_peer_mailbox, "mailbox", mailbox->mailbox); 31617 ast_data_add_str(data_peer_mailbox, "context", mailbox->context); 31618 } 31619 31620 /* amaflags */ 31621 enum_node = ast_data_add_node(data_peer, "amaflags"); 31622 if (!enum_node) { 31623 ao2_unlock(peer); 31624 ao2_ref(peer, -1); 31625 continue; 31626 } 31627 ast_data_add_int(enum_node, "value", peer->amaflags); 31628 ast_data_add_str(enum_node, "text", ast_cdr_flags2str(peer->amaflags)); 31629 31630 /* sip options */ 31631 data_sip_options = ast_data_add_node(data_peer, "sipoptions"); 31632 if (!data_sip_options) { 31633 ao2_unlock(peer); 31634 ao2_ref(peer, -1); 31635 continue; 31636 } 31637 for (x = 0 ; x < ARRAY_LEN(sip_options); x++) { 31638 ast_data_add_bool(data_sip_options, sip_options[x].text, peer->sipoptions & sip_options[x].id); 31639 } 31640 31641 /* callingpres */ 31642 enum_node = ast_data_add_node(data_peer, "callingpres"); 31643 if (!enum_node) { 31644 ao2_unlock(peer); 31645 ao2_ref(peer, -1); 31646 continue; 31647 } 31648 ast_data_add_int(enum_node, "value", peer->callingpres); 31649 ast_data_add_str(enum_node, "text", ast_describe_caller_presentation(peer->callingpres)); 31650 31651 /* codecs */ 31652 ast_data_add_codecs(data_peer, "codecs", peer->capability); 31653 31654 if (!ast_data_search_match(search, data_peer)) { 31655 ast_data_remove_node(data_root, data_peer); 31656 } 31657 31658 ao2_unlock(peer); 31659 ao2_ref(peer, -1); 31660 } 31661 ao2_iterator_destroy(&i); 31662 31663 return 0; 31664 }
| 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 3449 of file chan_sip.c.
References ast_strlen_zero().
Referenced by build_peer(), reload_config(), and sip_parse_register_line().
03450 { 03451 int port = standard; 03452 if (ast_strlen_zero(pt) || (sscanf(pt, "%30d", &port) != 1) || (port < 1) || (port > 65535)) { 03453 port = standard; 03454 } 03455 03456 return port; 03457 }
| 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 17869 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().
17870 { 17871 int x; 17872 format_t codec; 17873 17874 for(x = 0; x < 64 ; x++) { 17875 codec = ast_codec_pref_index(pref, x); 17876 if (!codec) 17877 break; 17878 ast_cli(fd, "%s", ast_getformatname(codec)); 17879 ast_cli(fd, ":%d", pref->framing[x]); 17880 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 17881 ast_cli(fd, ","); 17882 } 17883 if (!x) 17884 ast_cli(fd, "none"); 17885 }
| static void print_group | ( | int | fd, | |
| ast_group_t | group, | |||
| int | crlf | |||
| ) | [static] |
Print call group and pickup group.
Definition at line 17562 of file chan_sip.c.
References ast_cli(), and ast_print_group().
Referenced by _sip_show_peer(), and sip_show_user().
17563 { 17564 char buf[256]; 17565 ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) ); 17566 }
| 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 26853 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().
26854 { 26855 int rtn; 26856 const char *p_hdrval; 26857 int minse; 26858 26859 p_hdrval = get_header(rsp, "Min-SE"); 26860 if (ast_strlen_zero(p_hdrval)) { 26861 ast_log(LOG_WARNING, "422 response without a Min-SE header %s\n", p_hdrval); 26862 return; 26863 } 26864 rtn = parse_minse(p_hdrval, &minse); 26865 if (rtn != 0) { 26866 ast_log(LOG_WARNING, "Parsing of Min-SE header failed %s\n", p_hdrval); 26867 return; 26868 } 26869 p->stimer->st_cached_min_se = minse; 26870 if (p->stimer->st_interval < minse) { 26871 p->stimer->st_interval = minse; 26872 } 26873 transmit_invite(p, SIP_INVITE, 1, 2, NULL); 26874 }
| static int proc_session_timer | ( | const void * | vp | ) | [static] |
Session-Timers: Process session refresh timeout event.
Definition at line 26703 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().
26704 { 26705 struct sip_pvt *p = (struct sip_pvt *) vp; 26706 int res = 0; 26707 26708 if (!p->stimer) { 26709 ast_log(LOG_WARNING, "Null stimer in proc_session_timer - %s\n", p->callid); 26710 goto return_unref; 26711 } 26712 26713 ast_debug(2, "Session timer expired: %d - %s\n", p->stimer->st_schedid, p->callid); 26714 26715 if (!p->owner) { 26716 goto return_unref; 26717 } 26718 26719 if ((p->stimer->st_active != TRUE) || (p->owner->_state != AST_STATE_UP)) { 26720 goto return_unref; 26721 } 26722 26723 if (p->stimer->st_ref == SESSION_TIMER_REFRESHER_US) { 26724 res = 1; 26725 if (T38_ENABLED == p->t38.state) { 26726 transmit_reinvite_with_sdp(p, TRUE, TRUE); 26727 } else { 26728 transmit_reinvite_with_sdp(p, FALSE, TRUE); 26729 } 26730 } else { 26731 p->stimer->st_expirys++; 26732 if (p->stimer->st_expirys >= 2) { 26733 if (p->stimer->quit_flag) { 26734 goto return_unref; 26735 } 26736 ast_log(LOG_WARNING, "Session-Timer expired - %s\n", p->callid); 26737 sip_pvt_lock(p); 26738 while (p->owner && ast_channel_trylock(p->owner)) { 26739 sip_pvt_unlock(p); 26740 usleep(1); 26741 if (p->stimer && p->stimer->quit_flag) { 26742 goto return_unref; 26743 } 26744 sip_pvt_lock(p); 26745 } 26746 26747 ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV); 26748 ast_channel_unlock(p->owner); 26749 sip_pvt_unlock(p); 26750 } else { 26751 res = 1; 26752 } 26753 } 26754 26755 return_unref: 26756 if (!res) { 26757 /* An error occurred. Stop session timer processing */ 26758 if (p->stimer) { 26759 ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid); 26760 p->stimer->st_schedid = -1; 26761 stop_session_timer(p); 26762 } 26763 26764 /* If we are not asking to be rescheduled, then we need to release our 26765 * reference to the dialog. */ 26766 dialog_unref(p, "removing session timer ref"); 26767 } 26768 26769 return res; 26770 }
| static int process_crypto | ( | struct sip_pvt * | p, | |
| struct ast_rtp_instance * | rtp, | |||
| struct sip_srtp ** | srtp, | |||
| const char * | a | |||
| ) | [static] |
Definition at line 30426 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().
30427 { 30428 /* If no RTP instance exists for this media stream don't bother processing the crypto line */ 30429 if (!rtp) { 30430 ast_debug(3, "Received offer with crypto line for media stream that is not enabled\n"); 30431 return FALSE; 30432 } 30433 30434 if (strncasecmp(a, "crypto:", 7)) { 30435 return FALSE; 30436 } 30437 if (!*srtp) { 30438 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 30439 ast_log(LOG_WARNING, "Ignoring unexpected crypto attribute in SDP answer\n"); 30440 return FALSE; 30441 } 30442 30443 if (setup_srtp(srtp) < 0) { 30444 return FALSE; 30445 } 30446 } 30447 30448 if (!(*srtp)->crypto && !((*srtp)->crypto = sdp_crypto_setup())) { 30449 return FALSE; 30450 } 30451 30452 if (sdp_crypto_process((*srtp)->crypto, a, rtp) < 0) { 30453 return FALSE; 30454 } 30455 30456 ast_set_flag(*srtp, SRTP_CRYPTO_OFFER_OK); 30457 30458 return TRUE; 30459 }
| 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 9211 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().
09212 { 09213 /* Iterators for SDP parsing */ 09214 int start = req->sdp_start; 09215 int next = start; 09216 int iterator = start; 09217 09218 /* Temporary vars for SDP parsing */ 09219 char type = '\0'; 09220 const char *value = NULL; 09221 const char *m = NULL; /* SDP media offer */ 09222 const char *nextm = NULL; 09223 int len = -1; 09224 09225 /* Host information */ 09226 struct ast_sockaddr sessionsa; 09227 struct ast_sockaddr audiosa; 09228 struct ast_sockaddr videosa; 09229 struct ast_sockaddr textsa; 09230 struct ast_sockaddr imagesa; 09231 struct ast_sockaddr *sa = NULL; /*!< RTP audio destination IP address */ 09232 struct ast_sockaddr *vsa = NULL; /*!< RTP video destination IP address */ 09233 struct ast_sockaddr *tsa = NULL; /*!< RTP text destination IP address */ 09234 struct ast_sockaddr *isa = NULL; /*!< UDPTL image destination IP address */ 09235 int portno = -1; /*!< RTP audio destination port number */ 09236 int vportno = -1; /*!< RTP video destination port number */ 09237 int tportno = -1; /*!< RTP text destination port number */ 09238 int udptlportno = -1; /*!< UDPTL image destination port number */ 09239 09240 /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */ 09241 format_t peercapability = 0, vpeercapability = 0, tpeercapability = 0; 09242 int peernoncodeccapability = 0, vpeernoncodeccapability = 0, tpeernoncodeccapability = 0; 09243 09244 struct ast_rtp_codecs newaudiortp, newvideortp, newtextrtp; 09245 format_t newjointcapability; /* Negotiated capability */ 09246 format_t newpeercapability; 09247 int newnoncodeccapability; 09248 09249 const char *codecs; 09250 int codec; 09251 09252 /* SRTP */ 09253 int secure_audio = FALSE; 09254 int secure_video = FALSE; 09255 09256 /* Others */ 09257 int sendonly = -1; 09258 int numberofports; 09259 int numberofmediastreams = 0; 09260 int last_rtpmap_codec = 0; 09261 int red_data_pt[10]; /* For T.140 RED */ 09262 int red_num_gen = 0; /* For T.140 RED */ 09263 char red_fmtp[100] = "empty"; /* For T.140 RED */ 09264 int debug = sip_debug_test_pvt(p); 09265 09266 /* START UNKNOWN */ 09267 char buf[SIPBUFSIZE]; 09268 /* END UNKNOWN */ 09269 09270 /* Initial check */ 09271 if (!p->rtp) { 09272 ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n"); 09273 return -1; 09274 } 09275 09276 /* Make sure that the codec structures are all cleared out */ 09277 ast_rtp_codecs_payloads_clear(&newaudiortp, NULL); 09278 ast_rtp_codecs_payloads_clear(&newvideortp, NULL); 09279 ast_rtp_codecs_payloads_clear(&newtextrtp, NULL); 09280 09281 /* Update our last rtprx when we receive an SDP, too */ 09282 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 09283 09284 memset(p->offered_media, 0, sizeof(p->offered_media)); 09285 09286 /* default: novideo and notext set */ 09287 p->novideo = TRUE; 09288 p->notext = TRUE; 09289 09290 /* Scan for the first media stream (m=) line to limit scanning of globals */ 09291 nextm = get_sdp_iterate(&next, req, "m"); 09292 if (ast_strlen_zero(nextm)) { 09293 ast_log(LOG_WARNING, "Insufficient information for SDP (m= not found)\n"); 09294 return -1; 09295 } 09296 09297 /* Scan session level SDP parameters (lines before first media stream) */ 09298 while ((type = get_sdp_line(&iterator, next - 1, req, &value)) != '\0') { 09299 int processed = FALSE; 09300 switch (type) { 09301 case 'o': 09302 /* If we end up receiving SDP that doesn't actually modify the session we don't want to treat this as a fatal 09303 * error. We just want to ignore the SDP and let the rest of the packet be handled as normal. 09304 */ 09305 if (!process_sdp_o(value, p)) { 09306 return (p->session_modify == FALSE) ? 0 : -1; 09307 } 09308 processed = TRUE; 09309 break; 09310 case 'c': 09311 if (process_sdp_c(value, &sessionsa)) { 09312 processed = TRUE; 09313 sa = &sessionsa; 09314 vsa = sa; 09315 tsa = sa; 09316 isa = sa; 09317 } 09318 break; 09319 case 'a': 09320 if (process_sdp_a_sendonly(value, &sendonly)) { 09321 processed = TRUE; 09322 } 09323 else if (process_sdp_a_audio(value, p, &newaudiortp, &last_rtpmap_codec)) 09324 processed = TRUE; 09325 else if (process_sdp_a_video(value, p, &newvideortp, &last_rtpmap_codec)) 09326 processed = TRUE; 09327 else if (process_sdp_a_text(value, p, &newtextrtp, red_fmtp, &red_num_gen, red_data_pt, &last_rtpmap_codec)) 09328 processed = TRUE; 09329 else if (process_sdp_a_image(value, p)) 09330 processed = TRUE; 09331 break; 09332 } 09333 09334 ast_debug(3, "Processing session-level SDP %c=%s... %s\n", type, value, (processed == TRUE)? "OK." : "UNSUPPORTED OR FAILED."); 09335 } 09336 09337 /* Scan media stream (m=) specific parameters loop */ 09338 while (!ast_strlen_zero(nextm)) { 09339 int audio = FALSE; 09340 int video = FALSE; 09341 int image = FALSE; 09342 int text = FALSE; 09343 int processed_crypto = FALSE; 09344 char protocol[5] = {0,}; 09345 int x; 09346 09347 numberofports = 0; 09348 len = -1; 09349 start = next; 09350 m = nextm; 09351 iterator = next; 09352 nextm = get_sdp_iterate(&next, req, "m"); 09353 09354 /* Check for 'audio' media offer */ 09355 if (strncmp(m, "audio ", 6) == 0) { 09356 if ((sscanf(m, "audio %30u/%30u RTP/%4s %n", &x, &numberofports, protocol, &len) == 3 && len > 0) || 09357 (sscanf(m, "audio %30u RTP/%4s %n", &x, protocol, &len) == 2 && len > 0)) { 09358 if (x == 0) { 09359 ast_log(LOG_WARNING, "Ignoring audio media offer because port number is zero\n"); 09360 continue; 09361 } 09362 09363 /* Check number of ports offered for stream */ 09364 if (numberofports > 1) { 09365 ast_log(LOG_WARNING, "%d ports offered for audio media, not supported by Asterisk. Will try anyway...\n", numberofports); 09366 } 09367 09368 if (!strcmp(protocol, "SAVP")) { 09369 secure_audio = 1; 09370 } else if (strcmp(protocol, "AVP")) { 09371 ast_log(LOG_WARNING, "Unknown RTP profile in audio offer: %s\n", m); 09372 continue; 09373 } 09374 09375 if (p->offered_media[SDP_AUDIO].order_offered) { 09376 ast_log(LOG_WARNING, "Rejecting non-primary audio stream: %s\n", m); 09377 return -1; 09378 } 09379 09380 audio = TRUE; 09381 p->offered_media[SDP_AUDIO].order_offered = ++numberofmediastreams; 09382 portno = x; 09383 09384 /* Scan through the RTP payload types specified in a "m=" line: */ 09385 codecs = m + len; 09386 ast_copy_string(p->offered_media[SDP_AUDIO].codecs, codecs, sizeof(p->offered_media[SDP_AUDIO].codecs)); 09387 for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 09388 if (sscanf(codecs, "%30u%n", &codec, &len) != 1) { 09389 ast_log(LOG_WARNING, "Invalid syntax in RTP audio format list: %s\n", codecs); 09390 return -1; 09391 } 09392 if (debug) { 09393 ast_verbose("Found RTP audio format %d\n", codec); 09394 } 09395 09396 ast_rtp_codecs_payloads_set_m_type(&newaudiortp, NULL, codec); 09397 } 09398 } else { 09399 ast_log(LOG_WARNING, "Rejecting audio media offer due to invalid or unsupported syntax: %s\n", m); 09400 return -1; 09401 } 09402 } 09403 /* Check for 'video' media offer */ 09404 else if (strncmp(m, "video ", 6) == 0) { 09405 if ((sscanf(m, "video %30u/%30u RTP/%4s %n", &x, &numberofports, protocol, &len) == 3 && len > 0) || 09406 (sscanf(m, "video %30u RTP/%4s %n", &x, protocol, &len) == 2 && len > 0)) { 09407 if (x == 0) { 09408 ast_log(LOG_WARNING, "Ignoring video media offer because port number is zero\n"); 09409 continue; 09410 } 09411 09412 /* Check number of ports offered for stream */ 09413 if (numberofports > 1) { 09414 ast_log(LOG_WARNING, "%d ports offered for video media, not supported by Asterisk. Will try anyway...\n", numberofports); 09415 } 09416 09417 if (!strcmp(protocol, "SAVP")) { 09418 secure_video = 1; 09419 } else if (strcmp(protocol, "AVP")) { 09420 ast_log(LOG_WARNING, "Unknown RTP profile in video offer: %s\n", m); 09421 continue; 09422 } 09423 09424 if (p->offered_media[SDP_VIDEO].order_offered) { 09425 ast_log(LOG_WARNING, "Rejecting non-primary video stream: %s\n", m); 09426 return -1; 09427 } 09428 09429 video = TRUE; 09430 p->novideo = FALSE; 09431 p->offered_media[SDP_VIDEO].order_offered = ++numberofmediastreams; 09432 vportno = x; 09433 09434 /* Scan through the RTP payload types specified in a "m=" line: */ 09435 codecs = m + len; 09436 ast_copy_string(p->offered_media[SDP_VIDEO].codecs, codecs, sizeof(p->offered_media[SDP_VIDEO].codecs)); 09437 for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 09438 if (sscanf(codecs, "%30u%n", &codec, &len) != 1) { 09439 ast_log(LOG_WARNING, "Invalid syntax in RTP video format list: %s\n", codecs); 09440 return -1; 09441 } 09442 if (debug) { 09443 ast_verbose("Found RTP video format %d\n", codec); 09444 } 09445 ast_rtp_codecs_payloads_set_m_type(&newvideortp, NULL, codec); 09446 } 09447 } else { 09448 ast_log(LOG_WARNING, "Rejecting video media offer due to invalid or unsupported syntax: %s\n", m); 09449 return -1; 09450 } 09451 } 09452 /* Check for 'text' media offer */ 09453 else if (strncmp(m, "text ", 5) == 0) { 09454 if ((sscanf(m, "text %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 09455 (sscanf(m, "text %30u RTP/AVP %n", &x, &len) == 1 && len > 0)) { 09456 if (x == 0) { 09457 ast_log(LOG_WARNING, "Ignoring text media offer because port number is zero\n"); 09458 continue; 09459 } 09460 09461 /* Check number of ports offered for stream */ 09462 if (numberofports > 1) { 09463 ast_log(LOG_WARNING, "%d ports offered for text media, not supported by Asterisk. Will try anyway...\n", numberofports); 09464 } 09465 09466 if (p->offered_media[SDP_TEXT].order_offered) { 09467 ast_log(LOG_WARNING, "Rejecting non-primary text stream: %s\n", m); 09468 return -1; 09469 } 09470 09471 text = TRUE; 09472 p->notext = FALSE; 09473 p->offered_media[SDP_TEXT].order_offered = ++numberofmediastreams; 09474 tportno = x; 09475 09476 /* Scan through the RTP payload types specified in a "m=" line: */ 09477 codecs = m + len; 09478 ast_copy_string(p->offered_media[SDP_TEXT].codecs, codecs, sizeof(p->offered_media[SDP_TEXT].codecs)); 09479 for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 09480 if (sscanf(codecs, "%30u%n", &codec, &len) != 1) { 09481 ast_log(LOG_WARNING, "Invalid syntax in RTP video format list: %s\n", codecs); 09482 return -1; 09483 } 09484 if (debug) { 09485 ast_verbose("Found RTP text format %d\n", codec); 09486 } 09487 ast_rtp_codecs_payloads_set_m_type(&newtextrtp, NULL, codec); 09488 } 09489 } else { 09490 ast_log(LOG_WARNING, "Rejecting text media offer due to invalid or unsupported syntax: %s\n", m); 09491 return -1; 09492 } 09493 } 09494 /* Check for 'image' media offer */ 09495 else if (strncmp(m, "image ", 6) == 0) { 09496 if (((sscanf(m, "image %30u udptl t38%n", &x, &len) == 1 && len > 0) || 09497 (sscanf(m, "image %30u UDPTL t38%n", &x, &len) == 1 && len > 0))) { 09498 if (x == 0) { 09499 ast_log(LOG_WARNING, "Ignoring image media offer because port number is zero\n"); 09500 continue; 09501 } 09502 09503 if (initialize_udptl(p)) { 09504 ast_log(LOG_WARNING, "Rejecting offer with image stream due to UDPTL initialization failure\n"); 09505 return -1; 09506 } 09507 09508 if (p->offered_media[SDP_IMAGE].order_offered) { 09509 ast_log(LOG_WARNING, "Rejecting non-primary image stream: %s\n", m); 09510 return -1; 09511 } 09512 09513 image = TRUE; 09514 if (debug) { 09515 ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid); 09516 } 09517 09518 p->offered_media[SDP_IMAGE].order_offered = ++numberofmediastreams; 09519 udptlportno = x; 09520 09521 if (p->t38.state != T38_ENABLED) { 09522 memset(&p->t38.their_parms, 0, sizeof(p->t38.their_parms)); 09523 09524 /* default EC to none, the remote end should 09525 * respond with the EC they want to use */ 09526 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 09527 } 09528 } else { 09529 ast_log(LOG_WARNING, "Rejecting image media offer due to invalid or unsupported syntax: %s\n", m); 09530 return -1; 09531 } 09532 } else { 09533 ast_log(LOG_WARNING, "Unsupported top-level media type in offer: %s\n", m); 09534 continue; 09535 } 09536 09537 /* Media stream specific parameters */ 09538 while ((type = get_sdp_line(&iterator, next - 1, req, &value)) != '\0') { 09539 int processed = FALSE; 09540 09541 switch (type) { 09542 case 'c': 09543 if (audio) { 09544 if (process_sdp_c(value, &audiosa)) { 09545 processed = TRUE; 09546 sa = &audiosa; 09547 } 09548 } else if (video) { 09549 if (process_sdp_c(value, &videosa)) { 09550 processed = TRUE; 09551 vsa = &videosa; 09552 } 09553 } else if (text) { 09554 if (process_sdp_c(value, &textsa)) { 09555 processed = TRUE; 09556 tsa = &textsa; 09557 } 09558 } else if (image) { 09559 if (process_sdp_c(value, &imagesa)) { 09560 processed = TRUE; 09561 isa = &imagesa; 09562 } 09563 } 09564 break; 09565 case 'a': 09566 /* Audio specific scanning */ 09567 if (audio) { 09568 if (process_sdp_a_sendonly(value, &sendonly)) { 09569 processed = TRUE; 09570 } else if (!processed_crypto && process_crypto(p, p->rtp, &p->srtp, value)) { 09571 processed_crypto = TRUE; 09572 processed = TRUE; 09573 } else if (process_sdp_a_audio(value, p, &newaudiortp, &last_rtpmap_codec)) { 09574 processed = TRUE; 09575 } 09576 } 09577 /* Video specific scanning */ 09578 else if (video) { 09579 if (!processed_crypto && process_crypto(p, p->vrtp, &p->vsrtp, value)) { 09580 processed_crypto = TRUE; 09581 processed = TRUE; 09582 } else if (process_sdp_a_video(value, p, &newvideortp, &last_rtpmap_codec)) { 09583 processed = TRUE; 09584 } 09585 } 09586 /* Text (T.140) specific scanning */ 09587 else if (text) { 09588 if (process_sdp_a_text(value, p, &newtextrtp, red_fmtp, &red_num_gen, red_data_pt, &last_rtpmap_codec)) { 09589 processed = TRUE; 09590 } else if (!processed_crypto && process_crypto(p, p->trtp, &p->tsrtp, value)) { 09591 processed_crypto = TRUE; 09592 processed = TRUE; 09593 } 09594 } 09595 /* Image (T.38 FAX) specific scanning */ 09596 else if (image) { 09597 if (process_sdp_a_image(value, p)) 09598 processed = TRUE; 09599 } 09600 break; 09601 } 09602 09603 ast_debug(3, "Processing media-level (%s) SDP %c=%s... %s\n", 09604 (audio == TRUE)? "audio" : (video == TRUE)? "video" : (text == TRUE)? "text" : "image", 09605 type, value, 09606 (processed == TRUE)? "OK." : "UNSUPPORTED OR FAILED."); 09607 } 09608 09609 /* Ensure crypto lines are provided where necessary */ 09610 if (audio && secure_audio && !processed_crypto) { 09611 ast_log(LOG_WARNING, "Rejecting secure audio stream without encryption details: %s\n", m); 09612 return -1; 09613 } else if (video && secure_video && !processed_crypto) { 09614 ast_log(LOG_WARNING, "Rejecting secure video stream without encryption details: %s\n", m); 09615 return -1; 09616 } 09617 } 09618 09619 /* Sanity checks */ 09620 if (!sa && !vsa && !tsa && !isa) { 09621 ast_log(LOG_WARNING, "Insufficient information in SDP (c=)...\n"); 09622 return -1; 09623 } 09624 09625 if ((portno == -1) && 09626 (vportno == -1) && 09627 (tportno == -1) && 09628 (udptlportno == -1)) { 09629 ast_log(LOG_WARNING, "Failing due to no acceptable offer found\n"); 09630 return -1; 09631 } 09632 09633 if (secure_audio && !(p->srtp && (ast_test_flag(p->srtp, SRTP_CRYPTO_OFFER_OK)))) { 09634 ast_log(LOG_WARNING, "Can't provide secure audio requested in SDP offer\n"); 09635 return -1; 09636 } 09637 09638 if (!secure_audio && p->srtp) { 09639 ast_log(LOG_WARNING, "We are requesting SRTP for audio, but they responded without it!\n"); 09640 return -1; 09641 } 09642 09643 if (secure_video && !(p->vsrtp && (ast_test_flag(p->vsrtp, SRTP_CRYPTO_OFFER_OK)))) { 09644 ast_log(LOG_WARNING, "Can't provide secure video requested in SDP offer\n"); 09645 return -1; 09646 } 09647 09648 if (!p->novideo && !secure_video && p->vsrtp) { 09649 ast_log(LOG_WARNING, "We are requesting SRTP for video, but they responded without it!\n"); 09650 return -1; 09651 } 09652 09653 if (!(secure_audio || secure_video) && ast_test_flag(&p->flags[1], SIP_PAGE2_USE_SRTP)) { 09654 ast_log(LOG_WARNING, "Matched device setup to use SRTP, but request was not!\n"); 09655 return -1; 09656 } 09657 09658 if (udptlportno == -1) { 09659 change_t38_state(p, T38_DISABLED); 09660 } 09661 09662 /* Now gather all of the codecs that we are asked for: */ 09663 ast_rtp_codecs_payload_formats(&newaudiortp, &peercapability, &peernoncodeccapability); 09664 ast_rtp_codecs_payload_formats(&newvideortp, &vpeercapability, &vpeernoncodeccapability); 09665 ast_rtp_codecs_payload_formats(&newtextrtp, &tpeercapability, &tpeernoncodeccapability); 09666 09667 newjointcapability = p->capability & (peercapability | vpeercapability | tpeercapability); 09668 newpeercapability = (peercapability | vpeercapability | tpeercapability); 09669 newnoncodeccapability = p->noncodeccapability & peernoncodeccapability; 09670 09671 if (debug) { 09672 /* shame on whoever coded this.... */ 09673 char s1[SIPBUFSIZE], s2[SIPBUFSIZE], s3[SIPBUFSIZE], s4[SIPBUFSIZE], s5[SIPBUFSIZE]; 09674 09675 ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s/text=%s, combined - %s\n", 09676 ast_getformatname_multiple(s1, SIPBUFSIZE, p->capability), 09677 ast_getformatname_multiple(s2, SIPBUFSIZE, peercapability), 09678 ast_getformatname_multiple(s3, SIPBUFSIZE, vpeercapability), 09679 ast_getformatname_multiple(s4, SIPBUFSIZE, tpeercapability), 09680 ast_getformatname_multiple(s5, SIPBUFSIZE, newjointcapability)); 09681 } 09682 if (debug) { 09683 struct ast_str *s1 = ast_str_alloca(SIPBUFSIZE); 09684 struct ast_str *s2 = ast_str_alloca(SIPBUFSIZE); 09685 struct ast_str *s3 = ast_str_alloca(SIPBUFSIZE); 09686 09687 ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n", 09688 ast_rtp_lookup_mime_multiple2(s1, p->noncodeccapability, 0, 0), 09689 ast_rtp_lookup_mime_multiple2(s2, peernoncodeccapability, 0, 0), 09690 ast_rtp_lookup_mime_multiple2(s3, newnoncodeccapability, 0, 0)); 09691 } 09692 if (!newjointcapability && udptlportno == -1) { 09693 ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n"); 09694 /* Do NOT Change current setting */ 09695 return -1; 09696 } 09697 09698 if (portno != -1 || vportno != -1 || tportno != -1) { 09699 /* We are now ready to change the sip session and RTP structures with the offered codecs, since 09700 they are acceptable */ 09701 p->jointcapability = newjointcapability; /* Our joint codec profile for this call */ 09702 p->peercapability = newpeercapability; /* The other side's capability in latest offer */ 09703 p->jointnoncodeccapability = newnoncodeccapability; /* DTMF capabilities */ 09704 09705 /* respond with single most preferred joint codec, limiting the other side's choice */ 09706 if (ast_test_flag(&p->flags[1], SIP_PAGE2_PREFERRED_CODEC)) { 09707 p->jointcapability = ast_codec_choose(&p->prefs, p->jointcapability, 1); 09708 } 09709 } 09710 09711 /* Setup audio address and port */ 09712 if (p->rtp) { 09713 if (portno > 0) { 09714 ast_sockaddr_set_port(sa, portno); 09715 ast_rtp_instance_set_remote_address(p->rtp, sa); 09716 if (debug) { 09717 ast_verbose("Peer audio RTP is at port %s\n", 09718 ast_sockaddr_stringify(sa)); 09719 } 09720 09721 ast_rtp_codecs_payloads_copy(&newaudiortp, ast_rtp_instance_get_codecs(p->rtp), p->rtp); 09722 /* Ensure RTCP is enabled since it may be inactive 09723 if we're coming back from a T.38 session */ 09724 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_RTCP, 1); 09725 /* Ensure audio RTCP reads are enabled */ 09726 if (p->owner) { 09727 ast_channel_set_fd(p->owner, 1, ast_rtp_instance_fd(p->rtp, 1)); 09728 } 09729 09730 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) { 09731 ast_clear_flag(&p->flags[0], SIP_DTMF); 09732 if (newnoncodeccapability & AST_RTP_DTMF) { 09733 /* XXX Would it be reasonable to drop the DSP at this point? XXX */ 09734 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 09735 /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */ 09736 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF, 1); 09737 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 09738 } else { 09739 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 09740 } 09741 } 09742 } else if (udptlportno > 0) { 09743 if (debug) 09744 ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session.\n"); 09745 /* Prevent audio RTCP reads */ 09746 if (p->owner) { 09747 ast_channel_set_fd(p->owner, 1, -1); 09748 } 09749 /* Silence RTCP while audio RTP is inactive */ 09750 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_RTCP, 0); 09751 } else { 09752 ast_rtp_instance_stop(p->rtp); 09753 if (debug) 09754 ast_verbose("Peer doesn't provide audio\n"); 09755 } 09756 } 09757 09758 /* Setup video address and port */ 09759 if (p->vrtp) { 09760 if (vportno > 0) { 09761 ast_sockaddr_set_port(vsa, vportno); 09762 ast_rtp_instance_set_remote_address(p->vrtp, vsa); 09763 if (debug) { 09764 ast_verbose("Peer video RTP is at port %s\n", 09765 ast_sockaddr_stringify(vsa)); 09766 } 09767 ast_rtp_codecs_payloads_copy(&newvideortp, ast_rtp_instance_get_codecs(p->vrtp), p->vrtp); 09768 } else { 09769 ast_rtp_instance_stop(p->vrtp); 09770 if (debug) 09771 ast_verbose("Peer doesn't provide video\n"); 09772 } 09773 } 09774 09775 /* Setup text address and port */ 09776 if (p->trtp) { 09777 if (tportno > 0) { 09778 ast_sockaddr_set_port(tsa, tportno); 09779 ast_rtp_instance_set_remote_address(p->trtp, tsa); 09780 if (debug) { 09781 ast_verbose("Peer T.140 RTP is at port %s\n", 09782 ast_sockaddr_stringify(tsa)); 09783 } 09784 if ((p->jointcapability & AST_FORMAT_T140RED)) { 09785 p->red = 1; 09786 ast_rtp_red_init(p->trtp, 300, red_data_pt, 2); 09787 } else { 09788 p->red = 0; 09789 } 09790 ast_rtp_codecs_payloads_copy(&newtextrtp, ast_rtp_instance_get_codecs(p->trtp), p->trtp); 09791 } else { 09792 ast_rtp_instance_stop(p->trtp); 09793 if (debug) 09794 ast_verbose("Peer doesn't provide T.140\n"); 09795 } 09796 } 09797 09798 /* Setup image address and port */ 09799 if (p->udptl) { 09800 if (udptlportno > 0) { 09801 if (ast_test_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP) && ast_test_flag(&p->flags[1], SIP_PAGE2_UDPTL_DESTINATION)) { 09802 ast_rtp_instance_get_remote_address(p->rtp, isa); 09803 if (!ast_sockaddr_isnull(isa) && debug) { 09804 ast_debug(1, "Peer T.38 UDPTL is set behind NAT and with destination, destination address now %s\n", ast_sockaddr_stringify(isa)); 09805 } 09806 } 09807 ast_sockaddr_set_port(isa, udptlportno); 09808 ast_udptl_set_peer(p->udptl, isa); 09809 if (debug) 09810 ast_debug(1,"Peer T.38 UDPTL is at port %s\n", ast_sockaddr_stringify(isa)); 09811 09812 /* verify the far max ifp can be calculated. this requires far max datagram to be set. */ 09813 if (!ast_udptl_get_far_max_datagram(p->udptl)) { 09814 /* setting to zero will force a default if none was provided by the SDP */ 09815 ast_udptl_set_far_max_datagram(p->udptl, 0); 09816 } 09817 09818 /* Remote party offers T38, we need to update state */ 09819 if ((t38action == SDP_T38_ACCEPT) && 09820 (p->t38.state == T38_LOCAL_REINVITE)) { 09821 change_t38_state(p, T38_ENABLED); 09822 } else if ((t38action == SDP_T38_INITIATE) && 09823 p->owner && p->lastinvite) { 09824 change_t38_state(p, T38_PEER_REINVITE); /* T38 Offered in re-invite from remote party */ 09825 /* If fax detection is enabled then send us off to the fax extension */ 09826 if (ast_test_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_T38)) { 09827 ast_channel_lock(p->owner); 09828 if (strcmp(p->owner->exten, "fax")) { 09829 const char *target_context = S_OR(p->owner->macrocontext, p->owner->context); 09830 ast_channel_unlock(p->owner); 09831 if (ast_exists_extension(p->owner, target_context, "fax", 1, 09832 S_COR(p->owner->caller.id.number.valid, p->owner->caller.id.number.str, NULL))) { 09833 ast_verbose(VERBOSE_PREFIX_2 "Redirecting '%s' to fax extension due to peer T.38 re-INVITE\n", p->owner->name); 09834 pbx_builtin_setvar_helper(p->owner, "FAXEXTEN", p->owner->exten); 09835 if (ast_async_goto(p->owner, target_context, "fax", 1)) { 09836 ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", p->owner->name, target_context); 09837 } 09838 } else { 09839 ast_log(LOG_NOTICE, "T.38 re-INVITE detected but no fax extension\n"); 09840 } 09841 } else { 09842 ast_channel_unlock(p->owner); 09843 } 09844 } 09845 } 09846 } else { 09847 change_t38_state(p, T38_DISABLED); 09848 ast_udptl_stop(p->udptl); 09849 if (debug) 09850 ast_debug(1, "Peer doesn't provide T.38 UDPTL\n"); 09851 } 09852 } 09853 09854 if ((portno == -1) && (p->t38.state != T38_DISABLED)) { 09855 ast_debug(3, "Have T.38 but no audio, accepting offer anyway\n"); 09856 return 0; 09857 } 09858 09859 /* Ok, we're going with this offer */ 09860 ast_debug(2, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, p->jointcapability)); 09861 09862 if (!p->owner) /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */ 09863 return 0; 09864 09865 ast_debug(4, "We have an owner, now see if we need to change this call\n"); 09866 09867 if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 09868 if (debug) { 09869 char s1[SIPBUFSIZE], s2[SIPBUFSIZE]; 09870 ast_debug(1, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n", 09871 ast_getformatname_multiple(s1, SIPBUFSIZE, p->jointcapability), 09872 ast_getformatname_multiple(s2, SIPBUFSIZE, p->owner->nativeformats)); 09873 } 09874 p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability) | (p->capability & tpeercapability); 09875 ast_set_read_format(p->owner, p->owner->readformat); 09876 ast_set_write_format(p->owner, p->owner->writeformat); 09877 } 09878 09879 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)) { 09880 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 09881 /* Activate a re-invite */ 09882 ast_queue_frame(p->owner, &ast_null_frame); 09883 change_hold_state(p, req, FALSE, sendonly); 09884 } 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)) { 09885 ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 09886 S_OR(p->mohsuggest, NULL), 09887 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 09888 if (sendonly) 09889 ast_rtp_instance_stop(p->rtp); 09890 /* RTCP needs to go ahead, even if we're on hold!!! */ 09891 /* Activate a re-invite */ 09892 ast_queue_frame(p->owner, &ast_null_frame); 09893 change_hold_state(p, req, TRUE, sendonly); 09894 } 09895 09896 return 0; 09897 }
| 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 10025 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().
10026 { 10027 int found = FALSE; 10028 int codec; 10029 char mimeSubtype[128]; 10030 char fmtp_string[64]; 10031 unsigned int sample_rate; 10032 int debug = sip_debug_test_pvt(p); 10033 10034 if (!strncasecmp(a, "ptime", 5)) { 10035 char *tmp = strrchr(a, ':'); 10036 long int framing = 0; 10037 if (tmp) { 10038 tmp++; 10039 framing = strtol(tmp, NULL, 10); 10040 if (framing == LONG_MIN || framing == LONG_MAX) { 10041 framing = 0; 10042 ast_debug(1, "Can't read framing from SDP: %s\n", a); 10043 } 10044 } 10045 if (framing && p->autoframing) { 10046 struct ast_codec_pref *pref = &ast_rtp_instance_get_codecs(p->rtp)->pref; 10047 int codec_n; 10048 for (codec_n = 0; codec_n < AST_RTP_MAX_PT; codec_n++) { 10049 struct ast_rtp_payload_type format = ast_rtp_codecs_payload_lookup(ast_rtp_instance_get_codecs(p->rtp), codec_n); 10050 if (!format.asterisk_format || !format.code) /* non-codec or not found */ 10051 continue; 10052 ast_debug(1, "Setting framing for %s to %ld\n", ast_getformatname(format.code), framing); 10053 ast_codec_pref_setsize(pref, format.code, framing); 10054 } 10055 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, pref); 10056 } 10057 found = TRUE; 10058 } else if (sscanf(a, "rtpmap: %30u %127[^/]/%30u", &codec, mimeSubtype, &sample_rate) == 3) { 10059 /* We have a rtpmap to handle */ 10060 if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 10061 if (!(ast_rtp_codecs_payloads_set_rtpmap_type_rate(newaudiortp, NULL, codec, "audio", mimeSubtype, 10062 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0, sample_rate))) { 10063 if (debug) 10064 ast_verbose("Found audio description format %s for ID %d\n", mimeSubtype, codec); 10065 //found_rtpmap_codecs[last_rtpmap_codec] = codec; 10066 (*last_rtpmap_codec)++; 10067 found = TRUE; 10068 } else { 10069 ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec); 10070 if (debug) 10071 ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec); 10072 } 10073 } else { 10074 if (debug) 10075 ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec); 10076 } 10077 } else if (sscanf(a, "fmtp: %30u %63s", &codec, fmtp_string) == 2) { 10078 struct ast_rtp_payload_type payload; 10079 10080 payload = ast_rtp_codecs_payload_lookup(newaudiortp, codec); 10081 if (payload.code && payload.asterisk_format) { 10082 unsigned int bit_rate; 10083 10084 switch (payload.code) { 10085 case AST_FORMAT_SIREN7: 10086 if (sscanf(fmtp_string, "bitrate=%30u", &bit_rate) == 1) { 10087 if (bit_rate != 32000) { 10088 ast_log(LOG_WARNING, "Got Siren7 offer at %d bps, but only 32000 bps supported; ignoring.\n", bit_rate); 10089 ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec); 10090 } else { 10091 found = TRUE; 10092 } 10093 } 10094 break; 10095 case AST_FORMAT_SIREN14: 10096 if (sscanf(fmtp_string, "bitrate=%30u", &bit_rate) == 1) { 10097 if (bit_rate != 48000) { 10098 ast_log(LOG_WARNING, "Got Siren14 offer at %d bps, but only 48000 bps supported; ignoring.\n", bit_rate); 10099 ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec); 10100 } else { 10101 found = TRUE; 10102 } 10103 } 10104 break; 10105 case AST_FORMAT_G719: 10106 if (sscanf(fmtp_string, "bitrate=%30u", &bit_rate) == 1) { 10107 if (bit_rate != 64000) { 10108 ast_log(LOG_WARNING, "Got G.719 offer at %d bps, but only 64000 bps supported; ignoring.\n", bit_rate); 10109 ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec); 10110 } else { 10111 found = TRUE; 10112 } 10113 } 10114 } 10115 } 10116 } 10117 10118 return found; 10119 }
| static int process_sdp_a_image | ( | const char * | a, | |
| struct sip_pvt * | p | |||
| ) | [static] |
Definition at line 10204 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().
10205 { 10206 int found = FALSE; 10207 char s[256]; 10208 unsigned int x; 10209 char *attrib = ast_strdupa(a); 10210 char *pos; 10211 10212 if (initialize_udptl(p)) { 10213 return found; 10214 } 10215 10216 /* Due to a typo in an IANA registration of one of the T.38 attributes, 10217 * RFC5347 section 2.5.2 recommends that all T.38 attributes be parsed in 10218 * a case insensitive manner. Hence, the importance of proof reading (and 10219 * code reviews). 10220 */ 10221 for (pos = attrib; *pos; ++pos) { 10222 *pos = tolower(*pos); 10223 } 10224 10225 if ((sscanf(attrib, "t38faxmaxbuffer:%30u", &x) == 1)) { 10226 ast_debug(3, "MaxBufferSize:%d\n", x); 10227 found = TRUE; 10228 } else if ((sscanf(attrib, "t38maxbitrate:%30u", &x) == 1) || (sscanf(attrib, "t38faxmaxrate:%30u", &x) == 1)) { 10229 ast_debug(3, "T38MaxBitRate: %d\n", x); 10230 switch (x) { 10231 case 14400: 10232 p->t38.their_parms.rate = AST_T38_RATE_14400; 10233 break; 10234 case 12000: 10235 p->t38.their_parms.rate = AST_T38_RATE_12000; 10236 break; 10237 case 9600: 10238 p->t38.their_parms.rate = AST_T38_RATE_9600; 10239 break; 10240 case 7200: 10241 p->t38.their_parms.rate = AST_T38_RATE_7200; 10242 break; 10243 case 4800: 10244 p->t38.their_parms.rate = AST_T38_RATE_4800; 10245 break; 10246 case 2400: 10247 p->t38.their_parms.rate = AST_T38_RATE_2400; 10248 break; 10249 } 10250 found = TRUE; 10251 } else if ((sscanf(attrib, "t38faxversion:%30u", &x) == 1)) { 10252 ast_debug(3, "FaxVersion: %u\n", x); 10253 p->t38.their_parms.version = x; 10254 found = TRUE; 10255 } else if ((sscanf(attrib, "t38faxmaxdatagram:%30u", &x) == 1) || (sscanf(attrib, "t38maxdatagram:%30u", &x) == 1)) { 10256 /* override the supplied value if the configuration requests it */ 10257 if (((signed int) p->t38_maxdatagram >= 0) && ((unsigned int) p->t38_maxdatagram > x)) { 10258 ast_debug(1, "Overriding T38FaxMaxDatagram '%d' with '%d'\n", x, p->t38_maxdatagram); 10259 x = p->t38_maxdatagram; 10260 } 10261 ast_debug(3, "FaxMaxDatagram: %u\n", x); 10262 ast_udptl_set_far_max_datagram(p->udptl, x); 10263 found = TRUE; 10264 } else if ((strncmp(attrib, "t38faxfillbitremoval", 20) == 0)) { 10265 if (sscanf(attrib, "t38faxfillbitremoval:%30u", &x) == 1) { 10266 ast_debug(3, "FillBitRemoval: %d\n", x); 10267 if (x == 1) { 10268 p->t38.their_parms.fill_bit_removal = TRUE; 10269 } 10270 } else { 10271 ast_debug(3, "FillBitRemoval\n"); 10272 p->t38.their_parms.fill_bit_removal = TRUE; 10273 } 10274 found = TRUE; 10275 } else if ((strncmp(attrib, "t38faxtranscodingmmr", 20) == 0)) { 10276 if (sscanf(attrib, "t38faxtranscodingmmr:%30u", &x) == 1) { 10277 ast_debug(3, "Transcoding MMR: %d\n", x); 10278 if (x == 1) { 10279 p->t38.their_parms.transcoding_mmr = TRUE; 10280 } 10281 } else { 10282 ast_debug(3, "Transcoding MMR\n"); 10283 p->t38.their_parms.transcoding_mmr = TRUE; 10284 } 10285 found = TRUE; 10286 } else if ((strncmp(attrib, "t38faxtranscodingjbig", 21) == 0)) { 10287 if (sscanf(attrib, "t38faxtranscodingjbig:%30u", &x) == 1) { 10288 ast_debug(3, "Transcoding JBIG: %d\n", x); 10289 if (x == 1) { 10290 p->t38.their_parms.transcoding_jbig = TRUE; 10291 } 10292 } else { 10293 ast_debug(3, "Transcoding JBIG\n"); 10294 p->t38.their_parms.transcoding_jbig = TRUE; 10295 } 10296 found = TRUE; 10297 } else if ((sscanf(attrib, "t38faxratemanagement:%255s", s) == 1)) { 10298 ast_debug(3, "RateManagement: %s\n", s); 10299 if (!strcasecmp(s, "localTCF")) 10300 p->t38.their_parms.rate_management = AST_T38_RATE_MANAGEMENT_LOCAL_TCF; 10301 else if (!strcasecmp(s, "transferredTCF")) 10302 p->t38.their_parms.rate_management = AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF; 10303 found = TRUE; 10304 } else if ((sscanf(attrib, "t38faxudpec:%255s", s) == 1)) { 10305 ast_debug(3, "UDP EC: %s\n", s); 10306 if (!strcasecmp(s, "t38UDPRedundancy")) { 10307 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY); 10308 } else if (!strcasecmp(s, "t38UDPFEC")) { 10309 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC); 10310 } else { 10311 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 10312 } 10313 found = TRUE; 10314 } 10315 10316 return found; 10317 }
| static int process_sdp_a_sendonly | ( | const char * | a, | |
| int * | sendonly | |||
| ) | [static] |
Definition at line 10005 of file chan_sip.c.
Referenced by process_sdp().
10006 { 10007 int found = FALSE; 10008 10009 if (!strcasecmp(a, "sendonly")) { 10010 if (*sendonly == -1) 10011 *sendonly = 1; 10012 found = TRUE; 10013 } else if (!strcasecmp(a, "inactive")) { 10014 if (*sendonly == -1) 10015 *sendonly = 2; 10016 found = TRUE; 10017 } else if (!strcasecmp(a, "sendrecv")) { 10018 if (*sendonly == -1) 10019 *sendonly = 0; 10020 found = TRUE; 10021 } 10022 return found; 10023 }
| 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 10155 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().
10156 { 10157 int found = FALSE; 10158 int codec; 10159 char mimeSubtype[128]; 10160 unsigned int sample_rate; 10161 char *red_cp; 10162 int debug = sip_debug_test_pvt(p); 10163 10164 if (sscanf(a, "rtpmap: %30u %127[^/]/%30u", &codec, mimeSubtype, &sample_rate) == 3) { 10165 /* We have a rtpmap to handle */ 10166 if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 10167 if (!strncasecmp(mimeSubtype, "T140", 4)) { /* Text */ 10168 if (p->trtp) { 10169 /* ast_verbose("Adding t140 mimeSubtype to textrtp struct\n"); */ 10170 ast_rtp_codecs_payloads_set_rtpmap_type_rate(newtextrtp, NULL, codec, "text", mimeSubtype, 0, sample_rate); 10171 found = TRUE; 10172 } 10173 } else if (!strncasecmp(mimeSubtype, "RED", 3)) { /* Text with Redudancy */ 10174 if (p->trtp) { 10175 ast_rtp_codecs_payloads_set_rtpmap_type_rate(newtextrtp, NULL, codec, "text", mimeSubtype, 0, sample_rate); 10176 sprintf(red_fmtp, "fmtp:%d ", codec); 10177 if (debug) 10178 ast_verbose("RED submimetype has payload type: %d\n", codec); 10179 found = TRUE; 10180 } 10181 } 10182 } else { 10183 if (debug) 10184 ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec); 10185 } 10186 } else if (!strncmp(a, red_fmtp, strlen(red_fmtp))) { 10187 /* count numbers of generations in fmtp */ 10188 red_cp = &red_fmtp[strlen(red_fmtp)]; 10189 strncpy(red_fmtp, a, 100); 10190 10191 sscanf(red_cp, "%30u", &red_data_pt[*red_num_gen]); 10192 red_cp = strtok(red_cp, "/"); 10193 while (red_cp && (*red_num_gen)++ < AST_RED_MAX_GENERATION) { 10194 sscanf(red_cp, "%30u", &red_data_pt[*red_num_gen]); 10195 red_cp = strtok(NULL, "/"); 10196 } 10197 red_cp = red_fmtp; 10198 found = TRUE; 10199 } 10200 10201 return found; 10202 }
| 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 10121 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().
10122 { 10123 int found = FALSE; 10124 int codec; 10125 char mimeSubtype[128]; 10126 unsigned int sample_rate; 10127 int debug = sip_debug_test_pvt(p); 10128 10129 if (sscanf(a, "rtpmap: %30u %127[^/]/%30u", &codec, mimeSubtype, &sample_rate) == 3) { 10130 /* We have a rtpmap to handle */ 10131 if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 10132 /* Note: should really look at the '#chans' params too */ 10133 if (!strncasecmp(mimeSubtype, "H26", 3) || !strncasecmp(mimeSubtype, "MP4", 3)) { 10134 if (!(ast_rtp_codecs_payloads_set_rtpmap_type_rate(newvideortp, NULL, codec, "video", mimeSubtype, 0, sample_rate))) { 10135 if (debug) 10136 ast_verbose("Found video description format %s for ID %d\n", mimeSubtype, codec); 10137 //found_rtpmap_codecs[last_rtpmap_codec] = codec; 10138 (*last_rtpmap_codec)++; 10139 found = TRUE; 10140 } else { 10141 ast_rtp_codecs_payloads_unset(newvideortp, NULL, codec); 10142 if (debug) 10143 ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec); 10144 } 10145 } 10146 } else { 10147 if (debug) 10148 ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec); 10149 } 10150 } 10151 10152 return found; 10153 }
| static int process_sdp_c | ( | const char * | c, | |
| struct ast_sockaddr * | addr | |||
| ) | [static] |
Definition at line 9978 of file chan_sip.c.
References ast_log(), ast_sockaddr_resolve_first_af(), FALSE, LOG_WARNING, and TRUE.
Referenced by process_sdp().
09979 { 09980 char proto[4], host[258]; 09981 int af; 09982 09983 /* Check for Media-description-level-address */ 09984 if (sscanf(c, "IN %3s %255s", proto, host) == 2) { 09985 if (!strcmp("IP4", proto)) { 09986 af = AF_INET; 09987 } else if (!strcmp("IP6", proto)) { 09988 af = AF_INET6; 09989 } else { 09990 ast_log(LOG_WARNING, "Unknown protocol '%s'.\n", proto); 09991 return FALSE; 09992 } 09993 if (ast_sockaddr_resolve_first_af(addr, host, 0, af)) { 09994 ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in c= line, '%s'\n", c); 09995 return FALSE; 09996 } 09997 return TRUE; 09998 } else { 09999 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 10000 return FALSE; 10001 } 10002 return FALSE; 10003 }
| static int process_sdp_o | ( | const char * | o, | |
| struct sip_pvt * | p | |||
| ) | [static] |
Definition at line 9899 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().
09900 { 09901 char *o_copy; 09902 char *token; 09903 int64_t rua_version; 09904 09905 /* Store the SDP version number of remote UA. This will allow us to 09906 distinguish between session modifications and session refreshes. If 09907 the remote UA does not send an incremented SDP version number in a 09908 subsequent RE-INVITE then that means its not changing media session. 09909 The RE-INVITE may have been sent to update connected party, remote 09910 target or to refresh the session (Session-Timers). Asterisk must not 09911 change media session and increment its own version number in answer 09912 SDP in this case. */ 09913 09914 p->session_modify = TRUE; 09915 09916 if (ast_strlen_zero(o)) { 09917 ast_log(LOG_WARNING, "SDP syntax error. SDP without an o= line\n"); 09918 return FALSE; 09919 } 09920 09921 o_copy = ast_strdupa(o); 09922 token = strsep(&o_copy, " "); /* Skip username */ 09923 if (!o_copy) { 09924 ast_log(LOG_WARNING, "SDP syntax error in o= line username\n"); 09925 return FALSE; 09926 } 09927 token = strsep(&o_copy, " "); /* Skip session-id */ 09928 if (!o_copy) { 09929 ast_log(LOG_WARNING, "SDP syntax error in o= line session-id\n"); 09930 return FALSE; 09931 } 09932 token = strsep(&o_copy, " "); /* Version */ 09933 if (!o_copy) { 09934 ast_log(LOG_WARNING, "SDP syntax error in o= line\n"); 09935 return FALSE; 09936 } 09937 if (!sscanf(token, "%30" SCNd64, &rua_version)) { 09938 ast_log(LOG_WARNING, "SDP syntax error in o= line version\n"); 09939 return FALSE; 09940 } 09941 09942 /* we need to check the SDP version number the other end sent us; 09943 * our rules for deciding what to accept are a bit complex. 09944 * 09945 * 1) if 'ignoresdpversion' has been set for this dialog, then 09946 * we will just accept whatever they sent and assume it is 09947 * a modification of the session, even if it is not 09948 * 2) otherwise, if this is the first SDP we've seen from them 09949 * we accept it 09950 * 3) otherwise, if the new SDP version number is higher than the 09951 * old one, we accept it 09952 * 4) otherwise, if this SDP is in response to us requesting a switch 09953 * to T.38, we accept the SDP, but also generate a warning message 09954 * that this peer should have the 'ignoresdpversion' option set, 09955 * because it is not following the SDP offer/answer RFC; if we did 09956 * not request a switch to T.38, then we stop parsing the SDP, as it 09957 * has not changed from the previous version 09958 */ 09959 09960 if (ast_test_flag(&p->flags[1], SIP_PAGE2_IGNORESDPVERSION) || 09961 (p->sessionversion_remote < 0) || 09962 (p->sessionversion_remote < rua_version)) { 09963 p->sessionversion_remote = rua_version; 09964 } else { 09965 if (p->t38.state == T38_LOCAL_REINVITE) { 09966 p->sessionversion_remote = rua_version; 09967 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); 09968 } else { 09969 p->session_modify = FALSE; 09970 ast_debug(2, "Call %s responded to our reinvite without changing SDP version; ignoring SDP.\n", p->callid); 09971 return FALSE; 09972 } 09973 } 09974 09975 return TRUE; 09976 }
| 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 8247 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().
08248 { 08249 struct sip_via *via = parse_via(get_header(req, "Via")); 08250 08251 if (!via) { 08252 ast_log(LOG_ERROR, "error processing via header\n"); 08253 return -1; 08254 } 08255 08256 if (via->maddr) { 08257 if (ast_sockaddr_resolve_first_transport(&p->sa, via->maddr, PARSE_PORT_FORBID, p->socket.type)) { 08258 ast_log(LOG_WARNING, "Can't find address for maddr '%s'\n", via->maddr); 08259 ast_log(LOG_ERROR, "error processing via header\n"); 08260 free_via(via); 08261 return -1; 08262 } 08263 08264 if (addr_is_multicast(&p->sa)) { 08265 setsockopt(sipsock, IPPROTO_IP, IP_MULTICAST_TTL, &via->ttl, sizeof(via->ttl)); 08266 } 08267 } 08268 08269 ast_sockaddr_set_port(&p->sa, via->port ? via->port : STANDARD_SIP_PORT); 08270 08271 free_via(via); 08272 return 0; 08273 }
| 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 3402 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().
03403 { 03404 char *mutable_proxy, *sep, *name; 03405 int allocated = 0; 03406 03407 if (!dest) { 03408 dest = ao2_alloc(sizeof(struct sip_proxy), NULL); 03409 if (!dest) { 03410 ast_log(LOG_WARNING, "Unable to allocate config storage for proxy\n"); 03411 return NULL; 03412 } 03413 allocated = 1; 03414 } 03415 03416 /* Format is: [transport://]name[:port][,force] */ 03417 mutable_proxy = ast_skip_blanks(ast_strdupa(proxy)); 03418 sep = strchr(mutable_proxy, ','); 03419 if (sep) { 03420 *sep++ = '\0'; 03421 dest->force = !strncasecmp(ast_skip_blanks(sep), "force", 5); 03422 } else { 03423 dest->force = FALSE; 03424 } 03425 03426 sip_parse_host(mutable_proxy, sipconf_lineno, &name, &dest->port, &dest->transport); 03427 03428 /* Check that there is a name at all */ 03429 if (ast_strlen_zero(name)) { 03430 if (allocated) { 03431 ao2_ref(dest, -1); 03432 } else { 03433 dest->name[0] = '\0'; 03434 } 03435 return NULL; 03436 } 03437 ast_copy_string(dest->name, name, sizeof(dest->name)); 03438 03439 /* Resolve host immediately */ 03440 proxy_update(dest); 03441 03442 return dest; 03443 }
| static int proxy_update | ( | struct sip_proxy * | proxy | ) | [static] |
Resolve DNS srv name or host name in a sip_proxy structure
Definition at line 3378 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().
03379 { 03380 /* if it's actually an IP address and not a name, 03381 there's no need for a managed lookup */ 03382 if (!ast_sockaddr_parse(&proxy->ip, proxy->name, 0)) { 03383 /* Ok, not an IP address, then let's check if it's a domain or host */ 03384 /* XXX Todo - if we have proxy port, don't do SRV */ 03385 proxy->ip.ss.ss_family = get_address_family_filter(SIP_TRANSPORT_UDP); /* Filter address family */ 03386 if (ast_get_ip_or_srv(&proxy->ip, proxy->name, sip_cfg.srvlookup ? "_sip._udp" : NULL) < 0) { 03387 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", proxy->name); 03388 return FALSE; 03389 } 03390 03391 } 03392 03393 ast_sockaddr_set_port(&proxy->ip, proxy->port); 03394 03395 proxy->last_dnsupdate = time(NULL); 03396 return TRUE; 03397 }
| static int publish_expire | ( | const void * | data | ) | [static] |
Definition at line 1020 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().
01021 { 01022 struct sip_esc_entry *esc_entry = (struct sip_esc_entry *) data; 01023 struct event_state_compositor *esc = get_esc(esc_entry->event); 01024 01025 ast_assert(esc != NULL); 01026 01027 ao2_unlink(esc->compositor, esc_entry); 01028 ao2_ref(esc_entry, -1); 01029 return 0; 01030 }
| static void pvt_set_needdestroy | ( | struct sip_pvt * | pvt, | |
| const char * | reason | |||
| ) | [inline, static] |
Definition at line 3343 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().
03344 { 03345 if (pvt->final_destruction_scheduled) { 03346 return; /* This is already scheduled for final destruction, let the scheduler take care of it. */ 03347 } 03348 append_history(pvt, "NeedDestroy", "Setting needdestroy because %s", reason); 03349 pvt->needdestroy = 1; 03350 }
| static int read_raw_content_length | ( | const char * | message | ) | [static] |
Get the content length from an unparsed SIP message.
Definition at line 2689 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().
02690 { 02691 char *content_length_str; 02692 int content_length = -1; 02693 02694 struct ast_str *msg_copy; 02695 char *msg; 02696 02697 /* Using a ast_str because lws2sws takes one of those */ 02698 if (!(msg_copy = ast_str_create(strlen(message) + 1))) { 02699 return -1; 02700 } 02701 ast_str_set(&msg_copy, 0, "%s", message); 02702 02703 if (sip_cfg.pedanticsipchecking) { 02704 lws2sws(msg_copy); 02705 } 02706 02707 msg = ast_str_buffer(msg_copy); 02708 02709 /* Let's find a Content-Length header */ 02710 if ((content_length_str = strcasestr(msg, "\nContent-Length:"))) { 02711 content_length_str += sizeof("\nContent-Length:") - 1; 02712 } else if ((content_length_str = strcasestr(msg, "\nl:"))) { 02713 content_length_str += sizeof("\nl:") - 1; 02714 } else { 02715 /* RFC 3261 18.3 02716 * "In the case of stream-oriented transports such as TCP, the Content- 02717 * Length header field indicates the size of the body. The Content- 02718 * Length header field MUST be used with stream oriented transports." 02719 */ 02720 goto done; 02721 } 02722 02723 /* Double-check that this is a complete header */ 02724 if (!strchr(content_length_str, '\n')) { 02725 goto done; 02726 } 02727 02728 if (sscanf(content_length_str, "%30d", &content_length) != 1) { 02729 content_length = -1; 02730 } 02731 02732 done: 02733 ast_free(msg_copy); 02734 return content_length; 02735 }
| 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 5298 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().
05299 { 05300 struct sip_peer *peer = NULL; 05301 struct ast_variable *var = NULL; 05302 struct ast_variable *varregs = NULL; 05303 char ipaddr[INET6_ADDRSTRLEN]; 05304 int realtimeregs = ast_check_realtime("sipregs"); 05305 05306 if (addr) { 05307 ast_copy_string(ipaddr, ast_sockaddr_stringify_addr(addr), sizeof(ipaddr)); 05308 } else { 05309 ipaddr[0] = '\0'; 05310 } 05311 05312 if (newpeername && realtime_peer_by_name(&newpeername, addr, ipaddr, &var, realtimeregs ? &varregs : NULL)) { 05313 ; 05314 } else if (addr && realtime_peer_by_addr(&newpeername, addr, ipaddr, &var, realtimeregs ? &varregs : NULL)) { 05315 ; 05316 } else { 05317 return NULL; 05318 } 05319 05320 /* If we're looking for users, don't return peers (although this check 05321 * should probably be done in realtime_peer_by_* instead...) */ 05322 if (which_objects == FINDUSERS) { 05323 struct ast_variable *tmp; 05324 for (tmp = var; tmp; tmp = tmp->next) { 05325 if (!strcasecmp(tmp->name, "type") && (!strcasecmp(tmp->value, "peer"))) { 05326 goto cleanup; 05327 } 05328 } 05329 } 05330 05331 /* Peer found in realtime, now build it in memory */ 05332 peer = build_peer(newpeername, var, varregs, TRUE, devstate_only); 05333 if (!peer) { 05334 goto cleanup; 05335 } 05336 05337 /* Previous versions of Asterisk did not require the type field to be 05338 * set for real time peers. This statement preserves that behavior. */ 05339 if (peer->type == 0) { 05340 if (which_objects == FINDUSERS) { 05341 peer->type = SIP_TYPE_USER; 05342 } else if (which_objects == FINDPEERS) { 05343 peer->type = SIP_TYPE_PEER; 05344 } else { 05345 peer->type = SIP_TYPE_PEER | SIP_TYPE_USER; 05346 } 05347 } 05348 05349 ast_debug(3, "-REALTIME- loading peer from database to memory. Name: %s. Peer objects: %d\n", peer->name, rpeerobjs); 05350 05351 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && !devstate_only) { 05352 /* Cache peer */ 05353 ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS); 05354 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 05355 AST_SCHED_REPLACE_UNREF(peer->expire, sched, sip_cfg.rtautoclear * 1000, expire_register, peer, 05356 unref_peer(_data, "remove registration ref"), 05357 unref_peer(peer, "remove registration ref"), 05358 ref_peer(peer, "add registration ref")); 05359 } 05360 ao2_t_link(peers, peer, "link peer into peers table"); 05361 if (!ast_sockaddr_isnull(&peer->addr)) { 05362 ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table"); 05363 } 05364 } 05365 peer->is_realtime = 1; 05366 05367 cleanup: 05368 ast_variables_destroy(var); 05369 ast_variables_destroy(varregs); 05370 return peer; 05371 }
| 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 5229 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().
05230 { 05231 char portstring[6]; /* up to 5 digits plus null terminator */ 05232 ast_copy_string(portstring, ast_sockaddr_stringify_port(addr), sizeof(portstring)); 05233 05234 /* We're not finding this peer by this name anymore. Reset it. */ 05235 *name = NULL; 05236 05237 /* First check for fixed IP hosts */ 05238 if ((*var = ast_load_realtime("sippeers", "host", ipaddr, "port", portstring, SENTINEL))) { 05239 ; 05240 /* Check for registered hosts (in sipregs) */ 05241 } else if (varregs && (*varregs = ast_load_realtime("sipregs", "ipaddr", ipaddr, "port", portstring, SENTINEL)) && 05242 (*var = realtime_peer_get_sippeer_helper(name, varregs))) { 05243 ; 05244 /* Check for registered hosts (in sippeers) */ 05245 } else if (!varregs && (*var = ast_load_realtime("sippeers", "ipaddr", ipaddr, "port", portstring, SENTINEL))) { 05246 ; 05247 /* We couldn't match on ipaddress and port, so we need to check if port is insecure */ 05248 } else if ((*var = get_insecure_variable_from_sippeers("host", ipaddr))) { 05249 ; 05250 /* Same as above, but try the IP address field (in sipregs) 05251 * Observe that it fetches the name/var at the same time, without the 05252 * realtime_peer_get_sippeer_helper. Also note that it is quite inefficient. 05253 * Avoid sipregs if possible. */ 05254 } else if (varregs && (*varregs = get_insecure_variable_from_sipregs("ipaddr", ipaddr, var))) { 05255 ; 05256 /* Same as above, but try the IP address field (in sippeers) */ 05257 } else if (!varregs && (*var = get_insecure_variable_from_sippeers("ipaddr", ipaddr))) { 05258 ; 05259 } 05260 05261 /* Nothing found? */ 05262 if (!*var) { 05263 return 0; 05264 } 05265 05266 /* Check peer name. It must not be empty. There may exist a 05267 * different match that does have a name, but it's too late for 05268 * that now. */ 05269 if (!*name && !(*name = get_name_from_variable(*var))) { 05270 ast_log(LOG_WARNING, "Found peer for IP %s but it has no name\n", ipaddr); 05271 ast_variables_destroy(*var); 05272 *var = NULL; 05273 if (varregs && *varregs) { 05274 ast_variables_destroy(*varregs); 05275 *varregs = NULL; 05276 } 05277 return 0; 05278 } 05279 05280 /* Make sure varregs is populated if var is. The inverse, 05281 * ensuring that var is set when varregs is, is taken 05282 * care of by realtime_peer_get_sippeer_helper(). */ 05283 if (varregs && !*varregs) { 05284 *varregs = ast_load_realtime("sipregs", "name", *name, SENTINEL); 05285 } 05286 return 1; 05287 }
| 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 5157 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().
05158 { 05159 /* Peer by name and host=dynamic */ 05160 if ((*var = ast_load_realtime("sippeers", "name", *name, "host", "dynamic", SENTINEL))) { 05161 ; 05162 /* Peer by name and host=IP */ 05163 } else if (addr && !(*var = ast_load_realtime("sippeers", "name", *name, "host", ipaddr, SENTINEL))) { 05164 ; 05165 /* Peer by name and host=HOSTNAME */ 05166 } else if ((*var = ast_load_realtime("sippeers", "name", *name, SENTINEL))) { 05167 /*!\note 05168 * If this one loaded something, then we need to ensure that the host 05169 * field matched. The only reason why we can't have this as a criteria 05170 * is because we only have the IP address and the host field might be 05171 * set as a name (and the reverse PTR might not match). 05172 */ 05173 if (addr) { 05174 struct ast_variable *tmp; 05175 for (tmp = *var; tmp; tmp = tmp->next) { 05176 if (!strcasecmp(tmp->name, "host")) { 05177 struct ast_sockaddr *addrs = NULL; 05178 05179 if (ast_sockaddr_resolve(&addrs, 05180 tmp->value, 05181 PARSE_PORT_FORBID, 05182 get_address_family_filter(SIP_TRANSPORT_UDP)) <= 0 || 05183 ast_sockaddr_cmp(&addrs[0], addr)) { 05184 /* No match */ 05185 ast_variables_destroy(*var); 05186 *var = NULL; 05187 } 05188 ast_free(addrs); 05189 break; 05190 } 05191 } 05192 } 05193 } 05194 05195 /* Did we find anything? */ 05196 if (*var) { 05197 if (varregs) { 05198 *varregs = ast_load_realtime("sipregs", "name", *name, SENTINEL); 05199 } 05200 return 1; 05201 } 05202 return 0; 05203 }
| static struct ast_variable* realtime_peer_get_sippeer_helper | ( | const char ** | name, | |
| struct ast_variable ** | varregs | |||
| ) | [static, read] |
Definition at line 5211 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().
05211 { 05212 struct ast_variable *var = NULL; 05213 const char *old_name = *name; 05214 *name = get_name_from_variable(*varregs); 05215 if (!*name || !(var = ast_load_realtime("sippeers", "name", *name, SENTINEL))) { 05216 if (!*name) { 05217 ast_log(LOG_WARNING, "Found sipreg but it has no name\n"); 05218 } 05219 ast_variables_destroy(*varregs); 05220 *varregs = NULL; 05221 *name = old_name; 05222 } 05223 return var; 05224 }
| 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 4867 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().
04868 { 04869 char port[10]; 04870 char ipaddr[INET6_ADDRSTRLEN]; 04871 char regseconds[20]; 04872 char *tablename = NULL; 04873 char str_lastms[20]; 04874 04875 const char *sysname = ast_config_AST_SYSTEM_NAME; 04876 char *syslabel = NULL; 04877 04878 time_t nowtime = time(NULL) + expirey; 04879 const char *fc = fullcontact ? "fullcontact" : NULL; 04880 04881 int realtimeregs = ast_check_realtime("sipregs"); 04882 04883 tablename = realtimeregs ? "sipregs" : "sippeers"; 04884 04885 04886 snprintf(str_lastms, sizeof(str_lastms), "%d", lastms); 04887 snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); /* Expiration time */ 04888 ast_copy_string(ipaddr, ast_sockaddr_isnull(addr) ? "" : ast_sockaddr_stringify_addr(addr), sizeof(ipaddr)); 04889 ast_copy_string(port, ast_sockaddr_port(addr) ? ast_sockaddr_stringify_port(addr) : "", sizeof(port)); 04890 04891 if (ast_strlen_zero(sysname)) /* No system name, disable this */ 04892 sysname = NULL; 04893 else if (sip_cfg.rtsave_sysname) 04894 syslabel = "regserver"; 04895 04896 /* XXX IMPORTANT: Anytime you add a new parameter to be updated, you 04897 * must also add it to contrib/scripts/asterisk.ldap-schema, 04898 * contrib/scripts/asterisk.ldif, 04899 * and to configs/res_ldap.conf.sample as described in 04900 * bugs 15156 and 15895 04901 */ 04902 if (fc) { 04903 ast_update_realtime(tablename, "name", peername, "ipaddr", ipaddr, 04904 "port", port, "regseconds", regseconds, 04905 deprecated_username ? "username" : "defaultuser", defaultuser, 04906 "useragent", useragent, "lastms", str_lastms, 04907 fc, fullcontact, syslabel, sysname, SENTINEL); /* note fc and syslabel _can_ be NULL */ 04908 } else { 04909 ast_update_realtime(tablename, "name", peername, "ipaddr", ipaddr, 04910 "port", port, "regseconds", regseconds, 04911 "useragent", useragent, "lastms", str_lastms, 04912 deprecated_username ? "username" : "defaultuser", defaultuser, 04913 syslabel, sysname, SENTINEL); /* note syslabel _can_ be NULL */ 04914 } 04915 }
| static void receive_message | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Receive SIP MESSAGE method messages.
Definition at line 16911 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().
16912 { 16913 char buf[1400]; 16914 char *bufp; 16915 struct ast_frame f; 16916 const char *content_type = get_header(req, "Content-Type"); 16917 16918 if (strncmp(content_type, "text/plain", strlen("text/plain"))) { /* No text/plain attachment */ 16919 transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */ 16920 if (!p->owner) 16921 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16922 return; 16923 } 16924 16925 if (get_msg_text(buf, sizeof(buf), req)) { 16926 ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); 16927 transmit_response(p, "500 Internal Server Error", req); 16928 if (!p->owner) { 16929 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16930 } 16931 return; 16932 } 16933 16934 /* Strip trailing line feeds from message body. (get_msg_text may add 16935 * a trailing linefeed and we don't need any at the end) */ 16936 bufp = buf + strlen(buf); 16937 while (--bufp >= buf && *bufp == '\n') { 16938 *bufp = '\0'; 16939 } 16940 16941 if (p->owner) { 16942 if (sip_debug_test_pvt(p)) 16943 ast_verbose("SIP Text message received: '%s'\n", buf); 16944 memset(&f, 0, sizeof(f)); 16945 f.frametype = AST_FRAME_TEXT; 16946 f.subclass.integer = 0; 16947 f.offset = 0; 16948 f.data.ptr = buf; 16949 f.datalen = strlen(buf) + 1; 16950 ast_queue_frame(p->owner, &f); 16951 transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */ 16952 return; 16953 } 16954 16955 /* Message outside of a call, we do not support that */ 16956 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); 16957 transmit_response(p, "405 Method Not Allowed", req); 16958 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16959 return; 16960 }
| static struct sip_peer* ref_peer | ( | struct sip_peer * | peer, | |
| char * | tag | |||
| ) | [static, read] |
Definition at line 3134 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().
03135 { 03136 ao2_t_ref(peer, 1, tag); 03137 return peer; 03138 }
| 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 3216 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().
03217 { 03218 struct sip_proxy *old_obproxy = pvt->outboundproxy; 03219 /* The sip_cfg.outboundproxy is statically allocated, and so 03220 * we don't ever need to adjust refcounts for it 03221 */ 03222 if (proxy && proxy != &sip_cfg.outboundproxy) { 03223 ao2_ref(proxy, +1); 03224 } 03225 pvt->outboundproxy = proxy; 03226 if (old_obproxy && old_obproxy != &sip_cfg.outboundproxy) { 03227 ao2_ref(old_obproxy, -1); 03228 } 03229 }
| static const char * referstatus2str | ( | enum referstatus | rstatus | ) | [static] |
Convert transfer status to string.
Definition at line 3338 of file chan_sip.c.
References map_x_s().
Referenced by show_channels_cb().
03339 { 03340 return map_x_s(referstatusstrings, rstatus, ""); 03341 }
| static void reg_source_db | ( | struct sip_peer * | peer | ) | [static] |
Get registration details from Asterisk DB.
Definition at line 14329 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().
14330 { 14331 char data[256]; 14332 struct ast_sockaddr sa; 14333 int expire; 14334 char full_addr[128]; 14335 AST_DECLARE_APP_ARGS(args, 14336 AST_APP_ARG(addr); 14337 AST_APP_ARG(port); 14338 AST_APP_ARG(expiry_str); 14339 AST_APP_ARG(username); 14340 AST_APP_ARG(contact); 14341 ); 14342 14343 /* If read-only RT backend, then refresh from local DB cache */ 14344 if (peer->rt_fromcontact && sip_cfg.peer_rtupdate) { 14345 return; 14346 } 14347 if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) { 14348 return; 14349 } 14350 14351 AST_NONSTANDARD_RAW_ARGS(args, data, ':'); 14352 14353 snprintf(full_addr, sizeof(full_addr), "%s:%s", args.addr, args.port); 14354 14355 if (!ast_sockaddr_parse(&sa, full_addr, 0)) { 14356 return; 14357 } 14358 14359 if (args.expiry_str) { 14360 expire = atoi(args.expiry_str); 14361 } else { 14362 return; 14363 } 14364 14365 if (args.username) { 14366 ast_string_field_set(peer, username, args.username); 14367 } 14368 if (args.contact) { 14369 ast_string_field_set(peer, fullcontact, args.contact); 14370 } 14371 14372 ast_debug(2, "SIP Seeding peer from astdb: '%s' at %s@%s for %d\n", 14373 peer->name, peer->username, ast_sockaddr_stringify_host(&sa), expire); 14374 14375 ast_sockaddr_copy(&peer->addr, &sa); 14376 if (peer->maxms) { 14377 /* Don't poke peer immediately, just schedule it within qualifyfreq */ 14378 AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, 14379 ast_random() % ((peer->qualifyfreq) ? peer->qualifyfreq : global_qualifyfreq) + 1, 14380 sip_poke_peer_s, peer, 14381 unref_peer(_data, "removing poke peer ref"), 14382 unref_peer(peer, "removing poke peer ref"), 14383 ref_peer(peer, "adding poke peer ref")); 14384 } 14385 AST_SCHED_REPLACE_UNREF(peer->expire, sched, (expire + 10) * 1000, expire_register, peer, 14386 unref_peer(_data, "remove registration ref"), 14387 unref_peer(peer, "remove registration ref"), 14388 ref_peer(peer, "add registration ref")); 14389 register_peer_exten(peer, TRUE); 14390 }
| static void register_peer_exten | ( | struct sip_peer * | peer, | |
| int | onoff | |||
| ) | [static] |
Automatically add peer extension to dial plan.
Definition at line 4918 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().
04919 { 04920 char multi[256]; 04921 char *stringp, *ext, *context; 04922 struct pbx_find_info q = { .stacklen = 0 }; 04923 04924 /* XXX note that sip_cfg.regcontext is both a global 'enable' flag and 04925 * the name of the global regexten context, if not specified 04926 * individually. 04927 */ 04928 if (ast_strlen_zero(sip_cfg.regcontext)) 04929 return; 04930 04931 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 04932 stringp = multi; 04933 while ((ext = strsep(&stringp, "&"))) { 04934 if ((context = strchr(ext, '@'))) { 04935 *context++ = '\0'; /* split ext@context */ 04936 if (!ast_context_find(context)) { 04937 ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context); 04938 continue; 04939 } 04940 } else { 04941 context = sip_cfg.regcontext; 04942 } 04943 if (onoff) { 04944 if (!ast_exists_extension(NULL, context, ext, 1, NULL)) { 04945 ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop", 04946 ast_strdup(peer->name), ast_free_ptr, "SIP"); 04947 } 04948 } else if (pbx_find_extension(NULL, NULL, &q, context, ext, 1, NULL, "", E_MATCH)) { 04949 ast_context_remove_extension(context, ext, 1, NULL); 04950 } 04951 } 04952 }
| 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 15313 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().
15315 { 15316 enum check_auth_result res = AUTH_NOT_FOUND; 15317 struct sip_peer *peer; 15318 char tmp[256]; 15319 char *c, *name, *unused_password, *domain; 15320 char *uri2 = ast_strdupa(uri); 15321 int send_mwi = 0; 15322 15323 terminate_uri(uri2); 15324 15325 ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp)); 15326 15327 c = get_in_brackets(tmp); 15328 c = remove_uri_parameters(c); 15329 15330 if (parse_uri_legacy_check(c, "sip:,sips:", &name, &unused_password, &domain, NULL)) { 15331 ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_sockaddr_stringify_addr(addr)); 15332 return -1; 15333 } 15334 15335 SIP_PEDANTIC_DECODE(name); 15336 SIP_PEDANTIC_DECODE(domain); 15337 15338 extract_host_from_hostport(&domain); 15339 15340 if (ast_strlen_zero(domain)) { 15341 /* <sip:name@[EMPTY]>, never good */ 15342 transmit_response(p, "404 Not found", &p->initreq); 15343 return AUTH_UNKNOWN_DOMAIN; 15344 } 15345 15346 if (ast_strlen_zero(name)) { 15347 /* <sip:[EMPTY][@]hostport>, unsure whether valid for 15348 * registration. RFC 3261, 10.2 states: 15349 * "The To header field and the Request-URI field typically 15350 * differ, as the former contains a user name." 15351 * But, Asterisk has always treated the domain-only uri as a 15352 * username: we allow admins to create accounts described by 15353 * domain name. */ 15354 name = domain; 15355 } 15356 15357 /* This here differs from 1.4 and 1.6: the domain matching ACLs were 15358 * skipped if it was a domain-only URI (used as username). Here we treat 15359 * <sip:hostport> as <sip:host@hostport> and won't forget to test the 15360 * domain ACLs against host. */ 15361 if (!AST_LIST_EMPTY(&domain_list)) { 15362 if (!check_sip_domain(domain, NULL, 0)) { 15363 if (sip_cfg.alwaysauthreject) { 15364 transmit_fake_auth_response(p, &p->initreq, XMIT_UNRELIABLE); 15365 } else { 15366 transmit_response(p, "404 Not found (unknown domain)", &p->initreq); 15367 } 15368 return AUTH_UNKNOWN_DOMAIN; 15369 } 15370 } 15371 15372 ast_string_field_set(p, exten, name); 15373 build_contact(p); 15374 if (req->ignore) { 15375 /* Expires is a special case, where we only want to load the peer if this isn't a deregistration attempt */ 15376 const char *expires = get_header(req, "Expires"); 15377 int expire = atoi(expires); 15378 15379 if (ast_strlen_zero(expires)) { /* No expires header; look in Contact */ 15380 if ((expires = strcasestr(get_header(req, "Contact"), ";expires="))) { 15381 expire = atoi(expires + 9); 15382 } 15383 } 15384 if (!ast_strlen_zero(expires) && expire == 0) { 15385 transmit_response_with_date(p, "200 OK", req); 15386 return 0; 15387 } 15388 } 15389 peer = find_peer(name, NULL, TRUE, FINDPEERS, FALSE, 0); 15390 15391 /* If we don't want username disclosure, use the bogus_peer when a user 15392 * is not found. */ 15393 if (!peer && sip_cfg.alwaysauthreject && !sip_cfg.autocreatepeer) { 15394 peer = bogus_peer; 15395 ref_peer(peer, "register_verify: ref the bogus_peer"); 15396 } 15397 15398 if (!(peer && ast_apply_ha(peer->ha, addr))) { 15399 /* Peer fails ACL check */ 15400 if (peer) { 15401 unref_peer(peer, "register_verify: unref_peer: from find_peer operation"); 15402 peer = NULL; 15403 res = AUTH_ACL_FAILED; 15404 } else { 15405 res = AUTH_NOT_FOUND; 15406 } 15407 } 15408 15409 if (peer) { 15410 ao2_lock(peer); 15411 if (!peer->host_dynamic) { 15412 ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name); 15413 res = AUTH_PEER_NOT_DYNAMIC; 15414 } else { 15415 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT_FORCE_RPORT); 15416 if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri2, XMIT_UNRELIABLE, req->ignore))) { 15417 if (sip_cancel_destroy(p)) 15418 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 15419 15420 if (check_request_transport(peer, req)) { 15421 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 15422 transmit_response_with_date(p, "403 Forbidden", req); 15423 res = AUTH_BAD_TRANSPORT; 15424 } else { 15425 15426 /* We have a successful registration attempt with proper authentication, 15427 now, update the peer */ 15428 switch (parse_register_contact(p, peer, req)) { 15429 case PARSE_REGISTER_DENIED: 15430 ast_log(LOG_WARNING, "Registration denied because of contact ACL\n"); 15431 transmit_response_with_date(p, "603 Denied", req); 15432 res = 0; 15433 break; 15434 case PARSE_REGISTER_FAILED: 15435 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 15436 transmit_response_with_date(p, "400 Bad Request", req); 15437 res = 0; 15438 break; 15439 case PARSE_REGISTER_QUERY: 15440 ast_string_field_set(p, fullcontact, peer->fullcontact); 15441 transmit_response_with_date(p, "200 OK", req); 15442 res = 0; 15443 break; 15444 case PARSE_REGISTER_UPDATE: 15445 ast_string_field_set(p, fullcontact, peer->fullcontact); 15446 update_peer(peer, p->expiry); 15447 /* Say OK and ask subsystem to retransmit msg counter */ 15448 transmit_response_with_date(p, "200 OK", req); 15449 send_mwi = 1; 15450 res = 0; 15451 break; 15452 } 15453 } 15454 15455 } 15456 } 15457 ao2_unlock(peer); 15458 } 15459 if (!peer && sip_cfg.autocreatepeer) { 15460 /* Create peer if we have autocreate mode enabled */ 15461 peer = temp_peer(name); 15462 if (peer) { 15463 ao2_t_link(peers, peer, "link peer into peer table"); 15464 if (!ast_sockaddr_isnull(&peer->addr)) { 15465 ao2_t_link(peers_by_ip, peer, "link peer into peers-by-ip table"); 15466 } 15467 ao2_lock(peer); 15468 if (sip_cancel_destroy(p)) 15469 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 15470 switch (parse_register_contact(p, peer, req)) { 15471 case PARSE_REGISTER_DENIED: 15472 ast_log(LOG_WARNING, "Registration denied because of contact ACL\n"); 15473 transmit_response_with_date(p, "403 Forbidden", req); 15474 res = 0; 15475 break; 15476 case PARSE_REGISTER_FAILED: 15477 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 15478 transmit_response_with_date(p, "400 Bad Request", req); 15479 res = 0; 15480 break; 15481 case PARSE_REGISTER_QUERY: 15482 ast_string_field_set(p, fullcontact, peer->fullcontact); 15483 transmit_response_with_date(p, "200 OK", req); 15484 send_mwi = 1; 15485 res = 0; 15486 break; 15487 case PARSE_REGISTER_UPDATE: 15488 ast_string_field_set(p, fullcontact, peer->fullcontact); 15489 /* Say OK and ask subsystem to retransmit msg counter */ 15490 transmit_response_with_date(p, "200 OK", req); 15491 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)); 15492 send_mwi = 1; 15493 res = 0; 15494 break; 15495 } 15496 ao2_unlock(peer); 15497 } 15498 } 15499 if (!res) { 15500 if (send_mwi) { 15501 sip_pvt_unlock(p); 15502 sip_send_mwi_to_peer(peer, 0); 15503 sip_pvt_lock(p); 15504 } else { 15505 update_peer_lastmsgssent(peer, -1, 0); 15506 } 15507 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", peer->name); 15508 } 15509 if (res < 0) { 15510 switch (res) { 15511 case AUTH_SECRET_FAILED: 15512 /* Wrong password in authentication. Go away, don't try again until you fixed it */ 15513 transmit_response(p, "403 Forbidden", &p->initreq); 15514 if (global_authfailureevents) { 15515 const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr)); 15516 const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr)); 15517 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 15518 "ChannelType: SIP\r\n" 15519 "Peer: SIP/%s\r\n" 15520 "PeerStatus: Rejected\r\n" 15521 "Cause: AUTH_SECRET_FAILED\r\n" 15522 "Address: %s\r\n" 15523 "Port: %s\r\n", 15524 name, peer_addr, peer_port); 15525 } 15526 break; 15527 case AUTH_USERNAME_MISMATCH: 15528 /* Username and digest username does not match. 15529 Asterisk uses the From: username for authentication. We need the 15530 devices to use the same authentication user name until we support 15531 proper authentication by digest auth name */ 15532 case AUTH_NOT_FOUND: 15533 case AUTH_PEER_NOT_DYNAMIC: 15534 case AUTH_ACL_FAILED: 15535 if (sip_cfg.alwaysauthreject) { 15536 transmit_fake_auth_response(p, &p->initreq, XMIT_UNRELIABLE); 15537 if (global_authfailureevents) { 15538 const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr)); 15539 const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr)); 15540 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 15541 "ChannelType: SIP\r\n" 15542 "Peer: SIP/%s\r\n" 15543 "PeerStatus: Rejected\r\n" 15544 "Cause: %s\r\n" 15545 "Address: %s\r\n" 15546 "Port: %s\r\n", 15547 name, 15548 res == AUTH_PEER_NOT_DYNAMIC ? "AUTH_PEER_NOT_DYNAMIC" : "URI_NOT_FOUND", 15549 peer_addr, peer_port); 15550 } 15551 } else { 15552 /* URI not found */ 15553 if (res == AUTH_PEER_NOT_DYNAMIC) { 15554 transmit_response(p, "403 Forbidden", &p->initreq); 15555 if (global_authfailureevents) { 15556 const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr)); 15557 const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr)); 15558 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 15559 "ChannelType: SIP\r\n" 15560 "Peer: SIP/%s\r\n" 15561 "PeerStatus: Rejected\r\n" 15562 "Cause: AUTH_PEER_NOT_DYNAMIC\r\n" 15563 "Address: %s\r\n" 15564 "Port: %s\r\n", 15565 name, peer_addr, peer_port); 15566 } 15567 } else { 15568 transmit_response(p, "404 Not found", &p->initreq); 15569 if (global_authfailureevents) { 15570 const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr)); 15571 const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr)); 15572 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 15573 "ChannelType: SIP\r\n" 15574 "Peer: SIP/%s\r\n" 15575 "PeerStatus: Rejected\r\n" 15576 "Cause: %s\r\n" 15577 "Address: %s\r\n" 15578 "Port: %s\r\n", 15579 name, 15580 (res == AUTH_USERNAME_MISMATCH) ? "AUTH_USERNAME_MISMATCH" : "URI_NOT_FOUND", 15581 peer_addr, peer_port); 15582 } 15583 } 15584 } 15585 break; 15586 case AUTH_BAD_TRANSPORT: 15587 default: 15588 break; 15589 } 15590 } 15591 if (peer) { 15592 unref_peer(peer, "register_verify: unref_peer: tossing stack peer pointer at end of func"); 15593 } 15594 15595 return res; 15596 }
| static struct sip_registry* registry_addref | ( | struct sip_registry * | reg, | |
| char * | tag | |||
| ) | [static, read] |
Add object reference to SIP registry.
Definition at line 3320 of file chan_sip.c.
References ast_debug, and ASTOBJ_REF.
Referenced by handle_response_register(), sip_send_all_registers(), and transmit_register().
03321 { 03322 ast_debug(3, "SIP Registry %s: refcount now %d\n", reg->hostname, reg->refcount + 1); 03323 return ASTOBJ_REF(reg); /* Add pointer to registry in packet */ 03324 }
| void * registry_unref | ( | struct sip_registry * | reg, | |
| char * | tag | |||
| ) | [static] |
Definition at line 3312 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().
03313 { 03314 ast_debug(3, "SIP Registry %s: refcount now %d\n", reg->hostname, reg->refcount - 1); 03315 ASTOBJ_UNREF(reg, sip_registry_destroy); 03316 return NULL; 03317 }
| static const char * regstate2str | ( | enum sipregistrystate | regstate | ) | [static] |
Convert registration state status to string.
Definition at line 13601 of file chan_sip.c.
References map_x_s().
Referenced by handle_response_register(), manager_show_registry(), sip_reg_timeout(), and sip_show_registry().
13602 { 13603 return map_x_s(regstatestrings, regstate, "Unknown"); 13604 }
| static int reinvite_timeout | ( | const void * | data | ) | [static] |
Definition at line 6621 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().
06622 { 06623 struct sip_pvt *dialog = (struct sip_pvt *) data; 06624 struct ast_channel *owner = sip_pvt_lock_full(dialog); 06625 dialog->reinviteid = -1; 06626 check_pendings(dialog); 06627 if (owner) { 06628 ast_channel_unlock(owner); 06629 ast_channel_unref(owner); 06630 } 06631 ao2_unlock(dialog); 06632 dialog_unref(dialog, "unref for reinvite timeout"); 06633 return 0; 06634 }
| static int reload | ( | void | ) | [static] |
Part of Asterisk module interface.
Definition at line 30534 of file chan_sip.c.
References sip_reload().
30535 { 30536 if (sip_reload(0, 0, NULL)) 30537 return 0; 30538 return 1; 30539 }
| 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 28672 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_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(), dummy(), 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().
28673 { 28674 struct ast_config *cfg, *ucfg; 28675 struct ast_variable *v; 28676 struct sip_peer *peer; 28677 char *cat, *stringp, *context, *oldregcontext; 28678 char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT]; 28679 struct ast_flags dummy[2]; 28680 struct ast_flags config_flags = { reason == CHANNEL_MODULE_LOAD ? 0 : ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? 0 : CONFIG_FLAG_FILEUNCHANGED }; 28681 int auto_sip_domains = FALSE; 28682 struct ast_sockaddr old_bindaddr = bindaddr; 28683 int registry_count = 0, peer_count = 0, timerb_set = 0, timert1_set = 0; 28684 int subscribe_network_change = 1; 28685 time_t run_start, run_end; 28686 int bindport = 0; 28687 28688 run_start = time(0); 28689 ast_unload_realtime("sipregs"); 28690 ast_unload_realtime("sippeers"); 28691 cfg = ast_config_load(config, config_flags); 28692 28693 /* We *must* have a config file otherwise stop immediately */ 28694 if (!cfg) { 28695 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 28696 return -1; 28697 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 28698 ucfg = ast_config_load("users.conf", config_flags); 28699 if (ucfg == CONFIG_STATUS_FILEUNCHANGED) { 28700 return 1; 28701 } else if (ucfg == CONFIG_STATUS_FILEINVALID) { 28702 ast_log(LOG_ERROR, "Contents of users.conf are invalid and cannot be parsed\n"); 28703 return 1; 28704 } 28705 /* Must reread both files, because one changed */ 28706 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 28707 if ((cfg = ast_config_load(config, config_flags)) == CONFIG_STATUS_FILEINVALID) { 28708 ast_log(LOG_ERROR, "Contents of %s are invalid and cannot be parsed\n", config); 28709 ast_config_destroy(ucfg); 28710 return 1; 28711 } 28712 if (!cfg) { 28713 /* should have been able to reload here */ 28714 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 28715 return -1; 28716 } 28717 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 28718 ast_log(LOG_ERROR, "Contents of %s are invalid and cannot be parsed\n", config); 28719 return 1; 28720 } else { 28721 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 28722 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 28723 ast_log(LOG_ERROR, "Contents of users.conf are invalid and cannot be parsed\n"); 28724 ast_config_destroy(cfg); 28725 return 1; 28726 } 28727 } 28728 28729 ast_free_ha(sip_cfg.contact_ha); 28730 sip_cfg.contact_ha = NULL; 28731 28732 default_tls_cfg.enabled = FALSE; /* Default: Disable TLS */ 28733 28734 if (reason != CHANNEL_MODULE_LOAD) { 28735 ast_debug(4, "--------------- SIP reload started\n"); 28736 28737 clear_sip_domains(); 28738 ast_mutex_lock(&authl_lock); 28739 if (authl) { 28740 ao2_t_ref(authl, -1, "Removing old global authentication"); 28741 authl = NULL; 28742 } 28743 ast_mutex_unlock(&authl_lock); 28744 28745 28746 cleanup_all_regs(); 28747 /* Then, actually destroy users and registry */ 28748 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 28749 ast_debug(4, "--------------- Done destroying registry list\n"); 28750 ao2_t_callback(peers, OBJ_NODATA, peer_markall_func, NULL, "callback to mark all peers"); 28751 } 28752 28753 /* Reset certificate handling for TLS sessions */ 28754 if (reason != CHANNEL_MODULE_LOAD) { 28755 ast_free(default_tls_cfg.certfile); 28756 ast_free(default_tls_cfg.pvtfile); 28757 ast_free(default_tls_cfg.cipher); 28758 ast_free(default_tls_cfg.cafile); 28759 ast_free(default_tls_cfg.capath); 28760 } 28761 default_tls_cfg.certfile = ast_strdup(AST_CERTFILE); /*XXX Not sure if this is useful */ 28762 default_tls_cfg.pvtfile = ast_strdup(""); 28763 default_tls_cfg.cipher = ast_strdup(""); 28764 default_tls_cfg.cafile = ast_strdup(""); 28765 default_tls_cfg.capath = ast_strdup(""); 28766 28767 /* Initialize copy of current sip_cfg.regcontext for later use in removing stale contexts */ 28768 ast_copy_string(oldcontexts, sip_cfg.regcontext, sizeof(oldcontexts)); 28769 oldregcontext = oldcontexts; 28770 28771 /* Clear all flags before setting default values */ 28772 /* Preserve debugging settings for console */ 28773 sipdebug &= sip_debug_console; 28774 ast_clear_flag(&global_flags[0], AST_FLAGS_ALL); 28775 ast_clear_flag(&global_flags[1], AST_FLAGS_ALL); 28776 ast_clear_flag(&global_flags[2], AST_FLAGS_ALL); 28777 28778 /* Reset IP addresses */ 28779 ast_sockaddr_parse(&bindaddr, "0.0.0.0:0", 0); 28780 memset(&internip, 0, sizeof(internip)); 28781 28782 /* Free memory for local network address mask */ 28783 ast_free_ha(localaddr); 28784 memset(&localaddr, 0, sizeof(localaddr)); 28785 memset(&externaddr, 0, sizeof(externaddr)); 28786 memset(&media_address, 0, sizeof(media_address)); 28787 memset(&default_prefs, 0 , sizeof(default_prefs)); 28788 memset(&sip_cfg.outboundproxy, 0, sizeof(struct sip_proxy)); 28789 sip_cfg.outboundproxy.force = FALSE; /*!< Don't force proxy usage, use route: headers */ 28790 default_transports = SIP_TRANSPORT_UDP; 28791 default_primary_transport = SIP_TRANSPORT_UDP; 28792 ourport_tcp = STANDARD_SIP_PORT; 28793 ourport_tls = STANDARD_TLS_PORT; 28794 externtcpport = STANDARD_SIP_PORT; 28795 externtlsport = STANDARD_TLS_PORT; 28796 sip_cfg.srvlookup = DEFAULT_SRVLOOKUP; 28797 global_tos_sip = DEFAULT_TOS_SIP; 28798 global_tos_audio = DEFAULT_TOS_AUDIO; 28799 global_tos_video = DEFAULT_TOS_VIDEO; 28800 global_tos_text = DEFAULT_TOS_TEXT; 28801 global_cos_sip = DEFAULT_COS_SIP; 28802 global_cos_audio = DEFAULT_COS_AUDIO; 28803 global_cos_video = DEFAULT_COS_VIDEO; 28804 global_cos_text = DEFAULT_COS_TEXT; 28805 28806 externhost[0] = '\0'; /* External host name (for behind NAT DynDNS support) */ 28807 externexpire = 0; /* Expiration for DNS re-issuing */ 28808 externrefresh = 10; 28809 28810 /* Reset channel settings to default before re-configuring */ 28811 sip_cfg.allow_external_domains = DEFAULT_ALLOW_EXT_DOM; /* Allow external invites */ 28812 sip_cfg.regcontext[0] = '\0'; 28813 sip_cfg.capability = DEFAULT_CAPABILITY; 28814 sip_cfg.regextenonqualify = DEFAULT_REGEXTENONQUALIFY; 28815 sip_cfg.legacy_useroption_parsing = DEFAULT_LEGACY_USEROPTION_PARSING; 28816 sip_cfg.notifyringing = DEFAULT_NOTIFYRINGING; 28817 sip_cfg.notifycid = DEFAULT_NOTIFYCID; 28818 sip_cfg.notifyhold = FALSE; /*!< Keep track of hold status for a peer */ 28819 sip_cfg.directrtpsetup = FALSE; /* Experimental feature, disabled by default */ 28820 sip_cfg.alwaysauthreject = DEFAULT_ALWAYSAUTHREJECT; 28821 sip_cfg.auth_options_requests = DEFAULT_AUTH_OPTIONS; 28822 sip_cfg.allowsubscribe = FALSE; 28823 sip_cfg.disallowed_methods = SIP_UNKNOWN; 28824 sip_cfg.contact_ha = NULL; /* Reset the contact ACL */ 28825 snprintf(global_useragent, sizeof(global_useragent), "%s %s", DEFAULT_USERAGENT, ast_get_version()); 28826 snprintf(global_sdpsession, sizeof(global_sdpsession), "%s %s", DEFAULT_SDPSESSION, ast_get_version()); 28827 snprintf(global_sdpowner, sizeof(global_sdpowner), "%s", DEFAULT_SDPOWNER); 28828 global_prematuremediafilter = TRUE; 28829 ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime)); 28830 ast_copy_string(sip_cfg.realm, S_OR(ast_config_AST_SYSTEM_NAME, DEFAULT_REALM), sizeof(sip_cfg.realm)); 28831 sip_cfg.domainsasrealm = DEFAULT_DOMAINSASREALM; 28832 ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid)); 28833 ast_copy_string(default_mwi_from, DEFAULT_MWI_FROM, sizeof(default_mwi_from)); 28834 sip_cfg.compactheaders = DEFAULT_COMPACTHEADERS; 28835 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 28836 global_regattempts_max = 0; 28837 sip_cfg.pedanticsipchecking = DEFAULT_PEDANTIC; 28838 sip_cfg.autocreatepeer = DEFAULT_AUTOCREATEPEER; 28839 global_autoframing = 0; 28840 sip_cfg.allowguest = DEFAULT_ALLOWGUEST; 28841 global_callcounter = DEFAULT_CALLCOUNTER; 28842 global_match_auth_username = FALSE; /*!< Match auth username if available instead of From: Default off. */ 28843 global_rtptimeout = 0; 28844 global_rtpholdtimeout = 0; 28845 global_rtpkeepalive = DEFAULT_RTPKEEPALIVE; 28846 sip_cfg.allowtransfer = TRANSFER_OPENFORALL; /* Merrily accept all transfers by default */ 28847 sip_cfg.rtautoclear = 120; 28848 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE); /* Default for all devices: TRUE */ 28849 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP_YES); /* Default for all devices: Yes */ 28850 sip_cfg.peer_rtupdate = TRUE; 28851 global_dynamic_exclude_static = 0; /* Exclude static peers */ 28852 sip_cfg.tcp_enabled = FALSE; 28853 28854 /* Session-Timers */ 28855 global_st_mode = SESSION_TIMER_MODE_ACCEPT; 28856 global_st_refresher = SESSION_TIMER_REFRESHER_PARAM_UAS; 28857 global_min_se = DEFAULT_MIN_SE; 28858 global_max_se = DEFAULT_MAX_SE; 28859 28860 /* Peer poking settings */ 28861 global_qualify_gap = DEFAULT_QUALIFY_GAP; 28862 global_qualify_peers = DEFAULT_QUALIFY_PEERS; 28863 28864 /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for devices */ 28865 ast_copy_string(sip_cfg.default_context, DEFAULT_CONTEXT, sizeof(sip_cfg.default_context)); 28866 sip_cfg.default_subscribecontext[0] = '\0'; 28867 sip_cfg.default_max_forwards = DEFAULT_MAX_FORWARDS; 28868 default_language[0] = '\0'; 28869 default_fromdomain[0] = '\0'; 28870 default_fromdomainport = 0; 28871 default_qualify = DEFAULT_QUALIFY; 28872 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 28873 ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret)); 28874 ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest)); 28875 ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten)); 28876 ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */ 28877 ast_set_flag(&global_flags[0], SIP_DIRECT_MEDIA); /*!< Allow re-invites */ 28878 ast_set_flag(&global_flags[0], SIP_NAT_FORCE_RPORT); /*!< Default to nat=force_rport */ 28879 ast_copy_string(default_engine, DEFAULT_ENGINE, sizeof(default_engine)); 28880 ast_copy_string(default_parkinglot, DEFAULT_PARKINGLOT, sizeof(default_parkinglot)); 28881 28882 /* Debugging settings, always default to off */ 28883 dumphistory = FALSE; 28884 recordhistory = FALSE; 28885 sipdebug &= ~sip_debug_config; 28886 28887 /* Misc settings for the channel */ 28888 global_relaxdtmf = FALSE; 28889 sip_cfg.callevents = DEFAULT_CALLEVENTS; 28890 global_authfailureevents = FALSE; 28891 global_t1 = DEFAULT_TIMER_T1; 28892 global_timer_b = 64 * DEFAULT_TIMER_T1; 28893 global_t1min = DEFAULT_T1MIN; 28894 global_qualifyfreq = DEFAULT_QUALIFYFREQ; 28895 global_t38_maxdatagram = -1; 28896 global_shrinkcallerid = 1; 28897 authlimit = DEFAULT_AUTHLIMIT; 28898 authtimeout = DEFAULT_AUTHTIMEOUT; 28899 global_store_sip_cause = DEFAULT_STORE_SIP_CAUSE; 28900 28901 sip_cfg.matchexternaddrlocally = DEFAULT_MATCHEXTERNADDRLOCALLY; 28902 28903 /* Copy the default jb config over global_jbconf */ 28904 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 28905 28906 ast_clear_flag(&global_flags[1], SIP_PAGE2_FAX_DETECT); 28907 ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT | SIP_PAGE2_VIDEOSUPPORT_ALWAYS); 28908 ast_clear_flag(&global_flags[1], SIP_PAGE2_TEXTSUPPORT); 28909 ast_clear_flag(&global_flags[1], SIP_PAGE2_IGNORESDPVERSION); 28910 28911 28912 /* Read the [general] config section of sip.conf (or from realtime config) */ 28913 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) { 28914 if (handle_common_options(&global_flags[0], &dummy[0], v)) { 28915 continue; 28916 } 28917 if (handle_t38_options(&global_flags[0], &dummy[0], v, &global_t38_maxdatagram)) { 28918 continue; 28919 } 28920 /* handle jb conf */ 28921 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 28922 continue; 28923 28924 /* handle tls conf, don't allow setting of tlsverifyclient as it isn't supported by chan_sip */ 28925 if (!strcasecmp(v->name, "tlsverifyclient")) { 28926 ast_log(LOG_WARNING, "Ignoring unsupported option 'tlsverifyclient'\n"); 28927 continue; 28928 } else if (!ast_tls_read_conf(&default_tls_cfg, &sip_tls_desc, v->name, v->value)) { 28929 continue; 28930 } 28931 28932 if (!strcasecmp(v->name, "context")) { 28933 ast_copy_string(sip_cfg.default_context, v->value, sizeof(sip_cfg.default_context)); 28934 } else if (!strcasecmp(v->name, "subscribecontext")) { 28935 ast_copy_string(sip_cfg.default_subscribecontext, v->value, sizeof(sip_cfg.default_subscribecontext)); 28936 } else if (!strcasecmp(v->name, "callcounter")) { 28937 global_callcounter = ast_true(v->value) ? 1 : 0; 28938 } else if (!strcasecmp(v->name, "allowguest")) { 28939 sip_cfg.allowguest = ast_true(v->value) ? 1 : 0; 28940 } else if (!strcasecmp(v->name, "realm")) { 28941 ast_copy_string(sip_cfg.realm, v->value, sizeof(sip_cfg.realm)); 28942 } else if (!strcasecmp(v->name, "domainsasrealm")) { 28943 sip_cfg.domainsasrealm = ast_true(v->value); 28944 } else if (!strcasecmp(v->name, "useragent")) { 28945 ast_copy_string(global_useragent, v->value, sizeof(global_useragent)); 28946 ast_debug(1, "Setting SIP channel User-Agent Name to %s\n", global_useragent); 28947 } else if (!strcasecmp(v->name, "sdpsession")) { 28948 ast_copy_string(global_sdpsession, v->value, sizeof(global_sdpsession)); 28949 } else if (!strcasecmp(v->name, "sdpowner")) { 28950 /* Field cannot contain spaces */ 28951 if (!strstr(v->value, " ")) { 28952 ast_copy_string(global_sdpowner, v->value, sizeof(global_sdpowner)); 28953 } else { 28954 ast_log(LOG_WARNING, "'%s' must not contain spaces at line %d. Using default.\n", v->value, v->lineno); 28955 } 28956 } else if (!strcasecmp(v->name, "allowtransfer")) { 28957 sip_cfg.allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 28958 } else if (!strcasecmp(v->name, "rtcachefriends")) { 28959 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 28960 } else if (!strcasecmp(v->name, "rtsavesysname")) { 28961 sip_cfg.rtsave_sysname = ast_true(v->value); 28962 } else if (!strcasecmp(v->name, "rtupdate")) { 28963 sip_cfg.peer_rtupdate = ast_true(v->value); 28964 } else if (!strcasecmp(v->name, "ignoreregexpire")) { 28965 sip_cfg.ignore_regexpire = ast_true(v->value); 28966 } else if (!strcasecmp(v->name, "timert1")) { 28967 /* Defaults to 500ms, but RFC 3261 states that it is recommended 28968 * for the value to be set higher, though a lower value is only 28969 * allowed on private networks unconnected to the Internet. */ 28970 global_t1 = atoi(v->value); 28971 } else if (!strcasecmp(v->name, "timerb")) { 28972 int tmp = atoi(v->value); 28973 if (tmp < 500) { 28974 global_timer_b = global_t1 * 64; 28975 ast_log(LOG_WARNING, "Invalid value for timerb ('%s'). Setting to default ('%d').\n", v->value, global_timer_b); 28976 } 28977 timerb_set = 1; 28978 } else if (!strcasecmp(v->name, "t1min")) { 28979 global_t1min = atoi(v->value); 28980 } else if (!strcasecmp(v->name, "transport")) { 28981 char *val = ast_strdupa(v->value); 28982 char *trans; 28983 28984 default_transports = default_primary_transport = 0; 28985 while ((trans = strsep(&val, ","))) { 28986 trans = ast_skip_blanks(trans); 28987 28988 if (!strncasecmp(trans, "udp", 3)) { 28989 default_transports |= SIP_TRANSPORT_UDP; 28990 } else if (!strncasecmp(trans, "tcp", 3)) { 28991 default_transports |= SIP_TRANSPORT_TCP; 28992 } else if (!strncasecmp(trans, "tls", 3)) { 28993 default_transports |= SIP_TRANSPORT_TLS; 28994 } else { 28995 ast_log(LOG_NOTICE, "'%s' is not a valid transport type. if no other is specified, udp will be used.\n", trans); 28996 } 28997 if (default_primary_transport == 0) { 28998 default_primary_transport = default_transports; 28999 } 29000 } 29001 } else if (!strcasecmp(v->name, "tcpenable")) { 29002 if (!ast_false(v->value)) { 29003 ast_debug(2, "Enabling TCP socket for listening\n"); 29004 sip_cfg.tcp_enabled = TRUE; 29005 } 29006 } else if (!strcasecmp(v->name, "tcpbindaddr")) { 29007 if (ast_parse_arg(v->value, PARSE_ADDR, 29008 &sip_tcp_desc.local_address)) { 29009 ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n", 29010 v->name, v->value, v->lineno, config); 29011 } 29012 ast_debug(2, "Setting TCP socket address to %s\n", 29013 ast_sockaddr_stringify(&sip_tcp_desc.local_address)); 29014 } else if (!strcasecmp(v->name, "dynamic_exclude_static") || !strcasecmp(v->name, "dynamic_excludes_static")) { 29015 global_dynamic_exclude_static = ast_true(v->value); 29016 } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) { 29017 int ha_error = 0; 29018 sip_cfg.contact_ha = ast_append_ha(v->name + 7, v->value, sip_cfg.contact_ha, &ha_error); 29019 if (ha_error) { 29020 ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value); 29021 } 29022 } else if (!strcasecmp(v->name, "rtautoclear")) { 29023 int i = atoi(v->value); 29024 if (i > 0) { 29025 sip_cfg.rtautoclear = i; 29026 } else { 29027 i = 0; 29028 } 29029 ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR); 29030 } else if (!strcasecmp(v->name, "usereqphone")) { 29031 ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE); 29032 } else if (!strcasecmp(v->name, "prematuremedia")) { 29033 global_prematuremediafilter = ast_true(v->value); 29034 } else if (!strcasecmp(v->name, "relaxdtmf")) { 29035 global_relaxdtmf = ast_true(v->value); 29036 } else if (!strcasecmp(v->name, "vmexten")) { 29037 ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten)); 29038 } else if (!strcasecmp(v->name, "rtptimeout")) { 29039 if ((sscanf(v->value, "%30d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) { 29040 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 29041 global_rtptimeout = 0; 29042 } 29043 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 29044 if ((sscanf(v->value, "%30d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) { 29045 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 29046 global_rtpholdtimeout = 0; 29047 } 29048 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 29049 if ((sscanf(v->value, "%30d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) { 29050 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 29051 global_rtpkeepalive = DEFAULT_RTPKEEPALIVE; 29052 } 29053 } else if (!strcasecmp(v->name, "compactheaders")) { 29054 sip_cfg.compactheaders = ast_true(v->value); 29055 } else if (!strcasecmp(v->name, "notifymimetype")) { 29056 ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime)); 29057 } else if (!strcasecmp(v->name, "directrtpsetup")) { 29058 sip_cfg.directrtpsetup = ast_true(v->value); 29059 } else if (!strcasecmp(v->name, "notifyringing")) { 29060 sip_cfg.notifyringing = ast_true(v->value); 29061 } else if (!strcasecmp(v->name, "notifyhold")) { 29062 sip_cfg.notifyhold = ast_true(v->value); 29063 } else if (!strcasecmp(v->name, "notifycid")) { 29064 if (!strcasecmp(v->value, "ignore-context")) { 29065 sip_cfg.notifycid = IGNORE_CONTEXT; 29066 } else { 29067 sip_cfg.notifycid = ast_true(v->value) ? ENABLED : DISABLED; 29068 } 29069 } else if (!strcasecmp(v->name, "alwaysauthreject")) { 29070 sip_cfg.alwaysauthreject = ast_true(v->value); 29071 } else if (!strcasecmp(v->name, "auth_options_requests")) { 29072 if (ast_true(v->value)) { 29073 sip_cfg.auth_options_requests = 1; 29074 } 29075 } else if (!strcasecmp(v->name, "mohinterpret")) { 29076 ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret)); 29077 } else if (!strcasecmp(v->name, "mohsuggest")) { 29078 ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest)); 29079 } else if (!strcasecmp(v->name, "language")) { 29080 ast_copy_string(default_language, v->value, sizeof(default_language)); 29081 } else if (!strcasecmp(v->name, "regcontext")) { 29082 ast_copy_string(newcontexts, v->value, sizeof(newcontexts)); 29083 stringp = newcontexts; 29084 /* Let's remove any contexts that are no longer defined in regcontext */ 29085 cleanup_stale_contexts(stringp, oldregcontext); 29086 /* Create contexts if they don't exist already */ 29087 while ((context = strsep(&stringp, "&"))) { 29088 ast_copy_string(used_context, context, sizeof(used_context)); 29089 ast_context_find_or_create(NULL, NULL, context, "SIP"); 29090 } 29091 ast_copy_string(sip_cfg.regcontext, v->value, sizeof(sip_cfg.regcontext)); 29092 } else if (!strcasecmp(v->name, "regextenonqualify")) { 29093 sip_cfg.regextenonqualify = ast_true(v->value); 29094 } else if (!strcasecmp(v->name, "legacy_useroption_parsing")) { 29095 sip_cfg.legacy_useroption_parsing = ast_true(v->value); 29096 } else if (!strcasecmp(v->name, "callerid")) { 29097 ast_copy_string(default_callerid, v->value, sizeof(default_callerid)); 29098 } else if (!strcasecmp(v->name, "mwi_from")) { 29099 ast_copy_string(default_mwi_from, v->value, sizeof(default_mwi_from)); 29100 } else if (!strcasecmp(v->name, "fromdomain")) { 29101 char *fromdomainport; 29102 ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain)); 29103 if ((fromdomainport = strchr(default_fromdomain, ':'))) { 29104 *fromdomainport++ = '\0'; 29105 if (!(default_fromdomainport = port_str2int(fromdomainport, 0))) { 29106 ast_log(LOG_NOTICE, "'%s' is not a valid port number for fromdomain.\n",fromdomainport); 29107 } 29108 } else { 29109 default_fromdomainport = STANDARD_SIP_PORT; 29110 } 29111 } else if (!strcasecmp(v->name, "outboundproxy")) { 29112 struct sip_proxy *proxy; 29113 if (ast_strlen_zero(v->value)) { 29114 ast_log(LOG_WARNING, "no value given for outbound proxy on line %d of sip.conf\n", v->lineno); 29115 continue; 29116 } 29117 proxy = proxy_from_config(v->value, v->lineno, &sip_cfg.outboundproxy); 29118 if (!proxy) { 29119 ast_log(LOG_WARNING, "failure parsing the outbound proxy on line %d of sip.conf.\n", v->lineno); 29120 continue; 29121 } 29122 } else if (!strcasecmp(v->name, "autocreatepeer")) { 29123 sip_cfg.autocreatepeer = ast_true(v->value); 29124 } else if (!strcasecmp(v->name, "match_auth_username")) { 29125 global_match_auth_username = ast_true(v->value); 29126 } else if (!strcasecmp(v->name, "srvlookup")) { 29127 sip_cfg.srvlookup = ast_true(v->value); 29128 } else if (!strcasecmp(v->name, "pedantic")) { 29129 sip_cfg.pedanticsipchecking = ast_true(v->value); 29130 } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) { 29131 max_expiry = atoi(v->value); 29132 if (max_expiry < 1) { 29133 max_expiry = DEFAULT_MAX_EXPIRY; 29134 } 29135 } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) { 29136 min_expiry = atoi(v->value); 29137 if (min_expiry < 1) { 29138 min_expiry = DEFAULT_MIN_EXPIRY; 29139 } 29140 } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) { 29141 default_expiry = atoi(v->value); 29142 if (default_expiry < 1) { 29143 default_expiry = DEFAULT_DEFAULT_EXPIRY; 29144 } 29145 } else if (!strcasecmp(v->name, "mwiexpiry") || !strcasecmp(v->name, "mwiexpirey")) { 29146 mwi_expiry = atoi(v->value); 29147 if (mwi_expiry < 1) { 29148 mwi_expiry = DEFAULT_MWI_EXPIRY; 29149 } 29150 } else if (!strcasecmp(v->name, "tcpauthtimeout")) { 29151 if (ast_parse_arg(v->value, PARSE_INT32|PARSE_DEFAULT|PARSE_IN_RANGE, 29152 &authtimeout, DEFAULT_AUTHTIMEOUT, 1, INT_MAX)) { 29153 ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n", 29154 v->name, v->value, v->lineno, config); 29155 } 29156 } else if (!strcasecmp(v->name, "tcpauthlimit")) { 29157 if (ast_parse_arg(v->value, PARSE_INT32|PARSE_DEFAULT|PARSE_IN_RANGE, 29158 &authlimit, DEFAULT_AUTHLIMIT, 1, INT_MAX)) { 29159 ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n", 29160 v->name, v->value, v->lineno, config); 29161 } 29162 } else if (!strcasecmp(v->name, "sipdebug")) { 29163 if (ast_true(v->value)) 29164 sipdebug |= sip_debug_config; 29165 } else if (!strcasecmp(v->name, "dumphistory")) { 29166 dumphistory = ast_true(v->value); 29167 } else if (!strcasecmp(v->name, "recordhistory")) { 29168 recordhistory = ast_true(v->value); 29169 } else if (!strcasecmp(v->name, "registertimeout")) { 29170 global_reg_timeout = atoi(v->value); 29171 if (global_reg_timeout < 1) { 29172 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 29173 } 29174 } else if (!strcasecmp(v->name, "registerattempts")) { 29175 global_regattempts_max = atoi(v->value); 29176 } else if (!strcasecmp(v->name, "bindaddr") || !strcasecmp(v->name, "udpbindaddr")) { 29177 if (ast_parse_arg(v->value, PARSE_ADDR, &bindaddr)) { 29178 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 29179 } 29180 } else if (!strcasecmp(v->name, "localnet")) { 29181 struct ast_ha *na; 29182 int ha_error = 0; 29183 29184 if (!(na = ast_append_ha("d", v->value, localaddr, &ha_error))) { 29185 ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value); 29186 } else { 29187 localaddr = na; 29188 } 29189 if (ha_error) { 29190 ast_log(LOG_ERROR, "Bad localnet configuration value line %d : %s\n", v->lineno, v->value); 29191 } 29192 } else if (!strcasecmp(v->name, "media_address")) { 29193 if (ast_parse_arg(v->value, PARSE_ADDR, &media_address)) 29194 ast_log(LOG_WARNING, "Invalid address for media_address keyword: %s\n", v->value); 29195 } else if (!strcasecmp(v->name, "externaddr") || !strcasecmp(v->name, "externip")) { 29196 if (ast_parse_arg(v->value, PARSE_ADDR, &externaddr)) { 29197 ast_log(LOG_WARNING, 29198 "Invalid address for externaddr keyword: %s\n", 29199 v->value); 29200 } 29201 externexpire = 0; 29202 } else if (!strcasecmp(v->name, "externhost")) { 29203 ast_copy_string(externhost, v->value, sizeof(externhost)); 29204 if (ast_sockaddr_resolve_first(&externaddr, externhost, 0)) { 29205 ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost); 29206 } 29207 externexpire = time(NULL); 29208 } else if (!strcasecmp(v->name, "externrefresh")) { 29209 if (sscanf(v->value, "%30d", &externrefresh) != 1) { 29210 ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno); 29211 externrefresh = 10; 29212 } 29213 } else if (!strcasecmp(v->name, "externtcpport")) { 29214 if (!(externtcpport = port_str2int(v->value, 0))) { 29215 ast_log(LOG_WARNING, "Invalid externtcpport value, must be a positive integer between 1 and 65535 at line %d\n", v->lineno); 29216 externtcpport = 0; 29217 } 29218 } else if (!strcasecmp(v->name, "externtlsport")) { 29219 if (!(externtlsport = port_str2int(v->value, STANDARD_TLS_PORT))) { 29220 ast_log(LOG_WARNING, "Invalid externtlsport value, must be a positive integer between 1 and 65535 at line %d\n", v->lineno); 29221 } 29222 } else if (!strcasecmp(v->name, "allow")) { 29223 int error = ast_parse_allow_disallow(&default_prefs, &sip_cfg.capability, v->value, TRUE); 29224 if (error) { 29225 ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value); 29226 } 29227 } else if (!strcasecmp(v->name, "disallow")) { 29228 int error = ast_parse_allow_disallow(&default_prefs, &sip_cfg.capability, v->value, FALSE); 29229 if (error) { 29230 ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value); 29231 } 29232 } else if (!strcasecmp(v->name, "preferred_codec_only")) { 29233 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_PREFERRED_CODEC); 29234 } else if (!strcasecmp(v->name, "autoframing")) { 29235 global_autoframing = ast_true(v->value); 29236 } else if (!strcasecmp(v->name, "allowexternaldomains")) { 29237 sip_cfg.allow_external_domains = ast_true(v->value); 29238 } else if (!strcasecmp(v->name, "autodomain")) { 29239 auto_sip_domains = ast_true(v->value); 29240 } else if (!strcasecmp(v->name, "domain")) { 29241 char *domain = ast_strdupa(v->value); 29242 char *cntx = strchr(domain, ','); 29243 29244 if (cntx) { 29245 *cntx++ = '\0'; 29246 } 29247 29248 if (ast_strlen_zero(cntx)) { 29249 ast_debug(1, "No context specified at line %d for domain '%s'\n", v->lineno, domain); 29250 } 29251 if (ast_strlen_zero(domain)) { 29252 ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno); 29253 } else { 29254 add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, cntx ? ast_strip(cntx) : ""); 29255 } 29256 } else if (!strcasecmp(v->name, "register")) { 29257 if (sip_register(v->value, v->lineno) == 0) { 29258 registry_count++; 29259 } 29260 } else if (!strcasecmp(v->name, "mwi")) { 29261 sip_subscribe_mwi(v->value, v->lineno); 29262 } else if (!strcasecmp(v->name, "tos_sip")) { 29263 if (ast_str2tos(v->value, &global_tos_sip)) { 29264 ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, refer to QoS documentation\n", v->lineno); 29265 } 29266 } else if (!strcasecmp(v->name, "tos_audio")) { 29267 if (ast_str2tos(v->value, &global_tos_audio)) { 29268 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, refer to QoS documentation\n", v->lineno); 29269 } 29270 } else if (!strcasecmp(v->name, "tos_video")) { 29271 if (ast_str2tos(v->value, &global_tos_video)) { 29272 ast_log(LOG_WARNING, "Invalid tos_video value at line %d, refer to QoS documentation\n", v->lineno); 29273 } 29274 } else if (!strcasecmp(v->name, "tos_text")) { 29275 if (ast_str2tos(v->value, &global_tos_text)) { 29276 ast_log(LOG_WARNING, "Invalid tos_text value at line %d, refer to QoS documentation\n", v->lineno); 29277 } 29278 } else if (!strcasecmp(v->name, "cos_sip")) { 29279 if (ast_str2cos(v->value, &global_cos_sip)) { 29280 ast_log(LOG_WARNING, "Invalid cos_sip value at line %d, refer to QoS documentation\n", v->lineno); 29281 } 29282 } else if (!strcasecmp(v->name, "cos_audio")) { 29283 if (ast_str2cos(v->value, &global_cos_audio)) { 29284 ast_log(LOG_WARNING, "Invalid cos_audio value at line %d, refer to QoS documentation\n", v->lineno); 29285 } 29286 } else if (!strcasecmp(v->name, "cos_video")) { 29287 if (ast_str2cos(v->value, &global_cos_video)) { 29288 ast_log(LOG_WARNING, "Invalid cos_video value at line %d, refer to QoS documentation\n", v->lineno); 29289 } 29290 } else if (!strcasecmp(v->name, "cos_text")) { 29291 if (ast_str2cos(v->value, &global_cos_text)) { 29292 ast_log(LOG_WARNING, "Invalid cos_text value at line %d, refer to QoS documentation\n", v->lineno); 29293 } 29294 } else if (!strcasecmp(v->name, "bindport")) { 29295 if (sscanf(v->value, "%5d", &bindport) != 1) { 29296 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 29297 } 29298 } else if (!strcasecmp(v->name, "qualify")) { 29299 if (!strcasecmp(v->value, "no")) { 29300 default_qualify = 0; 29301 } else if (!strcasecmp(v->value, "yes")) { 29302 default_qualify = DEFAULT_MAXMS; 29303 } else if (sscanf(v->value, "%30d", &default_qualify) != 1) { 29304 ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno); 29305 default_qualify = 0; 29306 } 29307 } else if (!strcasecmp(v->name, "qualifyfreq")) { 29308 int i; 29309 if (sscanf(v->value, "%30d", &i) == 1) { 29310 global_qualifyfreq = i * 1000; 29311 } else { 29312 ast_log(LOG_WARNING, "Invalid qualifyfreq number '%s' at line %d of %s\n", v->value, v->lineno, config); 29313 global_qualifyfreq = DEFAULT_QUALIFYFREQ; 29314 } 29315 } else if (!strcasecmp(v->name, "callevents")) { 29316 sip_cfg.callevents = ast_true(v->value); 29317 } else if (!strcasecmp(v->name, "authfailureevents")) { 29318 global_authfailureevents = ast_true(v->value); 29319 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 29320 default_maxcallbitrate = atoi(v->value); 29321 if (default_maxcallbitrate < 0) 29322 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 29323 } else if (!strcasecmp(v->name, "matchexternaddrlocally") || !strcasecmp(v->name, "matchexterniplocally")) { 29324 sip_cfg.matchexternaddrlocally = ast_true(v->value); 29325 } else if (!strcasecmp(v->name, "session-timers")) { 29326 int i = (int) str2stmode(v->value); 29327 if (i < 0) { 29328 ast_log(LOG_WARNING, "Invalid session-timers '%s' at line %d of %s\n", v->value, v->lineno, config); 29329 global_st_mode = SESSION_TIMER_MODE_ACCEPT; 29330 } else { 29331 global_st_mode = i; 29332 } 29333 } else if (!strcasecmp(v->name, "session-expires")) { 29334 if (sscanf(v->value, "%30d", &global_max_se) != 1) { 29335 ast_log(LOG_WARNING, "Invalid session-expires '%s' at line %d of %s\n", v->value, v->lineno, config); 29336 global_max_se = DEFAULT_MAX_SE; 29337 } 29338 } else if (!strcasecmp(v->name, "session-minse")) { 29339 if (sscanf(v->value, "%30d", &global_min_se) != 1) { 29340 ast_log(LOG_WARNING, "Invalid session-minse '%s' at line %d of %s\n", v->value, v->lineno, config); 29341 global_min_se = DEFAULT_MIN_SE; 29342 } 29343 if (global_min_se < DEFAULT_MIN_SE) { 29344 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); 29345 global_min_se = DEFAULT_MIN_SE; 29346 } 29347 } else if (!strcasecmp(v->name, "session-refresher")) { 29348 int i = (int) str2strefresherparam(v->value); 29349 if (i < 0) { 29350 ast_log(LOG_WARNING, "Invalid session-refresher '%s' at line %d of %s\n", v->value, v->lineno, config); 29351 global_st_refresher = SESSION_TIMER_REFRESHER_PARAM_UAS; 29352 } else { 29353 global_st_refresher = i; 29354 } 29355 } else if (!strcasecmp(v->name, "storesipcause")) { 29356 global_store_sip_cause = ast_true(v->value); 29357 } else if (!strcasecmp(v->name, "qualifygap")) { 29358 if (sscanf(v->value, "%30d", &global_qualify_gap) != 1) { 29359 ast_log(LOG_WARNING, "Invalid qualifygap '%s' at line %d of %s\n", v->value, v->lineno, config); 29360 global_qualify_gap = DEFAULT_QUALIFY_GAP; 29361 } 29362 } else if (!strcasecmp(v->name, "qualifypeers")) { 29363 if (sscanf(v->value, "%30d", &global_qualify_peers) != 1) { 29364 ast_log(LOG_WARNING, "Invalid pokepeers '%s' at line %d of %s\n", v->value, v->lineno, config); 29365 global_qualify_peers = DEFAULT_QUALIFY_PEERS; 29366 } 29367 } else if (!strcasecmp(v->name, "disallowed_methods")) { 29368 char *disallow = ast_strdupa(v->value); 29369 mark_parsed_methods(&sip_cfg.disallowed_methods, disallow); 29370 } else if (!strcasecmp(v->name, "shrinkcallerid")) { 29371 if (ast_true(v->value)) { 29372 global_shrinkcallerid = 1; 29373 } else if (ast_false(v->value)) { 29374 global_shrinkcallerid = 0; 29375 } else { 29376 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno); 29377 } 29378 } else if (!strcasecmp(v->name, "use_q850_reason")) { 29379 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_Q850_REASON); 29380 } else if (!strcasecmp(v->name, "maxforwards")) { 29381 if (sscanf(v->value, "%30d", &sip_cfg.default_max_forwards) != 1 29382 || sip_cfg.default_max_forwards < 1 || 255 < sip_cfg.default_max_forwards) { 29383 ast_log(LOG_WARNING, "'%s' is not a valid maxforwards value at line %d. Using default.\n", v->value, v->lineno); 29384 sip_cfg.default_max_forwards = DEFAULT_MAX_FORWARDS; 29385 } 29386 } else if (!strcasecmp(v->name, "subscribe_network_change_event")) { 29387 if (ast_true(v->value)) { 29388 subscribe_network_change = 1; 29389 } else if (ast_false(v->value)) { 29390 subscribe_network_change = 0; 29391 } else { 29392 ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno); 29393 } 29394 } else if (!strcasecmp(v->name, "snom_aoc_enabled")) { 29395 ast_set2_flag(&global_flags[2], ast_true(v->value), SIP_PAGE3_SNOM_AOC); 29396 } else if (!strcasecmp(v->name, "parkinglot")) { 29397 ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot)); 29398 } 29399 } 29400 29401 if (subscribe_network_change) { 29402 network_change_event_subscribe(); 29403 } else { 29404 network_change_event_unsubscribe(); 29405 } 29406 29407 if (global_t1 < global_t1min) { 29408 ast_log(LOG_WARNING, "'t1min' (%d) cannot be greater than 't1timer' (%d). Resetting 't1timer' to the value of 't1min'\n", global_t1min, global_t1); 29409 global_t1 = global_t1min; 29410 } 29411 29412 if (global_timer_b < global_t1 * 64) { 29413 if (timerb_set && timert1_set) { 29414 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); 29415 } else if (timerb_set) { 29416 if ((global_t1 = global_timer_b / 64) < global_t1min) { 29417 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); 29418 global_t1 = global_t1min; 29419 global_timer_b = global_t1 * 64; 29420 } 29421 } else { 29422 global_timer_b = global_t1 * 64; 29423 } 29424 } 29425 if (!sip_cfg.allow_external_domains && AST_LIST_EMPTY(&domain_list)) { 29426 ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n"); 29427 sip_cfg.allow_external_domains = 1; 29428 } 29429 /* If not or badly configured, set default transports */ 29430 if (!sip_cfg.tcp_enabled && (default_transports & SIP_TRANSPORT_TCP)) { 29431 ast_log(LOG_WARNING, "Cannot use 'tcp' transport with tcpenable=no. Removing from available transports.\n"); 29432 default_primary_transport &= ~SIP_TRANSPORT_TCP; 29433 default_transports &= ~SIP_TRANSPORT_TCP; 29434 } 29435 if (!default_tls_cfg.enabled && (default_transports & SIP_TRANSPORT_TLS)) { 29436 ast_log(LOG_WARNING, "Cannot use 'tls' transport with tlsenable=no. Removing from available transports.\n"); 29437 default_primary_transport &= ~SIP_TRANSPORT_TLS; 29438 default_transports &= ~SIP_TRANSPORT_TLS; 29439 } 29440 if (!default_transports) { 29441 ast_log(LOG_WARNING, "No valid transports available, falling back to 'udp'.\n"); 29442 default_transports = default_primary_transport = SIP_TRANSPORT_UDP; 29443 } else if (!default_primary_transport) { 29444 ast_log(LOG_WARNING, "No valid default transport. Selecting 'udp' as default.\n"); 29445 default_primary_transport = SIP_TRANSPORT_UDP; 29446 } 29447 29448 /* Build list of authentication to various SIP realms, i.e. service providers */ 29449 for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) { 29450 /* Format for authentication is auth = username:password@realm */ 29451 if (!strcasecmp(v->name, "auth")) { 29452 add_realm_authentication(&authl, v->value, v->lineno); 29453 } 29454 } 29455 29456 if (bindport) { 29457 if (ast_sockaddr_port(&bindaddr)) { 29458 ast_log(LOG_WARNING, "bindport is also specified in bindaddr. " 29459 "Using %d.\n", bindport); 29460 } 29461 ast_sockaddr_set_port(&bindaddr, bindport); 29462 } 29463 29464 if (!ast_sockaddr_port(&bindaddr)) { 29465 ast_sockaddr_set_port(&bindaddr, STANDARD_SIP_PORT); 29466 } 29467 29468 /* Set UDP address and open socket */ 29469 ast_sockaddr_copy(&internip, &bindaddr); 29470 if (ast_find_ourip(&internip, &bindaddr, 0)) { 29471 ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n"); 29472 ast_config_destroy(cfg); 29473 return 0; 29474 } 29475 29476 ast_mutex_lock(&netlock); 29477 if ((sipsock > -1) && (ast_sockaddr_cmp(&old_bindaddr, &bindaddr))) { 29478 close(sipsock); 29479 sipsock = -1; 29480 } 29481 if (sipsock < 0) { 29482 sipsock = socket(ast_sockaddr_is_ipv6(&bindaddr) ? 29483 AF_INET6 : AF_INET, SOCK_DGRAM, 0); 29484 if (sipsock < 0) { 29485 ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno)); 29486 ast_config_destroy(cfg); 29487 ast_mutex_unlock(&netlock); 29488 return -1; 29489 } else { 29490 /* Allow SIP clients on the same host to access us: */ 29491 const int reuseFlag = 1; 29492 29493 setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR, 29494 (const char*)&reuseFlag, 29495 sizeof reuseFlag); 29496 29497 ast_enable_packet_fragmentation(sipsock); 29498 29499 if (ast_bind(sipsock, &bindaddr) < 0) { 29500 ast_log(LOG_WARNING, "Failed to bind to %s: %s\n", 29501 ast_sockaddr_stringify(&bindaddr), strerror(errno)); 29502 close(sipsock); 29503 sipsock = -1; 29504 } else { 29505 ast_verb(2, "SIP Listening on %s\n", ast_sockaddr_stringify(&bindaddr)); 29506 ast_set_qos(sipsock, global_tos_sip, global_cos_sip, "SIP"); 29507 } 29508 } 29509 } else { 29510 ast_set_qos(sipsock, global_tos_sip, global_cos_sip, "SIP"); 29511 } 29512 ast_mutex_unlock(&netlock); 29513 29514 /* Start TCP server */ 29515 if (sip_cfg.tcp_enabled) { 29516 if (ast_sockaddr_isnull(&sip_tcp_desc.local_address)) { 29517 ast_sockaddr_copy(&sip_tcp_desc.local_address, &bindaddr); 29518 } 29519 if (!ast_sockaddr_port(&sip_tcp_desc.local_address)) { 29520 ast_sockaddr_set_port(&sip_tcp_desc.local_address, STANDARD_SIP_PORT); 29521 } 29522 } else { 29523 ast_sockaddr_setnull(&sip_tcp_desc.local_address); 29524 } 29525 ast_tcptls_server_start(&sip_tcp_desc); 29526 if (sip_cfg.tcp_enabled && sip_tcp_desc.accept_fd == -1) { 29527 /* TCP server start failed. Tell the admin */ 29528 ast_log(LOG_ERROR, "SIP TCP Server start failed. Not listening on TCP socket.\n"); 29529 } else { 29530 ast_debug(2, "SIP TCP server started\n"); 29531 } 29532 29533 /* Start TLS server if needed */ 29534 memcpy(sip_tls_desc.tls_cfg, &default_tls_cfg, sizeof(default_tls_cfg)); 29535 29536 if (ast_ssl_setup(sip_tls_desc.tls_cfg)) { 29537 if (ast_sockaddr_isnull(&sip_tls_desc.local_address)) { 29538 ast_sockaddr_copy(&sip_tls_desc.local_address, &bindaddr); 29539 ast_sockaddr_set_port(&sip_tls_desc.local_address, 29540 STANDARD_TLS_PORT); 29541 } 29542 if (!ast_sockaddr_port(&sip_tls_desc.local_address)) { 29543 ast_sockaddr_set_port(&sip_tls_desc.local_address, 29544 STANDARD_TLS_PORT); 29545 } 29546 ast_tcptls_server_start(&sip_tls_desc); 29547 if (default_tls_cfg.enabled && sip_tls_desc.accept_fd == -1) { 29548 ast_log(LOG_ERROR, "TLS Server start failed. Not listening on TLS socket.\n"); 29549 sip_tls_desc.tls_cfg = NULL; 29550 } 29551 } else if (sip_tls_desc.tls_cfg->enabled) { 29552 sip_tls_desc.tls_cfg = NULL; 29553 ast_log(LOG_WARNING, "SIP TLS server did not load because of errors.\n"); 29554 } 29555 29556 if (ucfg) { 29557 struct ast_variable *gen; 29558 int genhassip, genregistersip; 29559 const char *hassip, *registersip; 29560 29561 genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip")); 29562 genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip")); 29563 gen = ast_variable_browse(ucfg, "general"); 29564 cat = ast_category_browse(ucfg, NULL); 29565 while (cat) { 29566 if (strcasecmp(cat, "general")) { 29567 hassip = ast_variable_retrieve(ucfg, cat, "hassip"); 29568 registersip = ast_variable_retrieve(ucfg, cat, "registersip"); 29569 if (ast_true(hassip) || (!hassip && genhassip)) { 29570 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0, 0); 29571 if (peer) { 29572 /* user.conf entries are always of type friend */ 29573 peer->type = SIP_TYPE_USER | SIP_TYPE_PEER; 29574 ao2_t_link(peers, peer, "link peer into peer table"); 29575 if ((peer->type & SIP_TYPE_PEER) && !ast_sockaddr_isnull(&peer->addr)) { 29576 ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table"); 29577 } 29578 29579 unref_peer(peer, "unref_peer: from reload_config"); 29580 peer_count++; 29581 } 29582 } 29583 if (ast_true(registersip) || (!registersip && genregistersip)) { 29584 char tmp[256]; 29585 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 29586 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 29587 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 29588 const char *contact = ast_variable_retrieve(ucfg, cat, "contact"); 29589 const char *authuser = ast_variable_retrieve(ucfg, cat, "authuser"); 29590 if (!host) { 29591 host = ast_variable_retrieve(ucfg, "general", "host"); 29592 } 29593 if (!username) { 29594 username = ast_variable_retrieve(ucfg, "general", "username"); 29595 } 29596 if (!secret) { 29597 secret = ast_variable_retrieve(ucfg, "general", "secret"); 29598 } 29599 if (!contact) { 29600 contact = "s"; 29601 } 29602 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 29603 if (!ast_strlen_zero(secret)) { 29604 if (!ast_strlen_zero(authuser)) { 29605 snprintf(tmp, sizeof(tmp), "%s?%s:%s:%s@%s/%s", cat, username, secret, authuser, host, contact); 29606 } else { 29607 snprintf(tmp, sizeof(tmp), "%s?%s:%s@%s/%s", cat, username, secret, host, contact); 29608 } 29609 } else if (!ast_strlen_zero(authuser)) { 29610 snprintf(tmp, sizeof(tmp), "%s?%s::%s@%s/%s", cat, username, authuser, host, contact); 29611 } else { 29612 snprintf(tmp, sizeof(tmp), "%s?%s@%s/%s", cat, username, host, contact); 29613 } 29614 if (sip_register(tmp, 0) == 0) { 29615 registry_count++; 29616 } 29617 } 29618 } 29619 } 29620 cat = ast_category_browse(ucfg, cat); 29621 } 29622 ast_config_destroy(ucfg); 29623 } 29624 29625 /* Load peers, users and friends */ 29626 cat = NULL; 29627 while ( (cat = ast_category_browse(cfg, cat)) ) { 29628 const char *utype; 29629 if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication")) 29630 continue; 29631 utype = ast_variable_retrieve(cfg, cat, "type"); 29632 if (!utype) { 29633 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 29634 continue; 29635 } else { 29636 if (!strcasecmp(utype, "user")) { 29637 ; 29638 } else if (!strcasecmp(utype, "friend")) { 29639 ; 29640 } else if (!strcasecmp(utype, "peer")) { 29641 ; 29642 } else { 29643 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf"); 29644 continue; 29645 } 29646 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0, 0); 29647 if (peer) { 29648 display_nat_warning(cat, reason, &peer->flags[0]); 29649 ao2_t_link(peers, peer, "link peer into peers table"); 29650 if ((peer->type & SIP_TYPE_PEER) && !ast_sockaddr_isnull(&peer->addr)) { 29651 ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table"); 29652 } 29653 unref_peer(peer, "unref the result of the build_peer call. Now, the links from the tables are the only ones left."); 29654 peer_count++; 29655 } 29656 } 29657 } 29658 29659 /* Add default domains - host name, IP address and IP:port 29660 * Only do this if user added any sip domain with "localdomains" 29661 * In order to *not* break backwards compatibility 29662 * Some phones address us at IP only, some with additional port number 29663 */ 29664 if (auto_sip_domains) { 29665 char temp[MAXHOSTNAMELEN]; 29666 29667 /* First our default IP address */ 29668 if (!ast_sockaddr_isnull(&bindaddr) && !ast_sockaddr_is_any(&bindaddr)) { 29669 add_sip_domain(ast_sockaddr_stringify_addr(&bindaddr), 29670 SIP_DOMAIN_AUTO, NULL); 29671 } else if (!ast_sockaddr_isnull(&internip) && !ast_sockaddr_is_any(&internip)) { 29672 /* Our internal IP address, if configured */ 29673 add_sip_domain(ast_sockaddr_stringify_addr(&internip), 29674 SIP_DOMAIN_AUTO, NULL); 29675 } else { 29676 ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n"); 29677 } 29678 29679 /* If TCP is running on a different IP than UDP, then add it too */ 29680 if (!ast_sockaddr_isnull(&sip_tcp_desc.local_address) && 29681 !ast_sockaddr_cmp(&bindaddr, &sip_tcp_desc.local_address)) { 29682 add_sip_domain(ast_sockaddr_stringify_addr(&sip_tcp_desc.local_address), 29683 SIP_DOMAIN_AUTO, NULL); 29684 } 29685 29686 /* If TLS is running on a different IP than UDP and TCP, then add that too */ 29687 if (!ast_sockaddr_isnull(&sip_tls_desc.local_address) && 29688 !ast_sockaddr_cmp(&bindaddr, &sip_tls_desc.local_address) && 29689 !ast_sockaddr_cmp(&sip_tcp_desc.local_address, 29690 &sip_tls_desc.local_address)) { 29691 add_sip_domain(ast_sockaddr_stringify_addr(&sip_tcp_desc.local_address), 29692 SIP_DOMAIN_AUTO, NULL); 29693 } 29694 29695 /* Our extern IP address, if configured */ 29696 if (!ast_sockaddr_isnull(&externaddr)) { 29697 add_sip_domain(ast_sockaddr_stringify_addr(&externaddr), 29698 SIP_DOMAIN_AUTO, NULL); 29699 } 29700 29701 /* Extern host name (NAT traversal support) */ 29702 if (!ast_strlen_zero(externhost)) { 29703 add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL); 29704 } 29705 29706 /* Our host name */ 29707 if (!gethostname(temp, sizeof(temp))) { 29708 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 29709 } 29710 } 29711 29712 /* Release configuration from memory */ 29713 ast_config_destroy(cfg); 29714 29715 /* Load the list of manual NOTIFY types to support */ 29716 if (notify_types) 29717 ast_config_destroy(notify_types); 29718 if ((notify_types = ast_config_load(notify_config, config_flags)) == CONFIG_STATUS_FILEINVALID) { 29719 ast_log(LOG_ERROR, "Contents of %s are invalid and cannot be parsed.\n", notify_config); 29720 notify_types = NULL; 29721 } 29722 29723 /* Done, tell the manager */ 29724 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); 29725 run_end = time(0); 29726 ast_debug(4, "SIP reload_config done...Runtime= %d sec\n", (int)(run_end-run_start)); 29727 29728 return 0; 29729 }
| static char * remove_uri_parameters | ( | char * | uri | ) | [static] |
Definition at line 12389 of file chan_sip.c.
Referenced by extract_uri(), parse_moved_contact(), register_verify(), reqprep(), and transmit_state_notify().
12390 { 12391 char *atsign; 12392 atsign = strchr(uri, '@'); /* First, locate the at sign */ 12393 if (!atsign) { 12394 atsign = uri; /* Ok hostname only, let's stick with the rest */ 12395 } 12396 atsign = strchr(atsign, ';'); /* Locate semi colon */ 12397 if (atsign) 12398 *atsign = '\0'; /* Kill at the semi colon */ 12399 return uri; 12400 }
| 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 19827 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().
19828 { 19829 char tmp[512]; 19830 char *c; 19831 char oldnonce[256]; 19832 19833 /* table of recognised keywords, and places where they should be copied */ 19834 const struct x { 19835 const char *key; 19836 const ast_string_field *field; 19837 } *i, keys[] = { 19838 { "realm=", &p->realm }, 19839 { "nonce=", &p->nonce }, 19840 { "opaque=", &p->opaque }, 19841 { "qop=", &p->qop }, 19842 { "domain=", &p->domain }, 19843 { NULL, 0 }, 19844 }; 19845 19846 ast_copy_string(tmp, get_header(req, header), sizeof(tmp)); 19847 if (ast_strlen_zero(tmp)) 19848 return -1; 19849 if (strncasecmp(tmp, "Digest ", strlen("Digest "))) { 19850 ast_log(LOG_WARNING, "missing Digest.\n"); 19851 return -1; 19852 } 19853 c = tmp + strlen("Digest "); 19854 ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce)); 19855 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 19856 for (i = keys; i->key != NULL; i++) { 19857 char *src, *separator; 19858 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 19859 continue; 19860 /* Found. Skip keyword, take text in quotes or up to the separator. */ 19861 c += strlen(i->key); 19862 if (*c == '"') { 19863 src = ++c; 19864 separator = "\""; 19865 } else { 19866 src = c; 19867 separator = ","; 19868 } 19869 strsep(&c, separator); /* clear separator and move ptr */ 19870 ast_string_field_ptr_set(p, i->field, src); 19871 break; 19872 } 19873 if (i->key == NULL) /* not found, try ',' */ 19874 strsep(&c, ","); 19875 } 19876 /* Reset nonce count */ 19877 if (strcmp(p->nonce, oldnonce)) 19878 p->noncecount = 0; 19879 19880 /* Save auth data for following registrations */ 19881 if (p->registry) { 19882 struct sip_registry *r = p->registry; 19883 19884 if (strcmp(r->nonce, p->nonce)) { 19885 ast_string_field_set(r, realm, p->realm); 19886 ast_string_field_set(r, nonce, p->nonce); 19887 ast_string_field_set(r, authdomain, p->domain); 19888 ast_string_field_set(r, opaque, p->opaque); 19889 ast_string_field_set(r, qop, p->qop); 19890 r->noncecount = 0; 19891 } 19892 } 19893 return build_reply_digest(p, sipmethod, digest, digest_len); 19894 }
| 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 10822 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().
10823 { 10824 struct sip_request *orig = &p->initreq; 10825 char stripped[80]; 10826 char tmp[80]; 10827 char newto[256]; 10828 const char *c; 10829 const char *ot, *of; 10830 int is_strict = FALSE; /*!< Strict routing flag */ 10831 int is_outbound = ast_test_flag(&p->flags[0], SIP_OUTGOING); /* Session direction */ 10832 10833 snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text); 10834 10835 if (!seqno) { 10836 p->ocseq++; 10837 seqno = p->ocseq; 10838 } 10839 10840 /* A CANCEL must have the same branch as the INVITE that it is canceling. */ 10841 if (sipmethod == SIP_CANCEL) { 10842 p->branch = p->invite_branch; 10843 build_via(p); 10844 } else if (newbranch && (sipmethod == SIP_INVITE)) { 10845 p->branch ^= ast_random(); 10846 p->invite_branch = p->branch; 10847 build_via(p); 10848 } else if (newbranch) { 10849 p->branch ^= ast_random(); 10850 build_via(p); 10851 } 10852 10853 /* Check for strict or loose router */ 10854 if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop, ";lr") == NULL) { 10855 is_strict = TRUE; 10856 if (sipdebug) 10857 ast_debug(1, "Strict routing enforced for session %s\n", p->callid); 10858 } 10859 10860 if (sipmethod == SIP_CANCEL) 10861 c = REQ_OFFSET_TO_STR(&p->initreq, rlPart2); /* Use original URI */ 10862 else if (sipmethod == SIP_ACK) { 10863 /* Use URI from Contact: in 200 OK (if INVITE) 10864 (we only have the contacturi on INVITEs) */ 10865 if (!ast_strlen_zero(p->okcontacturi)) 10866 c = is_strict ? p->route->hop : p->okcontacturi; 10867 else 10868 c = REQ_OFFSET_TO_STR(&p->initreq, rlPart2); 10869 } else if (!ast_strlen_zero(p->okcontacturi)) 10870 c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */ 10871 else if (!ast_strlen_zero(p->uri)) 10872 c = p->uri; 10873 else { 10874 char *n; 10875 /* We have no URI, use To: or From: header as URI (depending on direction) */ 10876 ast_copy_string(stripped, get_header(orig, is_outbound ? "To" : "From"), 10877 sizeof(stripped)); 10878 n = get_in_brackets(stripped); 10879 c = remove_uri_parameters(n); 10880 } 10881 init_req(req, sipmethod, c); 10882 10883 snprintf(tmp, sizeof(tmp), "%u %s", seqno, sip_methods[sipmethod].text); 10884 10885 add_header(req, "Via", p->via); 10886 /* 10887 * Use the learned route set unless this is a CANCEL on an ACK for a non-2xx 10888 * final response. For a CANCEL or ACK, we have to send to the same destination 10889 * as the original INVITE. 10890 */ 10891 if (p->route && 10892 !(sipmethod == SIP_CANCEL || 10893 (sipmethod == SIP_ACK && (p->invitestate == INV_COMPLETED || p->invitestate == INV_CANCELLED)))) { 10894 set_destination(p, p->route->hop); 10895 add_route(req, is_strict ? p->route->next : p->route); 10896 } 10897 add_header_max_forwards(p, req); 10898 10899 ot = get_header(orig, "To"); 10900 of = get_header(orig, "From"); 10901 10902 /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly 10903 as our original request, including tag (or presumably lack thereof) */ 10904 if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) { 10905 /* Add the proper tag if we don't have it already. If they have specified 10906 their tag, use it. Otherwise, use our own tag */ 10907 if (is_outbound && !ast_strlen_zero(p->theirtag)) 10908 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 10909 else if (!is_outbound) 10910 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 10911 else 10912 snprintf(newto, sizeof(newto), "%s", ot); 10913 ot = newto; 10914 } 10915 10916 if (is_outbound) { 10917 add_header(req, "From", of); 10918 add_header(req, "To", ot); 10919 } else { 10920 add_header(req, "From", ot); 10921 add_header(req, "To", of); 10922 } 10923 /* Do not add Contact for MESSAGE, BYE and Cancel requests */ 10924 if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE) 10925 add_header(req, "Contact", p->our_contact); 10926 10927 copy_header(req, orig, "Call-ID"); 10928 add_header(req, "CSeq", tmp); 10929 10930 if (!ast_strlen_zero(global_useragent)) 10931 add_header(req, "User-Agent", global_useragent); 10932 10933 if (!ast_strlen_zero(p->url)) { 10934 add_header(req, "Access-URL", p->url); 10935 ast_string_field_set(p, url, NULL); 10936 } 10937 10938 /* Add Session-Timers related headers if the feature is active for this session. 10939 An exception to this behavior is the ACK request. Since Asterisk never requires 10940 session-timers support from a remote end-point (UAS) in an INVITE, it must 10941 not send 'Require: timer' header in the ACK request. 10942 This should only be added in the INVITE transactions, not MESSAGE or REFER or other 10943 in-dialog messages. 10944 */ 10945 if (p->stimer && p->stimer->st_active == TRUE && p->stimer->st_active_peer_ua == TRUE 10946 && sipmethod == SIP_INVITE) { 10947 char se_hdr[256]; 10948 snprintf(se_hdr, sizeof(se_hdr), "%d;refresher=%s", p->stimer->st_interval, 10949 p->stimer->st_ref == SESSION_TIMER_REFRESHER_US ? "uac" : "uas"); 10950 add_header(req, "Session-Expires", se_hdr); 10951 snprintf(se_hdr, sizeof(se_hdr), "%d", st_get_se(p, FALSE)); 10952 add_header(req, "Min-SE", se_hdr); 10953 } 10954 10955 return 0; 10956 }
| static int resp_needs_contact | ( | const char * | msg, | |
| enum sipmethod | method | |||
| ) | [inline, static] |
Test if this response needs a contact header.
Definition at line 10670 of file chan_sip.c.
Referenced by respprep().
10670 { 10671 /* Requirements for Contact header inclusion in responses generated 10672 * from the header tables found in the following RFCs. Where the 10673 * Contact header was marked mandatory (m) or optional (o) this 10674 * function returns 1. 10675 * 10676 * - RFC 3261 (ACK, BYE, CANCEL, INVITE, OPTIONS, REGISTER) 10677 * - RFC 2976 (INFO) 10678 * - RFC 3262 (PRACK) 10679 * - RFC 3265 (SUBSCRIBE, NOTIFY) 10680 * - RFC 3311 (UPDATE) 10681 * - RFC 3428 (MESSAGE) 10682 * - RFC 3515 (REFER) 10683 * - RFC 3903 (PUBLISH) 10684 */ 10685 10686 switch (method) { 10687 /* 1xx, 2xx, 3xx, 485 */ 10688 case SIP_INVITE: 10689 case SIP_UPDATE: 10690 case SIP_SUBSCRIBE: 10691 case SIP_NOTIFY: 10692 if ((msg[0] >= '1' && msg[0] <= '3') || !strncmp(msg, "485", 3)) 10693 return 1; 10694 break; 10695 10696 /* 2xx, 3xx, 485 */ 10697 case SIP_REGISTER: 10698 case SIP_OPTIONS: 10699 if (msg[0] == '2' || msg[0] == '3' || !strncmp(msg, "485", 3)) 10700 return 1; 10701 break; 10702 10703 /* 3xx, 485 */ 10704 case SIP_BYE: 10705 case SIP_PRACK: 10706 case SIP_MESSAGE: 10707 case SIP_PUBLISH: 10708 if (msg[0] == '3' || !strncmp(msg, "485", 3)) 10709 return 1; 10710 break; 10711 10712 /* 2xx, 3xx, 4xx, 5xx, 6xx */ 10713 case SIP_REFER: 10714 if (msg[0] >= '2' && msg[0] <= '6') 10715 return 1; 10716 break; 10717 10718 /* contact will not be included for everything else */ 10719 case SIP_ACK: 10720 case SIP_CANCEL: 10721 case SIP_INFO: 10722 case SIP_PING: 10723 default: 10724 return 0; 10725 } 10726 return 0; 10727 }
| 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 10730 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().
10731 { 10732 char newto[256]; 10733 const char *ot; 10734 10735 init_resp(resp, msg); 10736 copy_via_headers(p, resp, req, "Via"); 10737 if (msg[0] == '1' || msg[0] == '2') 10738 copy_all_header(resp, req, "Record-Route"); 10739 copy_header(resp, req, "From"); 10740 ot = get_header(req, "To"); 10741 if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) { 10742 /* Add the proper tag if we don't have it already. If they have specified 10743 their tag, use it. Otherwise, use our own tag */ 10744 if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING)) 10745 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 10746 else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) 10747 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 10748 else 10749 ast_copy_string(newto, ot, sizeof(newto)); 10750 ot = newto; 10751 } 10752 add_header(resp, "To", ot); 10753 copy_header(resp, req, "Call-ID"); 10754 copy_header(resp, req, "CSeq"); 10755 if (!ast_strlen_zero(global_useragent)) 10756 add_header(resp, "Server", global_useragent); 10757 add_header(resp, "Allow", ALLOWED_METHODS); 10758 add_supported_header(p, resp); 10759 10760 /* If this is an invite, add Session-Timers related headers if the feature is active for this session */ 10761 if (p->method == SIP_INVITE && p->stimer && p->stimer->st_active == TRUE) { 10762 char se_hdr[256]; 10763 snprintf(se_hdr, sizeof(se_hdr), "%d;refresher=%s", p->stimer->st_interval, 10764 p->stimer->st_ref == SESSION_TIMER_REFRESHER_US ? "uas" : "uac"); 10765 add_header(resp, "Session-Expires", se_hdr); 10766 /* RFC 2048, Section 9 10767 * If the refresher parameter in the Session-Expires header field in the 10768 * 2xx response has a value of 'uac', the UAS MUST place a Require 10769 * header field into the response with the value 'timer'. 10770 * ... 10771 * If the refresher parameter in 10772 * the 2xx response has a value of 'uas' and the Supported header field 10773 * in the request contained the value 'timer', the UAS SHOULD place a 10774 * Require header field into the response with the value 'timer' 10775 */ 10776 if (p->stimer->st_ref == SESSION_TIMER_REFRESHER_THEM || 10777 (p->stimer->st_ref == SESSION_TIMER_REFRESHER_US && 10778 p->stimer->st_active_peer_ua == TRUE)) { 10779 resp->reqsipoptions |= SIP_OPT_TIMER; 10780 } 10781 } 10782 10783 if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_PUBLISH)) { 10784 /* For registration responses, we also need expiry and 10785 contact info */ 10786 char tmp[256]; 10787 10788 snprintf(tmp, sizeof(tmp), "%d", p->expiry); 10789 add_header(resp, "Expires", tmp); 10790 if (p->expiry) { /* Only add contact if we have an expiry time */ 10791 char contact[SIPBUFSIZE]; 10792 const char *contact_uri = p->method == SIP_SUBSCRIBE ? p->our_contact : p->fullcontact; 10793 char *brackets = strchr(contact_uri, '<'); 10794 snprintf(contact, sizeof(contact), "%s%s%s;expires=%d", brackets ? "" : "<", contact_uri, brackets ? "" : ">", p->expiry); 10795 add_header(resp, "Contact", contact); /* Not when we unregister */ 10796 } 10797 } else if (!ast_strlen_zero(p->our_contact) && resp_needs_contact(msg, p->method)) { 10798 add_header(resp, "Contact", p->our_contact); 10799 } 10800 10801 if (!ast_strlen_zero(p->url)) { 10802 add_header(resp, "Access-URL", p->url); 10803 ast_string_field_set(p, url, NULL); 10804 } 10805 10806 /* default to routing the response to the address where the request 10807 * came from. Since we don't have a transport layer, we do this here. 10808 * The process_via() function will update the port to either the port 10809 * specified in the via header or the default port later on (per RFC 10810 * 3261 section 18.2.2). 10811 */ 10812 p->sa = p->recv; 10813 10814 if (process_via(p, req)) { 10815 ast_log(LOG_WARNING, "error processing via header, will send response to originating address\n"); 10816 } 10817 10818 return 0; 10819 }
| static int restart_monitor | ( | void | ) | [static] |
Start the channel monitor thread.
Definition at line 26614 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().
26615 { 26616 /* If we're supposed to be stopped -- stay stopped */ 26617 if (monitor_thread == AST_PTHREADT_STOP) 26618 return 0; 26619 ast_mutex_lock(&monlock); 26620 if (monitor_thread == pthread_self()) { 26621 ast_mutex_unlock(&monlock); 26622 ast_log(LOG_WARNING, "Cannot kill myself\n"); 26623 return -1; 26624 } 26625 if (monitor_thread != AST_PTHREADT_NULL) { 26626 /* Wake up the thread */ 26627 pthread_kill(monitor_thread, SIGURG); 26628 } else { 26629 /* Start a new monitor */ 26630 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 26631 ast_mutex_unlock(&monlock); 26632 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 26633 return -1; 26634 } 26635 } 26636 ast_mutex_unlock(&monlock); 26637 return 0; 26638 }
| static void restart_session_timer | ( | struct sip_pvt * | p | ) | [static] |
Session-Timers: Restart session timer.
Definition at line 26642 of file chan_sip.c.
References ast_debug, ast_log(), AST_SCHED_DEL_UNREF, LOG_WARNING, start_session_timer(), and TRUE.
Referenced by handle_request_invite().
26643 { 26644 if (!p->stimer) { 26645 ast_log(LOG_WARNING, "Null stimer in restart_session_timer - %s\n", p->callid); 26646 return; 26647 } 26648 26649 if (p->stimer->st_active == TRUE) { 26650 ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid); 26651 AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid, 26652 dialog_unref(p, "Removing session timer ref")); 26653 start_session_timer(p); 26654 } 26655 }
| static int retrans_pkt | ( | const void * | data | ) | [static] |
Retransmit SIP message if no answer (Called from scheduler).
Definition at line 3888 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().
03889 { 03890 struct sip_pkt *pkt = (struct sip_pkt *)data, *prev, *cur = NULL; 03891 int reschedule = DEFAULT_RETRANS; 03892 int xmitres = 0; 03893 /* how many ms until retrans timeout is reached */ 03894 int64_t diff = pkt->retrans_stop_time - ast_tvdiff_ms(ast_tvnow(), pkt->time_sent); 03895 03896 /* Do not retransmit if time out is reached. This will be negative if the time between 03897 * the first transmission and now is larger than our timeout period. This is a fail safe 03898 * check in case the scheduler gets behind or the clock is changed. */ 03899 if ((diff <= 0) || (diff > pkt->retrans_stop_time)) { 03900 pkt->retrans_stop = 1; 03901 } 03902 03903 /* Lock channel PVT */ 03904 sip_pvt_lock(pkt->owner); 03905 03906 if (!pkt->retrans_stop) { 03907 pkt->retrans++; 03908 if (!pkt->timer_t1) { /* Re-schedule using timer_a and timer_t1 */ 03909 if (sipdebug) { 03910 ast_debug(4, "SIP TIMER: Not rescheduling id #%d:%s (Method %d) (No timer T1)\n", 03911 pkt->retransid, 03912 sip_methods[pkt->method].text, 03913 pkt->method); 03914 } 03915 } else { 03916 int siptimer_a; 03917 03918 if (sipdebug) { 03919 ast_debug(4, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", 03920 pkt->retransid, 03921 pkt->retrans, 03922 sip_methods[pkt->method].text, 03923 pkt->method); 03924 } 03925 if (!pkt->timer_a) { 03926 pkt->timer_a = 2 ; 03927 } else { 03928 pkt->timer_a = 2 * pkt->timer_a; 03929 } 03930 03931 /* For non-invites, a maximum of 4 secs */ 03932 siptimer_a = pkt->timer_t1 * pkt->timer_a; /* Double each time */ 03933 if (pkt->method != SIP_INVITE && siptimer_a > 4000) { 03934 siptimer_a = 4000; 03935 } 03936 03937 /* Reschedule re-transmit */ 03938 reschedule = siptimer_a; 03939 ast_debug(4, "** SIP timers: Rescheduling retransmission %d to %d ms (t1 %d ms (Retrans id #%d)) \n", 03940 pkt->retrans + 1, 03941 siptimer_a, 03942 pkt->timer_t1, 03943 pkt->retransid); 03944 } 03945 03946 if (sip_debug_test_pvt(pkt->owner)) { 03947 const struct ast_sockaddr *dst = sip_real_dst(pkt->owner); 03948 ast_verbose("Retransmitting #%d (%s) to %s:\n%s\n---\n", 03949 pkt->retrans, sip_nat_mode(pkt->owner), 03950 ast_sockaddr_stringify(dst), 03951 ast_str_buffer(pkt->data)); 03952 } 03953 03954 append_history(pkt->owner, "ReTx", "%d %s", reschedule, ast_str_buffer(pkt->data)); 03955 xmitres = __sip_xmit(pkt->owner, pkt->data); 03956 03957 /* If there was no error during the network transmission, schedule the next retransmission, 03958 * but if the next retransmission is going to be beyond our timeout period, mark the packet's 03959 * stop_retrans value and set the next retransmit to be the exact time of timeout. This will 03960 * allow any responses to the packet to be processed before the packet is destroyed on the next 03961 * call to this function by the scheduler. */ 03962 if (xmitres != XMIT_ERROR) { 03963 if (reschedule >= diff) { 03964 pkt->retrans_stop = 1; 03965 reschedule = diff; 03966 } 03967 sip_pvt_unlock(pkt->owner); 03968 return reschedule; 03969 } 03970 } 03971 03972 /* At this point, either the packet's retransmission timed out, or there was a 03973 * transmission error, either way destroy the scheduler item and this packet. */ 03974 03975 pkt->retransid = -1; /* Kill this scheduler item */ 03976 03977 if (pkt->method != SIP_OPTIONS && xmitres == 0) { 03978 if (pkt->is_fatal || sipdebug) { /* Tell us if it's critical or if we're debugging */ 03979 ast_log(LOG_WARNING, "Retransmission timeout reached on transmission %s from %s for seqno %u (%s %s) -- See https://wiki.asterisk.org/wiki/display/AST/SIP+Retransmissions\n" 03980 "Packet timed out after %dms with no response\n", 03981 pkt->owner->callid, 03982 pkt->owner->from, 03983 pkt->seqno, 03984 pkt->is_fatal ? "Critical" : "Non-critical", 03985 pkt->is_resp ? "Response" : "Request", 03986 (int) ast_tvdiff_ms(ast_tvnow(), pkt->time_sent)); 03987 } 03988 } else if (pkt->method == SIP_OPTIONS && sipdebug) { 03989 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); 03990 } 03991 03992 if (xmitres == XMIT_ERROR) { 03993 ast_log(LOG_WARNING, "Transmit error :: Cancelling transmission on Call ID %s\n", pkt->owner->callid); 03994 append_history(pkt->owner, "XmitErr", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)"); 03995 } else { 03996 append_history(pkt->owner, "MaxRetries", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)"); 03997 } 03998 03999 if (pkt->is_fatal) { 04000 while(pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) { 04001 sip_pvt_unlock(pkt->owner); /* SIP_PVT, not channel */ 04002 usleep(1); 04003 sip_pvt_lock(pkt->owner); 04004 } 04005 if (pkt->owner->owner && !pkt->owner->owner->hangupcause) { 04006 pkt->owner->owner->hangupcause = AST_CAUSE_NO_USER_RESPONSE; 04007 } 04008 if (pkt->owner->owner) { 04009 ast_log(LOG_WARNING, "Hanging up call %s from channel %s - no reply to our critical packet (see https://wiki.asterisk.org/wiki/display/AST/SIP+Retransmissions).\n", pkt->owner->callid, pkt->owner->owner->name); 04010 04011 if (pkt->is_resp && 04012 (pkt->response_code >= 200) && 04013 (pkt->response_code < 300) && 04014 pkt->owner->pendinginvite && 04015 ast_test_flag(&pkt->owner->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) { 04016 /* This is a timeout of the 2XX response to a pending INVITE. In this case terminate the INVITE 04017 * transaction just as if we received the ACK, but immediately hangup with a BYE (sip_hangup 04018 * will send the BYE as long as the dialog is not set as "alreadygone") 04019 * RFC 3261 section 13.3.1.4. 04020 * "If the server retransmits the 2xx response for 64*T1 seconds without receiving 04021 * an ACK, the dialog is confirmed, but the session SHOULD be terminated. This is 04022 * accomplished with a BYE, as described in Section 15." */ 04023 pkt->owner->invitestate = INV_TERMINATED; 04024 pkt->owner->pendinginvite = 0; 04025 } else { 04026 /* there is nothing left to do, mark the dialog as gone */ 04027 sip_alreadygone(pkt->owner); 04028 } 04029 ast_queue_hangup_with_cause(pkt->owner->owner, AST_CAUSE_NO_USER_RESPONSE); 04030 ast_channel_unlock(pkt->owner->owner); 04031 } else { 04032 /* If no channel owner, destroy now */ 04033 04034 /* Let the peerpoke system expire packets when the timer expires for poke_noanswer */ 04035 if (pkt->method != SIP_OPTIONS && pkt->method != SIP_REGISTER) { 04036 pvt_set_needdestroy(pkt->owner, "no response to critical packet"); 04037 sip_alreadygone(pkt->owner); 04038 append_history(pkt->owner, "DialogKill", "Killing this failed dialog immediately"); 04039 } 04040 } 04041 } 04042 04043 if (pkt->method == SIP_BYE) { 04044 /* We're not getting answers on SIP BYE's. Tear down the call anyway. */ 04045 sip_alreadygone(pkt->owner); 04046 if (pkt->owner->owner) { 04047 ast_channel_unlock(pkt->owner->owner); 04048 } 04049 append_history(pkt->owner, "ByeFailure", "Remote peer doesn't respond to bye. Destroying call anyway."); 04050 pvt_set_needdestroy(pkt->owner, "no response to BYE"); 04051 } 04052 04053 /* Remove the packet */ 04054 for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) { 04055 if (cur == pkt) { 04056 UNLINK(cur, pkt->owner->packets, prev); 04057 sip_pvt_unlock(pkt->owner); 04058 if (pkt->owner) { 04059 pkt->owner = dialog_unref(pkt->owner,"pkt is being freed, its dialog ref is dead now"); 04060 } 04061 if (pkt->data) { 04062 ast_free(pkt->data); 04063 } 04064 pkt->data = NULL; 04065 ast_free(pkt); 04066 return 0; 04067 } 04068 } 04069 /* error case */ 04070 ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n"); 04071 sip_pvt_unlock(pkt->owner); 04072 return 0; 04073 }
| static int send_provisional_keepalive | ( | const void * | data | ) | [static] |
Definition at line 4480 of file chan_sip.c.
References send_provisional_keepalive_full().
Referenced by update_provisional_keepalive().
04480 { 04481 struct sip_pvt *pvt = (struct sip_pvt *) data; 04482 04483 return send_provisional_keepalive_full(pvt, 0); 04484 }
| static int send_provisional_keepalive_full | ( | struct sip_pvt * | pvt, | |
| int | with_sdp | |||
| ) | [static] |
Definition at line 4431 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().
04432 { 04433 const char *msg = NULL; 04434 struct ast_channel *chan; 04435 int res = 0; 04436 04437 chan = sip_pvt_lock_full(pvt); 04438 04439 if (!pvt->last_provisional || !strncasecmp(pvt->last_provisional, "100", 3)) { 04440 msg = "183 Session Progress"; 04441 } 04442 04443 if (pvt->invitestate < INV_COMPLETED) { 04444 if (with_sdp) { 04445 transmit_response_with_sdp(pvt, S_OR(msg, pvt->last_provisional), &pvt->initreq, XMIT_UNRELIABLE, FALSE, FALSE); 04446 } else { 04447 transmit_response(pvt, S_OR(msg, pvt->last_provisional), &pvt->initreq); 04448 } 04449 res = PROVIS_KEEPALIVE_TIMEOUT; 04450 } 04451 04452 if (chan) { 04453 ast_channel_unlock(chan); 04454 chan = ast_channel_unref(chan); 04455 } 04456 04457 if (!res) { 04458 pvt->provisional_keepalive_sched_id = -1; 04459 } 04460 04461 sip_pvt_unlock(pvt); 04462 04463 #if 0 04464 /* 04465 * XXX BUG TODO 04466 * 04467 * Without this code, it appears as if this function is leaking its 04468 * reference to the sip_pvt. However, adding it introduces a crash. 04469 * This points to some sort of reference count imbalance elsewhere, 04470 * but I'm not sure where ... 04471 */ 04472 if (!res) { 04473 dialog_unref(pvt, "dialog ref for provisional keepalive"); 04474 } 04475 #endif 04476 04477 return res; 04478 }
| static int send_provisional_keepalive_with_sdp | ( | const void * | data | ) | [static] |
Definition at line 4486 of file chan_sip.c.
References send_provisional_keepalive_full().
Referenced by update_provisional_keepalive().
04486 { 04487 struct sip_pvt *pvt = (void *)data; 04488 04489 return send_provisional_keepalive_full(pvt, 1); 04490 }
| static int send_request | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| enum xmittype | reliable, | |||
| uint32_t | seqno | |||
| ) | [static] |
Definition at line 4571 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().
04572 { 04573 int res; 04574 04575 /* If we have an outbound proxy, reset peer address 04576 Only do this once. 04577 */ 04578 if (p->outboundproxy) { 04579 p->sa = p->outboundproxy->ip; 04580 } 04581 04582 finalize_content(req); 04583 add_blank(req); 04584 if (sip_debug_test_pvt(p)) { 04585 if (ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT)) { 04586 ast_verbose("%sTransmitting (NAT) to %s:\n%s\n---\n", reliable ? "Reliably " : "", ast_sockaddr_stringify(&p->recv), ast_str_buffer(req->data)); 04587 } else { 04588 ast_verbose("%sTransmitting (no NAT) to %s:\n%s\n---\n", reliable ? "Reliably " : "", ast_sockaddr_stringify(&p->sa), ast_str_buffer(req->data)); 04589 } 04590 } 04591 if (p->do_history) { 04592 struct sip_request tmp = { .rlPart1 = 0, }; 04593 parse_copy(&tmp, req); 04594 append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", ast_str_buffer(tmp.data), get_header(&tmp, "CSeq"), sip_methods[tmp.method].text); 04595 deinit_req(&tmp); 04596 } 04597 res = (reliable) ? 04598 __sip_reliable_xmit(p, seqno, 0, req->data, (reliable == XMIT_CRITICAL), req->method) : 04599 __sip_xmit(p, req->data); 04600 deinit_req(req); 04601 return res; 04602 }
| 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 4529 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().
04530 { 04531 int res; 04532 04533 finalize_content(req); 04534 add_blank(req); 04535 if (sip_debug_test_pvt(p)) { 04536 const struct ast_sockaddr *dst = sip_real_dst(p); 04537 04538 ast_verbose("\n<--- %sTransmitting (%s) to %s --->\n%s\n<------------>\n", 04539 reliable ? "Reliably " : "", sip_nat_mode(p), 04540 ast_sockaddr_stringify(dst), 04541 ast_str_buffer(req->data)); 04542 } 04543 if (p->do_history) { 04544 struct sip_request tmp = { .rlPart1 = 0, }; 04545 parse_copy(&tmp, req); 04546 append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", ast_str_buffer(tmp.data), get_header(&tmp, "CSeq"), 04547 (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? REQ_OFFSET_TO_STR(&tmp, rlPart2) : sip_methods[tmp.method].text); 04548 deinit_req(&tmp); 04549 } 04550 04551 /* If we are sending a final response to an INVITE, stop retransmitting provisional responses */ 04552 if (p->initreq.method == SIP_INVITE && reliable == XMIT_CRITICAL) { 04553 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")); 04554 } 04555 04556 res = (reliable) ? 04557 __sip_reliable_xmit(p, seqno, 1, req->data, (reliable == XMIT_CRITICAL), req->method) : 04558 __sip_xmit(p, req->data); 04559 deinit_req(req); 04560 if (res > 0) { 04561 return 0; 04562 } 04563 return res; 04564 }
| static enum ast_cc_service_type service_string_to_service_type | ( | const char *const | service_string | ) | [static] |
Definition at line 841 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().
00842 { 00843 enum ast_cc_service_type service; 00844 for (service = AST_CC_CCBS; service <= AST_CC_CCNL; ++service) { 00845 if (!strcasecmp(service_string, sip_cc_service_map[service].service_string)) { 00846 return service; 00847 } 00848 } 00849 return AST_CC_NONE; 00850 }
| static int set_address_from_contact | ( | struct sip_pvt * | pvt | ) | [static] |
Change the other partys IP address based on given contact.
Definition at line 14486 of file chan_sip.c.
References __set_address_from_contact(), and ast_test_flag.
Referenced by handle_response_invite().
14487 { 14488 if (ast_test_flag(&pvt->flags[0], SIP_NAT_FORCE_RPORT)) { 14489 /* NAT: Don't trust the contact field. Just use what they came to us 14490 with. */ 14491 /*! \todo We need to save the TRANSPORT here too */ 14492 pvt->sa = pvt->recv; 14493 return 0; 14494 } 14495 14496 return __set_address_from_contact(pvt->fullcontact, &pvt->sa, pvt->socket.type == SIP_TRANSPORT_TLS ? 1 : 0); 14497 }
| 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 10539 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().
10540 { 10541 char *h, *maddr, hostname[256]; 10542 int hn; 10543 int debug=sip_debug_test_pvt(p); 10544 int tls_on = FALSE; 10545 10546 if (debug) 10547 ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri); 10548 10549 /* Find and parse hostname */ 10550 h = strchr(uri, '@'); 10551 if (h) 10552 ++h; 10553 else { 10554 h = uri; 10555 if (!strncasecmp(h, "sip:", 4)) { 10556 h += 4; 10557 } else if (!strncasecmp(h, "sips:", 5)) { 10558 h += 5; 10559 tls_on = TRUE; 10560 } 10561 } 10562 hn = strcspn(h, ";>") + 1; 10563 if (hn > sizeof(hostname)) 10564 hn = sizeof(hostname); 10565 ast_copy_string(hostname, h, hn); 10566 /* XXX bug here if string has been trimmed to sizeof(hostname) */ 10567 h += hn - 1; 10568 10569 /*! \todo XXX If we have sip_cfg.srvlookup on, then look for NAPTR/SRV, 10570 * otherwise, just look for A records */ 10571 if (ast_sockaddr_resolve_first_transport(&p->sa, hostname, 0, p->socket.type)) { 10572 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 10573 return; 10574 } 10575 10576 /* Got the hostname - but maybe there's a "maddr=" to override address? */ 10577 maddr = strstr(h, "maddr="); 10578 if (maddr) { 10579 int port; 10580 10581 maddr += 6; 10582 hn = strspn(maddr, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 10583 "0123456789-.:[]") + 1; 10584 if (hn > sizeof(hostname)) 10585 hn = sizeof(hostname); 10586 ast_copy_string(hostname, maddr, hn); 10587 10588 port = ast_sockaddr_port(&p->sa); 10589 10590 /*! \todo XXX If we have sip_cfg.srvlookup on, then look for 10591 * NAPTR/SRV, otherwise, just look for A records */ 10592 if (ast_sockaddr_resolve_first_transport(&p->sa, hostname, PARSE_PORT_FORBID, p->socket.type)) { 10593 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 10594 return; 10595 } 10596 10597 ast_sockaddr_set_port(&p->sa, port); 10598 } 10599 10600 if (!ast_sockaddr_port(&p->sa)) { 10601 ast_sockaddr_set_port(&p->sa, tls_on ? 10602 STANDARD_TLS_PORT : STANDARD_SIP_PORT); 10603 } 10604 10605 if (debug) { 10606 ast_verbose("set_destination: set destination to %s\n", 10607 ast_sockaddr_stringify(&p->sa)); 10608 } 10609 }
| 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 27403 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().
27404 { 27405 if (ast_strlen_zero(value)) 27406 return; 27407 27408 if (!ast_false(value)) { 27409 char buf[64]; 27410 char *word, *next; 27411 27412 ast_copy_string(buf, value, sizeof(buf)); 27413 next = buf; 27414 while ((word = strsep(&next, ","))) { 27415 if (!strcasecmp(word, "port")) 27416 ast_set_flag(&flags[0], SIP_INSECURE_PORT); 27417 else if (!strcasecmp(word, "invite")) 27418 ast_set_flag(&flags[0], SIP_INSECURE_INVITE); 27419 else 27420 ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno); 27421 } 27422 } 27423 }
| 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 14859 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().
14860 { 14861 if (p->stalenonce || forceupdate || ast_strlen_zero(p->randdata)) { 14862 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 14863 p->stalenonce = 0; 14864 } 14865 }
| static void set_peer_defaults | ( | struct sip_peer * | peer | ) | [static] |
Set peer defaults before configuring specific configurations.
Definition at line 27827 of file chan_sip.c.
References 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().
27828 { 27829 if (peer->expire == 0) { 27830 /* Don't reset expire or port time during reload 27831 if we have an active registration 27832 */ 27833 peer->expire = -1; 27834 peer->pokeexpire = -1; 27835 set_socket_transport(&peer->socket, SIP_TRANSPORT_UDP); 27836 } 27837 peer->type = SIP_TYPE_PEER; 27838 ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 27839 ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 27840 ast_copy_flags(&peer->flags[2], &global_flags[2], SIP_PAGE3_FLAGS_TO_COPY); 27841 ast_string_field_set(peer, context, sip_cfg.default_context); 27842 ast_string_field_set(peer, subscribecontext, sip_cfg.default_subscribecontext); 27843 ast_string_field_set(peer, language, default_language); 27844 ast_string_field_set(peer, mohinterpret, default_mohinterpret); 27845 ast_string_field_set(peer, mohsuggest, default_mohsuggest); 27846 ast_string_field_set(peer, engine, default_engine); 27847 ast_sockaddr_setnull(&peer->addr); 27848 ast_sockaddr_setnull(&peer->defaddr); 27849 peer->capability = sip_cfg.capability; 27850 peer->maxcallbitrate = default_maxcallbitrate; 27851 peer->rtptimeout = global_rtptimeout; 27852 peer->rtpholdtimeout = global_rtpholdtimeout; 27853 peer->rtpkeepalive = global_rtpkeepalive; 27854 peer->allowtransfer = sip_cfg.allowtransfer; 27855 peer->autoframing = global_autoframing; 27856 peer->t38_maxdatagram = global_t38_maxdatagram; 27857 peer->qualifyfreq = global_qualifyfreq; 27858 if (global_callcounter) 27859 peer->call_limit=INT_MAX; 27860 ast_string_field_set(peer, vmexten, default_vmexten); 27861 ast_string_field_set(peer, secret, ""); 27862 ast_string_field_set(peer, remotesecret, ""); 27863 ast_string_field_set(peer, md5secret, ""); 27864 ast_string_field_set(peer, cid_num, ""); 27865 ast_string_field_set(peer, cid_name, ""); 27866 ast_string_field_set(peer, cid_tag, ""); 27867 ast_string_field_set(peer, fromdomain, ""); 27868 ast_string_field_set(peer, fromuser, ""); 27869 ast_string_field_set(peer, regexten, ""); 27870 peer->callgroup = 0; 27871 peer->pickupgroup = 0; 27872 peer->maxms = default_qualify; 27873 peer->prefs = default_prefs; 27874 peer->stimer.st_mode_oper = global_st_mode; /* Session-Timers */ 27875 peer->stimer.st_ref = global_st_refresher; 27876 peer->stimer.st_min_se = global_min_se; 27877 peer->stimer.st_max_se = global_max_se; 27878 peer->timer_t1 = global_t1; 27879 peer->timer_b = global_timer_b; 27880 clear_peer_mailboxes(peer); 27881 peer->disallowed_methods = sip_cfg.disallowed_methods; 27882 peer->transports = default_transports; 27883 peer->default_outbound_transport = default_primary_transport; 27884 }
| 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 8851 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().
08852 { 08853 pvt->allowed_methods = parse_allowed_methods(req); 08854 08855 if (ast_test_flag(&pvt->flags[1], SIP_PAGE2_RPID_UPDATE)) { 08856 mark_method_allowed(&pvt->allowed_methods, SIP_UPDATE); 08857 } 08858 pvt->allowed_methods &= ~(pvt->disallowed_methods); 08859 08860 return pvt->allowed_methods; 08861 }
| static void set_socket_transport | ( | struct sip_socket * | socket, | |
| int | transport | |||
| ) | [static] |
Definition at line 14240 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().
14241 { 14242 /* if the transport type changes, clear all socket data */ 14243 if (socket->type != transport) { 14244 socket->fd = -1; 14245 socket->type = transport; 14246 if (socket->tcptls_session) { 14247 ao2_ref(socket->tcptls_session, -1); 14248 socket->tcptls_session = NULL; 14249 } 14250 } 14251 }
| static void set_t38_capabilities | ( | struct sip_pvt * | p | ) | [static] |
Set the global T38 capabilities on a SIP dialog structure.
Definition at line 5539 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().
05540 { 05541 if (p->udptl) { 05542 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) == SIP_PAGE2_T38SUPPORT_UDPTL_REDUNDANCY) { 05543 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY); 05544 } else if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) == SIP_PAGE2_T38SUPPORT_UDPTL_FEC) { 05545 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC); 05546 } else if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) == SIP_PAGE2_T38SUPPORT_UDPTL) { 05547 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 05548 } 05549 } 05550 }
| static int setup_srtp | ( | struct sip_srtp ** | srtp | ) | [static] |
Definition at line 30412 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().
30413 { 30414 if (!ast_rtp_engine_srtp_is_registered()) { 30415 ast_log(LOG_ERROR, "No SRTP module loaded, can't setup SRTP session.\n"); 30416 return -1; 30417 } 30418 30419 if (!(*srtp = sip_srtp_alloc())) { /* Allocate SRTP data structure */ 30420 return -1; 30421 } 30422 30423 return 0; 30424 }
| static int show_channels_cb | ( | void * | __cur, | |
| void * | __arg, | |||
| int | flags | |||
| ) | [static] |
callback for show channel|subscription
Definition at line 18978 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().
18979 { 18980 struct sip_pvt *cur = __cur; 18981 struct __show_chan_arg *arg = __arg; 18982 const struct ast_sockaddr *dst; 18983 18984 sip_pvt_lock(cur); 18985 dst = sip_real_dst(cur); 18986 18987 /* XXX indentation preserved to reduce diff. Will be fixed later */ 18988 if (cur->subscribed == NONE && !arg->subscriptions) { 18989 /* set if SIP transfer in progress */ 18990 const char *referstatus = cur->refer ? referstatus2str(cur->refer->status) : ""; 18991 char formatbuf[SIPBUFSIZE/2]; 18992 18993 ast_cli(arg->fd, FORMAT, ast_sockaddr_stringify_addr(dst), 18994 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 18995 cur->callid, 18996 ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0), 18997 AST_CLI_YESNO(ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD)), 18998 cur->needdestroy ? "(d)" : "", 18999 cur->lastmsg , 19000 referstatus, 19001 cur->relatedpeer ? cur->relatedpeer->name : "<guest>" 19002 ); 19003 arg->numchans++; 19004 } 19005 if (cur->subscribed != NONE && arg->subscriptions) { 19006 struct ast_str *mailbox_str = ast_str_alloca(512); 19007 if (cur->subscribed == MWI_NOTIFICATION && cur->relatedpeer) 19008 peer_mailboxes_to_str(&mailbox_str, cur->relatedpeer); 19009 ast_cli(arg->fd, FORMAT4, ast_sockaddr_stringify_addr(dst), 19010 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 19011 cur->callid, 19012 /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */ 19013 cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri, 19014 cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 19015 subscription_type2str(cur->subscribed), 19016 cur->subscribed == MWI_NOTIFICATION ? S_OR(ast_str_buffer(mailbox_str), "<none>") : "<none>", 19017 cur->expiry 19018 ); 19019 arg->numchans++; 19020 } 19021 sip_pvt_unlock(cur); 19022 return 0; /* don't care, we scan all channels */ 19023 }
| static int show_chanstats_cb | ( | void * | __cur, | |
| void * | __arg, | |||
| int | flags | |||
| ) | [static] |
Callback for show_chanstats.
Definition at line 18581 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().
18582 { 18583 #define FORMAT2 "%-15.15s %-11.11s %-8.8s %-10.10s %-10.10s ( %%) %-6.6s %-10.10s %-10.10s ( %%) %-6.6s\n" 18584 #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" 18585 struct sip_pvt *cur = __cur; 18586 struct ast_rtp_instance_stats stats; 18587 char durbuf[10]; 18588 int duration; 18589 int durh, durm, durs; 18590 struct ast_channel *c; 18591 struct __show_chan_arg *arg = __arg; 18592 int fd = arg->fd; 18593 18594 sip_pvt_lock(cur); 18595 c = cur->owner; 18596 18597 if (cur->subscribed != NONE) { 18598 /* Subscriptions */ 18599 sip_pvt_unlock(cur); 18600 return 0; /* don't care, we scan all channels */ 18601 } 18602 18603 if (!cur->rtp) { 18604 if (sipdebug) { 18605 ast_cli(fd, "%-15.15s %-11.11s (inv state: %s) -- %s\n", 18606 ast_sockaddr_stringify_addr(&cur->sa), cur->callid, 18607 invitestate2string[cur->invitestate].desc, 18608 "-- No RTP active"); 18609 } 18610 sip_pvt_unlock(cur); 18611 return 0; /* don't care, we scan all channels */ 18612 } 18613 18614 if (ast_rtp_instance_get_stats(cur->rtp, &stats, AST_RTP_INSTANCE_STAT_ALL)) { 18615 sip_pvt_unlock(cur); 18616 ast_log(LOG_WARNING, "Could not get RTP stats.\n"); 18617 return 0; 18618 } 18619 18620 if (c && c->cdr && !ast_tvzero(c->cdr->start)) { 18621 duration = (int)(ast_tvdiff_ms(ast_tvnow(), c->cdr->start) / 1000); 18622 durh = duration / 3600; 18623 durm = (duration % 3600) / 60; 18624 durs = duration % 60; 18625 snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs); 18626 } else { 18627 durbuf[0] = '\0'; 18628 } 18629 18630 ast_cli(fd, FORMAT, 18631 ast_sockaddr_stringify_addr(&cur->sa), 18632 cur->callid, 18633 durbuf, 18634 stats.rxcount > (unsigned int) 100000 ? (unsigned int) (stats.rxcount)/(unsigned int) 1000 : stats.rxcount, 18635 stats.rxcount > (unsigned int) 100000 ? "K":" ", 18636 stats.rxploss, 18637 (stats.rxcount + stats.rxploss) > 0 ? (double) stats.rxploss / (stats.rxcount + stats.rxploss) * 100 : 0, 18638 stats.rxjitter, 18639 stats.txcount > (unsigned int) 100000 ? (unsigned int) (stats.txcount)/(unsigned int) 1000 : stats.txcount, 18640 stats.txcount > (unsigned int) 100000 ? "K":" ", 18641 stats.txploss, 18642 stats.txcount > 0 ? (double) stats.txploss / stats.txcount * 100 : 0, 18643 stats.txjitter 18644 ); 18645 arg->numchans++; 18646 sip_pvt_unlock(cur); 18647 18648 return 0; /* don't care, we scan all channels */ 18649 }
| static int sip_addheader | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Add a SIP header to an outbound INVITE.
Definition at line 30199 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().
30200 { 30201 int no = 0; 30202 int ok = FALSE; 30203 char varbuf[30]; 30204 const char *inbuf = data; 30205 char *subbuf; 30206 30207 if (ast_strlen_zero(inbuf)) { 30208 ast_log(LOG_WARNING, "This application requires the argument: Header\n"); 30209 return 0; 30210 } 30211 ast_channel_lock(chan); 30212 30213 /* Check for headers */ 30214 while (!ok && no <= 50) { 30215 no++; 30216 snprintf(varbuf, sizeof(varbuf), "__SIPADDHEADER%.2d", no); 30217 30218 /* Compare without the leading underscores */ 30219 if ((pbx_builtin_getvar_helper(chan, (const char *) varbuf + 2) == (const char *) NULL)) { 30220 ok = TRUE; 30221 } 30222 } 30223 if (ok) { 30224 size_t len = strlen(inbuf); 30225 subbuf = ast_alloca(len + 1); 30226 ast_get_encoded_str(inbuf, subbuf, len + 1); 30227 pbx_builtin_setvar_helper(chan, varbuf, subbuf); 30228 if (sipdebug) { 30229 ast_debug(1, "SIP Header added \"%s\" as %s\n", inbuf, varbuf); 30230 } 30231 } else { 30232 ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n"); 30233 } 30234 ast_channel_unlock(chan); 30235 return 0; 30236 }
| 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 8086 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().
08088 { 08089 struct sip_pvt *p; 08090 08091 if (!(p = ao2_t_alloc(sizeof(*p), sip_destroy_fn, "allocate a dialog(pvt) struct"))) 08092 return NULL; 08093 08094 if (ast_string_field_init(p, 512)) { 08095 ao2_t_ref(p, -1, "failed to string_field_init, drop p"); 08096 return NULL; 08097 } 08098 08099 if (!(p->cc_params = ast_cc_config_params_init())) { 08100 ao2_t_ref(p, -1, "Yuck, couldn't allocate cc_params struct. Get rid o' p"); 08101 return NULL; 08102 } 08103 08104 /* If this dialog is created as the result of an incoming Request. Lets store 08105 * some information about that request */ 08106 if (req) { 08107 struct sip_via *via; 08108 const char *cseq = get_header(req, "Cseq"); 08109 uint32_t seqno; 08110 08111 /* get branch parameter from initial Request that started this dialog */ 08112 via = parse_via(get_header(req, "Via")); 08113 if (via) { 08114 /* only store the branch if it begins with the magic prefix "z9hG4bK", otherwise 08115 * it is not useful to us to have it */ 08116 if (!ast_strlen_zero(via->branch) && !strncasecmp(via->branch, "z9hG4bK", 7)) { 08117 ast_string_field_set(p, initviabranch, via->branch); 08118 ast_string_field_set(p, initviasentby, via->sent_by); 08119 } 08120 free_via(via); 08121 } 08122 08123 /* Store initial incoming cseq. An error in sscanf here is ignored. There is no approperiate 08124 * except not storing the number. CSeq validation must take place before dialog creation in find_call */ 08125 if (!ast_strlen_zero(cseq) && (sscanf(cseq, "%30u", &seqno) == 1)) { 08126 p->init_icseq = seqno; 08127 } 08128 /* Later in ast_sip_ouraddrfor we need this to choose the right ip and port for the specific transport */ 08129 set_socket_transport(&p->socket, req->socket.type); 08130 } else { 08131 set_socket_transport(&p->socket, SIP_TRANSPORT_UDP); 08132 } 08133 08134 p->socket.fd = -1; 08135 p->method = intended_method; 08136 p->initid = -1; 08137 p->waitid = -1; 08138 p->reinviteid = -1; 08139 p->autokillid = -1; 08140 p->request_queue_sched_id = -1; 08141 p->provisional_keepalive_sched_id = -1; 08142 p->t38id = -1; 08143 p->subscribed = NONE; 08144 p->stateid = -1; 08145 p->sessionversion_remote = -1; 08146 p->session_modify = TRUE; 08147 p->stimer = NULL; 08148 p->prefs = default_prefs; /* Set default codecs for this call */ 08149 p->maxforwards = sip_cfg.default_max_forwards; 08150 08151 if (intended_method != SIP_OPTIONS) { /* Peerpoke has it's own system */ 08152 p->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */ 08153 p->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */ 08154 } 08155 08156 if (!addr) { 08157 p->ourip = internip; 08158 } else { 08159 ast_sockaddr_copy(&p->sa, addr); 08160 ast_sip_ouraddrfor(&p->sa, &p->ourip, p); 08161 } 08162 08163 /* Copy global flags to this PVT at setup. */ 08164 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 08165 ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 08166 ast_copy_flags(&p->flags[2], &global_flags[2], SIP_PAGE3_FLAGS_TO_COPY); 08167 08168 p->do_history = recordhistory; 08169 08170 p->branch = ast_random(); 08171 make_our_tag(p); 08172 p->ocseq = INITIAL_CSEQ; 08173 p->allowed_methods = UINT_MAX; 08174 08175 if (sip_methods[intended_method].need_rtp) { 08176 p->maxcallbitrate = default_maxcallbitrate; 08177 p->autoframing = global_autoframing; 08178 } 08179 08180 if (useglobal_nat && addr) { 08181 /* Setup NAT structure according to global settings if we have an address */ 08182 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT_FORCE_RPORT); 08183 ast_sockaddr_copy(&p->recv, addr); 08184 08185 do_setnat(p); 08186 } 08187 08188 if (p->method != SIP_REGISTER) { 08189 ast_string_field_set(p, fromdomain, default_fromdomain); 08190 p->fromdomainport = default_fromdomainport; 08191 } 08192 build_via(p); 08193 if (!callid) 08194 build_callid_pvt(p); 08195 else 08196 ast_string_field_set(p, callid, callid); 08197 /* Assign default music on hold class */ 08198 ast_string_field_set(p, mohinterpret, default_mohinterpret); 08199 ast_string_field_set(p, mohsuggest, default_mohsuggest); 08200 p->capability = sip_cfg.capability; 08201 p->allowtransfer = sip_cfg.allowtransfer; 08202 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 08203 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) { 08204 p->noncodeccapability |= AST_RTP_DTMF; 08205 } 08206 ast_string_field_set(p, context, sip_cfg.default_context); 08207 ast_string_field_set(p, parkinglot, default_parkinglot); 08208 ast_string_field_set(p, engine, default_engine); 08209 08210 AST_LIST_HEAD_INIT_NOLOCK(&p->request_queue); 08211 08212 /* Add to active dialog list */ 08213 08214 ao2_t_link(dialogs, p, "link pvt into dialogs table"); 08215 08216 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"); 08217 return p; 08218 }
| 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 3371 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().
03372 { 03373 ast_debug(3, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid); 03374 dialog->alreadygone = 1; 03375 }
| 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 6875 of file chan_sip.c.
References ast_channel::_state, ast_debug, ast_rtp_instance_update_source(), ast_set_flag, ast_setstate(), AST_STATE_UP, FALSE, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, transmit_response_with_sdp(), TRUE, and try_suggested_sip_codec().
06876 { 06877 int res = 0; 06878 struct sip_pvt *p = ast->tech_pvt; 06879 06880 sip_pvt_lock(p); 06881 if (ast->_state != AST_STATE_UP) { 06882 try_suggested_sip_codec(p); 06883 06884 ast_setstate(ast, AST_STATE_UP); 06885 ast_debug(1, "SIP answering channel: %s\n", ast->name); 06886 ast_rtp_instance_update_source(p->rtp); 06887 res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL, FALSE, TRUE); 06888 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 06889 } 06890 sip_pvt_unlock(p); 06891 return res; 06892 }
| 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 5911 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.
05912 { 05913 int res; 05914 struct sip_pvt *p = ast->tech_pvt; /* chan is locked, so the reference cannot go away */ 05915 struct varshead *headp; 05916 struct ast_var_t *current; 05917 const char *referer = NULL; /* SIP referrer */ 05918 int cc_core_id; 05919 char uri[SIPBUFSIZE] = ""; 05920 05921 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 05922 ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name); 05923 return -1; 05924 } 05925 05926 if (ast_cc_is_recall(ast, &cc_core_id, "SIP")) { 05927 char device_name[AST_CHANNEL_NAME]; 05928 struct ast_cc_monitor *recall_monitor; 05929 struct sip_monitor_instance *monitor_instance; 05930 ast_channel_get_device_name(ast, device_name, sizeof(device_name)); 05931 if ((recall_monitor = ast_cc_get_monitor_by_recall_core_id(cc_core_id, device_name))) { 05932 monitor_instance = recall_monitor->private_data; 05933 ast_copy_string(uri, monitor_instance->notify_uri, sizeof(uri)); 05934 ao2_t_ref(recall_monitor, -1, "Got the URI we need so unreffing monitor"); 05935 } 05936 } 05937 05938 /* Check whether there is vxml_url, distinctive ring variables */ 05939 headp=&ast->varshead; 05940 AST_LIST_TRAVERSE(headp, current, entries) { 05941 /* Check whether there is a VXML_URL variable */ 05942 if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) { 05943 p->options->vxml_url = ast_var_value(current); 05944 } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) { 05945 p->options->uri_options = ast_var_value(current); 05946 } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 05947 /* Check whether there is a variable with a name starting with SIPADDHEADER */ 05948 p->options->addsipheaders = 1; 05949 } else if (!strcasecmp(ast_var_name(current), "SIPFROMDOMAIN")) { 05950 ast_string_field_set(p, fromdomain, ast_var_value(current)); 05951 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) { 05952 /* This is a transfered call */ 05953 p->options->transfer = 1; 05954 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) { 05955 /* This is the referrer */ 05956 referer = ast_var_value(current); 05957 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) { 05958 /* We're replacing a call. */ 05959 p->options->replaces = ast_var_value(current); 05960 } else if (!strcasecmp(ast_var_name(current), "SIP_MAX_FORWARDS")) { 05961 if (sscanf(ast_var_value(current), "%d", &(p->maxforwards)) != 1) { 05962 ast_log(LOG_WARNING, "The SIP_MAX_FORWARDS channel variable is not a valid integer.\n"); 05963 } 05964 } 05965 } 05966 05967 /* Check to see if we should try to force encryption */ 05968 if (p->req_secure_signaling && p->socket.type != SIP_TRANSPORT_TLS) { 05969 ast_log(LOG_WARNING, "Encrypted signaling is required\n"); 05970 ast->hangupcause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 05971 return -1; 05972 } 05973 05974 if (ast_test_flag(&p->flags[1], SIP_PAGE2_USE_SRTP)) { 05975 if (ast_test_flag(&p->flags[0], SIP_REINVITE)) { 05976 ast_debug(1, "Direct media not possible when using SRTP, ignoring canreinvite setting\n"); 05977 ast_clear_flag(&p->flags[0], SIP_REINVITE); 05978 } 05979 05980 if (p->rtp && !p->srtp && setup_srtp(&p->srtp) < 0) { 05981 ast_log(LOG_WARNING, "SRTP audio setup failed\n"); 05982 return -1; 05983 } 05984 05985 if (p->vrtp && !p->vsrtp && setup_srtp(&p->vsrtp) < 0) { 05986 ast_log(LOG_WARNING, "SRTP video setup failed\n"); 05987 return -1; 05988 } 05989 05990 if (p->trtp && !p->tsrtp && setup_srtp(&p->tsrtp) < 0) { 05991 ast_log(LOG_WARNING, "SRTP text setup failed\n"); 05992 return -1; 05993 } 05994 } 05995 05996 res = 0; 05997 ast_set_flag(&p->flags[0], SIP_OUTGOING); 05998 05999 /* T.38 re-INVITE FAX detection should never be done for outgoing calls, 06000 * so ensure it is disabled. 06001 */ 06002 ast_clear_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_T38); 06003 06004 if (p->options->transfer) { 06005 char buf[SIPBUFSIZE/2]; 06006 06007 if (referer) { 06008 if (sipdebug) 06009 ast_debug(3, "Call for %s transfered by %s\n", p->username, referer); 06010 snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer); 06011 } else 06012 snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name); 06013 ast_string_field_set(p, cid_name, buf); 06014 } 06015 ast_debug(1, "Outgoing Call for %s\n", p->username); 06016 06017 res = update_call_counter(p, INC_CALL_RINGING); 06018 06019 if (res == -1) { 06020 ast->hangupcause = AST_CAUSE_USER_BUSY; 06021 return res; 06022 } 06023 p->callingpres = ast_party_id_presentation(&ast->caller.id); 06024 p->jointcapability = ast_rtp_instance_available_formats(p->rtp, p->capability, p->prefcodec); 06025 p->jointnoncodeccapability = p->noncodeccapability; 06026 06027 /* If there are no audio formats left to offer, punt */ 06028 if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 06029 ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username); 06030 res = -1; 06031 } else { 06032 int xmitres; 06033 struct ast_party_connected_line connected; 06034 struct ast_set_party_connected_line update_connected; 06035 06036 sip_pvt_lock(p); 06037 06038 /* Supply initial connected line information if available. */ 06039 memset(&update_connected, 0, sizeof(update_connected)); 06040 ast_party_connected_line_init(&connected); 06041 if (!ast_strlen_zero(p->cid_num) 06042 || (p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) { 06043 update_connected.id.number = 1; 06044 connected.id.number.valid = 1; 06045 connected.id.number.str = (char *) p->cid_num; 06046 connected.id.number.presentation = p->callingpres; 06047 } 06048 if (!ast_strlen_zero(p->cid_name) 06049 || (p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) { 06050 update_connected.id.name = 1; 06051 connected.id.name.valid = 1; 06052 connected.id.name.str = (char *) p->cid_name; 06053 connected.id.name.presentation = p->callingpres; 06054 } 06055 if (update_connected.id.number || update_connected.id.name) { 06056 connected.id.tag = (char *) p->cid_tag; 06057 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; 06058 ast_channel_queue_connected_line_update(ast, &connected, &update_connected); 06059 } 06060 06061 xmitres = transmit_invite(p, SIP_INVITE, 1, 2, uri); 06062 if (xmitres == XMIT_ERROR) { 06063 sip_pvt_unlock(p); 06064 return -1; 06065 } 06066 p->invitestate = INV_CALLING; 06067 06068 /* Initialize auto-congest time */ 06069 AST_SCHED_REPLACE_UNREF(p->initid, sched, p->timer_b, auto_congest, p, 06070 dialog_unref(_data, "dialog ptr dec when SCHED_REPLACE del op succeeded"), 06071 dialog_unref(p, "dialog ptr dec when SCHED_REPLACE add failed"), 06072 dialog_ref(p, "dialog ptr inc when SCHED_REPLACE add succeeded") ); 06073 sip_pvt_unlock(p); 06074 } 06075 return res; 06076 }
| 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 4293 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().
04294 { 04295 if (p->final_destruction_scheduled) { 04296 return 0; 04297 } 04298 04299 if (p->autokillid > -1) { 04300 append_history(p, "CancelDestroy", ""); 04301 AST_SCHED_DEL_UNREF(sched, p->autokillid, dialog_unref(p, "remove ref for autokillid")); 04302 } 04303 return 0; 04304 }
| static void sip_cc_agent_destructor | ( | struct ast_cc_agent * | agent | ) | [static] |
Definition at line 1819 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().
01820 { 01821 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01822 01823 if (!agent_pvt) { 01824 /* The agent constructor probably failed. */ 01825 return; 01826 } 01827 01828 sip_cc_agent_stop_offer_timer(agent); 01829 if (agent_pvt->subscribe_pvt) { 01830 sip_pvt_lock(agent_pvt->subscribe_pvt); 01831 if (!ast_test_flag(&agent_pvt->subscribe_pvt->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) { 01832 /* If we haven't sent a 200 OK for the SUBSCRIBE dialog yet, then we need to send a response letting 01833 * the subscriber know something went wrong 01834 */ 01835 transmit_response(agent_pvt->subscribe_pvt, "500 Internal Server Error", &agent_pvt->subscribe_pvt->initreq); 01836 } 01837 sip_pvt_unlock(agent_pvt->subscribe_pvt); 01838 agent_pvt->subscribe_pvt = dialog_unref(agent_pvt->subscribe_pvt, "SIP CC agent destructor: Remove ref to subscription"); 01839 } 01840 ast_free(agent_pvt); 01841 }
| static int sip_cc_agent_init | ( | struct ast_cc_agent * | agent, | |
| struct ast_channel * | chan | |||
| ) | [static] |
Definition at line 1706 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.
01707 { 01708 struct sip_cc_agent_pvt *agent_pvt = ast_calloc(1, sizeof(*agent_pvt)); 01709 struct sip_pvt *call_pvt = chan->tech_pvt; 01710 01711 if (!agent_pvt) { 01712 return -1; 01713 } 01714 01715 ast_assert(!strcmp(chan->tech->type, "SIP")); 01716 01717 ast_copy_string(agent_pvt->original_callid, call_pvt->callid, sizeof(agent_pvt->original_callid)); 01718 ast_copy_string(agent_pvt->original_exten, call_pvt->exten, sizeof(agent_pvt->original_exten)); 01719 agent_pvt->offer_timer_id = -1; 01720 agent->private_data = agent_pvt; 01721 sip_pvt_lock(call_pvt); 01722 ast_set_flag(&call_pvt->flags[0], SIP_OFFER_CC); 01723 sip_pvt_unlock(call_pvt); 01724 return 0; 01725 }
| static int sip_cc_agent_recall | ( | struct ast_cc_agent * | agent | ) | [static] |
Definition at line 1799 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().
01800 { 01801 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01802 /* If we have received a PUBLISH beforehand stating that the caller in question 01803 * is not available, we can save ourself a bit of effort here and just report 01804 * the caller as busy 01805 */ 01806 if (!agent_pvt->is_available) { 01807 return ast_cc_agent_caller_busy(agent->core_id, "Caller %s is busy, reporting to the core", 01808 agent->device_name); 01809 } 01810 /* Otherwise, we transmit a NOTIFY to the caller and await either 01811 * a PUBLISH or an INVITE 01812 */ 01813 sip_pvt_lock(agent_pvt->subscribe_pvt); 01814 transmit_cc_notify(agent, agent_pvt->subscribe_pvt, CC_READY); 01815 sip_pvt_unlock(agent_pvt->subscribe_pvt); 01816 return 0; 01817 }
| static void sip_cc_agent_respond | ( | struct ast_cc_agent * | agent, | |
| enum ast_cc_agent_response_reason | reason | |||
| ) | [static] |
Definition at line 1755 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.
01756 { 01757 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01758 01759 sip_pvt_lock(agent_pvt->subscribe_pvt); 01760 ast_set_flag(&agent_pvt->subscribe_pvt->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 01761 if (reason == AST_CC_AGENT_RESPONSE_SUCCESS || !ast_strlen_zero(agent_pvt->notify_uri)) { 01762 /* The second half of this if statement may be a bit hard to grasp, 01763 * so here's an explanation. When a subscription comes into 01764 * chan_sip, as long as it is not malformed, it will be passed 01765 * to the CC core. If the core senses an out-of-order state transition, 01766 * then the core will call this callback with the "reason" set to a 01767 * failure condition. 01768 * However, an out-of-order state transition will occur during a resubscription 01769 * for CC. In such a case, we can see that we have already generated a notify_uri 01770 * and so we can detect that this isn't a *real* failure. Rather, it is just 01771 * something the core doesn't recognize as a legitimate SIP state transition. 01772 * Thus we respond with happiness and flowers. 01773 */ 01774 transmit_response(agent_pvt->subscribe_pvt, "200 OK", &agent_pvt->subscribe_pvt->initreq); 01775 transmit_cc_notify(agent, agent_pvt->subscribe_pvt, CC_QUEUED); 01776 } else { 01777 transmit_response(agent_pvt->subscribe_pvt, "500 Internal Error", &agent_pvt->subscribe_pvt->initreq); 01778 } 01779 sip_pvt_unlock(agent_pvt->subscribe_pvt); 01780 agent_pvt->is_available = TRUE; 01781 }
| static int sip_cc_agent_start_monitoring | ( | struct ast_cc_agent * | agent | ) | [static] |
Definition at line 1790 of file chan_sip.c.
| static int sip_cc_agent_start_offer_timer | ( | struct ast_cc_agent * | agent | ) | [static] |
Definition at line 1737 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().
01738 { 01739 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01740 int when; 01741 01742 when = ast_get_cc_offer_timer(agent->cc_params) * 1000; 01743 agent_pvt->offer_timer_id = ast_sched_add(sched, when, sip_offer_timer_expire, agent); 01744 return 0; 01745 }
| static int sip_cc_agent_status_request | ( | struct ast_cc_agent * | agent | ) | [static] |
Definition at line 1783 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.
01784 { 01785 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01786 enum ast_device_state state = agent_pvt->is_available ? AST_DEVICE_NOT_INUSE : AST_DEVICE_INUSE; 01787 return ast_cc_agent_status_response(agent->core_id, state); 01788 }
| static int sip_cc_agent_stop_offer_timer | ( | struct ast_cc_agent * | agent | ) | [static] |
Definition at line 1747 of file chan_sip.c.
References AST_SCHED_DEL, and ast_cc_agent::private_data.
Referenced by sip_cc_agent_destructor().
01748 { 01749 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01750 01751 AST_SCHED_DEL(sched, agent_pvt->offer_timer_id); 01752 return 0; 01753 }
| static int sip_cc_monitor_cancel_available_timer | ( | struct ast_cc_monitor * | monitor, | |
| int * | sched_id | |||
| ) | [static] |
Definition at line 2058 of file chan_sip.c.
References ao2_t_ref, and AST_SCHED_DEL.
02059 { 02060 if (*sched_id != -1) { 02061 AST_SCHED_DEL(sched, *sched_id); 02062 ao2_t_ref(monitor, -1, "Removing scheduler's reference to the monitor"); 02063 } 02064 return 0; 02065 }
| static void sip_cc_monitor_destructor | ( | void * | private_data | ) | [static] |
Definition at line 2067 of file chan_sip.c.
References ao2_unlink, and ast_module_unref().
02068 { 02069 struct sip_monitor_instance *monitor_instance = private_data; 02070 ao2_unlink(sip_monitor_instances, monitor_instance); 02071 ast_module_unref(ast_module_info->self); 02072 }
| static int sip_cc_monitor_request_cc | ( | struct ast_cc_monitor * | monitor, | |
| int * | available_timer_id | |||
| ) | [static] |
Definition at line 1925 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().
01926 { 01927 struct sip_monitor_instance *monitor_instance = monitor->private_data; 01928 enum ast_cc_service_type service = monitor->service_offered; 01929 int when; 01930 01931 if (!monitor_instance) { 01932 return -1; 01933 } 01934 01935 if (!(monitor_instance->subscription_pvt = sip_alloc(NULL, NULL, 0, SIP_SUBSCRIBE, NULL))) { 01936 return -1; 01937 } 01938 01939 when = service == AST_CC_CCBS ? ast_get_ccbs_available_timer(monitor->interface->config_params) : 01940 ast_get_ccnr_available_timer(monitor->interface->config_params); 01941 01942 sip_pvt_lock(monitor_instance->subscription_pvt); 01943 ast_set_flag(&monitor_instance->subscription_pvt->flags[0], SIP_OUTGOING); 01944 create_addr(monitor_instance->subscription_pvt, monitor_instance->peername, 0, 1); 01945 ast_sip_ouraddrfor(&monitor_instance->subscription_pvt->sa, &monitor_instance->subscription_pvt->ourip, monitor_instance->subscription_pvt); 01946 monitor_instance->subscription_pvt->subscribed = CALL_COMPLETION; 01947 monitor_instance->subscription_pvt->expiry = when; 01948 01949 transmit_invite(monitor_instance->subscription_pvt, SIP_SUBSCRIBE, FALSE, 2, monitor_instance->subscribe_uri); 01950 sip_pvt_unlock(monitor_instance->subscription_pvt); 01951 01952 ao2_t_ref(monitor, +1, "Adding a ref to the monitor for the scheduler"); 01953 *available_timer_id = ast_sched_add(sched, when * 1000, ast_cc_available_timer_expire, monitor); 01954 return 0; 01955 }
| static int sip_cc_monitor_suspend | ( | struct ast_cc_monitor * | monitor | ) | [static] |
Definition at line 1983 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().
01984 { 01985 struct sip_monitor_instance *monitor_instance = monitor->private_data; 01986 enum sip_publish_type publish_type; 01987 struct cc_epa_entry *cc_entry; 01988 01989 if (!monitor_instance) { 01990 return -1; 01991 } 01992 01993 if (!monitor_instance->suspension_entry) { 01994 /* We haven't yet allocated the suspension entry, so let's give it a shot */ 01995 if (!(monitor_instance->suspension_entry = create_epa_entry("call-completion", monitor_instance->peername))) { 01996 ast_log(LOG_WARNING, "Unable to allocate sip EPA entry for call-completion\n"); 01997 ao2_ref(monitor_instance, -1); 01998 return -1; 01999 } 02000 if (!(cc_entry = ast_calloc(1, sizeof(*cc_entry)))) { 02001 ast_log(LOG_WARNING, "Unable to allocate space for instance data of EPA entry for call-completion\n"); 02002 ao2_ref(monitor_instance, -1); 02003 return -1; 02004 } 02005 cc_entry->core_id = monitor->core_id; 02006 monitor_instance->suspension_entry->instance_data = cc_entry; 02007 publish_type = SIP_PUBLISH_INITIAL; 02008 } else { 02009 publish_type = SIP_PUBLISH_MODIFY; 02010 cc_entry = monitor_instance->suspension_entry->instance_data; 02011 } 02012 02013 cc_entry->current_state = CC_CLOSED; 02014 02015 if (ast_strlen_zero(monitor_instance->notify_uri)) { 02016 /* If we have no set notify_uri, then what this means is that we have 02017 * not received a NOTIFY from this destination stating that he is 02018 * currently available. 02019 * 02020 * This situation can arise when the core calls the suspend callbacks 02021 * of multiple destinations. If one of the other destinations aside 02022 * from this one notified Asterisk that he is available, then there 02023 * is no reason to take any suspension action on this device. Rather, 02024 * we should return now and if we receive a NOTIFY while monitoring 02025 * is still "suspended" then we can immediately respond with the 02026 * proper PUBLISH to let this endpoint know what is going on. 02027 */ 02028 return 0; 02029 } 02030 construct_pidf_body(CC_CLOSED, monitor_instance->suspension_entry->body, sizeof(monitor_instance->suspension_entry->body), monitor_instance->peername); 02031 return transmit_publish(monitor_instance->suspension_entry, publish_type, monitor_instance->notify_uri); 02032 }
| static int sip_cc_monitor_unsuspend | ( | struct ast_cc_monitor * | monitor | ) | [static] |
Definition at line 2034 of file chan_sip.c.
References ast_assert, ast_strlen_zero(), construct_pidf_body(), ast_cc_monitor::private_data, and transmit_publish().
02035 { 02036 struct sip_monitor_instance *monitor_instance = monitor->private_data; 02037 struct cc_epa_entry *cc_entry; 02038 02039 if (!monitor_instance) { 02040 return -1; 02041 } 02042 02043 ast_assert(monitor_instance->suspension_entry != NULL); 02044 02045 cc_entry = monitor_instance->suspension_entry->instance_data; 02046 cc_entry->current_state = CC_OPEN; 02047 if (ast_strlen_zero(monitor_instance->notify_uri)) { 02048 /* This means we are being asked to unsuspend a call leg we never 02049 * sent a PUBLISH on. As such, there is no reason to send another 02050 * PUBLISH at this point either. We can just return instead. 02051 */ 02052 return 0; 02053 } 02054 construct_pidf_body(CC_OPEN, monitor_instance->suspension_entry->body, sizeof(monitor_instance->suspension_entry->body), monitor_instance->peername); 02055 return transmit_publish(monitor_instance->suspension_entry, SIP_PUBLISH_MODIFY, monitor_instance->notify_uri); 02056 }
| 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 2490 of file chan_sip.c.
References ast_log(), errno, and LOG_ERROR.
Referenced by _sip_tcp_helper_thread(), sip_tcp_read(), and sip_tls_read().
02491 { 02492 int timeout; 02493 time_t now; 02494 if(time(&now) == -1) { 02495 ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno)); 02496 return -1; 02497 } 02498 02499 timeout = (authtimeout - (now - start)) * 1000; 02500 if (timeout < 0) { 02501 /* we have timed out */ 02502 return 0; 02503 } 02504 02505 return timeout; 02506 }
| 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 19659 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.
19660 { 19661 struct ast_variable *varlist; 19662 int i; 19663 19664 switch (cmd) { 19665 case CLI_INIT: 19666 e->command = "sip notify"; 19667 e->usage = 19668 "Usage: sip notify <type> <peer> [<peer>...]\n" 19669 " Send a NOTIFY message to a SIP peer or peers\n" 19670 " Message types are defined in sip_notify.conf\n"; 19671 return NULL; 19672 case CLI_GENERATE: 19673 return complete_sipnotify(a->line, a->word, a->pos, a->n); 19674 } 19675 19676 if (a->argc < 4) 19677 return CLI_SHOWUSAGE; 19678 19679 if (!notify_types) { 19680 ast_cli(a->fd, "No %s file found, or no types listed there\n", notify_config); 19681 return CLI_FAILURE; 19682 } 19683 19684 varlist = ast_variable_browse(notify_types, a->argv[2]); 19685 19686 if (!varlist) { 19687 ast_cli(a->fd, "Unable to find notify type '%s'\n", a->argv[2]); 19688 return CLI_FAILURE; 19689 } 19690 19691 for (i = 3; i < a->argc; i++) { 19692 struct sip_pvt *p; 19693 char buf[512]; 19694 struct ast_variable *header, *var; 19695 19696 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) { 19697 ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n"); 19698 return CLI_FAILURE; 19699 } 19700 19701 if (create_addr(p, a->argv[i], NULL, 1)) { 19702 /* Maybe they're not registered, etc. */ 19703 dialog_unlink_all(p); 19704 dialog_unref(p, "unref dialog inside for loop" ); 19705 /* sip_destroy(p); */ 19706 ast_cli(a->fd, "Could not create address for '%s'\n", a->argv[i]); 19707 continue; 19708 } 19709 19710 /* Notify is outgoing call */ 19711 ast_set_flag(&p->flags[0], SIP_OUTGOING); 19712 sip_notify_allocate(p); 19713 p->notify->headers = header = ast_variable_new("Subscription-State", "terminated", ""); 19714 19715 for (var = varlist; var; var = var->next) { 19716 ast_copy_string(buf, var->value, sizeof(buf)); 19717 ast_unescape_semicolon(buf); 19718 19719 if (!strcasecmp(var->name, "Content")) { 19720 if (ast_str_strlen(p->notify->content)) 19721 ast_str_append(&p->notify->content, 0, "\r\n"); 19722 ast_str_append(&p->notify->content, 0, "%s", buf); 19723 } else if (!strcasecmp(var->name, "Content-Length")) { 19724 ast_log(LOG_WARNING, "it is not necessary to specify Content-Length in sip_notify.conf, ignoring\n"); 19725 } else { 19726 header->next = ast_variable_new(var->name, buf, ""); 19727 header = header->next; 19728 } 19729 } 19730 19731 /* Now that we have the peer's address, set our ip and change callid */ 19732 ast_sip_ouraddrfor(&p->sa, &p->ourip, p); 19733 build_via(p); 19734 19735 change_callid_pvt(p, NULL); 19736 19737 ast_cli(a->fd, "Sending NOTIFY of type '%s' to '%s'\n", a->argv[2], a->argv[i]); 19738 sip_scheddestroy(p, SIP_TRANS_TIMEOUT); 19739 transmit_invite(p, SIP_NOTIFY, 0, 2, NULL); 19740 dialog_unref(p, "bump down the count of p since we're done with it."); 19741 } 19742 19743 return CLI_SUCCESS; 19744 }
| static int sip_debug_test_addr | ( | const struct ast_sockaddr * | addr | ) | [inline, static] |
See if we pass debug IP filter.
Definition at line 3521 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().
03522 { 03523 /* Can't debug if sipdebug is not enabled */ 03524 if (!sipdebug) { 03525 return 0; 03526 } 03527 03528 /* A null debug_addr means we'll debug any address */ 03529 if (ast_sockaddr_isnull(&debugaddr)) { 03530 return 1; 03531 } 03532 03533 /* If no port was specified for a debug address, just compare the 03534 * addresses, otherwise compare the address and port 03535 */ 03536 if (ast_sockaddr_port(&debugaddr)) { 03537 return !ast_sockaddr_cmp(&debugaddr, addr); 03538 } else { 03539 return !ast_sockaddr_cmp_addr(&debugaddr, addr); 03540 } 03541 }
| static int sip_debug_test_pvt | ( | struct sip_pvt * | p | ) | [inline, static] |
Test PVT for debugging output.
Definition at line 3560 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().
03561 { 03562 if (!sipdebug) { 03563 return 0; 03564 } 03565 return sip_debug_test_addr(sip_real_dst(p)); 03566 }
| 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 6444 of file chan_sip.c.
References __sip_destroy(), ast_debug, and TRUE.
Referenced by sip_destroy_fn(), and sip_subscribe_mwi_destroy().
06445 { 06446 ast_debug(3, "Destroying SIP dialog %s\n", p->callid); 06447 __sip_destroy(p, TRUE, TRUE); 06448 return NULL; 06449 }
| static void sip_destroy_fn | ( | void * | p | ) | [static] |
Definition at line 6434 of file chan_sip.c.
References sip_destroy().
Referenced by sip_alloc().
06435 { 06436 sip_destroy(p); 06437 }
| static void sip_destroy_peer | ( | struct sip_peer * | peer | ) | [static] |
Destroy peer object from memory.
Definition at line 4977 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().
04978 { 04979 ast_debug(3, "Destroying SIP peer %s\n", peer->name); 04980 04981 /* 04982 * Remove any mailbox event subscriptions for this peer before 04983 * we destroy anything. An event subscription callback may be 04984 * happening right now. 04985 */ 04986 clear_peer_mailboxes(peer); 04987 04988 if (peer->outboundproxy) { 04989 ao2_ref(peer->outboundproxy, -1); 04990 peer->outboundproxy = NULL; 04991 } 04992 04993 /* Delete it, it needs to disappear */ 04994 if (peer->call) { 04995 dialog_unlink_all(peer->call); 04996 peer->call = dialog_unref(peer->call, "peer->call is being unset"); 04997 } 04998 04999 if (peer->mwipvt) { /* We have an active subscription, delete it */ 05000 dialog_unlink_all(peer->mwipvt); 05001 peer->mwipvt = dialog_unref(peer->mwipvt, "unreffing peer->mwipvt"); 05002 } 05003 05004 if (peer->chanvars) { 05005 ast_variables_destroy(peer->chanvars); 05006 peer->chanvars = NULL; 05007 } 05008 05009 register_peer_exten(peer, FALSE); 05010 ast_free_ha(peer->ha); 05011 ast_free_ha(peer->directmediaha); 05012 if (peer->selfdestruct) 05013 ast_atomic_fetchadd_int(&apeerobjs, -1); 05014 else if (!ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && peer->is_realtime) { 05015 ast_atomic_fetchadd_int(&rpeerobjs, -1); 05016 ast_debug(3, "-REALTIME- peer Destroyed. Name: %s. Realtime Peer objects: %d\n", peer->name, rpeerobjs); 05017 } else 05018 ast_atomic_fetchadd_int(&speerobjs, -1); 05019 if (peer->auth) { 05020 ao2_t_ref(peer->auth, -1, "Removing peer authentication"); 05021 peer->auth = NULL; 05022 } 05023 05024 if (peer->socket.tcptls_session) { 05025 ao2_ref(peer->socket.tcptls_session, -1); 05026 peer->socket.tcptls_session = NULL; 05027 } 05028 05029 ast_cc_config_params_destroy(peer->cc_params); 05030 05031 ast_string_field_free_memory(peer); 05032 }
| static void sip_destroy_peer_fn | ( | void * | peer | ) | [static] |
Definition at line 4971 of file chan_sip.c.
References sip_destroy_peer().
Referenced by build_peer(), and temp_peer().
04972 { 04973 sip_destroy_peer(peer); 04974 }
| 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 27127 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().
27128 { 27129 char *host; 27130 char *tmp; 27131 struct sip_peer *p; 27132 27133 int res = AST_DEVICE_INVALID; 27134 27135 /* make sure data is not null. Maybe unnecessary, but better be safe */ 27136 host = ast_strdupa(data ? data : ""); 27137 if ((tmp = strchr(host, '@'))) 27138 host = tmp + 1; 27139 27140 ast_debug(3, "Checking device state for peer %s\n", host); 27141 27142 /* If find_peer asks for a realtime peer, then this breaks rtautoclear. This 27143 * is because when a peer tries to autoexpire, the last thing it does is to 27144 * queue up an event telling the system that the devicestate has changed 27145 * (presumably to unavailable). If we ask for a realtime peer here, this would 27146 * load it BACK into memory, thus defeating the point of trying to clear dead 27147 * hosts out of memory. 27148 */ 27149 if ((p = find_peer(host, NULL, FALSE, FINDALLDEVICES, TRUE, 0))) { 27150 if (!(ast_sockaddr_isnull(&p->addr) && ast_sockaddr_isnull(&p->defaddr))) { 27151 /* we have an address for the peer */ 27152 27153 /* Check status in this order 27154 - Hold 27155 - Ringing 27156 - Busy (enforced only by call limit) 27157 - Inuse (we have a call) 27158 - Unreachable (qualify) 27159 If we don't find any of these state, report AST_DEVICE_NOT_INUSE 27160 for registered devices */ 27161 27162 if (p->onHold) 27163 /* First check for hold or ring states */ 27164 res = AST_DEVICE_ONHOLD; 27165 else if (p->inRinging) { 27166 if (p->inRinging == p->inUse) 27167 res = AST_DEVICE_RINGING; 27168 else 27169 res = AST_DEVICE_RINGINUSE; 27170 } else if (p->call_limit && (p->inUse == p->call_limit)) 27171 /* check call limit */ 27172 res = AST_DEVICE_BUSY; 27173 else if (p->call_limit && p->busy_level && p->inUse >= p->busy_level) 27174 /* We're forcing busy before we've reached the call limit */ 27175 res = AST_DEVICE_BUSY; 27176 else if (p->call_limit && p->inUse) 27177 /* Not busy, but we do have a call */ 27178 res = AST_DEVICE_INUSE; 27179 else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0))) 27180 /* We don't have a call. Are we reachable at all? Requires qualify= */ 27181 res = AST_DEVICE_UNAVAILABLE; 27182 else /* Default reply if we're registered and have no other data */ 27183 res = AST_DEVICE_NOT_INUSE; 27184 } else { 27185 /* there is no address, it's unavailable */ 27186 res = AST_DEVICE_UNAVAILABLE; 27187 } 27188 unref_peer(p, "unref_peer, from sip_devicestate, release ref from find_peer"); 27189 } 27190 27191 return res; 27192 }
| 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 19616 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.
19617 { 19618 int oldsipdebug = sipdebug & sip_debug_console; 19619 const char *what; 19620 19621 if (cmd == CLI_INIT) { 19622 e->command = "sip set debug {on|off|ip|peer}"; 19623 e->usage = 19624 "Usage: sip set debug {off|on|ip addr[:port]|peer peername}\n" 19625 " Globally disables dumping of SIP packets,\n" 19626 " or enables it either globally or for a (single)\n" 19627 " IP address or registered peer.\n"; 19628 return NULL; 19629 } else if (cmd == CLI_GENERATE) { 19630 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer")) 19631 return complete_sip_peer(a->word, a->n, 0); 19632 return NULL; 19633 } 19634 19635 what = a->argv[e->args-1]; /* guaranteed to exist */ 19636 if (a->argc == e->args) { /* on/off */ 19637 if (!strcasecmp(what, "on")) { 19638 sipdebug |= sip_debug_console; 19639 sipdebug_text = 1; /*! \note this can be a special debug command - "sip debug text" or something */ 19640 memset(&debugaddr, 0, sizeof(debugaddr)); 19641 ast_cli(a->fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 19642 return CLI_SUCCESS; 19643 } else if (!strcasecmp(what, "off")) { 19644 sipdebug &= ~sip_debug_console; 19645 sipdebug_text = 0; 19646 ast_cli(a->fd, "SIP Debugging Disabled\n"); 19647 return CLI_SUCCESS; 19648 } 19649 } else if (a->argc == e->args +1) {/* ip/peer */ 19650 if (!strcasecmp(what, "ip")) 19651 return sip_do_debug_ip(a->fd, a->argv[e->args]); 19652 else if (!strcasecmp(what, "peer")) 19653 return sip_do_debug_peer(a->fd, a->argv[e->args]); 19654 } 19655 return CLI_SHOWUSAGE; /* default, failure */ 19656 }
| static char * sip_do_debug_ip | ( | int | fd, | |
| const char * | arg | |||
| ) | [static] |
Enable SIP Debugging for a single IP.
Definition at line 19585 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().
19586 { 19587 if (ast_sockaddr_resolve_first_af(&debugaddr, arg, 0, 0)) { 19588 return CLI_SHOWUSAGE; 19589 } 19590 19591 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_sockaddr_stringify_addr(&debugaddr)); 19592 sipdebug |= sip_debug_console; 19593 19594 return CLI_SUCCESS; 19595 }
| static char * sip_do_debug_peer | ( | int | fd, | |
| const char * | arg | |||
| ) | [static] |
Turn on SIP debugging for a given peer.
Definition at line 19598 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().
19599 { 19600 struct sip_peer *peer = find_peer(arg, NULL, TRUE, FINDPEERS, FALSE, 0); 19601 if (!peer) 19602 ast_cli(fd, "No such peer '%s'\n", arg); 19603 else if (ast_sockaddr_isnull(&peer->addr)) 19604 ast_cli(fd, "Unable to get IP address of peer '%s'\n", arg); 19605 else { 19606 ast_sockaddr_copy(&debugaddr, &peer->addr); 19607 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_sockaddr_stringify_addr(&debugaddr)); 19608 sipdebug |= sip_debug_console; 19609 } 19610 if (peer) 19611 unref_peer(peer, "sip_do_debug_peer: unref_peer, from find_peer call"); 19612 return CLI_SUCCESS; 19613 }
| static int sip_do_reload | ( | enum channelreloadreason | reason | ) | [static] |
Reload module.
Definition at line 30462 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().
30463 { 30464 time_t start_poke, end_poke; 30465 30466 reload_config(reason); 30467 ast_sched_dump(sched); 30468 30469 start_poke = time(0); 30470 /* Prune peers who still are supposed to be deleted */ 30471 unlink_marked_peers_from_tables(); 30472 30473 ast_debug(4, "--------------- Done destroying pruned peers\n"); 30474 30475 /* Send qualify (OPTIONS) to all peers */ 30476 sip_poke_all_peers(); 30477 30478 /* Register with all services */ 30479 sip_send_all_registers(); 30480 30481 sip_send_all_mwi_subscriptions(); 30482 30483 end_poke = time(0); 30484 30485 ast_debug(4, "do_reload finished. peer poke/prune reg contact time = %d sec.\n", (int)(end_poke-start_poke)); 30486 30487 ast_debug(4, "--------------- SIP reload done\n"); 30488 30489 return 0; 30490 }
| static int sip_dtmfmode | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Set the DTMFmode for an outbound SIP call (application).
Definition at line 30145 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().
30146 { 30147 struct sip_pvt *p; 30148 const char *mode = data; 30149 30150 if (!data) { 30151 ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n"); 30152 return 0; 30153 } 30154 ast_channel_lock(chan); 30155 if (!IS_SIP_TECH(chan->tech)) { 30156 ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n"); 30157 ast_channel_unlock(chan); 30158 return 0; 30159 } 30160 p = chan->tech_pvt; 30161 if (!p) { 30162 ast_channel_unlock(chan); 30163 return 0; 30164 } 30165 sip_pvt_lock(p); 30166 if (!strcasecmp(mode, "info")) { 30167 ast_clear_flag(&p->flags[0], SIP_DTMF); 30168 ast_set_flag(&p->flags[0], SIP_DTMF_INFO); 30169 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 30170 } else if (!strcasecmp(mode, "shortinfo")) { 30171 ast_clear_flag(&p->flags[0], SIP_DTMF); 30172 ast_set_flag(&p->flags[0], SIP_DTMF_SHORTINFO); 30173 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 30174 } else if (!strcasecmp(mode, "rfc2833")) { 30175 ast_clear_flag(&p->flags[0], SIP_DTMF); 30176 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 30177 p->jointnoncodeccapability |= AST_RTP_DTMF; 30178 } else if (!strcasecmp(mode, "inband")) { 30179 ast_clear_flag(&p->flags[0], SIP_DTMF); 30180 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 30181 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 30182 } else { 30183 ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n", mode); 30184 } 30185 if (p->rtp) 30186 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 30187 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || 30188 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) { 30189 enable_dsp_detect(p); 30190 } else { 30191 disable_dsp_detect(p); 30192 } 30193 sip_pvt_unlock(p); 30194 ast_channel_unlock(chan); 30195 return 0; 30196 }
| 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 19385 of file chan_sip.c.
References ast_debug, AST_LIST_TRAVERSE, ast_log(), LOG_NOTICE, and option_debug.
Referenced by __sip_destroy().
19386 { 19387 int x = 0; 19388 struct sip_history *hist; 19389 static int errmsg = 0; 19390 19391 if (!dialog) 19392 return; 19393 19394 if (!option_debug && !sipdebug) { 19395 if (!errmsg) { 19396 ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n"); 19397 errmsg = 1; 19398 } 19399 return; 19400 } 19401 19402 ast_debug(1, "\n---------- SIP HISTORY for '%s' \n", dialog->callid); 19403 if (dialog->subscribed) 19404 ast_debug(1, " * Subscription\n"); 19405 else 19406 ast_debug(1, " * SIP Call\n"); 19407 if (dialog->history) 19408 AST_LIST_TRAVERSE(dialog->history, hist, list) 19409 ast_debug(1, " %-3.3d. %s\n", ++x, hist->event); 19410 if (!x) 19411 ast_debug(1, "Call '%s' has no history\n", dialog->callid); 19412 ast_debug(1, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid); 19413 }
| static int sip_epa_register | ( | const struct epa_static_data * | static_data | ) | [static] |
Definition at line 862 of file chan_sip.c.
References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, and AST_LIST_UNLOCK.
Referenced by load_module().
00863 { 00864 struct epa_backend *backend = ast_calloc(1, sizeof(*backend)); 00865 00866 if (!backend) { 00867 return -1; 00868 } 00869 00870 backend->static_data = static_data; 00871 00872 AST_LIST_LOCK(&epa_static_data_list); 00873 AST_LIST_INSERT_TAIL(&epa_static_data_list, backend, next); 00874 AST_LIST_UNLOCK(&epa_static_data_list); 00875 return 0; 00876 }
| static void sip_epa_unregister_all | ( | void | ) | [static] |
Definition at line 878 of file chan_sip.c.
References ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, and AST_LIST_UNLOCK.
Referenced by unload_module().
00879 { 00880 struct epa_backend *backend; 00881 00882 AST_LIST_LOCK(&epa_static_data_list); 00883 while ((backend = AST_LIST_REMOVE_HEAD(&epa_static_data_list, next))) { 00884 ast_free(backend); 00885 } 00886 AST_LIST_UNLOCK(&epa_static_data_list); 00887 }
| 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 7003 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.
07004 { 07005 int ret = -1; 07006 struct sip_pvt *p; 07007 07008 if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE)) 07009 ast_debug(1, "New channel is zombie\n"); 07010 if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE)) 07011 ast_debug(1, "Old channel is zombie\n"); 07012 07013 if (!newchan || !newchan->tech_pvt) { 07014 if (!newchan) 07015 ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name); 07016 else 07017 ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name); 07018 return -1; 07019 } 07020 p = newchan->tech_pvt; 07021 07022 sip_pvt_lock(p); 07023 append_history(p, "Masq", "Old channel: %s\n", oldchan->name); 07024 append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name); 07025 if (p->owner != oldchan) 07026 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner); 07027 else { 07028 p->owner = newchan; 07029 /* Re-invite RTP back to Asterisk. Needed if channel is masqueraded out of a native 07030 RTP bridge (i.e., RTP not going through Asterisk): RTP bridge code might not be 07031 able to do this if the masquerade happens before the bridge breaks (e.g., AMI 07032 redirect of both channels). Note that a channel can not be masqueraded *into* 07033 a native bridge. So there is no danger that this breaks a native bridge that 07034 should stay up. */ 07035 sip_set_rtp_peer(newchan, NULL, NULL, 0, 0, 0); 07036 ret = 0; 07037 } 07038 ast_debug(3, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name); 07039 07040 sip_pvt_unlock(p); 07041 return ret; 07042 }
| static const char * sip_get_callid | ( | struct ast_channel * | chan | ) | [static] |
Deliver SIP call ID for the call.
Definition at line 4825 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 2074 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().
02075 { 02076 char *call_info = ast_strdupa(get_header(req, "Call-Info")); 02077 char *uri; 02078 char *purpose; 02079 char *service_str; 02080 static const char cc_purpose[] = "purpose=call-completion"; 02081 static const int cc_purpose_len = sizeof(cc_purpose) - 1; 02082 02083 if (ast_strlen_zero(call_info)) { 02084 /* No Call-Info present. Definitely no CC offer */ 02085 return -1; 02086 } 02087 02088 uri = strsep(&call_info, ";"); 02089 02090 while ((purpose = strsep(&call_info, ";"))) { 02091 if (!strncmp(purpose, cc_purpose, cc_purpose_len)) { 02092 break; 02093 } 02094 } 02095 if (!purpose) { 02096 /* We didn't find the appropriate purpose= parameter. Oh well */ 02097 return -1; 02098 } 02099 02100 /* Okay, call-completion has been offered. Let's figure out what type of service this is */ 02101 while ((service_str = strsep(&call_info, ";"))) { 02102 if (!strncmp(service_str, "m=", 2)) { 02103 break; 02104 } 02105 } 02106 if (!service_str) { 02107 /* So they didn't offer a particular service, We'll just go with CCBS since it really 02108 * doesn't matter anyway 02109 */ 02110 service_str = "BS"; 02111 } else { 02112 /* We already determined that there is an "m=" so no need to check 02113 * the result of this strsep 02114 */ 02115 strsep(&service_str, "="); 02116 } 02117 02118 if ((*service = service_string_to_service_type(service_str)) == AST_CC_NONE) { 02119 /* Invalid service offered */ 02120 return -1; 02121 } 02122 02123 ast_copy_string(subscribe_uri, get_in_brackets(uri), size); 02124 02125 return 0; 02126 }
| static format_t sip_get_codec | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 30125 of file chan_sip.c.
References ast_channel::tech_pvt.
30126 { 30127 struct sip_pvt *p = chan->tech_pvt; 30128 return p->peercapability ? p->peercapability : p->capability; 30129 }
| static enum ast_rtp_glue_result sip_get_rtp_peer | ( | struct ast_channel * | chan, | |
| struct ast_rtp_instance ** | instance | |||
| ) | [static] |
Definition at line 29836 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.
29837 { 29838 struct sip_pvt *p = NULL; 29839 struct ast_channel *opp_chan; 29840 struct sip_pvt *opp = NULL; 29841 enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_LOCAL; 29842 29843 if (!(p = chan->tech_pvt)) { 29844 return AST_RTP_GLUE_RESULT_FORBID; 29845 } 29846 29847 if ((opp_chan = ast_bridged_channel(chan)) && (((opp_chan->tech != &sip_tech) && (opp_chan->tech != &sip_tech_info)) || 29848 (!(opp = opp_chan->tech_pvt)))) { 29849 return AST_RTP_GLUE_RESULT_FORBID; 29850 } 29851 29852 sip_pvt_lock(p); 29853 while (opp && sip_pvt_trylock(opp)) { 29854 sip_pvt_unlock(p); 29855 usleep(1); 29856 sip_pvt_lock(p); 29857 } 29858 29859 if (!(p->rtp)) { 29860 if (opp) { 29861 sip_pvt_unlock(opp); 29862 } 29863 sip_pvt_unlock(p); 29864 return AST_RTP_GLUE_RESULT_FORBID; 29865 } 29866 29867 ao2_ref(p->rtp, +1); 29868 *instance = p->rtp; 29869 29870 if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) { 29871 res = AST_RTP_GLUE_RESULT_REMOTE; 29872 if (opp && !apply_directmedia_ha(p, opp, "audio")) { 29873 res = AST_RTP_GLUE_RESULT_FORBID; 29874 } 29875 } else if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA_NAT)) { 29876 res = AST_RTP_GLUE_RESULT_REMOTE; 29877 } else if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) { 29878 res = AST_RTP_GLUE_RESULT_FORBID; 29879 } 29880 29881 if (opp) { 29882 sip_pvt_unlock(opp); 29883 } 29884 29885 if (p->srtp) { 29886 res = AST_RTP_GLUE_RESULT_FORBID; 29887 } 29888 29889 sip_pvt_unlock(p); 29890 29891 return res; 29892 }
| static enum ast_rtp_glue_result sip_get_trtp_peer | ( | struct ast_channel * | chan, | |
| struct ast_rtp_instance ** | instance | |||
| ) | [static] |
Definition at line 29943 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.
29944 { 29945 struct sip_pvt *p = NULL; 29946 struct ast_channel *opp_chan; 29947 struct sip_pvt *opp = NULL; 29948 enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_FORBID; 29949 29950 if (!(p = chan->tech_pvt)) { 29951 return AST_RTP_GLUE_RESULT_FORBID; 29952 } 29953 29954 if ((opp_chan = ast_bridged_channel(chan)) && (((opp_chan->tech != &sip_tech) && (opp_chan->tech != &sip_tech_info)) || 29955 (!(opp = opp_chan->tech_pvt)))) { 29956 return AST_RTP_GLUE_RESULT_FORBID; 29957 } 29958 29959 sip_pvt_lock(p); 29960 while (opp && sip_pvt_trylock(opp)) { 29961 sip_pvt_unlock(p); 29962 usleep(1); 29963 sip_pvt_lock(p); 29964 } 29965 29966 if (!(p->trtp)) { 29967 if (opp) { 29968 sip_pvt_unlock(opp); 29969 } 29970 sip_pvt_unlock(p); 29971 return AST_RTP_GLUE_RESULT_FORBID; 29972 } 29973 29974 ao2_ref(p->trtp, +1); 29975 *instance = p->trtp; 29976 29977 if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) { 29978 res = AST_RTP_GLUE_RESULT_REMOTE; 29979 if (opp && !apply_directmedia_ha(p, opp, "text")) { 29980 res = AST_RTP_GLUE_RESULT_FORBID; 29981 } 29982 } 29983 29984 if (opp) { 29985 sip_pvt_unlock(opp); 29986 } 29987 sip_pvt_unlock(p); 29988 29989 return res; 29990 }
| static struct ast_udptl * sip_get_udptl_peer | ( | struct ast_channel * | chan | ) | [static, read] |
Definition at line 29756 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.
29757 { 29758 struct sip_pvt *p; 29759 struct ast_channel *opp_chan; 29760 struct sip_pvt *opp; 29761 struct ast_udptl *udptl = NULL; 29762 29763 p = chan->tech_pvt; 29764 if (!p) { 29765 return NULL; 29766 } 29767 29768 if (!(opp_chan = ast_bridged_channel(chan))) { 29769 return NULL; 29770 } else if (((opp_chan->tech != &sip_tech) && (opp_chan->tech != &sip_tech_info)) || 29771 (!(opp = opp_chan->tech_pvt))) { 29772 return NULL; 29773 } 29774 29775 sip_pvt_lock(p); 29776 while (sip_pvt_trylock(opp)) { 29777 sip_pvt_unlock(p); 29778 usleep(1); 29779 sip_pvt_lock(p); 29780 } 29781 29782 if (p->udptl && ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) { 29783 if (apply_directmedia_ha(p, opp, "UDPTL T.38 data")) { 29784 udptl = p->udptl; 29785 } 29786 } 29787 29788 sip_pvt_unlock(opp); 29789 sip_pvt_unlock(p); 29790 return udptl; 29791 }
| static enum ast_rtp_glue_result sip_get_vrtp_peer | ( | struct ast_channel * | chan, | |
| struct ast_rtp_instance ** | instance | |||
| ) | [static] |
Definition at line 29894 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.
29895 { 29896 struct sip_pvt *p = NULL; 29897 struct ast_channel *opp_chan; 29898 struct sip_pvt *opp = NULL; 29899 enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_FORBID; 29900 29901 if (!(p = chan->tech_pvt)) { 29902 return AST_RTP_GLUE_RESULT_FORBID; 29903 } 29904 29905 if ((opp_chan = ast_bridged_channel(chan)) && (((opp_chan->tech != &sip_tech) && (opp_chan->tech != &sip_tech_info)) || 29906 (!(opp = opp_chan->tech_pvt)))) { 29907 return AST_RTP_GLUE_RESULT_FORBID; 29908 } 29909 29910 sip_pvt_lock(p); 29911 while (opp && sip_pvt_trylock(opp)) { 29912 sip_pvt_unlock(p); 29913 usleep(1); 29914 sip_pvt_lock(p); 29915 } 29916 29917 if (!(p->vrtp)) { 29918 if (opp) { 29919 sip_pvt_unlock(opp); 29920 } 29921 sip_pvt_unlock(p); 29922 return AST_RTP_GLUE_RESULT_FORBID; 29923 } 29924 29925 ao2_ref(p->vrtp, +1); 29926 *instance = p->vrtp; 29927 29928 if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) { 29929 res = AST_RTP_GLUE_RESULT_REMOTE; 29930 if (opp && !apply_directmedia_ha(p, opp, "video")) { 29931 res = AST_RTP_GLUE_RESULT_FORBID; 29932 } 29933 } 29934 29935 if (opp) { 29936 sip_pvt_unlock(opp); 29937 } 29938 sip_pvt_unlock(p); 29939 29940 return res; 29941 }
| static void sip_handle_cc | ( | struct sip_pvt * | pvt, | |
| struct sip_request * | req, | |||
| enum ast_cc_service_type | service | |||
| ) | [static] |
Definition at line 2145 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().
02146 { 02147 enum ast_cc_monitor_policies monitor_policy = ast_get_cc_monitor_policy(pvt->cc_params); 02148 int core_id; 02149 char interface_name[AST_CHANNEL_NAME]; 02150 02151 if (monitor_policy == AST_CC_MONITOR_NEVER) { 02152 /* Don't bother, just return */ 02153 return; 02154 } 02155 02156 if ((core_id = ast_cc_get_current_core_id(pvt->owner)) == -1) { 02157 /* For some reason, CC is invalid, so don't try it! */ 02158 return; 02159 } 02160 02161 ast_channel_get_device_name(pvt->owner, interface_name, sizeof(interface_name)); 02162 02163 if (monitor_policy == AST_CC_MONITOR_ALWAYS || monitor_policy == AST_CC_MONITOR_NATIVE) { 02164 char subscribe_uri[SIPBUFSIZE]; 02165 char device_name[AST_CHANNEL_NAME]; 02166 enum ast_cc_service_type offered_service; 02167 struct sip_monitor_instance *monitor_instance; 02168 if (sip_get_cc_information(req, subscribe_uri, sizeof(subscribe_uri), &offered_service)) { 02169 /* If CC isn't being offered to us, or for some reason the CC offer is 02170 * not formatted correctly, then it may still be possible to use generic 02171 * call completion since the monitor policy may be "always" 02172 */ 02173 goto generic; 02174 } 02175 ast_channel_get_device_name(pvt->owner, device_name, sizeof(device_name)); 02176 if (!(monitor_instance = sip_monitor_instance_init(core_id, subscribe_uri, pvt->peername, device_name))) { 02177 /* Same deal. We can try using generic still */ 02178 goto generic; 02179 } 02180 /* We bump the refcount of chan_sip because once we queue this frame, the CC core 02181 * will have a reference to callbacks in this module. We decrement the module 02182 * refcount once the monitor destructor is called 02183 */ 02184 ast_module_ref(ast_module_info->self); 02185 ast_queue_cc_frame(pvt->owner, "SIP", pvt->dialstring, offered_service, monitor_instance); 02186 ao2_ref(monitor_instance, -1); 02187 return; 02188 } 02189 02190 generic: 02191 if (monitor_policy == AST_CC_MONITOR_GENERIC || monitor_policy == AST_CC_MONITOR_ALWAYS) { 02192 ast_queue_cc_frame(pvt->owner, AST_CC_GENERIC_MONITOR_TYPE, interface_name, service, NULL); 02193 } 02194 }
| 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 6638 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().
06639 { 06640 struct sip_pvt *p = ast->tech_pvt; 06641 int needcancel = FALSE; 06642 int needdestroy = 0; 06643 struct ast_channel *oldowner = ast; 06644 06645 if (!p) { 06646 ast_debug(1, "Asked to hangup channel that was not connected\n"); 06647 return 0; 06648 } 06649 if (ast_test_flag(ast, AST_FLAG_ANSWERED_ELSEWHERE) || ast->hangupcause == AST_CAUSE_ANSWERED_ELSEWHERE) { 06650 ast_debug(1, "This call was answered elsewhere\n"); 06651 if (ast->hangupcause == AST_CAUSE_ANSWERED_ELSEWHERE) { 06652 ast_debug(1, "####### It's the cause code, buddy. The cause code!!!\n"); 06653 } 06654 append_history(p, "Cancel", "Call answered elsewhere"); 06655 p->answered_elsewhere = TRUE; 06656 } 06657 06658 /* Store hangupcause locally in PVT so we still have it before disconnect */ 06659 if (p->owner) 06660 p->hangupcause = p->owner->hangupcause; 06661 06662 if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 06663 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 06664 if (sipdebug) 06665 ast_debug(1, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 06666 update_call_counter(p, DEC_CALL_LIMIT); 06667 } 06668 ast_debug(4, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid); 06669 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 06670 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */ 06671 p->needdestroy = 0; 06672 p->owner->tech_pvt = dialog_unref(p->owner->tech_pvt, "unref p->owner->tech_pvt"); 06673 sip_pvt_lock(p); 06674 p->owner = NULL; /* Owner will be gone after we return, so take it away */ 06675 sip_pvt_unlock(p); 06676 ast_module_unref(ast_module_info->self); 06677 return 0; 06678 } 06679 06680 ast_debug(1, "Hangup call %s, SIP callid %s\n", ast->name, p->callid); 06681 06682 sip_pvt_lock(p); 06683 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 06684 if (sipdebug) 06685 ast_debug(1, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 06686 update_call_counter(p, DEC_CALL_LIMIT); 06687 } 06688 06689 /* Determine how to disconnect */ 06690 if (p->owner != ast) { 06691 ast_log(LOG_WARNING, "Huh? We aren't the owner? Can't hangup call.\n"); 06692 sip_pvt_unlock(p); 06693 return 0; 06694 } 06695 /* If the call is not UP, we need to send CANCEL instead of BYE */ 06696 /* In case of re-invites, the call might be UP even though we have an incomplete invite transaction */ 06697 if (p->invitestate < INV_COMPLETED && p->owner->_state != AST_STATE_UP) { 06698 needcancel = TRUE; 06699 ast_debug(4, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state)); 06700 } 06701 06702 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 06703 06704 append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", p->owner ? ast_cause2str(p->hangupcause) : "Unknown"); 06705 06706 /* Disconnect */ 06707 disable_dsp_detect(p); 06708 06709 p->owner = NULL; 06710 ast->tech_pvt = dialog_unref(ast->tech_pvt, "unref ast->tech_pvt"); 06711 06712 ast_module_unref(ast_module_info->self); 06713 /* Do not destroy this pvt until we have timeout or 06714 get an answer to the BYE or INVITE/CANCEL 06715 If we get no answer during retransmit period, drop the call anyway. 06716 (Sorry, mother-in-law, you can't deny a hangup by sending 06717 603 declined to BYE...) 06718 */ 06719 if (p->alreadygone) 06720 needdestroy = 1; /* Set destroy flag at end of this function */ 06721 else if (p->invitestate != INV_CALLING) 06722 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 06723 06724 /* Start the process if it's not already started */ 06725 if (!p->alreadygone && p->initreq.data && ast_str_strlen(p->initreq.data)) { 06726 if (needcancel) { /* Outgoing call, not up */ 06727 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06728 /* if we can't send right now, mark it pending */ 06729 if (p->invitestate == INV_CALLING) { 06730 /* We can't send anything in CALLING state */ 06731 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 06732 /* 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. */ 06733 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 06734 append_history(p, "DELAY", "Not sending cancel, waiting for timeout"); 06735 } else { 06736 struct sip_pkt *cur; 06737 06738 for (cur = p->packets; cur; cur = cur->next) { 06739 __sip_semi_ack(p, cur->seqno, cur->is_resp, cur->method ? cur->method : find_sip_method(ast_str_buffer(cur->data))); 06740 } 06741 p->invitestate = INV_CANCELLED; 06742 /* Send a new request: CANCEL */ 06743 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 06744 /* Actually don't destroy us yet, wait for the 487 on our original 06745 INVITE, but do set an autodestruct just in case we never get it. */ 06746 needdestroy = 0; 06747 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 06748 } 06749 } else { /* Incoming call, not up */ 06750 const char *res; 06751 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")); 06752 if (p->hangupcause && (res = hangup_cause2sip(p->hangupcause))) 06753 transmit_response_reliable(p, res, &p->initreq); 06754 else 06755 transmit_response_reliable(p, "603 Declined", &p->initreq); 06756 p->invitestate = INV_TERMINATED; 06757 } 06758 } else { /* Call is in UP state, send BYE */ 06759 if (p->stimer->st_active == TRUE) { 06760 stop_session_timer(p); 06761 } 06762 06763 if (!p->pendinginvite) { 06764 struct ast_channel *bridge = ast_bridged_channel(oldowner); 06765 char quality_buf[AST_MAX_USER_FIELD], *quality; 06766 06767 /* We need to get the lock on bridge because ast_rtp_instance_set_stats_vars will attempt 06768 * to lock the bridge. This may get hairy... 06769 */ 06770 while (bridge && ast_channel_trylock(bridge)) { 06771 sip_pvt_unlock(p); 06772 do { 06773 CHANNEL_DEADLOCK_AVOIDANCE(oldowner); 06774 } while (sip_pvt_trylock(p)); 06775 bridge = ast_bridged_channel(oldowner); 06776 } 06777 06778 if (p->rtp) { 06779 ast_rtp_instance_set_stats_vars(oldowner, p->rtp); 06780 } 06781 06782 if (bridge) { 06783 struct sip_pvt *q = bridge->tech_pvt; 06784 06785 if (IS_SIP_TECH(bridge->tech) && q && q->rtp) { 06786 ast_rtp_instance_set_stats_vars(bridge, q->rtp); 06787 } 06788 ast_channel_unlock(bridge); 06789 } 06790 06791 /* 06792 * The channel variables are set below just to get the AMI 06793 * VarSet event because the channel is being hungup. 06794 */ 06795 if (p->rtp && (quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) { 06796 if (p->do_history) { 06797 append_history(p, "RTCPaudio", "Quality:%s", quality); 06798 } 06799 pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", quality); 06800 } 06801 if (p->vrtp && (quality = ast_rtp_instance_get_quality(p->vrtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) { 06802 if (p->do_history) { 06803 append_history(p, "RTCPvideo", "Quality:%s", quality); 06804 } 06805 pbx_builtin_setvar_helper(oldowner, "RTPVIDEOQOS", quality); 06806 } 06807 if (p->trtp && (quality = ast_rtp_instance_get_quality(p->trtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) { 06808 if (p->do_history) { 06809 append_history(p, "RTCPtext", "Quality:%s", quality); 06810 } 06811 pbx_builtin_setvar_helper(oldowner, "RTPTEXTQOS", quality); 06812 } 06813 06814 /* Send a hangup */ 06815 if (oldowner->_state == AST_STATE_UP) { 06816 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 06817 } 06818 06819 } else { 06820 /* Note we will need a BYE when this all settles out 06821 but we can't send one while we have "INVITE" outstanding. */ 06822 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 06823 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 06824 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")); 06825 if (sip_cancel_destroy(p)) { 06826 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 06827 } 06828 /* If we have an ongoing reinvite, there is a chance that we have gotten a provisional 06829 * response, but something weird has happened and we will never receive a final response. 06830 * So, just in case, check for pending actions after a bit of time to trigger the pending 06831 * bye that we are setting above */ 06832 if (p->ongoing_reinvite && p->reinviteid < 0) { 06833 p->reinviteid = ast_sched_add(sched, 32 * p->timer_t1, reinvite_timeout, dialog_ref(p, "ref for reinvite_timeout")); 06834 } 06835 } 06836 } 06837 } 06838 if (needdestroy) { 06839 pvt_set_needdestroy(p, "hangup"); 06840 } 06841 sip_pvt_unlock(p); 06842 return 0; 06843 }
| 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 7241 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().
07242 { 07243 struct sip_pvt *p = ast->tech_pvt; 07244 int res = 0; 07245 07246 sip_pvt_lock(p); 07247 switch(condition) { 07248 case AST_CONTROL_RINGING: 07249 if (ast->_state == AST_STATE_RING) { 07250 p->invitestate = INV_EARLY_MEDIA; 07251 if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) || 07252 (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) { 07253 /* Send 180 ringing if out-of-band seems reasonable */ 07254 transmit_provisional_response(p, "180 Ringing", &p->initreq, 0); 07255 ast_set_flag(&p->flags[0], SIP_RINGING); 07256 if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES) 07257 break; 07258 } else { 07259 /* Well, if it's not reasonable, just send in-band */ 07260 } 07261 } 07262 res = -1; 07263 break; 07264 case AST_CONTROL_BUSY: 07265 if (ast->_state != AST_STATE_UP) { 07266 transmit_response_reliable(p, "486 Busy Here", &p->initreq); 07267 p->invitestate = INV_COMPLETED; 07268 sip_alreadygone(p); 07269 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 07270 break; 07271 } 07272 res = -1; 07273 break; 07274 case AST_CONTROL_CONGESTION: 07275 if (ast->_state != AST_STATE_UP) { 07276 transmit_response_reliable(p, "503 Service Unavailable", &p->initreq); 07277 p->invitestate = INV_COMPLETED; 07278 sip_alreadygone(p); 07279 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 07280 break; 07281 } 07282 res = -1; 07283 break; 07284 case AST_CONTROL_INCOMPLETE: 07285 if (ast->_state != AST_STATE_UP) { 07286 switch (ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) { 07287 case SIP_PAGE2_ALLOWOVERLAP_YES: 07288 transmit_response_reliable(p, "484 Address Incomplete", &p->initreq); 07289 p->invitestate = INV_COMPLETED; 07290 sip_alreadygone(p); 07291 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 07292 break; 07293 case SIP_PAGE2_ALLOWOVERLAP_DTMF: 07294 /* Just wait for inband DTMF digits */ 07295 break; 07296 default: 07297 /* it actually means no support for overlap */ 07298 transmit_response_reliable(p, "404 Not Found", &p->initreq); 07299 p->invitestate = INV_COMPLETED; 07300 sip_alreadygone(p); 07301 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 07302 break; 07303 } 07304 } 07305 break; 07306 case AST_CONTROL_PROCEEDING: 07307 if ((ast->_state != AST_STATE_UP) && 07308 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 07309 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 07310 transmit_response(p, "100 Trying", &p->initreq); 07311 p->invitestate = INV_PROCEEDING; 07312 break; 07313 } 07314 res = -1; 07315 break; 07316 case AST_CONTROL_PROGRESS: 07317 if ((ast->_state != AST_STATE_UP) && 07318 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 07319 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 07320 p->invitestate = INV_EARLY_MEDIA; 07321 transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE); 07322 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 07323 break; 07324 } 07325 res = -1; 07326 break; 07327 case AST_CONTROL_HOLD: 07328 ast_rtp_instance_update_source(p->rtp); 07329 ast_moh_start(ast, data, p->mohinterpret); 07330 break; 07331 case AST_CONTROL_UNHOLD: 07332 ast_rtp_instance_update_source(p->rtp); 07333 ast_moh_stop(ast); 07334 break; 07335 case AST_CONTROL_VIDUPDATE: /* Request a video frame update */ 07336 if (p->vrtp && !p->novideo) { 07337 transmit_info_with_vidupdate(p); 07338 /* ast_rtcp_send_h261fur(p->vrtp); */ 07339 } else 07340 res = -1; 07341 break; 07342 case AST_CONTROL_T38_PARAMETERS: 07343 res = -1; 07344 if (datalen != sizeof(struct ast_control_t38_parameters)) { 07345 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); 07346 } else { 07347 const struct ast_control_t38_parameters *parameters = data; 07348 if (!initialize_udptl(p)) { 07349 res = interpret_t38_parameters(p, parameters); 07350 } 07351 } 07352 break; 07353 case AST_CONTROL_SRCUPDATE: 07354 ast_rtp_instance_update_source(p->rtp); 07355 break; 07356 case AST_CONTROL_SRCCHANGE: 07357 ast_rtp_instance_change_source(p->rtp); 07358 break; 07359 case AST_CONTROL_CONNECTED_LINE: 07360 update_connectedline(p, data, datalen); 07361 break; 07362 case AST_CONTROL_REDIRECTING: 07363 update_redirecting(p, data, datalen); 07364 break; 07365 case AST_CONTROL_AOC: 07366 { 07367 struct ast_aoc_decoded *decoded = ast_aoc_decode((struct ast_aoc_encoded *) data, datalen, ast); 07368 if (!decoded) { 07369 ast_log(LOG_ERROR, "Error decoding indicated AOC data\n"); 07370 res = -1; 07371 break; 07372 } 07373 switch (ast_aoc_get_msg_type(decoded)) { 07374 case AST_AOC_REQUEST: 07375 if (ast_aoc_get_termination_request(decoded)) { 07376 /* TODO, once there is a way to get AOC-E on hangup, attempt that here 07377 * before hanging up the channel.*/ 07378 07379 /* The other side has already initiated the hangup. This frame 07380 * just says they are waiting to get AOC-E before completely tearing 07381 * the call down. Since SIP does not support this at the moment go 07382 * ahead and terminate the call here to avoid an unnecessary timeout. */ 07383 ast_debug(1, "AOC-E termination request received on %s. This is not yet supported on sip. Continue with hangup \n", p->owner->name); 07384 ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV); 07385 } 07386 break; 07387 case AST_AOC_D: 07388 case AST_AOC_E: 07389 if (ast_test_flag(&p->flags[2], SIP_PAGE3_SNOM_AOC)) { 07390 transmit_info_with_aoc(p, decoded); 07391 } 07392 break; 07393 case AST_AOC_S: /* S not supported yet */ 07394 default: 07395 break; 07396 } 07397 ast_aoc_destroy_decoded(decoded); 07398 } 07399 break; 07400 case AST_CONTROL_UPDATE_RTP_PEER: /* Absorb this since it is handled by the bridge */ 07401 break; 07402 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. */ 07403 res = -1; 07404 break; 07405 case -1: 07406 res = -1; 07407 break; 07408 default: 07409 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition); 07410 res = -1; 07411 break; 07412 } 07413 sip_pvt_unlock(p); 07414 return res; 07415 }
| static int sip_is_xml_parsable | ( | void | ) | [static] |
Definition at line 30330 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 1851 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 1859 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().
01860 { 01861 struct sip_monitor_instance *monitor_instance = data; 01862 if (monitor_instance->subscription_pvt) { 01863 sip_pvt_lock(monitor_instance->subscription_pvt); 01864 monitor_instance->subscription_pvt->expiry = 0; 01865 transmit_invite(monitor_instance->subscription_pvt, SIP_SUBSCRIBE, FALSE, 0, monitor_instance->subscribe_uri); 01866 sip_pvt_unlock(monitor_instance->subscription_pvt); 01867 dialog_unref(monitor_instance->subscription_pvt, "Unref monitor instance ref of subscription pvt"); 01868 } 01869 if (monitor_instance->suspension_entry) { 01870 monitor_instance->suspension_entry->body[0] = '\0'; 01871 transmit_publish(monitor_instance->suspension_entry, SIP_PUBLISH_REMOVE ,monitor_instance->notify_uri); 01872 ao2_t_ref(monitor_instance->suspension_entry, -1, "Decrementing suspension entry refcount in sip_monitor_instance_destructor"); 01873 } 01874 ast_string_field_free_memory(monitor_instance); 01875 }
| static int sip_monitor_instance_hash_fn | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 1845 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 1877 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().
01878 { 01879 struct sip_monitor_instance *monitor_instance = ao2_alloc(sizeof(*monitor_instance), sip_monitor_instance_destructor); 01880 01881 if (!monitor_instance) { 01882 return NULL; 01883 } 01884 01885 if (ast_string_field_init(monitor_instance, 256)) { 01886 ao2_ref(monitor_instance, -1); 01887 return NULL; 01888 } 01889 01890 ast_string_field_set(monitor_instance, subscribe_uri, subscribe_uri); 01891 ast_string_field_set(monitor_instance, peername, peername); 01892 ast_string_field_set(monitor_instance, device_name, device_name); 01893 monitor_instance->core_id = core_id; 01894 ao2_link(sip_monitor_instances, monitor_instance); 01895 return monitor_instance; 01896 }
| static const char * sip_nat_mode | ( | const struct sip_pvt * | p | ) | [static] |
Display SIP nat mode.
Definition at line 3554 of file chan_sip.c.
References ast_test_flag.
Referenced by check_via(), retrans_pkt(), and send_response().
03555 { 03556 return ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT) ? "NAT" : "no NAT"; 03557 }
| 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 7428 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_verbose, 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, option_debug, 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, VERBOSE_PREFIX_3, and ast_channel::writeformat.
Referenced by handle_request_invite(), and sip_request_call().
07429 { 07430 struct ast_channel *tmp; 07431 struct ast_variable *v = NULL; 07432 format_t fmt; 07433 format_t what; 07434 format_t video; 07435 format_t text; 07436 format_t needvideo = 0; 07437 int needtext = 0; 07438 char buf[SIPBUFSIZE]; 07439 char *exten; 07440 07441 if (option_debug > 1) { 07442 ast_verbose(VERBOSE_PREFIX_3 "NEW SIP CHANNEL, title: <%s>\n", title?title:"Null"); 07443 ast_verbose(VERBOSE_PREFIX_3 "from: %s\n", i->from); 07444 ast_verbose(VERBOSE_PREFIX_3 "username: <%s>\n", i->username); 07445 ast_verbose(VERBOSE_PREFIX_3 "peername: <%s>\n", i->peername); 07446 ast_verbose(VERBOSE_PREFIX_3 "fromdomain: %s\n", i->fromdomain); 07447 ast_verbose(VERBOSE_PREFIX_3 "fromuser: %s\n", i->fromuser); 07448 ast_verbose(VERBOSE_PREFIX_3 "fromname: %s\n", i->fromname); 07449 ast_verbose(VERBOSE_PREFIX_3 "fullcontact: %s\n", i->fullcontact); 07450 } 07451 { 07452 char my_name[128]; /* pick a good name */ 07453 07454 if (!ast_strlen_zero(i->username)) { 07455 if (!ast_strlen_zero(title) && strcmp(i->username, title)) { 07456 /* title not empty and different from username */ 07457 snprintf(my_name, sizeof(my_name), "%s@%s", i->username, title); 07458 } else { 07459 /* username not empty, title is empty or equal to username */ 07460 snprintf(my_name, sizeof(my_name), "%s", i->username); 07461 } 07462 } else { /* username empty */ 07463 if (title) { 07464 snprintf(my_name, sizeof(my_name), "%s", title); 07465 } else { 07466 snprintf(my_name, sizeof(my_name), "%s", i->fromdomain); 07467 } 07468 } 07469 07470 sip_pvt_unlock(i); 07471 /* Don't hold a sip pvt lock while we allocate a channel */ 07472 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, ast_atomic_fetchadd_int((int *)&chan_idx, +1)); 07473 } 07474 if (!tmp) { 07475 ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n"); 07476 sip_pvt_lock(i); 07477 return NULL; 07478 } 07479 ast_channel_lock(tmp); 07480 sip_pvt_lock(i); 07481 ast_channel_cc_params_init(tmp, i->cc_params); 07482 tmp->caller.id.tag = ast_strdup(i->cid_tag); 07483 07484 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; 07485 07486 /* Select our native format based on codec preference until we receive 07487 something from another device to the contrary. */ 07488 if (i->jointcapability) { /* The joint capabilities of us and peer */ 07489 what = i->jointcapability; 07490 video = i->jointcapability & AST_FORMAT_VIDEO_MASK; 07491 text = i->jointcapability & AST_FORMAT_TEXT_MASK; 07492 } else if (i->capability) { /* Our configured capability for this peer */ 07493 what = i->capability; 07494 video = i->capability & AST_FORMAT_VIDEO_MASK; 07495 text = i->capability & AST_FORMAT_TEXT_MASK; 07496 } else { 07497 what = sip_cfg.capability; /* Global codec support */ 07498 video = sip_cfg.capability & AST_FORMAT_VIDEO_MASK; 07499 text = sip_cfg.capability & AST_FORMAT_TEXT_MASK; 07500 } 07501 07502 /* Set the native formats for audio and merge in video */ 07503 tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | video | text; 07504 ast_debug(3, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, tmp->nativeformats)); 07505 ast_debug(3, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->jointcapability)); 07506 ast_debug(3, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->capability)); 07507 ast_debug(3, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, ast_codec_choose(&i->prefs, what, 1))); 07508 if (i->prefcodec) 07509 ast_debug(3, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->prefcodec)); 07510 07511 /* XXX Why are we choosing a codec from the native formats?? */ 07512 fmt = ast_best_codec(tmp->nativeformats); 07513 07514 /* If we have a prefcodec setting, we have an inbound channel that set a 07515 preferred format for this call. Otherwise, we check the jointcapability 07516 We also check for vrtp. If it's not there, we are not allowed do any video anyway. 07517 */ 07518 if (i->vrtp) { 07519 if (ast_test_flag(&i->flags[1], SIP_PAGE2_VIDEOSUPPORT)) 07520 needvideo = AST_FORMAT_VIDEO_MASK; 07521 else if (i->prefcodec) 07522 needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK; /* Outbound call */ 07523 else 07524 needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK; /* Inbound call */ 07525 } 07526 07527 if (i->trtp) { 07528 if (i->prefcodec) 07529 needtext = i->prefcodec & AST_FORMAT_TEXT_MASK; /* Outbound call */ 07530 else 07531 needtext = i->jointcapability & AST_FORMAT_TEXT_MASK; /* Inbound call */ 07532 } 07533 07534 if (needvideo) 07535 ast_debug(3, "This channel can handle video! HOLLYWOOD next!\n"); 07536 else 07537 ast_debug(3, "This channel will not be able to handle video.\n"); 07538 07539 enable_dsp_detect(i); 07540 07541 if ((ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || 07542 (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) { 07543 if (i->rtp) { 07544 ast_rtp_instance_dtmf_mode_set(i->rtp, AST_RTP_DTMF_MODE_INBAND); 07545 } 07546 } else if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) { 07547 if (i->rtp) { 07548 ast_rtp_instance_dtmf_mode_set(i->rtp, AST_RTP_DTMF_MODE_RFC2833); 07549 } 07550 } 07551 07552 /* Set file descriptors for audio, video, and realtime text. Since 07553 * UDPTL is created as needed in the lifetime of a dialog, its file 07554 * descriptor is set in initialize_udptl */ 07555 if (i->rtp) { 07556 ast_channel_set_fd(tmp, 0, ast_rtp_instance_fd(i->rtp, 0)); 07557 ast_channel_set_fd(tmp, 1, ast_rtp_instance_fd(i->rtp, 1)); 07558 ast_rtp_instance_set_write_format(i->rtp, fmt); 07559 ast_rtp_instance_set_read_format(i->rtp, fmt); 07560 } 07561 if (needvideo && i->vrtp) { 07562 ast_channel_set_fd(tmp, 2, ast_rtp_instance_fd(i->vrtp, 0)); 07563 ast_channel_set_fd(tmp, 3, ast_rtp_instance_fd(i->vrtp, 1)); 07564 } 07565 if (needtext && i->trtp) { 07566 ast_channel_set_fd(tmp, 4, ast_rtp_instance_fd(i->trtp, 0)); 07567 } 07568 if (i->udptl) { 07569 ast_channel_set_fd(tmp, 5, ast_udptl_fd(i->udptl)); 07570 } 07571 07572 if (state == AST_STATE_RING) 07573 tmp->rings = 1; 07574 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 07575 07576 tmp->writeformat = fmt; 07577 tmp->rawwriteformat = fmt; 07578 07579 tmp->readformat = fmt; 07580 tmp->rawreadformat = fmt; 07581 07582 tmp->tech_pvt = dialog_ref(i, "sip_new: set chan->tech_pvt to i"); 07583 07584 tmp->callgroup = i->callgroup; 07585 tmp->pickupgroup = i->pickupgroup; 07586 tmp->caller.id.name.presentation = i->callingpres; 07587 tmp->caller.id.number.presentation = i->callingpres; 07588 if (!ast_strlen_zero(i->parkinglot)) 07589 ast_string_field_set(tmp, parkinglot, i->parkinglot); 07590 if (!ast_strlen_zero(i->accountcode)) 07591 ast_string_field_set(tmp, accountcode, i->accountcode); 07592 if (i->amaflags) 07593 tmp->amaflags = i->amaflags; 07594 if (!ast_strlen_zero(i->language)) 07595 ast_string_field_set(tmp, language, i->language); 07596 i->owner = tmp; 07597 ast_module_ref(ast_module_info->self); 07598 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 07599 /*Since it is valid to have extensions in the dialplan that have unescaped characters in them 07600 * we should decode the uri before storing it in the channel, but leave it encoded in the sip_pvt 07601 * structure so that there aren't issues when forming URI's 07602 */ 07603 exten = ast_strdupa(i->exten); 07604 sip_pvt_unlock(i); 07605 ast_channel_unlock(tmp); 07606 if (!ast_exists_extension(NULL, i->context, i->exten, 1, i->cid_num)) { 07607 ast_uri_decode(exten); 07608 } 07609 ast_channel_lock(tmp); 07610 sip_pvt_lock(i); 07611 ast_copy_string(tmp->exten, exten, sizeof(tmp->exten)); 07612 07613 /* Don't use ast_set_callerid() here because it will 07614 * generate an unnecessary NewCallerID event */ 07615 if (!ast_strlen_zero(i->cid_num)) { 07616 tmp->caller.ani.number.valid = 1; 07617 tmp->caller.ani.number.str = ast_strdup(i->cid_num); 07618 } 07619 if (!ast_strlen_zero(i->rdnis)) { 07620 tmp->redirecting.from.number.valid = 1; 07621 tmp->redirecting.from.number.str = ast_strdup(i->rdnis); 07622 } 07623 07624 if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) { 07625 tmp->dialed.number.str = ast_strdup(i->exten); 07626 } 07627 07628 tmp->priority = 1; 07629 if (!ast_strlen_zero(i->uri)) 07630 pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri); 07631 if (!ast_strlen_zero(i->domain)) 07632 pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain); 07633 if (!ast_strlen_zero(i->callid)) 07634 pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid); 07635 if (i->rtp) 07636 ast_jb_configure(tmp, &global_jbconf); 07637 07638 if (!i->relatedpeer) { 07639 tmp->flags |= AST_FLAG_DISABLE_DEVSTATE_CACHE; 07640 } 07641 /* Set channel variables for this call from configuration */ 07642 for (v = i->chanvars ; v ; v = v->next) { 07643 char valuebuf[1024]; 07644 pbx_builtin_setvar_helper(tmp, v->name, ast_get_encoded_str(v->value, valuebuf, sizeof(valuebuf))); 07645 } 07646 07647 if (i->do_history) 07648 append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid); 07649 07650 /* Inform manager user about new channel and their SIP call ID */ 07651 if (sip_cfg.callevents) 07652 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", 07653 "Channel: %s\r\nUniqueid: %s\r\nChanneltype: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\n", 07654 tmp->name, tmp->uniqueid, "SIP", i->callid, i->fullcontact); 07655 07656 return tmp; 07657 }
| static int sip_notify_allocate | ( | struct sip_pvt * | p | ) | [static] |
Allocate SIP refer structure.
Definition at line 13999 of file chan_sip.c.
References ast_calloc, and ast_str_create().
Referenced by manager_sipnotify(), and sip_cli_notify().
14000 { 14001 p->notify = ast_calloc(1, sizeof(struct sip_notify)); 14002 if (p->notify) { 14003 p->notify->content = ast_str_create(128); 14004 } 14005 return p->notify ? 1 : 0; 14006 }
| static int sip_offer_timer_expire | ( | const void * | data | ) | [static] |
Definition at line 1727 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().
01728 { 01729 struct ast_cc_agent *agent = (struct ast_cc_agent *) data; 01730 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01731 01732 agent_pvt->offer_timer_id = -1; 01733 01734 return ast_cc_failed(agent->core_id, "SIP agent %s's offer timer expired", agent->device_name); 01735 }
| 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 22141 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().
22142 { 22143 struct sip_dual *d; 22144 struct ast_channel *transferee, *transferer; 22145 pthread_t th; 22146 22147 transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->linkedid, chan1->amaflags, "Parking/%s", chan1->name); 22148 transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->linkedid, chan2->amaflags, "SIPPeer/%s", chan2->name); 22149 d = ast_calloc(1, sizeof(*d)); 22150 if (!transferee || !transferer || !d) { 22151 if (transferee) { 22152 ast_hangup(transferee); 22153 } 22154 if (transferer) { 22155 ast_hangup(transferer); 22156 } 22157 ast_free(d); 22158 return -1; 22159 } 22160 d->park_exten = ast_strdup(park_exten); 22161 d->park_context = ast_strdup(park_context); 22162 if (!d->park_exten || !d->park_context) { 22163 ast_hangup(transferee); 22164 ast_hangup(transferer); 22165 ast_free(d->park_exten); 22166 ast_free(d->park_context); 22167 ast_free(d); 22168 return -1; 22169 } 22170 22171 /* Make formats okay */ 22172 transferee->readformat = chan1->readformat; 22173 transferee->writeformat = chan1->writeformat; 22174 22175 /* Prepare for taking over the channel */ 22176 if (ast_channel_masquerade(transferee, chan1)) { 22177 ast_hangup(transferee); 22178 ast_hangup(transferer); 22179 ast_free(d->park_exten); 22180 ast_free(d->park_context); 22181 ast_free(d); 22182 return -1; 22183 } 22184 22185 /* Setup the extensions and such */ 22186 ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context)); 22187 ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten)); 22188 transferee->priority = chan1->priority; 22189 22190 ast_do_masquerade(transferee); 22191 22192 /* We make a clone of the peer channel too, so we can play 22193 back the announcement */ 22194 22195 /* Make formats okay */ 22196 transferer->readformat = chan2->readformat; 22197 transferer->writeformat = chan2->writeformat; 22198 ast_string_field_set(transferer, parkinglot, chan2->parkinglot); 22199 22200 /* Prepare for taking over the channel */ 22201 if (ast_channel_masquerade(transferer, chan2)) { 22202 ast_hangup(transferer); 22203 ast_free(d->park_exten); 22204 ast_free(d->park_context); 22205 ast_free(d); 22206 return -1; 22207 } 22208 22209 /* Setup the extensions and such */ 22210 ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context)); 22211 ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten)); 22212 transferer->priority = chan2->priority; 22213 22214 ast_do_masquerade(transferer); 22215 22216 /* Save original request for followup */ 22217 copy_request(&d->req, req); 22218 d->chan1 = transferee; /* Transferee */ 22219 d->chan2 = transferer; /* Transferer */ 22220 d->seqno = seqno; 22221 if (ast_pthread_create_detached_background(&th, NULL, sip_park_thread, d) < 0) { 22222 /* Could not start thread */ 22223 deinit_req(&d->req); 22224 ast_free(d->park_exten); 22225 ast_free(d->park_context); 22226 ast_free(d); /* We don't need it anymore. If thread is created, d will be free'd 22227 by sip_park_thread() */ 22228 return -1; 22229 } 22230 return 0; 22231 }
| 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 22093 of file chan_sip.c.
References append_history, AST_CAUSE_NORMAL_CLEARING, ast_debug, ast_free, ast_hangup(), ast_park_call_exten(), deinit_req(), ext, ast_channel::hangupcause, ast_channel::tech_pvt, transmit_message_with_text(), transmit_notify_with_sipfrag(), and TRUE.
Referenced by sip_park().
22094 { 22095 struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */ 22096 struct sip_dual *d; 22097 int ext; 22098 int res; 22099 22100 d = stuff; 22101 transferee = d->chan1; 22102 transferer = d->chan2; 22103 22104 ast_debug(4, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name); 22105 22106 res = ast_park_call_exten(transferee, transferer, d->park_exten, d->park_context, 0, &ext); 22107 22108 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE 22109 if (res) { 22110 transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n"); 22111 } else { 22112 /* Then tell the transferer what happened */ 22113 sprintf(buf, "Call parked on extension '%d'", ext); 22114 transmit_message_with_text(transferer->tech_pvt, buf); 22115 } 22116 #endif 22117 22118 /* Any way back to the current call??? */ 22119 /* Transmit response to the REFER request */ 22120 if (!res) { 22121 /* Transfer succeeded */ 22122 append_history(transferer->tech_pvt, "SIPpark", "Parked call on %d", ext); 22123 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE); 22124 transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING; 22125 ast_hangup(transferer); /* This will cause a BYE */ 22126 ast_debug(1, "SIP Call parked on extension '%d'\n", ext); 22127 } else { 22128 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE); 22129 append_history(transferer->tech_pvt, "SIPpark", "Parking failed\n"); 22130 ast_debug(1, "SIP Call parked failed \n"); 22131 /* Do not hangup call */ 22132 } 22133 deinit_req(&d->req); 22134 ast_free(d->park_exten); 22135 ast_free(d->park_context); 22136 ast_free(d); 22137 return NULL; 22138 }
| 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 15068 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().
15069 { 15070 if (!p->relatedpeer) { 15071 return; 15072 } 15073 15074 /* If they put someone on hold, increment the value... otherwise decrement it */ 15075 ast_atomic_fetchadd_int(&p->relatedpeer->onHold, (hold ? +1 : -1)); 15076 15077 /* Request device state update */ 15078 ast_devstate_changed(AST_DEVICE_UNKNOWN, (p->owner->flags & AST_FLAG_DISABLE_DEVSTATE_CACHE ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE), 15079 "SIP/%s", p->relatedpeer->name); 15080 15081 return; 15082 }
| 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 22256 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().
22257 { 22258 pthread_t threadid; 22259 22260 ast_channel_ref(chan); 22261 22262 if (ast_pthread_create_detached_background(&threadid, NULL, sip_pickup_thread, chan)) { 22263 ast_debug(1, "Unable to start Group pickup thread on channel %s\n", chan->name); 22264 ast_channel_unref(chan); 22265 return -1; 22266 } 22267 ast_debug(1, "Started Group pickup thread on channel %s\n", chan->name); 22268 return 0; 22269 }
| static void * sip_pickup_thread | ( | void * | stuff | ) | [static] |
SIP pickup support function Starts in a new thread, then pickup the call.
Definition at line 22237 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().
22238 { 22239 struct ast_channel *chan; 22240 chan = stuff; 22241 22242 if (ast_pickup_call(chan)) { 22243 chan->hangupcause = AST_CAUSE_CALL_REJECTED; 22244 } else { 22245 chan->hangupcause = AST_CAUSE_NORMAL_CLEARING; 22246 } 22247 ast_hangup(chan); 22248 ast_channel_unref(chan); 22249 chan = NULL; 22250 return NULL; 22251 }
| static void sip_poke_all_peers | ( | void | ) | [static] |
Send a poke to all known peers.
Definition at line 30340 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().
30341 { 30342 int ms = 0, num = 0; 30343 struct ao2_iterator i; 30344 struct sip_peer *peer; 30345 30346 if (!speerobjs) { /* No peers, just give up */ 30347 return; 30348 } 30349 30350 i = ao2_iterator_init(peers, 0); 30351 while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) { 30352 ao2_lock(peer); 30353 /* Don't schedule poking on a peer without qualify */ 30354 if (peer->maxms) { 30355 if (num == global_qualify_peers) { 30356 ms += global_qualify_gap; 30357 num = 0; 30358 } else { 30359 num++; 30360 } 30361 AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, ms, sip_poke_peer_s, peer, 30362 unref_peer(_data, "removing poke peer ref"), 30363 unref_peer(peer, "removing poke peer ref"), 30364 ref_peer(peer, "adding poke peer ref")); 30365 } 30366 ao2_unlock(peer); 30367 unref_peer(peer, "toss iterator peer ptr"); 30368 } 30369 ao2_iterator_destroy(&i); 30370 }
| static int sip_poke_noanswer | ( | const void * | data | ) | [static] |
React to lack of answer to Qualify poke.
Definition at line 26958 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().
26959 { 26960 struct sip_peer *peer = (struct sip_peer *)data; 26961 26962 peer->pokeexpire = -1; 26963 26964 if (peer->lastms > -1) { 26965 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms); 26966 if (sip_cfg.peer_rtupdate) { 26967 ast_update_realtime(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", "name", peer->name, "lastms", "-1", SENTINEL); 26968 } 26969 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1); 26970 if (sip_cfg.regextenonqualify) { 26971 register_peer_exten(peer, FALSE); 26972 } 26973 } 26974 26975 if (peer->call) { 26976 dialog_unlink_all(peer->call); 26977 peer->call = dialog_unref(peer->call, "unref dialog peer->call"); 26978 /* peer->call = sip_destroy(peer->call);*/ 26979 } 26980 26981 /* Don't send a devstate change if nothing changed. */ 26982 if (peer->lastms > -1) { 26983 peer->lastms = -1; 26984 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", peer->name); 26985 } 26986 26987 /* Try again quickly */ 26988 AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, 26989 DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer, 26990 unref_peer(_data, "removing poke peer ref"), 26991 unref_peer(peer, "removing poke peer ref"), 26992 ref_peer(peer, "adding poke peer ref")); 26993 26994 /* Release the ref held by the running scheduler entry */ 26995 unref_peer(peer, "release peer poke noanswer ref"); 26996 26997 return 0; 26998 }
| static int sip_poke_peer | ( | struct sip_peer * | peer, | |
| int | force | |||
| ) | [static] |
Check availability of peer, also keep NAT open.
Definition at line 27008 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().
27009 { 27010 struct sip_pvt *p; 27011 int xmitres = 0; 27012 27013 if ((!peer->maxms && !force) || ast_sockaddr_isnull(&peer->addr)) { 27014 /* IF we have no IP, or this isn't to be monitored, return 27015 immediately after clearing things out */ 27016 AST_SCHED_DEL_UNREF(sched, peer->pokeexpire, 27017 unref_peer(peer, "removing poke peer ref")); 27018 27019 peer->lastms = 0; 27020 if (peer->call) { 27021 peer->call = dialog_unref(peer->call, "unref dialog peer->call"); 27022 } 27023 return 0; 27024 } 27025 if (peer->call) { 27026 if (sipdebug) { 27027 ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n"); 27028 } 27029 dialog_unlink_all(peer->call); 27030 peer->call = dialog_unref(peer->call, "unref dialog peer->call"); 27031 /* peer->call = sip_destroy(peer->call); */ 27032 } 27033 if (!(p = sip_alloc(NULL, NULL, 0, SIP_OPTIONS, NULL))) { 27034 return -1; 27035 } 27036 peer->call = dialog_ref(p, "copy sip alloc from p to peer->call"); 27037 27038 p->sa = peer->addr; 27039 p->recv = peer->addr; 27040 copy_socket_data(&p->socket, &peer->socket); 27041 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 27042 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 27043 ast_copy_flags(&p->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY); 27044 27045 /* Send OPTIONs to peer's fullcontact */ 27046 if (!ast_strlen_zero(peer->fullcontact)) { 27047 ast_string_field_set(p, fullcontact, peer->fullcontact); 27048 } 27049 27050 if (!ast_strlen_zero(peer->fromuser)) { 27051 ast_string_field_set(p, fromuser, peer->fromuser); 27052 } 27053 27054 if (!ast_strlen_zero(peer->tohost)) { 27055 ast_string_field_set(p, tohost, peer->tohost); 27056 } else { 27057 ast_string_field_set(p, tohost, ast_sockaddr_stringify_host_remote(&peer->addr)); 27058 } 27059 27060 /* Recalculate our side, and recalculate Call ID */ 27061 ast_sip_ouraddrfor(&p->sa, &p->ourip, p); 27062 build_via(p); 27063 27064 /* Change the dialog callid. */ 27065 change_callid_pvt(p, NULL); 27066 27067 AST_SCHED_DEL_UNREF(sched, peer->pokeexpire, 27068 unref_peer(peer, "removing poke peer ref")); 27069 27070 if (p->relatedpeer) 27071 p->relatedpeer = unref_peer(p->relatedpeer,"unsetting the relatedpeer field in the dialog, before it is set to something else."); 27072 p->relatedpeer = ref_peer(peer, "setting the relatedpeer field in the dialog"); 27073 ast_set_flag(&p->flags[0], SIP_OUTGOING); 27074 #ifdef VOCAL_DATA_HACK 27075 ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username)); 27076 xmitres = transmit_invite(p, SIP_INVITE, 0, 2, NULL); /* sinks the p refcount */ 27077 #else 27078 xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2, NULL); /* sinks the p refcount */ 27079 #endif 27080 peer->ps = ast_tvnow(); 27081 if (xmitres == XMIT_ERROR) { 27082 /* Immediately unreachable, network problems */ 27083 sip_poke_noanswer(ref_peer(peer, "add ref for peerexpire (fake, for sip_poke_noanswer to remove)")); 27084 } else if (!force) { 27085 AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, peer->maxms * 2, sip_poke_noanswer, peer, 27086 unref_peer(_data, "removing poke peer ref"), 27087 unref_peer(peer, "removing poke peer ref"), 27088 ref_peer(peer, "adding poke peer ref")); 27089 } 27090 dialog_unref(p, "unref dialog at end of sip_poke_peer, obtained from sip_alloc, just before it goes out of scope"); 27091 return 0; 27092 }
| 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 14304 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().
14305 { 14306 struct sip_peer *peer = (struct sip_peer *)data; 14307 struct sip_peer *foundpeer; 14308 14309 peer->pokeexpire = -1; 14310 14311 foundpeer = ao2_find(peers, peer, OBJ_POINTER); 14312 if (!foundpeer) { 14313 unref_peer(peer, "removing poke peer ref"); 14314 return 0; 14315 } else if (foundpeer->name != peer->name) { 14316 unref_peer(foundpeer, "removing above peer ref"); 14317 unref_peer(peer, "removing poke peer ref"); 14318 return 0; 14319 } 14320 14321 unref_peer(foundpeer, "removing above peer ref"); 14322 sip_poke_peer(peer, 0); 14323 unref_peer(peer, "removing poke peer ref"); 14324 14325 return 0; 14326 }
| static int sip_prepare_socket | ( | struct sip_pvt * | p | ) | [static] |
Definition at line 26204 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().
26205 { 26206 struct sip_socket *s = &p->socket; 26207 static const char name[] = "SIP socket"; 26208 struct sip_threadinfo *th = NULL; 26209 struct ast_tcptls_session_instance *tcptls_session; 26210 struct ast_tcptls_session_args *ca; 26211 struct ast_sockaddr sa_tmp; 26212 pthread_t launched; 26213 26214 /* check to see if a socket is already active */ 26215 if ((s->fd != -1) && (s->type == SIP_TRANSPORT_UDP)) { 26216 return s->fd; 26217 } 26218 if ((s->type & (SIP_TRANSPORT_TCP | SIP_TRANSPORT_TLS)) && 26219 (s->tcptls_session) && 26220 (s->tcptls_session->fd != -1)) { 26221 return s->tcptls_session->fd; 26222 } 26223 26224 /*! \todo Check this... This might be wrong, depending on the proxy configuration 26225 If proxy is in "force" mode its correct. 26226 */ 26227 if (p->outboundproxy && p->outboundproxy->transport) { 26228 s->type = p->outboundproxy->transport; 26229 } 26230 26231 if (s->type == SIP_TRANSPORT_UDP) { 26232 s->fd = sipsock; 26233 return s->fd; 26234 } 26235 26236 /* At this point we are dealing with a TCP/TLS connection 26237 * 1. We need to check to see if a connection thread exists 26238 * for this address, if so use that. 26239 * 2. If a thread does not exist for this address, but the tcptls_session 26240 * exists on the socket, the connection was closed. 26241 * 3. If no tcptls_session thread exists for the address, and no tcptls_session 26242 * already exists on the socket, create a new one and launch a new thread. 26243 */ 26244 26245 /* 1. check for existing threads */ 26246 ast_sockaddr_copy(&sa_tmp, sip_real_dst(p)); 26247 if ((tcptls_session = sip_tcp_locate(&sa_tmp))) { 26248 s->fd = tcptls_session->fd; 26249 if (s->tcptls_session) { 26250 ao2_ref(s->tcptls_session, -1); 26251 s->tcptls_session = NULL; 26252 } 26253 s->tcptls_session = tcptls_session; 26254 return s->fd; 26255 /* 2. Thread not found, if tcptls_session already exists, it once had a thread and is now terminated */ 26256 } else if (s->tcptls_session) { 26257 return s->fd; /* XXX whether reconnection is ever necessary here needs to be investigated further */ 26258 } 26259 26260 /* 3. Create a new TCP/TLS client connection */ 26261 /* create new session arguments for the client connection */ 26262 if (!(ca = ao2_alloc(sizeof(*ca), sip_tcptls_client_args_destructor)) || 26263 !(ca->name = ast_strdup(name))) { 26264 goto create_tcptls_session_fail; 26265 } 26266 ca->accept_fd = -1; 26267 ast_sockaddr_copy(&ca->remote_address,sip_real_dst(p)); 26268 /* if type is TLS, we need to create a tls cfg for this session arg */ 26269 if (s->type == SIP_TRANSPORT_TLS) { 26270 if (!(ca->tls_cfg = ast_calloc(1, sizeof(*ca->tls_cfg)))) { 26271 goto create_tcptls_session_fail; 26272 } 26273 memcpy(ca->tls_cfg, &default_tls_cfg, sizeof(*ca->tls_cfg)); 26274 26275 if (!(ca->tls_cfg->certfile = ast_strdup(default_tls_cfg.certfile)) || 26276 !(ca->tls_cfg->pvtfile = ast_strdup(default_tls_cfg.pvtfile)) || 26277 !(ca->tls_cfg->cipher = ast_strdup(default_tls_cfg.cipher)) || 26278 !(ca->tls_cfg->cafile = ast_strdup(default_tls_cfg.cafile)) || 26279 !(ca->tls_cfg->capath = ast_strdup(default_tls_cfg.capath))) { 26280 26281 goto create_tcptls_session_fail; 26282 } 26283 26284 /* this host is used as the common name in ssl/tls */ 26285 if (!ast_strlen_zero(p->tohost)) { 26286 ast_copy_string(ca->hostname, p->tohost, sizeof(ca->hostname)); 26287 } 26288 } 26289 26290 /* Create a client connection for address, this does not start the connection, just sets it up. */ 26291 if (!(s->tcptls_session = ast_tcptls_client_create(ca))) { 26292 goto create_tcptls_session_fail; 26293 } 26294 26295 s->fd = s->tcptls_session->fd; 26296 26297 /* client connections need to have the sip_threadinfo object created before 26298 * the thread is detached. This ensures the alert_pipe is up before it will 26299 * be used. Note that this function links the new threadinfo object into the 26300 * threadt container. */ 26301 if (!(th = sip_threadinfo_create(s->tcptls_session, s->type))) { 26302 goto create_tcptls_session_fail; 26303 } 26304 26305 /* Give the new thread a reference to the tcptls_session */ 26306 ao2_ref(s->tcptls_session, +1); 26307 26308 if (ast_pthread_create_detached_background(&launched, NULL, sip_tcp_worker_fn, s->tcptls_session)) { 26309 ast_debug(1, "Unable to launch '%s'.", ca->name); 26310 ao2_ref(s->tcptls_session, -1); /* take away the thread ref we just gave it */ 26311 goto create_tcptls_session_fail; 26312 } 26313 26314 return s->fd; 26315 26316 create_tcptls_session_fail: 26317 if (ca) { 26318 ao2_t_ref(ca, -1, "failed to create client, getting rid of client tcptls_session arguments"); 26319 } 26320 if (s->tcptls_session) { 26321 ast_tcptls_close_session_file(s->tcptls_session); 26322 s->fd = -1; 26323 ao2_ref(s->tcptls_session, -1); 26324 s->tcptls_session = NULL; 26325 } 26326 if (th) { 26327 ao2_t_unlink(threadt, th, "Removing tcptls thread info object, thread failed to open"); 26328 } 26329 26330 return -1; 26331 }
| 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 17730 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.
17731 { 17732 struct sip_peer *peer, *pi; 17733 int prunepeer = FALSE; 17734 int multi = FALSE; 17735 const char *name = NULL; 17736 regex_t regexbuf; 17737 int havepattern = 0; 17738 struct ao2_iterator i; 17739 static const char * const choices[] = { "all", "like", NULL }; 17740 char *cmplt; 17741 17742 if (cmd == CLI_INIT) { 17743 e->command = "sip prune realtime [peer|all]"; 17744 e->usage = 17745 "Usage: sip prune realtime [peer [<name>|all|like <pattern>]|all]\n" 17746 " Prunes object(s) from the cache.\n" 17747 " Optional regular expression pattern is used to filter the objects.\n"; 17748 return NULL; 17749 } else if (cmd == CLI_GENERATE) { 17750 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer")) { 17751 cmplt = ast_cli_complete(a->word, choices, a->n); 17752 if (!cmplt) 17753 cmplt = complete_sip_peer(a->word, a->n - sizeof(choices), SIP_PAGE2_RTCACHEFRIENDS); 17754 return cmplt; 17755 } 17756 if (a->pos == 5 && !strcasecmp(a->argv[4], "like")) 17757 return complete_sip_peer(a->word, a->n, SIP_PAGE2_RTCACHEFRIENDS); 17758 return NULL; 17759 } 17760 switch (a->argc) { 17761 case 4: 17762 name = a->argv[3]; 17763 /* we accept a name in position 3, but keywords are not good. */ 17764 if (!strcasecmp(name, "peer") || !strcasecmp(name, "like")) 17765 return CLI_SHOWUSAGE; 17766 prunepeer = TRUE; 17767 if (!strcasecmp(name, "all")) { 17768 multi = TRUE; 17769 name = NULL; 17770 } 17771 /* else a single name, already set */ 17772 break; 17773 case 5: 17774 /* sip prune realtime {peer|like} name */ 17775 name = a->argv[4]; 17776 if (!strcasecmp(a->argv[3], "peer")) 17777 prunepeer = TRUE; 17778 else if (!strcasecmp(a->argv[3], "like")) { 17779 prunepeer = TRUE; 17780 multi = TRUE; 17781 } else 17782 return CLI_SHOWUSAGE; 17783 if (!strcasecmp(name, "like")) 17784 return CLI_SHOWUSAGE; 17785 if (!multi && !strcasecmp(name, "all")) { 17786 multi = TRUE; 17787 name = NULL; 17788 } 17789 break; 17790 case 6: 17791 name = a->argv[5]; 17792 multi = TRUE; 17793 /* sip prune realtime {peer} like name */ 17794 if (strcasecmp(a->argv[4], "like")) 17795 return CLI_SHOWUSAGE; 17796 if (!strcasecmp(a->argv[3], "peer")) { 17797 prunepeer = TRUE; 17798 } else 17799 return CLI_SHOWUSAGE; 17800 break; 17801 default: 17802 return CLI_SHOWUSAGE; 17803 } 17804 17805 if (multi && name) { 17806 if (regcomp(®exbuf, name, REG_EXTENDED | REG_NOSUB)) { 17807 return CLI_SHOWUSAGE; 17808 } 17809 havepattern = 1; 17810 } 17811 17812 if (multi) { 17813 if (prunepeer) { 17814 int pruned = 0; 17815 17816 i = ao2_iterator_init(peers, 0); 17817 while ((pi = ao2_t_iterator_next(&i, "iterate thru peers table"))) { 17818 ao2_lock(pi); 17819 if (name && regexec(®exbuf, pi->name, 0, NULL, 0)) { 17820 ao2_unlock(pi); 17821 unref_peer(pi, "toss iterator peer ptr before continue"); 17822 continue; 17823 }; 17824 if (ast_test_flag(&pi->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 17825 pi->the_mark = 1; 17826 pruned++; 17827 } 17828 ao2_unlock(pi); 17829 unref_peer(pi, "toss iterator peer ptr"); 17830 } 17831 ao2_iterator_destroy(&i); 17832 if (pruned) { 17833 unlink_marked_peers_from_tables(); 17834 ast_cli(a->fd, "%d peers pruned.\n", pruned); 17835 } else 17836 ast_cli(a->fd, "No peers found to prune.\n"); 17837 } 17838 } else { 17839 if (prunepeer) { 17840 struct sip_peer tmp; 17841 ast_copy_string(tmp.name, name, sizeof(tmp.name)); 17842 if ((peer = ao2_t_find(peers, &tmp, OBJ_POINTER | OBJ_UNLINK, "finding to unlink from peers"))) { 17843 if (!ast_sockaddr_isnull(&peer->addr)) { 17844 ao2_t_unlink(peers_by_ip, peer, "unlinking peer from peers_by_ip also"); 17845 } 17846 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 17847 ast_cli(a->fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name); 17848 /* put it back! */ 17849 ao2_t_link(peers, peer, "link peer into peer table"); 17850 if (!ast_sockaddr_isnull(&peer->addr)) { 17851 ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table"); 17852 } 17853 } else 17854 ast_cli(a->fd, "Peer '%s' pruned.\n", name); 17855 unref_peer(peer, "sip_prune_realtime: unref_peer: tossing temp peer ptr"); 17856 } else 17857 ast_cli(a->fd, "Peer '%s' not found.\n", name); 17858 } 17859 } 17860 17861 if (havepattern) { 17862 regfree(®exbuf); 17863 } 17864 17865 return CLI_SUCCESS; 17866 }
| static struct ast_channel * sip_pvt_lock_full | ( | struct sip_pvt * | pvt | ) | [static, read] |
Definition at line 8447 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().
08448 { 08449 struct ast_channel *chan; 08450 08451 /* Locking is simple when it is done right. If you see a deadlock resulting 08452 * in this function, it is not this function's fault, Your problem exists elsewhere. 08453 * This function is perfect... seriously. */ 08454 for (;;) { 08455 /* First, get the channel and grab a reference to it */ 08456 sip_pvt_lock(pvt); 08457 chan = pvt->owner; 08458 if (chan) { 08459 /* The channel can not go away while we hold the pvt lock. 08460 * Give the channel a ref so it will not go away after we let 08461 * the pvt lock go. */ 08462 ast_channel_ref(chan); 08463 } else { 08464 /* no channel, return pvt locked */ 08465 return NULL; 08466 } 08467 08468 /* We had to hold the pvt lock while getting a ref to the owner channel 08469 * but now we have to let this lock go in order to preserve proper 08470 * locking order when grabbing the channel lock */ 08471 sip_pvt_unlock(pvt); 08472 08473 /* Look, no deadlock avoidance, hooray! */ 08474 ast_channel_lock(chan); 08475 sip_pvt_lock(pvt); 08476 08477 if (pvt->owner == chan) { 08478 /* done */ 08479 break; 08480 } 08481 08482 /* If the owner changed while everything was unlocked, no problem, 08483 * just start over and everthing will work. This is rare, do not be 08484 * confused by this loop and think this it is an expensive operation. 08485 * The majority of the calls to this function will never involve multiple 08486 * executions of this loop. */ 08487 ast_channel_unlock(chan); 08488 ast_channel_unref(chan); 08489 sip_pvt_unlock(pvt); 08490 } 08491 08492 /* If owner exists, it is locked and reffed */ 08493 return pvt->owner; 08494 }
| 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 18015 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.
18016 { 18017 switch (cmd) { 18018 case CLI_INIT: 18019 e->command = "sip qualify peer"; 18020 e->usage = 18021 "Usage: sip qualify peer <name> [load]\n" 18022 " Requests a response from one SIP peer and the current status.\n" 18023 " Option \"load\" forces lookup of peer in realtime storage.\n"; 18024 return NULL; 18025 case CLI_GENERATE: 18026 return complete_sip_show_peer(a->line, a->word, a->pos, a->n); 18027 } 18028 return _sip_qualify_peer(0, a->fd, NULL, NULL, a->argc, (const char **) a->argv); 18029 }
| 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 4707 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.
04708 { 04709 int res = -1; 04710 enum ast_t38_state state = T38_STATE_UNAVAILABLE; 04711 struct sip_pvt *p = (struct sip_pvt *) chan->tech_pvt; 04712 char *cp; 04713 04714 sip_pvt_lock(p); 04715 04716 switch (option) { 04717 case AST_OPTION_T38_STATE: 04718 /* Make sure we got an ast_t38_state enum passed in */ 04719 if (*datalen != sizeof(enum ast_t38_state)) { 04720 ast_log(LOG_ERROR, "Invalid datalen for AST_OPTION_T38_STATE option. Expected %d, got %d\n", (int)sizeof(enum ast_t38_state), *datalen); 04721 break; 04722 } 04723 04724 /* 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 */ 04725 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) { 04726 switch (p->t38.state) { 04727 case T38_LOCAL_REINVITE: 04728 case T38_PEER_REINVITE: 04729 state = T38_STATE_NEGOTIATING; 04730 break; 04731 case T38_ENABLED: 04732 state = T38_STATE_NEGOTIATED; 04733 break; 04734 default: 04735 state = T38_STATE_UNKNOWN; 04736 } 04737 } 04738 04739 *((enum ast_t38_state *) data) = state; 04740 res = 0; 04741 04742 break; 04743 case AST_OPTION_DIGIT_DETECT: 04744 cp = (char *) data; 04745 *cp = p->dsp ? 1 : 0; 04746 ast_debug(1, "Reporting digit detection %sabled on %s\n", *cp ? "en" : "dis", chan->name); 04747 break; 04748 case AST_OPTION_SECURE_SIGNALING: 04749 *((unsigned int *) data) = p->req_secure_signaling; 04750 res = 0; 04751 break; 04752 case AST_OPTION_SECURE_MEDIA: 04753 *((unsigned int *) data) = ast_test_flag(&p->flags[1], SIP_PAGE2_USE_SRTP) ? 1 : 0; 04754 res = 0; 04755 break; 04756 case AST_OPTION_DEVICE_NAME: 04757 if (p && p->outgoing_call) { 04758 cp = (char *) data; 04759 ast_copy_string(cp, p->dialstring, *datalen); 04760 res = 0; 04761 } 04762 /* We purposely break with a return of -1 in the 04763 * implied else case here 04764 */ 04765 break; 04766 default: 04767 break; 04768 } 04769 04770 sip_pvt_unlock(p); 04771 04772 return res; 04773 }
| static void sip_queue_hangup_cause | ( | struct sip_pvt * | p, | |
| int | cause | |||
| ) | [static] |
Definition at line 20635 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().
20636 { 20637 struct ast_channel *owner = p->owner; 20638 const char *name = ast_strdupa(owner->name); 20639 20640 /* Cannot hold any channel/private locks when calling. */ 20641 ast_channel_ref(owner); 20642 ast_channel_unlock(owner); 20643 sip_pvt_unlock(p); 20644 ast_set_hangupsource(owner, name, 0); 20645 if (cause) { 20646 ast_queue_hangup_with_cause(owner, cause); 20647 } else { 20648 ast_queue_hangup(owner); 20649 } 20650 ast_channel_unref(owner); 20651 20652 /* Relock things. */ 20653 owner = sip_pvt_lock_full(p); 20654 if (owner) { 20655 ast_channel_unref(owner); 20656 } 20657 }
| static struct ast_frame * sip_read | ( | struct ast_channel * | ast | ) | [static, read] |
Read SIP RTP from channel.
Definition at line 7907 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.
07908 { 07909 struct ast_frame *fr; 07910 struct sip_pvt *p = ast->tech_pvt; 07911 int faxdetected = FALSE; 07912 07913 sip_pvt_lock(p); 07914 fr = sip_rtp_read(ast, p, &faxdetected); 07915 p->lastrtprx = time(NULL); 07916 07917 /* If we detect a CNG tone and fax detection is enabled then send us off to the fax extension */ 07918 if (faxdetected && ast_test_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_CNG)) { 07919 if (strcmp(ast->exten, "fax")) { 07920 const char *target_context = S_OR(ast->macrocontext, ast->context); 07921 /* We need to unlock 'ast' here because 07922 * ast_exists_extension has the potential to start and 07923 * stop an autoservice on the channel. Such action is 07924 * prone to deadlock if the channel is locked. 07925 */ 07926 sip_pvt_unlock(p); 07927 ast_channel_unlock(ast); 07928 if (ast_exists_extension(ast, target_context, "fax", 1, 07929 S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, NULL))) { 07930 ast_channel_lock(ast); 07931 sip_pvt_lock(p); 07932 ast_verbose(VERBOSE_PREFIX_2 "Redirecting '%s' to fax extension due to CNG detection\n", ast->name); 07933 pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten); 07934 if (ast_async_goto(ast, target_context, "fax", 1)) { 07935 ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context); 07936 } 07937 ast_frfree(fr); 07938 fr = &ast_null_frame; 07939 } else { 07940 ast_channel_lock(ast); 07941 sip_pvt_lock(p); 07942 ast_log(LOG_NOTICE, "FAX CNG detected but no fax extension\n"); 07943 } 07944 } 07945 } 07946 07947 /* Only allow audio through if they sent progress with SDP, or if the channel is actually answered */ 07948 if (fr && fr->frametype == AST_FRAME_VOICE && p->invitestate != INV_EARLY_MEDIA && ast->_state != AST_STATE_UP) { 07949 ast_frfree(fr); 07950 fr = &ast_null_frame; 07951 } 07952 07953 sip_pvt_unlock(p); 07954 07955 return fr; 07956 }
| static struct ast_sockaddr * sip_real_dst | ( | const struct sip_pvt * | p | ) | [static, read] |
The real destination address for a write.
Definition at line 3544 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().
03545 { 03546 if (p->outboundproxy) { 03547 return &p->outboundproxy->ip; 03548 } 03549 03550 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; 03551 }
| static const char* sip_reason_code_to_str | ( | enum AST_REDIRECTING_REASON | code | ) | [static] |
Definition at line 2293 of file chan_sip.c.
References ARRAY_LEN, sip_reason_table, and sip_reasons::text.
Referenced by add_diversion_header().
02294 { 02295 if (code >= 0 && code < ARRAY_LEN(sip_reason_table)) { 02296 return sip_reason_table[code].text; 02297 } 02298 02299 return "unknown"; 02300 }
| static enum AST_REDIRECTING_REASON sip_reason_str_to_code | ( | const char * | text | ) | [static] |
Definition at line 2278 of file chan_sip.c.
References ARRAY_LEN, AST_REDIRECTING_REASON_UNKNOWN, sip_reasons::code, and sip_reason_table.
Referenced by get_rdnis().
02279 { 02280 enum AST_REDIRECTING_REASON ast = AST_REDIRECTING_REASON_UNKNOWN; 02281 int i; 02282 02283 for (i = 0; i < ARRAY_LEN(sip_reason_table); ++i) { 02284 if (!strcasecmp(text, sip_reason_table[i].text)) { 02285 ast = sip_reason_table[i].code; 02286 break; 02287 } 02288 } 02289 02290 return ast; 02291 }
| static int sip_refer_allocate | ( | struct sip_pvt * | p | ) | [static] |
Allocate SIP refer structure.
Definition at line 13992 of file chan_sip.c.
References ast_calloc.
Referenced by get_also_info(), handle_request_invite(), handle_request_refer(), and transmit_refer().
13993 { 13994 p->refer = ast_calloc(1, sizeof(struct sip_refer)); 13995 return p->refer ? 1 : 0; 13996 }
| 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 13655 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().
13656 { 13657 13658 /* if we are here, our registration timed out, so we'll just do it over */ 13659 struct sip_registry *r = (struct sip_registry *)data; /* the ref count should have been bumped when the sched item was added */ 13660 struct sip_pvt *p; 13661 13662 /* if we couldn't get a reference to the registry object, punt */ 13663 if (!r) { 13664 return 0; 13665 } 13666 13667 if (r->dnsmgr) { 13668 /* If the registration has timed out, maybe the IP changed. Force a refresh. */ 13669 ast_dnsmgr_refresh(r->dnsmgr); 13670 } 13671 13672 /* If the initial tranmission failed, we may not have an existing dialog, 13673 * so it is possible that r->call == NULL. 13674 * Otherwise destroy it, as we have a timeout so we don't want it. 13675 */ 13676 if (r->call) { 13677 /* Unlink us, destroy old call. Locking is not relevant here because all this happens 13678 in the single SIP manager thread. */ 13679 p = r->call; 13680 sip_pvt_lock(p); 13681 pvt_set_needdestroy(p, "registration timeout"); 13682 /* Pretend to ACK anything just in case */ 13683 __sip_pretend_ack(p); 13684 sip_pvt_unlock(p); 13685 13686 /* decouple the two objects */ 13687 /* p->registry == r, so r has 2 refs, and the unref won't take the object away */ 13688 if (p->registry) { 13689 p->registry = registry_unref(p->registry, "p->registry unreffed"); 13690 } 13691 r->call = dialog_unref(r->call, "unrefing r->call"); 13692 } 13693 /* If we have a limit, stop registration and give up */ 13694 r->timeout = -1; 13695 if (global_regattempts_max && r->regattempts >= global_regattempts_max) { 13696 /* Ok, enough is enough. Don't try any more */ 13697 /* We could add an external notification here... 13698 steal it from app_voicemail :-) */ 13699 ast_log(LOG_NOTICE, " -- Last Registration Attempt #%d failed, Giving up forever trying to register '%s@%s'\n", r->regattempts, r->username, r->hostname); 13700 r->regstate = REG_STATE_FAILED; 13701 } else { 13702 r->regstate = REG_STATE_UNREGISTERED; 13703 transmit_register(r, SIP_REGISTER, NULL, NULL); 13704 ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 13705 } 13706 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)); 13707 registry_unref(r, "unreffing registry_unref r"); 13708 return 0; 13709 }
| 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 8664 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().
08665 { 08666 struct sip_registry *reg; 08667 08668 if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) { 08669 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n"); 08670 return -1; 08671 } 08672 08673 ast_atomic_fetchadd_int(®objs, 1); 08674 ASTOBJ_INIT(reg); 08675 08676 if (sip_parse_register_line(reg, default_expiry, value, lineno)) { 08677 registry_unref(reg, "failure to parse, unref the reg pointer"); 08678 return -1; 08679 } 08680 08681 /* set default expiry if necessary */ 08682 if (reg->refresh && !reg->expiry && !reg->configured_expiry) { 08683 reg->refresh = reg->expiry = reg->configured_expiry = default_expiry; 08684 } 08685 08686 /* Add the new registry entry to the list */ 08687 ASTOBJ_CONTAINER_LINK(®l, reg); 08688 08689 /* release the reference given by ASTOBJ_INIT. The container has another reference */ 08690 registry_unref(reg, "unref the reg pointer"); 08691 08692 return 0; 08693 }
| static void sip_register_tests | ( | void | ) | [static] |
SIP test registration.
Definition at line 30744 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().
30745 { 30746 sip_config_parser_register_tests(); 30747 sip_request_parser_register_tests(); 30748 sip_dialplan_function_register_tests(); 30749 }
| 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 6080 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().
06081 { 06082 /* Really delete */ 06083 ast_debug(3, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname); 06084 06085 if (reg->call) { 06086 /* Clear registry before destroying to ensure 06087 we don't get reentered trying to grab the registry lock */ 06088 reg->call->registry = registry_unref(reg->call->registry, "destroy reg->call->registry"); 06089 ast_debug(3, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname); 06090 dialog_unlink_all(reg->call); 06091 reg->call = dialog_unref(reg->call, "unref reg->call"); 06092 /* reg->call = sip_destroy(reg->call); */ 06093 } 06094 AST_SCHED_DEL(sched, reg->expire); 06095 AST_SCHED_DEL(sched, reg->timeout); 06096 06097 ast_string_field_free_memory(reg); 06098 ast_atomic_fetchadd_int(®objs, -1); 06099 ast_free(reg); 06100 }
| 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 20487 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().
20488 { 20489 struct sip_pvt *p = (struct sip_pvt *) data; 20490 struct ast_channel *owner; 20491 20492 sip_pvt_lock(p); /* called from schedule thread which requires a lock */ 20493 while ((owner = p->owner) && ast_channel_trylock(owner)) { 20494 sip_pvt_unlock(p); 20495 usleep(1); 20496 sip_pvt_lock(p); 20497 } 20498 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 20499 p->waitid = -1; 20500 check_pendings(p); 20501 sip_pvt_unlock(p); 20502 if (owner) { 20503 ast_channel_unlock(owner); 20504 } 20505 dialog_unref(p, "unref the dialog ptr from sip_reinvite_retry, because it held a dialog ptr"); 20506 return 0; 20507 }
| 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 30493 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().
30494 { 30495 static struct sip_peer *tmp_peer, *new_peer; 30496 30497 switch (cmd) { 30498 case CLI_INIT: 30499 e->command = "sip reload"; 30500 e->usage = 30501 "Usage: sip reload\n" 30502 " Reloads SIP configuration from sip.conf\n"; 30503 return NULL; 30504 case CLI_GENERATE: 30505 return NULL; 30506 } 30507 30508 ast_mutex_lock(&sip_reload_lock); 30509 if (sip_reloading) { 30510 ast_verbose("Previous SIP reload not yet done\n"); 30511 } else { 30512 sip_reloading = TRUE; 30513 sip_reloadreason = (a && a->fd) ? CHANNEL_CLI_RELOAD : CHANNEL_MODULE_RELOAD; 30514 } 30515 ast_mutex_unlock(&sip_reload_lock); 30516 restart_monitor(); 30517 30518 tmp_peer = bogus_peer; 30519 /* Create new bogus peer possibly with new global settings. */ 30520 if ((new_peer = temp_peer("(bogus_peer)"))) { 30521 ast_string_field_set(new_peer, md5secret, BOGUS_PEER_MD5SECRET); 30522 ast_clear_flag(&new_peer->flags[0], SIP_INSECURE); 30523 bogus_peer = new_peer; 30524 ao2_t_ref(tmp_peer, -1, "unref the old bogus_peer during reload"); 30525 } else { 30526 ast_log(LOG_ERROR, "Could not update the fake authentication peer.\n"); 30527 /* You probably have bigger (memory?) issues to worry about though.. */ 30528 } 30529 30530 return CLI_SUCCESS; 30531 }
| static int sip_removeheader | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Remove SIP headers added previously with SipAddHeader application.
Definition at line 30239 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().
30240 { 30241 struct ast_var_t *newvariable; 30242 struct varshead *headp; 30243 int removeall = 0; 30244 char *inbuf = (char *) data; 30245 30246 if (ast_strlen_zero(inbuf)) { 30247 removeall = 1; 30248 } 30249 ast_channel_lock(chan); 30250 30251 headp=&chan->varshead; 30252 AST_LIST_TRAVERSE_SAFE_BEGIN (headp, newvariable, entries) { 30253 if (strncasecmp(ast_var_name(newvariable), "SIPADDHEADER", strlen("SIPADDHEADER")) == 0) { 30254 if (removeall || (!strncasecmp(ast_var_value(newvariable),inbuf,strlen(inbuf)))) { 30255 if (sipdebug) 30256 ast_debug(1,"removing SIP Header \"%s\" as %s\n", 30257 ast_var_value(newvariable), 30258 ast_var_name(newvariable)); 30259 AST_LIST_REMOVE_CURRENT(entries); 30260 ast_var_delete(newvariable); 30261 } 30262 } 30263 } 30264 AST_LIST_TRAVERSE_SAFE_END; 30265 30266 ast_channel_unlock(chan); 30267 return 0; 30268 }
| 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 27209 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.
27210 { 27211 struct sip_pvt *p; 27212 struct ast_channel *tmpc = NULL; 27213 char *ext = NULL, *host; 27214 char tmp[256]; 27215 char *dest = data; 27216 char *dnid; 27217 char *secret = NULL; 27218 char *md5secret = NULL; 27219 char *authname = NULL; 27220 char *trans = NULL; 27221 char dialstring[256]; 27222 char *remote_address; 27223 enum sip_transport transport = 0; 27224 format_t oldformat = format; 27225 AST_DECLARE_APP_ARGS(args, 27226 AST_APP_ARG(peerorhost); 27227 AST_APP_ARG(exten); 27228 AST_APP_ARG(remote_address); 27229 ); 27230 27231 /* mask request with some set of allowed formats. 27232 * XXX this needs to be fixed. 27233 * The original code uses AST_FORMAT_AUDIO_MASK, but it is 27234 * unclear what to use here. We have global_capabilities, which is 27235 * configured from sip.conf, and sip_tech.capabilities, which is 27236 * hardwired to all audio formats. 27237 */ 27238 format &= AST_FORMAT_AUDIO_MASK; 27239 if (!format) { 27240 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)); 27241 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; /* Can't find codec to connect to host */ 27242 return NULL; 27243 } 27244 ast_debug(1, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat)); 27245 27246 if (ast_strlen_zero(dest)) { 27247 ast_log(LOG_ERROR, "Unable to create channel with empty destination.\n"); 27248 *cause = AST_CAUSE_CHANNEL_UNACCEPTABLE; 27249 return NULL; 27250 } 27251 27252 if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE, NULL))) { 27253 ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", dest); 27254 *cause = AST_CAUSE_SWITCH_CONGESTION; 27255 return NULL; 27256 } 27257 27258 p->outgoing_call = TRUE; 27259 27260 snprintf(dialstring, sizeof(dialstring), "%s/%s", type, dest); 27261 ast_string_field_set(p, dialstring, dialstring); 27262 27263 if (!(p->options = ast_calloc(1, sizeof(*p->options)))) { 27264 dialog_unlink_all(p); 27265 dialog_unref(p, "unref dialog p from mem fail"); 27266 /* sip_destroy(p); */ 27267 ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n"); 27268 *cause = AST_CAUSE_SWITCH_CONGESTION; 27269 return NULL; 27270 } 27271 27272 /* Save the destination, the SIP dial string */ 27273 ast_copy_string(tmp, dest, sizeof(tmp)); 27274 27275 /* Find DNID and take it away */ 27276 dnid = strchr(tmp, '!'); 27277 if (dnid != NULL) { 27278 *dnid++ = '\0'; 27279 ast_string_field_set(p, todnid, dnid); 27280 } 27281 27282 /* Divvy up the items separated by slashes */ 27283 AST_NONSTANDARD_APP_ARGS(args, tmp, '/'); 27284 27285 /* Find at sign - @ */ 27286 host = strchr(args.peerorhost, '@'); 27287 if (host) { 27288 *host++ = '\0'; 27289 ext = args.peerorhost; 27290 secret = strchr(ext, ':'); 27291 } 27292 if (secret) { 27293 *secret++ = '\0'; 27294 md5secret = strchr(secret, ':'); 27295 } 27296 if (md5secret) { 27297 *md5secret++ = '\0'; 27298 authname = strchr(md5secret, ':'); 27299 } 27300 if (authname) { 27301 *authname++ = '\0'; 27302 trans = strchr(authname, ':'); 27303 } 27304 if (trans) { 27305 *trans++ = '\0'; 27306 if (!strcasecmp(trans, "tcp")) 27307 transport = SIP_TRANSPORT_TCP; 27308 else if (!strcasecmp(trans, "tls")) 27309 transport = SIP_TRANSPORT_TLS; 27310 else { 27311 if (strcasecmp(trans, "udp")) 27312 ast_log(LOG_WARNING, "'%s' is not a valid transport option to Dial() for SIP calls, using udp by default.\n", trans); 27313 transport = SIP_TRANSPORT_UDP; 27314 } 27315 } else { /* use default */ 27316 transport = SIP_TRANSPORT_UDP; 27317 } 27318 27319 if (!host) { 27320 ext = args.exten; 27321 host = args.peerorhost; 27322 remote_address = args.remote_address; 27323 } else { 27324 remote_address = args.remote_address; 27325 if (!ast_strlen_zero(args.exten)) { 27326 ast_log(LOG_NOTICE, "Conflicting extension values given. Using '%s' and not '%s'\n", ext, args.exten); 27327 } 27328 } 27329 27330 if (!ast_strlen_zero(remote_address)) { 27331 p->options->outboundproxy = proxy_from_config(remote_address, 0, NULL); 27332 if (!p->options->outboundproxy) { 27333 ast_log(LOG_WARNING, "Unable to parse outboundproxy %s. We will not use this remote IP address\n", remote_address); 27334 } 27335 } 27336 27337 set_socket_transport(&p->socket, transport); 27338 27339 /* We now have 27340 host = peer name, DNS host name or DNS domain (for SRV) 27341 ext = extension (user part of URI) 27342 dnid = destination of the call (applies to the To: header) 27343 */ 27344 if (create_addr(p, host, NULL, 1)) { 27345 *cause = AST_CAUSE_UNREGISTERED; 27346 ast_debug(3, "Cant create SIP call - target device not registered\n"); 27347 dialog_unlink_all(p); 27348 dialog_unref(p, "unref dialog p UNREGISTERED"); 27349 /* sip_destroy(p); */ 27350 return NULL; 27351 } 27352 if (ast_strlen_zero(p->peername) && ext) 27353 ast_string_field_set(p, peername, ext); 27354 /* Recalculate our side, and recalculate Call ID */ 27355 ast_sip_ouraddrfor(&p->sa, &p->ourip, p); 27356 build_via(p); 27357 27358 /* Change the dialog callid. */ 27359 change_callid_pvt(p, NULL); 27360 27361 /* We have an extension to call, don't use the full contact here */ 27362 /* This to enable dialing registered peers with extension dialling, 27363 like SIP/peername/extension 27364 SIP/peername will still use the full contact 27365 */ 27366 if (ext) { 27367 ast_string_field_set(p, username, ext); 27368 ast_string_field_set(p, fullcontact, NULL); 27369 } 27370 if (secret && !ast_strlen_zero(secret)) 27371 ast_string_field_set(p, peersecret, secret); 27372 27373 if (md5secret && !ast_strlen_zero(md5secret)) 27374 ast_string_field_set(p, peermd5secret, md5secret); 27375 27376 if (authname && !ast_strlen_zero(authname)) 27377 ast_string_field_set(p, authname, authname); 27378 #if 0 27379 printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host); 27380 #endif 27381 p->prefcodec = oldformat; /* Format for this call */ 27382 p->jointcapability = oldformat & p->capability; 27383 sip_pvt_lock(p); 27384 tmpc = sip_new(p, AST_STATE_DOWN, host, requestor ? requestor->linkedid : NULL); /* Place the call */ 27385 if (sip_cfg.callevents) 27386 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", 27387 "Channel: %s\r\nChanneltype: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\nPeername: %s\r\n", 27388 p->owner? p->owner->name : "", "SIP", p->callid, p->fullcontact, p->peername); 27389 sip_pvt_unlock(p); 27390 if (!tmpc) { 27391 dialog_unlink_all(p); 27392 /* sip_destroy(p); */ 27393 } else { 27394 ast_channel_unlock(tmpc); 27395 } 27396 dialog_unref(p, "toss pvt ptr at end of sip_request_call"); 27397 ast_update_use_count(); 27398 restart_monitor(); 27399 return tmpc; 27400 }
| 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 13612 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().
13613 { 13614 /* if we are here, we know that we need to reregister. */ 13615 struct sip_registry *r = (struct sip_registry *) data; 13616 13617 /* if we couldn't get a reference to the registry object, punt */ 13618 if (!r) { 13619 return 0; 13620 } 13621 13622 if (r->call && r->call->do_history) { 13623 append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname); 13624 } 13625 /* Since registry's are only added/removed by the the monitor thread, this 13626 may be overkill to reference/dereference at all here */ 13627 if (sipdebug) { 13628 ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname); 13629 } 13630 13631 r->expire = -1; 13632 r->expiry = r->configured_expiry; 13633 __sip_do_register(r); 13634 registry_unref(r, "unref the re-register scheduled event"); 13635 return 0; 13636 }
| 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 7816 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().
07817 { 07818 /* Retrieve audio/etc from channel. Assumes p->lock is already held. */ 07819 struct ast_frame *f; 07820 07821 if (!p->rtp) { 07822 /* We have no RTP allocated for this channel */ 07823 return &ast_null_frame; 07824 } 07825 07826 switch(ast->fdno) { 07827 case 0: 07828 f = ast_rtp_instance_read(p->rtp, 0); /* RTP Audio */ 07829 break; 07830 case 1: 07831 f = ast_rtp_instance_read(p->rtp, 1); /* RTCP Control Channel */ 07832 break; 07833 case 2: 07834 f = ast_rtp_instance_read(p->vrtp, 0); /* RTP Video */ 07835 break; 07836 case 3: 07837 f = ast_rtp_instance_read(p->vrtp, 1); /* RTCP Control Channel for video */ 07838 break; 07839 case 4: 07840 f = ast_rtp_instance_read(p->trtp, 0); /* RTP Text */ 07841 if (sipdebug_text) { 07842 int i; 07843 unsigned char* arr = f->data.ptr; 07844 for (i=0; i < f->datalen; i++) 07845 ast_verbose("%c", (arr[i] > ' ' && arr[i] < '}') ? arr[i] : '.'); 07846 ast_verbose(" -> "); 07847 for (i=0; i < f->datalen; i++) 07848 ast_verbose("%02X ", arr[i]); 07849 ast_verbose("\n"); 07850 } 07851 break; 07852 case 5: 07853 f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */ 07854 break; 07855 default: 07856 f = &ast_null_frame; 07857 } 07858 /* Don't forward RFC2833 if we're not supposed to */ 07859 if (f && (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END) && 07860 (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833)) { 07861 ast_debug(1, "Ignoring DTMF (%c) RTP frame because dtmfmode is not RFC2833\n", f->subclass.integer); 07862 ast_frfree(f); 07863 return &ast_null_frame; 07864 } 07865 07866 /* We already hold the channel lock */ 07867 if (!p->owner || (f && f->frametype != AST_FRAME_VOICE)) 07868 return f; 07869 07870 if (f && f->subclass.codec != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) { 07871 if (!(f->subclass.codec & p->jointcapability)) { 07872 ast_debug(1, "Bogus frame of format '%s' received from '%s'!\n", 07873 ast_getformatname(f->subclass.codec), p->owner->name); 07874 ast_frfree(f); 07875 return &ast_null_frame; 07876 } 07877 ast_debug(1, "Oooh, format changed to %s\n", 07878 ast_getformatname(f->subclass.codec)); 07879 p->owner->nativeformats = (p->owner->nativeformats & (AST_FORMAT_VIDEO_MASK | AST_FORMAT_TEXT_MASK)) | f->subclass.codec; 07880 ast_set_read_format(p->owner, p->owner->readformat); 07881 ast_set_write_format(p->owner, p->owner->writeformat); 07882 } 07883 07884 if (f && p->dsp) { 07885 f = ast_dsp_process(p->owner, p->dsp, f); 07886 if (f && f->frametype == AST_FRAME_DTMF) { 07887 if (f->subclass.integer == 'f') { 07888 ast_debug(1, "Fax CNG detected on %s\n", ast->name); 07889 *faxdetect = 1; 07890 /* If we only needed this DSP for fax detection purposes we can just drop it now */ 07891 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 07892 ast_dsp_set_features(p->dsp, DSP_FEATURE_DIGIT_DETECT); 07893 } else { 07894 ast_dsp_free(p->dsp); 07895 p->dsp = NULL; 07896 } 07897 } else { 07898 ast_debug(1, "* Detected inband DTMF '%c'\n", f->subclass.integer); 07899 } 07900 } 07901 } 07902 07903 return f; 07904 }
| static const char* sip_sanitized_host | ( | const char * | host | ) | [static] |
Definition at line 13711 of file chan_sip.c.
References ast_sockaddr_parse(), ast_sockaddr_stringify_host_remote(), and PARSE_PORT_FORBID.
Referenced by transmit_register().
13712 { 13713 struct ast_sockaddr addr = { { 0, 0, }, }; 13714 13715 /* peer/sip_pvt->tohost and sip_registry->hostname should never have a port 13716 * in them, so we use PARSE_PORT_FORBID here. If this lookup fails, we return 13717 * the original host which is most likely a host name and not an IP. */ 13718 if (!ast_sockaddr_parse(&addr, host, PARSE_PORT_FORBID)) { 13719 return host; 13720 } 13721 return ast_sockaddr_stringify_host_remote(&addr); 13722 }
| void sip_scheddestroy | ( | struct sip_pvt * | p, | |
| int | ms | |||
| ) |
Schedule destruction of SIP dialog.
Definition at line 4257 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(), handle_response_register(), 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().
04258 { 04259 if (p->final_destruction_scheduled) { 04260 return; /* already set final destruction */ 04261 } 04262 04263 if (ms < 0) { 04264 if (p->timer_t1 == 0) { 04265 p->timer_t1 = global_t1; /* Set timer T1 if not set (RFC 3261) */ 04266 } 04267 if (p->timer_b == 0) { 04268 p->timer_b = global_timer_b; /* Set timer B if not set (RFC 3261) */ 04269 } 04270 ms = p->timer_t1 * 64; 04271 } 04272 if (sip_debug_test_pvt(p)) { 04273 ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text); 04274 } 04275 if (sip_cancel_destroy(p)) { 04276 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 04277 } 04278 04279 if (p->do_history) { 04280 append_history(p, "SchedDestroy", "%d ms", ms); 04281 } 04282 p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, dialog_ref(p, "setting ref as passing into ast_sched_add for __sip_autodestruct")); 04283 04284 if (p->stimer && p->stimer->st_active == TRUE && p->stimer->st_schedid > 0) { 04285 stop_session_timer(p); 04286 } 04287 }
| 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 4244 of file chan_sip.c.
References sip_scheddestroy().
Referenced by handle_request_bye().
04245 { 04246 if (p->final_destruction_scheduled) { 04247 return; /* already set final destruction */ 04248 } 04249 04250 sip_scheddestroy(p, ms); 04251 if (p->autokillid != -1) { 04252 p->final_destruction_scheduled = 1; 04253 } 04254 }
| static void sip_send_all_mwi_subscriptions | ( | void | ) | [static] |
Send all MWI subscriptions.
Definition at line 30397 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().
30398 { 30399 ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do { 30400 struct sip_subscription_mwi *saved; 30401 ASTOBJ_WRLOCK(iterator); 30402 AST_SCHED_DEL(sched, iterator->resub); 30403 saved = ASTOBJ_REF(iterator); 30404 if ((iterator->resub = ast_sched_add(sched, 1, sip_subscribe_mwi_do, saved)) < 0) { 30405 ASTOBJ_UNREF(saved, sip_subscribe_mwi_destroy); 30406 } 30407 ASTOBJ_UNLOCK(iterator); 30408 } while (0)); 30409 }
| static void sip_send_all_registers | ( | void | ) | [static] |
Send all known registrations.
Definition at line 30373 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().
30374 { 30375 int ms; 30376 int regspacing; 30377 if (!regobjs) 30378 return; 30379 regspacing = default_expiry * 1000/regobjs; 30380 if (regspacing > 100) { 30381 regspacing = 100; 30382 } 30383 ms = regspacing; 30384 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 30385 ASTOBJ_WRLOCK(iterator); 30386 ms += regspacing; 30387 AST_SCHED_REPLACE_UNREF(iterator->expire, sched, ms, sip_reregister, iterator, 30388 registry_unref(_data, "REPLACE sched del decs the refcount"), 30389 registry_unref(iterator, "REPLACE sched add failure decs the refcount"), 30390 registry_addref(iterator, "REPLACE sched add incs the refcount")); 30391 ASTOBJ_UNLOCK(iterator); 30392 } while (0) 30393 ); 30394 }
| 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 26363 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().
26364 { 26365 /* Called with peer lock, but releases it */ 26366 struct sip_pvt *p; 26367 int newmsgs = 0, oldmsgs = 0; 26368 const char *vmexten = NULL; 26369 26370 ao2_lock(peer); 26371 26372 if (peer->vmexten) { 26373 vmexten = ast_strdupa(peer->vmexten); 26374 } 26375 26376 if (ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY) && !peer->mwipvt) { 26377 update_peer_lastmsgssent(peer, -1, 1); 26378 ao2_unlock(peer); 26379 return 0; 26380 } 26381 26382 /* Do we have an IP address? If not, skip this peer */ 26383 if (ast_sockaddr_isnull(&peer->addr) && ast_sockaddr_isnull(&peer->defaddr)) { 26384 update_peer_lastmsgssent(peer, -1, 1); 26385 ao2_unlock(peer); 26386 return 0; 26387 } 26388 26389 /* Attempt to use cached mwi to get message counts. */ 26390 if (!get_cached_mwi(peer, &newmsgs, &oldmsgs) && !cache_only) { 26391 /* Fall back to manually checking the mailbox if not cache_only and get_cached_mwi failed */ 26392 struct ast_str *mailbox_str = ast_str_alloca(512); 26393 peer_mailboxes_to_str(&mailbox_str, peer); 26394 ao2_unlock(peer); 26395 /* If there is no mailbox do nothing */ 26396 if (!ast_str_strlen(mailbox_str)) { 26397 update_peer_lastmsgssent(peer, -1, 0); 26398 return 0; 26399 } 26400 ast_app_inboxcount(ast_str_buffer(mailbox_str), &newmsgs, &oldmsgs); 26401 ao2_lock(peer); 26402 } 26403 26404 if (peer->mwipvt) { 26405 /* Base message on subscription */ 26406 p = dialog_ref(peer->mwipvt, "sip_send_mwi_to_peer: Setting dialog ptr p from peer->mwipvt"); 26407 ao2_unlock(peer); 26408 } else { 26409 ao2_unlock(peer); 26410 /* Build temporary dialog for this message */ 26411 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) { 26412 update_peer_lastmsgssent(peer, -1, 0); 26413 return -1; 26414 } 26415 26416 /* If we don't set the socket type to 0, then create_addr_from_peer will fail immediately if the peer 26417 * uses any transport other than UDP. We set the type to 0 here and then let create_addr_from_peer copy 26418 * the peer's socket information to the sip_pvt we just allocated 26419 */ 26420 set_socket_transport(&p->socket, 0); 26421 if (create_addr_from_peer(p, peer)) { 26422 /* Maybe they're not registered, etc. */ 26423 dialog_unlink_all(p); 26424 dialog_unref(p, "unref dialog p just created via sip_alloc"); 26425 update_peer_lastmsgssent(peer, -1, 0); 26426 return 0; 26427 } 26428 /* Recalculate our side, and recalculate Call ID */ 26429 ast_sip_ouraddrfor(&p->sa, &p->ourip, p); 26430 build_via(p); 26431 26432 ao2_lock(peer); 26433 if (!ast_strlen_zero(peer->mwi_from)) { 26434 ast_string_field_set(p, mwi_from, peer->mwi_from); 26435 } else if (!ast_strlen_zero(default_mwi_from)) { 26436 ast_string_field_set(p, mwi_from, default_mwi_from); 26437 } 26438 ao2_unlock(peer); 26439 26440 /* Change the dialog callid. */ 26441 change_callid_pvt(p, NULL); 26442 26443 /* Destroy this session after 32 secs */ 26444 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 26445 } 26446 26447 /* 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, 26448 we really need to have a lock on it */ 26449 sip_pvt_lock(p); 26450 26451 /* Send MWI */ 26452 ast_set_flag(&p->flags[0], SIP_OUTGOING); 26453 /* the following will decrement the refcount on p as it finishes */ 26454 transmit_notify_with_mwi(p, newmsgs, oldmsgs, vmexten); 26455 sip_pvt_unlock(p); 26456 dialog_unref(p, "unref dialog ptr p just before it goes out of scope at the end of sip_send_mwi_to_peer."); 26457 26458 update_peer_lastmsgssent(peer, ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)), 0); 26459 26460 return 0; 26461 }
| static int sip_senddigit_begin | ( | struct ast_channel * | ast, | |
| char | digit | |||
| ) | [static] |
Definition at line 7044 of file chan_sip.c.
References ast_rtp_instance_dtmf_begin(), ast_test_flag, sip_pvt_lock, sip_pvt_unlock, and ast_channel::tech_pvt.
07045 { 07046 struct sip_pvt *p = ast->tech_pvt; 07047 int res = 0; 07048 07049 sip_pvt_lock(p); 07050 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 07051 case SIP_DTMF_INBAND: 07052 res = -1; /* Tell Asterisk to generate inband indications */ 07053 break; 07054 case SIP_DTMF_RFC2833: 07055 if (p->rtp) 07056 ast_rtp_instance_dtmf_begin(p->rtp, digit); 07057 break; 07058 default: 07059 break; 07060 } 07061 sip_pvt_unlock(p); 07062 07063 return res; 07064 }
| 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 7068 of file chan_sip.c.
References 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().
07069 { 07070 struct sip_pvt *p = ast->tech_pvt; 07071 int res = 0; 07072 07073 sip_pvt_lock(p); 07074 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 07075 case SIP_DTMF_INFO: 07076 case SIP_DTMF_SHORTINFO: 07077 transmit_info_with_digit(p, digit, duration); 07078 break; 07079 case SIP_DTMF_RFC2833: 07080 if (p->rtp) 07081 ast_rtp_instance_dtmf_end_with_duration(p->rtp, digit, duration); 07082 break; 07083 case SIP_DTMF_INBAND: 07084 res = -1; /* Tell Asterisk to stop inband indications */ 07085 break; 07086 } 07087 sip_pvt_unlock(p); 07088 07089 return res; 07090 }
| 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 4791 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.
04792 { 04793 struct sip_pvt *p = chan->tech_pvt; 04794 04795 if (subclass != AST_HTML_URL) 04796 return -1; 04797 04798 ast_string_field_build(p, url, "<%s>;mode=active", data); 04799 04800 if (sip_debug_test_pvt(p)) 04801 ast_debug(1, "Send URL %s, state = %d!\n", data, chan->_state); 04802 04803 switch (chan->_state) { 04804 case AST_STATE_RING: 04805 transmit_response(p, "100 Trying", &p->initreq); 04806 break; 04807 case AST_STATE_RINGING: 04808 transmit_response(p, "180 Ringing", &p->initreq); 04809 break; 04810 case AST_STATE_UP: 04811 if (!p->pendinginvite) { /* We are up, and have no outstanding invite */ 04812 transmit_reinvite_with_sdp(p, FALSE, FALSE); 04813 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 04814 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 04815 } 04816 break; 04817 default: 04818 ast_log(LOG_WARNING, "Don't know how to send URI when state is %d!\n", chan->_state); 04819 } 04820 04821 return 0; 04822 }
| static int sip_sendtext | ( | struct ast_channel * | ast, | |
| const char * | text | |||
| ) | [static] |
Definition at line 4835 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().
04836 { 04837 struct sip_pvt *dialog = ast->tech_pvt; 04838 int debug; 04839 04840 if (!dialog) { 04841 return -1; 04842 } 04843 /* NOT ast_strlen_zero, because a zero-length message is specifically 04844 * allowed by RFC 3428 (See section 10, Examples) */ 04845 if (!text) { 04846 return 0; 04847 } 04848 if(!is_method_allowed(&dialog->allowed_methods, SIP_MESSAGE)) { 04849 ast_debug(2, "Trying to send MESSAGE to device that does not support it.\n"); 04850 return(0); 04851 } 04852 04853 debug = sip_debug_test_pvt(dialog); 04854 if (debug) { 04855 ast_verbose("Sending text %s on %s\n", text, ast->name); 04856 } 04857 04858 transmit_message_with_text(dialog, text); 04859 return 0; 04860 }
| 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 19747 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.
19748 { 19749 switch (cmd) { 19750 case CLI_INIT: 19751 e->command = "sip set history {on|off}"; 19752 e->usage = 19753 "Usage: sip set history {on|off}\n" 19754 " Enables/Disables recording of SIP dialog history for debugging purposes.\n" 19755 " Use 'sip show history' to view the history of a call number.\n"; 19756 return NULL; 19757 case CLI_GENERATE: 19758 return NULL; 19759 } 19760 19761 if (a->argc != e->args) 19762 return CLI_SHOWUSAGE; 19763 19764 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) { 19765 recordhistory = TRUE; 19766 ast_cli(a->fd, "SIP History Recording Enabled (use 'sip show history')\n"); 19767 } else if (!strncasecmp(a->argv[e->args - 1], "off", 3)) { 19768 recordhistory = FALSE; 19769 ast_cli(a->fd, "SIP History Recording Disabled\n"); 19770 } else { 19771 return CLI_SHOWUSAGE; 19772 } 19773 return CLI_SUCCESS; 19774 }
| static void sip_set_redirstr | ( | struct sip_pvt * | p, | |
| char * | reason | |||
| ) | [static] |
Translate referring cause.
Definition at line 15599 of file chan_sip.c.
References ast_string_field_set.
Referenced by get_rdnis().
15599 { 15600 15601 if (!strcmp(reason, "unknown")) { 15602 ast_string_field_set(p, redircause, "UNKNOWN"); 15603 } else if (!strcmp(reason, "user-busy")) { 15604 ast_string_field_set(p, redircause, "BUSY"); 15605 } else if (!strcmp(reason, "no-answer")) { 15606 ast_string_field_set(p, redircause, "NOANSWER"); 15607 } else if (!strcmp(reason, "unavailable")) { 15608 ast_string_field_set(p, redircause, "UNREACHABLE"); 15609 } else if (!strcmp(reason, "unconditional")) { 15610 ast_string_field_set(p, redircause, "UNCONDITIONAL"); 15611 } else if (!strcmp(reason, "time-of-day")) { 15612 ast_string_field_set(p, redircause, "UNKNOWN"); 15613 } else if (!strcmp(reason, "do-not-disturb")) { 15614 ast_string_field_set(p, redircause, "UNKNOWN"); 15615 } else if (!strcmp(reason, "deflection")) { 15616 ast_string_field_set(p, redircause, "UNKNOWN"); 15617 } else if (!strcmp(reason, "follow-me")) { 15618 ast_string_field_set(p, redircause, "UNKNOWN"); 15619 } else if (!strcmp(reason, "out-of-service")) { 15620 ast_string_field_set(p, redircause, "UNREACHABLE"); 15621 } else if (!strcmp(reason, "away")) { 15622 ast_string_field_set(p, redircause, "UNREACHABLE"); 15623 } else { 15624 ast_string_field_set(p, redircause, "UNKNOWN"); 15625 } 15626 }
| 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 29992 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().
29993 { 29994 struct sip_pvt *p; 29995 int changed = 0; 29996 29997 /* Lock the channel and the private safely. */ 29998 ast_channel_lock(chan); 29999 p = chan->tech_pvt; 30000 if (!p) { 30001 ast_channel_unlock(chan); 30002 return -1; 30003 } 30004 sip_pvt_lock(p); 30005 if (p->owner != chan) { 30006 /* I suppose it could be argued that if this happens it is a bug. */ 30007 ast_debug(1, "The private is not owned by channel %s anymore.\n", chan->name); 30008 sip_pvt_unlock(p); 30009 ast_channel_unlock(chan); 30010 return 0; 30011 } 30012 30013 /* Disable early RTP bridge */ 30014 if ((instance || vinstance || tinstance) && 30015 !ast_bridged_channel(chan) && 30016 !sip_cfg.directrtpsetup) { 30017 sip_pvt_unlock(p); 30018 ast_channel_unlock(chan); 30019 return 0; 30020 } 30021 30022 if (p->alreadygone) { 30023 /* If we're destroyed, don't bother */ 30024 sip_pvt_unlock(p); 30025 ast_channel_unlock(chan); 30026 return 0; 30027 } 30028 30029 /* if this peer cannot handle reinvites of the media stream to devices 30030 that are known to be behind a NAT, then stop the process now 30031 */ 30032 if (nat_active && !ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA_NAT)) { 30033 sip_pvt_unlock(p); 30034 ast_channel_unlock(chan); 30035 return 0; 30036 } 30037 30038 if (instance) { 30039 changed |= ast_rtp_instance_get_and_cmp_remote_address(instance, &p->redirip); 30040 30041 if (p->rtp) { 30042 /* Prevent audio RTCP reads */ 30043 ast_channel_set_fd(chan, 1, -1); 30044 /* Silence RTCP while audio RTP is inactive */ 30045 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_RTCP, 0); 30046 } 30047 } else if (!ast_sockaddr_isnull(&p->redirip)) { 30048 memset(&p->redirip, 0, sizeof(p->redirip)); 30049 changed = 1; 30050 30051 if (p->rtp) { 30052 /* Enable RTCP since it will be inactive if we're coming back 30053 * from a reinvite */ 30054 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_RTCP, 1); 30055 /* Enable audio RTCP reads */ 30056 ast_channel_set_fd(chan, 1, ast_rtp_instance_fd(p->rtp, 1)); 30057 } 30058 } 30059 30060 if (vinstance) { 30061 changed |= ast_rtp_instance_get_and_cmp_remote_address(vinstance, &p->vredirip); 30062 30063 if (p->vrtp) { 30064 /* Prevent video RTCP reads */ 30065 ast_channel_set_fd(chan, 3, -1); 30066 /* Silence RTCP while video RTP is inactive */ 30067 ast_rtp_instance_set_prop(p->vrtp, AST_RTP_PROPERTY_RTCP, 0); 30068 } 30069 } else if (!ast_sockaddr_isnull(&p->vredirip)) { 30070 memset(&p->vredirip, 0, sizeof(p->vredirip)); 30071 changed = 1; 30072 30073 if (p->vrtp) { 30074 /* Enable RTCP since it will be inactive if we're coming back 30075 * from a reinvite */ 30076 ast_rtp_instance_set_prop(p->vrtp, AST_RTP_PROPERTY_RTCP, 1); 30077 /* Enable video RTCP reads */ 30078 ast_channel_set_fd(chan, 3, ast_rtp_instance_fd(p->vrtp, 1)); 30079 } 30080 } 30081 30082 if (tinstance) { 30083 changed |= ast_rtp_instance_get_and_cmp_remote_address(tinstance, &p->tredirip); 30084 } else if (!ast_sockaddr_isnull(&p->tredirip)) { 30085 memset(&p->tredirip, 0, sizeof(p->tredirip)); 30086 changed = 1; 30087 } 30088 if (codecs && (p->redircodecs != codecs)) { 30089 p->redircodecs = codecs; 30090 changed = 1; 30091 } 30092 30093 if (ast_test_flag(&p->flags[2], SIP_PAGE3_DIRECT_MEDIA_OUTGOING) && !p->outgoing_call) { 30094 /* We only wish to withhold sending the initial direct media reinvite on the incoming dialog. 30095 * Further direct media reinvites beyond the initial should be sent. In order to allow further 30096 * direct media reinvites to be sent, we clear this flag. 30097 */ 30098 ast_clear_flag(&p->flags[2], SIP_PAGE3_DIRECT_MEDIA_OUTGOING); 30099 sip_pvt_unlock(p); 30100 ast_channel_unlock(chan); 30101 return 0; 30102 } 30103 30104 if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 30105 if (chan->_state != AST_STATE_UP) { /* We are in early state */ 30106 if (p->do_history) 30107 append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal."); 30108 ast_debug(1, "Early remote bridge setting SIP '%s' - Sending media to %s\n", p->callid, ast_sockaddr_stringify(instance ? &p->redirip : &p->ourip)); 30109 } else if (!p->pendinginvite) { /* We are up, and have no outstanding invite */ 30110 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)); 30111 transmit_reinvite_with_sdp(p, FALSE, FALSE); 30112 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 30113 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)); 30114 /* We have a pending Invite. Send re-invite when we're done with the invite */ 30115 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 30116 } 30117 } 30118 /* Reset lastrtprx timer */ 30119 p->lastrtprx = p->lastrtptx = time(NULL); 30120 sip_pvt_unlock(p); 30121 ast_channel_unlock(chan); 30122 return 0; 30123 }
| static int sip_set_udptl_peer | ( | struct ast_channel * | chan, | |
| struct ast_udptl * | udptl | |||
| ) | [static] |
Definition at line 29793 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.
29794 { 29795 struct sip_pvt *p; 29796 29797 /* Lock the channel and the private safely. */ 29798 ast_channel_lock(chan); 29799 p = chan->tech_pvt; 29800 if (!p) { 29801 ast_channel_unlock(chan); 29802 return -1; 29803 } 29804 sip_pvt_lock(p); 29805 if (p->owner != chan) { 29806 /* I suppose it could be argued that if this happens it is a bug. */ 29807 ast_debug(1, "The private is not owned by channel %s anymore.\n", chan->name); 29808 sip_pvt_unlock(p); 29809 ast_channel_unlock(chan); 29810 return 0; 29811 } 29812 29813 if (udptl) { 29814 ast_udptl_get_peer(udptl, &p->udptlredirip); 29815 } else { 29816 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 29817 } 29818 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 29819 if (!p->pendinginvite) { 29820 ast_debug(3, "Sending reinvite on SIP '%s' - It's UDPTL soon redirected to IP %s\n", 29821 p->callid, ast_sockaddr_stringify(udptl ? &p->udptlredirip : &p->ourip)); 29822 transmit_reinvite_with_sdp(p, TRUE, FALSE); 29823 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 29824 ast_debug(3, "Deferring reinvite on SIP '%s' - It's UDPTL will be redirected to IP %s\n", 29825 p->callid, ast_sockaddr_stringify(udptl ? &p->udptlredirip : &p->ourip)); 29826 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 29827 } 29828 } 29829 /* Reset lastrtprx timer */ 29830 p->lastrtprx = p->lastrtptx = time(NULL); 29831 sip_pvt_unlock(p); 29832 ast_channel_unlock(chan); 29833 return 0; 29834 }
| 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 4647 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.
04648 { 04649 int res = -1; 04650 struct sip_pvt *p = chan->tech_pvt; 04651 04652 if (!p) { 04653 ast_log(LOG_ERROR, "Attempt to Ref a null pointer. sip private structure is gone!\n"); 04654 return -1; 04655 } 04656 04657 sip_pvt_lock(p); 04658 04659 switch (option) { 04660 case AST_OPTION_FORMAT_READ: 04661 if (p->rtp) { 04662 res = ast_rtp_instance_set_read_format(p->rtp, *(int *) data); 04663 } 04664 break; 04665 case AST_OPTION_FORMAT_WRITE: 04666 if (p->rtp) { 04667 res = ast_rtp_instance_set_write_format(p->rtp, *(int *) data); 04668 } 04669 break; 04670 case AST_OPTION_MAKE_COMPATIBLE: 04671 if (p->rtp) { 04672 res = ast_rtp_instance_make_compatible(chan, p->rtp, (struct ast_channel *) data); 04673 } 04674 break; 04675 case AST_OPTION_DIGIT_DETECT: 04676 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || 04677 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) { 04678 char *cp = (char *) data; 04679 04680 ast_debug(1, "%sabling digit detection on %s\n", *cp ? "En" : "Dis", chan->name); 04681 if (*cp) { 04682 enable_dsp_detect(p); 04683 } else { 04684 disable_dsp_detect(p); 04685 } 04686 res = 0; 04687 } 04688 break; 04689 case AST_OPTION_SECURE_SIGNALING: 04690 p->req_secure_signaling = *(unsigned int *) data; 04691 res = 0; 04692 break; 04693 case AST_OPTION_SECURE_MEDIA: 04694 ast_set2_flag(&p->flags[1], *(unsigned int *) data, SIP_PAGE2_USE_SRTP); 04695 res = 0; 04696 break; 04697 default: 04698 break; 04699 } 04700 04701 sip_pvt_unlock(p); 04702 04703 return res; 04704 }
| 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 19209 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(), TRUE, ast_cli_entry::usage, and ast_cli_args::word.
19210 { 19211 struct sip_pvt *cur; 19212 size_t len; 19213 int found = 0; 19214 struct ao2_iterator i; 19215 19216 switch (cmd) { 19217 case CLI_INIT: 19218 e->command = "sip show channel"; 19219 e->usage = 19220 "Usage: sip show channel <call-id>\n" 19221 " Provides detailed status on a given SIP dialog (identified by SIP call-id).\n"; 19222 return NULL; 19223 case CLI_GENERATE: 19224 return complete_sipch(a->line, a->word, a->pos, a->n); 19225 } 19226 19227 if (a->argc != 4) 19228 return CLI_SHOWUSAGE; 19229 len = strlen(a->argv[3]); 19230 19231 i = ao2_iterator_init(dialogs, 0); 19232 while ((cur = ao2_t_iterator_next(&i, "iterate thru dialogs"))) { 19233 sip_pvt_lock(cur); 19234 19235 if (!strncasecmp(cur->callid, a->argv[3], len)) { 19236 char formatbuf[SIPBUFSIZE/2]; 19237 ast_cli(a->fd, "\n"); 19238 if (cur->subscribed != NONE) 19239 ast_cli(a->fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); 19240 else 19241 ast_cli(a->fd, " * SIP Call\n"); 19242 ast_cli(a->fd, " Curr. trans. direction: %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming"); 19243 ast_cli(a->fd, " Call-ID: %s\n", cur->callid); 19244 ast_cli(a->fd, " Owner channel ID: %s\n", cur->owner ? cur->owner->name : "<none>"); 19245 ast_cli(a->fd, " Our Codec Capability: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->capability)); 19246 ast_cli(a->fd, " Non-Codec Capability (DTMF): %d\n", cur->noncodeccapability); 19247 ast_cli(a->fd, " Their Codec Capability: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->peercapability)); 19248 ast_cli(a->fd, " Joint Codec Capability: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->jointcapability)); 19249 ast_cli(a->fd, " Format: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) ); 19250 ast_cli(a->fd, " T.38 support %s\n", AST_CLI_YESNO(cur->udptl != NULL)); 19251 ast_cli(a->fd, " Video support %s\n", AST_CLI_YESNO(cur->vrtp != NULL)); 19252 ast_cli(a->fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate); 19253 ast_cli(a->fd, " Theoretical Address: %s\n", ast_sockaddr_stringify(&cur->sa)); 19254 ast_cli(a->fd, " Received Address: %s\n", ast_sockaddr_stringify(&cur->recv)); 19255 ast_cli(a->fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer)); 19256 ast_cli(a->fd, " Force rport: %s\n", AST_CLI_YESNO(ast_test_flag(&cur->flags[0], SIP_NAT_FORCE_RPORT))); 19257 if (ast_sockaddr_isnull(&cur->redirip)) { 19258 ast_cli(a->fd, 19259 " Audio IP: %s (local)\n", 19260 ast_sockaddr_stringify_addr(&cur->ourip)); 19261 } else { 19262 ast_cli(a->fd, 19263 " Audio IP: %s (Outside bridge)\n", 19264 ast_sockaddr_stringify_addr(&cur->redirip)); 19265 } 19266 ast_cli(a->fd, " Our Tag: %s\n", cur->tag); 19267 ast_cli(a->fd, " Their Tag: %s\n", cur->theirtag); 19268 ast_cli(a->fd, " SIP User agent: %s\n", cur->useragent); 19269 if (!ast_strlen_zero(cur->username)) 19270 ast_cli(a->fd, " Username: %s\n", cur->username); 19271 if (!ast_strlen_zero(cur->peername)) 19272 ast_cli(a->fd, " Peername: %s\n", cur->peername); 19273 if (!ast_strlen_zero(cur->uri)) 19274 ast_cli(a->fd, " Original uri: %s\n", cur->uri); 19275 if (!ast_strlen_zero(cur->cid_num)) 19276 ast_cli(a->fd, " Caller-ID: %s\n", cur->cid_num); 19277 ast_cli(a->fd, " Need Destroy: %s\n", AST_CLI_YESNO(cur->needdestroy)); 19278 ast_cli(a->fd, " Last Message: %s\n", cur->lastmsg); 19279 ast_cli(a->fd, " Promiscuous Redir: %s\n", AST_CLI_YESNO(ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR))); 19280 ast_cli(a->fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); 19281 ast_cli(a->fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF))); 19282 ast_cli(a->fd, " SIP Options: "); 19283 if (cur->sipoptions) { 19284 int x; 19285 for (x = 0 ; x < ARRAY_LEN(sip_options); x++) { 19286 if (cur->sipoptions & sip_options[x].id) 19287 ast_cli(a->fd, "%s ", sip_options[x].text); 19288 } 19289 ast_cli(a->fd, "\n"); 19290 } else 19291 ast_cli(a->fd, "(none)\n"); 19292 19293 if (!cur->stimer) 19294 ast_cli(a->fd, " Session-Timer: Uninitiallized\n"); 19295 else { 19296 ast_cli(a->fd, " Session-Timer: %s\n", cur->stimer->st_active ? "Active" : "Inactive"); 19297 if (cur->stimer->st_active == TRUE) { 19298 ast_cli(a->fd, " S-Timer Interval: %d\n", cur->stimer->st_interval); 19299 ast_cli(a->fd, " S-Timer Refresher: %s\n", strefresher2str(cur->stimer->st_ref)); 19300 ast_cli(a->fd, " S-Timer Expirys: %d\n", cur->stimer->st_expirys); 19301 ast_cli(a->fd, " S-Timer Sched Id: %d\n", cur->stimer->st_schedid); 19302 ast_cli(a->fd, " S-Timer Peer Sts: %s\n", cur->stimer->st_active_peer_ua ? "Active" : "Inactive"); 19303 ast_cli(a->fd, " S-Timer Cached Min-SE: %d\n", cur->stimer->st_cached_min_se); 19304 ast_cli(a->fd, " S-Timer Cached SE: %d\n", cur->stimer->st_cached_max_se); 19305 ast_cli(a->fd, " S-Timer Cached Ref: %s\n", strefresherparam2str(cur->stimer->st_cached_ref)); 19306 ast_cli(a->fd, " S-Timer Cached Mode: %s\n", stmode2str(cur->stimer->st_cached_mode)); 19307 } 19308 } 19309 19310 ast_cli(a->fd, "\n\n"); 19311 19312 found++; 19313 } 19314 19315 sip_pvt_unlock(cur); 19316 19317 ao2_t_ref(cur, -1, "toss dialog ptr set by iterator_next"); 19318 } 19319 ao2_iterator_destroy(&i); 19320 19321 if (!found) 19322 ast_cli(a->fd, "No such SIP Call ID starting with '%s'\n", a->argv[3]); 19323 19324 return CLI_SUCCESS; 19325 }
| 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 19030 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.
19031 { 19032 struct __show_chan_arg arg = { .fd = a->fd, .numchans = 0 }; 19033 19034 19035 if (cmd == CLI_INIT) { 19036 e->command = "sip show {channels|subscriptions}"; 19037 e->usage = 19038 "Usage: sip show channels\n" 19039 " Lists all currently active SIP calls (dialogs).\n" 19040 "Usage: sip show subscriptions\n" 19041 " Lists active SIP subscriptions.\n"; 19042 return NULL; 19043 } else if (cmd == CLI_GENERATE) 19044 return NULL; 19045 19046 if (a->argc != e->args) 19047 return CLI_SHOWUSAGE; 19048 arg.subscriptions = !strcasecmp(a->argv[e->args - 1], "subscriptions"); 19049 if (!arg.subscriptions) 19050 ast_cli(arg.fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Format", "Hold", "Last Message", "Expiry", "Peer"); 19051 else 19052 ast_cli(arg.fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox", "Expiry"); 19053 19054 /* iterate on the container and invoke the callback on each item */ 19055 ao2_t_callback(dialogs, OBJ_NODATA, show_channels_cb, &arg, "callback to show channels"); 19056 19057 /* print summary information */ 19058 ast_cli(arg.fd, "%d active SIP %s%s\n", arg.numchans, 19059 (arg.subscriptions ? "subscription" : "dialog"), 19060 ESS(arg.numchans)); /* ESS(n) returns an "s" if n>1 */ 19061 return CLI_SUCCESS; 19062 #undef FORMAT 19063 #undef FORMAT2 19064 #undef FORMAT3 19065 }
| 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 18652 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.
18653 { 18654 struct __show_chan_arg arg = { .fd = a->fd, .numchans = 0 }; 18655 18656 switch (cmd) { 18657 case CLI_INIT: 18658 e->command = "sip show channelstats"; 18659 e->usage = 18660 "Usage: sip show channelstats\n" 18661 " Lists all currently active SIP channel's RTCP statistics.\n" 18662 " Note that calls in the much optimized RTP P2P bridge mode will not show any packets here."; 18663 return NULL; 18664 case CLI_GENERATE: 18665 return NULL; 18666 } 18667 18668 if (a->argc != 3) 18669 return CLI_SHOWUSAGE; 18670 18671 ast_cli(a->fd, FORMAT2, "Peer", "Call ID", "Duration", "Recv: Pack", "Lost", "Jitter", "Send: Pack", "Lost", "Jitter"); 18672 /* iterate on the container and invoke the callback on each item */ 18673 ao2_t_callback(dialogs, OBJ_NODATA, show_chanstats_cb, &arg, "callback to sip show chanstats"); 18674 ast_cli(a->fd, "%d active SIP channel%s\n", arg.numchans, (arg.numchans != 1) ? "s" : ""); 18675 return CLI_SUCCESS; 18676 }
| 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 17901 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.
17902 { 17903 struct domain *d; 17904 #define FORMAT "%-40.40s %-20.20s %-16.16s\n" 17905 17906 switch (cmd) { 17907 case CLI_INIT: 17908 e->command = "sip show domains"; 17909 e->usage = 17910 "Usage: sip show domains\n" 17911 " Lists all configured SIP local domains.\n" 17912 " Asterisk only responds to SIP messages to local domains.\n"; 17913 return NULL; 17914 case CLI_GENERATE: 17915 return NULL; 17916 } 17917 17918 if (AST_LIST_EMPTY(&domain_list)) { 17919 ast_cli(a->fd, "SIP Domain support not enabled.\n\n"); 17920 return CLI_SUCCESS; 17921 } else { 17922 ast_cli(a->fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); 17923 AST_LIST_LOCK(&domain_list); 17924 AST_LIST_TRAVERSE(&domain_list, d, list) 17925 ast_cli(a->fd, FORMAT, d->domain, S_OR(d->context, "(default)"), 17926 domain_mode_to_text(d->mode)); 17927 AST_LIST_UNLOCK(&domain_list); 17928 ast_cli(a->fd, "\n"); 17929 return CLI_SUCCESS; 17930 } 17931 }
| 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 19328 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.
19329 { 19330 struct sip_pvt *cur; 19331 size_t len; 19332 int found = 0; 19333 struct ao2_iterator i; 19334 19335 switch (cmd) { 19336 case CLI_INIT: 19337 e->command = "sip show history"; 19338 e->usage = 19339 "Usage: sip show history <call-id>\n" 19340 " Provides detailed dialog history on a given SIP call (specified by call-id).\n"; 19341 return NULL; 19342 case CLI_GENERATE: 19343 return complete_sip_show_history(a->line, a->word, a->pos, a->n); 19344 } 19345 19346 if (a->argc != 4) 19347 return CLI_SHOWUSAGE; 19348 19349 if (!recordhistory) 19350 ast_cli(a->fd, "\n***Note: History recording is currently DISABLED. Use 'sip set history on' to ENABLE.\n"); 19351 19352 len = strlen(a->argv[3]); 19353 19354 i = ao2_iterator_init(dialogs, 0); 19355 while ((cur = ao2_t_iterator_next(&i, "iterate thru dialogs"))) { 19356 sip_pvt_lock(cur); 19357 if (!strncasecmp(cur->callid, a->argv[3], len)) { 19358 struct sip_history *hist; 19359 int x = 0; 19360 19361 ast_cli(a->fd, "\n"); 19362 if (cur->subscribed != NONE) 19363 ast_cli(a->fd, " * Subscription\n"); 19364 else 19365 ast_cli(a->fd, " * SIP Call\n"); 19366 if (cur->history) 19367 AST_LIST_TRAVERSE(cur->history, hist, list) 19368 ast_cli(a->fd, "%d. %s\n", ++x, hist->event); 19369 if (x == 0) 19370 ast_cli(a->fd, "Call '%s' has no history\n", cur->callid); 19371 found++; 19372 } 19373 sip_pvt_unlock(cur); 19374 ao2_t_ref(cur, -1, "toss dialog ptr from iterator_next"); 19375 } 19376 ao2_iterator_destroy(&i); 19377 19378 if (!found) 19379 ast_cli(a->fd, "No such SIP Call ID starting with '%s'\n", a->argv[3]); 19380 19381 return CLI_SUCCESS; 19382 }
| 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 16963 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.
16964 { 16965 #define FORMAT "%-25.25s %-15.15s %-15.15s \n" 16966 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" 16967 char ilimits[40]; 16968 char iused[40]; 16969 int showall = FALSE; 16970 struct ao2_iterator i; 16971 struct sip_peer *peer; 16972 16973 switch (cmd) { 16974 case CLI_INIT: 16975 e->command = "sip show inuse"; 16976 e->usage = 16977 "Usage: sip show inuse [all]\n" 16978 " List all SIP devices usage counters and limits.\n" 16979 " Add option \"all\" to show all devices, not only those with a limit.\n"; 16980 return NULL; 16981 case CLI_GENERATE: 16982 return NULL; 16983 } 16984 16985 if (a->argc < 3) 16986 return CLI_SHOWUSAGE; 16987 16988 if (a->argc == 4 && !strcmp(a->argv[3], "all")) 16989 showall = TRUE; 16990 16991 ast_cli(a->fd, FORMAT, "* Peer name", "In use", "Limit"); 16992 16993 i = ao2_iterator_init(peers, 0); 16994 while ((peer = ao2_t_iterator_next(&i, "iterate thru peer table"))) { 16995 ao2_lock(peer); 16996 if (peer->call_limit) 16997 snprintf(ilimits, sizeof(ilimits), "%d", peer->call_limit); 16998 else 16999 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 17000 snprintf(iused, sizeof(iused), "%d/%d/%d", peer->inUse, peer->inRinging, peer->onHold); 17001 if (showall || peer->call_limit) 17002 ast_cli(a->fd, FORMAT2, peer->name, iused, ilimits); 17003 ao2_unlock(peer); 17004 unref_peer(peer, "toss iterator pointer"); 17005 } 17006 ao2_iterator_destroy(&i); 17007 17008 return CLI_SUCCESS; 17009 #undef FORMAT 17010 #undef FORMAT2 17011 }
| static char * sip_show_mwi | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 18909 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.
18910 { 18911 #define FORMAT "%-30.30s %-12.12s %-10.10s %-10.10s\n" 18912 char host[80]; 18913 18914 switch (cmd) { 18915 case CLI_INIT: 18916 e->command = "sip show mwi"; 18917 e->usage = 18918 "Usage: sip show mwi\n" 18919 " Provides a list of MWI subscriptions and status.\n"; 18920 return NULL; 18921 case CLI_GENERATE: 18922 return NULL; 18923 } 18924 18925 ast_cli(a->fd, FORMAT, "Host", "Username", "Mailbox", "Subscribed"); 18926 18927 ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do { 18928 ASTOBJ_RDLOCK(iterator); 18929 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); 18930 ast_cli(a->fd, FORMAT, host, iterator->username, iterator->mailbox, AST_CLI_YESNO(iterator->subscribed)); 18931 ASTOBJ_UNLOCK(iterator); 18932 } while(0)); 18933 18934 return CLI_SUCCESS; 18935 #undef FORMAT 18936 }
| 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 17534 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.
17535 { 17536 char tmp[256]; 17537 17538 switch (cmd) { 17539 case CLI_INIT: 17540 e->command = "sip show objects"; 17541 e->usage = 17542 "Usage: sip show objects\n" 17543 " Lists status of known SIP objects\n"; 17544 return NULL; 17545 case CLI_GENERATE: 17546 return NULL; 17547 } 17548 17549 if (a->argc != 3) 17550 return CLI_SHOWUSAGE; 17551 ast_cli(a->fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs); 17552 ao2_t_callback(peers, OBJ_NODATA, peer_dump_func, a, "initiate ao2_callback to dump peers"); 17553 ast_cli(a->fd, "-= Peer objects by IP =-\n\n"); 17554 ao2_t_callback(peers_by_ip, OBJ_NODATA, peer_dump_func, a, "initiate ao2_callback to dump peers_by_ip"); 17555 ast_cli(a->fd, "-= Registry objects: %d =-\n\n", regobjs); 17556 ASTOBJ_CONTAINER_DUMP(a->fd, tmp, sizeof(tmp), ®l); 17557 ast_cli(a->fd, "-= Dialog objects:\n\n"); 17558 ao2_t_callback(dialogs, OBJ_NODATA, dialog_dump_func, a, "initiate ao2_callback to dump dialogs"); 17559 return CLI_SUCCESS; 17560 }
| 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 17956 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.
17957 { 17958 switch (cmd) { 17959 case CLI_INIT: 17960 e->command = "sip show peer"; 17961 e->usage = 17962 "Usage: sip show peer <name> [load]\n" 17963 " Shows all details on one SIP peer and the current status.\n" 17964 " Option \"load\" forces lookup of peer in realtime storage.\n"; 17965 return NULL; 17966 case CLI_GENERATE: 17967 return complete_sip_show_peer(a->line, a->word, a->pos, a->n); 17968 } 17969 return _sip_show_peer(0, a->fd, NULL, NULL, a->argc, (const char **) a->argv); 17970 }
| 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 17286 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.
17287 { 17288 switch (cmd) { 17289 case CLI_INIT: 17290 e->command = "sip show peers"; 17291 e->usage = 17292 "Usage: sip show peers [like <pattern>]\n" 17293 " Lists all known SIP peers.\n" 17294 " Optional regular expression pattern is used to filter the peer list.\n"; 17295 return NULL; 17296 case CLI_GENERATE: 17297 return NULL; 17298 } 17299 17300 return _sip_show_peers(a->fd, NULL, NULL, NULL, a->argc, (const char **) a->argv); 17301 }
| 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 18490 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.
18491 { 18492 #define FORMAT2 "%-39.39s %-6.6s %-12.12s %8.8s %-20.20s %-25.25s\n" 18493 #define FORMAT "%-39.39s %-6.6s %-12.12s %8d %-20.20s %-25.25s\n" 18494 char host[80]; 18495 char user[80]; 18496 char tmpdat[256]; 18497 struct ast_tm tm; 18498 int counter = 0; 18499 18500 switch (cmd) { 18501 case CLI_INIT: 18502 e->command = "sip show registry"; 18503 e->usage = 18504 "Usage: sip show registry\n" 18505 " Lists all registration requests and status.\n"; 18506 return NULL; 18507 case CLI_GENERATE: 18508 return NULL; 18509 } 18510 18511 if (a->argc != 3) 18512 return CLI_SHOWUSAGE; 18513 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Refresh", "State", "Reg.Time"); 18514 18515 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 18516 ASTOBJ_RDLOCK(iterator); 18517 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); 18518 snprintf(user, sizeof(user), "%s", iterator->username); 18519 if (!ast_strlen_zero(iterator->regdomain)) { 18520 snprintf(tmpdat, sizeof(tmpdat), "%s", user); 18521 snprintf(user, sizeof(user), "%s@%s", tmpdat, iterator->regdomain);} 18522 if (iterator->regdomainport) { 18523 snprintf(tmpdat, sizeof(tmpdat), "%s", user); 18524 snprintf(user, sizeof(user), "%s:%d", tmpdat, iterator->regdomainport);} 18525 if (iterator->regtime.tv_sec) { 18526 ast_localtime(&iterator->regtime, &tm, NULL); 18527 ast_strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm); 18528 } else 18529 tmpdat[0] = '\0'; 18530 ast_cli(a->fd, FORMAT, host, (iterator->dnsmgr) ? "Y" : "N", user, iterator->refresh, regstate2str(iterator->regstate), tmpdat); 18531 ASTOBJ_UNLOCK(iterator); 18532 counter++; 18533 } while(0)); 18534 ast_cli(a->fd, "%d SIP registrations.\n", counter); 18535 return CLI_SUCCESS; 18536 #undef FORMAT 18537 #undef FORMAT2 18538 }
| static char * sip_show_sched | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 18447 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.
18448 { 18449 struct ast_str *cbuf; 18450 struct ast_cb_names cbnames = {9, { "retrans_pkt", 18451 "__sip_autodestruct", 18452 "expire_register", 18453 "auto_congest", 18454 "sip_reg_timeout", 18455 "sip_poke_peer_s", 18456 "sip_poke_noanswer", 18457 "sip_reregister", 18458 "sip_reinvite_retry"}, 18459 { retrans_pkt, 18460 __sip_autodestruct, 18461 expire_register, 18462 auto_congest, 18463 sip_reg_timeout, 18464 sip_poke_peer_s, 18465 sip_poke_noanswer, 18466 sip_reregister, 18467 sip_reinvite_retry}}; 18468 18469 switch (cmd) { 18470 case CLI_INIT: 18471 e->command = "sip show sched"; 18472 e->usage = 18473 "Usage: sip show sched\n" 18474 " Shows stats on what's in the sched queue at the moment\n"; 18475 return NULL; 18476 case CLI_GENERATE: 18477 return NULL; 18478 } 18479 18480 cbuf = ast_str_alloca(2048); 18481 18482 ast_cli(a->fd, "\n"); 18483 ast_sched_report(sched, &cbuf, &cbnames); 18484 ast_cli(a->fd, "%s", ast_str_buffer(cbuf)); 18485 18486 return CLI_SUCCESS; 18487 }
| 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 18681 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.
18682 { 18683 int realtimepeers; 18684 int realtimeregs; 18685 char codec_buf[SIPBUFSIZE]; 18686 const char *msg; /* temporary msg pointer */ 18687 struct sip_auth_container *credentials; 18688 18689 switch (cmd) { 18690 case CLI_INIT: 18691 e->command = "sip show settings"; 18692 e->usage = 18693 "Usage: sip show settings\n" 18694 " Provides detailed list of the configuration of the SIP channel.\n"; 18695 return NULL; 18696 case CLI_GENERATE: 18697 return NULL; 18698 } 18699 18700 if (a->argc != 3) 18701 return CLI_SHOWUSAGE; 18702 18703 realtimepeers = ast_check_realtime("sippeers"); 18704 realtimeregs = ast_check_realtime("sipregs"); 18705 18706 ast_mutex_lock(&authl_lock); 18707 credentials = authl; 18708 if (credentials) { 18709 ao2_t_ref(credentials, +1, "Ref global auth for show"); 18710 } 18711 ast_mutex_unlock(&authl_lock); 18712 18713 ast_cli(a->fd, "\n\nGlobal Settings:\n"); 18714 ast_cli(a->fd, "----------------\n"); 18715 ast_cli(a->fd, " UDP Bindaddress: %s\n", ast_sockaddr_stringify(&bindaddr)); 18716 if (ast_sockaddr_is_ipv6(&bindaddr) && ast_sockaddr_is_any(&bindaddr)) { 18717 ast_cli(a->fd, " ** Additional Info:\n"); 18718 ast_cli(a->fd, " [::] may include IPv4 in addition to IPv6, if such a feature is enabled in the OS.\n"); 18719 } 18720 ast_cli(a->fd, " TCP SIP Bindaddress: %s\n", 18721 sip_cfg.tcp_enabled != FALSE ? 18722 ast_sockaddr_stringify(&sip_tcp_desc.local_address) : 18723 "Disabled"); 18724 ast_cli(a->fd, " TLS SIP Bindaddress: %s\n", 18725 default_tls_cfg.enabled != FALSE ? 18726 ast_sockaddr_stringify(&sip_tls_desc.local_address) : 18727 "Disabled"); 18728 ast_cli(a->fd, " Videosupport: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT))); 18729 ast_cli(a->fd, " Textsupport: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_TEXTSUPPORT))); 18730 ast_cli(a->fd, " Ignore SDP sess. ver.: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_IGNORESDPVERSION))); 18731 ast_cli(a->fd, " AutoCreate Peer: %s\n", AST_CLI_YESNO(sip_cfg.autocreatepeer)); 18732 ast_cli(a->fd, " Match Auth Username: %s\n", AST_CLI_YESNO(global_match_auth_username)); 18733 ast_cli(a->fd, " Allow unknown access: %s\n", AST_CLI_YESNO(sip_cfg.allowguest)); 18734 ast_cli(a->fd, " Allow subscriptions: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))); 18735 ast_cli(a->fd, " Allow overlap dialing: %s\n", allowoverlap2str(ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP))); 18736 ast_cli(a->fd, " Allow promisc. redir: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_PROMISCREDIR))); 18737 ast_cli(a->fd, " Enable call counters: %s\n", AST_CLI_YESNO(global_callcounter)); 18738 ast_cli(a->fd, " SIP domain support: %s\n", AST_CLI_YESNO(!AST_LIST_EMPTY(&domain_list))); 18739 ast_cli(a->fd, " Realm. auth: %s\n", AST_CLI_YESNO(credentials != NULL)); 18740 if (credentials) { 18741 struct sip_auth *auth; 18742 18743 AST_LIST_TRAVERSE(&credentials->list, auth, node) { 18744 ast_cli(a->fd, " Realm. auth entry: Realm %-15.15s User %-10.20s %s\n", 18745 auth->realm, 18746 auth->username, 18747 !ast_strlen_zero(auth->secret) 18748 ? "<Secret set>" 18749 : (!ast_strlen_zero(auth->md5secret) 18750 ? "<MD5secret set>" : "<Not set>")); 18751 } 18752 ao2_t_ref(credentials, -1, "Unref global auth for show"); 18753 } 18754 ast_cli(a->fd, " Our auth realm %s\n", sip_cfg.realm); 18755 ast_cli(a->fd, " Use domains as realms: %s\n", AST_CLI_YESNO(sip_cfg.domainsasrealm)); 18756 ast_cli(a->fd, " Call to non-local dom.: %s\n", AST_CLI_YESNO(sip_cfg.allow_external_domains)); 18757 ast_cli(a->fd, " URI user is phone no: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_USEREQPHONE))); 18758 ast_cli(a->fd, " Always auth rejects: %s\n", AST_CLI_YESNO(sip_cfg.alwaysauthreject)); 18759 ast_cli(a->fd, " Direct RTP setup: %s\n", AST_CLI_YESNO(sip_cfg.directrtpsetup)); 18760 ast_cli(a->fd, " User Agent: %s\n", global_useragent); 18761 ast_cli(a->fd, " SDP Session Name: %s\n", ast_strlen_zero(global_sdpsession) ? "-" : global_sdpsession); 18762 ast_cli(a->fd, " SDP Owner Name: %s\n", ast_strlen_zero(global_sdpowner) ? "-" : global_sdpowner); 18763 ast_cli(a->fd, " Reg. context: %s\n", S_OR(sip_cfg.regcontext, "(not set)")); 18764 ast_cli(a->fd, " Regexten on Qualify: %s\n", AST_CLI_YESNO(sip_cfg.regextenonqualify)); 18765 ast_cli(a->fd, " Legacy userfield parse: %s\n", AST_CLI_YESNO(sip_cfg.legacy_useroption_parsing)); 18766 ast_cli(a->fd, " Caller ID: %s\n", default_callerid); 18767 if ((default_fromdomainport) && (default_fromdomainport != STANDARD_SIP_PORT)) { 18768 ast_cli(a->fd, " From: Domain: %s:%d\n", default_fromdomain, default_fromdomainport); 18769 } else { 18770 ast_cli(a->fd, " From: Domain: %s\n", default_fromdomain); 18771 } 18772 ast_cli(a->fd, " Record SIP history: %s\n", AST_CLI_ONOFF(recordhistory)); 18773 ast_cli(a->fd, " Call Events: %s\n", AST_CLI_ONOFF(sip_cfg.callevents)); 18774 ast_cli(a->fd, " Auth. Failure Events: %s\n", AST_CLI_ONOFF(global_authfailureevents)); 18775 18776 ast_cli(a->fd, " T.38 support: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT))); 18777 ast_cli(a->fd, " T.38 EC mode: %s\n", faxec2str(ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT))); 18778 ast_cli(a->fd, " T.38 MaxDtgrm: %d\n", global_t38_maxdatagram); 18779 if (!realtimepeers && !realtimeregs) 18780 ast_cli(a->fd, " SIP realtime: Disabled\n" ); 18781 else 18782 ast_cli(a->fd, " SIP realtime: Enabled\n" ); 18783 ast_cli(a->fd, " Qualify Freq : %d ms\n", global_qualifyfreq); 18784 ast_cli(a->fd, " Q.850 Reason header: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_Q850_REASON))); 18785 ast_cli(a->fd, " Store SIP_CAUSE: %s\n", AST_CLI_YESNO(global_store_sip_cause)); 18786 ast_cli(a->fd, "\nNetwork QoS Settings:\n"); 18787 ast_cli(a->fd, "---------------------------\n"); 18788 ast_cli(a->fd, " IP ToS SIP: %s\n", ast_tos2str(global_tos_sip)); 18789 ast_cli(a->fd, " IP ToS RTP audio: %s\n", ast_tos2str(global_tos_audio)); 18790 ast_cli(a->fd, " IP ToS RTP video: %s\n", ast_tos2str(global_tos_video)); 18791 ast_cli(a->fd, " IP ToS RTP text: %s\n", ast_tos2str(global_tos_text)); 18792 ast_cli(a->fd, " 802.1p CoS SIP: %d\n", global_cos_sip); 18793 ast_cli(a->fd, " 802.1p CoS RTP audio: %d\n", global_cos_audio); 18794 ast_cli(a->fd, " 802.1p CoS RTP video: %d\n", global_cos_video); 18795 ast_cli(a->fd, " 802.1p CoS RTP text: %d\n", global_cos_text); 18796 ast_cli(a->fd, " Jitterbuffer enabled: %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_ENABLED))); 18797 if (ast_test_flag(&global_jbconf, AST_JB_ENABLED)) { 18798 ast_cli(a->fd, " Jitterbuffer forced: %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_FORCED))); 18799 ast_cli(a->fd, " Jitterbuffer max size: %ld\n", global_jbconf.max_size); 18800 ast_cli(a->fd, " Jitterbuffer resync: %ld\n", global_jbconf.resync_threshold); 18801 ast_cli(a->fd, " Jitterbuffer impl: %s\n", global_jbconf.impl); 18802 if (!strcasecmp(global_jbconf.impl, "adaptive")) { 18803 ast_cli(a->fd, " Jitterbuffer tgt extra: %ld\n", global_jbconf.target_extra); 18804 } 18805 ast_cli(a->fd, " Jitterbuffer log: %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_LOG))); 18806 } 18807 18808 ast_cli(a->fd, "\nNetwork Settings:\n"); 18809 ast_cli(a->fd, "---------------------------\n"); 18810 /* determine if/how SIP address can be remapped */ 18811 if (localaddr == NULL) 18812 msg = "Disabled, no localnet list"; 18813 else if (ast_sockaddr_isnull(&externaddr)) 18814 msg = "Disabled"; 18815 else if (!ast_strlen_zero(externhost)) 18816 msg = "Enabled using externhost"; 18817 else 18818 msg = "Enabled using externaddr"; 18819 ast_cli(a->fd, " SIP address remapping: %s\n", msg); 18820 ast_cli(a->fd, " Externhost: %s\n", S_OR(externhost, "<none>")); 18821 ast_cli(a->fd, " Externaddr: %s\n", ast_sockaddr_stringify(&externaddr)); 18822 ast_cli(a->fd, " Externrefresh: %d\n", externrefresh); 18823 { 18824 struct ast_ha *d; 18825 const char *prefix = "Localnet:"; 18826 18827 for (d = localaddr; d ; prefix = "", d = d->next) { 18828 const char *addr = ast_strdupa(ast_sockaddr_stringify_addr(&d->addr)); 18829 const char *mask = ast_strdupa(ast_sockaddr_stringify_addr(&d->netmask)); 18830 ast_cli(a->fd, " %-24s%s/%s\n", prefix, addr, mask); 18831 } 18832 } 18833 ast_cli(a->fd, "\nGlobal Signalling Settings:\n"); 18834 ast_cli(a->fd, "---------------------------\n"); 18835 ast_cli(a->fd, " Codecs: "); 18836 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, sip_cfg.capability); 18837 ast_cli(a->fd, "%s\n", codec_buf); 18838 ast_cli(a->fd, " Codec Order: "); 18839 print_codec_to_cli(a->fd, &default_prefs); 18840 ast_cli(a->fd, "\n"); 18841 ast_cli(a->fd, " Relax DTMF: %s\n", AST_CLI_YESNO(global_relaxdtmf)); 18842 ast_cli(a->fd, " RFC2833 Compensation: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE))); 18843 ast_cli(a->fd, " Symmetric RTP: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_SYMMETRICRTP))); 18844 ast_cli(a->fd, " Compact SIP headers: %s\n", AST_CLI_YESNO(sip_cfg.compactheaders)); 18845 ast_cli(a->fd, " RTP Keepalive: %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" ); 18846 ast_cli(a->fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" ); 18847 ast_cli(a->fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)"); 18848 ast_cli(a->fd, " MWI NOTIFY mime type: %s\n", default_notifymime); 18849 ast_cli(a->fd, " DNS SRV lookup: %s\n", AST_CLI_YESNO(sip_cfg.srvlookup)); 18850 ast_cli(a->fd, " Pedantic SIP support: %s\n", AST_CLI_YESNO(sip_cfg.pedanticsipchecking)); 18851 ast_cli(a->fd, " Reg. min duration %d secs\n", min_expiry); 18852 ast_cli(a->fd, " Reg. max duration: %d secs\n", max_expiry); 18853 ast_cli(a->fd, " Reg. default duration: %d secs\n", default_expiry); 18854 ast_cli(a->fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout); 18855 ast_cli(a->fd, " Outbound reg. attempts: %d\n", global_regattempts_max); 18856 ast_cli(a->fd, " Notify ringing state: %s\n", AST_CLI_YESNO(sip_cfg.notifyringing)); 18857 if (sip_cfg.notifyringing) { 18858 ast_cli(a->fd, " Include CID: %s%s\n", 18859 AST_CLI_YESNO(sip_cfg.notifycid), 18860 sip_cfg.notifycid == IGNORE_CONTEXT ? " (Ignoring context)" : ""); 18861 } 18862 ast_cli(a->fd, " Notify hold state: %s\n", AST_CLI_YESNO(sip_cfg.notifyhold)); 18863 ast_cli(a->fd, " SIP Transfer mode: %s\n", transfermode2str(sip_cfg.allowtransfer)); 18864 ast_cli(a->fd, " Max Call Bitrate: %d kbps\n", default_maxcallbitrate); 18865 ast_cli(a->fd, " Auto-Framing: %s\n", AST_CLI_YESNO(global_autoframing)); 18866 ast_cli(a->fd, " Outb. proxy: %s %s\n", ast_strlen_zero(sip_cfg.outboundproxy.name) ? "<not set>" : sip_cfg.outboundproxy.name, 18867 sip_cfg.outboundproxy.force ? "(forced)" : ""); 18868 ast_cli(a->fd, " Session Timers: %s\n", stmode2str(global_st_mode)); 18869 ast_cli(a->fd, " Session Refresher: %s\n", strefresherparam2str(global_st_refresher)); 18870 ast_cli(a->fd, " Session Expires: %d secs\n", global_max_se); 18871 ast_cli(a->fd, " Session Min-SE: %d secs\n", global_min_se); 18872 ast_cli(a->fd, " Timer T1: %d\n", global_t1); 18873 ast_cli(a->fd, " Timer T1 minimum: %d\n", global_t1min); 18874 ast_cli(a->fd, " Timer B: %d\n", global_timer_b); 18875 ast_cli(a->fd, " No premature media: %s\n", AST_CLI_YESNO(global_prematuremediafilter)); 18876 ast_cli(a->fd, " Max forwards: %d\n", sip_cfg.default_max_forwards); 18877 18878 ast_cli(a->fd, "\nDefault Settings:\n"); 18879 ast_cli(a->fd, "-----------------\n"); 18880 ast_cli(a->fd, " Allowed transports: %s\n", get_transport_list(default_transports)); 18881 ast_cli(a->fd, " Outbound transport: %s\n", get_transport(default_primary_transport)); 18882 ast_cli(a->fd, " Context: %s\n", sip_cfg.default_context); 18883 ast_cli(a->fd, " Force rport: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_NAT_FORCE_RPORT))); 18884 ast_cli(a->fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF))); 18885 ast_cli(a->fd, " Qualify: %d\n", default_qualify); 18886 ast_cli(a->fd, " Use ClientCode: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_USECLIENTCODE))); 18887 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))); 18888 ast_cli(a->fd, " Language: %s\n", default_language); 18889 ast_cli(a->fd, " MOH Interpret: %s\n", default_mohinterpret); 18890 ast_cli(a->fd, " MOH Suggest: %s\n", default_mohsuggest); 18891 ast_cli(a->fd, " Voice Mail Extension: %s\n", default_vmexten); 18892 18893 18894 if (realtimepeers || realtimeregs) { 18895 ast_cli(a->fd, "\nRealtime SIP Settings:\n"); 18896 ast_cli(a->fd, "----------------------\n"); 18897 ast_cli(a->fd, " Realtime Peers: %s\n", AST_CLI_YESNO(realtimepeers)); 18898 ast_cli(a->fd, " Realtime Regs: %s\n", AST_CLI_YESNO(realtimeregs)); 18899 ast_cli(a->fd, " Cache Friends: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS))); 18900 ast_cli(a->fd, " Update: %s\n", AST_CLI_YESNO(sip_cfg.peer_rtupdate)); 18901 ast_cli(a->fd, " Ignore Reg. Expire: %s\n", AST_CLI_YESNO(sip_cfg.ignore_regexpire)); 18902 ast_cli(a->fd, " Save sys. name: %s\n", AST_CLI_YESNO(sip_cfg.rtsave_sysname)); 18903 ast_cli(a->fd, " Auto Clear: %d (%s)\n", sip_cfg.rtautoclear, ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR) ? "Enabled" : "Disabled"); 18904 } 18905 ast_cli(a->fd, "\n----\n"); 18906 return CLI_SUCCESS; 18907 }
| 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 17101 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.
17102 { 17103 struct sip_threadinfo *th; 17104 struct ao2_iterator i; 17105 17106 #define FORMAT2 "%-47.47s %9.9s %6.6s\n" 17107 #define FORMAT "%-47.47s %-9.9s %-6.6s\n" 17108 17109 switch (cmd) { 17110 case CLI_INIT: 17111 e->command = "sip show tcp"; 17112 e->usage = 17113 "Usage: sip show tcp\n" 17114 " Lists all active TCP/TLS sessions.\n"; 17115 return NULL; 17116 case CLI_GENERATE: 17117 return NULL; 17118 } 17119 17120 if (a->argc != 3) 17121 return CLI_SHOWUSAGE; 17122 17123 ast_cli(a->fd, FORMAT2, "Address", "Transport", "Type"); 17124 17125 i = ao2_iterator_init(threadt, 0); 17126 while ((th = ao2_t_iterator_next(&i, "iterate through tcp threads for 'sip show tcp'"))) { 17127 ast_cli(a->fd, FORMAT, 17128 ast_sockaddr_stringify(&th->tcptls_session->remote_address), 17129 get_transport(th->type), 17130 (th->tcptls_session->client ? "Client" : "Server")); 17131 ao2_t_ref(th, -1, "decrement ref from iterator"); 17132 } 17133 ao2_iterator_destroy(&i); 17134 17135 return CLI_SUCCESS; 17136 #undef FORMAT 17137 #undef FORMAT2 17138 }
| 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 18371 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.
18372 { 18373 char cbuf[256]; 18374 struct sip_peer *user; 18375 struct ast_variable *v; 18376 int load_realtime; 18377 18378 switch (cmd) { 18379 case CLI_INIT: 18380 e->command = "sip show user"; 18381 e->usage = 18382 "Usage: sip show user <name> [load]\n" 18383 " Shows all details on one SIP user and the current status.\n" 18384 " Option \"load\" forces lookup of peer in realtime storage.\n"; 18385 return NULL; 18386 case CLI_GENERATE: 18387 return complete_sip_show_user(a->line, a->word, a->pos, a->n); 18388 } 18389 18390 if (a->argc < 4) 18391 return CLI_SHOWUSAGE; 18392 18393 /* Load from realtime storage? */ 18394 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? TRUE : FALSE; 18395 18396 if ((user = find_peer(a->argv[3], NULL, load_realtime, FINDUSERS, FALSE, 0))) { 18397 ao2_lock(user); 18398 ast_cli(a->fd, "\n\n"); 18399 ast_cli(a->fd, " * Name : %s\n", user->name); 18400 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>"); 18401 ast_cli(a->fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>"); 18402 ast_cli(a->fd, " Context : %s\n", user->context); 18403 ast_cli(a->fd, " Language : %s\n", user->language); 18404 if (!ast_strlen_zero(user->accountcode)) 18405 ast_cli(a->fd, " Accountcode : %s\n", user->accountcode); 18406 ast_cli(a->fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); 18407 ast_cli(a->fd, " Transfer mode: %s\n", transfermode2str(user->allowtransfer)); 18408 ast_cli(a->fd, " MaxCallBR : %d kbps\n", user->maxcallbitrate); 18409 ast_cli(a->fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); 18410 ast_cli(a->fd, " Call limit : %d\n", user->call_limit); 18411 ast_cli(a->fd, " Callgroup : "); 18412 print_group(a->fd, user->callgroup, 0); 18413 ast_cli(a->fd, " Pickupgroup : "); 18414 print_group(a->fd, user->pickupgroup, 0); 18415 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>")); 18416 ast_cli(a->fd, " ACL : %s\n", AST_CLI_YESNO(user->ha != NULL)); 18417 ast_cli(a->fd, " Sess-Timers : %s\n", stmode2str(user->stimer.st_mode_oper)); 18418 ast_cli(a->fd, " Sess-Refresh : %s\n", strefresherparam2str(user->stimer.st_ref)); 18419 ast_cli(a->fd, " Sess-Expires : %d secs\n", user->stimer.st_max_se); 18420 ast_cli(a->fd, " Sess-Min-SE : %d secs\n", user->stimer.st_min_se); 18421 ast_cli(a->fd, " RTP Engine : %s\n", user->engine); 18422 18423 ast_cli(a->fd, " Codec Order : ("); 18424 print_codec_to_cli(a->fd, &user->prefs); 18425 ast_cli(a->fd, ")\n"); 18426 18427 ast_cli(a->fd, " Auto-Framing: %s \n", AST_CLI_YESNO(user->autoframing)); 18428 if (user->chanvars) { 18429 ast_cli(a->fd, " Variables :\n"); 18430 for (v = user->chanvars ; v ; v = v->next) 18431 ast_cli(a->fd, " %s = %s\n", v->name, v->value); 18432 } 18433 18434 ast_cli(a->fd, "\n"); 18435 18436 ao2_unlock(user); 18437 unref_peer(user, "sip show user"); 18438 } else { 18439 ast_cli(a->fd, "User %s not found.\n", a->argv[3]); 18440 ast_cli(a->fd, "\n"); 18441 } 18442 18443 return CLI_SUCCESS; 18444 }
| 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 17141 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.
17142 { 17143 regex_t regexbuf; 17144 int havepattern = FALSE; 17145 struct ao2_iterator user_iter; 17146 struct sip_peer *user; 17147 17148 #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" 17149 17150 switch (cmd) { 17151 case CLI_INIT: 17152 e->command = "sip show users"; 17153 e->usage = 17154 "Usage: sip show users [like <pattern>]\n" 17155 " Lists all known SIP users.\n" 17156 " Optional regular expression pattern is used to filter the user list.\n"; 17157 return NULL; 17158 case CLI_GENERATE: 17159 return NULL; 17160 } 17161 17162 switch (a->argc) { 17163 case 5: 17164 if (!strcasecmp(a->argv[3], "like")) { 17165 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB)) 17166 return CLI_SHOWUSAGE; 17167 havepattern = TRUE; 17168 } else 17169 return CLI_SHOWUSAGE; 17170 case 3: 17171 break; 17172 default: 17173 return CLI_SHOWUSAGE; 17174 } 17175 17176 ast_cli(a->fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "ForcerPort"); 17177 17178 user_iter = ao2_iterator_init(peers, 0); 17179 while ((user = ao2_t_iterator_next(&user_iter, "iterate thru peers table"))) { 17180 ao2_lock(user); 17181 if (!(user->type & SIP_TYPE_USER)) { 17182 ao2_unlock(user); 17183 unref_peer(user, "sip show users"); 17184 continue; 17185 } 17186 17187 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) { 17188 ao2_unlock(user); 17189 unref_peer(user, "sip show users"); 17190 continue; 17191 } 17192 17193 ast_cli(a->fd, FORMAT, user->name, 17194 user->secret, 17195 user->accountcode, 17196 user->context, 17197 AST_CLI_YESNO(user->ha != NULL), 17198 AST_CLI_YESNO(ast_test_flag(&user->flags[0], SIP_NAT_FORCE_RPORT))); 17199 ao2_unlock(user); 17200 unref_peer(user, "sip show users"); 17201 } 17202 ao2_iterator_destroy(&user_iter); 17203 17204 if (havepattern) 17205 regfree(®exbuf); 17206 17207 return CLI_SUCCESS; 17208 #undef FORMAT 17209 }
| static int sip_sipredirect | ( | struct sip_pvt * | p, | |
| const char * | dest | |||
| ) | [static] |
Transfer call before connect with a 302 redirect.
Definition at line 30276 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().
30277 { 30278 char *cdest; 30279 char *extension, *domain; 30280 30281 cdest = ast_strdupa(dest); 30282 30283 extension = strsep(&cdest, "@"); 30284 domain = cdest; 30285 if (ast_strlen_zero(extension)) { 30286 ast_log(LOG_ERROR, "Missing mandatory argument: extension\n"); 30287 return 0; 30288 } 30289 30290 /* we'll issue the redirect message here */ 30291 if (!domain) { 30292 char *local_to_header; 30293 char to_header[256]; 30294 30295 ast_copy_string(to_header, get_header(&p->initreq, "To"), sizeof(to_header)); 30296 if (ast_strlen_zero(to_header)) { 30297 ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n"); 30298 return 0; 30299 } 30300 if (((local_to_header = strcasestr(to_header, "sip:")) || (local_to_header = strcasestr(to_header, "sips:"))) 30301 && (local_to_header = strchr(local_to_header, '@'))) { 30302 char ldomain[256]; 30303 30304 memset(ldomain, 0, sizeof(ldomain)); 30305 local_to_header++; 30306 /* This is okey because lhost and lport are as big as tmp */ 30307 sscanf(local_to_header, "%256[^<>; ]", ldomain); 30308 if (ast_strlen_zero(ldomain)) { 30309 ast_log(LOG_ERROR, "Can't find the host address\n"); 30310 return 0; 30311 } 30312 domain = ast_strdupa(ldomain); 30313 } 30314 } 30315 30316 ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s>", extension, domain); 30317 transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq); 30318 30319 sip_scheddestroy(p, SIP_TRANS_TIMEOUT); /* Make sure we stop send this reply. */ 30320 sip_alreadygone(p); 30321 30322 if (p->owner) { 30323 enum ast_control_transfer message = AST_TRANSFER_SUCCESS; 30324 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 30325 } 30326 /* hangup here */ 30327 return 0; 30328 }
| 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 8063 of file chan_sip.c.
References ast_calloc, ast_log(), and LOG_ERROR.
Referenced by handle_request_invite(), and st_get_mode().
08064 { 08065 struct sip_st_dlg *stp; 08066 08067 if (p->stimer) { 08068 ast_log(LOG_ERROR, "Session-Timer struct already allocated\n"); 08069 return p->stimer; 08070 } 08071 08072 if (!(stp = ast_calloc(1, sizeof(struct sip_st_dlg)))) 08073 return NULL; 08074 08075 p->stimer = stp; 08076 08077 stp->st_schedid = -1; /* Session-Timers ast_sched scheduler id */ 08078 08079 return p->stimer; 08080 }
| 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 26139 of file chan_sip.c.
Referenced by initreqprep(), and transmit_notify_with_mwi().
26140 { 26141 if (type & SIP_TRANSPORT_TLS) 26142 return port == STANDARD_TLS_PORT; 26143 else 26144 return port == STANDARD_SIP_PORT; 26145 }
| 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 8696 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().
08697 { 08698 struct sip_subscription_mwi *mwi; 08699 int portnum = 0; 08700 enum sip_transport transport = SIP_TRANSPORT_UDP; 08701 char buf[256] = ""; 08702 char *username = NULL, *hostname = NULL, *secret = NULL, *authuser = NULL, *porta = NULL, *mailbox = NULL; 08703 08704 if (!value) { 08705 return -1; 08706 } 08707 08708 ast_copy_string(buf, value, sizeof(buf)); 08709 08710 username = buf; 08711 08712 if ((hostname = strrchr(buf, '@'))) { 08713 *hostname++ = '\0'; 08714 } else { 08715 return -1; 08716 } 08717 08718 if ((secret = strchr(username, ':'))) { 08719 *secret++ = '\0'; 08720 if ((authuser = strchr(secret, ':'))) { 08721 *authuser++ = '\0'; 08722 } 08723 } 08724 08725 if ((mailbox = strchr(hostname, '/'))) { 08726 *mailbox++ = '\0'; 08727 } 08728 08729 if (ast_strlen_zero(username) || ast_strlen_zero(hostname) || ast_strlen_zero(mailbox)) { 08730 ast_log(LOG_WARNING, "Format for MWI subscription is user[:secret[:authuser]]@host[:port]/mailbox at line %d\n", lineno); 08731 return -1; 08732 } 08733 08734 if ((porta = strchr(hostname, ':'))) { 08735 *porta++ = '\0'; 08736 if (!(portnum = atoi(porta))) { 08737 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 08738 return -1; 08739 } 08740 } 08741 08742 if (!(mwi = ast_calloc_with_stringfields(1, struct sip_subscription_mwi, 256))) { 08743 return -1; 08744 } 08745 08746 ASTOBJ_INIT(mwi); 08747 ast_string_field_set(mwi, username, username); 08748 if (secret) { 08749 ast_string_field_set(mwi, secret, secret); 08750 } 08751 if (authuser) { 08752 ast_string_field_set(mwi, authuser, authuser); 08753 } 08754 ast_string_field_set(mwi, hostname, hostname); 08755 ast_string_field_set(mwi, mailbox, mailbox); 08756 mwi->resub = -1; 08757 mwi->portno = portnum; 08758 mwi->transport = transport; 08759 08760 ASTOBJ_CONTAINER_LINK(&submwil, mwi); 08761 ASTOBJ_UNREF(mwi, sip_subscribe_mwi_destroy); 08762 08763 return 0; 08764 }
| static void sip_subscribe_mwi_destroy | ( | struct sip_subscription_mwi * | mwi | ) | [static] |
Destroy MWI subscription object.
Definition at line 6103 of file chan_sip.c.
References ast_free, AST_SCHED_DEL, ast_string_field_free_memory, and sip_destroy().
Referenced by __sip_subscribe_mwi_do(), handle_response_subscribe(), sip_send_all_mwi_subscriptions(), sip_subscribe_mwi(), sip_subscribe_mwi_do(), and unload_module().
06104 { 06105 if (mwi->call) { 06106 mwi->call->mwi = NULL; 06107 sip_destroy(mwi->call); 06108 } 06109 06110 AST_SCHED_DEL(sched, mwi->resub); 06111 ast_string_field_free_memory(mwi); 06112 ast_free(mwi); 06113 }
| static int sip_subscribe_mwi_do | ( | const void * | data | ) | [static] |
Send a subscription or resubscription for MWI.
Definition at line 12859 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().
12860 { 12861 struct sip_subscription_mwi *mwi = (struct sip_subscription_mwi*)data; 12862 12863 if (!mwi) { 12864 return -1; 12865 } 12866 12867 mwi->resub = -1; 12868 __sip_subscribe_mwi_do(mwi); 12869 ASTOBJ_UNREF(mwi, sip_subscribe_mwi_destroy); 12870 12871 return 0; 12872 }
| 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 22837 of file chan_sip.c.
References change_t38_state(), sip_pvt_lock, sip_pvt_unlock, and transmit_response_reliable().
Referenced by handle_request_invite().
22838 { 22839 struct sip_pvt *p = (struct sip_pvt *) data; 22840 22841 sip_pvt_lock(p); 22842 /* an application may have taken ownership of the T.38 negotiation on this 22843 * channel while we were waiting to grab the lock... if it did, the scheduler 22844 * id will have been reset to -1, which is our indication that we do *not* 22845 * want to abort the negotiation process 22846 */ 22847 if (p->t38id != -1) { 22848 change_t38_state(p, T38_DISABLED); 22849 transmit_response_reliable(p, "488 Not acceptable here", &p->initreq); 22850 p->t38id = -1; 22851 dialog_unref(p, "unref the dialog ptr from sip_t38_abort, because it held a dialog ptr"); 22852 } 22853 sip_pvt_unlock(p); 22854 return 0; 22855 }
| 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 26164 of file chan_sip.c.
References ao2_callback, ao2_ref, ao2_t_ref, and threadinfo_locate_cb().
Referenced by sip_prepare_socket().
26165 { 26166 struct sip_threadinfo *th; 26167 struct ast_tcptls_session_instance *tcptls_instance = NULL; 26168 26169 if ((th = ao2_callback(threadt, 0, threadinfo_locate_cb, s))) { 26170 tcptls_instance = (ao2_ref(th->tcptls_session, +1), th->tcptls_session); 26171 ao2_t_ref(th, -1, "decrement ref from callback"); 26172 } 26173 26174 return tcptls_instance; 26175 }
| static int sip_tcp_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 connection.
| req | The request structure to be filled in | |
| tcptls_session | The TCP connection from which to read |
| -1 | Failed to read data | |
| 0 | Successfully read data |
Definition at line 2818 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_wait_for_input(), check_message_integrity(), ast_tcptls_session_instance::client, 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().
02820 { 02821 enum message_integrity message_integrity = MESSAGE_FRAGMENT; 02822 02823 while (message_integrity == MESSAGE_FRAGMENT) { 02824 size_t datalen; 02825 02826 if (ast_str_strlen(tcptls_session->overflow_buf) == 0) { 02827 char readbuf[4097]; 02828 int timeout; 02829 int res; 02830 if (!tcptls_session->client && !authenticated) { 02831 if ((timeout = sip_check_authtimeout(start)) < 0) { 02832 return -1; 02833 } 02834 02835 if (timeout == 0) { 02836 ast_debug(2, "SIP TCP server timed out\n"); 02837 return -1; 02838 } 02839 } else { 02840 timeout = -1; 02841 } 02842 res = ast_wait_for_input(tcptls_session->fd, timeout); 02843 if (res < 0) { 02844 ast_debug(2, "SIP TCP server :: ast_wait_for_input returned %d\n", res); 02845 return -1; 02846 } else if (res == 0) { 02847 ast_debug(2, "SIP TCP server timed out\n"); 02848 return -1; 02849 } 02850 02851 res = recv(tcptls_session->fd, readbuf, sizeof(readbuf) - 1, 0); 02852 if (res < 0) { 02853 ast_debug(2, "SIP TCP server error when receiving data\n"); 02854 return -1; 02855 } else if (res == 0) { 02856 ast_debug(2, "SIP TCP server has shut down\n"); 02857 return -1; 02858 } 02859 readbuf[res] = '\0'; 02860 ast_str_append(&req->data, 0, "%s", readbuf); 02861 } else { 02862 ast_str_append(&req->data, 0, "%s", ast_str_buffer(tcptls_session->overflow_buf)); 02863 ast_str_reset(tcptls_session->overflow_buf); 02864 } 02865 02866 datalen = ast_str_strlen(req->data); 02867 if (datalen > SIP_MAX_PACKET_SIZE) { 02868 ast_log(LOG_WARNING, "Rejecting TCP packet from '%s' because way too large: %zu\n", 02869 ast_sockaddr_stringify(&tcptls_session->remote_address), datalen); 02870 return -1; 02871 } 02872 02873 message_integrity = check_message_integrity(&req->data, &tcptls_session->overflow_buf); 02874 } 02875 02876 return 0; 02877 }
| static void * sip_tcp_worker_fn | ( | void * | data | ) | [static] |
SIP TCP connection handler.
Definition at line 2476 of file chan_sip.c.
References _sip_tcp_helper_thread().
Referenced by sip_prepare_socket().
02477 { 02478 struct ast_tcptls_session_instance *tcptls_session = data; 02479 02480 return _sip_tcp_helper_thread(tcptls_session); 02481 }
| static void sip_tcptls_client_args_destructor | ( | void * | obj | ) | [static] |
Definition at line 2356 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().
02357 { 02358 struct ast_tcptls_session_args *args = obj; 02359 if (args->tls_cfg) { 02360 ast_free(args->tls_cfg->certfile); 02361 ast_free(args->tls_cfg->pvtfile); 02362 ast_free(args->tls_cfg->cipher); 02363 ast_free(args->tls_cfg->cafile); 02364 ast_free(args->tls_cfg->capath); 02365 02366 ast_ssl_teardown(args->tls_cfg); 02367 } 02368 ast_free(args->tls_cfg); 02369 ast_free((char *) args->name); 02370 }
| 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 2418 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().
02419 { 02420 int res = len; 02421 struct sip_threadinfo *th = NULL; 02422 struct tcptls_packet *packet = NULL; 02423 struct sip_threadinfo tmp = { 02424 .tcptls_session = tcptls_session, 02425 }; 02426 enum sip_tcptls_alert alert = TCPTLS_ALERT_DATA; 02427 02428 if (!tcptls_session) { 02429 return XMIT_ERROR; 02430 } 02431 02432 ast_mutex_lock(&tcptls_session->lock); 02433 02434 if ((tcptls_session->fd == -1) || 02435 !(th = ao2_t_find(threadt, &tmp, OBJ_POINTER, "ao2_find, getting sip_threadinfo in tcp helper thread")) || 02436 !(packet = ao2_alloc(sizeof(*packet), tcptls_packet_destructor)) || 02437 !(packet->data = ast_str_create(len))) { 02438 goto tcptls_write_setup_error; 02439 } 02440 02441 /* goto tcptls_write_error should _NOT_ be used beyond this point */ 02442 ast_str_set(&packet->data, 0, "%s", (char *) buf); 02443 packet->len = len; 02444 02445 /* alert tcptls thread handler that there is a packet to be sent. 02446 * must lock the thread info object to guarantee control of the 02447 * packet queue */ 02448 ao2_lock(th); 02449 if (write(th->alert_pipe[1], &alert, sizeof(alert)) == -1) { 02450 ast_log(LOG_ERROR, "write() to alert pipe failed: %s\n", strerror(errno)); 02451 ao2_t_ref(packet, -1, "could not write to alert pipe, remove packet"); 02452 packet = NULL; 02453 res = XMIT_ERROR; 02454 } else { /* it is safe to queue the frame after issuing the alert when we hold the threadinfo lock */ 02455 AST_LIST_INSERT_TAIL(&th->packet_q, packet, entry); 02456 } 02457 ao2_unlock(th); 02458 02459 ast_mutex_unlock(&tcptls_session->lock); 02460 ao2_t_ref(th, -1, "In sip_tcptls_write, unref threadinfo object after finding it"); 02461 return res; 02462 02463 tcptls_write_setup_error: 02464 if (th) { 02465 ao2_t_ref(th, -1, "In sip_tcptls_write, unref threadinfo obj, could not create packet"); 02466 } 02467 if (packet) { 02468 ao2_t_ref(packet, -1, "could not allocate packet's data"); 02469 } 02470 ast_mutex_unlock(&tcptls_session->lock); 02471 02472 return XMIT_ERROR; 02473 }
| 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 2394 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().
02395 { 02396 struct sip_threadinfo *th; 02397 02398 if (!tcptls_session || !(th = ao2_alloc(sizeof(*th), sip_threadinfo_destructor))) { 02399 return NULL; 02400 } 02401 02402 th->alert_pipe[0] = th->alert_pipe[1] = -1; 02403 02404 if (pipe(th->alert_pipe) == -1) { 02405 ao2_t_ref(th, -1, "Failed to open alert pipe on sip_threadinfo"); 02406 ast_log(LOG_ERROR, "Could not create sip alert pipe in tcptls thread, error %s\n", strerror(errno)); 02407 return NULL; 02408 } 02409 ao2_t_ref(tcptls_session, +1, "tcptls_session ref for sip_threadinfo object"); 02410 th->tcptls_session = tcptls_session; 02411 th->type = transport ? transport : (tcptls_session->ssl ? SIP_TRANSPORT_TLS: SIP_TRANSPORT_TCP); 02412 ao2_t_link(threadt, th, "Adding new tcptls helper thread"); 02413 ao2_t_ref(th, -1, "Decrementing threadinfo ref from alloc, only table ref remains"); 02414 return th; 02415 }
| static void sip_threadinfo_destructor | ( | void * | obj | ) | [static] |
Definition at line 2372 of file chan_sip.c.
References ao2_t_ref, and AST_LIST_REMOVE_HEAD.
Referenced by sip_threadinfo_create().
02373 { 02374 struct sip_threadinfo *th = obj; 02375 struct tcptls_packet *packet; 02376 if (th->alert_pipe[1] > -1) { 02377 close(th->alert_pipe[0]); 02378 } 02379 if (th->alert_pipe[1] > -1) { 02380 close(th->alert_pipe[1]); 02381 } 02382 th->alert_pipe[0] = th->alert_pipe[1] = -1; 02383 02384 while ((packet = AST_LIST_REMOVE_HEAD(&th->packet_q, entry))) { 02385 ao2_t_ref(packet, -1, "thread destruction, removing packet from frame queue"); 02386 } 02387 02388 if (th->tcptls_session) { 02389 ao2_t_ref(th->tcptls_session, -1, "remove tcptls_session for sip_threadinfo object"); 02390 } 02391 }
| static int sip_tls_read | ( | struct sip_request * | req, | |
| struct sip_request * | reqcpy, | |||
| struct ast_tcptls_session_instance * | tcptls_session, | |||
| int | authenticated, | |||
| time_t | start, | |||
| struct sip_threadinfo * | me | |||
| ) | [static] |
Read a SIP request or response from a TLS connection.
Because TLS operations are hidden from view via a FILE handle, the logic for reading data is a bit complex, and we have to make periodic checks to be sure we aren't taking too long to perform the necessary action.
| req | The request structure to fill in | |
| tcptls_session | The TLS connection on which the data is being received | |
| authenticated | A flag indicating whether authentication has occurred yet. This is only relevant in a server role. | |
| start | The time at which we started attempting to read data. Used in determining if there has been a timeout. | |
| me | Thread info. Used as a means of determining if the session needs to be stoppped. |
| -1 | Failed to read data | |
| 0 | Succeeded in reading data |
Definition at line 2528 of file chan_sip.c.
References ast_debug, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_sockaddr_stringify(), ast_str_append(), ast_str_strlen(), ast_wait_for_input(), ast_tcptls_session_instance::client, copy_request(), ast_tcptls_session_instance::f, ast_tcptls_session_instance::fd, get_header(), ast_tcptls_session_instance::lock, LOG_WARNING, MIN, parse_request(), ast_tcptls_session_instance::remote_address, and sip_check_authtimeout().
Referenced by _sip_tcp_helper_thread().
02530 { 02531 int res, content_length, after_poll = 1, need_poll = 1; 02532 size_t datalen = ast_str_strlen(req->data); 02533 char buf[1024] = ""; 02534 int timeout = -1; 02535 02536 /* Read in headers one line at a time */ 02537 while (datalen < 4 || strncmp(REQ_OFFSET_TO_STR(req, data->used - 4), "\r\n\r\n", 4)) { 02538 if (!tcptls_session->client && !authenticated) { 02539 if ((timeout = sip_check_authtimeout(start)) < 0) { 02540 ast_debug(2, "SIP TLS server failed to determine authentication timeout\n"); 02541 return -1; 02542 } 02543 02544 if (timeout == 0) { 02545 ast_debug(2, "SIP TLS server timed out\n"); 02546 return -1; 02547 } 02548 } else { 02549 timeout = -1; 02550 } 02551 02552 /* special polling behavior is required for TLS 02553 * sockets because of the buffering done in the 02554 * TLS layer */ 02555 if (need_poll) { 02556 need_poll = 0; 02557 after_poll = 1; 02558 res = ast_wait_for_input(tcptls_session->fd, timeout); 02559 if (res < 0) { 02560 ast_debug(2, "SIP TLS server :: ast_wait_for_input returned %d\n", res); 02561 return -1; 02562 } else if (res == 0) { 02563 /* timeout */ 02564 ast_debug(2, "SIP TLS server timed out\n"); 02565 return -1; 02566 } 02567 } 02568 02569 ast_mutex_lock(&tcptls_session->lock); 02570 if (!fgets(buf, sizeof(buf), tcptls_session->f)) { 02571 ast_mutex_unlock(&tcptls_session->lock); 02572 if (after_poll) { 02573 return -1; 02574 } else { 02575 need_poll = 1; 02576 continue; 02577 } 02578 } 02579 ast_mutex_unlock(&tcptls_session->lock); 02580 after_poll = 0; 02581 if (me->stop) { 02582 return -1; 02583 } 02584 ast_str_append(&req->data, 0, "%s", buf); 02585 02586 datalen = ast_str_strlen(req->data); 02587 if (datalen > SIP_MAX_PACKET_SIZE) { 02588 ast_log(LOG_WARNING, "Rejecting TLS packet from '%s' because way too large: %zu\n", 02589 ast_sockaddr_stringify(&tcptls_session->remote_address), datalen); 02590 return -1; 02591 } 02592 } 02593 copy_request(reqcpy, req); 02594 parse_request(reqcpy); 02595 /* In order to know how much to read, we need the content-length header */ 02596 if (sscanf(get_header(reqcpy, "Content-Length"), "%30d", &content_length)) { 02597 while (content_length > 0) { 02598 size_t bytes_read; 02599 if (!tcptls_session->client && !authenticated) { 02600 if ((timeout = sip_check_authtimeout(start)) < 0) { 02601 return -1; 02602 } 02603 02604 if (timeout == 0) { 02605 ast_debug(2, "SIP TLS server timed out\n"); 02606 return -1; 02607 } 02608 } else { 02609 timeout = -1; 02610 } 02611 02612 if (need_poll) { 02613 need_poll = 0; 02614 after_poll = 1; 02615 res = ast_wait_for_input(tcptls_session->fd, timeout); 02616 if (res < 0) { 02617 ast_debug(2, "SIP TLS server :: ast_wait_for_input returned %d\n", res); 02618 return -1; 02619 } else if (res == 0) { 02620 /* timeout */ 02621 ast_debug(2, "SIP TLS server timed out\n"); 02622 return -1; 02623 } 02624 } 02625 02626 ast_mutex_lock(&tcptls_session->lock); 02627 if (!(bytes_read = fread(buf, 1, MIN(sizeof(buf) - 1, content_length), tcptls_session->f))) { 02628 ast_mutex_unlock(&tcptls_session->lock); 02629 if (after_poll) { 02630 return -1; 02631 } else { 02632 need_poll = 1; 02633 continue; 02634 } 02635 } 02636 buf[bytes_read] = '\0'; 02637 ast_mutex_unlock(&tcptls_session->lock); 02638 after_poll = 0; 02639 if (me->stop) { 02640 return -1; 02641 } 02642 content_length -= strlen(buf); 02643 ast_str_append(&req->data, 0, "%s", buf); 02644 02645 datalen = ast_str_strlen(req->data); 02646 if (datalen > SIP_MAX_PACKET_SIZE) { 02647 ast_log(LOG_WARNING, "Rejecting TLS packet from '%s' because way too large: %zu\n", 02648 ast_sockaddr_stringify(&tcptls_session->remote_address), datalen); 02649 return -1; 02650 } 02651 } 02652 } 02653 /*! \todo XXX If there's no Content-Length or if the content-length and what 02654 we receive is not the same - we should generate an error */ 02655 return 0; 02656 }
| static int sip_transfer | ( | struct ast_channel * | ast, | |
| const char * | dest | |||
| ) | [static] |
Transfer SIP call.
Definition at line 7093 of file chan_sip.c.
References ast_channel::_state, AST_STATE_RING, sip_pvt_lock, sip_pvt_unlock, sip_sipredirect(), ast_channel::tech_pvt, and transmit_refer().
07094 { 07095 struct sip_pvt *p = ast->tech_pvt; 07096 int res; 07097 07098 if (dest == NULL) /* functions below do not take a NULL */ 07099 dest = ""; 07100 sip_pvt_lock(p); 07101 if (ast->_state == AST_STATE_RING) 07102 res = sip_sipredirect(p, dest); 07103 else 07104 res = transmit_refer(p, dest); 07105 sip_pvt_unlock(p); 07106 return res; 07107 }
| 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 18544 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.
18545 { 18546 struct sip_peer *peer; 18547 int load_realtime = 0; 18548 18549 switch (cmd) { 18550 case CLI_INIT: 18551 e->command = "sip unregister"; 18552 e->usage = 18553 "Usage: sip unregister <peer>\n" 18554 " Unregister (force expiration) a SIP peer from the registry\n"; 18555 return NULL; 18556 case CLI_GENERATE: 18557 return complete_sip_unregister(a->line, a->word, a->pos, a->n); 18558 } 18559 18560 if (a->argc != 3) 18561 return CLI_SHOWUSAGE; 18562 18563 if ((peer = find_peer(a->argv[2], NULL, load_realtime, FINDPEERS, TRUE, 0))) { 18564 if (peer->expire > 0) { 18565 AST_SCHED_DEL_UNREF(sched, peer->expire, 18566 unref_peer(peer, "remove register expire ref")); 18567 expire_register(ref_peer(peer, "ref for expire_register")); 18568 ast_cli(a->fd, "Unregistered peer \'%s\'\n\n", a->argv[2]); 18569 } else { 18570 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]); 18571 } 18572 unref_peer(peer, "sip_unregister: unref_peer via sip_unregister: done with peer from find_peer call"); 18573 } else { 18574 ast_cli(a->fd, "Peer unknown: \'%s\'. Not unregistered.\n", a->argv[2]); 18575 } 18576 18577 return CLI_SUCCESS; 18578 }
| static void sip_unregister_tests | ( | void | ) | [static] |
SIP test registration.
Definition at line 30752 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().
30753 { 30754 sip_config_parser_unregister_tests(); 30755 sip_request_parser_unregister_tests(); 30756 sip_dialplan_function_unregister_tests(); 30757 }
| static int sip_write | ( | struct ast_channel * | ast, | |
| struct ast_frame * | frame | |||
| ) | [static] |
Send frame to media channel (rtp).
Definition at line 6895 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.
06896 { 06897 struct sip_pvt *p = ast->tech_pvt; 06898 int res = 0; 06899 06900 switch (frame->frametype) { 06901 case AST_FRAME_VOICE: 06902 if (!(frame->subclass.codec & ast->nativeformats)) { 06903 char s1[512], s2[512], s3[512]; 06904 ast_log(LOG_WARNING, "Asked to transmit frame type %s, while native formats is %s read/write = %s/%s\n", 06905 ast_getformatname(frame->subclass.codec), 06906 ast_getformatname_multiple(s1, sizeof(s1), ast->nativeformats & AST_FORMAT_AUDIO_MASK), 06907 ast_getformatname_multiple(s2, sizeof(s2), ast->readformat), 06908 ast_getformatname_multiple(s3, sizeof(s3), ast->writeformat)); 06909 return 0; 06910 } 06911 if (p) { 06912 sip_pvt_lock(p); 06913 if (p->t38.state == T38_ENABLED) { 06914 /* drop frame, can't sent VOICE frames while in T.38 mode */ 06915 sip_pvt_unlock(p); 06916 break; 06917 } else if (p->rtp) { 06918 /* If channel is not up, activate early media session */ 06919 if ((ast->_state != AST_STATE_UP) && 06920 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 06921 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06922 ast_rtp_instance_update_source(p->rtp); 06923 if (!global_prematuremediafilter) { 06924 p->invitestate = INV_EARLY_MEDIA; 06925 transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE); 06926 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 06927 } 06928 } 06929 p->lastrtptx = time(NULL); 06930 res = ast_rtp_instance_write(p->rtp, frame); 06931 } 06932 sip_pvt_unlock(p); 06933 } 06934 break; 06935 case AST_FRAME_VIDEO: 06936 if (p) { 06937 sip_pvt_lock(p); 06938 if (p->vrtp) { 06939 /* Activate video early media */ 06940 if ((ast->_state != AST_STATE_UP) && 06941 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 06942 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06943 p->invitestate = INV_EARLY_MEDIA; 06944 transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE); 06945 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 06946 } 06947 p->lastrtptx = time(NULL); 06948 res = ast_rtp_instance_write(p->vrtp, frame); 06949 } 06950 sip_pvt_unlock(p); 06951 } 06952 break; 06953 case AST_FRAME_TEXT: 06954 if (p) { 06955 sip_pvt_lock(p); 06956 if (p->red) { 06957 ast_rtp_red_buffer(p->trtp, frame); 06958 } else { 06959 if (p->trtp) { 06960 /* Activate text early media */ 06961 if ((ast->_state != AST_STATE_UP) && 06962 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 06963 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06964 p->invitestate = INV_EARLY_MEDIA; 06965 transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE); 06966 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 06967 } 06968 p->lastrtptx = time(NULL); 06969 res = ast_rtp_instance_write(p->trtp, frame); 06970 } 06971 } 06972 sip_pvt_unlock(p); 06973 } 06974 break; 06975 case AST_FRAME_IMAGE: 06976 return 0; 06977 break; 06978 case AST_FRAME_MODEM: 06979 if (p) { 06980 sip_pvt_lock(p); 06981 /* UDPTL requires two-way communication, so early media is not needed here. 06982 we simply forget the frames if we get modem frames before the bridge is up. 06983 Fax will re-transmit. 06984 */ 06985 if ((ast->_state == AST_STATE_UP) && 06986 p->udptl && 06987 (p->t38.state == T38_ENABLED)) { 06988 res = ast_udptl_write(p->udptl, frame); 06989 } 06990 sip_pvt_unlock(p); 06991 } 06992 break; 06993 default: 06994 ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype); 06995 return 0; 06996 } 06997 06998 return res; 06999 }
| static int sipsock_read | ( | int * | id, | |
| int | fd, | |||
| short | events, | |||
| void * | ignore | |||
| ) | [static] |
Read data from SIP UDP socket.
Definition at line 26010 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().
26011 { 26012 struct sip_request req; 26013 struct ast_sockaddr addr; 26014 int res; 26015 static char readbuf[65535]; 26016 26017 memset(&req, 0, sizeof(req)); 26018 res = ast_recvfrom(fd, readbuf, sizeof(readbuf) - 1, 0, &addr); 26019 if (res < 0) { 26020 #if !defined(__FreeBSD__) 26021 if (errno == EAGAIN) 26022 ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n"); 26023 else 26024 #endif 26025 if (errno != ECONNREFUSED) 26026 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 26027 return 1; 26028 } 26029 26030 readbuf[res] = '\0'; 26031 26032 if (!(req.data = ast_str_create(SIP_MIN_PACKET))) { 26033 return 1; 26034 } 26035 26036 if (ast_str_set(&req.data, 0, "%s", readbuf) == AST_DYNSTR_BUILD_FAILED) { 26037 return -1; 26038 } 26039 26040 req.socket.fd = sipsock; 26041 set_socket_transport(&req.socket, SIP_TRANSPORT_UDP); 26042 req.socket.tcptls_session = NULL; 26043 req.socket.port = htons(ast_sockaddr_port(&bindaddr)); 26044 26045 handle_request_do(&req, &addr); 26046 deinit_req(&req); 26047 26048 return 1; 26049 }
| static int sockaddr_is_null_or_any | ( | const struct ast_sockaddr * | addr | ) | [static] |
Definition at line 9201 of file chan_sip.c.
References ast_sockaddr_is_any(), and ast_sockaddr_isnull().
Referenced by process_sdp().
09202 { 09203 return ast_sockaddr_isnull(addr) || ast_sockaddr_is_any(addr); 09204 }
| 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 26935 of file chan_sip.c.
References sip_st_alloc().
Referenced by add_supported_header(), handle_request_invite(), handle_response_invite(), and transmit_invite().
26936 { 26937 if (!p->stimer) { 26938 sip_st_alloc(p); 26939 if (!p->stimer) { 26940 return SESSION_TIMER_MODE_INVALID; 26941 } 26942 } 26943 26944 if (!no_cached && p->stimer->st_cached_mode != SESSION_TIMER_MODE_INVALID) 26945 return p->stimer->st_cached_mode; 26946 26947 if (p->relatedpeer) { 26948 p->stimer->st_cached_mode = p->relatedpeer->stimer.st_mode_oper; 26949 return p->stimer->st_cached_mode; 26950 } 26951 26952 p->stimer->st_cached_mode = global_st_mode; 26953 return global_st_mode; 26954 }
| 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 26913 of file chan_sip.c.
Referenced by handle_request_invite().
26914 { 26915 if (p->stimer->st_cached_ref != SESSION_TIMER_REFRESHER_AUTO) { 26916 return p->stimer->st_cached_ref; 26917 } 26918 26919 if (p->relatedpeer) { 26920 p->stimer->st_cached_ref = (p->relatedpeer->stimer.st_ref == SESSION_TIMER_REFRESHER_PARAM_UAC) ? SESSION_TIMER_REFRESHER_THEM : SESSION_TIMER_REFRESHER_US; 26921 return p->stimer->st_cached_ref; 26922 } 26923 26924 p->stimer->st_cached_ref = (global_st_refresher == SESSION_TIMER_REFRESHER_PARAM_UAC) ? SESSION_TIMER_REFRESHER_THEM : SESSION_TIMER_REFRESHER_US; 26925 return p->stimer->st_cached_ref; 26926 }
| 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 26881 of file chan_sip.c.
References TRUE.
Referenced by handle_request_invite(), handle_response_invite(), reqprep(), and transmit_invite().
26882 { 26883 if (max == TRUE) { 26884 if (p->stimer->st_cached_max_se) { 26885 return p->stimer->st_cached_max_se; 26886 } 26887 if (p->relatedpeer) { 26888 p->stimer->st_cached_max_se = p->relatedpeer->stimer.st_max_se; 26889 return (p->stimer->st_cached_max_se); 26890 } 26891 p->stimer->st_cached_max_se = global_max_se; 26892 return (p->stimer->st_cached_max_se); 26893 } 26894 /* Find Min SE timer */ 26895 if (p->stimer->st_cached_min_se) { 26896 return p->stimer->st_cached_min_se; 26897 } 26898 if (p->relatedpeer) { 26899 p->stimer->st_cached_min_se = p->relatedpeer->stimer.st_min_se; 26900 return (p->stimer->st_cached_min_se); 26901 } 26902 p->stimer->st_cached_min_se = global_min_se; 26903 return (p->stimer->st_cached_min_se); 26904 }
| static void start_session_timer | ( | struct sip_pvt * | p | ) | [static] |
Session-Timers: Start session timer.
Definition at line 26676 of file chan_sip.c.
References ast_debug, ast_log(), ast_sched_add(), AST_SCHED_DEL_UNREF, LOG_ERROR, LOG_WARNING, proc_session_timer(), and TRUE.
Referenced by handle_request_invite(), handle_response_invite(), and restart_session_timer().
26677 { 26678 if (!p->stimer) { 26679 ast_log(LOG_WARNING, "Null stimer in start_session_timer - %s\n", p->callid); 26680 return; 26681 } 26682 26683 if (p->stimer->st_schedid > -1) { 26684 /* in the event a timer is already going, stop it */ 26685 ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid); 26686 AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid, 26687 dialog_unref(p, "unref stimer->st_schedid from dialog")); 26688 } 26689 26690 p->stimer->st_schedid = ast_sched_add(sched, p->stimer->st_interval * 1000 / 2, proc_session_timer, 26691 dialog_ref(p, "adding session timer ref")); 26692 if (p->stimer->st_schedid < 0) { 26693 dialog_unref(p, "removing session timer ref"); 26694 ast_log(LOG_ERROR, "ast_sched_add failed - %s\n", p->callid); 26695 } else { 26696 p->stimer->st_active = TRUE; 26697 ast_debug(2, "Session timer started: %d - %s\n", p->stimer->st_schedid, p->callid); 26698 } 26699 }
| 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 13045 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_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, 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().
13046 { 13047 enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN; 13048 const char *statestring = "terminated"; 13049 const char *pidfstate = "--"; 13050 const char *pidfnote= "Ready"; 13051 char hint[AST_MAX_EXTENSION]; 13052 13053 switch (state) { 13054 case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE): 13055 statestring = (sip_cfg.notifyringing) ? "early" : "confirmed"; 13056 local_state = NOTIFY_INUSE; 13057 pidfstate = "busy"; 13058 pidfnote = "Ringing"; 13059 break; 13060 case AST_EXTENSION_RINGING: 13061 statestring = "early"; 13062 local_state = NOTIFY_INUSE; 13063 pidfstate = "busy"; 13064 pidfnote = "Ringing"; 13065 break; 13066 case AST_EXTENSION_INUSE: 13067 statestring = "confirmed"; 13068 local_state = NOTIFY_INUSE; 13069 pidfstate = "busy"; 13070 pidfnote = "On the phone"; 13071 break; 13072 case AST_EXTENSION_BUSY: 13073 statestring = "confirmed"; 13074 local_state = NOTIFY_CLOSED; 13075 pidfstate = "busy"; 13076 pidfnote = "On the phone"; 13077 break; 13078 case AST_EXTENSION_UNAVAILABLE: 13079 statestring = "terminated"; 13080 local_state = NOTIFY_CLOSED; 13081 pidfstate = "away"; 13082 pidfnote = "Unavailable"; 13083 break; 13084 case AST_EXTENSION_ONHOLD: 13085 statestring = "confirmed"; 13086 local_state = NOTIFY_CLOSED; 13087 pidfstate = "busy"; 13088 pidfnote = "On hold"; 13089 break; 13090 case AST_EXTENSION_NOT_INUSE: 13091 default: 13092 /* Default setting */ 13093 break; 13094 } 13095 13096 /* Check which device/devices we are watching and if they are registered */ 13097 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten)) { 13098 char *hint2 = hint, *individual_hint = NULL; 13099 int hint_count = 0, unavailable_count = 0; 13100 13101 while ((individual_hint = strsep(&hint2, "&"))) { 13102 hint_count++; 13103 13104 if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE) 13105 unavailable_count++; 13106 } 13107 13108 /* If none of the hinted devices are registered, we will 13109 * override notification and show no availability. 13110 */ 13111 if (hint_count > 0 && hint_count == unavailable_count) { 13112 local_state = NOTIFY_CLOSED; 13113 pidfstate = "away"; 13114 pidfnote = "Not online"; 13115 } 13116 } 13117 13118 switch (subscribed) { 13119 case XPIDF_XML: 13120 case CPIM_PIDF_XML: 13121 ast_str_append(tmp, 0, 13122 "<?xml version=\"1.0\"?>\n" 13123 "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n" 13124 "<presence>\n"); 13125 ast_str_append(tmp, 0, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom); 13126 ast_str_append(tmp, 0, "<atom id=\"%s\">\n", exten); 13127 ast_str_append(tmp, 0, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto); 13128 ast_str_append(tmp, 0, "<status status=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed"); 13129 ast_str_append(tmp, 0, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline"); 13130 ast_str_append(tmp, 0, "</address>\n</atom>\n</presence>\n"); 13131 break; 13132 case PIDF_XML: /* Eyebeam supports this format */ 13133 ast_str_append(tmp, 0, 13134 "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n" 13135 "<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); 13136 ast_str_append(tmp, 0, "<pp:person><status>\n"); 13137 if (pidfstate[0] != '-') { 13138 ast_str_append(tmp, 0, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate); 13139 } 13140 ast_str_append(tmp, 0, "</status></pp:person>\n"); 13141 ast_str_append(tmp, 0, "<note>%s</note>\n", pidfnote); /* Note */ 13142 ast_str_append(tmp, 0, "<tuple id=\"%s\">\n", exten); /* Tuple start */ 13143 ast_str_append(tmp, 0, "<contact priority=\"1\">%s</contact>\n", mto); 13144 if (pidfstate[0] == 'b') /* Busy? Still open ... */ 13145 ast_str_append(tmp, 0, "<status><basic>open</basic></status>\n"); 13146 else 13147 ast_str_append(tmp, 0, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed"); 13148 ast_str_append(tmp, 0, "</tuple>\n</presence>\n"); 13149 break; 13150 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 13151 ast_str_append(tmp, 0, "<?xml version=\"1.0\"?>\n"); 13152 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); 13153 if ((state & AST_EXTENSION_RINGING) && sip_cfg.notifyringing) { 13154 /* Twice the extension length should be enough for XML encoding */ 13155 char local_display[AST_MAX_EXTENSION * 2]; 13156 char remote_display[AST_MAX_EXTENSION * 2]; 13157 char *local_target = ast_strdupa(mto); 13158 /* It may seem odd to base the remote_target on the To header here, 13159 * but testing by reporters on issue ASTERISK-16735 found that basing 13160 * on the From header would cause ringing state hints to not work 13161 * properly on certain SNOM devices. If you are using notifycid properly 13162 * (i.e. in the same extension and context as the dialed call) then this 13163 * should not be an issue since the data will be overwritten shortly 13164 * with channel caller ID 13165 */ 13166 char *remote_target = ast_strdupa(mto); 13167 13168 ast_xml_escape(exten, local_display, sizeof(local_display)); 13169 ast_xml_escape(exten, remote_display, sizeof(remote_display)); 13170 13171 /* There are some limitations to how this works. The primary one is that the 13172 callee must be dialing the same extension that is being monitored. Simply dialing 13173 the hint'd device is not sufficient. */ 13174 if (sip_cfg.notifycid) { 13175 struct ast_channel *caller; 13176 13177 if ((caller = ast_channel_callback(find_calling_channel, NULL, p, 0))) { 13178 char *cid_num; 13179 char *connected_num; 13180 int need; 13181 13182 ast_channel_lock(caller); 13183 cid_num = S_COR(caller->caller.id.number.valid, 13184 caller->caller.id.number.str, ""); 13185 need = strlen(cid_num) + strlen(p->fromdomain) + sizeof("sip:@"); 13186 remote_target = ast_alloca(need); 13187 snprintf(remote_target, need, "sip:%s@%s", cid_num, p->fromdomain); 13188 13189 ast_xml_escape(S_COR(caller->caller.id.name.valid, 13190 caller->caller.id.name.str, ""), 13191 remote_display, sizeof(remote_display)); 13192 13193 connected_num = S_COR(caller->connected.id.number.valid, 13194 caller->connected.id.number.str, ""); 13195 need = strlen(connected_num) + strlen(p->fromdomain) + sizeof("sip:@"); 13196 local_target = ast_alloca(need); 13197 snprintf(local_target, need, "sip:%s@%s", connected_num, p->fromdomain); 13198 13199 ast_xml_escape(S_COR(caller->connected.id.name.valid, 13200 caller->connected.id.name.str, ""), 13201 local_display, sizeof(local_display)); 13202 13203 ast_channel_unlock(caller); 13204 caller = ast_channel_unref(caller); 13205 } 13206 13207 /* We create a fake call-id which the phone will send back in an INVITE 13208 Replaces header which we can grab and do some magic with. */ 13209 if (sip_cfg.pedanticsipchecking) { 13210 ast_str_append(tmp, 0, "<dialog id=\"%s\" call-id=\"pickup-%s\" local-tag=\"%s\" remote-tag=\"%s\" direction=\"recipient\">\n", 13211 exten, p->callid, p->theirtag, p->tag); 13212 } else { 13213 ast_str_append(tmp, 0, "<dialog id=\"%s\" call-id=\"pickup-%s\" direction=\"recipient\">\n", 13214 exten, p->callid); 13215 } 13216 ast_str_append(tmp, 0, 13217 "<remote>\n" 13218 /* See the limitations of this above. Luckily the phone seems to still be 13219 happy when these values are not correct. */ 13220 "<identity display=\"%s\">%s</identity>\n" 13221 "<target uri=\"%s\"/>\n" 13222 "</remote>\n" 13223 "<local>\n" 13224 "<identity display=\"%s\">%s</identity>\n" 13225 "<target uri=\"%s\"/>\n" 13226 "</local>\n", 13227 remote_display, remote_target, remote_target, local_display, local_target, local_target); 13228 } else { 13229 ast_str_append(tmp, 0, "<dialog id=\"%s\" direction=\"recipient\">\n", exten); 13230 } 13231 13232 } else { 13233 ast_str_append(tmp, 0, "<dialog id=\"%s\">\n", exten); 13234 } 13235 ast_str_append(tmp, 0, "<state>%s</state>\n", statestring); 13236 if (state == AST_EXTENSION_ONHOLD) { 13237 ast_str_append(tmp, 0, "<local>\n<target uri=\"%s\">\n" 13238 "<param pname=\"+sip.rendering\" pvalue=\"no\"/>\n" 13239 "</target>\n</local>\n", mto); 13240 } 13241 ast_str_append(tmp, 0, "</dialog>\n</dialog-info>\n"); 13242 break; 13243 case NONE: 13244 default: 13245 break; 13246 } 13247 }
| static const char* stmode2str | ( | enum st_mode | m | ) | [static] |
Definition at line 17037 of file chan_sip.c.
References map_x_s().
Referenced by _sip_show_peer(), sip_show_channel(), sip_show_settings(), and sip_show_user().
| static void stop_media_flows | ( | struct sip_pvt * | p | ) | [static] |
Immediately stop RTP, VRTP and UDPTL as applicable.
Definition at line 21638 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().
21639 { 21640 /* Immediately stop RTP, VRTP and UDPTL as applicable */ 21641 if (p->rtp) 21642 ast_rtp_instance_stop(p->rtp); 21643 if (p->vrtp) 21644 ast_rtp_instance_stop(p->vrtp); 21645 if (p->trtp) 21646 ast_rtp_instance_stop(p->trtp); 21647 if (p->udptl) 21648 ast_udptl_stop(p->udptl); 21649 }
| static void stop_session_timer | ( | struct sip_pvt * | p | ) | [static] |
Session-Timers: Stop session timer.
Definition at line 26659 of file chan_sip.c.
References ast_debug, ast_log(), AST_SCHED_DEL_UNREF, FALSE, LOG_WARNING, and TRUE.
Referenced by __sip_destroy(), dialog_unlink_all(), handle_request_bye(), proc_session_timer(), sip_hangup(), and sip_scheddestroy().
26660 { 26661 if (!p->stimer) { 26662 ast_log(LOG_WARNING, "Null stimer in stop_session_timer - %s\n", p->callid); 26663 return; 26664 } 26665 26666 if (p->stimer->st_active == TRUE) { 26667 p->stimer->st_active = FALSE; 26668 ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid); 26669 AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid, 26670 dialog_unref(p, "removing session timer ref")); 26671 } 26672 }
| static int str2dtmfmode | ( | const char * | str | ) | [static] |
| static enum st_mode str2stmode | ( | const char * | s | ) | [static] |
Definition at line 17042 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 17067 of file chan_sip.c.
References map_s_x().
Referenced by build_peer(), and reload_config().
17068 { 17069 return map_s_x(strefresher_params, s, -1); 17070 }
| static const char* strefresher2str | ( | enum st_refresher | r | ) | [static] |
Definition at line 17072 of file chan_sip.c.
References map_x_s().
Referenced by sip_show_channel().
17073 { 17074 return map_x_s(strefreshers, r, "Unknown"); 17075 }
| static const char * strefresherparam2str | ( | enum st_refresher | r | ) | [static] |
Definition at line 17062 of file chan_sip.c.
References map_x_s().
Referenced by _sip_show_peer(), sip_show_channel(), sip_show_settings(), and sip_show_user().
17063 { 17064 return map_x_s(strefresher_params, r, "Unknown"); 17065 }
| static const char * subscription_type2str | ( | enum subscriptiontype | subtype | ) | [static] |
Show subscription type in string format.
Definition at line 18940 of file chan_sip.c.
References ARRAY_LEN, subscription_types, cfsubscription_types::text, and type.
Referenced by show_channels_cb(), and sip_show_channel().
18941 { 18942 int i; 18943 18944 for (i = 1; i < ARRAY_LEN(subscription_types); i++) { 18945 if (subscription_types[i].type == subtype) { 18946 return subscription_types[i].text; 18947 } 18948 } 18949 return subscription_types[0].text; 18950 }
| 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 11589 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().
11590 { 11591 switch (rate) { 11592 case AST_T38_RATE_2400: 11593 return 2400; 11594 case AST_T38_RATE_4800: 11595 return 4800; 11596 case AST_T38_RATE_7200: 11597 return 7200; 11598 case AST_T38_RATE_9600: 11599 return 9600; 11600 case AST_T38_RATE_12000: 11601 return 12000; 11602 case AST_T38_RATE_14400: 11603 return 14400; 11604 default: 11605 return 0; 11606 } 11607 }
| static void tcptls_packet_destructor | ( | void * | obj | ) | [static] |
Definition at line 2349 of file chan_sip.c.
References ast_free.
Referenced by sip_tcptls_write().
02350 { 02351 struct tcptls_packet *packet = obj; 02352 02353 ast_free(packet->data); 02354 }
| static struct sip_peer * temp_peer | ( | const char * | name | ) | [static, read] |
Create temporary peer (used in autocreatepeer mode).
Definition at line 27887 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().
27888 { 27889 struct sip_peer *peer; 27890 27891 if (!(peer = ao2_t_alloc(sizeof(*peer), sip_destroy_peer_fn, "allocate a peer struct"))) 27892 return NULL; 27893 27894 if (ast_string_field_init(peer, 512)) { 27895 ao2_t_ref(peer, -1, "failed to string_field_init, drop peer"); 27896 return NULL; 27897 } 27898 27899 if (!(peer->cc_params = ast_cc_config_params_init())) { 27900 ao2_t_ref(peer, -1, "failed to allocate cc_params for peer"); 27901 return NULL; 27902 } 27903 27904 ast_atomic_fetchadd_int(&apeerobjs, 1); 27905 set_peer_defaults(peer); 27906 27907 ast_copy_string(peer->name, name, sizeof(peer->name)); 27908 27909 peer->selfdestruct = TRUE; 27910 peer->host_dynamic = TRUE; 27911 peer->prefs = default_prefs; 27912 reg_source_db(peer); 27913 27914 return peer; 27915 }
| static void temp_pvt_cleanup | ( | void * | data | ) | [static] |
Definition at line 11039 of file chan_sip.c.
References ast_free, and ast_string_field_free_memory.
11040 { 11041 struct sip_pvt *p = data; 11042 11043 ast_string_field_free_memory(p); 11044 11045 ast_free(data); 11046 }
| static int temp_pvt_init | ( | void * | data | ) | [static] |
Definition at line 11031 of file chan_sip.c.
References ast_string_field_init.
11032 { 11033 struct sip_pvt *p = data; 11034 11035 p->do_history = 0; /* XXX do we need it ? isn't already all 0 ? */ 11036 return ast_string_field_init(p, 512); 11037 }
| 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 15272 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 26147 of file chan_sip.c.
References ast_sockaddr_cmp(), CMP_MATCH, and CMP_STOP.
Referenced by sip_tcp_locate().
26148 { 26149 struct sip_threadinfo *th = obj; 26150 struct ast_sockaddr *s = arg; 26151 26152 if (!ast_sockaddr_cmp(s, &th->tcptls_session->remote_address)) { 26153 return CMP_MATCH | CMP_STOP; 26154 } 26155 26156 return 0; 26157 }
| static int threadt_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 30679 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 30672 of file chan_sip.c.
References ast_sockaddr_hash().
Referenced by load_module().
30673 { 30674 const struct sip_threadinfo *th = obj; 30675 30676 return ast_sockaddr_hash(&th->tcptls_session->remote_address); 30677 }
| static char * transfermode2str | ( | enum transfermodes | mode | ) | [static] |
Convert transfer mode to text string.
Definition at line 17015 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 13249 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().
13250 { 13251 struct sip_request req; 13252 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 13253 char uri[SIPBUFSIZE]; 13254 char state_str[64]; 13255 char subscription_state_hdr[64]; 13256 13257 if (state < CC_QUEUED || state > CC_READY) { 13258 ast_log(LOG_WARNING, "Invalid state provided for transmit_cc_notify (%d)\n", state); 13259 return -1; 13260 } 13261 13262 reqprep(&req, subscription, SIP_NOTIFY, 0, TRUE); 13263 snprintf(state_str, sizeof(state_str), "%s\r\n", sip_cc_notify_state_map[state].state_string); 13264 add_header(&req, "Event", "call-completion"); 13265 add_header(&req, "Content-Type", "application/call-completion"); 13266 snprintf(subscription_state_hdr, sizeof(subscription_state_hdr), "active;expires=%d", subscription->expiry); 13267 add_header(&req, "Subscription-State", subscription_state_hdr); 13268 if (state == CC_READY) { 13269 generate_uri(subscription, agent_pvt->notify_uri, sizeof(agent_pvt->notify_uri)); 13270 snprintf(uri, sizeof(uri) - 1, "cc-URI: %s\r\n", agent_pvt->notify_uri); 13271 } 13272 add_content(&req, state_str); 13273 if (state == CC_READY) { 13274 add_content(&req, uri); 13275 } 13276 return send_request(subscription, &req, XMIT_RELIABLE, subscription->ocseq); 13277 }
| 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 15171 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().
15172 { 15173 /* We have to emulate EXACTLY what we'd get with a good peer 15174 * and a bad password, or else we leak information. */ 15175 const char *response = "401 Unauthorized"; 15176 const char *reqheader = "Authorization"; 15177 const char *respheader = "WWW-Authenticate"; 15178 const char *authtoken; 15179 struct ast_str *buf; 15180 char *c; 15181 15182 /* table of recognised keywords, and their value in the digest */ 15183 enum keys { K_NONCE, K_LAST }; 15184 struct x { 15185 const char *key; 15186 const char *s; 15187 } *i, keys[] = { 15188 [K_NONCE] = { "nonce=", "" }, 15189 [K_LAST] = { NULL, NULL} 15190 }; 15191 15192 authtoken = get_header(req, reqheader); 15193 if (req->ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 15194 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 15195 * information */ 15196 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 15197 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 15198 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15199 return; 15200 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 15201 /* We have no auth, so issue challenge and request authentication */ 15202 set_nonce_randdata(p, 1); 15203 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 15204 /* Schedule auto destroy in 32 seconds */ 15205 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15206 return; 15207 } 15208 15209 if (!(buf = ast_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) { 15210 __transmit_response(p, "403 Forbidden", &p->initreq, reliable); 15211 return; 15212 } 15213 15214 /* Make a copy of the response and parse it */ 15215 if (ast_str_set(&buf, 0, "%s", authtoken) == AST_DYNSTR_BUILD_FAILED) { 15216 __transmit_response(p, "403 Forbidden", &p->initreq, reliable); 15217 return; 15218 } 15219 15220 c = buf->str; 15221 15222 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 15223 for (i = keys; i->key != NULL; i++) { 15224 const char *separator = ","; /* default */ 15225 15226 if (strncasecmp(c, i->key, strlen(i->key)) != 0) { 15227 continue; 15228 } 15229 /* Found. Skip keyword, take text in quotes or up to the separator. */ 15230 c += strlen(i->key); 15231 if (*c == '"') { /* in quotes. Skip first and look for last */ 15232 c++; 15233 separator = "\""; 15234 } 15235 i->s = c; 15236 strsep(&c, separator); 15237 break; 15238 } 15239 if (i->key == NULL) { /* not found, jump after space or comma */ 15240 strsep(&c, " ,"); 15241 } 15242 } 15243 15244 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 15245 if (strcasecmp(p->randdata, keys[K_NONCE].s)) { 15246 if (!req->ignore) { 15247 set_nonce_randdata(p, 1); 15248 } 15249 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 15250 15251 /* Schedule auto destroy in 32 seconds */ 15252 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15253 } else { 15254 __transmit_response(p, "403 Forbidden", &p->initreq, reliable); 15255 } 15256 }
| 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 14086 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().
14087 { 14088 struct sip_request req; 14089 struct ast_str *str = ast_str_alloca(512); 14090 const struct ast_aoc_unit_entry *unit_entry = ast_aoc_get_unit_info(decoded, 0); 14091 enum ast_aoc_charge_type charging = ast_aoc_get_charge_type(decoded); 14092 14093 reqprep(&req, p, SIP_INFO, 0, 1); 14094 14095 if (ast_aoc_get_msg_type(decoded) == AST_AOC_D) { 14096 ast_str_append(&str, 0, "type=active;"); 14097 } else if (ast_aoc_get_msg_type(decoded) == AST_AOC_E) { 14098 ast_str_append(&str, 0, "type=terminated;"); 14099 } else { 14100 /* unsupported message type */ 14101 return -1; 14102 } 14103 14104 switch (charging) { 14105 case AST_AOC_CHARGE_FREE: 14106 ast_str_append(&str, 0, "free-of-charge;"); 14107 break; 14108 case AST_AOC_CHARGE_CURRENCY: 14109 ast_str_append(&str, 0, "charging;"); 14110 ast_str_append(&str, 0, "charging-info=currency;"); 14111 ast_str_append(&str, 0, "amount=%u;", ast_aoc_get_currency_amount(decoded)); 14112 ast_str_append(&str, 0, "multiplier=%s;", ast_aoc_get_currency_multiplier_decimal(decoded)); 14113 if (!ast_strlen_zero(ast_aoc_get_currency_name(decoded))) { 14114 ast_str_append(&str, 0, "currency=%s;", ast_aoc_get_currency_name(decoded)); 14115 } 14116 break; 14117 case AST_AOC_CHARGE_UNIT: 14118 ast_str_append(&str, 0, "charging;"); 14119 ast_str_append(&str, 0, "charging-info=pulse;"); 14120 if (unit_entry) { 14121 ast_str_append(&str, 0, "recorded-units=%u;", unit_entry->amount); 14122 } 14123 break; 14124 default: 14125 ast_str_append(&str, 0, "not-available;"); 14126 }; 14127 14128 add_header(&req, "AOC", ast_str_buffer(str)); 14129 14130 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 14131 }
| 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 14134 of file chan_sip.c.
References add_digit(), ast_test_flag, reqprep(), and send_request().
Referenced by sip_senddigit_end().
14135 { 14136 struct sip_request req; 14137 14138 reqprep(&req, p, SIP_INFO, 0, 1); 14139 add_digit(&req, digit, duration, (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_SHORTINFO)); 14140 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 14141 }
| static int transmit_info_with_vidupdate | ( | struct sip_pvt * | p | ) | [static] |
Send SIP INFO with video update request.
Definition at line 14144 of file chan_sip.c.
References add_vidupdate(), reqprep(), and send_request().
Referenced by sip_indicate().
14145 { 14146 struct sip_request req; 14147 14148 reqprep(&req, p, SIP_INFO, 0, 1); 14149 add_vidupdate(&req); 14150 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 14151 }
| 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 12689 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().
12690 { 12691 struct sip_request req; 12692 struct ast_variable *var; 12693 12694 if (init) {/* Bump branch even on initial requests */ 12695 p->branch ^= ast_random(); 12696 p->invite_branch = p->branch; 12697 build_via(p); 12698 } 12699 if (init > 1) { 12700 initreqprep(&req, p, sipmethod, explicit_uri); 12701 } else { 12702 /* If init=1, we should not generate a new branch. If it's 0, we need a new branch. */ 12703 reqprep(&req, p, sipmethod, 0, init ? 0 : 1); 12704 } 12705 12706 if (p->options && p->options->auth) { 12707 add_header(&req, p->options->authheader, p->options->auth); 12708 } 12709 append_date(&req); 12710 if (sipmethod == SIP_REFER) { /* Call transfer */ 12711 if (p->refer) { 12712 char buf[SIPBUFSIZE]; 12713 if (!ast_strlen_zero(p->refer->refer_to)) { 12714 add_header(&req, "Refer-To", p->refer->refer_to); 12715 } 12716 if (!ast_strlen_zero(p->refer->referred_by)) { 12717 snprintf(buf, sizeof(buf), "%s <%s>", p->refer->referred_by_name, p->refer->referred_by); 12718 add_header(&req, "Referred-By", buf); 12719 } 12720 } 12721 } else if (sipmethod == SIP_SUBSCRIBE) { 12722 char buf[SIPBUFSIZE]; 12723 if (p->subscribed == MWI_NOTIFICATION) { 12724 add_header(&req, "Event", "message-summary"); 12725 add_header(&req, "Accept", "application/simple-message-summary"); 12726 } else if (p->subscribed == CALL_COMPLETION) { 12727 add_header(&req, "Event", "call-completion"); 12728 add_header(&req, "Accept", "application/call-completion"); 12729 } 12730 snprintf(buf, sizeof(buf), "%d", p->expiry); 12731 add_header(&req, "Expires", buf); 12732 } 12733 12734 /* This new INVITE is part of an attended transfer. Make sure that the 12735 other end knows and replace the current call with this new call */ 12736 if (p->options && !ast_strlen_zero(p->options->replaces)) { 12737 add_header(&req, "Replaces", p->options->replaces); 12738 add_header(&req, "Require", "replaces"); 12739 } 12740 12741 /* Add Session-Timers related headers */ 12742 if (st_get_mode(p, 0) == SESSION_TIMER_MODE_ORIGINATE 12743 || (st_get_mode(p, 0) == SESSION_TIMER_MODE_ACCEPT 12744 && st_get_se(p, FALSE) != DEFAULT_MIN_SE)) { 12745 char i2astr[10]; 12746 12747 if (!p->stimer->st_interval) { 12748 p->stimer->st_interval = st_get_se(p, TRUE); 12749 } 12750 12751 p->stimer->st_active = TRUE; 12752 if (st_get_mode(p, 0) == SESSION_TIMER_MODE_ORIGINATE) { 12753 snprintf(i2astr, sizeof(i2astr), "%d", p->stimer->st_interval); 12754 add_header(&req, "Session-Expires", i2astr); 12755 } 12756 12757 snprintf(i2astr, sizeof(i2astr), "%d", st_get_se(p, FALSE)); 12758 add_header(&req, "Min-SE", i2astr); 12759 } 12760 12761 add_header(&req, "Allow", ALLOWED_METHODS); 12762 add_supported_header(p, &req); 12763 12764 if (p->options && p->options->addsipheaders && p->owner) { 12765 struct ast_channel *chan = p->owner; /* The owner channel */ 12766 struct varshead *headp; 12767 12768 ast_channel_lock(chan); 12769 12770 headp = &chan->varshead; 12771 12772 if (!headp) { 12773 ast_log(LOG_WARNING, "No Headp for the channel...ooops!\n"); 12774 } else { 12775 const struct ast_var_t *current; 12776 AST_LIST_TRAVERSE(headp, current, entries) { 12777 /* SIPADDHEADER: Add SIP header to outgoing call */ 12778 if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 12779 char *content, *end; 12780 const char *header = ast_var_value(current); 12781 char *headdup = ast_strdupa(header); 12782 12783 /* Strip of the starting " (if it's there) */ 12784 if (*headdup == '"') { 12785 headdup++; 12786 } 12787 if ((content = strchr(headdup, ':'))) { 12788 *content++ = '\0'; 12789 content = ast_skip_blanks(content); /* Skip white space */ 12790 /* Strip the ending " (if it's there) */ 12791 end = content + strlen(content) -1; 12792 if (*end == '"') { 12793 *end = '\0'; 12794 } 12795 12796 add_header(&req, headdup, content); 12797 if (sipdebug) { 12798 ast_debug(1, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content); 12799 } 12800 } 12801 } 12802 } 12803 } 12804 12805 ast_channel_unlock(chan); 12806 } 12807 if ((sipmethod == SIP_INVITE || sipmethod == SIP_UPDATE) && ast_test_flag(&p->flags[0], SIP_SENDRPID)) 12808 add_rpid(&req, p); 12809 if (sipmethod == SIP_INVITE) { 12810 add_diversion_header(&req, p); 12811 } 12812 if (sdp) { 12813 memset(p->offered_media, 0, sizeof(p->offered_media)); 12814 if (p->udptl && p->t38.state == T38_LOCAL_REINVITE) { 12815 ast_debug(1, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12816 add_sdp(&req, p, FALSE, FALSE, TRUE); 12817 } else if (p->rtp) { 12818 try_suggested_sip_codec(p); 12819 add_sdp(&req, p, FALSE, TRUE, FALSE); 12820 } 12821 } else if (p->notify) { 12822 for (var = p->notify->headers; var; var = var->next) { 12823 add_header(&req, var->name, var->value); 12824 } 12825 if (ast_str_strlen(p->notify->content)) { 12826 add_content(&req, ast_str_buffer(p->notify->content)); 12827 } 12828 } else if (sipmethod == SIP_PUBLISH) { 12829 char expires[SIPBUFSIZE]; 12830 12831 switch (p->epa_entry->static_data->event) { 12832 case CALL_COMPLETION: 12833 snprintf(expires, sizeof(expires), "%d", p->expiry); 12834 add_header(&req, "Event", "call-completion"); 12835 add_header(&req, "Expires", expires); 12836 if (p->epa_entry->publish_type != SIP_PUBLISH_INITIAL) { 12837 add_header(&req, "SIP-If-Match", p->epa_entry->entity_tag); 12838 } 12839 12840 if (!ast_strlen_zero(p->epa_entry->body)) { 12841 add_header(&req, "Content-Type", "application/pidf+xml"); 12842 add_content(&req, p->epa_entry->body); 12843 } 12844 default: 12845 break; 12846 } 12847 } 12848 12849 if (!p->initreq.headers || init > 2) { 12850 initialize_initreq(p, &req); 12851 } 12852 if (sipmethod == SIP_INVITE || sipmethod == SIP_SUBSCRIBE) { 12853 p->lastinvite = p->ocseq; 12854 } 12855 return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq); 12856 }
| static int transmit_message_with_text | ( | struct sip_pvt * | p, | |
| const char * | text | |||
| ) | [static] |
Transmit text with SIP MESSAGE method.
Definition at line 13982 of file chan_sip.c.
References add_text(), reqprep(), and send_request().
Referenced by sip_park_thread(), and sip_sendtext().
13983 { 13984 struct sip_request req; 13985 13986 reqprep(&req, p, SIP_MESSAGE, 0, 1); 13987 add_text(&req, text); 13988 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 13989 }
| 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 13374 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().
13375 { 13376 struct sip_request req; 13377 struct ast_str *out = ast_str_alloca(500); 13378 int ourport = (p->fromdomainport) ? p->fromdomainport : ast_sockaddr_port(&p->ourip); 13379 const char *domain; 13380 const char *exten = S_OR(vmexten, default_vmexten); 13381 13382 initreqprep(&req, p, SIP_NOTIFY, NULL); 13383 add_header(&req, "Event", "message-summary"); 13384 add_header(&req, "Content-Type", default_notifymime); 13385 ast_str_append(&out, 0, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no"); 13386 13387 /* domain initialization occurs here because initreqprep changes ast_sockaddr_stringify string. */ 13388 domain = S_OR(p->fromdomain, ast_sockaddr_stringify_host_remote(&p->ourip)); 13389 13390 if (!sip_standard_port(p->socket.type, ourport)) { 13391 if (p->socket.type == SIP_TRANSPORT_UDP) { 13392 ast_str_append(&out, 0, "Message-Account: sip:%s@%s:%d\r\n", exten, domain, ourport); 13393 } else { 13394 ast_str_append(&out, 0, "Message-Account: sip:%s@%s:%d;transport=%s\r\n", exten, domain, ourport, get_transport(p->socket.type)); 13395 } 13396 } else { 13397 if (p->socket.type == SIP_TRANSPORT_UDP) { 13398 ast_str_append(&out, 0, "Message-Account: sip:%s@%s\r\n", exten, domain); 13399 } else { 13400 ast_str_append(&out, 0, "Message-Account: sip:%s@%s;transport=%s\r\n", exten, domain, get_transport(p->socket.type)); 13401 } 13402 } 13403 /* Cisco has a bug in the SIP stack where it can't accept the 13404 (0/0) notification. This can temporarily be disabled in 13405 sip.conf with the "buggymwi" option */ 13406 ast_str_append(&out, 0, "Voice-Message: %d/%d%s\r\n", 13407 newmsgs, oldmsgs, (ast_test_flag(&p->flags[1], SIP_PAGE2_BUGGY_MWI) ? "" : " (0/0)")); 13408 13409 if (p->subscribed) { 13410 if (p->expiry) { 13411 add_header(&req, "Subscription-State", "active"); 13412 } else { /* Expired */ 13413 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 13414 } 13415 } 13416 13417 add_content(&req, ast_str_buffer(out)); 13418 13419 if (!p->initreq.headers) { 13420 initialize_initreq(p, &req); 13421 } 13422 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 13423 }
| 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 13426 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().
13427 { 13428 struct sip_request req; 13429 char tmp[SIPBUFSIZE/2]; 13430 13431 reqprep(&req, p, SIP_NOTIFY, 0, 1); 13432 snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq); 13433 add_header(&req, "Event", tmp); 13434 add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active"); 13435 add_header(&req, "Content-Type", "message/sipfrag;version=2.0"); 13436 add_header(&req, "Allow", ALLOWED_METHODS); 13437 add_supported_header(p, &req); 13438 13439 snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message); 13440 add_content(&req, tmp); 13441 13442 if (!p->initreq.headers) { 13443 initialize_initreq(p, &req); 13444 } 13445 13446 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 13447 }
| static int transmit_provisional_response | ( | struct sip_pvt * | p, | |
| const char * | msg, | |||
| const struct sip_request * | req, | |||
| int | with_sdp | |||
| ) | [static] |
Definition at line 11305 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().
11306 { 11307 int res; 11308 11309 if (!(res = with_sdp ? transmit_response_with_sdp(p, msg, req, XMIT_UNRELIABLE, FALSE, FALSE) : transmit_response(p, msg, req))) { 11310 p->last_provisional = msg; 11311 update_provisional_keepalive(p, with_sdp); 11312 } 11313 11314 return res; 11315 }
| 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 12645 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().
12646 { 12647 struct sip_pvt *pvt; 12648 int expires; 12649 12650 epa_entry->publish_type = publish_type; 12651 12652 if (!(pvt = sip_alloc(NULL, NULL, 0, SIP_PUBLISH, NULL))) { 12653 return -1; 12654 } 12655 12656 sip_pvt_lock(pvt); 12657 12658 if (create_addr(pvt, epa_entry->destination, NULL, TRUE)) { 12659 sip_pvt_unlock(pvt); 12660 dialog_unlink_all(pvt); 12661 dialog_unref(pvt, "create_addr failed in transmit_publish. Unref dialog"); 12662 return -1; 12663 } 12664 ast_sip_ouraddrfor(&pvt->sa, &pvt->ourip, pvt); 12665 ast_set_flag(&pvt->flags[0], SIP_OUTGOING); 12666 expires = (publish_type == SIP_PUBLISH_REMOVE) ? 0 : DEFAULT_PUBLISH_EXPIRES; 12667 pvt->expiry = expires; 12668 12669 /* Bump refcount for sip_pvt's reference */ 12670 ao2_ref(epa_entry, +1); 12671 pvt->epa_entry = epa_entry; 12672 12673 transmit_invite(pvt, SIP_PUBLISH, FALSE, 2, explicit_uri); 12674 sip_pvt_unlock(pvt); 12675 sip_scheddestroy(pvt, DEFAULT_TRANS_TIMEOUT); 12676 dialog_unref(pvt, "Done with the sip_pvt allocated for transmitting PUBLISH"); 12677 return 0; 12678 }
| 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 14013 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().
14014 { 14015 struct sip_request req = { 14016 .headers = 0, 14017 }; 14018 char from[256]; 14019 const char *of; 14020 char *c; 14021 char referto[256]; 14022 int use_tls=FALSE; 14023 14024 if (sipdebug) { 14025 ast_debug(1, "SIP transfer of %s to %s\n", p->callid, dest); 14026 } 14027 14028 /* Are we transfering an inbound or outbound call ? */ 14029 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 14030 of = get_header(&p->initreq, "To"); 14031 } else { 14032 of = get_header(&p->initreq, "From"); 14033 } 14034 14035 ast_copy_string(from, of, sizeof(from)); 14036 of = get_in_brackets(from); 14037 ast_string_field_set(p, from, of); 14038 if (!strncasecmp(of, "sip:", 4)) { 14039 of += 4; 14040 } else if (!strncasecmp(of, "sips:", 5)) { 14041 of += 5; 14042 use_tls = TRUE; 14043 } else { 14044 ast_log(LOG_NOTICE, "From address missing 'sip(s):', assuming sip:\n"); 14045 } 14046 /* Get just the username part */ 14047 if (strchr(dest, '@')) { 14048 c = NULL; 14049 } else if ((c = strchr(of, '@'))) { 14050 *c++ = '\0'; 14051 } 14052 if (c) { 14053 snprintf(referto, sizeof(referto), "<sip%s:%s@%s>", use_tls ? "s" : "", dest, c); 14054 } else { 14055 snprintf(referto, sizeof(referto), "<sip%s:%s>", use_tls ? "s" : "", dest); 14056 } 14057 14058 /* save in case we get 407 challenge */ 14059 sip_refer_allocate(p); 14060 ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to)); 14061 ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by)); 14062 p->refer->status = REFER_SENT; /* Set refer status */ 14063 14064 reqprep(&req, p, SIP_REFER, 0, 1); 14065 14066 add_header(&req, "Refer-To", referto); 14067 add_header(&req, "Allow", ALLOWED_METHODS); 14068 add_supported_header(p, &req); 14069 if (!ast_strlen_zero(p->our_contact)) { 14070 add_header(&req, "Referred-By", p->our_contact); 14071 } 14072 14073 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 14074 14075 /* We should propably wait for a NOTIFY here until we ack the transfer */ 14076 /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */ 14077 14078 /*! \todo In theory, we should hang around and wait for a reply, before 14079 returning to the dial plan here. Don't know really how that would 14080 affect the transfer() app or the pbx, but, well, to make this 14081 useful we should have a STATUS code on transfer(). 14082 */ 14083 }
| 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 13727 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_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, make_our_tag(), 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().
13728 { 13729 struct sip_request req; 13730 char from[256]; 13731 char to[256]; 13732 char tmp[80]; 13733 char addr[80]; 13734 struct sip_pvt *p; 13735 struct sip_peer *peer = NULL; 13736 int res; 13737 int portno = 0; 13738 13739 /* exit if we are already in process with this registrar ?*/ 13740 if (r == NULL || ((auth == NULL) && (r->regstate == REG_STATE_REGSENT || r->regstate == REG_STATE_AUTHSENT))) { 13741 if (r) { 13742 ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname); 13743 } 13744 return 0; 13745 } 13746 13747 if (r->dnsmgr == NULL) { 13748 char transport[MAXHOSTNAMELEN]; 13749 peer = find_peer(r->hostname, NULL, TRUE, FINDPEERS, FALSE, 0); 13750 snprintf(transport, sizeof(transport), "_%s._%s",get_srv_service(r->transport), get_srv_protocol(r->transport)); /* have to use static get_transport function */ 13751 r->us.ss.ss_family = get_address_family_filter(r->transport); /* Filter address family */ 13752 13753 /* No point in doing a DNS lookup of the register hostname if we're just going to 13754 * end up using an outbound proxy. obproxy_get is safe to call with either of r->call 13755 * or peer NULL. Since we're only concerned with its existence, we're not going to 13756 * bother getting a ref to the proxy*/ 13757 if (!obproxy_get(r->call, peer)) { 13758 registry_addref(r, "add reg ref for dnsmgr"); 13759 ast_dnsmgr_lookup_cb(peer ? peer->tohost : r->hostname, &r->us, &r->dnsmgr, sip_cfg.srvlookup ? transport : NULL, on_dns_update_registry, r); 13760 if (!r->dnsmgr) { 13761 /*dnsmgr refresh disabled, no reference added! */ 13762 registry_unref(r, "remove reg ref, dnsmgr disabled"); 13763 } 13764 } 13765 if (peer) { 13766 peer = unref_peer(peer, "removing peer ref for dnsmgr_lookup"); 13767 } 13768 } 13769 13770 if (r->call) { /* We have a registration */ 13771 if (!auth) { 13772 ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname); 13773 return 0; 13774 } else { 13775 p = dialog_ref(r->call, "getting a copy of the r->call dialog in transmit_register"); 13776 make_our_tag(p); /* create a new local tag for every register attempt */ 13777 ast_string_field_set(p, theirtag, NULL); /* forget their old tag, so we don't match tags when getting response */ 13778 } 13779 } else { 13780 /* Build callid for registration if we haven't registered before */ 13781 if (!r->callid_valid) { 13782 build_callid_registry(r, &internip, default_fromdomain); 13783 r->callid_valid = TRUE; 13784 } 13785 /* Allocate SIP dialog for registration */ 13786 if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER, NULL))) { 13787 ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n"); 13788 return 0; 13789 } 13790 13791 if (p->do_history) { 13792 append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname); 13793 } 13794 13795 /* Use port number specified if no SRV record was found */ 13796 if (!ast_sockaddr_isnull(&r->us)) { 13797 if (!ast_sockaddr_port(&r->us) && r->portno) { 13798 ast_sockaddr_set_port(&r->us, r->portno); 13799 } 13800 13801 /* It is possible that DNS was unavailable at the time the peer was created. 13802 * Here, if we've updated the address in the registry via manually calling 13803 * ast_dnsmgr_lookup_cb() above, then we call the same function that dnsmgr would 13804 * call if it was updating a peer's address */ 13805 if ((peer = find_peer(S_OR(r->peername, r->hostname), NULL, TRUE, FINDPEERS, FALSE, 0))) { 13806 if (ast_sockaddr_cmp(&peer->addr, &r->us)) { 13807 on_dns_update_peer(&peer->addr, &r->us, peer); 13808 } 13809 peer = unref_peer(peer, "unref after find_peer"); 13810 } 13811 } 13812 13813 /* Find address to hostname */ 13814 if (create_addr(p, S_OR(r->peername, r->hostname), &r->us, 0)) { 13815 /* we have what we hope is a temporary network error, 13816 * probably DNS. We need to reschedule a registration try */ 13817 dialog_unlink_all(p); 13818 p = dialog_unref(p, "unref dialog after unlink_all"); 13819 if (r->timeout > -1) { 13820 AST_SCHED_REPLACE_UNREF(r->timeout, sched, global_reg_timeout * 1000, sip_reg_timeout, r, 13821 registry_unref(_data, "del for REPLACE of registry ptr"), 13822 registry_unref(r, "object ptr dec when SCHED_REPLACE add failed"), 13823 registry_addref(r,"add for REPLACE registry ptr")); 13824 ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout); 13825 } else { 13826 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, registry_addref(r, "add for REPLACE registry ptr")); 13827 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); 13828 } 13829 r->regattempts++; 13830 return 0; 13831 } 13832 13833 /* Copy back Call-ID in case create_addr changed it */ 13834 ast_string_field_set(r, callid, p->callid); 13835 13836 if (!r->dnsmgr && r->portno) { 13837 ast_sockaddr_set_port(&p->sa, r->portno); 13838 ast_sockaddr_set_port(&p->recv, r->portno); 13839 } 13840 if (!ast_strlen_zero(p->fromdomain)) { 13841 portno = (p->fromdomainport) ? p->fromdomainport : STANDARD_SIP_PORT; 13842 } else if (!ast_strlen_zero(r->regdomain)) { 13843 portno = (r->regdomainport) ? r->regdomainport : STANDARD_SIP_PORT; 13844 } else { 13845 portno = ast_sockaddr_port(&p->sa); 13846 } 13847 13848 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */ 13849 r->call = dialog_ref(p, "copying dialog into registry r->call"); /* Save pointer to SIP dialog */ 13850 p->registry = registry_addref(r, "transmit_register: addref to p->registry in transmit_register"); /* Add pointer to registry in packet */ 13851 if (!ast_strlen_zero(r->secret)) { /* Secret (password) */ 13852 ast_string_field_set(p, peersecret, r->secret); 13853 } 13854 if (!ast_strlen_zero(r->md5secret)) 13855 ast_string_field_set(p, peermd5secret, r->md5secret); 13856 /* User name in this realm 13857 - if authuser is set, use that, otherwise use username */ 13858 if (!ast_strlen_zero(r->authuser)) { 13859 ast_string_field_set(p, peername, r->authuser); 13860 ast_string_field_set(p, authname, r->authuser); 13861 } else if (!ast_strlen_zero(r->username)) { 13862 ast_string_field_set(p, peername, r->username); 13863 ast_string_field_set(p, authname, r->username); 13864 ast_string_field_set(p, fromuser, r->username); 13865 } 13866 if (!ast_strlen_zero(r->username)) { 13867 ast_string_field_set(p, username, r->username); 13868 } 13869 /* Save extension in packet */ 13870 if (!ast_strlen_zero(r->callback)) { 13871 ast_string_field_set(p, exten, r->callback); 13872 } 13873 13874 /* Set transport and port so the correct contact is built */ 13875 set_socket_transport(&p->socket, r->transport); 13876 if (r->transport == SIP_TRANSPORT_TLS || r->transport == SIP_TRANSPORT_TCP) { 13877 p->socket.port = 13878 htons(ast_sockaddr_port(&sip_tcp_desc.local_address)); 13879 } 13880 13881 /* 13882 check which address we should use in our contact header 13883 based on whether the remote host is on the external or 13884 internal network so we can register through nat 13885 */ 13886 ast_sip_ouraddrfor(&p->sa, &p->ourip, p); 13887 build_contact(p); 13888 } 13889 13890 /* set up a timeout */ 13891 if (auth == NULL) { 13892 if (r->timeout > -1) { 13893 ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout); 13894 } 13895 AST_SCHED_REPLACE_UNREF(r->timeout, sched, global_reg_timeout * 1000, sip_reg_timeout, r, 13896 registry_unref(_data,"reg ptr unrefed from del in SCHED_REPLACE"), 13897 registry_unref(r,"reg ptr unrefed from add failure in SCHED_REPLACE"), 13898 registry_addref(r,"reg ptr reffed from add in SCHED_REPLACE")); 13899 ast_debug(1, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); 13900 } 13901 13902 snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, S_OR(r->regdomain, sip_sanitized_host(p->tohost)), p->tag); 13903 if (!ast_strlen_zero(p->theirtag)) { 13904 snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, S_OR(r->regdomain, sip_sanitized_host(p->tohost)), p->theirtag); 13905 } else { 13906 snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, S_OR(r->regdomain, sip_sanitized_host(p->tohost))); 13907 } 13908 13909 /* Fromdomain is what we are registering to, regardless of actual 13910 host name from SRV */ 13911 if (portno && portno != STANDARD_SIP_PORT) { 13912 snprintf(addr, sizeof(addr), "sip:%s:%d", S_OR(p->fromdomain,S_OR(r->regdomain, sip_sanitized_host(r->hostname))), portno); 13913 } else { 13914 snprintf(addr, sizeof(addr), "sip:%s", S_OR(p->fromdomain,S_OR(r->regdomain, sip_sanitized_host(r->hostname)))); 13915 } 13916 13917 ast_string_field_set(p, uri, addr); 13918 13919 p->branch ^= ast_random(); 13920 13921 init_req(&req, sipmethod, addr); 13922 13923 /* Add to CSEQ */ 13924 snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text); 13925 p->ocseq = r->ocseq; 13926 13927 build_via(p); 13928 add_header(&req, "Via", p->via); 13929 add_header_max_forwards(p, &req); 13930 add_header(&req, "From", from); 13931 add_header(&req, "To", to); 13932 add_header(&req, "Call-ID", p->callid); 13933 add_header(&req, "CSeq", tmp); 13934 if (!ast_strlen_zero(global_useragent)) 13935 add_header(&req, "User-Agent", global_useragent); 13936 13937 if (auth) { /* Add auth header */ 13938 add_header(&req, authheader, auth); 13939 } else if (!ast_strlen_zero(r->nonce)) { 13940 char digest[1024]; 13941 13942 /* We have auth data to reuse, build a digest header. 13943 * Note, this is not always useful because some parties do not 13944 * like nonces to be reused (for good reasons!) so they will 13945 * challenge us anyways. 13946 */ 13947 if (sipdebug) { 13948 ast_debug(1, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname); 13949 } 13950 ast_string_field_set(p, realm, r->realm); 13951 ast_string_field_set(p, nonce, r->nonce); 13952 ast_string_field_set(p, domain, r->authdomain); 13953 ast_string_field_set(p, opaque, r->opaque); 13954 ast_string_field_set(p, qop, r->qop); 13955 p->noncecount = ++r->noncecount; 13956 13957 memset(digest, 0, sizeof(digest)); 13958 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 13959 add_header(&req, "Authorization", digest); 13960 } else { 13961 ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname); 13962 } 13963 } 13964 13965 snprintf(tmp, sizeof(tmp), "%d", r->expiry); 13966 add_header(&req, "Expires", tmp); 13967 add_header(&req, "Contact", p->our_contact); 13968 13969 initialize_initreq(p, &req); 13970 if (sip_debug_test_pvt(p)) { 13971 ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 13972 } 13973 r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT; 13974 r->regattempts++; /* Another attempt */ 13975 ast_debug(4, "REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname); 13976 res = send_request(p, &req, XMIT_CRITICAL, p->ocseq); 13977 dialog_unref(p, "p is finished here at the end of transmit_register"); 13978 return res; 13979 }
| 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 12350 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().
12351 { 12352 struct sip_request req; 12353 12354 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 12355 12356 add_header(&req, "Allow", ALLOWED_METHODS); 12357 add_supported_header(p, &req); 12358 if (sipdebug) { 12359 if (oldsdp == TRUE) 12360 add_header(&req, "X-asterisk-Info", "SIP re-invite (Session-Timers)"); 12361 else 12362 add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)"); 12363 } 12364 12365 if (ast_test_flag(&p->flags[0], SIP_SENDRPID)) 12366 add_rpid(&req, p); 12367 12368 if (p->do_history) { 12369 append_history(p, "ReInv", "Re-invite sent"); 12370 } 12371 memset(p->offered_media, 0, sizeof(p->offered_media)); 12372 12373 try_suggested_sip_codec(p); 12374 if (t38version) { 12375 add_sdp(&req, p, oldsdp, FALSE, TRUE); 12376 } else { 12377 add_sdp(&req, p, oldsdp, TRUE, FALSE); 12378 } 12379 12380 /* Use this as the basis */ 12381 initialize_initreq(p, &req); 12382 p->lastinvite = p->ocseq; 12383 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 12384 p->ongoing_reinvite = 1; 12385 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 12386 }
| 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 14156 of file chan_sip.c.
References add_header(), reqprep(), and send_request().
Referenced by check_pendings(), handle_response(), handle_response_invite(), and sip_hangup().
14157 { 14158 struct sip_request resp; 14159 14160 reqprep(&resp, p, sipmethod, seqno, newbranch); 14161 if (sipmethod == SIP_CANCEL && p->answered_elsewhere) { 14162 add_header(&resp, "Reason", "SIP;cause=200;text=\"Call completed elsewhere\""); 14163 } 14164 14165 if (sipmethod == SIP_ACK) { 14166 p->invitestate = INV_CONFIRMED; 14167 } 14168 14169 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 14170 }
| 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 14188 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().
14189 { 14190 struct sip_request resp; 14191 14192 reqprep(&resp, p, sipmethod, seqno, newbranch); 14193 if (!ast_strlen_zero(p->realm)) { 14194 char digest[1024]; 14195 14196 memset(digest, 0, sizeof(digest)); 14197 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 14198 char *dummy, *response; 14199 enum sip_auth_type code = p->options ? p->options->auth_type : PROXY_AUTH; /* XXX force 407 if unknown */ 14200 auth_headers(code, &dummy, &response); 14201 add_header(&resp, response, digest); 14202 } else { 14203 ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid); 14204 } 14205 } 14206 /* If we are hanging up and know a cause for that, send it in clear text to make 14207 debugging easier. */ 14208 if (sipmethod == SIP_BYE) { 14209 char buf[20]; 14210 14211 if (ast_test_flag(&p->flags[1], SIP_PAGE2_Q850_REASON) && p->hangupcause) { 14212 sprintf(buf, "Q.850;cause=%i", p->hangupcause & 0x7f); 14213 add_header(&resp, "Reason", buf); 14214 } 14215 14216 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->hangupcause)); 14217 snprintf(buf, sizeof(buf), "%d", p->hangupcause); 14218 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 14219 } 14220 14221 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 14222 }
| static int transmit_response | ( | struct sip_pvt * | p, | |
| const char * | msg, | |||
| const struct sip_request * | req | |||
| ) | [static] |
Transmit response, no retransmits.
Definition at line 11102 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().
11103 { 11104 return __transmit_response(p, msg, req, XMIT_UNRELIABLE); 11105 }
| 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 11135 of file chan_sip.c.
References __transmit_response().
Referenced by handle_incoming(), handle_invite_replaces(), handle_request_bye(), handle_request_cancel(), handle_request_invite(), interpret_t38_parameters(), sip_hangup(), sip_indicate(), sip_sipredirect(), and sip_t38_abort().
11136 { 11137 return __transmit_response(p, msg, req, req->ignore ? XMIT_UNRELIABLE : XMIT_CRITICAL); 11138 }
| 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 11049 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().
11050 { 11051 struct sip_pvt *p = NULL; 11052 11053 if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) { 11054 ast_log(LOG_ERROR, "Failed to get temporary pvt\n"); 11055 return -1; 11056 } 11057 11058 /* XXX the structure may be dirty from previous usage. 11059 * Here we should state clearly how we should reinitialize it 11060 * before using it. 11061 * E.g. certainly the threadstorage should be left alone, 11062 * but other thihngs such as flags etc. maybe need cleanup ? 11063 */ 11064 11065 /* Initialize the bare minimum */ 11066 p->method = intended_method; 11067 11068 if (!addr) { 11069 ast_sockaddr_copy(&p->ourip, &internip); 11070 } else { 11071 ast_sockaddr_copy(&p->sa, addr); 11072 ast_sip_ouraddrfor(&p->sa, &p->ourip, p); 11073 } 11074 11075 p->branch = ast_random(); 11076 make_our_tag(p); 11077 p->ocseq = INITIAL_CSEQ; 11078 11079 if (useglobal_nat && addr) { 11080 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT_FORCE_RPORT); 11081 ast_sockaddr_copy(&p->recv, addr); 11082 do_setnat(p); 11083 } 11084 11085 ast_string_field_set(p, fromdomain, default_fromdomain); 11086 p->fromdomainport = default_fromdomainport; 11087 build_via(p); 11088 ast_string_field_set(p, callid, callid); 11089 11090 copy_socket_data(&p->socket, &req->socket); 11091 11092 /* Use this temporary pvt structure to send the message */ 11093 __transmit_response(p, msg, req, XMIT_UNRELIABLE); 11094 11095 /* Free the string fields, but not the pool space */ 11096 ast_string_field_init(p, 0); 11097 11098 return 0; 11099 }
| 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 11171 of file chan_sip.c.
References add_header(), respprep(), and send_response().
Referenced by handle_incoming(), and handle_request_options().
11172 { 11173 struct sip_request resp; 11174 respprep(&resp, p, msg, req); 11175 add_header(&resp, "Accept", "application/sdp"); 11176 return send_response(p, &resp, reliable, 0); 11177 }
| 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 11192 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().
11193 { 11194 struct sip_request resp; 11195 char tmp[512]; 11196 uint32_t seqno = 0; 11197 11198 if (reliable && (sscanf(get_header(req, "CSeq"), "%30u ", &seqno) != 1)) { 11199 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 11200 return -1; 11201 } 11202 /* Choose Realm */ 11203 get_realm(p, req); 11204 11205 /* Stale means that they sent us correct authentication, but 11206 based it on an old challenge (nonce) */ 11207 snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", p->realm, randdata, stale ? ", stale=true" : ""); 11208 respprep(&resp, p, msg, req); 11209 add_header(&resp, header, tmp); 11210 append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount); 11211 return send_response(p, &resp, reliable, seqno); 11212 }
| 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 11162 of file chan_sip.c.
References append_date(), respprep(), and send_response().
Referenced by handle_response_subscribe(), and register_verify().
11163 { 11164 struct sip_request resp; 11165 respprep(&resp, p, msg, req); 11166 append_date(&resp); 11167 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 11168 }
| 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 11180 of file chan_sip.c.
References add_header(), respprep(), and send_response().
Referenced by handle_request_publish(), and handle_request_subscribe().
11181 { 11182 struct sip_request resp; 11183 char tmp[32]; 11184 11185 snprintf(tmp, sizeof(tmp), "%d", min_expiry); 11186 respprep(&resp, p, msg, req); 11187 add_header(&resp, "Min-Expires", tmp); 11188 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 11189 }
| 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 11118 of file chan_sip.c.
References add_header(), append_date(), respprep(), and send_response().
Referenced by handle_request_invite().
11119 { 11120 struct sip_request resp; 11121 char minse_str[20]; 11122 11123 respprep(&resp, p, msg, req); 11124 append_date(&resp); 11125 11126 snprintf(minse_str, sizeof(minse_str), "%d", minse_int); 11127 add_header(&resp, "Min-SE", minse_str); 11128 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 11129 }
| 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 11153 of file chan_sip.c.
References add_header(), respprep(), and send_response().
Referenced by handle_incoming().
11154 { 11155 struct sip_request resp; 11156 respprep(&resp, p, msg, req); 11157 add_header(&resp, "Retry-After", seconds); 11158 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 11159 }
| 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 12259 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().
12260 { 12261 struct sip_request resp; 12262 uint32_t seqno; 12263 if (sscanf(get_header(req, "CSeq"), "%30u ", &seqno) != 1) { 12264 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 12265 return -1; 12266 } 12267 respprep(&resp, p, msg, req); 12268 if (rpid == TRUE) { 12269 add_rpid(&resp, p); 12270 } 12271 if (ast_test_flag(&p->flags[0], SIP_OFFER_CC)) { 12272 add_cc_call_info_to_response(p, &resp); 12273 } 12274 if (p->rtp) { 12275 if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 12276 ast_debug(1, "Setting framing from config on incoming call\n"); 12277 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &p->prefs); 12278 } 12279 ast_rtp_instance_activate(p->rtp); 12280 try_suggested_sip_codec(p); 12281 if (p->t38.state == T38_ENABLED) { 12282 add_sdp(&resp, p, oldsdp, TRUE, TRUE); 12283 } else { 12284 add_sdp(&resp, p, oldsdp, TRUE, FALSE); 12285 } 12286 } else 12287 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid); 12288 if (reliable && !p->pendinginvite) 12289 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 12290 add_required_respheader(&resp); 12291 return send_response(p, &resp, reliable, seqno); 12292 }
| 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 11018 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().
11019 { 11020 struct sip_request resp; 11021 11022 if (need_new_etag) { 11023 create_new_sip_etag(esc_entry, 1); 11024 } 11025 respprep(&resp, p, msg, req); 11026 add_header(&resp, "SIP-ETag", esc_entry->entity_tag); 11027 11028 return send_response(p, &resp, 0, 0); 11029 }
| 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 12175 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().
12176 { 12177 struct sip_request resp; 12178 uint32_t seqno; 12179 12180 if (sscanf(get_header(req, "CSeq"), "%30u ", &seqno) != 1) { 12181 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 12182 return -1; 12183 } 12184 respprep(&resp, p, msg, req); 12185 if (p->udptl) { 12186 add_sdp(&resp, p, 0, 0, 1); 12187 } else 12188 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid); 12189 if (retrans && !p->pendinginvite) 12190 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 12191 return send_response(p, &resp, retrans, seqno); 12192 }
| 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 11108 of file chan_sip.c.
References add_header(), append_date(), respprep(), and send_response().
Referenced by handle_request_bye(), and handle_request_invite().
11109 { 11110 struct sip_request resp; 11111 respprep(&resp, p, msg, req); 11112 append_date(&resp); 11113 add_header(&resp, "Unsupported", unsupported); 11114 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 11115 }
| 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 13280 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().
13281 { 13282 struct ast_str *tmp = ast_str_alloca(4000); 13283 char from[256], to[256]; 13284 char *c, *mfrom, *mto; 13285 struct sip_request req; 13286 const struct cfsubscription_types *subscriptiontype; 13287 13288 /* If the subscription has not yet been accepted do not send a NOTIFY */ 13289 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) { 13290 return 0; 13291 } 13292 13293 memset(from, 0, sizeof(from)); 13294 memset(to, 0, sizeof(to)); 13295 13296 subscriptiontype = find_subscription_type(p->subscribed); 13297 13298 ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from)); 13299 c = get_in_brackets(from); 13300 if (strncasecmp(c, "sip:", 4) && strncasecmp(c, "sips:", 5)) { 13301 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 13302 return -1; 13303 } 13304 13305 mfrom = remove_uri_parameters(c); 13306 13307 ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to)); 13308 c = get_in_brackets(to); 13309 if (strncasecmp(c, "sip:", 4) && strncasecmp(c, "sips:", 5)) { 13310 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 13311 return -1; 13312 } 13313 mto = remove_uri_parameters(c); 13314 13315 reqprep(&req, p, SIP_NOTIFY, 0, 1); 13316 13317 switch(state) { 13318 case AST_EXTENSION_DEACTIVATED: 13319 if (timeout) 13320 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 13321 else { 13322 add_header(&req, "Subscription-State", "terminated;reason=probation"); 13323 add_header(&req, "Retry-After", "60"); 13324 } 13325 break; 13326 case AST_EXTENSION_REMOVED: 13327 add_header(&req, "Subscription-State", "terminated;reason=noresource"); 13328 break; 13329 default: 13330 if (p->expiry) 13331 add_header(&req, "Subscription-State", "active"); 13332 else /* Expired */ 13333 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 13334 } 13335 13336 switch (p->subscribed) { 13337 case XPIDF_XML: 13338 case CPIM_PIDF_XML: 13339 add_header(&req, "Event", subscriptiontype->event); 13340 state_notify_build_xml(state, full, p->exten, p->context, &tmp, p, p->subscribed, mfrom, mto); 13341 add_header(&req, "Content-Type", subscriptiontype->mediatype); 13342 p->dialogver++; 13343 break; 13344 case PIDF_XML: /* Eyebeam supports this format */ 13345 add_header(&req, "Event", subscriptiontype->event); 13346 state_notify_build_xml(state, full, p->exten, p->context, &tmp, p, p->subscribed, mfrom, mto); 13347 add_header(&req, "Content-Type", subscriptiontype->mediatype); 13348 p->dialogver++; 13349 break; 13350 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 13351 add_header(&req, "Event", subscriptiontype->event); 13352 state_notify_build_xml(state, full, p->exten, p->context, &tmp, p, p->subscribed, mfrom, mto); 13353 add_header(&req, "Content-Type", subscriptiontype->mediatype); 13354 p->dialogver++; 13355 break; 13356 case NONE: 13357 default: 13358 break; 13359 } 13360 13361 add_content(&req, ast_str_buffer(tmp)); 13362 13363 p->pendinginvite = p->ocseq; /* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */ 13364 13365 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 13366 }
| static void try_suggested_sip_codec | ( | struct sip_pvt * | p | ) | [static] |
Try setting codec suggested by the SIP_CODEC channel variable.
Definition at line 6846 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().
06847 { 06848 format_t fmt; 06849 const char *codec; 06850 06851 if (p->outgoing_call) { 06852 codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC_OUTBOUND"); 06853 } else if (!(codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC_INBOUND"))) { 06854 codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC"); 06855 } 06856 06857 if (!codec) 06858 return; 06859 06860 fmt = ast_getformatbyname(codec); 06861 if (fmt) { 06862 ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec); 06863 if (p->jointcapability & fmt) { 06864 p->jointcapability &= fmt; 06865 p->capability &= fmt; 06866 } else 06867 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n"); 06868 } else 06869 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec); 06870 return; 06871 }
| static void unlink_all_peers_from_tables | ( | void | ) | [static] |
Definition at line 3191 of file chan_sip.c.
References SIP_PEERS_ALL, and unlink_peers_from_tables().
Referenced by unload_module().
03192 { 03193 unlink_peers_from_tables(SIP_PEERS_ALL); 03194 }
| static void unlink_marked_peers_from_tables | ( | void | ) | [static] |
Definition at line 3186 of file chan_sip.c.
References SIP_PEERS_MARKED, and unlink_peers_from_tables().
Referenced by sip_do_reload(), and sip_prune_realtime().
03187 { 03188 unlink_peers_from_tables(SIP_PEERS_MARKED); 03189 }
| static void unlink_peer_from_tables | ( | struct sip_peer * | peer | ) | [static] |
Definition at line 3197 of file chan_sip.c.
References ao2_t_unlink, and ast_sockaddr_isnull().
Referenced by expire_register().
03198 { 03199 ao2_t_unlink(peers, peer, "ao2_unlink of peer from peers table"); 03200 if (!ast_sockaddr_isnull(&peer->addr)) { 03201 ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table"); 03202 } 03203 }
| static void unlink_peers_from_tables | ( | peer_unlink_flag_t | flag | ) | [static] |
Definition at line 3177 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().
03178 { 03179 ao2_t_callback(peers, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, 03180 match_and_cleanup_peer_sched, &flag, "initiating callback to remove marked peers"); 03181 ao2_t_callback(peers_by_ip, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, 03182 match_and_cleanup_peer_sched, &flag, "initiating callback to remove marked peers"); 03183 }
| static int unload_module | ( | void | ) | [static] |
PBX unload module API.
Definition at line 31828 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_context_destroy(), ast_context_find(), ast_custom_function_unregister(), ast_data_unregister, ast_debug, ast_dnsmgr_release(), ast_free, ast_free_ha(), 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(), 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().
31829 { 31830 struct sip_pvt *p; 31831 struct sip_threadinfo *th; 31832 struct ast_context *con; 31833 struct ao2_iterator i; 31834 int wait_count; 31835 31836 network_change_event_unsubscribe(); 31837 31838 ast_sched_dump(sched); 31839 31840 /* First, take us out of the channel type list */ 31841 ast_channel_unregister(&sip_tech); 31842 31843 /* Unregister dial plan functions */ 31844 ast_custom_function_unregister(&sipchaninfo_function); 31845 ast_custom_function_unregister(&sippeer_function); 31846 ast_custom_function_unregister(&sip_header_function); 31847 ast_custom_function_unregister(&checksipdomain_function); 31848 31849 /* Unregister dial plan applications */ 31850 ast_unregister_application(app_dtmfmode); 31851 ast_unregister_application(app_sipaddheader); 31852 ast_unregister_application(app_sipremoveheader); 31853 31854 #ifdef TEST_FRAMEWORK 31855 AST_TEST_UNREGISTER(test_sip_peers_get); 31856 AST_TEST_UNREGISTER(test_sip_mwi_subscribe_parse); 31857 AST_TEST_UNREGISTER(test_tcp_message_fragmentation); 31858 AST_TEST_UNREGISTER(get_in_brackets_const_test); 31859 #endif 31860 /* Unregister all the AstData providers */ 31861 ast_data_unregister(NULL); 31862 31863 /* Unregister CLI commands */ 31864 ast_cli_unregister_multiple(cli_sip, ARRAY_LEN(cli_sip)); 31865 31866 /* Disconnect from UDPTL */ 31867 ast_udptl_proto_unregister(&sip_udptl); 31868 31869 /* Disconnect from RTP engine */ 31870 ast_rtp_glue_unregister(&sip_rtp_glue); 31871 31872 /* Unregister AMI actions */ 31873 ast_manager_unregister("SIPpeers"); 31874 ast_manager_unregister("SIPshowpeer"); 31875 ast_manager_unregister("SIPqualifypeer"); 31876 ast_manager_unregister("SIPshowregistry"); 31877 ast_manager_unregister("SIPnotify"); 31878 31879 /* Kill TCP/TLS server threads */ 31880 if (sip_tcp_desc.master) { 31881 ast_tcptls_server_stop(&sip_tcp_desc); 31882 } 31883 if (sip_tls_desc.master) { 31884 ast_tcptls_server_stop(&sip_tls_desc); 31885 } 31886 ast_ssl_teardown(sip_tls_desc.tls_cfg); 31887 31888 /* Kill all existing TCP/TLS threads */ 31889 i = ao2_iterator_init(threadt, 0); 31890 while ((th = ao2_t_iterator_next(&i, "iterate through tcp threads for 'sip show tcp'"))) { 31891 pthread_t thread = th->threadid; 31892 th->stop = 1; 31893 pthread_kill(thread, SIGURG); 31894 ao2_t_ref(th, -1, "decrement ref from iterator"); 31895 } 31896 ao2_iterator_destroy(&i); 31897 31898 /* Hangup all dialogs if they have an owner */ 31899 i = ao2_iterator_init(dialogs, 0); 31900 while ((p = ao2_t_iterator_next(&i, "iterate thru dialogs"))) { 31901 if (p->owner) 31902 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 31903 ao2_t_ref(p, -1, "toss dialog ptr from iterator_next"); 31904 } 31905 ao2_iterator_destroy(&i); 31906 31907 unlink_all_peers_from_tables(); 31908 31909 ast_mutex_lock(&monlock); 31910 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 31911 pthread_cancel(monitor_thread); 31912 pthread_kill(monitor_thread, SIGURG); 31913 pthread_join(monitor_thread, NULL); 31914 } 31915 monitor_thread = AST_PTHREADT_STOP; 31916 ast_mutex_unlock(&monlock); 31917 31918 /* Destroy all the dialogs and free their memory */ 31919 i = ao2_iterator_init(dialogs, 0); 31920 while ((p = ao2_t_iterator_next(&i, "iterate thru dialogs"))) { 31921 dialog_unlink_all(p); 31922 ao2_t_ref(p, -1, "throw away iterator result"); 31923 } 31924 ao2_iterator_destroy(&i); 31925 31926 /* Free memory for local network address mask */ 31927 ast_free_ha(localaddr); 31928 31929 ast_mutex_lock(&authl_lock); 31930 if (authl) { 31931 ao2_t_ref(authl, -1, "Removing global authentication"); 31932 authl = NULL; 31933 } 31934 ast_mutex_unlock(&authl_lock); 31935 31936 sip_epa_unregister_all(); 31937 destroy_escs(); 31938 31939 ast_free(default_tls_cfg.certfile); 31940 ast_free(default_tls_cfg.pvtfile); 31941 ast_free(default_tls_cfg.cipher); 31942 ast_free(default_tls_cfg.cafile); 31943 ast_free(default_tls_cfg.capath); 31944 31945 cleanup_all_regs(); 31946 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 31947 ASTOBJ_CONTAINER_DESTROY(®l); 31948 31949 ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do { 31950 ASTOBJ_WRLOCK(iterator); 31951 if (iterator->dnsmgr) { 31952 ast_dnsmgr_release(iterator->dnsmgr); 31953 iterator->dnsmgr = NULL; 31954 ASTOBJ_UNREF(iterator, sip_subscribe_mwi_destroy); 31955 } 31956 ASTOBJ_UNLOCK(iterator); 31957 } while(0)); 31958 ASTOBJ_CONTAINER_DESTROYALL(&submwil, sip_subscribe_mwi_destroy); 31959 ASTOBJ_CONTAINER_DESTROY(&submwil); 31960 31961 /* 31962 * Wait awhile for the TCP/TLS thread container to become empty. 31963 * 31964 * XXX This is a hack, but the worker threads cannot be created 31965 * joinable. They can die on their own and remove themselves 31966 * from the container thus resulting in a huge memory leak. 31967 */ 31968 wait_count = 1000; 31969 while (ao2_container_count(threadt) && --wait_count) { 31970 sched_yield(); 31971 } 31972 if (!wait_count) { 31973 ast_debug(2, "TCP/TLS thread container did not become empty :(\n"); 31974 } 31975 31976 ao2_t_ref(bogus_peer, -1, "unref the bogus_peer"); 31977 31978 ao2_t_ref(peers, -1, "unref the peers table"); 31979 ao2_t_ref(peers_by_ip, -1, "unref the peers_by_ip table"); 31980 ao2_t_ref(dialogs, -1, "unref the dialogs table"); 31981 ao2_t_ref(dialogs_to_destroy, -1, "unref dialogs_to_destroy"); 31982 ao2_t_ref(threadt, -1, "unref the thread table"); 31983 ao2_t_ref(sip_monitor_instances, -1, "unref the sip_monitor_instances table"); 31984 31985 clear_sip_domains(); 31986 ast_free_ha(sip_cfg.contact_ha); 31987 close(sipsock); 31988 sched_context_destroy(sched); 31989 con = ast_context_find(used_context); 31990 if (con) { 31991 ast_context_destroy(con, "SIP"); 31992 } 31993 ast_unload_realtime("sipregs"); 31994 ast_unload_realtime("sippeers"); 31995 ast_cc_monitor_unregister(&sip_cc_monitor_callbacks); 31996 ast_cc_agent_unregister(&sip_cc_agent_callbacks); 31997 31998 sip_reqresp_parser_exit(); 31999 sip_unregister_tests(); 32000 32001 return 0; 32002 }
| 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 3128 of file chan_sip.c.
References ao2_t_ref.
Referenced by __sip_destroy(), _sip_qualify_peer(), _sip_show_peer(), _sip_show_peers(), 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().
03129 { 03130 ao2_t_ref(peer, -1, tag); 03131 return NULL; 03132 }
| 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 6291 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().
06292 { 06293 char name[256]; 06294 int *inuse = NULL, *call_limit = NULL, *inringing = NULL; 06295 int outgoing = fup->outgoing_call; 06296 struct sip_peer *p = NULL; 06297 06298 ast_debug(3, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming"); 06299 06300 06301 /* Test if we need to check call limits, in order to avoid 06302 realtime lookups if we do not need it */ 06303 if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT) && !ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD)) 06304 return 0; 06305 06306 ast_copy_string(name, fup->username, sizeof(name)); 06307 06308 /* Check the list of devices */ 06309 if (fup->relatedpeer) { 06310 p = ref_peer(fup->relatedpeer, "ref related peer for update_call_counter"); 06311 inuse = &p->inUse; 06312 call_limit = &p->call_limit; 06313 inringing = &p->inRinging; 06314 ast_copy_string(name, fup->peername, sizeof(name)); 06315 } 06316 if (!p) { 06317 ast_debug(2, "%s is not a local device, no call limit\n", name); 06318 return 0; 06319 } 06320 06321 switch(event) { 06322 /* incoming and outgoing affects the inUse counter */ 06323 case DEC_CALL_LIMIT: 06324 /* Decrement inuse count if applicable */ 06325 if (inuse) { 06326 sip_pvt_lock(fup); 06327 ao2_lock(p); 06328 if (*inuse > 0) { 06329 if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) { 06330 (*inuse)--; 06331 ast_clear_flag(&fup->flags[0], SIP_INC_COUNT); 06332 } 06333 } else { 06334 *inuse = 0; 06335 } 06336 ao2_unlock(p); 06337 sip_pvt_unlock(fup); 06338 } 06339 06340 /* Decrement ringing count if applicable */ 06341 if (inringing) { 06342 sip_pvt_lock(fup); 06343 ao2_lock(p); 06344 if (*inringing > 0) { 06345 if (ast_test_flag(&fup->flags[0], SIP_INC_RINGING)) { 06346 (*inringing)--; 06347 ast_clear_flag(&fup->flags[0], SIP_INC_RINGING); 06348 } 06349 } else { 06350 *inringing = 0; 06351 } 06352 ao2_unlock(p); 06353 sip_pvt_unlock(fup); 06354 } 06355 06356 /* Decrement onhold count if applicable */ 06357 sip_pvt_lock(fup); 06358 ao2_lock(p); 06359 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && sip_cfg.notifyhold) { 06360 ast_clear_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD); 06361 ao2_unlock(p); 06362 sip_pvt_unlock(fup); 06363 sip_peer_hold(fup, FALSE); 06364 } else { 06365 ao2_unlock(p); 06366 sip_pvt_unlock(fup); 06367 } 06368 if (sipdebug) 06369 ast_debug(2, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", "peer", name, *call_limit); 06370 break; 06371 06372 case INC_CALL_RINGING: 06373 case INC_CALL_LIMIT: 06374 /* If call limit is active and we have reached the limit, reject the call */ 06375 if (*call_limit > 0 ) { 06376 if (*inuse >= *call_limit) { 06377 ast_log(LOG_NOTICE, "Call %s %s '%s' rejected due to usage limit of %d\n", outgoing ? "to" : "from", "peer", name, *call_limit); 06378 unref_peer(p, "update_call_counter: unref peer p, call limit exceeded"); 06379 return -1; 06380 } 06381 } 06382 if (inringing && (event == INC_CALL_RINGING)) { 06383 sip_pvt_lock(fup); 06384 ao2_lock(p); 06385 if (!ast_test_flag(&fup->flags[0], SIP_INC_RINGING)) { 06386 (*inringing)++; 06387 ast_set_flag(&fup->flags[0], SIP_INC_RINGING); 06388 } 06389 ao2_unlock(p); 06390 sip_pvt_unlock(fup); 06391 } 06392 if (inuse) { 06393 sip_pvt_lock(fup); 06394 ao2_lock(p); 06395 if (!ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) { 06396 (*inuse)++; 06397 ast_set_flag(&fup->flags[0], SIP_INC_COUNT); 06398 } 06399 ao2_unlock(p); 06400 sip_pvt_unlock(fup); 06401 } 06402 if (sipdebug) { 06403 ast_debug(2, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", "peer", name, *inuse, *call_limit); 06404 } 06405 break; 06406 06407 case DEC_CALL_RINGING: 06408 if (inringing) { 06409 sip_pvt_lock(fup); 06410 ao2_lock(p); 06411 if (ast_test_flag(&fup->flags[0], SIP_INC_RINGING)) { 06412 if (*inringing > 0) { 06413 (*inringing)--; 06414 } 06415 ast_clear_flag(&fup->flags[0], SIP_INC_RINGING); 06416 } 06417 ao2_unlock(p); 06418 sip_pvt_unlock(fup); 06419 } 06420 break; 06421 06422 default: 06423 ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event); 06424 } 06425 06426 if (p) { 06427 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", p->name); 06428 unref_peer(p, "update_call_counter: unref_peer from call counter"); 06429 } 06430 return 0; 06431 }
| 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 13523 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().
13524 { 13525 13526 if (!ast_test_flag(&p->flags[0], SIP_SENDRPID)) { 13527 return; 13528 } 13529 if (!p->owner->connected.id.number.valid 13530 || ast_strlen_zero(p->owner->connected.id.number.str)) { 13531 return; 13532 } 13533 13534 append_history(p, "ConnectedLine", "%s party is now %s <%s>", 13535 ast_test_flag(&p->flags[0], SIP_OUTGOING) ? "Calling" : "Called", 13536 S_COR(p->owner->connected.id.name.valid, p->owner->connected.id.name.str, ""), 13537 S_COR(p->owner->connected.id.number.valid, p->owner->connected.id.number.str, "")); 13538 13539 if (p->owner->_state == AST_STATE_UP || ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 13540 struct sip_request req; 13541 13542 if (!p->pendinginvite && (p->invitestate == INV_CONFIRMED || p->invitestate == INV_TERMINATED)) { 13543 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 13544 13545 add_header(&req, "Allow", ALLOWED_METHODS); 13546 add_supported_header(p, &req); 13547 add_rpid(&req, p); 13548 add_sdp(&req, p, FALSE, TRUE, FALSE); 13549 13550 initialize_initreq(p, &req); 13551 p->lastinvite = p->ocseq; 13552 ast_set_flag(&p->flags[0], SIP_OUTGOING); 13553 p->invitestate = INV_CALLING; 13554 send_request(p, &req, XMIT_CRITICAL, p->ocseq); 13555 } else if ((is_method_allowed(&p->allowed_methods, SIP_UPDATE)) && (!ast_strlen_zero(p->okcontacturi))) { 13556 reqprep(&req, p, SIP_UPDATE, 0, 1); 13557 add_rpid(&req, p); 13558 add_header(&req, "X-Asterisk-rpid-update", "Yes"); 13559 send_request(p, &req, XMIT_CRITICAL, p->ocseq); 13560 } else { 13561 /* We cannot send the update yet, so we have to wait until we can */ 13562 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 13563 } 13564 } else { 13565 ast_set_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND); 13566 if (ast_test_flag(&p->flags[1], SIP_PAGE2_RPID_IMMEDIATE)) { 13567 struct sip_request resp; 13568 13569 if ((p->owner->_state == AST_STATE_RING) && !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT)) { 13570 ast_clear_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND); 13571 respprep(&resp, p, "180 Ringing", &p->initreq); 13572 add_rpid(&resp, p); 13573 send_response(p, &resp, XMIT_UNRELIABLE, 0); 13574 ast_set_flag(&p->flags[0], SIP_RINGING); 13575 } else if (p->owner->_state == AST_STATE_RINGING) { 13576 ast_clear_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND); 13577 respprep(&resp, p, "183 Session Progress", &p->initreq); 13578 add_rpid(&resp, p); 13579 send_response(p, &resp, XMIT_UNRELIABLE, 0); 13580 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 13581 } else { 13582 ast_debug(1, "Unable able to send update to '%s' in state '%s'\n", p->owner->name, ast_state2str(p->owner->_state)); 13583 } 13584 } 13585 } 13586 }
| static void update_peer | ( | struct sip_peer * | p, | |
| int | expire | |||
| ) | [static] |
Update peer data in database (if used).
Definition at line 5035 of file chan_sip.c.
References ast_test_flag, realtime_update_peer(), and sip_cfg.
Referenced by register_verify().
05036 { 05037 int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 05038 if (sip_cfg.peer_rtupdate && 05039 (p->is_realtime || rtcachefriends)) { 05040 realtime_update_peer(p->name, &p->addr, p->username, p->fullcontact, p->useragent, expire, p->deprecated_username, p->lastms); 05041 } 05042 }
| static void update_peer_lastmsgssent | ( | struct sip_peer * | peer, | |
| int | value, | |||
| int | locked | |||
| ) | [static] |
Definition at line 15296 of file chan_sip.c.
References ao2_lock, and ao2_unlock.
Referenced by register_verify(), and sip_send_mwi_to_peer().
15297 { 15298 if (!locked) { 15299 ao2_lock(peer); 15300 } 15301 peer->lastmsgssent = value; 15302 if (!locked) { 15303 ao2_unlock(peer); 15304 } 15305 }
| static void update_provisional_keepalive | ( | struct sip_pvt * | pvt, | |
| int | with_sdp | |||
| ) | [static] |
Definition at line 4492 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().
04493 { 04494 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")); 04495 04496 pvt->provisional_keepalive_sched_id = ast_sched_add(sched, PROVIS_KEEPALIVE_TIMEOUT, 04497 with_sdp ? send_provisional_keepalive_with_sdp : send_provisional_keepalive, dialog_ref(pvt, "Increment refcount to pass dialog pointer to sched callback")); 04498 }
| 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 13509 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().
13510 { 13511 struct sip_request resp; 13512 13513 if (p->owner->_state == AST_STATE_UP || ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 13514 return; 13515 } 13516 13517 respprep(&resp, p, "181 Call is being forwarded", &p->initreq); 13518 add_diversion_header(&resp, p); 13519 send_response(p, &resp, XMIT_UNRELIABLE, 0); 13520 }
struct _map_x_s allowoverlapstr[] [static] |
Definition at line 17604 of file chan_sip.c.
int apeerobjs = 0 [static] |
Autocreated peer objects
Definition at line 766 of file chan_sip.c.
char* app_dtmfmode = "SIPDtmfMode" [static] |
Definition at line 30140 of file chan_sip.c.
char* app_sipaddheader = "SIPAddHeader" [static] |
Definition at line 30141 of file chan_sip.c.
char* app_sipremoveheader = "SIPRemoveHeader" [static] |
Definition at line 30142 of file chan_sip.c.
struct sip_auth_container* authl = NULL [static] |
Authentication container for realm authentication.
Definition at line 1135 of file chan_sip.c.
int authlimit = DEFAULT_AUTHLIMIT [static] |
Definition at line 564 of file chan_sip.c.
int authtimeout = DEFAULT_AUTHTIMEOUT [static] |
Definition at line 565 of file chan_sip.c.
| struct ast_sockaddr bindaddr |
UDP: The address we bind to
Definition at line 1157 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 1114 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 759 of file chan_sip.c.
struct epa_static_data cc_epa_static_data [static] |
Definition at line 898 of file chan_sip.c.
unsigned int chan_idx [static] |
used in naming sip channel
Definition at line 707 of file chan_sip.c.
struct ast_custom_function checksipdomain_function [static] |
{
.name = "CHECKSIPDOMAIN",
.read = func_check_sipdomain,
}
Definition at line 20080 of file chan_sip.c.
struct ast_cli_entry cli_sip[] [static] |
SIP Cli commands definition.
Definition at line 30717 of file chan_sip.c.
const char config[] = "sip.conf" [static] |
Main configuration file
Definition at line 579 of file chan_sip.c.
struct ast_sockaddr debugaddr [static] |
Definition at line 1201 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 680 of file chan_sip.c.
char default_engine[256] [static] |
Default RTP engine
Definition at line 691 of file chan_sip.c.
int default_expiry = DEFAULT_DEFAULT_EXPIRY [static] |
Definition at line 560 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 682 of file chan_sip.c.
int default_fromdomainport [static] |
Default domain port on outbound messages
Definition at line 683 of file chan_sip.c.
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled.
Definition at line 569 of file chan_sip.c.
char default_language[MAX_LANGUAGE] [static] |
Default language setting for new channels
Definition at line 679 of file chan_sip.c.
int default_maxcallbitrate [static] |
Maximum bitrate for call
Definition at line 692 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 687 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 688 of file chan_sip.c.
char default_mwi_from[80] [static] |
Default caller ID for MWI updates
Definition at line 681 of file chan_sip.c.
char default_notifymime[AST_MAX_EXTENSION] [static] |
Default MIME media type for MWI notify messages
Definition at line 684 of file chan_sip.c.
char default_parkinglot[AST_MAX_CONTEXT] [static] |
Parkinglot
Definition at line 690 of file chan_sip.c.
struct ast_codec_pref default_prefs [static] |
Default codec prefs
Definition at line 693 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 695 of file chan_sip.c.
const int DEFAULT_PUBLISH_EXPIRES = 3600 [static] |
Definition at line 941 of file chan_sip.c.
int default_qualify [static] |
Default Qualify= setting
Definition at line 686 of file chan_sip.c.
struct ast_tls_config default_tls_cfg [static] |
Default TLS connection configuration.
Definition at line 2200 of file chan_sip.c.
unsigned int default_transports [static] |
Default Transports (enum sip_transport) that are acceptable
Definition at line 694 of file chan_sip.c.
char default_vmexten[AST_MAX_EXTENSION] [static] |
Default From Username on MWI updates
Definition at line 685 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 1101 of file chan_sip.c.
| struct ao2_container* dialogs_to_destroy |
This container holds the dialogs that will be destroyed immediately.
Definition at line 1091 of file chan_sip.c.
struct _map_x_s dtmfstr[] [static] |
mapping between dtmf flags and strings
Definition at line 17569 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 730 of file chan_sip.c.
int esc_etag_counter [static] |
Used to create new entity IDs by ESCs.
Definition at line 940 of file chan_sip.c.
const int ESC_MAX_BUCKETS = 37 [static] |
Definition at line 975 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 1182 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 1186 of file chan_sip.c.
char externhost[MAXHOSTNAMELEN] [static] |
External host name
Definition at line 1185 of file chan_sip.c.
int externrefresh = 10 [static] |
Refresh timer for DNS-based external address (dyndns)
Definition at line 1187 of file chan_sip.c.
uint16_t externtcpport [static] |
external tcp port
Definition at line 1188 of file chan_sip.c.
uint16_t externtlsport [static] |
external tls port
Definition at line 1189 of file chan_sip.c.
struct _map_x_s faxecmodes[] [static] |
Definition at line 18045 of file chan_sip.c.
int global_authfailureevents [static] |
Whether we send authentication failure manager events or not. Default no.
Definition at line 734 of file chan_sip.c.
unsigned int global_autoframing [static] |
Turn autoframing on or off.
Definition at line 738 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 718 of file chan_sip.c.
unsigned int global_cos_audio [static] |
802.1p class of service for audio RTP packets
Definition at line 726 of file chan_sip.c.
unsigned int global_cos_sip [static] |
802.1p class of service for SIP packets
Definition at line 725 of file chan_sip.c.
unsigned int global_cos_text [static] |
802.1p class of service for text RTP packets
Definition at line 728 of file chan_sip.c.
unsigned int global_cos_video [static] |
802.1p class of service for video RTP packets
Definition at line 727 of file chan_sip.c.
int global_dynamic_exclude_static = 0 [static] |
Exclude static peers from contact registrations
Definition at line 750 of file chan_sip.c.
struct ast_flags global_flags[3] = {{0}} [static] |
global SIP_ flags
Definition at line 770 of file chan_sip.c.
struct ast_jb_conf global_jbconf [static] |
Global jitterbuffer configuration
Definition at line 577 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 708 of file chan_sip.c.
int global_max_se [static] |
Highest threshold for session refresh interval
Definition at line 746 of file chan_sip.c.
int global_min_se [static] |
Lowest threshold for session refresh interval
Definition at line 745 of file chan_sip.c.
int global_prematuremediafilter [static] |
Enable/disable premature frames in a call (causing 183 early media)
Definition at line 711 of file chan_sip.c.
int global_qualify_gap [static] |
Time between our group of peer pokes
Definition at line 740 of file chan_sip.c.
int global_qualify_peers [static] |
Number of peers to poke at a given time
Definition at line 741 of file chan_sip.c.
int global_qualifyfreq [static] |
Qualify frequency
Definition at line 739 of file chan_sip.c.
int global_reg_timeout [static] |
Global time between attempts for outbound registrations
Definition at line 715 of file chan_sip.c.
int global_regattempts_max [static] |
Registration attempts before giving up
Definition at line 716 of file chan_sip.c.
int global_relaxdtmf [static] |
Relax DTMF
Definition at line 710 of file chan_sip.c.
int global_rtpholdtimeout [static] |
Time out call if no RTP during hold
Definition at line 713 of file chan_sip.c.
int global_rtpkeepalive [static] |
Send RTP keepalives
Definition at line 714 of file chan_sip.c.
int global_rtptimeout [static] |
Time out call if no RTP
Definition at line 712 of file chan_sip.c.
char global_sdpowner[AST_MAX_EXTENSION] [static] |
SDP owner name for the SIP channel
Definition at line 733 of file chan_sip.c.
char global_sdpsession[AST_MAX_EXTENSION] [static] |
SDP session name for the SIP channel
Definition at line 732 of file chan_sip.c.
int global_shrinkcallerid [static] |
enable or disable shrinking of caller id
Definition at line 717 of file chan_sip.c.
enum st_mode global_st_mode [static] |
Mode of operation for Session-Timers
Definition at line 743 of file chan_sip.c.
enum st_refresher_param global_st_refresher [static] |
Session-Timer refresher
Definition at line 744 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 748 of file chan_sip.c.
int global_t1 [static] |
T1 time
Definition at line 735 of file chan_sip.c.
int global_t1min [static] |
T1 roundtrip time minimum
Definition at line 736 of file chan_sip.c.
int global_t38_maxdatagram [static] |
global T.38 FaxMaxDatagram override
Definition at line 771 of file chan_sip.c.
int global_timer_b [static] |
Timer B - RFC 3261 Section 17.1.1.2
Definition at line 737 of file chan_sip.c.
unsigned int global_tos_audio [static] |
IP type of service for audio RTP packets
Definition at line 722 of file chan_sip.c.
unsigned int global_tos_sip [static] |
IP type of service for SIP packets
Definition at line 721 of file chan_sip.c.
unsigned int global_tos_text [static] |
IP type of service for text RTP packets
Definition at line 724 of file chan_sip.c.
unsigned int global_tos_video [static] |
IP type of service for video RTP packets
Definition at line 723 of file chan_sip.c.
char global_useragent[AST_MAX_EXTENSION] [static] |
Useragent for the SIP channel
Definition at line 731 of file chan_sip.c.
const int HASH_DIALOG_SIZE = 563 [static] |
Definition at line 828 of file chan_sip.c.
const int HASH_PEER_SIZE = 563 [static] |
Size of peer hash table, prime number preferred!
Definition at line 827 of file chan_sip.c.
struct _map_x_s insecurestr[] [static] |
Definition at line 17590 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 1165 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 794 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 1197 of file chan_sip.c.
int max_expiry = DEFAULT_MAX_EXPIRY [static] |
Maximum accepted registration time
Definition at line 559 of file chan_sip.c.
struct ast_sockaddr media_address [static] |
External RTP IP address if we are behind NAT
Definition at line 1183 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 558 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 788 of file chan_sip.c.
int mwi_expiry = DEFAULT_MWI_EXPIRY [static] |
Definition at line 561 of file chan_sip.c.
int network_change_event_sched_id = -1 [static] |
Definition at line 774 of file chan_sip.c.
struct ast_event_sub* network_change_event_subscription [static] |
subscription id for network change events
Definition at line 773 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 580 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 1203 of file chan_sip.c.
int ourport_tcp [static] |
The port used for TCP connections
Definition at line 1199 of file chan_sip.c.
int ourport_tls [static] |
The port used for TCP/TLS connections
Definition at line 1200 of file chan_sip.c.
struct ao2_container* peers [static] |
The peer list: Users, Peers and Friends.
Definition at line 1110 of file chan_sip.c.
struct ao2_container* peers_by_ip [static] |
Definition at line 1111 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 31666 of file chan_sip.c.
unsigned int recordhistory [static] |
Record SIP history. Off by default
Definition at line 729 of file chan_sip.c.
struct _map_x_s referstatusstrings[] [static] |
Definition at line 809 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 767 of file chan_sip.c.
struct _map_x_s regstatestrings[] [static] |
Definition at line 13588 of file chan_sip.c.
int rpeerobjs = 0 [static] |
Realtime peers
Definition at line 765 of file chan_sip.c.
| struct sched_context* sched |
The scheduling context
Definition at line 793 of file chan_sip.c.
Definition at line 832 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 833 of file chan_sip.c.
struct ast_cc_agent_callbacks sip_cc_agent_callbacks [static] |
Definition at line 1649 of file chan_sip.c.
struct ast_cc_monitor_callbacks sip_cc_monitor_callbacks [static] |
Definition at line 1916 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 698 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 31671 of file chan_sip.c.
struct ast_custom_function sip_header_function [static] |
{
.name = "SIP_HEADER",
.read = func_header_read,
}
Definition at line 20061 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 1843 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 790 of file chan_sip.c.
enum channelreloadreason sip_reloadreason [static] |
Reason for last reload/load of configuration
Definition at line 791 of file chan_sip.c.
struct ast_rtp_glue sip_rtp_glue [static] |
Definition at line 30131 of file chan_sip.c.
struct ast_tcptls_session_args sip_tcp_desc [static] |
The TCP server definition.
Definition at line 2203 of file chan_sip.c.
| struct ast_channel_tech sip_tech |
Definition of this channel for PBX channel registration.
Definition at line 1603 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 1638 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 2197 of file chan_sip.c.
struct ast_tcptls_session_args sip_tls_desc [static] |
The TCP/TLS server definition.
Definition at line 2214 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 3327 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 20245 of file chan_sip.c.
enum sip_debug_e sipdebug [static] |
Definition at line 801 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 807 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 20179 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 1155 of file chan_sip.c.
int* sipsock_read_id [static] |
ID of IO entry for sipsock FD
Definition at line 795 of file chan_sip.c.
int speerobjs = 0 [static] |
Static peers
Definition at line 764 of file chan_sip.c.
| enum sip_cc_notify_state state |
Definition at line 853 of file chan_sip.c.
| const char* state_string |
Definition at line 854 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 17030 of file chan_sip.c.
struct _map_x_s strefresher_params[] [static] |
Definition at line 17048 of file chan_sip.c.
struct _map_x_s strefreshers[] [static] |
Definition at line 17055 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 1107 of file chan_sip.c.
int unauth_sessions = 0 [static] |
Definition at line 563 of file chan_sip.c.
char used_context[AST_MAX_CONTEXT] [static] |
name of automatically created context for unloading
Definition at line 776 of file chan_sip.c.
1.6.1