Implementation of Session Initiation Protocol. More...
#include "asterisk.h"#include <signal.h>#include <sys/signal.h>#include <regex.h>#include <inttypes.h>#include "asterisk/network.h"#include "asterisk/paths.h"#include "asterisk/lock.h"#include "asterisk/config.h"#include "asterisk/module.h"#include "asterisk/pbx.h"#include "asterisk/sched.h"#include "asterisk/io.h"#include "asterisk/rtp_engine.h"#include "asterisk/udptl.h"#include "asterisk/acl.h"#include "asterisk/manager.h"#include "asterisk/callerid.h"#include "asterisk/cli.h"#include "asterisk/musiconhold.h"#include "asterisk/dsp.h"#include "asterisk/features.h"#include "asterisk/srv.h"#include "asterisk/astdb.h"#include "asterisk/causes.h"#include "asterisk/utils.h"#include "asterisk/file.h"#include "asterisk/astobj2.h"#include "asterisk/dnsmgr.h"#include "asterisk/devicestate.h"#include "asterisk/monitor.h"#include "asterisk/netsock2.h"#include "asterisk/localtime.h"#include "asterisk/abstract_jb.h"#include "asterisk/threadstorage.h"#include "asterisk/translate.h"#include "asterisk/ast_version.h"#include "asterisk/event.h"#include "asterisk/cel.h"#include "asterisk/data.h"#include "asterisk/aoc.h"#include "sip/include/sip.h"#include "sip/include/globals.h"#include "sip/include/config_parser.h"#include "sip/include/reqresp_parser.h"#include "sip/include/sip_utils.h"#include "sip/include/srtp.h"#include "sip/include/sdp_crypto.h"#include "asterisk/ccss.h"#include "asterisk/xml.h"#include "sip/include/dialog.h"#include "sip/include/dialplan_functions.h"Go to the source code of this file.
Data Structures | |
| struct | ast_register_list |
| The register list: Other SIP proxies we register with and receive calls from. More... | |
| struct | ast_subscription_mwi_list |
| The MWI subscription list. More... | |
| struct | cfsip_methods |
| The core structure to setup dialogs. We parse incoming messages by using structure and then route the messages according to the type. More... | |
| struct | cfsubscription_types |
Subscription types that we support. We support
| |
| struct | event_state_compositor |
| The Event State Compositors. More... | |
| struct | invstate2stringtable |
| Readable descriptions of device states. More... | |
| struct | match_req_args |
| struct | show_peers_context |
| Used in the sip_show_peers functions to pass parameters. More... | |
| struct | sip_reasons |
| Diversion header reasons. More... | |
Defines | |
| #define | SIP_PEDANTIC_DECODE(str) |
Variables | |
| static int | authlimit = DEFAULT_AUTHLIMIT |
| static int | authtimeout = DEFAULT_AUTHTIMEOUT |
| static int | can_parse_xml |
| static unsigned int | chan_idx |
| static const char | config [] = "sip.conf" |
| static int | default_expiry = DEFAULT_DEFAULT_EXPIRY |
| static struct ast_jb_conf | default_jbconf |
| Global jitterbuffer configuration - by default, jb is disabled. | |
| static unsigned int | dumphistory |
| static int | global_authfailureevents |
| static unsigned int | global_autoframing |
| static int | global_callcounter |
| static unsigned int | global_cos_audio |
| static unsigned int | global_cos_sip |
| static unsigned int | global_cos_text |
| static unsigned int | global_cos_video |
| static int | global_dynamic_exclude_static = 0 |
| static struct ast_jb_conf | global_jbconf |
| static int | global_match_auth_username |
| static int | global_max_se |
| static int | global_min_se |
| static int | global_prematuremediafilter |
| static int | global_qualify_gap |
| static int | global_qualify_peers |
| static int | global_qualifyfreq |
| static int | global_reg_retry_403 |
| static int | global_reg_timeout |
| static int | global_regattempts_max |
| static int | global_relaxdtmf |
| static int | global_rtpholdtimeout |
| static int | global_rtpkeepalive |
| static int | global_rtptimeout |
| static char | global_sdpowner [AST_MAX_EXTENSION] |
| static char | global_sdpsession [AST_MAX_EXTENSION] |
| static int | global_shrinkcallerid |
| static enum st_mode | global_st_mode |
| static enum st_refresher_param | global_st_refresher |
| static int | global_store_sip_cause |
| static int | global_t1 |
| static int | global_t1min |
| static int | global_timer_b |
| static unsigned int | global_tos_audio |
| static unsigned int | global_tos_sip |
| static unsigned int | global_tos_text |
| static unsigned int | global_tos_video |
| static char | global_useragent [AST_MAX_EXTENSION] |
| static struct invstate2stringtable | invitestate2string [] |
| Readable descriptions of device states. | |
| static int | max_expiry = DEFAULT_MAX_EXPIRY |
| static int | min_expiry = DEFAULT_MIN_EXPIRY |
| static int | mwi_expiry = DEFAULT_MWI_EXPIRY |
| static const char | notify_config [] = "sip_notify.conf" |
| static unsigned int | recordhistory |
| static struct sip_settings | sip_cfg |
| static struct cfsip_methods | sip_methods [] |
| The core structure to setup dialogs. We parse incoming messages by using structure and then route the messages according to the type. | |
| static struct sip_reasons | sip_reason_table [] |
| Diversion header reasons. | |
| static struct cfsubscription_types | subscription_types [] |
Subscription types that we support. We support
| |
| static int | unauth_sessions = 0 |
DefaultSettings | |
| static char | default_callerid [AST_MAX_EXTENSION] |
| static char | default_engine [256] |
| static char | default_fromdomain [AST_MAX_EXTENSION] |
| static int | default_fromdomainport |
| static char | default_language [MAX_LANGUAGE] |
| static int | default_maxcallbitrate |
| static char | default_mohinterpret [MAX_MUSICCLASS] |
| static char | default_mohsuggest [MAX_MUSICCLASS] |
| static char | default_mwi_from [80] |
| static char | default_notifymime [AST_MAX_EXTENSION] |
| static char | default_parkinglot [AST_MAX_CONTEXT] |
| static struct ast_codec_pref | default_prefs |
| static unsigned int | default_primary_transport |
| static int | default_qualify |
| static unsigned int | default_transports |
| static char | default_vmexten [AST_MAX_EXTENSION] |
Object counters @{ | |
| |
| #define | append_history(p, event, fmt, args...) append_history_full(p, "%-15s " fmt, event, ## args) |
| Append to SIP dialog history. | |
| #define | BOGUS_PEER_MD5SECRET "intentionally_invalid_md5_string" |
| We can recognise the bogus peer by this invalid MD5 hash. | |
| #define | CHECK_AUTH_BUF_INITLEN 256 |
| #define | check_request_transport(peer, tmpl) |
| generic function for determining if a correct transport is being used to contact a peer | |
| #define | CONTAINER_UNLINK(container, obj, tag) |
| Unlink the given object from the container and return TRUE if it was in the container. | |
| #define | DATA_EXPORT_SIP_PEER(MEMBER) |
| #define | FORMAT "%-15.15s %-15.15s %-15.15s %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s %-10.10s\n" |
| #define | FORMAT "%-30.30s %-12.12s %-10.10s %-10.10s\n" |
| #define | FORMAT "%-15.15s %-11.11s %-8.8s %-10.10u%-1.1s %-10.10u (%5.2f%%) %-6.4lf %-10.10u%-1.1s %-10.10u (%5.2f%%) %-6.4lf\n" |
| #define | FORMAT "%-39.39s %-6.6s %-12.12s %8d %-20.20s %-25.25s\n" |
| #define | FORMAT "%-40.40s %-20.20s %-16.16s\n" |
| #define | FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" |
| #define | FORMAT "%-47.47s %-9.9s %-6.6s\n" |
| #define | FORMAT "%-25.25s %-15.15s %-15.15s \n" |
| #define | FORMAT2 "%-15.15s %-15.15s %-15.15s %-15.15s %-7.7s %-15.15s %-10.10s %-10.10s\n" |
| #define | FORMAT2 "%-15.15s %-11.11s %-8.8s %-10.10s %-10.10s ( %%) %-6.6s %-10.10s %-10.10s ( %%) %-6.6s\n" |
| #define | FORMAT2 "%-39.39s %-6.6s %-12.12s %8.8s %-20.20s %-25.25s\n" |
| #define | FORMAT2 "%-47.47s %9.9s %6.6s\n" |
| #define | FORMAT2 "%-25.25s %-15.15s %-15.15s \n" |
| #define | FORMAT3 "%-15.15s %-15.15s %-15.15s %-15.15s %-13.13s %-15.15s %-10.10s %-6.6s\n" |
| #define | FORMAT4 "%-15.15s %-15.15s %-15.15s %-15.15s %-13.13s %-15.15s %-10.10s %-6.6d\n" |
| #define | PEERS_FORMAT2 "%-25.25s %-39.39s %-3.3s %-10.10s %-3.3s %-8s %-10s %s\n" |
| #define | sip_pvt_lock(x) ao2_lock(x) |
| #define | sip_pvt_trylock(x) ao2_trylock(x) |
| #define | sip_pvt_unlock(x) ao2_unlock(x) |
| #define | UNLINK(element, head, prev) |
| enum | match_req_res { SIP_REQ_MATCH, SIP_REQ_NOT_MATCH, SIP_REQ_LOOP_DETECTED } |
| enum | message_integrity { MESSAGE_INVALID, MESSAGE_FRAGMENT, MESSAGE_FRAGMENT_COMPLETE, MESSAGE_COMPLETE } |
Indication of a TCP message's integrity. More... | |
| enum | peer_unlink_flag_t { SIP_PEERS_MARKED, SIP_PEERS_ALL } |
| static struct _map_x_s | allowoverlapstr [] |
| static int | apeerobjs = 0 |
| static char * | app_dtmfmode = "SIPDtmfMode" |
| static char * | app_sipaddheader = "SIPAddHeader" |
| static char * | app_sipremoveheader = "SIPRemoveHeader" |
| static struct sip_auth_container * | authl = NULL |
| Authentication container for realm authentication. | |
| struct ast_sockaddr | bindaddr |
| static struct sip_peer * | bogus_peer |
| A bogus peer, to be used when authentication should fail. | |
| static struct epa_static_data | cc_epa_static_data |
| static struct ast_custom_function | checksipdomain_function |
| static struct ast_cli_entry | cli_sip [] |
| SIP Cli commands definition. | |
| static struct ast_sockaddr | debugaddr |
| static const int | DEFAULT_PUBLISH_EXPIRES = 3600 |
| static struct ast_tls_config | default_tls_cfg |
| Default TLS connection configuration. | |
| static struct ao2_container * | dialogs |
| Here we implement the container for dialogs (sip_pvt), defining generic wrapper functions to ease the transition from the current implementation (a single linked list) to a different container. In addition to a reference to the container, we need functions to lock/unlock the container and individual items, and functions to add/remove references to the individual items. | |
| struct ao2_container * | dialogs_to_destroy |
| static struct _map_x_s | dtmfstr [] |
| mapping between dtmf flags and strings | |
| static int | esc_etag_counter |
| static const int | ESC_MAX_BUCKETS = 37 |
| static struct event_state_compositor | event_state_compositors [] |
| The Event State Compositors. | |
| static struct ast_sockaddr | externaddr |
| our external IP address/port for SIP sessions. externaddr.sin_addr is only set when we know we might be behind a NAT, and this is done using a variety of (mutually exclusive) ways from the config file: | |
| static time_t | externexpire |
| static char | externhost [MAXHOSTNAMELEN] |
| static int | externrefresh = 10 |
| static uint16_t | externtcpport |
| static uint16_t | externtlsport |
| static struct _map_x_s | faxecmodes [] |
| static struct ast_flags | global_flags [3] = {{0}} |
| static unsigned int | global_t38_maxdatagram |
| static const int | HASH_DIALOG_SIZE = 563 |
| static const int | HASH_PEER_SIZE = 563 |
| static struct _map_x_s | insecurestr [] |
| static struct ast_sockaddr | internip |
| our (internal) default address/port to put in SIP/SDP messages internip is initialized picking a suitable address from one of the interfaces, and the same port number we bind to. It is used as the default address/port in SIP messages, and as the default address (but not port) in SDP messages. | |
| static struct io_context * | io |
| static struct ast_ha * | localaddr |
| List of local networks We store "localnet" addresses from the config file into an access list, marked as 'DENY', so the call to ast_apply_ha() will return AST_SENSE_DENY for 'local' addresses, and AST_SENSE_ALLOW for 'non local' (i.e. presumably public) addresses. | |
| static struct ast_sockaddr | media_address |
| static pthread_t | monitor_thread = AST_PTHREADT_NULL |
| This is the thread for the monitor which checks for input on the channels which are not currently in use. | |
| static int | network_change_event_sched_id = -1 |
| static struct ast_event_sub * | network_change_event_subscription |
| static struct ast_config * | notify_types = NULL |
| static int | ourport_tcp |
| static int | ourport_tls |
| static struct ao2_container * | peers |
| The peer list: Users, Peers and Friends. | |
| static struct ao2_container * | peers_by_ip |
| static struct ast_data_handler | peers_data_provider |
| static struct _map_x_s | referstatusstrings [] |
| static struct ast_register_list | regl |
| The register list: Other SIP proxies we register with and receive calls from. | |
| static int | regobjs = 0 |
| static struct _map_x_s | regstatestrings [] |
| static int | rpeerobjs = 0 |
| struct sched_context * | sched |
| static struct ast_cc_agent_callbacks | sip_cc_agent_callbacks |
| static struct ast_cc_monitor_callbacks | sip_cc_monitor_callbacks |
| struct { | |
| enum sip_cc_notify_state state | |
| const char * state_string | |
| } | sip_cc_notify_state_map [] |
| struct { | |
| enum ast_cc_service_type service | |
| const char * service_string | |
| } | sip_cc_service_map [] |
| static struct ast_data_entry | sip_data_providers [] |
| static struct ast_custom_function | sip_header_function |
| struct ao2_container * | sip_monitor_instances |
| static int | sip_reloading = FALSE |
| static enum channelreloadreason | sip_reloadreason |
| static struct ast_rtp_glue | sip_rtp_glue |
| static struct ast_tcptls_session_args | sip_tcp_desc |
| The TCP server definition. | |
| struct ast_channel_tech | sip_tech |
| Definition of this channel for PBX channel registration. | |
| struct ast_channel_tech | sip_tech_info |
| This version of the sip channel tech has no send_digit_begin callback so that the core knows that the channel does not want DTMF BEGIN frames. The struct is initialized just before registering the channel driver, and is for use with channels using SIP INFO DTMF. | |
| static struct ast_tls_config | sip_tls_cfg |
| Working TLS connection configuration. | |
| static struct ast_tcptls_session_args | sip_tls_desc |
| The TCP/TLS server definition. | |
| static struct ast_udptl_protocol | sip_udptl |
| Interface structure with callbacks used to connect to UDPTL module. | |
| static struct ast_custom_function | sipchaninfo_function |
| Structure to declare a dialplan function: SIPCHANINFO. | |
| static enum sip_debug_e | sipdebug |
| static int | sipdebug_text |
| extra debugging for 'text' related events. At the moment this is set together with sip_debug_console. | |
| static struct ast_custom_function | sippeer_function |
| Structure to declare a dialplan function: SIPPEER. | |
| static int | sipsock = -1 |
| Main socket for UDP SIP communication. | |
| static int * | sipsock_read_id |
| static int | speerobjs = 0 |
| static struct _map_x_s | stmodes [] |
| Report Peer status in character string. | |
| static struct _map_x_s | strefresher_params [] |
| static struct _map_x_s | strefreshers [] |
| static struct ast_subscription_mwi_list | submwil |
| The MWI subscription list. | |
| static struct ao2_container * | threadt |
| The table of TCP threads. | |
| static struct _map_x_s | trust_id_outboundstr [] |
| static char | used_context [AST_MAX_CONTEXT] |
| static const char * | __get_header (const struct sip_request *req, const char *name, int *start) |
| static int | __set_address_from_contact (const char *fullcontact, struct ast_sockaddr *addr, int tcp) |
| int | __sip_ack (struct sip_pvt *p, uint32_t seqno, int resp, int sipmethod) |
| Acknowledges receipt of a packet and stops retransmission called with p locked. | |
| static int | __sip_autodestruct (const void *data) |
| Kill a SIP dialog (called only by the scheduler) The scheduler has a reference to this dialog when p->autokillid != -1, and we are called using that reference. So if the event is not rescheduled, we need to call dialog_unref(). | |
| void | __sip_destroy (struct sip_pvt *p, int lockowner, int lockdialoglist) |
| Execute destruction of SIP dialog structure, release memory. | |
| static int | __sip_do_register (struct sip_registry *r) |
| Register with SIP proxy. | |
| void | __sip_pretend_ack (struct sip_pvt *p) |
| Pretend to ack all packets called with p locked. | |
| static int | __sip_reliable_xmit (struct sip_pvt *p, uint32_t seqno, int resp, struct ast_str *data, int fatal, int sipmethod) |
| int | __sip_semi_ack (struct sip_pvt *p, uint32_t seqno, int resp, int sipmethod) |
| Acks receipt of packet, keep it around (used for provisional responses). | |
| static int | __sip_subscribe_mwi_do (struct sip_subscription_mwi *mwi) |
| Actually setup an MWI subscription or resubscribe. | |
| static int | __sip_xmit (struct sip_pvt *p, struct ast_str *data) |
| static int | __transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
| Base transmit response function. | |
| static char * | _sip_qualify_peer (int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[]) |
| Send qualify message to peer from cli or manager. Mostly for debugging. | |
| static char * | _sip_show_peer (int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[]) |
| Show one peer in detail (main function). | |
| static char * | _sip_show_peers (int fd, int *total, struct mansession *s, const struct message *m, int argc, const char *argv[]) |
| Execute sip show peers command. | |
| static struct sip_peer * | _sip_show_peers_one (int fd, struct mansession *s, struct show_peers_context *cont, struct sip_peer *peer) |
| Emit informations for one peer during sip show peers command. | |
| static void * | _sip_tcp_helper_thread (struct ast_tcptls_session_instance *tcptls_session) |
| SIP TCP thread management function This function reads from the socket, parses the packet into a request. | |
| static void | add_blank (struct sip_request *req) |
| add a blank line if no body | |
| static void | add_cc_call_info_to_response (struct sip_pvt *p, struct sip_request *resp) |
| static void | add_codec_to_sdp (const struct sip_pvt *p, format_t codec, struct ast_str **m_buf, struct ast_str **a_buf, int debug, int *min_packet_size) |
| Add codec offer to SDP offer/answer body in INVITE or 200 OK. | |
| static int | add_content (struct sip_request *req, const char *line) |
| Add content (not header) to SIP message. | |
| static int | add_digit (struct sip_request *req, char digit, unsigned int duration, int mode) |
| Add DTMF INFO tone to sip message Mode = 0 for application/dtmf-relay (Cisco) 1 for application/dtmf. | |
| static void | add_diversion_header (struct sip_request *req, struct sip_pvt *pvt) |
| Add "Diversion" header to outgoing message. | |
| static int | add_header (struct sip_request *req, const char *var, const char *value) |
| Add header to SIP message. | |
| static int | add_header_max_forwards (struct sip_pvt *dialog, struct sip_request *req) |
| Add 'Max-Forwards' header to SIP message. | |
| static void | add_noncodec_to_sdp (const struct sip_pvt *p, int format, struct ast_str **m_buf, struct ast_str **a_buf, int debug) |
| Add RFC 2833 DTMF offer to SDP. | |
| static void | add_peer_mailboxes (struct sip_peer *peer, const char *value) |
| static void | add_peer_mwi_subs (struct sip_peer *peer) |
| static void | add_realm_authentication (struct sip_auth_container **credentials, const char *configuration, int lineno) |
| static void | add_required_respheader (struct sip_request *req) |
| static void | add_route (struct sip_request *req, struct sip_route *route) |
| Add route header into request per learned route. | |
| static int | add_rpid (struct sip_request *req, struct sip_pvt *p) |
| Add Remote-Party-ID header to SIP message. | |
| static enum sip_result | add_sdp (struct sip_request *resp, struct sip_pvt *p, int oldsdp, int add_audio, int add_t38) |
| Add Session Description Protocol message. | |
| static int | add_sip_domain (const char *domain, const enum domain_mode mode, const char *context) |
| Add SIP domain to list of domains we are responsible for. | |
| static int | add_supported_header (struct sip_pvt *pvt, struct sip_request *req) |
| Add "Supported" header to sip message. Since some options may be disabled in the config, the sip_pvt must be inspected to determine what is supported for this dialog. | |
| static void | add_tcodec_to_sdp (const struct sip_pvt *p, int codec, struct ast_str **m_buf, struct ast_str **a_buf, int debug, int *min_packet_size) |
| Add text codec offer to SDP offer/answer body in INVITE or 200 OK. | |
| static int | add_text (struct sip_request *req, const char *text) |
| Add text body to SIP message. | |
| static struct ast_variable * | add_var (const char *buf, struct ast_variable *list) |
| implement the setvar config line | |
| static void | add_vcodec_to_sdp (const struct sip_pvt *p, format_t codec, struct ast_str **m_buf, struct ast_str **a_buf, int debug, int *min_packet_size) |
| Add video codec offer to SDP offer/answer body in INVITE or 200 OK. | |
| static int | add_vidupdate (struct sip_request *req) |
| add XML encoded media control with update | |
| static int | addr_is_multicast (const struct ast_sockaddr *addr) |
| Check if an ip is an multicast IP. addr the address to check. | |
| static const char * | allowoverlap2str (int mode) |
| Convert AllowOverlap setting to printable string. | |
| static void | append_date (struct sip_request *req) |
| Append date to SIP message. | |
| static void | append_history_full (struct sip_pvt *p, const char *fmt,...) |
| Append to SIP dialog history with arg list. | |
| static void | append_history_va (struct sip_pvt *p, const char *fmt, va_list ap) |
| Append to SIP dialog history with arg list. | |
| static int | apply_directmedia_ha (struct sip_pvt *p1, struct sip_pvt *p2, const char *op) |
| AST_DATA_STRUCTURE (sip_peer, DATA_EXPORT_SIP_PEER) | |
| AST_LIST_HEAD_NOLOCK (sip_history_head, sip_history) | |
| AST_LIST_HEAD_STATIC (epa_static_data_list, epa_backend) | |
| static | AST_LIST_HEAD_STATIC (domain_list, domain) |
| AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER,"Session Initiation Protocol (SIP)",.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DRIVER,.nonoptreq="res_crypto,chan_local",) | |
| AST_MUTEX_DEFINE_STATIC (authl_lock) | |
| Global authentication container protection while adjusting the references. | |
| AST_MUTEX_DEFINE_STATIC (sip_reload_lock) | |
| AST_MUTEX_DEFINE_STATIC (monlock) | |
| Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical. | |
| AST_MUTEX_DEFINE_STATIC (netlock) | |
| static void | ast_quiet_chan (struct ast_channel *chan) |
| Turn off generator data XXX Does this function belong in the SIP channel? | |
| static void | ast_sip_ouraddrfor (const struct ast_sockaddr *them, struct ast_sockaddr *us, struct sip_pvt *p) |
| NAT fix - decide which IP address to use for Asterisk server? | |
| static int | ast_sockaddr_resolve_first (struct ast_sockaddr *addr, const char *name, int flag) |
| Return the first entry from ast_sockaddr_resolve filtered by family of binddaddr. | |
| static int | ast_sockaddr_resolve_first_af (struct ast_sockaddr *addr, const char *name, int flag, int family) |
| Return the first entry from ast_sockaddr_resolve filtered by address family. | |
| static int | ast_sockaddr_resolve_first_transport (struct ast_sockaddr *addr, const char *name, int flag, unsigned int transport) |
| Return the first entry from ast_sockaddr_resolve filtered by family of binddaddr. | |
| AST_THREADSTORAGE (check_auth_buf) | |
| AST_THREADSTORAGE_CUSTOM (ts_temp_pvt, temp_pvt_init, temp_pvt_cleanup) | |
| A per-thread temporary pvt structure. | |
| static int | attempt_transfer (struct sip_dual *transferer, struct sip_dual *target) |
| Attempt transfer of SIP call This fix for attended transfers on a local PBX. | |
| static void | auth_headers (enum sip_auth_type code, char **header, char **respheader) |
| return the request and response header for a 401 or 407 code | |
| static int | auto_congest (const void *arg) |
| Scheduled congestion on a call. Only called by the scheduler, must return the reference when done. | |
| static void | build_callid_pvt (struct sip_pvt *pvt) |
| Build SIP Call-ID value for a non-REGISTER transaction. | |
| static void | build_callid_registry (struct sip_registry *reg, const struct ast_sockaddr *ourip, const char *fromdomain) |
| Build SIP Call-ID value for a REGISTER transaction. | |
| static void | build_contact (struct sip_pvt *p) |
| Build contact header - the contact header we send out. | |
| static void | build_localtag_registry (struct sip_registry *reg) |
| Build SIP From tag value for REGISTER. | |
| static struct sip_peer * | build_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime, int devstate_only) |
| Build peer from configuration (file or realtime static/dynamic). | |
| static int | build_reply_digest (struct sip_pvt *p, int method, char *digest, int digest_len) |
| Build reply digest. | |
| static void | build_route (struct sip_pvt *p, struct sip_request *req, int backwards, int resp) |
| Build route list from Record-Route header. | |
| static void | build_via (struct sip_pvt *p) |
| Build a Via header for a request. | |
| static int | cb_extensionstate (char *context, char *exten, int state, void *data) |
| Callback for the devicestate notification (SUBSCRIBE) support subsystem. | |
| static void | cb_extensionstate_destroy (int id, void *data) |
| static void | cc_epa_destructor (void *data) |
| static void | cc_handle_publish_error (struct sip_pvt *pvt, const int resp, struct sip_request *req, struct sip_epa_entry *epa_entry) |
| static void | change_callid_pvt (struct sip_pvt *pvt, const char *callid) |
| static void | change_hold_state (struct sip_pvt *dialog, struct sip_request *req, int holdstate, int sendonly) |
| Change hold state for a call. | |
| static void | change_redirecting_information (struct sip_pvt *p, struct sip_request *req, struct ast_party_redirecting *redirecting, struct ast_set_party_redirecting *update_redirecting, int set_call_forward) |
| update redirecting information for a channel based on headers | |
| static void | change_t38_state (struct sip_pvt *p, int state) |
| Change the T38 state on a SIP dialog. | |
| static enum check_auth_result | check_auth (struct sip_pvt *p, struct sip_request *req, const char *username, const char *secret, const char *md5secret, int sipmethod, const char *uri, enum xmittype reliable, int ignore) |
| Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set). | |
| static enum message_integrity | check_message_integrity (struct ast_str **request, struct ast_str **overflow) |
| Check that a message received over TCP is a full message. | |
| static enum check_auth_result | check_peer_ok (struct sip_pvt *p, char *of, struct sip_request *req, int sipmethod, struct ast_sockaddr *addr, struct sip_peer **authpeer, enum xmittype reliable, char *calleridname, char *uri2) |
| Validate device authentication. | |
| static void | check_pendings (struct sip_pvt *p) |
| Check pending actions on SIP call. | |
| static void | check_rtp_timeout (struct sip_pvt *dialog, time_t t) |
| helper function for the monitoring thread -- seems to be called with the assumption that the dialog is locked | |
| static int | check_sip_domain (const char *domain, char *context, size_t len) |
| check_sip_domain: Check if domain part of uri is local to our server | |
| static int | check_user (struct sip_pvt *p, struct sip_request *req, int sipmethod, const char *uri, enum xmittype reliable, struct ast_sockaddr *addr) |
| Find user If we get a match, this will add a reference pointer to the user object in ASTOBJ, that needs to be unreferenced. | |
| static enum check_auth_result | check_user_full (struct sip_pvt *p, struct sip_request *req, int sipmethod, const char *uri, enum xmittype reliable, struct ast_sockaddr *addr, struct sip_peer **authpeer) |
| Check if matching user or peer is defined Match user on From: user name and peer on IP/port This is used on first invite (not re-invites) and subscribe requests. | |
| static void | check_via (struct sip_pvt *p, const struct sip_request *req) |
| check Via: header for hostname, port and rport request/answer | |
| static attribute_unused void | check_via_response (struct sip_pvt *p, struct sip_request *req) |
| check received= and rport= in a SIP response. If we get a response with received= and/or rport= in the Via: line, use them as 'p->ourip' (see RFC 3581 for rport, and RFC 3261 for received). Using these two fields SIP can produce the correct address and port in the SIP headers without the need for STUN. The address part is also reused for the media sessions. Note that ast_sip_ouraddrfor() still rewrites p->ourip if you specify externaddr/seternaddr/. | |
| static void | cleanup_all_regs (void) |
| static void | cleanup_stale_contexts (char *new, char *old) |
| Destroy disused contexts between reloads Only used in reload_config so the code for regcontext doesn't get ugly. | |
| static void | clear_peer_mailboxes (struct sip_peer *peer) |
| static void | clear_sip_domains (void) |
| Clear our domain list (at reload). | |
| static char * | complete_sip_peer (const char *word, int state, int flags2) |
| Do completion on peer name. | |
| static char * | complete_sip_registered_peer (const char *word, int state, int flags2) |
| Do completion on registered peer name. | |
| static char * | complete_sip_show_history (const char *line, const char *word, int pos, int state) |
| Support routine for 'sip show history' CLI. | |
| static char * | complete_sip_show_peer (const char *line, const char *word, int pos, int state) |
| Support routine for 'sip show peer' CLI. | |
| static char * | complete_sip_show_user (const char *line, const char *word, int pos, int state) |
| Support routine for 'sip show user' CLI. | |
| static char * | complete_sip_unregister (const char *line, const char *word, int pos, int state) |
| Support routine for 'sip unregister' CLI. | |
| static char * | complete_sip_user (const char *word, int state) |
| Do completion on user name. | |
| static char * | complete_sipch (const char *line, const char *word, int pos, int state) |
| Support routine for 'sip show channel' and 'sip show history' CLI This is in charge of generating all strings that match a prefix in the given position. As many functions of this kind, each invokation has O(state) time complexity so be careful in using it. | |
| static char * | complete_sipnotify (const char *line, const char *word, int pos, int state) |
| Support routine for 'sip notify' CLI. | |
| static int | construct_pidf_body (enum sip_cc_publish_state state, char *pidf_body, size_t size, const char *presentity) |
| static int | copy_all_header (struct sip_request *req, const struct sip_request *orig, const char *field) |
| Copy all headers from one request to another. | |
| static int | copy_header (struct sip_request *req, const struct sip_request *orig, const char *field) |
| Copy one header field from one request to another. | |
| static void | copy_request (struct sip_request *dst, const struct sip_request *src) |
| copy SIP request (mostly used to save request for responses) | |
| static void | copy_socket_data (struct sip_socket *to_sock, const struct sip_socket *from_sock) |
| static struct ast_variable * | copy_vars (struct ast_variable *src) |
| duplicate a list of channel variables, | |
| static int | copy_via_headers (struct sip_pvt *p, struct sip_request *req, const struct sip_request *orig, const char *field) |
| Copy SIP VIA Headers from the request to the response. | |
| static int | create_addr (struct sip_pvt *dialog, const char *opeer, struct ast_sockaddr *addr, int newdialog) |
| create address structure from device name Or, if peer not found, find it in the global DNS returns TRUE (-1) on failure, FALSE on success | |
| static int | create_addr_from_peer (struct sip_pvt *dialog, struct sip_peer *peer) |
| Create address structure from peer reference. This function copies data from peer to the dialog, so we don't have to look up the peer again from memory or database during the life time of the dialog. | |
| static struct sip_epa_entry * | create_epa_entry (const char *const event_package, const char *const destination) |
| static struct sip_esc_entry * | create_esc_entry (struct event_state_compositor *esc, struct sip_request *req, const int expires) |
| static void | create_new_sip_etag (struct sip_esc_entry *esc_entry, int is_linked) |
| static int | default_sip_port (enum sip_transport type) |
| The default sip port for the given transport. | |
| static void | deinit_req (struct sip_request *req) |
| Deinitialize SIP response/request. | |
| static void | destroy_association (struct sip_peer *peer) |
| Remove registration data from realtime database or AST/DB when registration expires. | |
| static void | destroy_escs (void) |
| static void | destroy_mailbox (struct sip_mailbox *mailbox) |
| static void | destroy_realm_authentication (void *obj) |
| static int | determine_firstline_parts (struct sip_request *req) |
| Parse first line of incoming SIP request. | |
| static enum sip_publish_type | determine_sip_publish_type (struct sip_request *req, const char *const event, const char *const etag, const char *const expires, int *expires_int) |
| static int | dialog_cmp_cb (void *obj, void *arg, int flags) |
| static int | dialog_dump_func (void *userobj, void *arg, int flags) |
| static int | dialog_find_multiple (void *obj, void *arg, int flags) |
| static int | dialog_hash_cb (const void *obj, const int flags) |
| static int | dialog_initialize_rtp (struct sip_pvt *dialog) |
| Initialize RTP portion of a dialog. | |
| static int | dialog_needdestroy (void *dialogobj, void *arg, int flags) |
| Match dialogs that need to be destroyed. | |
| struct sip_pvt * | dialog_ref_debug (struct sip_pvt *p, char *tag, char *file, int line, const char *func) |
| void | dialog_unlink_all (struct sip_pvt *dialog) |
| Unlink a dialog from the dialogs container, as well as any other places that it may be currently stored. | |
| static int | dialog_unlink_callback (void *obj, void *arg, int flags) |
| struct sip_pvt * | dialog_unref_debug (struct sip_pvt *p, char *tag, char *file, int line, const char *func) |
| static void | disable_dsp_detect (struct sip_pvt *p) |
| static void | display_nat_warning (const char *cat, int reason, struct ast_flags *flags) |
| static int | do_magic_pickup (struct ast_channel *channel, const char *extension, const char *context) |
| static void * | do_monitor (void *data) |
| The SIP monitoring thread. | |
| static int | do_proxy_auth (struct sip_pvt *p, struct sip_request *req, enum sip_auth_type code, int sipmethod, int init) |
| Add authentication on outbound SIP packet. | |
| static int | do_register_auth (struct sip_pvt *p, struct sip_request *req, enum sip_auth_type code) |
| Authenticate for outbound registration. | |
| static void | do_setnat (struct sip_pvt *p) |
| Set nat mode on the various data sockets. | |
| static const char * | domain_mode_to_text (const enum domain_mode mode) |
| Print domain mode to cli. | |
| static const char * | dtmfmode2str (int mode) |
| Convert DTMF mode to printable string. | |
| static void | enable_dsp_detect (struct sip_pvt *p) |
| static int | esc_cmp_fn (void *obj, void *arg, int flags) |
| static void | esc_entry_destructor (void *obj) |
| static int | esc_hash_fn (const void *obj, const int flags) |
| static int | expire_register (const void *data) |
| Expire registration of SIP peer. | |
| static void | extract_host_from_hostport (char **hostport) |
| Terminate a host:port at the ':'. | |
| static void | extract_uri (struct sip_pvt *p, struct sip_request *req) |
| Check Contact: URI of SIP message. | |
| static const char * | faxec2str (int faxec) |
| static int | finalize_content (struct sip_request *req) |
| Add 'Content-Length' header and content to SIP message. | |
| static const char * | find_alias (const char *name, const char *_default) |
| Find compressed SIP alias. | |
| static int | find_by_callid_helper (void *obj, void *arg, int flags) |
| static int | find_by_name (void *obj, void *arg, void *data, int flags) |
| static int | find_by_notify_uri_helper (void *obj, void *arg, int flags) |
| static int | find_by_subscribe_uri_helper (void *obj, void *arg, int flags) |
| static struct sip_pvt * | find_call (struct sip_request *req, struct ast_sockaddr *addr, const int intended_method) |
| find or create a dialog structure for an incoming SIP message. Connect incoming SIP message to current dialog or create new dialog structure Returns a reference to the sip_pvt object, remember to give it back once done. Called by handle_request_do | |
| static int | find_calling_channel (void *obj, void *arg, void *data, int flags) |
| Find the channel that is causing the RINGING update. | |
| const char * | find_closing_quote (const char *start, const char *lim) |
| Locate closing quote in a string, skipping escaped quotes. optionally with a limit on the search. start must be past the first quote. | |
| static struct sip_peer * | find_peer (const char *peer, struct ast_sockaddr *addr, int realtime, int which_objects, int devstate_only, int transport) |
| Locate device by name or ip address. | |
| static struct sip_auth * | find_realm_authentication (struct sip_auth_container *credentials, const char *realm) |
| static int | find_sdp (struct sip_request *req) |
| Determine whether a SIP message contains an SDP in its body. | |
| static struct ast_cc_agent * | find_sip_cc_agent_by_notify_uri (const char *const uri) |
| static struct ast_cc_agent * | find_sip_cc_agent_by_original_callid (struct sip_pvt *pvt) |
| static struct ast_cc_agent * | find_sip_cc_agent_by_subscribe_uri (const char *const uri) |
| static int | find_sip_method (const char *msg) |
| find_sip_method: Find SIP method from header | |
| static int | find_sip_monitor_instance_by_subscription_pvt (void *obj, void *arg, int flags) |
| static int | find_sip_monitor_instance_by_suspension_entry (void *obj, void *arg, int flags) |
| static struct epa_static_data * | find_static_data (const char *const event_package) |
| static struct cfsubscription_types * | find_subscription_type (enum subscriptiontype subtype) |
| Find subscription type in array. | |
| static void | free_old_route (struct sip_route *route) |
| Remove route from route list. | |
| static int | func_check_sipdomain (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
| Dial plan function to check if domain is local. | |
| static int | func_header_read (struct ast_channel *chan, const char *function, char *data, char *buf, size_t len) |
| Read SIP header (dialplan function). | |
| static int | function_sipchaninfo_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
| ${SIPCHANINFO()} Dialplan function - reads sip channel data | |
| static int | function_sippeer (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
| ${SIPPEER()} Dialplan function - reads peer data | |
| static char * | generate_random_string (char *buf, size_t size) |
| Generate 32 byte random string for callid's etc. | |
| static char * | generate_uri (struct sip_pvt *pvt, char *buf, size_t size) |
| static int | get_address_family_filter (unsigned int transport) |
| Helper for dns resolution to filter by address family. | |
| static int | get_also_info (struct sip_pvt *p, struct sip_request *oreq) |
| Call transfer support (old way, deprecated by the IETF). | |
| static char * | get_body (struct sip_request *req, char *name, char delimiter) |
| Get a specific line from the message body. | |
| static char * | get_body_by_line (const char *line, const char *name, int nameLen, char delimiter) |
| Reads one line of SIP message body. | |
| static int | get_cached_mwi (struct sip_peer *peer, int *new, int *old) |
| Get cached MWI info. | |
| static void | get_crypto_attrib (struct sip_srtp *srtp, const char **a_crypto) |
| static enum sip_get_dest_result | get_destination (struct sip_pvt *p, struct sip_request *oreq, int *cc_recall_core_id) |
| Find out who the call is for. | |
| static int | get_domain (const char *str, char *domain, int len) |
| Extract domain from SIP To/From header. | |
| static struct event_state_compositor * | get_esc (const char *const event_package) |
| static struct sip_esc_entry * | get_esc_entry (const char *entity_tag, struct event_state_compositor *esc) |
| static const char * | get_header (const struct sip_request *req, const char *name) |
| Get header from SIP request. | |
| static struct ast_variable * | get_insecure_variable_from_config (struct ast_config *config) |
| static struct ast_variable * | get_insecure_variable_from_sippeers (const char *column, const char *value) |
| static struct ast_variable * | get_insecure_variable_from_sipregs (const char *column, const char *value, struct ast_variable **var) |
| static int | get_ip_and_port_from_sdp (struct sip_request *req, const enum media_type media, struct ast_sockaddr *addr) |
| static int | get_msg_text (char *buf, int len, struct sip_request *req) |
| Get message body from a SIP request. | |
| static const char * | get_name_from_variable (const struct ast_variable *var) |
| static void | get_our_media_address (struct sip_pvt *p, int needvideo, int needtext, struct ast_sockaddr *addr, struct ast_sockaddr *vaddr, struct ast_sockaddr *taddr, struct ast_sockaddr *dest, struct ast_sockaddr *vdest, struct ast_sockaddr *tdest) |
| Set all IP media addresses for this call. | |
| static int | get_pai (struct sip_pvt *p, struct sip_request *req) |
| Parse the parts of the P-Asserted-Identity header on an incoming packet. Returns 1 if a valid header is found and it is different from the current caller id. | |
| static int | get_rdnis (struct sip_pvt *p, struct sip_request *oreq, char **name, char **number, int *reason) |
| Get referring dnis. | |
| static void | get_realm (struct sip_pvt *p, const struct sip_request *req) |
| Choose realm based on From header and then To header or use globaly configured realm. Realm from From/To header should be listed among served domains in config file: domain=... | |
| static int | get_refer_info (struct sip_pvt *transferer, struct sip_request *outgoing_req) |
| Call transfer support (the REFER method) Extracts Refer headers into pvt dialog structure. | |
| static int | get_rpid (struct sip_pvt *p, struct sip_request *oreq) |
| Get name, number and presentation from remote party id header, returns true if a valid header was found and it was different from the current caller id. | |
| static const char * | get_sdp_iterate (int *start, struct sip_request *req, const char *name) |
| Lookup 'name' in the SDP starting at the 'start' line. Returns the matching line, and 'start' is updated with the next line number. | |
| static char | get_sdp_line (int *start, int stop, struct sip_request *req, const char **value) |
| Fetches the next valid SDP line between the 'start' line (inclusive) and the 'stop' line (exclusive). Returns the type ('a', 'c', ...) and matching line in reference 'start' is updated with the next line number. | |
| static struct sip_pvt * | get_sip_pvt_byid_locked (const char *callid, const char *totag, const char *fromtag) |
| Lock dialog lock and find matching pvt lock. | |
| static const char * | get_srv_protocol (enum sip_transport t) |
| Return protocol string for srv dns query. | |
| static const char * | get_srv_service (enum sip_transport t) |
| Return service string for srv dns query. | |
| static const char * | get_transport (enum sip_transport t) |
| Return transport as string. | |
| static const char * | get_transport_list (unsigned int transports) |
| Return configuration of transports for a device. | |
| static const char * | get_transport_pvt (struct sip_pvt *p) |
| Return transport of dialog. | |
| static int | get_transport_str2enum (const char *transport) |
| Return int representing a bit field of transport types found in const char *transport. | |
| static const char * | gettag (const struct sip_request *req, const char *header, char *tagbuf, int tagbufsize) |
| Get tag from packet. | |
| static int | handle_cc_notify (struct sip_pvt *pvt, struct sip_request *req) |
| static int | handle_cc_subscribe (struct sip_pvt *p, struct sip_request *req) |
| static int | handle_common_options (struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v) |
| Handle flag-type options common to configuration of devices - peers. | |
| static int | handle_incoming (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, int *recount, int *nounlock) |
| Handle incoming SIP requests (methods). | |
| static int | handle_invite_replaces (struct sip_pvt *p, struct sip_request *req, int debug, uint32_t seqno, struct ast_sockaddr *addr, int *nounlock) |
| Handle the transfer part of INVITE with a replaces: header, meaning a target pickup or an attended transfer. Used only once. XXX 'ignore' is unused. | |
| static int | handle_request_bye (struct sip_pvt *p, struct sip_request *req) |
| Handle incoming BYE request. | |
| static int | handle_request_cancel (struct sip_pvt *p, struct sip_request *req) |
| Handle incoming CANCEL request. | |
| static int | handle_request_do (struct sip_request *req, struct ast_sockaddr *addr) |
| Handle incoming SIP message - request or response. | |
| static void | handle_request_info (struct sip_pvt *p, struct sip_request *req) |
| Receive SIP INFO Message. | |
| static int | handle_request_invite (struct sip_pvt *p, struct sip_request *req, int debug, uint32_t seqno, struct ast_sockaddr *addr, int *recount, const char *e, int *nounlock) |
| Handle incoming INVITE request. | |
| static int | handle_request_invite_st (struct sip_pvt *p, struct sip_request *req, const char *required, int reinvite) |
| static int | handle_request_message (struct sip_pvt *p, struct sip_request *req) |
| Handle incoming MESSAGE request. | |
| static int | handle_request_notify (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, uint32_t seqno, const char *e) |
| Handle incoming notifications. | |
| static int | handle_request_options (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, const char *e) |
| Handle incoming OPTIONS request An OPTIONS request should be answered like an INVITE from the same UA, including SDP. | |
| static int | handle_request_publish (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, const uint32_t seqno, const char *uri) |
| static int | handle_request_refer (struct sip_pvt *p, struct sip_request *req, int debug, uint32_t seqno, int *nounlock) |
| static int | handle_request_register (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, const char *e) |
| Handle incoming REGISTER request. | |
| static int | handle_request_subscribe (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, uint32_t seqno, const char *e) |
| Handle incoming SUBSCRIBE request. | |
| static int | handle_request_update (struct sip_pvt *p, struct sip_request *req) |
| bare-bones support for SIP UPDATE | |
| static void | handle_response (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno) |
| Handle SIP response in dialogue. | |
| static void | handle_response_info (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno) |
| static void | handle_response_invite (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno) |
| Handle SIP response to INVITE dialogue. | |
| static void | handle_response_message (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno) |
| static void | handle_response_notify (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno) |
| static void | handle_response_peerpoke (struct sip_pvt *p, int resp, struct sip_request *req) |
| Handle qualification responses (OPTIONS). | |
| static void | handle_response_publish (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno) |
| static void | handle_response_refer (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno) |
| static int | handle_response_register (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno) |
| Handle responses on REGISTER to services. | |
| static void | handle_response_subscribe (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno) |
| static void | handle_response_update (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno) |
| Handle authentication challenge for SIP UPDATE. | |
| static int | handle_sip_publish_initial (struct sip_pvt *p, struct sip_request *req, struct event_state_compositor *esc, const int expires) |
| static int | handle_sip_publish_modify (struct sip_pvt *p, struct sip_request *req, struct event_state_compositor *esc, const char *const etag, const int expires) |
| static int | handle_sip_publish_refresh (struct sip_pvt *p, struct sip_request *req, struct event_state_compositor *esc, const char *const etag, const int expires) |
| static int | handle_sip_publish_remove (struct sip_pvt *p, struct sip_request *req, struct event_state_compositor *esc, const char *const etag) |
| static int | handle_t38_options (struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v, unsigned int *maxdatagram) |
| Handle T.38 configuration options common to users and peers. | |
| const char * | hangup_cause2sip (int cause) |
| Convert Asterisk hangup causes to SIP codes. | |
| int | hangup_sip2cause (int cause) |
| Convert SIP hangup causes to Asterisk hangup causes. | |
| static int | init_req (struct sip_request *req, int sipmethod, const char *recip) |
| Initialize SIP request. | |
| static int | init_resp (struct sip_request *resp, const char *msg) |
| Initialize SIP response, based on SIP request. | |
| static int | initialize_escs (void) |
| static void | initialize_initreq (struct sip_pvt *p, struct sip_request *req) |
| Initialize the initital request packet in the pvt structure. This packet is used for creating replies and future requests in a dialog. | |
| static int | initialize_udptl (struct sip_pvt *p) |
| static void | initreqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod, const char *const explicit_uri) |
| Initiate new SIP request to peer/user. | |
| static const char * | insecure2str (int mode) |
| Convert Insecure setting to printable string. | |
| static int | interpret_t38_parameters (struct sip_pvt *p, const struct ast_control_t38_parameters *parameters) |
| Helper function which updates T.38 capability information and triggers a reinvite. | |
| static int | is_method_allowed (unsigned int *allowed_methods, enum sipmethod method) |
| Check if method is allowed for a device or a dialog. | |
| static void | list_route (struct sip_route *route) |
| List all routes - mostly for debugging. | |
| static int | load_module (void) |
| PBX load module - initialization. | |
| static int | local_attended_transfer (struct sip_pvt *transferer, struct sip_dual *current, struct sip_request *req, uint32_t seqno, int *nounlock) |
| Find all call legs and bridge transferee with target called from handle_request_refer. | |
| static void | lws2sws (struct ast_str *data) |
| Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled. | |
| static void | make_our_tag (struct sip_pvt *pvt) |
| Make our SIP dialog tag. | |
| static int | manager_show_registry (struct mansession *s, const struct message *m) |
| Show SIP registrations in the manager API. | |
| static int | manager_sip_qualify_peer (struct mansession *s, const struct message *m) |
| Qualify SIP peers in the manager API. | |
| static int | manager_sip_show_peer (struct mansession *s, const struct message *m) |
| Show SIP peers in the manager API. | |
| static int | manager_sip_show_peers (struct mansession *s, const struct message *m) |
| Show SIP peers in the manager API. | |
| static int | manager_sipnotify (struct mansession *s, const struct message *m) |
| static int | map_s_x (const struct _map_x_s *table, const char *s, int errorvalue) |
| map from a string to an integer value, case insensitive. If no match is found, return errorvalue. | |
| static const char * | map_x_s (const struct _map_x_s *table, int x, const char *errorstring) |
| map from an integer value to a string. If no match is found, return errorstring | |
| static void | mark_method_allowed (unsigned int *allowed_methods, enum sipmethod method) |
| static void | mark_method_unallowed (unsigned int *allowed_methods, enum sipmethod method) |
| static void | mark_parsed_methods (unsigned int *methods, char *methods_str) |
| static int | match_and_cleanup_peer_sched (void *peerobj, void *arg, int flags) |
| static enum match_req_res | match_req_to_dialog (struct sip_pvt *sip_pvt_ptr, struct match_req_args *arg) |
| static int | method_match (enum sipmethod id, const char *name) |
| returns true if 'name' (with optional trailing whitespace) matches the sip method 'id'. Strictly speaking, SIP methods are case SENSITIVE, but we do a case-insensitive comparison to be more tolerant. following Jon Postel's rule: Be gentle in what you accept, strict with what you send | |
| static void | mwi_event_cb (const struct ast_event *event, void *userdata) |
| Receive MWI events that we have subscribed to. | |
| static void | network_change_event_cb (const struct ast_event *, void *) |
| static int | network_change_event_sched_cb (const void *data) |
| static void | network_change_event_subscribe (void) |
| static void | network_change_event_unsubscribe (void) |
| static struct sip_proxy * | obproxy_get (struct sip_pvt *dialog, struct sip_peer *peer) |
| Get default outbound proxy or global proxy. | |
| static void | on_dns_update_mwi (struct ast_sockaddr *old, struct ast_sockaddr *new, void *data) |
| static void | on_dns_update_peer (struct ast_sockaddr *old, struct ast_sockaddr *new, void *data) |
| static void | on_dns_update_registry (struct ast_sockaddr *old, struct ast_sockaddr *new, void *data) |
| static unsigned int | parse_allowed_methods (struct sip_request *req) |
| parse the Allow header to see what methods the endpoint we are communicating with allows. | |
| static void | parse_copy (struct sip_request *dst, const struct sip_request *src) |
| Copy SIP request, parse it. | |
| static int | parse_minse (const char *p_hdrval, int *const p_interval) |
| Session-Timers: Function for parsing Min-SE header. | |
| static void | parse_moved_contact (struct sip_pvt *p, struct sip_request *req, char **name, char **number, int set_call_forward) |
| Parse 302 Moved temporalily response. | |
| static int | parse_ok_contact (struct sip_pvt *pvt, struct sip_request *req) |
| Save contact header for 200 OK on INVITE. | |
| static enum parse_register_result | parse_register_contact (struct sip_pvt *pvt, struct sip_peer *peer, struct sip_request *req) |
| Parse contact header and save registration (peer registration). | |
| static int | parse_request (struct sip_request *req) |
| Parse a SIP message. | |
| static int | parse_session_expires (const char *p_hdrval, int *const p_interval, enum st_refresher_param *const p_ref) |
| Session-Timers: Function for parsing Session-Expires header. | |
| static int | parse_uri_legacy_check (char *uri, const char *scheme, char **user, char **pass, char **hostport, char **transport) |
| parse uri in a way that allows semicolon stripping if legacy mode is enabled | |
| static int | peer_cmp_cb (void *obj, void *arg, int flags) |
| static int | peer_dump_func (void *userobj, void *arg, int flags) |
| static int | peer_hash_cb (const void *obj, const int flags) |
| static int | peer_ipcmp_cb (void *obj, void *arg, int flags) |
| static int | peer_iphash_cb (const void *obj, const int flags) |
| static void | peer_mailboxes_to_str (struct ast_str **mailbox_str, struct sip_peer *peer) |
| list peer mailboxes to CLI | |
| static int | peer_markall_func (void *device, void *arg, int flags) |
| static void | peer_sched_cleanup (struct sip_peer *peer) |
| static int | peer_status (struct sip_peer *peer, char *status, int statuslen) |
| int | peercomparefunc (const void *a, const void *b) |
| static int | peers_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root) |
| unsigned int | port_str2int (const char *pt, unsigned int standard) |
| converts ascii port to int representation. If no pt buffer is provided or the pt has errors when being converted to an int value, the port provided as the standard is used. | |
| static void | print_codec_to_cli (int fd, struct ast_codec_pref *pref) |
| Print codec list from preference to CLI/manager. | |
| static void | print_group (int fd, ast_group_t group, int crlf) |
| Print call group and pickup group. | |
| static void | proc_422_rsp (struct sip_pvt *p, struct sip_request *rsp) |
| Handle 422 response to INVITE with session-timer requested. | |
| static int | proc_session_timer (const void *vp) |
| Session-Timers: Process session refresh timeout event. | |
| static int | process_crypto (struct sip_pvt *p, struct ast_rtp_instance *rtp, struct sip_srtp **srtp, const char *a) |
| static int | process_sdp (struct sip_pvt *p, struct sip_request *req, int t38action) |
| Process SIP SDP offer, select formats and activate media channels If offer is rejected, we will not change any properties of the call Return 0 on success, a negative value on errors. Must be called after find_sdp(). | |
| static int | process_sdp_a_audio (const char *a, struct sip_pvt *p, struct ast_rtp_codecs *newaudiortp, int *last_rtpmap_codec) |
| static int | process_sdp_a_image (const char *a, struct sip_pvt *p) |
| static int | process_sdp_a_sendonly (const char *a, int *sendonly) |
| static int | process_sdp_a_text (const char *a, struct sip_pvt *p, struct ast_rtp_codecs *newtextrtp, char *red_fmtp, int *red_num_gen, int *red_data_pt, int *last_rtpmap_codec) |
| static int | process_sdp_a_video (const char *a, struct sip_pvt *p, struct ast_rtp_codecs *newvideortp, int *last_rtpmap_codec) |
| static int | process_sdp_c (const char *c, struct ast_sockaddr *addr) |
| static int | process_sdp_o (const char *o, struct sip_pvt *p) |
| static int | process_via (struct sip_pvt *p, const struct sip_request *req) |
| Process the Via header according to RFC 3261 section 18.2.2. | |
| static struct sip_proxy * | proxy_from_config (const char *proxy, int sipconf_lineno, struct sip_proxy *dest) |
| Parse proxy string and return an ao2_alloc'd proxy. If dest is non-NULL, no allocation is performed and dest is used instead. On error NULL is returned. | |
| static int | proxy_update (struct sip_proxy *proxy) |
| static int | publish_expire (const void *data) |
| static void | pvt_set_needdestroy (struct sip_pvt *pvt, const char *reason) |
| static int | read_raw_content_length (const char *message) |
| Get the content length from an unparsed SIP message. | |
| static struct sip_peer * | realtime_peer (const char *newpeername, struct ast_sockaddr *addr, int devstate_only, int which_objects) |
| realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf Checks the "sipregs" realtime family from extconfig.conf if it's configured. This returns a pointer to a peer and because we use build_peer, we can rest assured that the refcount is bumped. | |
| static int | realtime_peer_by_addr (const char **name, struct ast_sockaddr *addr, const char *ipaddr, struct ast_variable **var, struct ast_variable **varregs) |
| static int | realtime_peer_by_name (const char *const *name, struct ast_sockaddr *addr, const char *ipaddr, struct ast_variable **var, struct ast_variable **varregs) |
| static struct ast_variable * | realtime_peer_get_sippeer_helper (const char **name, struct ast_variable **varregs) |
| static void | realtime_update_peer (const char *peername, struct ast_sockaddr *addr, const char *defaultuser, const char *fullcontact, const char *useragent, int expirey, unsigned short deprecated_username, int lastms) |
| Update peer object in realtime storage If the Asterisk system name is set in asterisk.conf, we will use that name and store that in the "regserver" field in the sippeers table to facilitate multi-server setups. | |
| static void | receive_message (struct sip_pvt *p, struct sip_request *req) |
| Receive SIP MESSAGE method messages. | |
| static struct sip_peer * | ref_peer (struct sip_peer *peer, char *tag) |
| static void | ref_proxy (struct sip_pvt *pvt, struct sip_proxy *proxy) |
| maintain proper refcounts for a sip_pvt's outboundproxy | |
| static const char * | referstatus2str (enum referstatus rstatus) |
| Convert transfer status to string. | |
| static void | reg_source_db (struct sip_peer *peer) |
| Get registration details from Asterisk DB. | |
| static void | register_peer_exten (struct sip_peer *peer, int onoff) |
| Automatically add peer extension to dial plan. | |
| static enum check_auth_result | register_verify (struct sip_pvt *p, struct ast_sockaddr *addr, struct sip_request *req, const char *uri) |
Verify registration of user
| |
| static struct sip_registry * | registry_addref (struct sip_registry *reg, char *tag) |
| Add object reference to SIP registry. | |
| static void * | registry_unref (struct sip_registry *reg, char *tag) |
| static const char * | regstate2str (enum sipregistrystate regstate) |
| Convert registration state status to string. | |
| static int | reinvite_timeout (const void *data) |
| static int | reload (void) |
| Part of Asterisk module interface. | |
| static int | reload_config (enum channelreloadreason reason) |
| Re-read SIP.conf config file. | |
| static char * | remove_uri_parameters (char *uri) |
| static int | reply_digest (struct sip_pvt *p, struct sip_request *req, char *header, int sipmethod, char *digest, int digest_len) |
| reply to authentication for outbound registrations | |
| static int | reqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod, uint32_t seqno, int newbranch) |
| Initialize a SIP request message (not the initial one in a dialog). | |
| static int | resp_needs_contact (const char *msg, enum sipmethod method) |
| Test if this response needs a contact header. | |
| static int | respprep (struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req) |
| Prepare SIP response packet. | |
| static int | restart_monitor (void) |
| Start the channel monitor thread. | |
| static void | restart_session_timer (struct sip_pvt *p) |
| Session-Timers: Restart session timer. | |
| static int | retrans_pkt (const void *data) |
| Retransmit SIP message if no answer (Called from scheduler). | |
| static int | send_provisional_keepalive (const void *data) |
| static int | send_provisional_keepalive_full (struct sip_pvt *pvt, int with_sdp) |
| static int | send_provisional_keepalive_with_sdp (const void *data) |
| static int | send_request (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno) |
| static int | send_response (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno) |
| Transmit response on SIP request. | |
| static enum ast_cc_service_type | service_string_to_service_type (const char *const service_string) |
| static int | set_address_from_contact (struct sip_pvt *pvt) |
| Change the other partys IP address based on given contact. | |
| static void | set_destination (struct sip_pvt *p, char *uri) |
| Set destination from SIP URI. | |
| static void | set_insecure_flags (struct ast_flags *flags, const char *value, int lineno) |
| Parse insecure= setting in sip.conf and set flags according to setting. | |
| static void | set_nonce_randdata (struct sip_pvt *p, int forceupdate) |
| builds the sip_pvt's randdata field which is used for the nonce challenge. When forceupdate is not set, the nonce is only updated if the current one is stale. In this case, a stalenonce is one which has already received a response, if a nonce has not received a response it is not always necessary or beneficial to create a new one. | |
| static void | set_peer_defaults (struct sip_peer *peer) |
| Set peer defaults before configuring specific configurations. | |
| static unsigned int | set_pvt_allowed_methods (struct sip_pvt *pvt, struct sip_request *req) |
| static void | set_socket_transport (struct sip_socket *socket, int transport) |
| static void | set_t38_capabilities (struct sip_pvt *p) |
| Set the global T38 capabilities on a SIP dialog structure. | |
| static int | setup_srtp (struct sip_srtp **srtp) |
| static int | show_channels_cb (void *__cur, void *__arg, int flags) |
| callback for show channel|subscription | |
| static int | show_chanstats_cb (void *__cur, void *__arg, int flags) |
| Callback for show_chanstats. | |
| static int | sip_addheader (struct ast_channel *chan, const char *data) |
| Add a SIP header to an outbound INVITE. | |
| struct sip_pvt * | sip_alloc (ast_string_field callid, struct ast_sockaddr *addr, int useglobal_nat, const int intended_method, struct sip_request *req) |
| Allocate sip_pvt structure, set defaults and link in the container. Returns a reference to the object so whoever uses it later must remember to release the reference. | |
| static void | sip_alreadygone (struct sip_pvt *dialog) |
| Encapsulate setting of SIP_ALREADYGONE to be able to trace it with debugging. | |
| static int | sip_answer (struct ast_channel *ast) |
| sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface | |
| static int | sip_call (struct ast_channel *ast, char *dest, int timeout) |
| Initiate SIP call from PBX used from the dial() application. | |
| int | sip_cancel_destroy (struct sip_pvt *p) |
| Cancel destruction of SIP dialog. Be careful as this also absorbs the reference - if you call it from within the scheduler, this might be the last reference. | |
| static void | sip_cc_agent_destructor (struct ast_cc_agent *agent) |
| static int | sip_cc_agent_init (struct ast_cc_agent *agent, struct ast_channel *chan) |
| static int | sip_cc_agent_recall (struct ast_cc_agent *agent) |
| static void | sip_cc_agent_respond (struct ast_cc_agent *agent, enum ast_cc_agent_response_reason reason) |
| static int | sip_cc_agent_start_monitoring (struct ast_cc_agent *agent) |
| static int | sip_cc_agent_start_offer_timer (struct ast_cc_agent *agent) |
| static int | sip_cc_agent_status_request (struct ast_cc_agent *agent) |
| static int | sip_cc_agent_stop_offer_timer (struct ast_cc_agent *agent) |
| static int | sip_cc_monitor_cancel_available_timer (struct ast_cc_monitor *monitor, int *sched_id) |
| static void | sip_cc_monitor_destructor (void *private_data) |
| static int | sip_cc_monitor_request_cc (struct ast_cc_monitor *monitor, int *available_timer_id) |
| static int | sip_cc_monitor_suspend (struct ast_cc_monitor *monitor) |
| static int | sip_cc_monitor_unsuspend (struct ast_cc_monitor *monitor) |
| static int | sip_check_authtimeout (time_t start) |
| Check if the authtimeout has expired. | |
| static char * | sip_cli_notify (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Cli command to send SIP notify to peer. | |
| static int | sip_debug_test_addr (const struct ast_sockaddr *addr) |
| See if we pass debug IP filter. | |
| static int | sip_debug_test_pvt (struct sip_pvt *p) |
| Test PVT for debugging output. | |
| struct sip_pvt * | sip_destroy (struct sip_pvt *p) |
| Destroy SIP call structure. Make it return NULL so the caller can do things like foo = sip_destroy(foo); and reduce the chance of bugs due to dangling pointers. | |
| static void | sip_destroy_fn (void *p) |
| static void | sip_destroy_peer (struct sip_peer *peer) |
| Destroy peer object from memory. | |
| static void | sip_destroy_peer_fn (void *peer) |
| static int | sip_devicestate (void *data) |
| Part of PBX channel interface. | |
| static char * | sip_do_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Turn on SIP debugging (CLI command). | |
| static char * | sip_do_debug_ip (int fd, const char *arg) |
| Enable SIP Debugging for a single IP. | |
| static char * | sip_do_debug_peer (int fd, const char *arg) |
| Turn on SIP debugging for a given peer. | |
| static int | sip_do_reload (enum channelreloadreason reason) |
| Reload module. | |
| static int | sip_dtmfmode (struct ast_channel *chan, const char *data) |
| Set the DTMFmode for an outbound SIP call (application). | |
| static void | sip_dump_history (struct sip_pvt *dialog) |
| Dump SIP history to debug log file at end of lifespan for SIP dialog. | |
| static int | sip_epa_register (const struct epa_static_data *static_data) |
| static void | sip_epa_unregister_all (void) |
| static int | sip_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
| sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links | |
| static const char * | sip_get_callid (struct ast_channel *chan) |
| Deliver SIP call ID for the call. | |
| static int | sip_get_cc_information (struct sip_request *req, char *subscribe_uri, size_t size, enum ast_cc_service_type *service) |
| static format_t | sip_get_codec (struct ast_channel *chan) |
| static enum ast_rtp_glue_result | sip_get_rtp_peer (struct ast_channel *chan, struct ast_rtp_instance **instance) |
| static enum ast_rtp_glue_result | sip_get_trtp_peer (struct ast_channel *chan, struct ast_rtp_instance **instance) |
| static struct ast_udptl * | sip_get_udptl_peer (struct ast_channel *chan) |
| static enum ast_rtp_glue_result | sip_get_vrtp_peer (struct ast_channel *chan, struct ast_rtp_instance **instance) |
| static void | sip_handle_cc (struct sip_pvt *pvt, struct sip_request *req, enum ast_cc_service_type service) |
| static int | sip_hangup (struct ast_channel *ast) |
| sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup | |
| static int | sip_indicate (struct ast_channel *ast, int condition, const void *data, size_t datalen) |
| Play indication to user With SIP a lot of indications is sent as messages, letting the device play the indication - busy signal, congestion etc. | |
| static int | sip_is_xml_parsable (void) |
| static int | sip_monitor_instance_cmp_fn (void *obj, void *arg, int flags) |
| static void | sip_monitor_instance_destructor (void *data) |
| static int | sip_monitor_instance_hash_fn (const void *obj, const int flags) |
| static struct sip_monitor_instance * | sip_monitor_instance_init (int core_id, const char *const subscribe_uri, const char *const peername, const char *const device_name) |
| static const char * | sip_nat_mode (const struct sip_pvt *p) |
| Display SIP nat mode. | |
| static struct ast_channel * | sip_new (struct sip_pvt *i, int state, const char *title, const char *linkedid) |
| Initiate a call in the SIP channel. | |
| static int | sip_notify_allocate (struct sip_pvt *p) |
| Allocate SIP refer structure. | |
| static int | sip_offer_timer_expire (const void *data) |
| static int | sip_park (struct ast_channel *chan1, struct ast_channel *chan2, struct sip_request *req, uint32_t seqno, const char *park_exten, const char *park_context) |
| static void * | sip_park_thread (void *stuff) |
| Park SIP call support function Starts in a new thread, then parks the call XXX Should we add a wait period after streaming audio and before hangup?? Sometimes the audio can't be heard before hangup. | |
| static void | sip_peer_hold (struct sip_pvt *p, int hold) |
| Change onhold state of a peer using a pvt structure. | |
| static int | sip_pickup (struct ast_channel *chan) |
| Pickup a call using the subsystem in features.c This is executed in a separate thread. | |
| static void * | sip_pickup_thread (void *stuff) |
| SIP pickup support function Starts in a new thread, then pickup the call. | |
| static void | sip_poke_all_peers (void) |
| Send a poke to all known peers. | |
| static int | sip_poke_noanswer (const void *data) |
| React to lack of answer to Qualify poke. | |
| static int | sip_poke_peer (struct sip_peer *peer, int force) |
| Check availability of peer, also keep NAT open. | |
| static int | sip_poke_peer_s (const void *data) |
| Poke peer (send qualify to check if peer is alive and well). | |
| static int | sip_prepare_socket (struct sip_pvt *p) |
| static char * | sip_prune_realtime (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Remove temporary realtime objects from memory (CLI). | |
| static struct ast_channel * | sip_pvt_lock_full (struct sip_pvt *pvt) |
| static char * | sip_qualify_peer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Send an OPTIONS packet to a SIP peer. | |
| static int | sip_queryoption (struct ast_channel *chan, int option, void *data, int *datalen) |
| Query an option on a SIP dialog. | |
| static void | sip_queue_hangup_cause (struct sip_pvt *p, int cause) |
| static struct ast_frame * | sip_read (struct ast_channel *ast) |
| Read SIP RTP from channel. | |
| static struct ast_sockaddr * | sip_real_dst (const struct sip_pvt *p) |
| The real destination address for a write. | |
| static const char * | sip_reason_code_to_str (enum AST_REDIRECTING_REASON code) |
| static enum AST_REDIRECTING_REASON | sip_reason_str_to_code (const char *text) |
| static int | sip_refer_allocate (struct sip_pvt *p) |
| Allocate SIP refer structure. | |
| static int | sip_reg_timeout (const void *data) |
| Registration timeout, register again Registered as a timeout handler during transmit_register(), to retransmit the packet if a reply does not come back. This is called by the scheduler so the event is not pending anymore when we are called. | |
| static int | sip_register (const char *value, int lineno) |
| create sip_registry object from register=> line in sip.conf and link into reg container | |
| static void | sip_register_tests (void) |
| SIP test registration. | |
| static void | sip_registry_destroy (struct sip_registry *reg) |
| Destroy registry object Objects created with the register= statement in static configuration. | |
| static int | sip_reinvite_retry (const void *data) |
| Reset the NEEDREINVITE flag after waiting when we get 491 on a Re-invite to avoid race conditions between asterisk servers. Called from the scheduler. | |
| static char * | sip_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Force reload of module from cli. | |
| static int | sip_removeheader (struct ast_channel *chan, const char *data) |
| Remove SIP headers added previously with SipAddHeader application. | |
| static struct ast_channel * | sip_request_call (const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause) |
| PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here. | |
| static int | sip_reregister (const void *data) |
| Update registration with SIP Proxy. Called from the scheduler when the previous registration expires, so we don't have to cancel the pending event. We assume the reference so the sip_registry is valid, since it is stored in the scheduled event anyways. | |
| static struct ast_frame * | sip_rtp_read (struct ast_channel *ast, struct sip_pvt *p, int *faxdetect) |
| Read RTP from network. | |
| static const char * | sip_sanitized_host (const char *host) |
| void | sip_scheddestroy (struct sip_pvt *p, int ms) |
| Schedule destruction of SIP dialog. | |
| void | sip_scheddestroy_final (struct sip_pvt *p, int ms) |
| Schedule final destruction of SIP dialog. This can not be canceled. This function is used to keep a dialog around for a period of time in order to properly respond to any retransmits. | |
| static void | sip_send_all_mwi_subscriptions (void) |
| Send all MWI subscriptions. | |
| static void | sip_send_all_registers (void) |
| Send all known registrations. | |
| static int | sip_send_mwi_to_peer (struct sip_peer *peer, int cache_only) |
| Send message waiting indication to alert peer that they've got voicemail. | |
| static int | sip_senddigit_begin (struct ast_channel *ast, char digit) |
| static int | sip_senddigit_end (struct ast_channel *ast, char digit, unsigned int duration) |
| Send DTMF character on SIP channel within one call, we're able to transmit in many methods simultaneously. | |
| static int | sip_sendhtml (struct ast_channel *chan, int subclass, const char *data, int datalen) |
| Send message with Access-URL header, if this is an HTML URL only! | |
| static int | sip_sendtext (struct ast_channel *ast, const char *text) |
| static char * | sip_set_history (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Enable/Disable SIP History logging (CLI). | |
| static void | sip_set_redirstr (struct sip_pvt *p, char *reason) |
| Translate referring cause. | |
| static int | sip_set_rtp_peer (struct ast_channel *chan, struct ast_rtp_instance *instance, struct ast_rtp_instance *vinstance, struct ast_rtp_instance *tinstance, format_t codecs, int nat_active) |
| static int | sip_set_udptl_peer (struct ast_channel *chan, struct ast_udptl *udptl) |
| static int | sip_setoption (struct ast_channel *chan, int option, void *data, int datalen) |
| Set an option on a SIP dialog. | |
| static char * | sip_show_channel (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Show details of one active dialog. | |
| static char * | sip_show_channels (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| CLI for show channels or subscriptions. This is a new-style CLI handler so a single function contains the prototype for the function, the 'generator' to produce multiple entries in case it is required, and the actual handler for the command. | |
| static char * | sip_show_channelstats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| SIP show channelstats CLI (main function). | |
| static char * | sip_show_domains (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| CLI command to list local domains. | |
| static char * | sip_show_history (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Show history details of one dialog. | |
| static char * | sip_show_inuse (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| CLI Command to show calls within limits set by call_limit. | |
| static char * | sip_show_mwi (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | sip_show_objects (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| List all allocated SIP Objects (realtime or static). | |
| static char * | sip_show_peer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Show one peer in detail. | |
| static char * | sip_show_peers (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| CLI Show Peers command. | |
| static char * | sip_show_registry (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Show SIP Registry (registrations with other SIP proxies. | |
| static char * | sip_show_sched (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | sip_show_settings (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| List global settings for the SIP channel. | |
| static char * | sip_show_tcp (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Show active TCP connections. | |
| static char * | sip_show_user (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Show one user in detail. | |
| static char * | sip_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| CLI Command 'SIP Show Users'. | |
| static int | sip_sipredirect (struct sip_pvt *p, const char *dest) |
| Transfer call before connect with a 302 redirect. | |
| static struct sip_st_dlg * | sip_st_alloc (struct sip_pvt *const p) |
| Allocate Session-Timers struct w/in dialog. | |
| static int | sip_standard_port (enum sip_transport type, int port) |
| Returns the port to use for this socket. | |
| static int | sip_subscribe_mwi (const char *value, int lineno) |
| Parse mwi=> line in sip.conf and add to list. | |
| static void | sip_subscribe_mwi_destroy (struct sip_subscription_mwi *mwi) |
| Destroy MWI subscription object. | |
| static int | sip_subscribe_mwi_do (const void *data) |
| Send a subscription or resubscription for MWI. | |
| static int | sip_t38_abort (const void *data) |
| Called to deny a T38 reinvite if the core does not respond to our request. | |
| static struct ast_tcptls_session_instance * | sip_tcp_locate (struct ast_sockaddr *s) |
| Find thread for TCP/TLS session (based on IP/Port. | |
| static void * | sip_tcp_worker_fn (void *data) |
| SIP TCP connection handler. | |
| static void | sip_tcptls_client_args_destructor (void *obj) |
| static int | sip_tcptls_read (struct sip_request *req, struct ast_tcptls_session_instance *tcptls_session, int authenticated, time_t start) |
| Read SIP request or response from a TCP/TLS connection. | |
| static int | sip_tcptls_write (struct ast_tcptls_session_instance *tcptls_session, const void *buf, size_t len) |
| used to indicate to a tcptls thread that data is ready to be written | |
| static struct sip_threadinfo * | sip_threadinfo_create (struct ast_tcptls_session_instance *tcptls_session, int transport) |
| creates a sip_threadinfo object and links it into the threadt table. | |
| static void | sip_threadinfo_destructor (void *obj) |
| static int | sip_transfer (struct ast_channel *ast, const char *dest) |
| Transfer SIP call. | |
| static char * | sip_unregister (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Unregister (force expiration) a SIP peer in the registry via CLI. | |
| static void | sip_unregister_tests (void) |
| SIP test registration. | |
| static int | sip_write (struct ast_channel *ast, struct ast_frame *frame) |
| Send frame to media channel (rtp). | |
| static int | sipsock_read (int *id, int fd, short events, void *ignore) |
| Read data from SIP UDP socket. | |
| static int | sockaddr_is_null_or_any (const struct ast_sockaddr *addr) |
| static enum st_mode | st_get_mode (struct sip_pvt *p, int no_cached) |
| Get the session-timer mode. | |
| static enum st_refresher | st_get_refresher (struct sip_pvt *p) |
| Get the entity (UAC or UAS) that's acting as the session-timer refresher. | |
| static int | st_get_se (struct sip_pvt *p, int max) |
| Get Max or Min SE (session timer expiry). | |
| static void | start_session_timer (struct sip_pvt *p) |
| Session-Timers: Start session timer. | |
| static void | state_notify_build_xml (int state, int full, const char *exten, const char *context, struct ast_str **tmp, struct sip_pvt *p, int subscribed, const char *mfrom, const char *mto) |
| Builds XML portion of NOTIFY messages for presence or dialog updates. | |
| static const char * | stmode2str (enum st_mode m) |
| static void | stop_media_flows (struct sip_pvt *p) |
| Immediately stop RTP, VRTP and UDPTL as applicable. | |
| static void | stop_session_timer (struct sip_pvt *p) |
| Session-Timers: Stop session timer. | |
| static int | str2dtmfmode (const char *str) |
| maps a string to dtmfmode, returns -1 on error | |
| static enum st_mode | str2stmode (const char *s) |
| static enum st_refresher | str2strefresherparam (const char *s) |
| static const char * | strefresher2str (enum st_refresher r) |
| static const char * | strefresherparam2str (enum st_refresher r) |
| static const char * | subscription_type2str (enum subscriptiontype subtype) |
| Show subscription type in string format. | |
| static unsigned int | t38_get_rate (enum ast_control_t38_rate rate) |
| Get Max T.38 Transmission rate from T38 capabilities. | |
| static void | tcptls_packet_destructor (void *obj) |
| static struct sip_peer * | temp_peer (const char *name) |
| Create temporary peer (used in autocreatepeer mode). | |
| static void | temp_pvt_cleanup (void *) |
| static int | temp_pvt_init (void *) |
| static char * | terminate_uri (char *uri) |
| static int | threadinfo_locate_cb (void *obj, void *arg, int flags) |
| static int | threadt_cmp_cb (void *obj, void *arg, int flags) |
| static int | threadt_hash_cb (const void *obj, const int flags) |
| static char * | transfermode2str (enum transfermodes mode) |
| Convert transfer mode to text string. | |
| static int | transmit_cc_notify (struct ast_cc_agent *agent, struct sip_pvt *subscription, enum sip_cc_notify_state state) |
| static void | transmit_fake_auth_response (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable) |
| Send a fake 401 Unauthorized response when the administrator wants to hide the names of local devices from fishers. | |
| static int | transmit_info_with_aoc (struct sip_pvt *p, struct ast_aoc_decoded *decoded) |
| Send SIP INFO advice of charge message. | |
| static int | transmit_info_with_digit (struct sip_pvt *p, const char digit, unsigned int duration) |
| Send SIP INFO dtmf message, see Cisco documentation on cisco.com. | |
| static int | transmit_info_with_vidupdate (struct sip_pvt *p) |
| Send SIP INFO with video update request. | |
| static int | transmit_invite (struct sip_pvt *p, int sipmethod, int sdp, int init, const char *const explicit_uri) |
| Build REFER/INVITE/OPTIONS/SUBSCRIBE message and transmit it. | |
| static int | transmit_message_with_text (struct sip_pvt *p, const char *text) |
| Transmit text with SIP MESSAGE method. | |
| static int | transmit_notify_with_mwi (struct sip_pvt *p, int newmsgs, int oldmsgs, const char *vmexten) |
| Notify user of messages waiting in voicemail (RFC3842). | |
| static int | transmit_notify_with_sipfrag (struct sip_pvt *p, int cseq, char *message, int terminate) |
| Notify a transferring party of the status of transfer (RFC3515). | |
| static int | transmit_provisional_response (struct sip_pvt *p, const char *msg, const struct sip_request *req, int with_sdp) |
| static int | transmit_publish (struct sip_epa_entry *epa_entry, enum sip_publish_type publish_type, const char *const explicit_uri) |
| static int | transmit_refer (struct sip_pvt *p, const char *dest) |
| Transmit SIP REFER message (initiated by the transfer() dialplan application. | |
| static int | transmit_register (struct sip_registry *r, int sipmethod, const char *auth, const char *authheader) |
| Transmit register to SIP proxy or UA auth = NULL on the initial registration (from sip_reregister()). | |
| static int | transmit_reinvite_with_sdp (struct sip_pvt *p, int t38version, int oldsdp) |
| Transmit reinvite with SDP. | |
| static int | transmit_request (struct sip_pvt *p, int sipmethod, uint32_t seqno, enum xmittype reliable, int newbranch) |
| Transmit generic SIP request returns XMIT_ERROR if transmit failed with a critical error (don't retry). | |
| static int | transmit_request_with_auth (struct sip_pvt *p, int sipmethod, uint32_t seqno, enum xmittype reliable, int newbranch) |
| Transmit SIP request, auth added. | |
| static int | transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
| Transmit response, no retransmits. | |
| static int | transmit_response_reliable (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
| Transmit response, Make sure you get an ACK This is only used for responses to INVITEs, where we need to make sure we get an ACK. | |
| static int | transmit_response_using_temp (ast_string_field callid, struct ast_sockaddr *addr, int useglobal_nat, const int intended_method, const struct sip_request *req, const char *msg) |
| Transmit response, no retransmits, using a temporary pvt structure. | |
| static int | transmit_response_with_allow (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
| Append Accept header, content length before transmitting response. | |
| static int | transmit_response_with_auth (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *randdata, enum xmittype reliable, const char *header, int stale) |
| Respond with authorization request. | |
| static int | transmit_response_with_date (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
| Append date and content length before transmitting response. | |
| static int | transmit_response_with_minexpires (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
| Append Min-Expires header, content length before transmitting response. | |
| static int | transmit_response_with_minse (struct sip_pvt *p, const char *msg, const struct sip_request *req, int minse_int) |
| Transmit 422 response with Min-SE header (Session-Timers). | |
| static int | transmit_response_with_retry_after (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *seconds) |
| Append Retry-After header field when transmitting response. | |
| static int | transmit_response_with_sdp (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable, int oldsdp, int rpid) |
| Used for 200 OK and 183 early media. | |
| static int | transmit_response_with_sip_etag (struct sip_pvt *p, const char *msg, const struct sip_request *req, struct sip_esc_entry *esc_entry, int need_new_etag) |
| static int | transmit_response_with_t38_sdp (struct sip_pvt *p, char *msg, struct sip_request *req, int retrans) |
| Used for 200 OK and 183 early media. | |
| static int | transmit_response_with_unsupported (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *unsupported) |
| Transmit response, no retransmits. | |
| static int | transmit_state_notify (struct sip_pvt *p, int state, int full, int timeout) |
| Used in the SUBSCRIBE notification subsystem (RFC3265). | |
| static const char * | transport2str (enum sip_transport transport) |
| static const char * | trust_id_outbound2str (int mode) |
| static void | try_suggested_sip_codec (struct sip_pvt *p) |
| Try setting codec suggested by the SIP_CODEC channel variable. | |
| static void | unlink_all_peers_from_tables (void) |
| static void | unlink_marked_peers_from_tables (void) |
| static void | unlink_peers_from_tables (peer_unlink_flag_t flag) |
| static int | unload_module (void) |
| PBX unload module API. | |
| static void * | unref_peer (struct sip_peer *peer, char *tag) |
| static int | update_call_counter (struct sip_pvt *fup, int event) |
| update_call_counter: Handle call_limit for SIP devices Setting a call-limit will cause calls above the limit not to be accepted. | |
| static void | update_connectedline (struct sip_pvt *p, const void *data, size_t datalen) |
| Notify peer that the connected line has changed. | |
| static void | update_peer (struct sip_peer *p, int expire) |
| Update peer data in database (if used). | |
| static void | update_peer_lastmsgssent (struct sip_peer *peer, int value, int locked) |
| static void | update_provisional_keepalive (struct sip_pvt *pvt, int with_sdp) |
| static void | update_redirecting (struct sip_pvt *p, const void *data, size_t datalen) |
| Send a provisional response indicating that a call was redirected. | |
Implementation of Session Initiation Protocol.
See Also:
Implementation of RFC 3261 - without S/MIME, and experimental TCP and TLS support Configuration file sip.conf
********** IMPORTANT *
******** General TODO:s
Better support of forking
VIA branch tag transaction checking
Transaction support
******** Wishlist: Improvements
In the SIP channel, there's a list of active SIP dialogs, which includes all of these when they are active. "sip show channels" in the CLI will show most of these, excluding subscriptions which are shown by "sip show subscriptions"
sipsock_read sends the packet to handle_incoming(), that parses a bit more. If it is a response to an outbound request, the packet is sent to handle_response(). If it is a request, handle_incoming() sends it to one of a list of functions depending on the request type - INVITE, OPTIONS, REFER, BYE, CANCEL etc sipsock_read locks the ast_channel if it exists (an active call) and unlocks it after we have processed the SIP message.
A new INVITE is sent to handle_request_invite(), that will end up starting a new channel in the PBX, the new channel after that executing in a separate channel thread. This is an incoming "call". When the call is answered, either by a bridged channel or the PBX itself the sip_answer() function is called.
The actual media - Video or Audio - is mostly handled by the RTP subsystem in rtp.c
Definition in file chan_sip.c.
| #define append_history | ( | p, | |||
| event, | |||||
| fmt, | |||||
| args... | ) | append_history_full(p, "%-15s " fmt, event, ## args) |
Append to SIP dialog history.
Definition at line 2219 of file chan_sip.c.
Referenced by __sip_autodestruct(), __sip_reliable_xmit(), auto_congest(), build_reply_digest(), cb_extensionstate(), change_hold_state(), check_auth(), do_register_auth(), handle_invite_replaces(), handle_request_bye(), handle_request_do(), handle_request_invite(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response(), handle_response_invite(), local_attended_transfer(), obproxy_get(), pvt_set_needdestroy(), retrans_pkt(), send_request(), send_response(), sip_cancel_destroy(), sip_fixup(), sip_hangup(), sip_new(), sip_park_thread(), sip_reregister(), sip_scheddestroy(), sip_set_rtp_peer(), transmit_register(), transmit_reinvite_with_sdp(), transmit_response_with_auth(), and update_connectedline().
| #define BOGUS_PEER_MD5SECRET "intentionally_invalid_md5_string" |
We can recognise the bogus peer by this invalid MD5 hash.
Definition at line 1105 of file chan_sip.c.
Referenced by check_auth(), load_module(), and sip_reload().
| #define CHECK_AUTH_BUF_INITLEN 256 |
Definition at line 14832 of file chan_sip.c.
Referenced by check_auth(), and transmit_fake_auth_response().
| #define check_request_transport | ( | peer, | |||
| tmpl | ) |
generic function for determining if a correct transport is being used to contact a peer
this is done as a macro so that the "tmpl" var can be passed either a sip_request or a sip_peer
Definition at line 2302 of file chan_sip.c.
Referenced by create_addr_from_peer(), and register_verify().
| #define CONTAINER_UNLINK | ( | container, | |||
| obj, | |||||
| tag | ) |
Unlink the given object from the container and return TRUE if it was in the container.
Definition at line 7876 of file chan_sip.c.
Referenced by change_callid_pvt().
| #define DATA_EXPORT_SIP_PEER | ( | MEMBER | ) |
Definition at line 31649 of file chan_sip.c.
| #define FORMAT "%-15.15s %-15.15s %-15.15s %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s %-10.10s\n" |
Definition at line 18980 of file chan_sip.c.
| #define FORMAT "%-30.30s %-12.12s %-10.10s %-10.10s\n" |
Definition at line 18980 of file chan_sip.c.
| #define FORMAT "%-15.15s %-11.11s %-8.8s %-10.10u%-1.1s %-10.10u (%5.2f%%) %-6.4lf %-10.10u%-1.1s %-10.10u (%5.2f%%) %-6.4lf\n" |
Definition at line 18980 of file chan_sip.c.
| #define FORMAT "%-39.39s %-6.6s %-12.12s %8d %-20.20s %-25.25s\n" |
Definition at line 18980 of file chan_sip.c.
| #define FORMAT "%-40.40s %-20.20s %-16.16s\n" |
Definition at line 18980 of file chan_sip.c.
| #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" |
Definition at line 18980 of file chan_sip.c.
| #define FORMAT "%-47.47s %-9.9s %-6.6s\n" |
Definition at line 18980 of file chan_sip.c.
| #define FORMAT "%-25.25s %-15.15s %-15.15s \n" |
Definition at line 18980 of file chan_sip.c.
| #define FORMAT2 "%-15.15s %-15.15s %-15.15s %-15.15s %-7.7s %-15.15s %-10.10s %-10.10s\n" |
Definition at line 18979 of file chan_sip.c.
| #define FORMAT2 "%-15.15s %-11.11s %-8.8s %-10.10s %-10.10s ( %%) %-6.6s %-10.10s %-10.10s ( %%) %-6.6s\n" |
Definition at line 18979 of file chan_sip.c.
| #define FORMAT2 "%-39.39s %-6.6s %-12.12s %8.8s %-20.20s %-25.25s\n" |
Definition at line 18979 of file chan_sip.c.
| #define FORMAT2 "%-47.47s %9.9s %6.6s\n" |
Definition at line 18979 of file chan_sip.c.
| #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" |
Definition at line 18979 of file chan_sip.c.
| #define FORMAT3 "%-15.15s %-15.15s %-15.15s %-15.15s %-13.13s %-15.15s %-10.10s %-6.6s\n" |
Definition at line 18978 of file chan_sip.c.
Referenced by sip_show_channels().
| #define FORMAT4 "%-15.15s %-15.15s %-15.15s %-15.15s %-13.13s %-15.15s %-10.10s %-6.6d\n" |
Definition at line 18977 of file chan_sip.c.
Referenced by show_channels_cb().
| #define PEERS_FORMAT2 "%-25.25s %-39.39s %-3.3s %-10.10s %-3.3s %-8s %-10s %s\n" |
Definition at line 17288 of file chan_sip.c.
Referenced by _sip_show_peers(), and _sip_show_peers_one().
| #define SIP_PEDANTIC_DECODE | ( | str | ) |
if (sip_cfg.pedanticsipchecking && !ast_strlen_zero(str)) { \ ast_uri_decode(str); \ } \
Definition at line 690 of file chan_sip.c.
Referenced by check_user_full(), get_also_info(), get_destination(), get_refer_info(), and register_verify().
| #define sip_pvt_lock | ( | x | ) | ao2_lock(x) |
Definition at line 1091 of file chan_sip.c.
Referenced by __sip_ack(), __sip_autodestruct(), auto_congest(), cb_extensionstate(), complete_sipch(), find_call(), get_sip_pvt_byid_locked(), handle_incoming(), handle_invite_replaces(), handle_request_bye(), handle_request_invite(), handle_request_refer(), handle_request_subscribe(), local_attended_transfer(), parse_register_contact(), proc_session_timer(), register_verify(), retrans_pkt(), show_channels_cb(), show_chanstats_cb(), sip_answer(), sip_call(), sip_cc_agent_destructor(), sip_cc_agent_init(), sip_cc_agent_recall(), sip_cc_agent_respond(), sip_cc_monitor_request_cc(), sip_dtmfmode(), sip_fixup(), sip_get_rtp_peer(), sip_get_trtp_peer(), sip_get_udptl_peer(), sip_get_vrtp_peer(), sip_hangup(), sip_indicate(), sip_monitor_instance_destructor(), sip_new(), sip_pvt_lock_full(), sip_queryoption(), sip_read(), sip_reg_timeout(), sip_reinvite_retry(), sip_request_call(), sip_send_mwi_to_peer(), sip_senddigit_begin(), sip_senddigit_end(), sip_set_rtp_peer(), sip_set_udptl_peer(), sip_setoption(), sip_show_channel(), sip_show_history(), sip_t38_abort(), sip_transfer(), sip_write(), transmit_publish(), and update_call_counter().
| #define sip_pvt_trylock | ( | x | ) | ao2_trylock(x) |
Definition at line 1092 of file chan_sip.c.
Referenced by dialog_needdestroy(), sip_get_rtp_peer(), sip_get_trtp_peer(), sip_get_udptl_peer(), sip_get_vrtp_peer(), and sip_hangup().
| #define sip_pvt_unlock | ( | x | ) | ao2_unlock(x) |
Definition at line 1093 of file chan_sip.c.
Referenced by __sip_ack(), __sip_autodestruct(), auto_congest(), cb_extensionstate(), complete_sipch(), dialog_needdestroy(), dialog_unlink_all(), find_call(), get_sip_pvt_byid_locked(), handle_incoming(), handle_invite_replaces(), handle_request_bye(), handle_request_do(), handle_request_invite(), handle_request_refer(), handle_request_subscribe(), local_attended_transfer(), parse_register_contact(), proc_session_timer(), register_verify(), retrans_pkt(), send_provisional_keepalive_full(), show_channels_cb(), show_chanstats_cb(), sip_answer(), sip_call(), sip_cc_agent_destructor(), sip_cc_agent_init(), sip_cc_agent_recall(), sip_cc_agent_respond(), sip_cc_monitor_request_cc(), sip_dtmfmode(), sip_fixup(), sip_get_rtp_peer(), sip_get_trtp_peer(), sip_get_udptl_peer(), sip_get_vrtp_peer(), sip_hangup(), sip_indicate(), sip_monitor_instance_destructor(), sip_new(), sip_pvt_lock_full(), sip_queryoption(), sip_queue_hangup_cause(), sip_read(), sip_reg_timeout(), sip_reinvite_retry(), sip_request_call(), sip_send_mwi_to_peer(), sip_senddigit_begin(), sip_senddigit_end(), sip_set_rtp_peer(), sip_set_udptl_peer(), sip_setoption(), sip_show_channel(), sip_show_history(), sip_t38_abort(), sip_transfer(), sip_write(), transmit_publish(), and update_call_counter().
| #define UNLINK | ( | element, | |||
| head, | |||||
| prev | ) |
some list management macros.
Definition at line 1196 of file chan_sip.c.
Referenced by __sip_ack(), handle_request_cancel(), and retrans_pkt().
| enum match_req_res |
Definition at line 8173 of file chan_sip.c.
08173 { 08174 SIP_REQ_MATCH, 08175 SIP_REQ_NOT_MATCH, 08176 SIP_REQ_LOOP_DETECTED, 08177 };
| enum message_integrity |
Indication of a TCP message's integrity.
| MESSAGE_INVALID |
The message has an error in it with regards to its Content-Length header |
| MESSAGE_FRAGMENT |
The message is incomplete |
| MESSAGE_FRAGMENT_COMPLETE |
The data contains a complete message plus a fragment of another. |
| MESSAGE_COMPLETE |
The message is complete |
Definition at line 2504 of file chan_sip.c.
02504 { 02505 /*! 02506 * The message has an error in it with 02507 * regards to its Content-Length header 02508 */ 02509 MESSAGE_INVALID, 02510 /*! 02511 * The message is incomplete 02512 */ 02513 MESSAGE_FRAGMENT, 02514 /*! 02515 * The data contains a complete message 02516 * plus a fragment of another. 02517 */ 02518 MESSAGE_FRAGMENT_COMPLETE, 02519 /*! 02520 * The message is complete 02521 */ 02522 MESSAGE_COMPLETE, 02523 };
| enum peer_unlink_flag_t |
Definition at line 3004 of file chan_sip.c.
03004 { 03005 SIP_PEERS_MARKED, 03006 SIP_PEERS_ALL, 03007 } peer_unlink_flag_t;
| static const char * __get_header | ( | const struct sip_request * | req, | |
| const char * | name, | |||
| int * | start | |||
| ) | [static] |
Definition at line 7644 of file chan_sip.c.
References ast_skip_blanks(), find_alias(), len(), match(), and sip_cfg.
Referenced by build_route(), copy_all_header(), copy_via_headers(), func_header_read(), get_header(), handle_incoming(), handle_request_invite(), handle_request_subscribe(), handle_response_register(), and parse_register_contact().
07645 { 07646 /* 07647 * Technically you can place arbitrary whitespace both before and after the ':' in 07648 * a header, although RFC3261 clearly says you shouldn't before, and place just 07649 * one afterwards. If you shouldn't do it, what absolute idiot decided it was 07650 * a good idea to say you can do it, and if you can do it, why in the hell would. 07651 * you say you shouldn't. 07652 * Anyways, pedanticsipchecking controls whether we allow spaces before ':', 07653 * and we always allow spaces after that for compatibility. 07654 */ 07655 const char *sname = find_alias(name, NULL); 07656 int x, len = strlen(name), slen = (sname ? 1 : 0); 07657 for (x = *start; x < req->headers; x++) { 07658 const char *header = REQ_OFFSET_TO_STR(req, header[x]); 07659 int smatch = 0, match = !strncasecmp(header, name, len); 07660 if (slen) { 07661 smatch = !strncasecmp(header, sname, slen); 07662 } 07663 if (match || smatch) { 07664 /* skip name */ 07665 const char *r = header + (match ? len : slen ); 07666 if (sip_cfg.pedanticsipchecking) { 07667 r = ast_skip_blanks(r); 07668 } 07669 07670 if (*r == ':') { 07671 *start = x+1; 07672 return ast_skip_blanks(r+1); 07673 } 07674 } 07675 } 07676 07677 /* Don't return NULL, so get_header is always a valid pointer */ 07678 return ""; 07679 }
| static int __set_address_from_contact | ( | const char * | fullcontact, | |
| struct ast_sockaddr * | addr, | |||
| int | tcp | |||
| ) | [static] |
Definition at line 14394 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_sockaddr_port, ast_sockaddr_resolve_first_transport(), ast_sockaddr_set_port, ast_strlen_zero(), get_transport_str2enum(), LOG_WARNING, and parse_uri_legacy_check().
Referenced by build_peer(), and set_address_from_contact().
14395 { 14396 char *hostport, *transport; 14397 char contact_buf[256]; 14398 char *contact; 14399 14400 /* Work on a copy */ 14401 ast_copy_string(contact_buf, fullcontact, sizeof(contact_buf)); 14402 contact = contact_buf; 14403 14404 /* 14405 * We have only the part in <brackets> here so we just need to parse a SIP URI. 14406 * 14407 * Note: The outbound proxy could be using UDP between the proxy and Asterisk. 14408 * We still need to be able to send to the remote agent through the proxy. 14409 */ 14410 14411 if (parse_uri_legacy_check(contact, "sip:,sips:", &contact, NULL, &hostport, 14412 &transport)) { 14413 ast_log(LOG_WARNING, "Invalid contact uri %s (missing sip: or sips:), attempting to use anyway\n", fullcontact); 14414 } 14415 14416 /* XXX This could block for a long time XXX */ 14417 /* We should only do this if it's a name, not an IP */ 14418 /* \todo - if there's no PORT number in contact - we are required to check NAPTR/SRV records 14419 to find transport, port address and hostname. If there's a port number, we have to 14420 assume that the hostport part is a host name and only look for an A/AAAA record in DNS. 14421 */ 14422 14423 /* If we took in an invalid URI, hostport may not have been initialized */ 14424 /* ast_sockaddr_resolve requires an initialized hostport string. */ 14425 if (ast_strlen_zero(hostport)) { 14426 ast_log(LOG_WARNING, "Invalid URI: parse_uri failed to acquire hostport\n"); 14427 return -1; 14428 } 14429 14430 if (ast_sockaddr_resolve_first_transport(addr, hostport, 0, get_transport_str2enum(transport))) { 14431 ast_log(LOG_WARNING, "Invalid host name in Contact: (can't " 14432 "resolve in DNS) : '%s'\n", hostport); 14433 return -1; 14434 } 14435 14436 /* set port */ 14437 if (!ast_sockaddr_port(addr)) { 14438 ast_sockaddr_set_port(addr, 14439 (get_transport_str2enum(transport) == 14440 SIP_TRANSPORT_TLS || 14441 !strncasecmp(fullcontact, "sips", 4)) ? 14442 STANDARD_TLS_PORT : STANDARD_SIP_PORT); 14443 } 14444 14445 return 0; 14446 }
| int __sip_ack | ( | struct sip_pvt * | p, | |
| uint32_t | seqno, | |||
| int | resp, | |||
| int | sipmethod | |||
| ) |
Acknowledges receipt of a packet and stops retransmission called with p locked.
Definition at line 4154 of file chan_sip.c.
References ast_debug, ast_free, ast_sched_del(), FALSE, ref_proxy(), sip_pvt_lock, sip_pvt_unlock, TRUE, and UNLINK.
Referenced by __sip_pretend_ack(), handle_incoming(), handle_request_invite(), handle_request_publish(), and handle_response().
04155 { 04156 struct sip_pkt *cur, *prev = NULL; 04157 const char *msg = "Not Found"; /* used only for debugging */ 04158 int res = FALSE; 04159 04160 /* If we have an outbound proxy for this dialog, then delete it now since 04161 the rest of the requests in this dialog needs to follow the routing. 04162 If obforcing is set, we will keep the outbound proxy during the whole 04163 dialog, regardless of what the SIP rfc says 04164 */ 04165 if (p->outboundproxy && !p->outboundproxy->force) { 04166 ref_proxy(p, NULL); 04167 } 04168 04169 for (cur = p->packets; cur; prev = cur, cur = cur->next) { 04170 if (cur->seqno != seqno || cur->is_resp != resp) { 04171 continue; 04172 } 04173 if (cur->is_resp || cur->method == sipmethod) { 04174 res = TRUE; 04175 msg = "Found"; 04176 if (!resp && (seqno == p->pendinginvite)) { 04177 ast_debug(1, "Acked pending invite %u\n", p->pendinginvite); 04178 p->pendinginvite = 0; 04179 } 04180 if (cur->retransid > -1) { 04181 if (sipdebug) 04182 ast_debug(4, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid); 04183 } 04184 /* This odd section is designed to thwart a 04185 * race condition in the packet scheduler. There are 04186 * two conditions under which deleting the packet from the 04187 * scheduler can fail. 04188 * 04189 * 1. The packet has been removed from the scheduler because retransmission 04190 * is being attempted. The problem is that if the packet is currently attempting 04191 * retransmission and we are at this point in the code, then that MUST mean 04192 * that retrans_pkt is waiting on p's lock. Therefore we will relinquish the 04193 * lock temporarily to allow retransmission. 04194 * 04195 * 2. The packet has reached its maximum number of retransmissions and has 04196 * been permanently removed from the packet scheduler. If this is the case, then 04197 * the packet's retransid will be set to -1. The atomicity of the setting and checking 04198 * of the retransid to -1 is ensured since in both cases p's lock is held. 04199 */ 04200 while (cur->retransid > -1 && ast_sched_del(sched, cur->retransid)) { 04201 sip_pvt_unlock(p); 04202 usleep(1); 04203 sip_pvt_lock(p); 04204 } 04205 UNLINK(cur, p->packets, prev); 04206 dialog_unref(cur->owner, "unref pkt cur->owner dialog from sip ack before freeing pkt"); 04207 if (cur->data) { 04208 ast_free(cur->data); 04209 } 04210 ast_free(cur); 04211 break; 04212 } 04213 } 04214 ast_debug(1, "Stopping retransmission on '%s' of %s %u: Match %s\n", 04215 p->callid, resp ? "Response" : "Request", seqno, msg); 04216 return res; 04217 }
| static int __sip_autodestruct | ( | const void * | data | ) | [static] |
Kill a SIP dialog (called only by the scheduler) The scheduler has a reference to this dialog when p->autokillid != -1, and we are called using that reference. So if the event is not rescheduled, we need to call dialog_unref().
Definition at line 4017 of file chan_sip.c.
References __sip_pretend_ack(), append_history, AST_CAUSE_PROTOCOL_ERROR, ast_channel_unlock, ast_channel_unref, ast_debug, AST_EXTENSION_DEACTIVATED, ast_log(), ast_queue_hangup_with_cause(), dialog_unlink_all(), LOG_WARNING, method_match(), NONE, pvt_set_needdestroy(), sip_methods, sip_pvt_lock, sip_pvt_lock_full(), sip_pvt_unlock, sip_scheddestroy(), stop_media_flows(), cfsip_methods::text, transmit_request_with_auth(), transmit_state_notify(), and TRUE.
Referenced by sip_scheddestroy(), and sip_show_sched().
04018 { 04019 struct sip_pvt *p = (struct sip_pvt *)data; 04020 struct ast_channel *owner; 04021 04022 /* If this is a subscription, tell the phone that we got a timeout */ 04023 if (p->subscribed && p->subscribed != MWI_NOTIFICATION && p->subscribed != CALL_COMPLETION) { 04024 transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE); /* Send last notification */ 04025 p->subscribed = NONE; 04026 append_history(p, "Subscribestatus", "timeout"); 04027 ast_debug(3, "Re-scheduled destruction of SIP subscription %s\n", p->callid ? p->callid : "<unknown>"); 04028 return 10000; /* Reschedule this destruction so that we know that it's gone */ 04029 } 04030 04031 /* If there are packets still waiting for delivery, delay the destruction */ 04032 if (p->packets) { 04033 if (!p->needdestroy) { 04034 char method_str[31]; 04035 ast_debug(3, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>"); 04036 append_history(p, "ReliableXmit", "timeout"); 04037 if (sscanf(p->lastmsg, "Tx: %30s", method_str) == 1 || sscanf(p->lastmsg, "Rx: %30s", method_str) == 1) { 04038 if (p->ongoing_reinvite || method_match(SIP_CANCEL, method_str) || method_match(SIP_BYE, method_str)) { 04039 pvt_set_needdestroy(p, "autodestruct"); 04040 } 04041 } 04042 return 10000; 04043 } else { 04044 /* They've had their chance to respond. Time to bail */ 04045 __sip_pretend_ack(p); 04046 } 04047 } 04048 04049 /* Reset schedule ID */ 04050 p->autokillid = -1; 04051 04052 /* 04053 * Lock both the pvt and the channel safely so that we can queue up a frame. 04054 */ 04055 owner = sip_pvt_lock_full(p); 04056 if (owner) { 04057 ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner %s in place (Method: %s). Rescheduling destruction for 10000 ms\n", p->callid, owner->name, sip_methods[p->method].text); 04058 ast_queue_hangup_with_cause(owner, AST_CAUSE_PROTOCOL_ERROR); 04059 ast_channel_unlock(owner); 04060 ast_channel_unref(owner); 04061 sip_pvt_unlock(p); 04062 return 10000; 04063 } else if (p->refer && !p->alreadygone) { 04064 ast_debug(3, "Finally hanging up channel after transfer: %s\n", p->callid); 04065 stop_media_flows(p); 04066 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 04067 append_history(p, "ReferBYE", "Sending BYE on transferer call leg %s", p->callid); 04068 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 04069 } else { 04070 append_history(p, "AutoDestroy", "%s", p->callid); 04071 ast_debug(3, "Auto destroying SIP dialog '%s'\n", p->callid); 04072 sip_pvt_unlock(p); 04073 dialog_unlink_all(p); /* once it's unlinked and unrefd everywhere, it'll be freed automagically */ 04074 sip_pvt_lock(p); 04075 /* dialog_unref(p, "unref dialog-- no other matching conditions"); -- unlink all now should finish off the dialog's references and free it. */ 04076 /* sip_destroy(p); */ /* Go ahead and destroy dialog. All attempts to recover is done */ 04077 /* sip_destroy also absorbs the reference */ 04078 } 04079 04080 sip_pvt_unlock(p); 04081 04082 dialog_unref(p, "The ref to a dialog passed to this sched callback is going out of scope; unref it."); 04083 04084 return 0; 04085 }
| void __sip_destroy | ( | struct sip_pvt * | p, | |
| int | lockowner, | |||
| int | lockdialoglist | |||
| ) |
Execute destruction of SIP dialog structure, release memory.
Definition at line 5964 of file chan_sip.c.
References ao2_ref, ao2_t_ref, ast_cc_config_params_destroy(), ast_channel_lock, ast_channel_unlock, ast_debug, ast_free, ast_free_ha(), AST_LIST_REMOVE_HEAD, ast_rtp_instance_destroy(), AST_SOFTHANGUP_DEV, ast_string_field_free_memory, ast_test_flag, ast_udptl_destroy(), ast_variables_destroy(), ast_verbose, deinit_req(), free_old_route(), ref_proxy(), registry_unref(), sip_debug_test_pvt(), sip_dump_history(), sip_methods, sip_srtp_destroy(), stop_session_timer(), cfsip_methods::text, unref_peer(), and update_call_counter().
Referenced by sip_destroy().
05965 { 05966 struct sip_request *req; 05967 05968 /* Destroy Session-Timers if allocated */ 05969 if (p->stimer) { 05970 p->stimer->quit_flag = 1; 05971 stop_session_timer(p); 05972 ast_free(p->stimer); 05973 p->stimer = NULL; 05974 } 05975 05976 if (sip_debug_test_pvt(p)) 05977 ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 05978 05979 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 05980 update_call_counter(p, DEC_CALL_LIMIT); 05981 ast_debug(2, "This call did not properly clean up call limits. Call ID %s\n", p->callid); 05982 } 05983 05984 /* Unlink us from the owner if we have one */ 05985 if (p->owner) { 05986 if (lockowner) 05987 ast_channel_lock(p->owner); 05988 ast_debug(1, "Detaching from %s\n", p->owner->name); 05989 p->owner->tech_pvt = NULL; 05990 /* Make sure that the channel knows its backend is going away */ 05991 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 05992 if (lockowner) 05993 ast_channel_unlock(p->owner); 05994 /* Give the channel a chance to react before deallocation */ 05995 usleep(1); 05996 } 05997 05998 /* Remove link from peer to subscription of MWI */ 05999 if (p->relatedpeer && p->relatedpeer->mwipvt == p) 06000 p->relatedpeer->mwipvt = dialog_unref(p->relatedpeer->mwipvt, "delete ->relatedpeer->mwipvt"); 06001 if (p->relatedpeer && p->relatedpeer->call == p) 06002 p->relatedpeer->call = dialog_unref(p->relatedpeer->call, "unset the relatedpeer->call field in tandem with relatedpeer field itself"); 06003 06004 if (p->relatedpeer) 06005 p->relatedpeer = unref_peer(p->relatedpeer,"unsetting a dialog relatedpeer field in sip_destroy"); 06006 06007 if (p->registry) { 06008 if (p->registry->call == p) 06009 p->registry->call = dialog_unref(p->registry->call, "nulling out the registry's call dialog field in unlink_all"); 06010 p->registry = registry_unref(p->registry, "delete p->registry"); 06011 } 06012 06013 if (p->mwi) { 06014 p->mwi->call = NULL; 06015 p->mwi = NULL; 06016 } 06017 06018 if (dumphistory) 06019 sip_dump_history(p); 06020 06021 if (p->options) { 06022 if (p->options->outboundproxy) { 06023 ao2_ref(p->options->outboundproxy, -1); 06024 } 06025 ast_free(p->options); 06026 p->options = NULL; 06027 } 06028 06029 if (p->outboundproxy) { 06030 ref_proxy(p, NULL); 06031 } 06032 06033 if (p->notify) { 06034 ast_variables_destroy(p->notify->headers); 06035 ast_free(p->notify->content); 06036 ast_free(p->notify); 06037 p->notify = NULL; 06038 } 06039 if (p->rtp) { 06040 ast_rtp_instance_destroy(p->rtp); 06041 p->rtp = NULL; 06042 } 06043 if (p->vrtp) { 06044 ast_rtp_instance_destroy(p->vrtp); 06045 p->vrtp = NULL; 06046 } 06047 if (p->trtp) { 06048 ast_rtp_instance_destroy(p->trtp); 06049 p->trtp = NULL; 06050 } 06051 if (p->udptl) { 06052 ast_udptl_destroy(p->udptl); 06053 p->udptl = NULL; 06054 } 06055 if (p->refer) { 06056 if (p->refer->refer_call) { 06057 p->refer->refer_call = dialog_unref(p->refer->refer_call, "unref dialog p->refer->refer_call"); 06058 } 06059 ast_free(p->refer); 06060 p->refer = NULL; 06061 } 06062 if (p->route) { 06063 free_old_route(p->route); 06064 p->route = NULL; 06065 } 06066 deinit_req(&p->initreq); 06067 06068 /* Clear history */ 06069 if (p->history) { 06070 struct sip_history *hist; 06071 while ( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) { 06072 ast_free(hist); 06073 p->history_entries--; 06074 } 06075 ast_free(p->history); 06076 p->history = NULL; 06077 } 06078 06079 while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) { 06080 ast_free(req); 06081 } 06082 06083 if (p->chanvars) { 06084 ast_variables_destroy(p->chanvars); 06085 p->chanvars = NULL; 06086 } 06087 06088 if (p->srtp) { 06089 sip_srtp_destroy(p->srtp); 06090 p->srtp = NULL; 06091 } 06092 06093 if (p->vsrtp) { 06094 sip_srtp_destroy(p->vsrtp); 06095 p->vsrtp = NULL; 06096 } 06097 06098 if (p->tsrtp) { 06099 sip_srtp_destroy(p->tsrtp); 06100 p->tsrtp = NULL; 06101 } 06102 06103 if (p->directmediaha) { 06104 ast_free_ha(p->directmediaha); 06105 p->directmediaha = NULL; 06106 } 06107 06108 ast_string_field_free_memory(p); 06109 06110 ast_cc_config_params_destroy(p->cc_params); 06111 p->cc_params = NULL; 06112 06113 if (p->epa_entry) { 06114 ao2_ref(p->epa_entry, -1); 06115 p->epa_entry = NULL; 06116 } 06117 06118 if (p->socket.tcptls_session) { 06119 ao2_ref(p->socket.tcptls_session, -1); 06120 p->socket.tcptls_session = NULL; 06121 } 06122 06123 if (p->peerauth) { 06124 ao2_t_ref(p->peerauth, -1, "Removing active peer authentication"); 06125 p->peerauth = NULL; 06126 } 06127 }
| static int __sip_do_register | ( | struct sip_registry * | r | ) | [static] |
Register with SIP proxy.
Definition at line 13598 of file chan_sip.c.
References transmit_register().
Referenced by sip_reregister().
13599 { 13600 int res; 13601 13602 res = transmit_register(r, SIP_REGISTER, NULL, NULL); 13603 return res; 13604 }
| void __sip_pretend_ack | ( | struct sip_pvt * | p | ) |
Pretend to ack all packets called with p locked.
Definition at line 4221 of file chan_sip.c.
References __sip_ack(), ast_log(), ast_str_buffer(), find_sip_method(), LOG_WARNING, sip_methods, and cfsip_methods::text.
Referenced by __sip_autodestruct(), handle_request_bye(), handle_request_cancel(), and sip_reg_timeout().
04222 { 04223 struct sip_pkt *cur = NULL; 04224 04225 while (p->packets) { 04226 int method; 04227 if (cur == p->packets) { 04228 ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text); 04229 return; 04230 } 04231 cur = p->packets; 04232 method = (cur->method) ? cur->method : find_sip_method(ast_str_buffer(cur->data)); 04233 __sip_ack(p, cur->seqno, cur->is_resp, method); 04234 } 04235 }
| static enum sip_result __sip_reliable_xmit | ( | struct sip_pvt * | p, | |
| uint32_t | seqno, | |||
| int | resp, | |||
| struct ast_str * | data, | |||
| int | fatal, | |||
| int | sipmethod | |||
| ) | [static] |
Definition at line 3926 of file chan_sip.c.
References __sip_xmit(), append_history, ast_calloc, ast_debug, ast_free, ast_log(), AST_PTHREADT_NULL, AST_SCHED_DEL, AST_SCHED_REPLACE_VARIABLE, ast_str_buffer(), ast_str_create(), ast_str_set(), ast_str_strlen(), ast_tvnow(), DEFAULT_RETRANS, LOG_ERROR, and retrans_pkt().
Referenced by send_request(), and send_response().
03927 { 03928 struct sip_pkt *pkt = NULL; 03929 int siptimer_a = DEFAULT_RETRANS; 03930 int xmitres = 0; 03931 unsigned respid; 03932 03933 if (sipmethod == SIP_INVITE) { 03934 /* Note this is a pending invite */ 03935 p->pendinginvite = seqno; 03936 } 03937 03938 /* If the transport is something reliable (TCP or TLS) then don't really send this reliably */ 03939 /* I removed the code from retrans_pkt that does the same thing so it doesn't get loaded into the scheduler */ 03940 /*! \todo According to the RFC some packets need to be retransmitted even if its TCP, so this needs to get revisited */ 03941 if (!(p->socket.type & SIP_TRANSPORT_UDP)) { 03942 xmitres = __sip_xmit(p, data); /* Send packet */ 03943 if (xmitres == XMIT_ERROR) { /* Serious network trouble, no need to try again */ 03944 append_history(p, "XmitErr", "%s", fatal ? "(Critical)" : "(Non-critical)"); 03945 return AST_FAILURE; 03946 } else { 03947 return AST_SUCCESS; 03948 } 03949 } 03950 03951 if (!(pkt = ast_calloc(1, sizeof(*pkt)))) { 03952 return AST_FAILURE; 03953 } 03954 /* copy data, add a terminator and save length */ 03955 if (!(pkt->data = ast_str_create(ast_str_strlen(data)))) { 03956 ast_free(pkt); 03957 return AST_FAILURE; 03958 } 03959 ast_str_set(&pkt->data, 0, "%s%s", ast_str_buffer(data), "\0"); 03960 /* copy other parameters from the caller */ 03961 pkt->method = sipmethod; 03962 pkt->seqno = seqno; 03963 pkt->is_resp = resp; 03964 pkt->is_fatal = fatal; 03965 pkt->owner = dialog_ref(p, "__sip_reliable_xmit: setting pkt->owner"); 03966 pkt->next = p->packets; 03967 p->packets = pkt; /* Add it to the queue */ 03968 if (resp) { 03969 /* Parse out the response code */ 03970 if (sscanf(ast_str_buffer(pkt->data), "SIP/2.0 %30u", &respid) == 1) { 03971 pkt->response_code = respid; 03972 } 03973 } 03974 pkt->timer_t1 = p->timer_t1; /* Set SIP timer T1 */ 03975 pkt->retransid = -1; 03976 if (pkt->timer_t1) { 03977 siptimer_a = pkt->timer_t1; 03978 } 03979 03980 pkt->time_sent = ast_tvnow(); /* time packet was sent */ 03981 pkt->retrans_stop_time = 64 * (pkt->timer_t1 ? pkt->timer_t1 : DEFAULT_TIMER_T1); /* time in ms after pkt->time_sent to stop retransmission */ 03982 03983 /* Schedule retransmission */ 03984 AST_SCHED_REPLACE_VARIABLE(pkt->retransid, sched, siptimer_a, retrans_pkt, pkt, 1); 03985 if (sipdebug) { 03986 ast_debug(4, "*** SIP TIMER: Initializing retransmit timer on packet: Id #%d\n", pkt->retransid); 03987 } 03988 03989 xmitres = __sip_xmit(pkt->owner, pkt->data); /* Send packet */ 03990 03991 if (xmitres == XMIT_ERROR) { /* Serious network trouble, no need to try again */ 03992 append_history(pkt->owner, "XmitErr", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)"); 03993 ast_log(LOG_ERROR, "Serious Network Trouble; __sip_xmit returns error for pkt data\n"); 03994 AST_SCHED_DEL(sched, pkt->retransid); 03995 p->packets = pkt->next; 03996 pkt->owner = dialog_unref(pkt->owner,"pkt is being freed, its dialog ref is dead now"); 03997 ast_free(pkt->data); 03998 ast_free(pkt); 03999 return AST_FAILURE; 04000 } else { 04001 /* This is odd, but since the retrans timer starts at 500ms and the do_monitor thread 04002 * only wakes up every 1000ms by default, we have to poke the thread here to make 04003 * sure it successfully detects this must be retransmitted in less time than 04004 * it usually sleeps for. Otherwise it might not retransmit this packet for 1000ms. */ 04005 if (monitor_thread != AST_PTHREADT_NULL) { 04006 pthread_kill(monitor_thread, SIGURG); 04007 } 04008 return AST_SUCCESS; 04009 } 04010 }
| int __sip_semi_ack | ( | struct sip_pvt * | p, | |
| uint32_t | seqno, | |||
| int | resp, | |||
| int | sipmethod | |||
| ) |
Acks receipt of packet, keep it around (used for provisional responses).
Definition at line 4238 of file chan_sip.c.
References ast_debug, AST_SCHED_DEL, ast_str_buffer(), FALSE, method_match(), sip_methods, cfsip_methods::text, and TRUE.
Referenced by handle_response(), and sip_hangup().
04239 { 04240 struct sip_pkt *cur; 04241 int res = FALSE; 04242 04243 for (cur = p->packets; cur; cur = cur->next) { 04244 if (cur->seqno == seqno && cur->is_resp == resp && 04245 (cur->is_resp || method_match(sipmethod, ast_str_buffer(cur->data)))) { 04246 /* this is our baby */ 04247 if (cur->retransid > -1) { 04248 if (sipdebug) 04249 ast_debug(4, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text); 04250 } 04251 AST_SCHED_DEL(sched, cur->retransid); 04252 res = TRUE; 04253 break; 04254 } 04255 } 04256 ast_debug(1, "(Provisional) Stopping retransmission (but retaining packet) on '%s' %s %u: %s\n", p->callid, resp ? "Response" : "Request", seqno, res == -1 ? "Not Found" : "Found"); 04257 return res; 04258 }
| static int __sip_subscribe_mwi_do | ( | struct sip_subscription_mwi * | mwi | ) | [static] |
Actually setup an MWI subscription or resubscribe.
Definition at line 12862 of file chan_sip.c.
References ast_dnsmgr_lookup_cb(), ast_set_flag, ast_sip_ouraddrfor(), ast_sockaddr_port, ast_sockaddr_set_port, ast_string_field_set, ast_strlen_zero(), ASTOBJ_REF, ASTOBJ_UNREF, build_contact(), build_via(), change_callid_pvt(), create_addr(), dialog_unlink_all(), get_address_family_filter(), get_srv_protocol(), get_srv_service(), MAXHOSTNAMELEN, obproxy_get(), on_dns_update_mwi(), ref_proxy(), set_socket_transport(), sip_alloc(), sip_cfg, sip_subscribe_mwi_destroy(), and transmit_invite().
Referenced by sip_subscribe_mwi_do().
12863 { 12864 /* If we have no DNS manager let's do a lookup */ 12865 if (!mwi->dnsmgr) { 12866 char transport[MAXHOSTNAMELEN]; 12867 struct sip_subscription_mwi *saved; 12868 snprintf(transport, sizeof(transport), "_%s._%s", get_srv_service(mwi->transport), get_srv_protocol(mwi->transport)); 12869 12870 mwi->us.ss.ss_family = get_address_family_filter(mwi->transport); /* Filter address family */ 12871 saved = ASTOBJ_REF(mwi); 12872 ast_dnsmgr_lookup_cb(mwi->hostname, &mwi->us, &mwi->dnsmgr, sip_cfg.srvlookup ? transport : NULL, on_dns_update_mwi, saved); 12873 if (!mwi->dnsmgr) { 12874 ASTOBJ_UNREF(saved, sip_subscribe_mwi_destroy); /* dnsmgr disabled, remove reference */ 12875 } 12876 } 12877 12878 /* If we already have a subscription up simply send a resubscription */ 12879 if (mwi->call) { 12880 transmit_invite(mwi->call, SIP_SUBSCRIBE, 0, 0, NULL); 12881 return 0; 12882 } 12883 12884 /* Create a dialog that we will use for the subscription */ 12885 if (!(mwi->call = sip_alloc(NULL, NULL, 0, SIP_SUBSCRIBE, NULL))) { 12886 return -1; 12887 } 12888 12889 ref_proxy(mwi->call, obproxy_get(mwi->call, NULL)); 12890 12891 if (!ast_sockaddr_port(&mwi->us) && mwi->portno) { 12892 ast_sockaddr_set_port(&mwi->us, mwi->portno); 12893 } 12894 12895 /* Setup the destination of our subscription */ 12896 if (create_addr(mwi->call, mwi->hostname, &mwi->us, 0)) { 12897 dialog_unlink_all(mwi->call); 12898 mwi->call = dialog_unref(mwi->call, "unref dialog after unlink_all"); 12899 return 0; 12900 } 12901 12902 mwi->call->expiry = mwi_expiry; 12903 12904 if (!mwi->dnsmgr && mwi->portno) { 12905 ast_sockaddr_set_port(&mwi->call->sa, mwi->portno); 12906 ast_sockaddr_set_port(&mwi->call->recv, mwi->portno); 12907 } else { 12908 mwi->portno = ast_sockaddr_port(&mwi->call->sa); 12909 } 12910 12911 /* Set various other information */ 12912 if (!ast_strlen_zero(mwi->authuser)) { 12913 ast_string_field_set(mwi->call, peername, mwi->authuser); 12914 ast_string_field_set(mwi->call, authname, mwi->authuser); 12915 ast_string_field_set(mwi->call, fromuser, mwi->authuser); 12916 } else { 12917 ast_string_field_set(mwi->call, peername, mwi->username); 12918 ast_string_field_set(mwi->call, authname, mwi->username); 12919 ast_string_field_set(mwi->call, fromuser, mwi->username); 12920 } 12921 ast_string_field_set(mwi->call, username, mwi->username); 12922 if (!ast_strlen_zero(mwi->secret)) { 12923 ast_string_field_set(mwi->call, peersecret, mwi->secret); 12924 } 12925 set_socket_transport(&mwi->call->socket, mwi->transport); 12926 mwi->call->socket.port = htons(mwi->portno); 12927 ast_sip_ouraddrfor(&mwi->call->sa, &mwi->call->ourip, mwi->call); 12928 build_contact(mwi->call); 12929 build_via(mwi->call); 12930 12931 /* Change the dialog callid. */ 12932 change_callid_pvt(mwi->call, NULL); 12933 12934 ast_set_flag(&mwi->call->flags[0], SIP_OUTGOING); 12935 12936 /* Associate the call with us */ 12937 mwi->call->mwi = ASTOBJ_REF(mwi); 12938 12939 mwi->call->subscribed = MWI_NOTIFICATION; 12940 12941 /* Actually send the packet */ 12942 transmit_invite(mwi->call, SIP_SUBSCRIBE, 0, 2, NULL); 12943 12944 return 0; 12945 }
| static int __sip_xmit | ( | struct sip_pvt * | p, | |
| struct ast_str * | data | |||
| ) | [static] |
Definition at line 3521 of file chan_sip.c.
References ast_debug, ast_log(), ast_sendto(), ast_sockaddr_stringify(), ast_str_buffer(), ast_str_strlen(), errno, get_transport_pvt(), LOG_WARNING, sip_prepare_socket(), sip_real_dst(), and sip_tcptls_write().
Referenced by __sip_reliable_xmit(), retrans_pkt(), send_request(), and send_response().
03522 { 03523 int res = 0; 03524 const struct ast_sockaddr *dst = sip_real_dst(p); 03525 03526 ast_debug(2, "Trying to put '%.11s' onto %s socket destined for %s\n", ast_str_buffer(data), get_transport_pvt(p), ast_sockaddr_stringify(dst)); 03527 03528 if (sip_prepare_socket(p) < 0) { 03529 return XMIT_ERROR; 03530 } 03531 03532 if (p->socket.type == SIP_TRANSPORT_UDP) { 03533 res = ast_sendto(p->socket.fd, ast_str_buffer(data), ast_str_strlen(data), 0, dst); 03534 } else if (p->socket.tcptls_session) { 03535 res = sip_tcptls_write(p->socket.tcptls_session, ast_str_buffer(data), ast_str_strlen(data)); 03536 } else { 03537 ast_debug(2, "Socket type is TCP but no tcptls_session is present to write to\n"); 03538 return XMIT_ERROR; 03539 } 03540 03541 if (res == -1) { 03542 switch (errno) { 03543 case EBADF: /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */ 03544 case EHOSTUNREACH: /* Host can't be reached */ 03545 case ENETDOWN: /* Interface down */ 03546 case ENETUNREACH: /* Network failure */ 03547 case ECONNREFUSED: /* ICMP port unreachable */ 03548 res = XMIT_ERROR; /* Don't bother with trying to transmit again */ 03549 } 03550 } 03551 if (res != ast_str_strlen(data)) { 03552 ast_log(LOG_WARNING, "sip_xmit of %p (len %zu) to %s returned %d: %s\n", data, ast_str_strlen(data), ast_sockaddr_stringify(dst), res, strerror(errno)); 03553 } 03554 03555 return res; 03556 }
| static int __transmit_response | ( | struct sip_pvt * | p, | |
| const char * | msg, | |||
| const struct sip_request * | req, | |||
| enum xmittype | reliable | |||
| ) | [static] |
Base transmit response function.
Definition at line 10843 of file chan_sip.c.
References add_cc_call_info_to_response(), add_diversion_header(), add_header(), add_rpid(), ast_cause2str(), ast_clear_flag, ast_log(), ast_test_flag, get_header(), hangup_sip2cause(), LOG_WARNING, respprep(), and send_response().
Referenced by transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), and transmit_response_using_temp().
10844 { 10845 struct sip_request resp; 10846 uint32_t seqno = 0; 10847 10848 if (reliable && (sscanf(get_header(req, "CSeq"), "%30u ", &seqno) != 1)) { 10849 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 10850 return -1; 10851 } 10852 respprep(&resp, p, msg, req); 10853 10854 if (ast_test_flag(&p->flags[0], SIP_SENDRPID) 10855 && ast_test_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND) 10856 && (!strncmp(msg, "180", 3) || !strncmp(msg, "183", 3))) { 10857 ast_clear_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND); 10858 add_rpid(&resp, p); 10859 } 10860 if (ast_test_flag(&p->flags[0], SIP_OFFER_CC)) { 10861 add_cc_call_info_to_response(p, &resp); 10862 } 10863 10864 /* If we are sending a 302 Redirect we can add a diversion header if the redirect information is set */ 10865 if (!strncmp(msg, "302", 3)) { 10866 add_diversion_header(&resp, p); 10867 } 10868 10869 /* If we are cancelling an incoming invite for some reason, add information 10870 about the reason why we are doing this in clear text */ 10871 if (p->method == SIP_INVITE && msg[0] != '1') { 10872 char buf[20]; 10873 10874 if (ast_test_flag(&p->flags[1], SIP_PAGE2_Q850_REASON)) { 10875 int hangupcause = 0; 10876 10877 if (p->owner && p->owner->hangupcause) { 10878 hangupcause = p->owner->hangupcause; 10879 } else if (p->hangupcause) { 10880 hangupcause = p->hangupcause; 10881 } else { 10882 int respcode; 10883 if (sscanf(msg, "%30d ", &respcode)) 10884 hangupcause = hangup_sip2cause(respcode); 10885 } 10886 10887 if (hangupcause) { 10888 sprintf(buf, "Q.850;cause=%i", hangupcause & 0x7f); 10889 add_header(&resp, "Reason", buf); 10890 } 10891 } 10892 10893 if (p->owner && p->owner->hangupcause) { 10894 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 10895 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 10896 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 10897 } 10898 } 10899 return send_response(p, &resp, reliable, seqno); 10900 }
| static char * _sip_qualify_peer | ( | int | type, | |
| int | fd, | |||
| struct mansession * | s, | |||
| const struct message * | m, | |||
| int | argc, | |||
| const char * | argv[] | |||
| ) | [static] |
Send qualify message to peer from cli or manager. Mostly for debugging.
Definition at line 17976 of file chan_sip.c.
References ast_cli(), astman_send_error(), CLI_SHOWUSAGE, CLI_SUCCESS, FALSE, find_peer(), sip_poke_peer(), TRUE, and unref_peer().
Referenced by manager_sip_qualify_peer(), and sip_qualify_peer().
17977 { 17978 struct sip_peer *peer; 17979 int load_realtime; 17980 17981 if (argc < 4) 17982 return CLI_SHOWUSAGE; 17983 17984 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 17985 if ((peer = find_peer(argv[3], NULL, load_realtime, FINDPEERS, FALSE, 0))) { 17986 sip_poke_peer(peer, 1); 17987 unref_peer(peer, "qualify: done with peer"); 17988 } else if (type == 0) { 17989 ast_cli(fd, "Peer '%s' not found\n", argv[3]); 17990 } else { 17991 astman_send_error(s, m, "Peer not found"); 17992 } 17993 return CLI_SUCCESS; 17994 }
| static char * _sip_show_peer | ( | int | type, | |
| int | fd, | |||
| struct mansession * | s, | |||
| const struct message * | m, | |||
| int | argc, | |||
| const char * | argv[] | |||
| ) | [static] |
Show one peer in detail (main function).
Definition at line 18061 of file chan_sip.c.
References allowoverlap2str(), ao2_lock, ao2_t_ref, ao2_unlock, ARRAY_LEN, ast_callerid_merge(), ast_cdr_flags2str(), ast_check_realtime(), ast_cli(), AST_CLI_YESNO, ast_codec_pref_index(), ast_describe_caller_presentation(), ast_getformatname(), ast_getformatname_multiple(), AST_LIST_TRAVERSE, ast_print_group(), ast_sched_when(), ast_sockaddr_port, ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_str_alloca, ast_str_buffer(), ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), astman_send_error(), CLI_SHOWUSAGE, CLI_SUCCESS, dtmfmode2str(), FALSE, faxec2str(), find_peer(), get_transport(), get_transport_list(), insecure2str(), ast_variable::name, ast_variable::next, peer_mailboxes_to_str(), peer_status(), print_codec_to_cli(), print_group(), S_OR, sip_cfg, status, stmode2str(), strefresherparam2str(), text, transfermode2str(), TRUE, trust_id_outbound2str(), unref_peer(), and ast_variable::value.
Referenced by manager_sip_show_peer(), and sip_show_peer().
18062 { 18063 char status[30] = ""; 18064 char cbuf[256]; 18065 struct sip_peer *peer; 18066 char codec_buf[512]; 18067 struct ast_codec_pref *pref; 18068 struct ast_variable *v; 18069 int x = 0, load_realtime; 18070 format_t codec = 0; 18071 int realtimepeers; 18072 18073 realtimepeers = ast_check_realtime("sippeers"); 18074 18075 if (argc < 4) 18076 return CLI_SHOWUSAGE; 18077 18078 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 18079 peer = find_peer(argv[3], NULL, load_realtime, FINDPEERS, FALSE, 0); 18080 18081 if (s) { /* Manager */ 18082 if (peer) { 18083 const char *id = astman_get_header(m, "ActionID"); 18084 18085 astman_append(s, "Response: Success\r\n"); 18086 if (!ast_strlen_zero(id)) 18087 astman_append(s, "ActionID: %s\r\n", id); 18088 } else { 18089 snprintf (cbuf, sizeof(cbuf), "Peer %s not found.", argv[3]); 18090 astman_send_error(s, m, cbuf); 18091 return CLI_SUCCESS; 18092 } 18093 } 18094 if (peer && type==0 ) { /* Normal listing */ 18095 struct ast_str *mailbox_str = ast_str_alloca(512); 18096 struct sip_auth_container *credentials; 18097 18098 ao2_lock(peer); 18099 credentials = peer->auth; 18100 if (credentials) { 18101 ao2_t_ref(credentials, +1, "Ref peer auth for show"); 18102 } 18103 ao2_unlock(peer); 18104 18105 ast_cli(fd, "\n\n"); 18106 ast_cli(fd, " * Name : %s\n", peer->name); 18107 if (realtimepeers) { /* Realtime is enabled */ 18108 ast_cli(fd, " Realtime peer: %s\n", peer->is_realtime ? "Yes, cached" : "No"); 18109 } 18110 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 18111 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>"); 18112 ast_cli(fd, " Remote Secret: %s\n", ast_strlen_zero(peer->remotesecret)?"<Not set>":"<Set>"); 18113 if (credentials) { 18114 struct sip_auth *auth; 18115 18116 AST_LIST_TRAVERSE(&credentials->list, auth, node) { 18117 ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s %s\n", 18118 auth->realm, 18119 auth->username, 18120 !ast_strlen_zero(auth->secret) 18121 ? "<Secret set>" 18122 : (!ast_strlen_zero(auth->md5secret) 18123 ? "<MD5secret set>" : "<Not set>")); 18124 } 18125 ao2_t_ref(credentials, -1, "Unref peer auth for show"); 18126 } 18127 ast_cli(fd, " Context : %s\n", peer->context); 18128 ast_cli(fd, " Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") ); 18129 ast_cli(fd, " Language : %s\n", peer->language); 18130 if (!ast_strlen_zero(peer->accountcode)) 18131 ast_cli(fd, " Accountcode : %s\n", peer->accountcode); 18132 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(peer->amaflags)); 18133 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(peer->allowtransfer)); 18134 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres)); 18135 if (!ast_strlen_zero(peer->fromuser)) 18136 ast_cli(fd, " FromUser : %s\n", peer->fromuser); 18137 if (!ast_strlen_zero(peer->fromdomain)) 18138 ast_cli(fd, " FromDomain : %s Port %d\n", peer->fromdomain, (peer->fromdomainport) ? peer->fromdomainport : STANDARD_SIP_PORT); 18139 ast_cli(fd, " Callgroup : "); 18140 print_group(fd, peer->callgroup, 0); 18141 ast_cli(fd, " Pickupgroup : "); 18142 print_group(fd, peer->pickupgroup, 0); 18143 peer_mailboxes_to_str(&mailbox_str, peer); 18144 ast_cli(fd, " MOH Suggest : %s\n", peer->mohsuggest); 18145 ast_cli(fd, " Mailbox : %s\n", ast_str_buffer(mailbox_str)); 18146 ast_cli(fd, " VM Extension : %s\n", peer->vmexten); 18147 ast_cli(fd, " LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff); 18148 ast_cli(fd, " Call limit : %d\n", peer->call_limit); 18149 ast_cli(fd, " Max forwards : %d\n", peer->maxforwards); 18150 if (peer->busy_level) 18151 ast_cli(fd, " Busy level : %d\n", peer->busy_level); 18152 ast_cli(fd, " Dynamic : %s\n", AST_CLI_YESNO(peer->host_dynamic)); 18153 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 18154 ast_cli(fd, " MaxCallBR : %d kbps\n", peer->maxcallbitrate); 18155 ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, peer->expire)); 18156 ast_cli(fd, " Insecure : %s\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE))); 18157 ast_cli(fd, " Force rport : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT))); 18158 ast_cli(fd, " ACL : %s\n", AST_CLI_YESNO(peer->ha != NULL)); 18159 ast_cli(fd, " DirectMedACL : %s\n", AST_CLI_YESNO(peer->directmediaha != NULL)); 18160 ast_cli(fd, " T.38 support : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT))); 18161 ast_cli(fd, " T.38 EC mode : %s\n", faxec2str(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT))); 18162 ast_cli(fd, " T.38 MaxDtgrm: %u\n", peer->t38_maxdatagram); 18163 ast_cli(fd, " DirectMedia : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_DIRECT_MEDIA))); 18164 ast_cli(fd, " PromiscRedir : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR))); 18165 ast_cli(fd, " User=Phone : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_USEREQPHONE))); 18166 ast_cli(fd, " Video Support: %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT) || ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS))); 18167 ast_cli(fd, " Text Support : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT))); 18168 ast_cli(fd, " Ign SDP ver : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_IGNORESDPVERSION))); 18169 ast_cli(fd, " Trust RPID : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_TRUSTRPID))); 18170 ast_cli(fd, " Send RPID : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_SENDRPID))); 18171 ast_cli(fd, " TrustIDOutbnd: %s\n", trust_id_outbound2str(ast_test_flag(&peer->flags[1], SIP_PAGE2_TRUST_ID_OUTBOUND))); 18172 ast_cli(fd, " Subscriptions: %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))); 18173 ast_cli(fd, " Overlap dial : %s\n", allowoverlap2str(ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP))); 18174 if (peer->outboundproxy) 18175 ast_cli(fd, " Outb. proxy : %s %s\n", ast_strlen_zero(peer->outboundproxy->name) ? "<not set>" : peer->outboundproxy->name, 18176 peer->outboundproxy->force ? "(forced)" : ""); 18177 18178 /* - is enumerated */ 18179 ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 18180 ast_cli(fd, " Timer T1 : %d\n", peer->timer_t1); 18181 ast_cli(fd, " Timer B : %d\n", peer->timer_b); 18182 ast_cli(fd, " ToHost : %s\n", peer->tohost); 18183 ast_cli(fd, " Addr->IP : %s\n", ast_sockaddr_stringify(&peer->addr)); 18184 ast_cli(fd, " Defaddr->IP : %s\n", ast_sockaddr_stringify(&peer->defaddr)); 18185 ast_cli(fd, " Prim.Transp. : %s\n", get_transport(peer->socket.type)); 18186 ast_cli(fd, " Allowed.Trsp : %s\n", get_transport_list(peer->transports)); 18187 if (!ast_strlen_zero(sip_cfg.regcontext)) 18188 ast_cli(fd, " Reg. exten : %s\n", peer->regexten); 18189 ast_cli(fd, " Def. Username: %s\n", peer->username); 18190 ast_cli(fd, " SIP Options : "); 18191 if (peer->sipoptions) { 18192 int lastoption = -1; 18193 for (x = 0 ; x < ARRAY_LEN(sip_options); x++) { 18194 if (sip_options[x].id != lastoption) { 18195 if (peer->sipoptions & sip_options[x].id) 18196 ast_cli(fd, "%s ", sip_options[x].text); 18197 lastoption = x; 18198 } 18199 } 18200 } else 18201 ast_cli(fd, "(none)"); 18202 18203 ast_cli(fd, "\n"); 18204 ast_cli(fd, " Codecs : "); 18205 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 18206 ast_cli(fd, "%s\n", codec_buf); 18207 ast_cli(fd, " Codec Order : ("); 18208 print_codec_to_cli(fd, &peer->prefs); 18209 ast_cli(fd, ")\n"); 18210 18211 ast_cli(fd, " Auto-Framing : %s\n", AST_CLI_YESNO(peer->autoframing)); 18212 ast_cli(fd, " Status : "); 18213 peer_status(peer, status, sizeof(status)); 18214 ast_cli(fd, "%s\n", status); 18215 ast_cli(fd, " Useragent : %s\n", peer->useragent); 18216 ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); 18217 ast_cli(fd, " Qualify Freq : %d ms\n", peer->qualifyfreq); 18218 if (peer->chanvars) { 18219 ast_cli(fd, " Variables :\n"); 18220 for (v = peer->chanvars ; v ; v = v->next) 18221 ast_cli(fd, " %s = %s\n", v->name, v->value); 18222 } 18223 18224 ast_cli(fd, " Sess-Timers : %s\n", stmode2str(peer->stimer.st_mode_oper)); 18225 ast_cli(fd, " Sess-Refresh : %s\n", strefresherparam2str(peer->stimer.st_ref)); 18226 ast_cli(fd, " Sess-Expires : %d secs\n", peer->stimer.st_max_se); 18227 ast_cli(fd, " Min-Sess : %d secs\n", peer->stimer.st_min_se); 18228 ast_cli(fd, " RTP Engine : %s\n", peer->engine); 18229 ast_cli(fd, " Parkinglot : %s\n", peer->parkinglot); 18230 ast_cli(fd, " Use Reason : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_Q850_REASON))); 18231 ast_cli(fd, " Encryption : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_USE_SRTP))); 18232 ast_cli(fd, "\n"); 18233 peer = unref_peer(peer, "sip_show_peer: unref_peer: done with peer ptr"); 18234 } else if (peer && type == 1) { /* manager listing */ 18235 char buffer[256]; 18236 struct ast_str *mailbox_str = ast_str_alloca(512); 18237 astman_append(s, "Channeltype: SIP\r\n"); 18238 astman_append(s, "ObjectName: %s\r\n", peer->name); 18239 astman_append(s, "ChanObjectType: peer\r\n"); 18240 astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y"); 18241 astman_append(s, "RemoteSecretExist: %s\r\n", ast_strlen_zero(peer->remotesecret)?"N":"Y"); 18242 astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y"); 18243 astman_append(s, "Context: %s\r\n", peer->context); 18244 astman_append(s, "Language: %s\r\n", peer->language); 18245 if (!ast_strlen_zero(peer->accountcode)) 18246 astman_append(s, "Accountcode: %s\r\n", peer->accountcode); 18247 astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags)); 18248 astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres)); 18249 if (!ast_strlen_zero(peer->fromuser)) 18250 astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser); 18251 if (!ast_strlen_zero(peer->fromdomain)) 18252 astman_append(s, "SIP-FromDomain: %s\r\nSip-FromDomain-Port: %d\r\n", peer->fromdomain, (peer->fromdomainport) ? peer->fromdomainport : STANDARD_SIP_PORT); 18253 astman_append(s, "Callgroup: "); 18254 astman_append(s, "%s\r\n", ast_print_group(buffer, sizeof(buffer), peer->callgroup)); 18255 astman_append(s, "Pickupgroup: "); 18256 astman_append(s, "%s\r\n", ast_print_group(buffer, sizeof(buffer), peer->pickupgroup)); 18257 astman_append(s, "MOHSuggest: %s\r\n", peer->mohsuggest); 18258 peer_mailboxes_to_str(&mailbox_str, peer); 18259 astman_append(s, "VoiceMailbox: %s\r\n", ast_str_buffer(mailbox_str)); 18260 astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer)); 18261 astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent); 18262 astman_append(s, "Maxforwards: %d\r\n", peer->maxforwards); 18263 astman_append(s, "Call-limit: %d\r\n", peer->call_limit); 18264 astman_append(s, "Busy-level: %d\r\n", peer->busy_level); 18265 astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate); 18266 astman_append(s, "Dynamic: %s\r\n", peer->host_dynamic?"Y":"N"); 18267 astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); 18268 astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched, peer->expire)); 18269 astman_append(s, "SIP-AuthInsecure: %s\r\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE))); 18270 astman_append(s, "SIP-Forcerport: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT)?"Y":"N")); 18271 astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N")); 18272 astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_DIRECT_MEDIA)?"Y":"N")); 18273 astman_append(s, "SIP-DirectMedia: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_DIRECT_MEDIA)?"Y":"N")); 18274 astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N")); 18275 astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N")); 18276 astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N")); 18277 astman_append(s, "SIP-TextSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT)?"Y":"N")); 18278 astman_append(s, "SIP-T.38Support: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT)?"Y":"N")); 18279 astman_append(s, "SIP-T.38EC: %s\r\n", faxec2str(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT))); 18280 astman_append(s, "SIP-T.38MaxDtgrm: %u\r\n", peer->t38_maxdatagram); 18281 astman_append(s, "SIP-Sess-Timers: %s\r\n", stmode2str(peer->stimer.st_mode_oper)); 18282 astman_append(s, "SIP-Sess-Refresh: %s\r\n", strefresherparam2str(peer->stimer.st_ref)); 18283 astman_append(s, "SIP-Sess-Expires: %d\r\n", peer->stimer.st_max_se); 18284 astman_append(s, "SIP-Sess-Min: %d\r\n", peer->stimer.st_min_se); 18285 astman_append(s, "SIP-RTP-Engine: %s\r\n", peer->engine); 18286 astman_append(s, "SIP-Encryption: %s\r\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_USE_SRTP) ? "Y" : "N"); 18287 18288 /* - is enumerated */ 18289 astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 18290 astman_append(s, "ToHost: %s\r\n", peer->tohost); 18291 astman_append(s, "Address-IP: %s\r\nAddress-Port: %d\r\n", ast_sockaddr_stringify_addr(&peer->addr), ast_sockaddr_port(&peer->addr)); 18292 astman_append(s, "Default-addr-IP: %s\r\nDefault-addr-port: %d\r\n", ast_sockaddr_stringify_addr(&peer->defaddr), ast_sockaddr_port(&peer->defaddr)); 18293 astman_append(s, "Default-Username: %s\r\n", peer->username); 18294 if (!ast_strlen_zero(sip_cfg.regcontext)) 18295 astman_append(s, "RegExtension: %s\r\n", peer->regexten); 18296 astman_append(s, "Codecs: "); 18297 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 18298 astman_append(s, "%s\r\n", codec_buf); 18299 astman_append(s, "CodecOrder: "); 18300 pref = &peer->prefs; 18301 for(x = 0; x < 64 ; x++) { 18302 codec = ast_codec_pref_index(pref, x); 18303 if (!codec) 18304 break; 18305 astman_append(s, "%s", ast_getformatname(codec)); 18306 if (x < 63 && ast_codec_pref_index(pref, x+1)) 18307 astman_append(s, ","); 18308 } 18309 18310 astman_append(s, "\r\n"); 18311 astman_append(s, "Status: "); 18312 peer_status(peer, status, sizeof(status)); 18313 astman_append(s, "%s\r\n", status); 18314 astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent); 18315 astman_append(s, "Reg-Contact: %s\r\n", peer->fullcontact); 18316 astman_append(s, "QualifyFreq: %d ms\r\n", peer->qualifyfreq); 18317 astman_append(s, "Parkinglot: %s\r\n", peer->parkinglot); 18318 if (peer->chanvars) { 18319 for (v = peer->chanvars ; v ; v = v->next) { 18320 astman_append(s, "ChanVariable: %s=%s\r\n", v->name, v->value); 18321 } 18322 } 18323 astman_append(s, "SIP-Use-Reason-Header: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_Q850_REASON)) ? "Y" : "N"); 18324 18325 peer = unref_peer(peer, "sip_show_peer: unref_peer: done with peer"); 18326 18327 } else { 18328 ast_cli(fd, "Peer %s not found.\n", argv[3]); 18329 ast_cli(fd, "\n"); 18330 } 18331 18332 return CLI_SUCCESS; 18333 }
| static char * _sip_show_peers | ( | int | fd, | |
| int * | total, | |||
| struct mansession * | s, | |||
| const struct message * | m, | |||
| int | argc, | |||
| const char * | argv[] | |||
| ) | [static] |
Execute sip show peers command.
Definition at line 17303 of file chan_sip.c.
References _sip_show_peers_one(), ao2_callback, ao2_container_count(), ao2_iterator_destroy(), ao2_lock, ao2_t_iterator_next, ao2_unlock, ast_calloc, ast_check_realtime(), ast_cli(), ast_free, ast_log(), AST_LOG_ERROR, ast_strlen_zero(), astman_get_header(), CLI_FAILURE, CLI_SHOWUSAGE, CLI_SUCCESS, FALSE, show_peers_context::havepattern, id, show_peers_context::idtext, OBJ_MULTIPLE, peercomparefunc(), PEERS_FORMAT2, show_peers_context::peers_mon_offline, show_peers_context::peers_mon_online, show_peers_context::peers_unmon_offline, show_peers_context::peers_unmon_online, show_peers_context::realtimepeers, show_peers_context::regexbuf, TRUE, and unref_peer().
Referenced by manager_sip_show_peers(), and sip_show_peers().
17304 { 17305 struct show_peers_context cont = { 17306 .havepattern = FALSE, 17307 .idtext = "", 17308 17309 .peers_mon_online = 0, 17310 .peers_mon_offline = 0, 17311 .peers_unmon_online = 0, 17312 .peers_unmon_offline = 0, 17313 }; 17314 struct sip_peer *peer; 17315 struct ao2_iterator* it_peers; 17316 17317 int total_peers = 0; 17318 const char *id; 17319 struct sip_peer **peerarray; 17320 int k; 17321 17322 cont.realtimepeers = ast_check_realtime("sippeers"); 17323 17324 if (s) { /* Manager - get ActionID */ 17325 id = astman_get_header(m, "ActionID"); 17326 if (!ast_strlen_zero(id)) { 17327 snprintf(cont.idtext, sizeof(cont.idtext), "ActionID: %s\r\n", id); 17328 } 17329 } 17330 17331 switch (argc) { 17332 case 5: 17333 if (!strcasecmp(argv[3], "like")) { 17334 if (regcomp(&cont.regexbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 17335 return CLI_SHOWUSAGE; 17336 cont.havepattern = TRUE; 17337 } else 17338 return CLI_SHOWUSAGE; 17339 case 3: 17340 break; 17341 default: 17342 return CLI_SHOWUSAGE; 17343 } 17344 17345 if (!s) { 17346 /* Normal list */ 17347 ast_cli(fd, PEERS_FORMAT2, "Name/username", "Host", "Dyn", "Forcerport", "ACL", "Port", "Status", (cont.realtimepeers ? "Realtime" : "")); 17348 } 17349 17350 ao2_lock(peers); 17351 if (!(it_peers = ao2_callback(peers, OBJ_MULTIPLE, NULL, NULL))) { 17352 ast_log(AST_LOG_ERROR, "Unable to create iterator for peers container for sip show peers\n"); 17353 ao2_unlock(peers); 17354 return CLI_FAILURE; 17355 } 17356 if (!(peerarray = ast_calloc(sizeof(struct sip_peer *), ao2_container_count(peers)))) { 17357 ast_log(AST_LOG_ERROR, "Unable to allocate peer array for sip show peers\n"); 17358 ao2_iterator_destroy(it_peers); 17359 ao2_unlock(peers); 17360 return CLI_FAILURE; 17361 } 17362 ao2_unlock(peers); 17363 17364 while ((peer = ao2_t_iterator_next(it_peers, "iterate thru peers table"))) { 17365 ao2_lock(peer); 17366 17367 if (!(peer->type & SIP_TYPE_PEER)) { 17368 ao2_unlock(peer); 17369 unref_peer(peer, "unref peer because it's actually a user"); 17370 continue; 17371 } 17372 17373 if (cont.havepattern && regexec(&cont.regexbuf, peer->name, 0, NULL, 0)) { 17374 ao2_unlock(peer); 17375 unref_peer(peer, "toss iterator peer ptr before continue"); 17376 continue; 17377 } 17378 17379 peerarray[total_peers++] = peer; 17380 ao2_unlock(peer); 17381 } 17382 ao2_iterator_destroy(it_peers); 17383 17384 qsort(peerarray, total_peers, sizeof(struct sip_peer *), peercomparefunc); 17385 17386 for(k = 0; k < total_peers; k++) { 17387 peerarray[k] = _sip_show_peers_one(fd, s, &cont, peerarray[k]); 17388 } 17389 17390 if (!s) { 17391 ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n", 17392 total_peers, cont.peers_mon_online, cont.peers_mon_offline, cont.peers_unmon_online, cont.peers_unmon_offline); 17393 } 17394 17395 if (cont.havepattern) { 17396 regfree(&cont.regexbuf); 17397 } 17398 17399 if (total) { 17400 *total = total_peers; 17401 } 17402 17403 ast_free(peerarray); 17404 17405 return CLI_SUCCESS; 17406 }
| static struct sip_peer * _sip_show_peers_one | ( | int | fd, | |
| struct mansession * | s, | |||
| struct show_peers_context * | cont, | |||
| struct sip_peer * | peer | |||
| ) | [static, read] |
Emit informations for one peer during sip show peers command.
Definition at line 17409 of file chan_sip.c.
References ao2_lock, ao2_unlock, ast_cli(), ast_copy_string(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_sockaddr_stringify_port(), ast_strdupa, ast_strlen_zero(), ast_test_flag, astman_append(), show_peers_context::havepattern, show_peers_context::idtext, name, peer_status(), PEERS_FORMAT2, show_peers_context::peers_mon_offline, show_peers_context::peers_mon_online, show_peers_context::peers_unmon_offline, show_peers_context::peers_unmon_online, show_peers_context::realtimepeers, show_peers_context::regexbuf, status, and unref_peer().
Referenced by _sip_show_peers().
17410 { 17411 /* _sip_show_peers_one() is separated from _sip_show_peers() to properly free the ast_strdupa 17412 * (this is executed in a loop in _sip_show_peers() ) 17413 */ 17414 17415 char name[256]; 17416 char status[20] = ""; 17417 char pstatus; 17418 17419 /* 17420 * tmp_port and tmp_host store copies of ast_sockaddr_stringify strings since the 17421 * string pointers for that function aren't valid between subsequent calls to 17422 * ast_sockaddr_stringify functions 17423 */ 17424 char *tmp_port; 17425 char *tmp_host; 17426 17427 tmp_port = ast_sockaddr_isnull(&peer->addr) ? 17428 "0" : ast_strdupa(ast_sockaddr_stringify_port(&peer->addr)); 17429 17430 tmp_host = ast_sockaddr_isnull(&peer->addr) ? 17431 "(Unspecified)" : ast_strdupa(ast_sockaddr_stringify_addr(&peer->addr)); 17432 17433 ao2_lock(peer); 17434 if (cont->havepattern && regexec(&cont->regexbuf, peer->name, 0, NULL, 0)) { 17435 ao2_unlock(peer); 17436 return unref_peer(peer, "toss iterator peer ptr no match"); 17437 } 17438 17439 if (!ast_strlen_zero(peer->username) && !s) { 17440 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 17441 } else { 17442 ast_copy_string(name, peer->name, sizeof(name)); 17443 } 17444 17445 pstatus = peer_status(peer, status, sizeof(status)); 17446 if (pstatus == 1) { 17447 cont->peers_mon_online++; 17448 } else if (pstatus == 0) { 17449 cont->peers_mon_offline++; 17450 } else { 17451 if (ast_sockaddr_isnull(&peer->addr) || 17452 !ast_sockaddr_port(&peer->addr)) { 17453 cont->peers_unmon_offline++; 17454 } else { 17455 cont->peers_unmon_online++; 17456 } 17457 } 17458 17459 if (!s) { /* Normal CLI list */ 17460 ast_cli(fd, PEERS_FORMAT2, name, 17461 tmp_host, 17462 peer->host_dynamic ? " D " : " ", /* Dynamic or not? */ 17463 ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? " N " : " ", /* NAT=yes? */ 17464 peer->ha ? " A " : " ", /* permit/deny */ 17465 tmp_port, status, 17466 cont->realtimepeers ? (peer->is_realtime ? "Cached RT":"") : ""); 17467 } else { /* Manager format */ 17468 /* The names here need to be the same as other channels */ 17469 astman_append(s, 17470 "Event: PeerEntry\r\n%s" 17471 "Channeltype: SIP\r\n" 17472 "ObjectName: %s\r\n" 17473 "ChanObjectType: peer\r\n" /* "peer" or "user" */ 17474 "IPaddress: %s\r\n" 17475 "IPport: %s\r\n" 17476 "Dynamic: %s\r\n" 17477 "Forcerport: %s\r\n" 17478 "VideoSupport: %s\r\n" 17479 "TextSupport: %s\r\n" 17480 "ACL: %s\r\n" 17481 "Status: %s\r\n" 17482 "RealtimeDevice: %s\r\n\r\n", 17483 cont->idtext, 17484 peer->name, 17485 ast_sockaddr_isnull(&peer->addr) ? "-none-" : tmp_host, 17486 ast_sockaddr_isnull(&peer->addr) ? "0" : tmp_port, 17487 peer->host_dynamic ? "yes" : "no", /* Dynamic or not? */ 17488 ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? "yes" : "no", /* NAT=yes? */ 17489 ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */ 17490 ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT) ? "yes" : "no", /* TEXTSUPPORT=yes? */ 17491 peer->ha ? "yes" : "no", /* permit/deny */ 17492 status, 17493 cont->realtimepeers ? (peer->is_realtime ? "yes":"no") : "no"); 17494 } 17495 ao2_unlock(peer); 17496 17497 return unref_peer(peer, "toss iterator peer ptr"); 17498 }
| static void * _sip_tcp_helper_thread | ( | struct ast_tcptls_session_instance * | tcptls_session | ) | [static] |
SIP TCP thread management function This function reads from the socket, parses the packet into a request.
Definition at line 2728 of file chan_sip.c.
References ao2_lock, ao2_ref, ao2_t_find, ao2_t_ref, ao2_t_unlink, ao2_unlock, ast_atomic_fetchadd_int(), ast_debug, AST_LIST_REMOVE_HEAD, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_poll, ast_str_buffer(), ast_str_create(), ast_str_reset(), ast_str_strlen(), ast_tcptls_client_start(), ast_tcptls_close_session_file(), ast_tcptls_server_write(), ast_tcptls_stream_set_exclusive_input(), ast_tcptls_stream_set_timeout_disable(), ast_tcptls_stream_set_timeout_sequence(), ast_tvnow(), cleanup(), ast_tcptls_session_instance::client, deinit_req(), errno, ast_tcptls_session_instance::fd, handle_request_do(), ast_tcptls_session_instance::lock, LOG_ERROR, LOG_WARNING, OBJ_POINTER, ast_tcptls_session_instance::overflow_buf, ast_tcptls_session_instance::parent, ast_tcptls_session_instance::remote_address, set_socket_transport(), sip_check_authtimeout(), sip_tcptls_read(), sip_threadinfo_create(), ast_tcptls_session_instance::ssl, and ast_tcptls_session_instance::stream_cookie.
Referenced by sip_tcp_worker_fn().
02729 { 02730 int res, timeout = -1, authenticated = 0, flags; 02731 time_t start; 02732 struct sip_request req = { 0, } , reqcpy = { 0, }; 02733 struct sip_threadinfo *me = NULL; 02734 char buf[1024] = ""; 02735 struct pollfd fds[2] = { { 0 }, { 0 }, }; 02736 struct ast_tcptls_session_args *ca = NULL; 02737 02738 /* If this is a server session, then the connection has already been 02739 * setup. Check if the authlimit has been reached and if not create the 02740 * threadinfo object so we can access this thread for writing. 02741 * 02742 * if this is a client connection more work must be done. 02743 * 1. We own the parent session args for a client connection. This pointer needs 02744 * to be held on to so we can decrement it's ref count on thread destruction. 02745 * 2. The threadinfo object was created before this thread was launched, however 02746 * it must be found within the threadt table. 02747 * 3. Last, the tcptls_session must be started. 02748 */ 02749 if (!tcptls_session->client) { 02750 if (ast_atomic_fetchadd_int(&unauth_sessions, +1) >= authlimit) { 02751 /* unauth_sessions is decremented in the cleanup code */ 02752 goto cleanup; 02753 } 02754 02755 if ((flags = fcntl(tcptls_session->fd, F_GETFL)) == -1) { 02756 ast_log(LOG_ERROR, "error setting socket to non blocking mode, fcntl() failed: %s\n", strerror(errno)); 02757 goto cleanup; 02758 } 02759 02760 flags |= O_NONBLOCK; 02761 if (fcntl(tcptls_session->fd, F_SETFL, flags) == -1) { 02762 ast_log(LOG_ERROR, "error setting socket to non blocking mode, fcntl() failed: %s\n", strerror(errno)); 02763 goto cleanup; 02764 } 02765 02766 if (!(me = sip_threadinfo_create(tcptls_session, tcptls_session->ssl ? SIP_TRANSPORT_TLS : SIP_TRANSPORT_TCP))) { 02767 goto cleanup; 02768 } 02769 ao2_t_ref(me, +1, "Adding threadinfo ref for tcp_helper_thread"); 02770 } else { 02771 struct sip_threadinfo tmp = { 02772 .tcptls_session = tcptls_session, 02773 }; 02774 02775 if ((!(ca = tcptls_session->parent)) || 02776 (!(me = ao2_t_find(threadt, &tmp, OBJ_POINTER, "ao2_find, getting sip_threadinfo in tcp helper thread"))) || 02777 (!(tcptls_session = ast_tcptls_client_start(tcptls_session)))) { 02778 goto cleanup; 02779 } 02780 } 02781 02782 flags = 1; 02783 if (setsockopt(tcptls_session->fd, SOL_SOCKET, SO_KEEPALIVE, &flags, sizeof(flags))) { 02784 ast_log(LOG_ERROR, "error enabling TCP keep-alives on sip socket: %s\n", strerror(errno)); 02785 goto cleanup; 02786 } 02787 02788 me->threadid = pthread_self(); 02789 ast_debug(2, "Starting thread for %s server\n", tcptls_session->ssl ? "TLS" : "TCP"); 02790 02791 /* set up pollfd to watch for reads on both the socket and the alert_pipe */ 02792 fds[0].fd = tcptls_session->fd; 02793 fds[1].fd = me->alert_pipe[0]; 02794 fds[0].events = fds[1].events = POLLIN | POLLPRI; 02795 02796 if (!(req.data = ast_str_create(SIP_MIN_PACKET))) { 02797 goto cleanup; 02798 } 02799 if (!(reqcpy.data = ast_str_create(SIP_MIN_PACKET))) { 02800 goto cleanup; 02801 } 02802 02803 if(time(&start) == -1) { 02804 ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno)); 02805 goto cleanup; 02806 } 02807 02808 /* 02809 * We cannot let the stream exclusively wait for data to arrive. 02810 * We have to wake up the task to send outgoing messages. 02811 */ 02812 ast_tcptls_stream_set_exclusive_input(tcptls_session->stream_cookie, 0); 02813 02814 ast_tcptls_stream_set_timeout_sequence(tcptls_session->stream_cookie, ast_tvnow(), 02815 tcptls_session->client ? -1 : (authtimeout * 1000)); 02816 02817 for (;;) { 02818 struct ast_str *str_save; 02819 02820 if (!tcptls_session->client && req.authenticated && !authenticated) { 02821 authenticated = 1; 02822 ast_tcptls_stream_set_timeout_disable(tcptls_session->stream_cookie); 02823 ast_atomic_fetchadd_int(&unauth_sessions, -1); 02824 } 02825 02826 /* calculate the timeout for unauthenticated server sessions */ 02827 if (!tcptls_session->client && !authenticated ) { 02828 if ((timeout = sip_check_authtimeout(start)) < 0) { 02829 goto cleanup; 02830 } 02831 02832 if (timeout == 0) { 02833 ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "TLS": "TCP"); 02834 goto cleanup; 02835 } 02836 } else { 02837 timeout = -1; 02838 } 02839 02840 if (ast_str_strlen(tcptls_session->overflow_buf) == 0) { 02841 res = ast_poll(fds, 2, timeout); /* polls for both socket and alert_pipe */ 02842 if (res < 0) { 02843 ast_debug(2, "SIP %s server :: ast_wait_for_input returned %d\n", tcptls_session->ssl ? "TLS": "TCP", res); 02844 goto cleanup; 02845 } else if (res == 0) { 02846 /* timeout */ 02847 ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "TLS": "TCP"); 02848 goto cleanup; 02849 } 02850 } 02851 02852 /* 02853 * handle the socket event, check for both reads from the socket fd or TCP overflow buffer, 02854 * and writes from alert_pipe fd. 02855 */ 02856 if (fds[0].revents || (ast_str_strlen(tcptls_session->overflow_buf) > 0)) { /* there is data on the socket to be read */ 02857 fds[0].revents = 0; 02858 02859 /* clear request structure */ 02860 str_save = req.data; 02861 memset(&req, 0, sizeof(req)); 02862 req.data = str_save; 02863 ast_str_reset(req.data); 02864 02865 str_save = reqcpy.data; 02866 memset(&reqcpy, 0, sizeof(reqcpy)); 02867 reqcpy.data = str_save; 02868 ast_str_reset(reqcpy.data); 02869 02870 memset(buf, 0, sizeof(buf)); 02871 02872 if (tcptls_session->ssl) { 02873 set_socket_transport(&req.socket, SIP_TRANSPORT_TLS); 02874 req.socket.port = htons(ourport_tls); 02875 } else { 02876 set_socket_transport(&req.socket, SIP_TRANSPORT_TCP); 02877 req.socket.port = htons(ourport_tcp); 02878 } 02879 req.socket.fd = tcptls_session->fd; 02880 02881 res = sip_tcptls_read(&req, tcptls_session, authenticated, start); 02882 if (res < 0) { 02883 goto cleanup; 02884 } 02885 02886 req.socket.tcptls_session = tcptls_session; 02887 handle_request_do(&req, &tcptls_session->remote_address); 02888 } 02889 02890 if (fds[1].revents) { /* alert_pipe indicates there is data in the send queue to be sent */ 02891 enum sip_tcptls_alert alert; 02892 struct tcptls_packet *packet; 02893 02894 fds[1].revents = 0; 02895 02896 if (read(me->alert_pipe[0], &alert, sizeof(alert)) == -1) { 02897 ast_log(LOG_ERROR, "read() failed: %s\n", strerror(errno)); 02898 continue; 02899 } 02900 02901 switch (alert) { 02902 case TCPTLS_ALERT_STOP: 02903 goto cleanup; 02904 case TCPTLS_ALERT_DATA: 02905 ao2_lock(me); 02906 if (!(packet = AST_LIST_REMOVE_HEAD(&me->packet_q, entry))) { 02907 ast_log(LOG_WARNING, "TCPTLS thread alert_pipe indicated packet should be sent, but frame_q is empty\n"); 02908 } 02909 ao2_unlock(me); 02910 02911 if (packet) { 02912 if (ast_tcptls_server_write(tcptls_session, ast_str_buffer(packet->data), packet->len) == -1) { 02913 ast_log(LOG_WARNING, "Failure to write to tcp/tls socket\n"); 02914 } 02915 ao2_t_ref(packet, -1, "tcptls packet sent, this is no longer needed"); 02916 } 02917 break; 02918 default: 02919 ast_log(LOG_ERROR, "Unknown tcptls thread alert '%u'\n", alert); 02920 } 02921 } 02922 } 02923 02924 ast_debug(2, "Shutting down thread for %s server\n", tcptls_session->ssl ? "TLS" : "TCP"); 02925 02926 cleanup: 02927 if (tcptls_session && !tcptls_session->client && !authenticated) { 02928 ast_atomic_fetchadd_int(&unauth_sessions, -1); 02929 } 02930 02931 if (me) { 02932 ao2_t_unlink(threadt, me, "Removing tcptls helper thread, thread is closing"); 02933 ao2_t_ref(me, -1, "Removing tcp_helper_threads threadinfo ref"); 02934 } 02935 deinit_req(&reqcpy); 02936 deinit_req(&req); 02937 02938 /* if client, we own the parent session arguments and must decrement ref */ 02939 if (ca) { 02940 ao2_t_ref(ca, -1, "closing tcptls thread, getting rid of client tcptls_session arguments"); 02941 } 02942 02943 if (tcptls_session) { 02944 ast_mutex_lock(&tcptls_session->lock); 02945 ast_tcptls_close_session_file(tcptls_session); 02946 tcptls_session->parent = NULL; 02947 ast_mutex_unlock(&tcptls_session->lock); 02948 02949 ao2_ref(tcptls_session, -1); 02950 tcptls_session = NULL; 02951 } 02952 return NULL; 02953 }
| static void add_blank | ( | struct sip_request * | req | ) | [static] |
add a blank line if no body
Definition at line 4269 of file chan_sip.c.
References ast_str_append().
Referenced by send_request(), and send_response().
04270 { 04271 if (!req->lines) { 04272 /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */ 04273 ast_str_append(&req->data, 0, "\r\n"); 04274 } 04275 }
| static void add_cc_call_info_to_response | ( | struct sip_pvt * | p, | |
| struct sip_request * | resp | |||
| ) | [static] |
Definition at line 12134 of file chan_sip.c.
References add_header(), ao2_ref, ast_copy_string(), ast_log(), ast_str_alloca, ast_str_buffer(), ast_str_set(), ast_strlen_zero(), find_sip_cc_agent_by_original_callid(), generate_uri(), LOG_WARNING, and ast_cc_agent::private_data.
Referenced by __transmit_response(), and transmit_response_with_sdp().
12135 { 12136 char uri[SIPBUFSIZE]; 12137 struct ast_str *header = ast_str_alloca(SIPBUFSIZE); 12138 struct ast_cc_agent *agent = find_sip_cc_agent_by_original_callid(p); 12139 struct sip_cc_agent_pvt *agent_pvt; 12140 12141 if (!agent) { 12142 /* Um, what? How could the SIP_OFFER_CC flag be set but there not be an 12143 * agent? Oh well, we'll just warn and return without adding the header. 12144 */ 12145 ast_log(LOG_WARNING, "Can't find SIP CC agent for call '%s' even though OFFER_CC flag was set?\n", p->callid); 12146 return; 12147 } 12148 12149 agent_pvt = agent->private_data; 12150 12151 if (!ast_strlen_zero(agent_pvt->subscribe_uri)) { 12152 ast_copy_string(uri, agent_pvt->subscribe_uri, sizeof(uri)); 12153 } else { 12154 generate_uri(p, uri, sizeof(uri)); 12155 ast_copy_string(agent_pvt->subscribe_uri, uri, sizeof(agent_pvt->subscribe_uri)); 12156 } 12157 /* XXX Hardcode "NR" as the m reason for now. This should perhaps be changed 12158 * to be more accurate. This parameter has no bearing on the actual operation 12159 * of the feature; it's just there for informational purposes. 12160 */ 12161 ast_str_set(&header, 0, "<%s>;purpose=call-completion;m=%s", uri, "NR"); 12162 add_header(resp, "Call-Info", ast_str_buffer(header)); 12163 ao2_ref(agent, -1); 12164 }
| static void add_codec_to_sdp | ( | const struct sip_pvt * | p, | |
| format_t | codec, | |||
| struct ast_str ** | m_buf, | |||
| struct ast_str ** | a_buf, | |||
| int | debug, | |||
| int * | min_packet_size | |||
| ) | [static] |
Add codec offer to SDP offer/answer body in INVITE or 200 OK.
Definition at line 11385 of file chan_sip.c.
References ast_codec_pref_getsize(), AST_FORMAT_G719, AST_FORMAT_G723_1, AST_FORMAT_G729A, AST_FORMAT_ILBC, AST_FORMAT_SIREN14, AST_FORMAT_SIREN7, ast_getformatname(), ast_rtp_codecs_payload_code(), ast_rtp_instance_get_codecs(), ast_rtp_lookup_mime_subtype2(), ast_rtp_lookup_sample_rate2(), AST_RTP_OPT_G726_NONSTANDARD, ast_str_append(), ast_test_flag, ast_verbose, ast_format_list::cur_ms, and ast_rtp_codecs::pref.
Referenced by add_sdp().
11388 { 11389 int rtp_code; 11390 struct ast_format_list fmt; 11391 11392 11393 if (debug) 11394 ast_verbose("Adding codec 0x%" PRIx64 " (%s) to SDP\n", (uint64_t)codec, ast_getformatname(codec)); 11395 if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->rtp), 1, codec)) == -1) 11396 return; 11397 11398 if (p->rtp) { 11399 struct ast_codec_pref *pref = &ast_rtp_instance_get_codecs(p->rtp)->pref; 11400 fmt = ast_codec_pref_getsize(pref, codec); 11401 } else /* I don't see how you couldn't have p->rtp, but good to check for and error out if not there like earlier code */ 11402 return; 11403 ast_str_append(m_buf, 0, " %d", rtp_code); 11404 ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%u\r\n", rtp_code, 11405 ast_rtp_lookup_mime_subtype2(1, codec, 11406 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0), 11407 ast_rtp_lookup_sample_rate2(1, codec)); 11408 11409 switch (codec) { 11410 case AST_FORMAT_G729A: 11411 /* Indicate that we don't support VAD (G.729 annex B) */ 11412 ast_str_append(a_buf, 0, "a=fmtp:%d annexb=no\r\n", rtp_code); 11413 break; 11414 case AST_FORMAT_G723_1: 11415 /* Indicate that we don't support VAD (G.723.1 annex A) */ 11416 ast_str_append(a_buf, 0, "a=fmtp:%d annexa=no\r\n", rtp_code); 11417 break; 11418 case AST_FORMAT_ILBC: 11419 /* Add information about us using only 20/30 ms packetization */ 11420 ast_str_append(a_buf, 0, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms); 11421 break; 11422 case AST_FORMAT_SIREN7: 11423 /* Indicate that we only expect 32Kbps */ 11424 ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=32000\r\n", rtp_code); 11425 break; 11426 case AST_FORMAT_SIREN14: 11427 /* Indicate that we only expect 48Kbps */ 11428 ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=48000\r\n", rtp_code); 11429 break; 11430 case AST_FORMAT_G719: 11431 /* Indicate that we only expect 64Kbps */ 11432 ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=64000\r\n", rtp_code); 11433 break; 11434 } 11435 11436 if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size)) 11437 *min_packet_size = fmt.cur_ms; 11438 11439 /* Our first codec packetization processed cannot be zero */ 11440 if ((*min_packet_size)==0 && fmt.cur_ms) 11441 *min_packet_size = fmt.cur_ms; 11442 }
| static int add_content | ( | struct sip_request * | req, | |
| const char * | line | |||
| ) | [static] |
Add content (not header) to SIP message.
Definition at line 10276 of file chan_sip.c.
References ast_log(), ast_str_append(), and LOG_WARNING.
Referenced by add_digit(), add_sdp(), add_text(), add_vidupdate(), transmit_cc_notify(), transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), and transmit_state_notify().
10277 { 10278 if (req->lines) { 10279 ast_log(LOG_WARNING, "Can't add more content when the content has been finalized\n"); 10280 return -1; 10281 } 10282 10283 ast_str_append(&req->content, 0, "%s", line); 10284 return 0; 10285 }
| static int add_digit | ( | struct sip_request * | req, | |
| char | digit, | |||
| unsigned int | duration, | |||
| int | mode | |||
| ) | [static] |
Add DTMF INFO tone to sip message Mode = 0 for application/dtmf-relay (Cisco) 1 for application/dtmf.
Definition at line 11214 of file chan_sip.c.
References add_content(), and add_header().
Referenced by transmit_info_with_digit().
11215 { 11216 char tmp[256]; 11217 int event; 11218 if (mode) { 11219 /* Application/dtmf short version used by some implementations */ 11220 if ('0' <= digit && digit <= '9') { 11221 event = digit - '0'; 11222 } else if (digit == '*') { 11223 event = 10; 11224 } else if (digit == '#') { 11225 event = 11; 11226 } else if ('A' <= digit && digit <= 'D') { 11227 event = 12 + digit - 'A'; 11228 } else if ('a' <= digit && digit <= 'd') { 11229 event = 12 + digit - 'a'; 11230 } else { 11231 /* Unknown digit */ 11232 event = 0; 11233 } 11234 snprintf(tmp, sizeof(tmp), "%d\r\n", event); 11235 add_header(req, "Content-Type", "application/dtmf"); 11236 add_content(req, tmp); 11237 } else { 11238 /* Application/dtmf-relay as documented by Cisco */ 11239 snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration); 11240 add_header(req, "Content-Type", "application/dtmf-relay"); 11241 add_content(req, tmp); 11242 } 11243 return 0; 11244 }
| static void add_diversion_header | ( | struct sip_request * | req, | |
| struct sip_pvt * | pvt | |||
| ) | [static] |
Add "Diversion" header to outgoing message.
We need to add a Diversion header if the owner channel of this dialog has redirecting information associated with it.
| req | The request/response to which we will add the header | |
| pvt | The sip_pvt which represents the call-leg |
Definition at line 12529 of file chan_sip.c.
References add_header(), ast_escape_quoted(), ast_sockaddr_stringify_host_remote(), ast_strlen_zero(), and sip_reason_code_to_str().
Referenced by __transmit_response(), transmit_invite(), and update_redirecting().
12530 { 12531 const char *diverting_number; 12532 const char *diverting_name; 12533 const char *reason; 12534 char header_text[256]; 12535 12536 if (!pvt->owner) { 12537 return; 12538 } 12539 12540 diverting_number = pvt->owner->redirecting.from.number.str; 12541 if (!pvt->owner->redirecting.from.number.valid 12542 || ast_strlen_zero(diverting_number)) { 12543 return; 12544 } 12545 12546 reason = sip_reason_code_to_str(pvt->owner->redirecting.reason); 12547 12548 /* We at least have a number to place in the Diversion header, which is enough */ 12549 diverting_name = pvt->owner->redirecting.from.name.str; 12550 if (!pvt->owner->redirecting.from.name.valid 12551 || ast_strlen_zero(diverting_name)) { 12552 snprintf(header_text, sizeof(header_text), "<sip:%s@%s>;reason=%s", diverting_number, 12553 ast_sockaddr_stringify_host_remote(&pvt->ourip), reason); 12554 } else { 12555 char diverting_name_buf[128]; 12556 12557 ast_escape_quoted(diverting_name, diverting_name_buf, sizeof(diverting_name_buf)); 12558 snprintf(header_text, sizeof(header_text), "\"%s\" <sip:%s@%s>;reason=%s", 12559 diverting_name_buf, diverting_number, 12560 ast_sockaddr_stringify_host_remote(&pvt->ourip), reason); 12561 } 12562 12563 add_header(req, "Diversion", header_text); 12564 }
| static int add_header | ( | struct sip_request * | req, | |
| const char * | var, | |||
| const char * | value | |||
| ) | [static] |
Add header to SIP message.
Definition at line 10218 of file chan_sip.c.
References ast_log(), ast_str_append(), ast_str_strlen(), find_alias(), LOG_WARNING, and sip_cfg.
Referenced by __transmit_response(), add_cc_call_info_to_response(), add_digit(), add_diversion_header(), add_header_max_forwards(), add_required_respheader(), add_route(), add_rpid(), add_sdp(), add_supported_header(), add_text(), add_vidupdate(), append_date(), copy_all_header(), copy_header(), copy_via_headers(), finalize_content(), initreqprep(), reqprep(), respprep(), transmit_cc_notify(), transmit_info_with_aoc(), transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_register(), transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), transmit_response_with_allow(), transmit_response_with_auth(), transmit_response_with_minexpires(), transmit_response_with_minse(), transmit_response_with_retry_after(), transmit_response_with_sip_etag(), transmit_response_with_unsupported(), transmit_state_notify(), and update_connectedline().
10219 { 10220 if (req->headers == SIP_MAX_HEADERS) { 10221 ast_log(LOG_WARNING, "Out of SIP header space\n"); 10222 return -1; 10223 } 10224 10225 if (req->lines) { 10226 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 10227 return -1; 10228 } 10229 10230 if (sip_cfg.compactheaders) { 10231 var = find_alias(var, var); 10232 } 10233 10234 ast_str_append(&req->data, 0, "%s: %s\r\n", var, value); 10235 req->header[req->headers] = ast_str_strlen(req->data); 10236 10237 req->headers++; 10238 10239 return 0; 10240 }
| static int add_header_max_forwards | ( | struct sip_pvt * | dialog, | |
| struct sip_request * | req | |||
| ) | [static] |
Add 'Max-Forwards' header to SIP message.
Definition at line 10246 of file chan_sip.c.
References add_header().
Referenced by initreqprep(), reqprep(), and transmit_register().
10247 { 10248 char clen[10]; 10249 10250 snprintf(clen, sizeof(clen), "%d", dialog->maxforwards); 10251 10252 return add_header(req, "Max-Forwards", clen); 10253 }
| static void add_noncodec_to_sdp | ( | const struct sip_pvt * | p, | |
| int | format, | |||
| struct ast_str ** | m_buf, | |||
| struct ast_str ** | a_buf, | |||
| int | debug | |||
| ) | [static] |
Add RFC 2833 DTMF offer to SDP.
Definition at line 11523 of file chan_sip.c.
References ast_rtp_codecs_payload_code(), AST_RTP_DTMF, ast_rtp_instance_get_codecs(), ast_rtp_lookup_mime_subtype2(), ast_rtp_lookup_sample_rate2(), ast_str_append(), and ast_verbose.
Referenced by add_sdp().
11526 { 11527 int rtp_code; 11528 11529 if (debug) 11530 ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", (unsigned)format, ast_rtp_lookup_mime_subtype2(0, format, 0)); 11531 if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->rtp), 0, format)) == -1) 11532 return; 11533 11534 ast_str_append(m_buf, 0, " %d", rtp_code); 11535 ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%u\r\n", rtp_code, 11536 ast_rtp_lookup_mime_subtype2(0, format, 0), 11537 ast_rtp_lookup_sample_rate2(0, format)); 11538 if (format == AST_RTP_DTMF) /* Indicate we support DTMF and FLASH... */ 11539 ast_str_append(a_buf, 0, "a=fmtp:%d 0-16\r\n", rtp_code); 11540 }
| static void add_peer_mailboxes | ( | struct sip_peer * | peer, | |
| const char * | value | |||
| ) | [static] |
Definition at line 28042 of file chan_sip.c.
References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_strdupa, ast_strip(), ast_strlen_zero(), context, mailbox, mbox(), and S_OR.
Referenced by build_peer().
28043 { 28044 char *next, *mbox, *context; 28045 28046 next = ast_strdupa(value); 28047 28048 while ((mbox = context = strsep(&next, ","))) { 28049 struct sip_mailbox *mailbox; 28050 int duplicate = 0; 28051 /* remove leading/trailing whitespace from mailbox string */ 28052 mbox = ast_strip(mbox); 28053 strsep(&context, "@"); 28054 28055 if (ast_strlen_zero(mbox)) { 28056 continue; 28057 } 28058 28059 /* Check whether the mailbox is already in the list */ 28060 AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { 28061 if (!strcmp(mailbox->mailbox, mbox) && !strcmp(S_OR(mailbox->context, ""), S_OR(context, ""))) { 28062 duplicate = 1; 28063 break; 28064 } 28065 } 28066 if (duplicate) { 28067 continue; 28068 } 28069 28070 if (!(mailbox = ast_calloc(1, sizeof(*mailbox) + strlen(mbox) + strlen(S_OR(context, ""))))) { 28071 continue; 28072 } 28073 28074 if (!ast_strlen_zero(context)) { 28075 mailbox->context = mailbox->mailbox + strlen(mbox) + 1; 28076 strcpy(mailbox->context, context); /* SAFE */ 28077 } 28078 strcpy(mailbox->mailbox, mbox); /* SAFE */ 28079 28080 AST_LIST_INSERT_TAIL(&peer->mailboxes, mailbox, entry); 28081 } 28082 }
| static void add_peer_mwi_subs | ( | struct sip_peer * | peer | ) | [static] |
Definition at line 25293 of file chan_sip.c.
References AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, ast_event_subscribe(), ast_event_unsubscribe(), AST_LIST_TRAVERSE, mailbox, mwi_event_cb(), and S_OR.
Referenced by build_peer(), and handle_request_subscribe().
25294 { 25295 struct sip_mailbox *mailbox; 25296 25297 AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { 25298 if (mailbox->event_sub) { 25299 ast_event_unsubscribe(mailbox->event_sub); 25300 } 25301 25302 mailbox->event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "SIP mbox event", peer, 25303 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox->mailbox, 25304 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, S_OR(mailbox->context, "default"), 25305 AST_EVENT_IE_END); 25306 } 25307 }
| static void add_realm_authentication | ( | struct sip_auth_container ** | credentials, | |
| const char * | configuration, | |||
| int | lineno | |||
| ) | [static] |
Definition at line 27842 of file chan_sip.c.
References ao2_t_alloc, ast_calloc, ast_copy_string(), ast_debug, AST_LIST_INSERT_TAIL, ast_log(), ast_strdupa, ast_strlen_zero(), ast_verb, destroy_realm_authentication(), LOG_WARNING, and secret.
Referenced by build_peer(), and reload_config().
27843 { 27844 char *authcopy; 27845 char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; 27846 struct sip_auth *auth; 27847 27848 if (ast_strlen_zero(configuration)) { 27849 /* Nothing to add */ 27850 return; 27851 } 27852 27853 ast_debug(1, "Auth config :: %s\n", configuration); 27854 27855 authcopy = ast_strdupa(configuration); 27856 username = authcopy; 27857 27858 /* split user[:secret] and relm */ 27859 realm = strrchr(username, '@'); 27860 if (realm) 27861 *realm++ = '\0'; 27862 if (ast_strlen_zero(username) || ast_strlen_zero(realm)) { 27863 ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno); 27864 return; 27865 } 27866 27867 /* parse username at ':' for secret, or '#" for md5secret */ 27868 if ((secret = strchr(username, ':'))) { 27869 *secret++ = '\0'; 27870 } else if ((md5secret = strchr(username, '#'))) { 27871 *md5secret++ = '\0'; 27872 } 27873 27874 /* Create the continer if needed. */ 27875 if (!*credentials) { 27876 *credentials = ao2_t_alloc(sizeof(**credentials), destroy_realm_authentication, 27877 "Create realm auth container."); 27878 if (!*credentials) { 27879 /* Failed to create the credentials container. */ 27880 return; 27881 } 27882 } 27883 27884 /* Create the authentication credential entry. */ 27885 auth = ast_calloc(1, sizeof(*auth)); 27886 if (!auth) { 27887 return; 27888 } 27889 ast_copy_string(auth->realm, realm, sizeof(auth->realm)); 27890 ast_copy_string(auth->username, username, sizeof(auth->username)); 27891 if (secret) 27892 ast_copy_string(auth->secret, secret, sizeof(auth->secret)); 27893 if (md5secret) 27894 ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret)); 27895 27896 /* Add credential to container list. */ 27897 AST_LIST_INSERT_TAIL(&(*credentials)->list, auth, node); 27898 27899 ast_verb(3, "Added authentication for realm %s\n", realm); 27900 }
| static void add_required_respheader | ( | struct sip_request * | req | ) | [static] |
Definition at line 4347 of file chan_sip.c.
References add_header(), ARRAY_LEN, ast_free, ast_str_append(), ast_str_buffer(), ast_str_create(), ast_str_strlen(), str, and text.
Referenced by transmit_response_with_sdp().
04348 { 04349 struct ast_str *str; 04350 int i; 04351 04352 if (!req->reqsipoptions) { 04353 return; 04354 } 04355 04356 str = ast_str_create(32); 04357 04358 for (i = 0; i < ARRAY_LEN(sip_options); ++i) { 04359 if (!(req->reqsipoptions & sip_options[i].id)) { 04360 continue; 04361 } 04362 if (ast_str_strlen(str) > 0) { 04363 ast_str_append(&str, 0, ", "); 04364 } 04365 ast_str_append(&str, 0, "%s", sip_options[i].text); 04366 } 04367 04368 if (ast_str_strlen(str) > 0) { 04369 add_header(req, "Require", ast_str_buffer(str)); 04370 } 04371 04372 ast_free(str); 04373 }
| static void add_route | ( | struct sip_request * | req, | |
| struct sip_route * | route | |||
| ) | [static] |
Add route header into request per learned route.
Definition at line 10387 of file chan_sip.c.
References add_header(), and ast_copy_string().
Referenced by initreqprep(), and reqprep().
10388 { 10389 char r[SIPBUFSIZE*2], *p; 10390 int n, rem = sizeof(r); 10391 10392 if (!route) 10393 return; 10394 10395 p = r; 10396 for (;route ; route = route->next) { 10397 n = strlen(route->hop); 10398 if (rem < n+3) /* we need room for ",<route>" */ 10399 break; 10400 if (p != r) { /* add a separator after fist route */ 10401 *p++ = ','; 10402 --rem; 10403 } 10404 *p++ = '<'; 10405 ast_copy_string(p, route->hop, rem); /* cannot fail */ 10406 p += n; 10407 *p++ = '>'; 10408 rem -= (n+2); 10409 } 10410 *p = '\0'; 10411 add_header(req, "Route", r); 10412 }
| static int add_rpid | ( | struct sip_request * | req, | |
| struct sip_pvt * | p | |||
| ) | [static] |
Add Remote-Party-ID header to SIP message.
Definition at line 11250 of file chan_sip.c.
References add_header(), ast_escape_quoted(), ast_party_id_presentation(), AST_PRES_ALLOWED, AST_PRES_ALLOWED_NETWORK_NUMBER, AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, AST_PRES_PROHIB_NETWORK_NUMBER, AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, AST_PRES_RESTRICTION, ast_sockaddr_stringify_host_remote(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_set(), ast_strlen_zero(), ast_test_flag, ast_uri_encode(), and S_COR.
Referenced by __transmit_response(), transmit_invite(), transmit_reinvite_with_sdp(), transmit_response_with_sdp(), and update_connectedline().
11251 { 11252 struct ast_str *tmp = ast_str_alloca(256); 11253 char tmp2[256]; 11254 char lid_name_buf[128]; 11255 char *lid_num; 11256 char *lid_name; 11257 int lid_pres; 11258 const char *fromdomain; 11259 const char *privacy = NULL; 11260 const char *screen = NULL; 11261 const char *anonymous_string = "\"Anonymous\" <sip:anonymous@anonymous.invalid>"; 11262 11263 if (!ast_test_flag(&p->flags[0], SIP_SENDRPID)) { 11264 return 0; 11265 } 11266 11267 if (!p->owner) { 11268 return 0; 11269 } 11270 lid_num = S_COR(p->owner->connected.id.number.valid, 11271 p->owner->connected.id.number.str, 11272 NULL); 11273 if (!lid_num) { 11274 return 0; 11275 } 11276 lid_name = S_COR(p->owner->connected.id.name.valid, 11277 p->owner->connected.id.name.str, 11278 NULL); 11279 if (!lid_name) { 11280 lid_name = lid_num; 11281 } 11282 ast_escape_quoted(lid_name, lid_name_buf, sizeof(lid_name_buf)); 11283 lid_pres = ast_party_id_presentation(&p->owner->connected.id); 11284 11285 if (((lid_pres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) && 11286 (ast_test_flag(&p->flags[1], SIP_PAGE2_TRUST_ID_OUTBOUND) == SIP_PAGE2_TRUST_ID_OUTBOUND_NO)) { 11287 /* If pres is not allowed and we don't trust the peer, we don't apply an RPID header */ 11288 return 0; 11289 } 11290 11291 fromdomain = p->fromdomain; 11292 if (!fromdomain || 11293 ((ast_test_flag(&p->flags[1], SIP_PAGE2_TRUST_ID_OUTBOUND) == SIP_PAGE2_TRUST_ID_OUTBOUND_YES) && 11294 !strcmp("anonymous.invalid", fromdomain))) { 11295 /* If the fromdomain is NULL or if it was set to anonymous.invalid due to privacy settings and we trust the peer, 11296 * use the host IP address */ 11297 fromdomain = ast_sockaddr_stringify_host_remote(&p->ourip); 11298 } 11299 11300 lid_num = ast_uri_encode(lid_num, tmp2, sizeof(tmp2), 0); 11301 11302 if (ast_test_flag(&p->flags[0], SIP_SENDRPID_PAI)) { 11303 if (ast_test_flag(&p->flags[1], SIP_PAGE2_TRUST_ID_OUTBOUND) != SIP_PAGE2_TRUST_ID_OUTBOUND_LEGACY) { 11304 /* trust_id_outbound = yes - Always give full information even if it's private, but append a privacy header 11305 * When private data is included */ 11306 ast_str_set(&tmp, -1, "\"%s\" <sip:%s@%s>", lid_name_buf, lid_num, fromdomain); 11307 if ((lid_pres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) { 11308 add_header(req, "Privacy", "id"); 11309 } 11310 } else { 11311 /* trust_id_outbound = legacy - behave in a non RFC-3325 compliant manner and send anonymized data when 11312 * when handling private data. */ 11313 if ((lid_pres & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED) { 11314 ast_str_set(&tmp, -1, "\"%s\" <sip:%s@%s>", lid_name_buf, lid_num, fromdomain); 11315 } else { 11316 ast_str_set(&tmp, -1, "%s", anonymous_string); 11317 } 11318 } 11319 add_header(req, "P-Asserted-Identity", ast_str_buffer(tmp)); 11320 } else { 11321 ast_str_set(&tmp, -1, "\"%s\" <sip:%s@%s>;party=%s", lid_name_buf, lid_num, fromdomain, p->outgoing_call ? "calling" : "called"); 11322 11323 switch (lid_pres) { 11324 case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 11325 case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 11326 privacy = "off"; 11327 screen = "no"; 11328 break; 11329 case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 11330 case AST_PRES_ALLOWED_NETWORK_NUMBER: 11331 privacy = "off"; 11332 screen = "yes"; 11333 break; 11334 case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 11335 case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 11336 privacy = "full"; 11337 screen = "no"; 11338 break; 11339 case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 11340 case AST_PRES_PROHIB_NETWORK_NUMBER: 11341 privacy = "full"; 11342 screen = "yes"; 11343 break; 11344 case AST_PRES_NUMBER_NOT_AVAILABLE: 11345 break; 11346 default: 11347 if ((lid_pres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) { 11348 privacy = "full"; 11349 } 11350 else 11351 privacy = "off"; 11352 screen = "no"; 11353 break; 11354 } 11355 11356 if (!ast_strlen_zero(privacy) && !ast_strlen_zero(screen)) { 11357 ast_str_append(&tmp, -1, ";privacy=%s;screen=%s", privacy, screen); 11358 } 11359 11360 add_header(req, "Remote-Party-ID", ast_str_buffer(tmp)); 11361 } 11362 return 0; 11363 }
| static enum sip_result add_sdp | ( | struct sip_request * | resp, | |
| struct sip_pvt * | p, | |||
| int | oldsdp, | |||
| int | add_audio, | |||
| int | add_t38 | |||
| ) | [static] |
Add Session Description Protocol message.
If oldsdp is TRUE, then the SDP version number is not incremented. This mechanism is used in Session-Timers where RE-INVITEs are used for refreshing SIP sessions without modifying the media session in any way.
Definition at line 11661 of file chan_sip.c.
References add_codec_to_sdp(), add_content(), add_header(), add_noncodec_to_sdp(), add_tcodec_to_sdp(), add_vcodec_to_sdp(), ast_codec_pref_index(), ast_debug, AST_FORMAT_AUDIO_MASK, AST_FORMAT_TEXT_MASK, AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_log(), ast_random(), AST_RTP_MAX, ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_is_ipv4_mapped(), ast_sockaddr_is_ipv6(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_sockaddr_stringify_addr_remote(), ast_sockaddr_stringify_port(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_size(), ast_str_strlen(), ast_strlen_zero(), AST_T38_RATE_MANAGEMENT_LOCAL_TCF, AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF, ast_test_flag, ast_udptl_get_error_correction_scheme(), ast_udptl_get_local_max_datagram(), ast_udptl_get_us(), ast_verbose, capability, FALSE, get_crypto_attrib(), get_our_media_address(), LOG_WARNING, sip_debug_test_pvt(), t38_get_rate(), TRUE, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_REDUNDANCY, and version.
Referenced by transmit_invite(), transmit_reinvite_with_sdp(), transmit_response_with_sdp(), transmit_response_with_t38_sdp(), and update_connectedline().
11662 { 11663 format_t alreadysent = 0; 11664 int doing_directmedia = FALSE; 11665 11666 struct ast_sockaddr addr = { {0,} }; 11667 struct ast_sockaddr vaddr = { {0,} }; 11668 struct ast_sockaddr taddr = { {0,} }; 11669 struct ast_sockaddr udptladdr = { {0,} }; 11670 struct ast_sockaddr dest = { {0,} }; 11671 struct ast_sockaddr vdest = { {0,} }; 11672 struct ast_sockaddr tdest = { {0,} }; 11673 struct ast_sockaddr udptldest = { {0,} }; 11674 11675 /* SDP fields */ 11676 char *version = "v=0\r\n"; /* Protocol version */ 11677 char subject[256]; /* Subject of the session */ 11678 char owner[256]; /* Session owner/creator */ 11679 char connection[256]; /* Connection data */ 11680 char *session_time = "t=0 0\r\n"; /* Time the session is active */ 11681 char bandwidth[256] = ""; /* Max bitrate */ 11682 char *hold = ""; 11683 struct ast_str *m_audio = ast_str_alloca(256); /* Media declaration line for audio */ 11684 struct ast_str *m_video = ast_str_alloca(256); /* Media declaration line for video */ 11685 struct ast_str *m_text = ast_str_alloca(256); /* Media declaration line for text */ 11686 struct ast_str *m_modem = ast_str_alloca(256); /* Media declaration line for modem */ 11687 struct ast_str *a_audio = ast_str_alloca(1024); /* Attributes for audio */ 11688 struct ast_str *a_video = ast_str_alloca(1024); /* Attributes for video */ 11689 struct ast_str *a_text = ast_str_alloca(1024); /* Attributes for text */ 11690 struct ast_str *a_modem = ast_str_alloca(1024); /* Attributes for modem */ 11691 const char *a_crypto = NULL; 11692 const char *v_a_crypto = NULL; 11693 const char *t_a_crypto = NULL; 11694 11695 format_t x; 11696 format_t capability = 0; 11697 int needaudio = FALSE; 11698 int needvideo = FALSE; 11699 int needtext = FALSE; 11700 int debug = sip_debug_test_pvt(p); 11701 int min_audio_packet_size = 0; 11702 int min_video_packet_size = 0; 11703 int min_text_packet_size = 0; 11704 11705 char codecbuf[SIPBUFSIZE]; 11706 char buf[SIPBUFSIZE]; 11707 char dummy_answer[256]; 11708 11709 /* Set the SDP session name */ 11710 snprintf(subject, sizeof(subject), "s=%s\r\n", ast_strlen_zero(global_sdpsession) ? "-" : global_sdpsession); 11711 11712 if (!p->rtp) { 11713 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 11714 return AST_FAILURE; 11715 } 11716 /* XXX We should not change properties in the SIP dialog until 11717 we have acceptance of the offer if this is a re-invite */ 11718 11719 /* Set RTP Session ID and version */ 11720 if (!p->sessionid) { 11721 p->sessionid = (int)ast_random(); 11722 p->sessionversion = p->sessionid; 11723 } else { 11724 if (oldsdp == FALSE) 11725 p->sessionversion++; 11726 } 11727 11728 if (add_audio) { 11729 doing_directmedia = (!ast_sockaddr_isnull(&p->redirip) && p->redircodecs) ? TRUE : FALSE; 11730 /* Check if we need video in this call */ 11731 if ((p->jointcapability & AST_FORMAT_VIDEO_MASK) && !p->novideo) { 11732 if (doing_directmedia && !(p->jointcapability & AST_FORMAT_VIDEO_MASK & p->redircodecs)) { 11733 ast_debug(2, "This call needs video offers, but caller probably did not offer it!\n"); 11734 } else if (p->vrtp) { 11735 needvideo = TRUE; 11736 ast_debug(2, "This call needs video offers!\n"); 11737 } else { 11738 ast_debug(2, "This call needs video offers, but there's no video support enabled!\n"); 11739 } 11740 } 11741 /* Check if we need text in this call */ 11742 if ((p->jointcapability & AST_FORMAT_TEXT_MASK) && !p->notext) { 11743 if (sipdebug_text) 11744 ast_verbose("We think we can do text\n"); 11745 if (p->trtp) { 11746 if (sipdebug_text) { 11747 ast_verbose("And we have a text rtp object\n"); 11748 } 11749 needtext = TRUE; 11750 ast_debug(2, "This call needs text offers! \n"); 11751 } else { 11752 ast_debug(2, "This call needs text offers, but there's no text support enabled ! \n"); 11753 } 11754 } 11755 } 11756 11757 get_our_media_address(p, needvideo, needtext, &addr, &vaddr, &taddr, &dest, &vdest, &tdest); 11758 11759 snprintf(owner, sizeof(owner), "o=%s %d %d IN %s %s\r\n", 11760 ast_strlen_zero(global_sdpowner) ? "-" : global_sdpowner, 11761 p->sessionid, p->sessionversion, 11762 (ast_sockaddr_is_ipv6(&dest) && !ast_sockaddr_is_ipv4_mapped(&dest)) ? 11763 "IP6" : "IP4", 11764 ast_sockaddr_stringify_addr_remote(&dest)); 11765 11766 snprintf(connection, sizeof(connection), "c=IN %s %s\r\n", 11767 (ast_sockaddr_is_ipv6(&dest) && !ast_sockaddr_is_ipv4_mapped(&dest)) ? 11768 "IP6" : "IP4", 11769 ast_sockaddr_stringify_addr_remote(&dest)); 11770 11771 if (add_audio) { 11772 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR) { 11773 hold = "a=recvonly\r\n"; 11774 doing_directmedia = FALSE; 11775 } else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE) { 11776 hold = "a=inactive\r\n"; 11777 doing_directmedia = FALSE; 11778 } else { 11779 hold = "a=sendrecv\r\n"; 11780 } 11781 11782 capability = p->jointcapability; 11783 11784 /* XXX note, Video and Text are negated - 'true' means 'no' */ 11785 ast_debug(1, "** Our capability: %s Video flag: %s Text flag: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), capability), 11786 p->novideo ? "True" : "False", p->notext ? "True" : "False"); 11787 ast_debug(1, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec)); 11788 11789 if (doing_directmedia) { 11790 capability &= p->redircodecs; 11791 ast_debug(1, "** Our native-bridge filtered capablity: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), capability)); 11792 } 11793 11794 /* Check if we need audio */ 11795 if (capability & AST_FORMAT_AUDIO_MASK) 11796 needaudio = TRUE; 11797 11798 if (debug) { 11799 ast_verbose("Audio is at %s\n", ast_sockaddr_stringify_port(&addr)); 11800 } 11801 11802 /* Ok, we need video. Let's add what we need for video and set codecs. 11803 Video is handled differently than audio since we can not transcode. */ 11804 if (needvideo) { 11805 get_crypto_attrib(p->vsrtp, &v_a_crypto); 11806 ast_str_append(&m_video, 0, "m=video %d RTP/%s", ast_sockaddr_port(&vdest), 11807 v_a_crypto ? "SAVP" : "AVP"); 11808 11809 /* Build max bitrate string */ 11810 if (p->maxcallbitrate) 11811 snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate); 11812 if (debug) { 11813 ast_verbose("Video is at %s\n", ast_sockaddr_stringify(&vdest)); 11814 } 11815 } 11816 11817 /* Ok, we need text. Let's add what we need for text and set codecs. 11818 Text is handled differently than audio since we can not transcode. */ 11819 if (needtext) { 11820 if (sipdebug_text) 11821 ast_verbose("Lets set up the text sdp\n"); 11822 get_crypto_attrib(p->tsrtp, &t_a_crypto); 11823 ast_str_append(&m_text, 0, "m=text %d RTP/%s", ast_sockaddr_port(&tdest), 11824 t_a_crypto ? "SAVP" : "AVP"); 11825 if (debug) { /* XXX should I use tdest below ? */ 11826 ast_verbose("Text is at %s\n", ast_sockaddr_stringify(&taddr)); 11827 } 11828 } 11829 11830 /* Start building generic SDP headers */ 11831 11832 /* We break with the "recommendation" and send our IP, in order that our 11833 peer doesn't have to ast_gethostbyname() us */ 11834 11835 get_crypto_attrib(p->srtp, &a_crypto); 11836 ast_str_append(&m_audio, 0, "m=audio %d RTP/%s", ast_sockaddr_port(&dest), 11837 a_crypto ? "SAVP" : "AVP"); 11838 11839 /* Now, start adding audio codecs. These are added in this order: 11840 - First what was requested by the calling channel 11841 - Then preferences in order from sip.conf device config for this peer/user 11842 - Then other codecs in capabilities, including video 11843 */ 11844 11845 /* Prefer the audio codec we were requested to use, first, no matter what 11846 Note that p->prefcodec can include video codecs, so mask them out 11847 */ 11848 if ((capability & p->prefcodec) & AST_FORMAT_AUDIO_MASK) { 11849 format_t codec = p->prefcodec & AST_FORMAT_AUDIO_MASK; 11850 11851 add_codec_to_sdp(p, codec, &m_audio, &a_audio, debug, &min_audio_packet_size); 11852 alreadysent |= codec; 11853 } 11854 11855 /* Start by sending our preferred audio/video codecs */ 11856 for (x = 0; x < 64; x++) { 11857 format_t codec; 11858 11859 if (!(codec = ast_codec_pref_index(&p->prefs, x))) 11860 break; 11861 11862 if (!(capability & codec)) 11863 continue; 11864 11865 if (alreadysent & codec) 11866 continue; 11867 11868 add_codec_to_sdp(p, codec, &m_audio, &a_audio, debug, &min_audio_packet_size); 11869 alreadysent |= codec; 11870 } 11871 11872 /* Now send any other common audio and video codecs, and non-codec formats: */ 11873 for (x = 1ULL; x <= (needtext ? AST_FORMAT_TEXT_MASK : (needvideo ? AST_FORMAT_VIDEO_MASK : AST_FORMAT_AUDIO_MASK)); x <<= 1) { 11874 if (!(capability & x)) /* Codec not requested */ 11875 continue; 11876 11877 if (alreadysent & x) /* Already added to SDP */ 11878 continue; 11879 11880 if (x & AST_FORMAT_AUDIO_MASK) 11881 add_codec_to_sdp(p, x, &m_audio, &a_audio, debug, &min_audio_packet_size); 11882 else if (x & AST_FORMAT_VIDEO_MASK) 11883 add_vcodec_to_sdp(p, x, &m_video, &a_video, debug, &min_video_packet_size); 11884 else if (x & AST_FORMAT_TEXT_MASK) 11885 add_tcodec_to_sdp(p, x, &m_text, &a_text, debug, &min_text_packet_size); 11886 } 11887 11888 /* Now add DTMF RFC2833 telephony-event as a codec */ 11889 for (x = 1LL; x <= AST_RTP_MAX; x <<= 1) { 11890 if (!(p->jointnoncodeccapability & x)) 11891 continue; 11892 11893 add_noncodec_to_sdp(p, x, &m_audio, &a_audio, debug); 11894 } 11895 11896 ast_debug(3, "-- Done with adding codecs to SDP\n"); 11897 11898 if (!p->owner || p->owner->timingfd == -1) { 11899 ast_str_append(&a_audio, 0, "a=silenceSupp:off - - - -\r\n"); 11900 } 11901 11902 if (min_audio_packet_size) 11903 ast_str_append(&a_audio, 0, "a=ptime:%d\r\n", min_audio_packet_size); 11904 11905 /* XXX don't think you can have ptime for video */ 11906 if (min_video_packet_size) 11907 ast_str_append(&a_video, 0, "a=ptime:%d\r\n", min_video_packet_size); 11908 11909 /* XXX don't think you can have ptime for text */ 11910 if (min_text_packet_size) 11911 ast_str_append(&a_text, 0, "a=ptime:%d\r\n", min_text_packet_size); 11912 11913 if (ast_str_size(m_audio) - ast_str_strlen(m_audio) < 2 || ast_str_size(m_video) - ast_str_strlen(m_video) < 2 || 11914 ast_str_size(m_text) - ast_str_strlen(m_text) < 2 || ast_str_size(a_text) - ast_str_strlen(a_text) < 2 || 11915 ast_str_size(a_audio) - ast_str_strlen(a_audio) < 2 || ast_str_size(a_video) - ast_str_strlen(a_video) < 2) 11916 ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n"); 11917 } 11918 11919 if (add_t38) { 11920 /* Our T.38 end is */ 11921 ast_udptl_get_us(p->udptl, &udptladdr); 11922 11923 /* We don't use directmedia for T.38, so keep the destination the same as our IP address. */ 11924 ast_sockaddr_copy(&udptldest, &p->ourip); 11925 ast_sockaddr_set_port(&udptldest, ast_sockaddr_port(&udptladdr)); 11926 11927 if (debug) { 11928 ast_debug(1, "T.38 UDPTL is at %s port %d\n", ast_sockaddr_stringify_addr(&p->ourip), ast_sockaddr_port(&udptladdr)); 11929 } 11930 11931 /* We break with the "recommendation" and send our IP, in order that our 11932 peer doesn't have to ast_gethostbyname() us */ 11933 11934 ast_str_append(&m_modem, 0, "m=image %d udptl t38\r\n", ast_sockaddr_port(&udptldest)); 11935 11936 if (ast_sockaddr_cmp(&udptldest, &dest)) { 11937 ast_str_append(&m_modem, 0, "c=IN %s %s\r\n", 11938 (ast_sockaddr_is_ipv6(&udptldest) && !ast_sockaddr_is_ipv4_mapped(&udptldest)) ? 11939 "IP6" : "IP4", ast_sockaddr_stringify_addr_remote(&udptldest)); 11940 } 11941 11942 ast_str_append(&a_modem, 0, "a=T38FaxVersion:%u\r\n", p->t38.our_parms.version); 11943 ast_str_append(&a_modem, 0, "a=T38MaxBitRate:%u\r\n", t38_get_rate(p->t38.our_parms.rate)); 11944 if (p->t38.our_parms.fill_bit_removal) { 11945 ast_str_append(&a_modem, 0, "a=T38FaxFillBitRemoval\r\n"); 11946 } 11947 if (p->t38.our_parms.transcoding_mmr) { 11948 ast_str_append(&a_modem, 0, "a=T38FaxTranscodingMMR\r\n"); 11949 } 11950 if (p->t38.our_parms.transcoding_jbig) { 11951 ast_str_append(&a_modem, 0, "a=T38FaxTranscodingJBIG\r\n"); 11952 } 11953 switch (p->t38.our_parms.rate_management) { 11954 case AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF: 11955 ast_str_append(&a_modem, 0, "a=T38FaxRateManagement:transferredTCF\r\n"); 11956 break; 11957 case AST_T38_RATE_MANAGEMENT_LOCAL_TCF: 11958 ast_str_append(&a_modem, 0, "a=T38FaxRateManagement:localTCF\r\n"); 11959 break; 11960 } 11961 ast_str_append(&a_modem, 0, "a=T38FaxMaxDatagram:%u\r\n", ast_udptl_get_local_max_datagram(p->udptl)); 11962 switch (ast_udptl_get_error_correction_scheme(p->udptl)) { 11963 case UDPTL_ERROR_CORRECTION_NONE: 11964 break; 11965 case UDPTL_ERROR_CORRECTION_FEC: 11966 ast_str_append(&a_modem, 0, "a=T38FaxUdpEC:t38UDPFEC\r\n"); 11967 break; 11968 case UDPTL_ERROR_CORRECTION_REDUNDANCY: 11969 ast_str_append(&a_modem, 0, "a=T38FaxUdpEC:t38UDPRedundancy\r\n"); 11970 break; 11971 } 11972 } 11973 11974 if (needaudio) 11975 ast_str_append(&m_audio, 0, "\r\n"); 11976 if (needvideo) 11977 ast_str_append(&m_video, 0, "\r\n"); 11978 if (needtext) 11979 ast_str_append(&m_text, 0, "\r\n"); 11980 11981 add_header(resp, "Content-Type", "application/sdp"); 11982 add_content(resp, version); 11983 add_content(resp, owner); 11984 add_content(resp, subject); 11985 add_content(resp, connection); 11986 /* only if video response is appropriate */ 11987 if (needvideo) { 11988 add_content(resp, bandwidth); 11989 } 11990 add_content(resp, session_time); 11991 /* if this is a response to an invite, order our offers properly */ 11992 if (p->offered_media[SDP_AUDIO].order_offered || 11993 p->offered_media[SDP_VIDEO].order_offered || 11994 p->offered_media[SDP_TEXT].order_offered || 11995 p->offered_media[SDP_IMAGE].order_offered) { 11996 int i; 11997 /* we have up to 3 streams as limited by process_sdp */ 11998 for (i = 1; i <= 3; i++) { 11999 if (p->offered_media[SDP_AUDIO].order_offered == i) { 12000 if (needaudio) { 12001 add_content(resp, ast_str_buffer(m_audio)); 12002 add_content(resp, ast_str_buffer(a_audio)); 12003 add_content(resp, hold); 12004 if (a_crypto) { 12005 add_content(resp, a_crypto); 12006 } 12007 } else { 12008 snprintf(dummy_answer, sizeof(dummy_answer), "m=audio 0 RTP/AVP %s\r\n", p->offered_media[SDP_AUDIO].codecs); 12009 add_content(resp, dummy_answer); 12010 } 12011 } else if (p->offered_media[SDP_VIDEO].order_offered == i) { 12012 if (needvideo) { /* only if video response is appropriate */ 12013 add_content(resp, ast_str_buffer(m_video)); 12014 add_content(resp, ast_str_buffer(a_video)); 12015 add_content(resp, hold); /* Repeat hold for the video stream */ 12016 if (v_a_crypto) { 12017 add_content(resp, v_a_crypto); 12018 } 12019 } else { 12020 snprintf(dummy_answer, sizeof(dummy_answer), "m=video 0 RTP/AVP %s\r\n", p->offered_media[SDP_VIDEO].codecs); 12021 add_content(resp, dummy_answer); 12022 } 12023 } else if (p->offered_media[SDP_TEXT].order_offered == i) { 12024 if (needtext) { /* only if text response is appropriate */ 12025 add_content(resp, ast_str_buffer(m_text)); 12026 add_content(resp, ast_str_buffer(a_text)); 12027 add_content(resp, hold); /* Repeat hold for the text stream */ 12028 if (t_a_crypto) { 12029 add_content(resp, t_a_crypto); 12030 } 12031 } else { 12032 snprintf(dummy_answer, sizeof(dummy_answer), "m=text 0 RTP/AVP %s\r\n", p->offered_media[SDP_TEXT].codecs); 12033 add_content(resp, dummy_answer); 12034 } 12035 } else if (p->offered_media[SDP_IMAGE].order_offered == i) { 12036 if (add_t38) { 12037 add_content(resp, ast_str_buffer(m_modem)); 12038 add_content(resp, ast_str_buffer(a_modem)); 12039 } else { 12040 add_content(resp, "m=image 0 udptl t38\r\n"); 12041 } 12042 } 12043 } 12044 } else { 12045 /* generate new SDP from scratch, no offers */ 12046 if (needaudio) { 12047 add_content(resp, ast_str_buffer(m_audio)); 12048 add_content(resp, ast_str_buffer(a_audio)); 12049 add_content(resp, hold); 12050 if (a_crypto) { 12051 add_content(resp, a_crypto); 12052 } 12053 } 12054 if (needvideo) { /* only if video response is appropriate */ 12055 add_content(resp, ast_str_buffer(m_video)); 12056 add_content(resp, ast_str_buffer(a_video)); 12057 add_content(resp, hold); /* Repeat hold for the video stream */ 12058 if (v_a_crypto) { 12059 add_content(resp, v_a_crypto); 12060 } 12061 } 12062 if (needtext) { /* only if text response is appropriate */ 12063 add_content(resp, ast_str_buffer(m_text)); 12064 add_content(resp, ast_str_buffer(a_text)); 12065 add_content(resp, hold); /* Repeat hold for the text stream */ 12066 if (t_a_crypto) { 12067 add_content(resp, t_a_crypto); 12068 } 12069 } 12070 if (add_t38) { 12071 add_content(resp, ast_str_buffer(m_modem)); 12072 add_content(resp, ast_str_buffer(a_modem)); 12073 } 12074 } 12075 12076 /* Update lastrtprx when we send our SDP */ 12077 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 12078 12079 ast_debug(3, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, capability)); 12080 12081 return AST_SUCCESS; 12082 }
| static int add_sip_domain | ( | const char * | domain, | |
| const enum domain_mode | mode, | |||
| const char * | context | |||
| ) | [static] |
Add SIP domain to list of domains we are responsible for.
Definition at line 27751 of file chan_sip.c.
References ast_calloc, ast_copy_string(), ast_debug, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strlen_zero(), and LOG_WARNING.
Referenced by reload_config().
27752 { 27753 struct domain *d; 27754 27755 if (ast_strlen_zero(domain)) { 27756 ast_log(LOG_WARNING, "Zero length domain.\n"); 27757 return 1; 27758 } 27759 27760 if (!(d = ast_calloc(1, sizeof(*d)))) 27761 return 0; 27762 27763 ast_copy_string(d->domain, domain, sizeof(d->domain)); 27764 27765 if (!ast_strlen_zero(context)) 27766 ast_copy_string(d->context, context, sizeof(d->context)); 27767 27768 d->mode = mode; 27769 27770 AST_LIST_LOCK(&domain_list); 27771 AST_LIST_INSERT_TAIL(&domain_list, d, list); 27772 AST_LIST_UNLOCK(&domain_list); 27773 27774 if (sipdebug) 27775 ast_debug(1, "Added local SIP domain '%s'\n", domain); 27776 27777 return 1; 27778 }
| static int add_supported_header | ( | struct sip_pvt * | pvt, | |
| struct sip_request * | req | |||
| ) | [static] |
Add "Supported" header to sip message. Since some options may be disabled in the config, the sip_pvt must be inspected to determine what is supported for this dialog.
Definition at line 10206 of file chan_sip.c.
References add_header(), and st_get_mode().
Referenced by respprep(), transmit_invite(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_reinvite_with_sdp(), and update_connectedline().
10207 { 10208 int res; 10209 if (st_get_mode(pvt, 0) != SESSION_TIMER_MODE_REFUSE) { 10210 res = add_header(req, "Supported", "replaces, timer"); 10211 } else { 10212 res = add_header(req, "Supported", "replaces"); 10213 } 10214 return res; 10215 }
| static void add_tcodec_to_sdp | ( | const struct sip_pvt * | p, | |
| int | codec, | |||
| struct ast_str ** | m_buf, | |||
| struct ast_str ** | a_buf, | |||
| int | debug, | |||
| int * | min_packet_size | |||
| ) | [static] |
Add text codec offer to SDP offer/answer body in INVITE or 200 OK.
Definition at line 11469 of file chan_sip.c.
References AST_FORMAT_T140, AST_FORMAT_T140RED, ast_getformatname(), ast_rtp_codecs_payload_code(), ast_rtp_instance_get_codecs(), ast_rtp_lookup_mime_subtype2(), ast_rtp_lookup_sample_rate2(), ast_str_append(), and ast_verbose.
Referenced by add_sdp().
11472 { 11473 int rtp_code; 11474 11475 if (!p->trtp) 11476 return; 11477 11478 if (debug) 11479 ast_verbose("Adding text codec 0x%x (%s) to SDP\n", (unsigned)codec, ast_getformatname(codec)); 11480 11481 if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->trtp), 1, codec)) == -1) 11482 return; 11483 11484 ast_str_append(m_buf, 0, " %d", rtp_code); 11485 ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%u\r\n", rtp_code, 11486 ast_rtp_lookup_mime_subtype2(1, codec, 0), 11487 ast_rtp_lookup_sample_rate2(1, codec)); 11488 /* Add fmtp code here */ 11489 11490 if (codec == AST_FORMAT_T140RED) { 11491 int t140code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->trtp), 1, AST_FORMAT_T140); 11492 ast_str_append(a_buf, 0, "a=fmtp:%d %d/%d/%d\r\n", rtp_code, 11493 t140code, 11494 t140code, 11495 t140code); 11496 11497 } 11498 }
| static int add_text | ( | struct sip_request * | req, | |
| const char * | text | |||
| ) | [static] |
Add text body to SIP message.
Definition at line 11202 of file chan_sip.c.
References add_content(), and add_header().
Referenced by transmit_message_with_text().
11203 { 11204 /* XXX Convert \n's to \r\n's XXX */ 11205 add_header(req, "Content-Type", "text/plain;charset=UTF-8"); 11206 add_content(req, text); 11207 return 0; 11208 }
| static struct ast_variable* add_var | ( | const char * | buf, | |
| struct ast_variable * | list | |||
| ) | [static, read] |
implement the setvar config line
Definition at line 27931 of file chan_sip.c.
References ast_strdupa, ast_variable_new(), and ast_variable::next.
Referenced by build_peer().
27932 { 27933 struct ast_variable *tmpvar = NULL; 27934 char *varname = ast_strdupa(buf), *varval = NULL; 27935 27936 if ((varval = strchr(varname, '='))) { 27937 *varval++ = '\0'; 27938 if ((tmpvar = ast_variable_new(varname, varval, ""))) { 27939 tmpvar->next = list; 27940 list = tmpvar; 27941 } 27942 } 27943 return list; 27944 }
| static void add_vcodec_to_sdp | ( | const struct sip_pvt * | p, | |
| format_t | codec, | |||
| struct ast_str ** | m_buf, | |||
| struct ast_str ** | a_buf, | |||
| int | debug, | |||
| int * | min_packet_size | |||
| ) | [static] |
Add video codec offer to SDP offer/answer body in INVITE or 200 OK.
Definition at line 11446 of file chan_sip.c.
References ast_getformatname(), ast_rtp_codecs_payload_code(), ast_rtp_instance_get_codecs(), ast_rtp_lookup_mime_subtype2(), ast_rtp_lookup_sample_rate2(), ast_str_append(), and ast_verbose.
Referenced by add_sdp().
11449 { 11450 int rtp_code; 11451 11452 if (!p->vrtp) 11453 return; 11454 11455 if (debug) 11456 ast_verbose("Adding video codec 0x%" PRIx64 " (%s) to SDP\n", (uint64_t)codec, ast_getformatname(codec)); 11457 11458 if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->vrtp), 1, codec)) == -1) 11459 return; 11460 11461 ast_str_append(m_buf, 0, " %d", rtp_code); 11462 ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%u\r\n", rtp_code, 11463 ast_rtp_lookup_mime_subtype2(1, codec, 0), 11464 ast_rtp_lookup_sample_rate2(1, codec)); 11465 /* Add fmtp code here */ 11466 }
| static int add_vidupdate | ( | struct sip_request * | req | ) | [static] |
add XML encoded media control with update
Definition at line 11367 of file chan_sip.c.
References add_content(), and add_header().
Referenced by transmit_info_with_vidupdate().
11368 { 11369 const char *xml_is_a_huge_waste_of_space = 11370 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" 11371 " <media_control>\r\n" 11372 " <vc_primitive>\r\n" 11373 " <to_encoder>\r\n" 11374 " <picture_fast_update>\r\n" 11375 " </picture_fast_update>\r\n" 11376 " </to_encoder>\r\n" 11377 " </vc_primitive>\r\n" 11378 " </media_control>\r\n"; 11379 add_header(req, "Content-Type", "application/media_control+xml"); 11380 add_content(req, xml_is_a_huge_waste_of_space); 11381 return 0; 11382 }
| static int addr_is_multicast | ( | const struct ast_sockaddr * | addr | ) | [static] |
Check if an ip is an multicast IP. addr the address to check.
This function checks if an address is in the 224.0.0.0/4 network block.
Definition at line 8108 of file chan_sip.c.
References ast_sockaddr_ipv4().
Referenced by process_via().
08109 { 08110 return ((ast_sockaddr_ipv4(addr) & 0xf0000000) == 0xe0000000); 08111 }
| static const char * allowoverlap2str | ( | int | mode | ) | [static] |
Convert AllowOverlap setting to printable string.
Definition at line 17603 of file chan_sip.c.
References map_x_s().
Referenced by _sip_show_peer(), and sip_show_settings().
17604 { 17605 return map_x_s(allowoverlapstr, mode, "<error>"); 17606 }
| static void append_date | ( | struct sip_request * | req | ) | [static] |
Append date to SIP message.
Definition at line 11025 of file chan_sip.c.
References add_header().
Referenced by transmit_invite(), transmit_response_with_date(), transmit_response_with_minse(), and transmit_response_with_unsupported().
11026 { 11027 char tmpdat[256]; 11028 struct tm tm; 11029 time_t t = time(NULL); 11030 11031 gmtime_r(&t, &tm); 11032 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm); 11033 add_header(req, "Date", tmpdat); 11034 }
| static void append_history_full | ( | struct sip_pvt * | p, | |
| const char * | fmt, | |||
| ... | ||||
| ) | [static] |
Append to SIP dialog history with arg list.
Definition at line 3710 of file chan_sip.c.
References append_history_va().
03711 { 03712 va_list ap; 03713 03714 if (!p) { 03715 return; 03716 } 03717 03718 if (!p->do_history && !recordhistory && !dumphistory) { 03719 return; 03720 } 03721 03722 va_start(ap, fmt); 03723 append_history_va(p, fmt, ap); 03724 va_end(ap); 03725 03726 return; 03727 }
| static void append_history_va | ( | struct sip_pvt * | p, | |
| const char * | fmt, | |||
| va_list | ap | |||
| ) | [static] |
Append to SIP dialog history with arg list.
Definition at line 3682 of file chan_sip.c.
References ast_calloc, ast_free, AST_LIST_INSERT_TAIL, and AST_LIST_REMOVE_HEAD.
Referenced by append_history_full().
03683 { 03684 char buf[80], *c = buf; /* max history length */ 03685 struct sip_history *hist; 03686 int l; 03687 03688 vsnprintf(buf, sizeof(buf), fmt, ap); 03689 strsep(&c, "\r\n"); /* Trim up everything after \r or \n */ 03690 l = strlen(buf) + 1; 03691 if (!(hist = ast_calloc(1, sizeof(*hist) + l))) { 03692 return; 03693 } 03694 if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) { 03695 ast_free(hist); 03696 return; 03697 } 03698 memcpy(hist->event, buf, l); 03699 if (p->history_entries == MAX_HISTORY_ENTRIES) { 03700 struct sip_history *oldest; 03701 oldest = AST_LIST_REMOVE_HEAD(p->history, list); 03702 p->history_entries--; 03703 ast_free(oldest); 03704 } 03705 AST_LIST_INSERT_TAIL(p->history, hist, list); 03706 p->history_entries++; 03707 }
| static int apply_directmedia_ha | ( | struct sip_pvt * | p1, | |
| struct sip_pvt * | p2, | |||
| const char * | op | |||
| ) | [static] |
Definition at line 29869 of file chan_sip.c.
References ast_apply_ha(), ast_debug, ast_rtp_instance_get_local_address(), ast_rtp_instance_get_remote_address(), AST_SENSE_ALLOW, AST_SENSE_DENY, ast_sockaddr_stringify(), and ast_strdupa.
Referenced by sip_get_rtp_peer(), sip_get_trtp_peer(), sip_get_udptl_peer(), and sip_get_vrtp_peer().
29870 { 29871 struct ast_sockaddr us = { { 0, }, }, them = { { 0, }, }; 29872 int res = AST_SENSE_ALLOW; 29873 29874 ast_rtp_instance_get_remote_address(p1->rtp, &them); 29875 ast_rtp_instance_get_local_address(p1->rtp, &us); 29876 29877 /* If p2 is a guest call, there will be no peer. If there is no peer, there 29878 * is no directmediaha, so go ahead and allow it */ 29879 if (!p2->relatedpeer) { 29880 return res; 29881 } 29882 29883 if ((res = ast_apply_ha(p2->relatedpeer->directmediaha, &them)) == AST_SENSE_DENY) { 29884 const char *us_addr = ast_strdupa(ast_sockaddr_stringify(&us)); 29885 const char *them_addr = ast_strdupa(ast_sockaddr_stringify(&them)); 29886 29887 ast_debug(3, "Reinvite %s to %s denied by directmedia ACL on %s\n", 29888 op, them_addr, us_addr); 29889 } 29890 29891 return res; 29892 }
| AST_DATA_STRUCTURE | ( | sip_peer | , | |
| DATA_EXPORT_SIP_PEER | ||||
| ) |
| AST_LIST_HEAD_NOLOCK | ( | sip_history_head | , | |
| sip_history | ||||
| ) |
history list, entry in sip_pvt
| AST_LIST_HEAD_STATIC | ( | epa_static_data_list | , | |
| epa_backend | ||||
| ) |
| static AST_LIST_HEAD_STATIC | ( | domain_list | , | |
| domain | ||||
| ) | [static] |
The SIP domain list
| AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
| AST_MODFLAG_LOAD_ORDER | , | |||
| "Session Initiation Protocol (SIP)" | , | |||
| . | load = load_module, |
|||
| . | unload = unload_module, |
|||
| . | reload = reload, |
|||
| . | load_pri = AST_MODPRI_CHANNEL_DRIVER, |
|||
| . | nonoptreq = "res_crypto,chan_local" | |||
| ) |
| AST_MUTEX_DEFINE_STATIC | ( | authl_lock | ) |
Global authentication container protection while adjusting the references.
| AST_MUTEX_DEFINE_STATIC | ( | sip_reload_lock | ) |
| AST_MUTEX_DEFINE_STATIC | ( | monlock | ) |
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.
| AST_MUTEX_DEFINE_STATIC | ( | netlock | ) |
| static void ast_quiet_chan | ( | struct ast_channel * | chan | ) | [static] |
Turn off generator data XXX Does this function belong in the SIP channel?
Definition at line 22352 of file chan_sip.c.
References ast_channel::_state, ast_deactivate_generator(), AST_FLAG_MOH, ast_moh_stop(), AST_STATE_UP, ast_test_flag, and ast_channel::generatordata.
Referenced by attempt_transfer(), and handle_invite_replaces().
22353 { 22354 if (chan && chan->_state == AST_STATE_UP) { 22355 if (ast_test_flag(chan, AST_FLAG_MOH)) 22356 ast_moh_stop(chan); 22357 else if (chan->generatordata) 22358 ast_deactivate_generator(chan); 22359 } 22360 }
| static void ast_sip_ouraddrfor | ( | const struct ast_sockaddr * | them, | |
| struct ast_sockaddr * | us, | |||
| struct sip_pvt * | p | |||
| ) | [static] |
NAT fix - decide which IP address to use for Asterisk server?
Using the localaddr structure built up with localnet statements in sip.conf apply it to their address to see if we need to substitute our externaddr or can get away with our internal bindaddr 'us' is always overwritten.
Definition at line 3578 of file chan_sip.c.
References ast_apply_ha(), ast_debug, ast_log(), ast_ouraddrfor(), AST_SENSE_ALLOW, ast_sockaddr_copy(), ast_sockaddr_is_any(), ast_sockaddr_is_ipv6(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_resolve_first(), ast_sockaddr_set_port, ast_sockaddr_stringify(), bindaddr, externaddr, get_transport(), internip, ast_tcptls_session_args::local_address, LOG_NOTICE, LOG_WARNING, and sip_cfg.
Referenced by __sip_subscribe_mwi_do(), sip_alloc(), sip_cc_monitor_request_cc(), sip_cli_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_publish(), transmit_register(), and transmit_response_using_temp().
03579 { 03580 struct ast_sockaddr theirs; 03581 03582 /* Set want_remap to non-zero if we want to remap 'us' to an externally 03583 * reachable IP address and port. This is done if: 03584 * 1. we have a localaddr list (containing 'internal' addresses marked 03585 * as 'deny', so ast_apply_ha() will return AST_SENSE_DENY on them, 03586 * and AST_SENSE_ALLOW on 'external' ones); 03587 * 2. externaddr is set, so we know what to use as the 03588 * externally visible address; 03589 * 3. the remote address, 'them', is external; 03590 * 4. the address returned by ast_ouraddrfor() is 'internal' (AST_SENSE_DENY 03591 * when passed to ast_apply_ha() so it does need to be remapped. 03592 * This fourth condition is checked later. 03593 */ 03594 int want_remap = 0; 03595 03596 ast_sockaddr_copy(us, &internip); /* starting guess for the internal address */ 03597 /* now ask the system what would it use to talk to 'them' */ 03598 ast_ouraddrfor(them, us); 03599 ast_sockaddr_copy(&theirs, them); 03600 03601 if (ast_sockaddr_is_ipv6(&theirs)) { 03602 if (localaddr && !ast_sockaddr_isnull(&externaddr) && !ast_sockaddr_is_any(&bindaddr)) { 03603 ast_log(LOG_WARNING, "Address remapping activated in sip.conf " 03604 "but we're using IPv6, which doesn't need it. Please " 03605 "remove \"localnet\" and/or \"externaddr\" settings.\n"); 03606 } 03607 } else { 03608 want_remap = localaddr && 03609 !ast_sockaddr_isnull(&externaddr) && 03610 ast_apply_ha(localaddr, &theirs) == AST_SENSE_ALLOW ; 03611 } 03612 03613 if (want_remap && 03614 (!sip_cfg.matchexternaddrlocally || !ast_apply_ha(localaddr, us)) ) { 03615 /* if we used externhost, see if it is time to refresh the info */ 03616 if (externexpire && time(NULL) >= externexpire) { 03617 if (ast_sockaddr_resolve_first(&externaddr, externhost, 0)) { 03618 ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost); 03619 } 03620 externexpire = time(NULL) + externrefresh; 03621 } 03622 if (!ast_sockaddr_isnull(&externaddr)) { 03623 ast_sockaddr_copy(us, &externaddr); 03624 switch (p->socket.type) { 03625 case SIP_TRANSPORT_TCP: 03626 if (!externtcpport && ast_sockaddr_port(&externaddr)) { 03627 /* for consistency, default to the externaddr port */ 03628 externtcpport = ast_sockaddr_port(&externaddr); 03629 } 03630 ast_sockaddr_set_port(us, externtcpport); 03631 break; 03632 case SIP_TRANSPORT_TLS: 03633 ast_sockaddr_set_port(us, externtlsport); 03634 break; 03635 case SIP_TRANSPORT_UDP: 03636 if (!ast_sockaddr_port(&externaddr)) { 03637 ast_sockaddr_set_port(us, ast_sockaddr_port(&bindaddr)); 03638 } 03639 break; 03640 default: 03641 break; 03642 } 03643 } 03644 ast_debug(1, "Target address %s is not local, substituting externaddr\n", 03645 ast_sockaddr_stringify(them)); 03646 } else { 03647 /* no remapping, but we bind to a specific address, so use it. */ 03648 switch (p->socket.type) { 03649 case SIP_TRANSPORT_TCP: 03650 if (!ast_sockaddr_is_any(&sip_tcp_desc.local_address)) { 03651 ast_sockaddr_copy(us, 03652 &sip_tcp_desc.local_address); 03653 } else { 03654 ast_sockaddr_set_port(us, 03655 ast_sockaddr_port(&sip_tcp_desc.local_address)); 03656 } 03657 break; 03658 case SIP_TRANSPORT_TLS: 03659 if (!ast_sockaddr_is_any(&sip_tls_desc.local_address)) { 03660 ast_sockaddr_copy(us, 03661 &sip_tls_desc.local_address); 03662 } else { 03663 ast_sockaddr_set_port(us, 03664 ast_sockaddr_port(&sip_tls_desc.local_address)); 03665 } 03666 break; 03667 case SIP_TRANSPORT_UDP: 03668 /* fall through on purpose */ 03669 default: 03670 if (!ast_sockaddr_is_any(&bindaddr)) { 03671 ast_sockaddr_copy(us, &bindaddr); 03672 } 03673 if (!ast_sockaddr_port(us)) { 03674 ast_sockaddr_set_port(us, ast_sockaddr_port(&bindaddr)); 03675 } 03676 } 03677 } 03678 ast_debug(3, "Setting SIP_TRANSPORT_%s with address %s\n", get_transport(p->socket.type), ast_sockaddr_stringify(us)); 03679 }
| static int ast_sockaddr_resolve_first | ( | struct ast_sockaddr * | addr, | |
| const char * | name, | |||
| int | flag | |||
| ) | [static] |
Return the first entry from ast_sockaddr_resolve filtered by family of binddaddr.
Using this function probably means you have a faulty design.
Definition at line 30707 of file chan_sip.c.
References ast_sockaddr_resolve_first_af(), and get_address_family_filter().
Referenced by ast_sip_ouraddrfor(), check_via(), and reload_config().
30709 { 30710 return ast_sockaddr_resolve_first_af(addr, name, flag, get_address_family_filter(SIP_TRANSPORT_UDP)); 30711 }
| static int ast_sockaddr_resolve_first_af | ( | struct ast_sockaddr * | addr, | |
| const char * | name, | |||
| int | flag, | |||
| int | family | |||
| ) | [static] |
Return the first entry from ast_sockaddr_resolve filtered by address family.
Using this function probably means you have a faulty design.
Definition at line 30683 of file chan_sip.c.
References ast_debug, ast_free, ast_sockaddr_copy(), and ast_sockaddr_resolve().
Referenced by ast_sockaddr_resolve_first(), ast_sockaddr_resolve_first_transport(), get_ip_and_port_from_sdp(), process_sdp_c(), and sip_do_debug_ip().
30685 { 30686 struct ast_sockaddr *addrs; 30687 int addrs_cnt; 30688 30689 addrs_cnt = ast_sockaddr_resolve(&addrs, name, flag, family); 30690 if (addrs_cnt <= 0) { 30691 return 1; 30692 } 30693 if (addrs_cnt > 1) { 30694 ast_debug(1, "Multiple addresses, using the first one only\n"); 30695 } 30696 30697 ast_sockaddr_copy(addr, &addrs[0]); 30698 30699 ast_free(addrs); 30700 return 0; 30701 }
| static int ast_sockaddr_resolve_first_transport | ( | struct ast_sockaddr * | addr, | |
| const char * | name, | |||
| int | flag, | |||
| unsigned int | transport | |||
| ) | [static] |
Return the first entry from ast_sockaddr_resolve filtered by family of binddaddr.
Using this function probably means you have a faulty design.
Definition at line 30717 of file chan_sip.c.
References ast_sockaddr_resolve_first_af(), and get_address_family_filter().
Referenced by __set_address_from_contact(), create_addr(), parse_register_contact(), process_via(), and set_destination().
30719 { 30720 return ast_sockaddr_resolve_first_af(addr, name, flag, get_address_family_filter(transport)); 30721 }
| AST_THREADSTORAGE | ( | check_auth_buf | ) |
| AST_THREADSTORAGE_CUSTOM | ( | ts_temp_pvt | , | |
| temp_pvt_init | , | |||
| temp_pvt_cleanup | ||||
| ) |
A per-thread temporary pvt structure.
| static int attempt_transfer | ( | struct sip_dual * | transferer, | |
| struct sip_dual * | target | |||
| ) | [static] |
Attempt transfer of SIP call This fix for attended transfers on a local PBX.
Definition at line 22364 of file chan_sip.c.
References ast_channel_masquerade(), ast_debug, ast_log(), ast_quiet_chan(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), ast_state2str(), LOG_NOTICE, and LOG_WARNING.
Referenced by local_attended_transfer().
22365 { 22366 int res = 0; 22367 struct ast_channel *peera = NULL, 22368 *peerb = NULL, 22369 *peerc = NULL, 22370 *peerd = NULL; 22371 22372 22373 /* We will try to connect the transferee with the target and hangup 22374 all channels to the transferer */ 22375 ast_debug(4, "Sip transfer:--------------------\n"); 22376 if (transferer->chan1) 22377 ast_debug(4, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state)); 22378 else 22379 ast_debug(4, "-- No transferer first channel - odd??? \n"); 22380 if (target->chan1) 22381 ast_debug(4, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state)); 22382 else 22383 ast_debug(4, "-- No target first channel ---\n"); 22384 if (transferer->chan2) 22385 ast_debug(4, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state)); 22386 else 22387 ast_debug(4, "-- No bridged call to transferee\n"); 22388 if (target->chan2) 22389 ast_debug(4, "-- Bridged call to transfer target: %s State %s\n", target->chan2 ? target->chan2->name : "<none>", target->chan2 ? ast_state2str(target->chan2->_state) : "(none)"); 22390 else 22391 ast_debug(4, "-- No target second channel ---\n"); 22392 ast_debug(4, "-- END Sip transfer:--------------------\n"); 22393 if (transferer->chan2) { /* We have a bridge on the transferer's channel */ 22394 peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */ 22395 peerb = target->chan1; /* Transferer - PBX -> target channel - This will get lost in masq */ 22396 peerc = transferer->chan2; /* Asterisk to Transferee */ 22397 peerd = target->chan2; /* Asterisk to Target */ 22398 ast_debug(3, "SIP transfer: Four channels to handle\n"); 22399 } else if (target->chan2) { /* Transferer has no bridge (IVR), but transferee */ 22400 peera = target->chan1; /* Transferer to PBX -> target channel */ 22401 peerb = transferer->chan1; /* Transferer to IVR*/ 22402 peerc = target->chan2; /* Asterisk to Target */ 22403 peerd = transferer->chan2; /* Nothing */ 22404 ast_debug(3, "SIP transfer: Three channels to handle\n"); 22405 } 22406 22407 if (peera && peerb && peerc && (peerb != peerc)) { 22408 ast_quiet_chan(peera); /* Stop generators */ 22409 /* no need to quiet peerb since it should be hungup after the 22410 transfer and the masquerade needs to be able to see if MOH is 22411 playing on it */ 22412 ast_quiet_chan(peerc); 22413 if (peerd) 22414 ast_quiet_chan(peerd); 22415 22416 ast_debug(4, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name); 22417 if (ast_channel_masquerade(peerb, peerc)) { 22418 ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); 22419 res = -1; 22420 } else 22421 ast_debug(4, "SIP transfer: Succeeded to masquerade channels.\n"); 22422 return res; 22423 } else { 22424 ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n"); 22425 if (transferer->chan1) 22426 ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV); 22427 if (target->chan1) 22428 ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV); 22429 return -1; 22430 } 22431 return 0; 22432 }
| static void auth_headers | ( | enum sip_auth_type | code, | |
| char ** | header, | |||
| char ** | respheader | |||
| ) | [static] |
return the request and response header for a 401 or 407 code
Definition at line 14135 of file chan_sip.c.
References ast_verbose.
Referenced by check_auth(), do_proxy_auth(), do_register_auth(), and transmit_request_with_auth().
14136 { 14137 if (code == WWW_AUTH) { /* 401 */ 14138 *header = "WWW-Authenticate"; 14139 *respheader = "Authorization"; 14140 } else if (code == PROXY_AUTH) { /* 407 */ 14141 *header = "Proxy-Authenticate"; 14142 *respheader = "Proxy-Authorization"; 14143 } else { 14144 ast_verbose("-- wrong response code %u\n", code); 14145 *header = *respheader = "Invalid"; 14146 } 14147 }
| static int auto_congest | ( | const void * | arg | ) | [static] |
Scheduled congestion on a call. Only called by the scheduler, must return the reference when done.
Definition at line 5734 of file chan_sip.c.
References append_history, ast_channel_trylock, ast_channel_unlock, AST_CONTROL_CONGESTION, ast_queue_control(), sip_pvt_lock, sip_pvt_unlock, and sip_scheddestroy().
Referenced by sip_call(), and sip_show_sched().
05735 { 05736 struct sip_pvt *p = (struct sip_pvt *)arg; 05737 05738 sip_pvt_lock(p); 05739 p->initid = -1; /* event gone, will not be rescheduled */ 05740 if (p->owner) { 05741 /* XXX fails on possible deadlock */ 05742 if (!ast_channel_trylock(p->owner)) { 05743 append_history(p, "Cong", "Auto-congesting (timer)"); 05744 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 05745 ast_channel_unlock(p->owner); 05746 } 05747 05748 /* Give the channel a chance to act before we proceed with destruction */ 05749 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 05750 } 05751 sip_pvt_unlock(p); 05752 dialog_unref(p, "unreffing arg passed into auto_congest callback (p->initid)"); 05753 return 0; 05754 }
| static void build_callid_pvt | ( | struct sip_pvt * | pvt | ) | [static] |
Build SIP Call-ID value for a non-REGISTER transaction.
Definition at line 7867 of file chan_sip.c.
References ast_sockaddr_stringify_remote(), ast_string_field_build, generate_random_string(), and S_OR.
Referenced by change_callid_pvt(), and sip_alloc().
07868 { 07869 char buf[33]; 07870 const char *host = S_OR(pvt->fromdomain, ast_sockaddr_stringify_remote(&pvt->ourip)); 07871 07872 ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 07873 }
| static void build_callid_registry | ( | struct sip_registry * | reg, | |
| const struct ast_sockaddr * | ourip, | |||
| const char * | fromdomain | |||
| ) | [static] |
Build SIP Call-ID value for a REGISTER transaction.
Definition at line 7922 of file chan_sip.c.
References ast_sockaddr_stringify_host_remote(), ast_string_field_build, generate_random_string(), and S_OR.
Referenced by transmit_register().
07923 { 07924 char buf[33]; 07925 07926 const char *host = S_OR(fromdomain, ast_sockaddr_stringify_host_remote(ourip)); 07927 07928 ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 07929 }
| static void build_contact | ( | struct sip_pvt * | p | ) | [static] |
Build contact header - the contact header we send out.
Definition at line 12329 of file chan_sip.c.
References ast_sockaddr_stringify_remote(), ast_string_field_build, ast_strlen_zero(), ast_uri_encode(), and get_transport().
Referenced by __sip_subscribe_mwi_do(), check_user_full(), handle_request_invite(), handle_request_options(), handle_request_subscribe(), initreqprep(), register_verify(), and transmit_register().
12330 { 12331 char tmp[SIPBUFSIZE]; 12332 char *user = ast_uri_encode(p->exten, tmp, sizeof(tmp), 0); 12333 12334 if (p->socket.type == SIP_TRANSPORT_UDP) { 12335 ast_string_field_build(p, our_contact, "<sip:%s%s%s>", user, 12336 ast_strlen_zero(user) ? "" : "@", ast_sockaddr_stringify_remote(&p->ourip)); 12337 } else { 12338 ast_string_field_build(p, our_contact, "<sip:%s%s%s;transport=%s>", user, 12339 ast_strlen_zero(user) ? "" : "@", ast_sockaddr_stringify_remote(&p->ourip), 12340 get_transport(p->socket.type)); 12341 } 12342 }
| static void build_localtag_registry | ( | struct sip_registry * | reg | ) | [static] |
Build SIP From tag value for REGISTER.
Definition at line 7932 of file chan_sip.c.
References ast_random(), and ast_string_field_build.
Referenced by transmit_register().
07933 { 07934 ast_string_field_build(reg, localtag, "as%08lx", (unsigned long)ast_random()); 07935 }
| static struct sip_peer * build_peer | ( | const char * | name, | |
| struct ast_variable * | v, | |||
| struct ast_variable * | alt, | |||
| int | realtime, | |||
| int | devstate_only | |||
| ) | [static, read] |
Build peer from configuration (file or realtime static/dynamic).
< The first transport listed should be default outbound
Definition at line 28085 of file chan_sip.c.
References __set_address_from_contact(), accountcode, add_peer_mailboxes(), add_peer_mwi_subs(), add_realm_authentication(), add_var(), ao2_lock, ao2_t_alloc, ao2_t_find, ao2_t_ref, ao2_t_unlink, ao2_unlock, ast_append_ha(), ast_asprintf, ast_atomic_fetchadd_int(), ast_callerid_split(), AST_CC_AGENT_NATIVE, AST_CC_AGENT_NEVER, ast_cc_config_params_init, ast_cc_is_config_param(), ast_cc_set_param(), ast_cdr_amaflags2int(), ast_copy_flags, ast_copy_string(), ast_debug, ast_dnsmgr_lookup_cb(), ast_dnsmgr_refresh(), ast_free, ast_free_ha(), ast_get_cc_agent_policy(), ast_get_group(), ast_get_ip(), ast_get_time_t(), AST_LIST_EMPTY, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), ast_parse_allow_disallow(), ast_parse_caller_presentation(), AST_SCHED_DEL_UNREF, ast_set2_flag, ast_set_cc_agent_policy(), ast_set_flag, ast_skip_blanks(), ast_sockaddr_isnull(), ast_sockaddr_parse(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_setnull(), ast_sockaddr_stringify_addr(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_set(), ast_str_strlen(), ast_strdupa, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variables_destroy(), cid_name, cid_num, context, DEFAULT_MAXMS, destroy_association(), destroy_mailbox(), ast_tls_config::enabled, FALSE, ast_flags::flags, format, get_address_family_filter(), get_srv_protocol(), get_srv_service(), handle_common_options(), handle_t38_options(), language, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, mailbox, mark_parsed_methods(), MAXHOSTNAMELEN, mohinterpret, mohsuggest, ast_variable::name, ast_variable::next, OBJ_POINTER, OBJ_UNLINK, on_dns_update_peer(), parkinglot, PARSE_PORT_FORBID, port_str2int(), proxy_from_config(), ref_peer(), reg_source_db(), secret, set_peer_defaults(), set_socket_transport(), sip_cfg, sip_destroy_peer_fn(), sip_poke_peer(), sip_register(), sip_send_mwi_to_peer(), srvlookup, str2stmode(), str2strefresherparam(), TRUE, unref_peer(), and ast_variable::value.
Referenced by realtime_peer(), and reload_config().
28086 { 28087 struct sip_peer *peer = NULL; 28088 struct ast_ha *oldha = NULL; 28089 struct ast_ha *olddirectmediaha = NULL; 28090 int found = 0; 28091 int firstpass = 1; 28092 uint16_t port = 0; 28093 int format = 0; /* Ama flags */ 28094 int timerb_set = 0, timert1_set = 0; 28095 time_t regseconds = 0; 28096 struct ast_flags peerflags[3] = {{(0)}}; 28097 struct ast_flags mask[3] = {{(0)}}; 28098 char callback[256] = ""; 28099 struct sip_peer tmp_peer; 28100 const char *srvlookup = NULL; 28101 static int deprecation_warning = 1; 28102 int alt_fullcontact = alt ? 1 : 0, headercount = 0; 28103 struct ast_str *fullcontact = ast_str_alloca(512); 28104 28105 if (!realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 28106 /* Note we do NOT use find_peer here, to avoid realtime recursion */ 28107 /* We also use a case-sensitive comparison (unlike find_peer) so 28108 that case changes made to the peer name will be properly handled 28109 during reload 28110 */ 28111 ast_copy_string(tmp_peer.name, name, sizeof(tmp_peer.name)); 28112 peer = ao2_t_find(peers, &tmp_peer, OBJ_POINTER | OBJ_UNLINK, "find and unlink peer from peers table"); 28113 } 28114 28115 if (peer) { 28116 /* Already in the list, remove it and it will be added back (or FREE'd) */ 28117 found++; 28118 /* we've unlinked the peer from the peers container but not unlinked from the peers_by_ip container yet 28119 this leads to a wrong refcounter and the peer object is never destroyed */ 28120 if (!ast_sockaddr_isnull(&peer->addr)) { 28121 ao2_t_unlink(peers_by_ip, peer, "ao2_unlink peer from peers_by_ip table"); 28122 } 28123 if (!(peer->the_mark)) 28124 firstpass = 0; 28125 } else { 28126 if (!(peer = ao2_t_alloc(sizeof(*peer), sip_destroy_peer_fn, "allocate a peer struct"))) 28127 return NULL; 28128 28129 if (ast_string_field_init(peer, 512)) { 28130 ao2_t_ref(peer, -1, "failed to string_field_init, drop peer"); 28131 return NULL; 28132 } 28133 28134 if (!(peer->cc_params = ast_cc_config_params_init())) { 28135 ao2_t_ref(peer, -1, "failed to allocate cc_params for peer"); 28136 return NULL; 28137 } 28138 28139 if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 28140 ast_atomic_fetchadd_int(&rpeerobjs, 1); 28141 ast_debug(3, "-REALTIME- peer built. Name: %s. Peer objects: %d\n", name, rpeerobjs); 28142 } else 28143 ast_atomic_fetchadd_int(&speerobjs, 1); 28144 } 28145 28146 /* Note that our peer HAS had its reference count increased */ 28147 if (firstpass) { 28148 peer->lastmsgssent = -1; 28149 oldha = peer->ha; 28150 peer->ha = NULL; 28151 olddirectmediaha = peer->directmediaha; 28152 peer->directmediaha = NULL; 28153 set_peer_defaults(peer); /* Set peer defaults */ 28154 peer->type = 0; 28155 } 28156 28157 /* in case the case of the peer name has changed, update the name */ 28158 ast_copy_string(peer->name, name, sizeof(peer->name)); 28159 28160 /* If we have channel variables, remove them (reload) */ 28161 if (peer->chanvars) { 28162 ast_variables_destroy(peer->chanvars); 28163 peer->chanvars = NULL; 28164 /* XXX should unregister ? */ 28165 } 28166 28167 if (found) 28168 peer->portinuri = 0; 28169 28170 /* If we have realm authentication information, remove them (reload) */ 28171 ao2_lock(peer); 28172 if (peer->auth) { 28173 ao2_t_ref(peer->auth, -1, "Removing old peer authentication"); 28174 peer->auth = NULL; 28175 } 28176 ao2_unlock(peer); 28177 28178 /* clear the transport information. We will detect if a default value is required after parsing the config */ 28179 peer->default_outbound_transport = 0; 28180 peer->transports = 0; 28181 28182 if (!devstate_only) { 28183 struct sip_mailbox *mailbox; 28184 AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { 28185 mailbox->delme = 1; 28186 } 28187 } 28188 28189 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 28190 if (!devstate_only) { 28191 if (handle_common_options(&peerflags[0], &mask[0], v)) { 28192 continue; 28193 } 28194 if (handle_t38_options(&peerflags[0], &mask[0], v, &peer->t38_maxdatagram)) { 28195 continue; 28196 } 28197 if (!strcasecmp(v->name, "transport")) { 28198 char *val = ast_strdupa(v->value); 28199 char *trans; 28200 28201 peer->transports = peer->default_outbound_transport = 0; 28202 while ((trans = strsep(&val, ","))) { 28203 trans = ast_skip_blanks(trans); 28204 28205 if (!strncasecmp(trans, "udp", 3)) { 28206 peer->transports |= SIP_TRANSPORT_UDP; 28207 } else if (sip_cfg.tcp_enabled && !strncasecmp(trans, "tcp", 3)) { 28208 peer->transports |= SIP_TRANSPORT_TCP; 28209 } else if (default_tls_cfg.enabled && !strncasecmp(trans, "tls", 3)) { 28210 peer->transports |= SIP_TRANSPORT_TLS; 28211 } else if (!strncasecmp(trans, "tcp", 3) || !strncasecmp(trans, "tls", 3)) { 28212 ast_log(LOG_WARNING, "'%.3s' is not a valid transport type when %.3senable=no. If no other is specified, the defaults from general will be used.\n", trans, trans); 28213 } else { 28214 ast_log(LOG_NOTICE, "'%s' is not a valid transport type. if no other is specified, the defaults from general will be used.\n", trans); 28215 } 28216 28217 if (!peer->default_outbound_transport) { /*!< The first transport listed should be default outbound */ 28218 peer->default_outbound_transport = peer->transports; 28219 } 28220 } 28221 } else if (realtime && !strcasecmp(v->name, "regseconds")) { 28222 ast_get_time_t(v->value, ®seconds, 0, NULL); 28223 } else if (realtime && !strcasecmp(v->name, "name")) { 28224 ast_copy_string(peer->name, v->value, sizeof(peer->name)); 28225 } else if (realtime && !strcasecmp(v->name, "useragent")) { 28226 ast_string_field_set(peer, useragent, v->value); 28227 } else if (!strcasecmp(v->name, "type")) { 28228 if (!strcasecmp(v->value, "peer")) { 28229 peer->type |= SIP_TYPE_PEER; 28230 } else if (!strcasecmp(v->value, "user")) { 28231 peer->type |= SIP_TYPE_USER; 28232 } else if (!strcasecmp(v->value, "friend")) { 28233 peer->type = SIP_TYPE_USER | SIP_TYPE_PEER; 28234 } 28235 } else if (!strcasecmp(v->name, "remotesecret")) { 28236 ast_string_field_set(peer, remotesecret, v->value); 28237 } else if (!strcasecmp(v->name, "secret")) { 28238 ast_string_field_set(peer, secret, v->value); 28239 } else if (!strcasecmp(v->name, "md5secret")) { 28240 ast_string_field_set(peer, md5secret, v->value); 28241 } else if (!strcasecmp(v->name, "auth")) { 28242 add_realm_authentication(&peer->auth, v->value, v->lineno); 28243 } else if (!strcasecmp(v->name, "callerid")) { 28244 char cid_name[80] = { '\0' }, cid_num[80] = { '\0' }; 28245 28246 ast_callerid_split(v->value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num)); 28247 ast_string_field_set(peer, cid_name, cid_name); 28248 ast_string_field_set(peer, cid_num, cid_num); 28249 } else if (!strcasecmp(v->name, "mwi_from")) { 28250 ast_string_field_set(peer, mwi_from, v->value); 28251 } else if (!strcasecmp(v->name, "fullname")) { 28252 ast_string_field_set(peer, cid_name, v->value); 28253 } else if (!strcasecmp(v->name, "trunkname")) { 28254 /* This is actually for a trunk, so we don't want to override callerid */ 28255 ast_string_field_set(peer, cid_name, ""); 28256 } else if (!strcasecmp(v->name, "cid_number")) { 28257 ast_string_field_set(peer, cid_num, v->value); 28258 } else if (!strcasecmp(v->name, "cid_tag")) { 28259 ast_string_field_set(peer, cid_tag, v->value); 28260 } else if (!strcasecmp(v->name, "context")) { 28261 ast_string_field_set(peer, context, v->value); 28262 ast_set_flag(&peer->flags[1], SIP_PAGE2_HAVEPEERCONTEXT); 28263 } else if (!strcasecmp(v->name, "subscribecontext")) { 28264 ast_string_field_set(peer, subscribecontext, v->value); 28265 } else if (!strcasecmp(v->name, "fromdomain")) { 28266 char *fromdomainport; 28267 ast_string_field_set(peer, fromdomain, v->value); 28268 if ((fromdomainport = strchr(peer->fromdomain, ':'))) { 28269 *fromdomainport++ = '\0'; 28270 if (!(peer->fromdomainport = port_str2int(fromdomainport, 0))) { 28271 ast_log(LOG_NOTICE, "'%s' is not a valid port number for fromdomain.\n",fromdomainport); 28272 } 28273 } else { 28274 peer->fromdomainport = STANDARD_SIP_PORT; 28275 } 28276 } else if (!strcasecmp(v->name, "usereqphone")) { 28277 ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE); 28278 } else if (!strcasecmp(v->name, "fromuser")) { 28279 ast_string_field_set(peer, fromuser, v->value); 28280 } else if (!strcasecmp(v->name, "outboundproxy")) { 28281 struct sip_proxy *proxy; 28282 if (ast_strlen_zero(v->value)) { 28283 ast_log(LOG_WARNING, "no value given for outbound proxy on line %d of sip.conf\n", v->lineno); 28284 continue; 28285 } 28286 proxy = proxy_from_config(v->value, v->lineno, peer->outboundproxy); 28287 if (!proxy) { 28288 ast_log(LOG_WARNING, "failure parsing the outbound proxy on line %d of sip.conf.\n", v->lineno); 28289 continue; 28290 } 28291 peer->outboundproxy = proxy; 28292 } else if (!strcasecmp(v->name, "host")) { 28293 if (!strcasecmp(v->value, "dynamic")) { 28294 /* They'll register with us */ 28295 if ((!found && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) || !peer->host_dynamic) { 28296 /* Initialize stuff if this is a new peer, or if it used to 28297 * not be dynamic before the reload. */ 28298 ast_sockaddr_setnull(&peer->addr); 28299 } 28300 peer->host_dynamic = TRUE; 28301 } else { 28302 /* Non-dynamic. Make sure we become that way if we're not */ 28303 AST_SCHED_DEL_UNREF(sched, peer->expire, 28304 unref_peer(peer, "removing register expire ref")); 28305 peer->host_dynamic = FALSE; 28306 srvlookup = v->value; 28307 } 28308 } else if (!strcasecmp(v->name, "defaultip")) { 28309 if (!ast_strlen_zero(v->value) && ast_get_ip(&peer->defaddr, v->value)) { 28310 unref_peer(peer, "unref_peer: from build_peer defaultip"); 28311 return NULL; 28312 } 28313 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 28314 int ha_error = 0; 28315 if (!ast_strlen_zero(v->value)) { 28316 peer->ha = ast_append_ha(v->name, v->value, peer->ha, &ha_error); 28317 } 28318 if (ha_error) { 28319 ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value); 28320 } 28321 } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) { 28322 int ha_error = 0; 28323 if (!ast_strlen_zero(v->value)) { 28324 peer->contactha = ast_append_ha(v->name + 7, v->value, peer->contactha, &ha_error); 28325 } 28326 if (ha_error) { 28327 ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value); 28328 } 28329 } else if (!strcasecmp(v->name, "directmediapermit") || !strcasecmp(v->name, "directmediadeny")) { 28330 int ha_error = 0; 28331 peer->directmediaha = ast_append_ha(v->name + 11, v->value, peer->directmediaha, &ha_error); 28332 if (ha_error) { 28333 ast_log(LOG_ERROR, "Bad directmedia ACL entry in configuration line %d : %s\n", v->lineno, v->value); 28334 } 28335 } else if (!strcasecmp(v->name, "port")) { 28336 peer->portinuri = 1; 28337 if (!(port = port_str2int(v->value, 0))) { 28338 if (realtime) { 28339 /* If stored as integer, could be 0 for some DBs (notably MySQL) */ 28340 peer->portinuri = 0; 28341 } else { 28342 ast_log(LOG_WARNING, "Invalid peer port configuration at line %d : %s\n", v->lineno, v->value); 28343 } 28344 } 28345 } else if (!strcasecmp(v->name, "callingpres")) { 28346 peer->callingpres = ast_parse_caller_presentation(v->value); 28347 if (peer->callingpres == -1) { 28348 peer->callingpres = atoi(v->value); 28349 } 28350 } else if (!strcasecmp(v->name, "username") || !strcmp(v->name, "defaultuser")) { /* "username" is deprecated */ 28351 ast_string_field_set(peer, username, v->value); 28352 if (!strcasecmp(v->name, "username")) { 28353 if (deprecation_warning) { 28354 ast_log(LOG_NOTICE, "The 'username' field for sip peers has been deprecated in favor of the term 'defaultuser'\n"); 28355 deprecation_warning = 0; 28356 } 28357 peer->deprecated_username = 1; 28358 } 28359 } else if (!strcasecmp(v->name, "language")) { 28360 ast_string_field_set(peer, language, v->value); 28361 } else if (!strcasecmp(v->name, "regexten")) { 28362 ast_string_field_set(peer, regexten, v->value); 28363 } else if (!strcasecmp(v->name, "callbackextension")) { 28364 ast_copy_string(callback, v->value, sizeof(callback)); 28365 } else if (!strcasecmp(v->name, "amaflags")) { 28366 format = ast_cdr_amaflags2int(v->value); 28367 if (format < 0) { 28368 ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno); 28369 } else { 28370 peer->amaflags = format; 28371 } 28372 } else if (!strcasecmp(v->name, "maxforwards")) { 28373 if (sscanf(v->value, "%30d", &peer->maxforwards) != 1 28374 || peer->maxforwards < 1 || 255 < peer->maxforwards) { 28375 ast_log(LOG_WARNING, "'%s' is not a valid maxforwards value at line %d. Using default.\n", v->value, v->lineno); 28376 peer->maxforwards = sip_cfg.default_max_forwards; 28377 } 28378 } else if (!strcasecmp(v->name, "accountcode")) { 28379 ast_string_field_set(peer, accountcode, v->value); 28380 } else if (!strcasecmp(v->name, "mohinterpret")) { 28381 ast_string_field_set(peer, mohinterpret, v->value); 28382 } else if (!strcasecmp(v->name, "mohsuggest")) { 28383 ast_string_field_set(peer, mohsuggest, v->value); 28384 } else if (!strcasecmp(v->name, "parkinglot")) { 28385 ast_string_field_set(peer, parkinglot, v->value); 28386 } else if (!strcasecmp(v->name, "rtp_engine")) { 28387 ast_string_field_set(peer, engine, v->value); 28388 } else if (!strcasecmp(v->name, "mailbox")) { 28389 add_peer_mailboxes(peer, v->value); 28390 } else if (!strcasecmp(v->name, "hasvoicemail")) { 28391 /* People expect that if 'hasvoicemail' is set, that the mailbox will 28392 * be also set, even if not explicitly specified. */ 28393 if (ast_true(v->value) && AST_LIST_EMPTY(&peer->mailboxes)) { 28394 add_peer_mailboxes(peer, name); 28395 } 28396 } else if (!strcasecmp(v->name, "subscribemwi")) { 28397 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY); 28398 } else if (!strcasecmp(v->name, "vmexten")) { 28399 ast_string_field_set(peer, vmexten, v->value); 28400 } else if (!strcasecmp(v->name, "callgroup")) { 28401 peer->callgroup = ast_get_group(v->value); 28402 } else if (!strcasecmp(v->name, "allowtransfer")) { 28403 peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 28404 } else if (!strcasecmp(v->name, "pickupgroup")) { 28405 peer->pickupgroup = ast_get_group(v->value); 28406 } else if (!strcasecmp(v->name, "allow")) { 28407 int error = ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, TRUE); 28408 if (error) { 28409 ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value); 28410 } 28411 } else if (!strcasecmp(v->name, "disallow")) { 28412 int error = ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, FALSE); 28413 if (error) { 28414 ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value); 28415 } 28416 } else if (!strcasecmp(v->name, "preferred_codec_only")) { 28417 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_PREFERRED_CODEC); 28418 } else if (!strcasecmp(v->name, "autoframing")) { 28419 peer->autoframing = ast_true(v->value); 28420 } else if (!strcasecmp(v->name, "rtptimeout")) { 28421 if ((sscanf(v->value, "%30d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) { 28422 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 28423 peer->rtptimeout = global_rtptimeout; 28424 } 28425 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 28426 if ((sscanf(v->value, "%30d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) { 28427 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 28428 peer->rtpholdtimeout = global_rtpholdtimeout; 28429 } 28430 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 28431 if ((sscanf(v->value, "%30d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) { 28432 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 28433 peer->rtpkeepalive = global_rtpkeepalive; 28434 } 28435 } else if (!strcasecmp(v->name, "timert1")) { 28436 if ((sscanf(v->value, "%30d", &peer->timer_t1) != 1) || (peer->timer_t1 < 200) || (peer->timer_t1 < global_t1min)) { 28437 ast_log(LOG_WARNING, "'%s' is not a valid T1 time at line %d. Using default.\n", v->value, v->lineno); 28438 peer->timer_t1 = global_t1min; 28439 } 28440 timert1_set = 1; 28441 } else if (!strcasecmp(v->name, "timerb")) { 28442 if ((sscanf(v->value, "%30d", &peer->timer_b) != 1) || (peer->timer_b < 200)) { 28443 ast_log(LOG_WARNING, "'%s' is not a valid Timer B time at line %d. Using default.\n", v->value, v->lineno); 28444 peer->timer_b = global_timer_b; 28445 } 28446 timerb_set = 1; 28447 } else if (!strcasecmp(v->name, "setvar")) { 28448 peer->chanvars = add_var(v->value, peer->chanvars); 28449 } else if (!strcasecmp(v->name, "header")) { 28450 char tmp[4096]; 28451 snprintf(tmp, sizeof(tmp), "__SIPADDHEADERpre%2d=%s", ++headercount, v->value); 28452 peer->chanvars = add_var(tmp, peer->chanvars); 28453 } else if (!strcasecmp(v->name, "qualifyfreq")) { 28454 int i; 28455 if (sscanf(v->value, "%30d", &i) == 1) { 28456 peer->qualifyfreq = i * 1000; 28457 } else { 28458 ast_log(LOG_WARNING, "Invalid qualifyfreq number '%s' at line %d of %s\n", v->value, v->lineno, config); 28459 peer->qualifyfreq = global_qualifyfreq; 28460 } 28461 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 28462 peer->maxcallbitrate = atoi(v->value); 28463 if (peer->maxcallbitrate < 0) { 28464 peer->maxcallbitrate = default_maxcallbitrate; 28465 } 28466 } else if (!strcasecmp(v->name, "session-timers")) { 28467 int i = (int) str2stmode(v->value); 28468 if (i < 0) { 28469 ast_log(LOG_WARNING, "Invalid session-timers '%s' at line %d of %s\n", v->value, v->lineno, config); 28470 peer->stimer.st_mode_oper = global_st_mode; 28471 } else { 28472 peer->stimer.st_mode_oper = i; 28473 } 28474 } else if (!strcasecmp(v->name, "session-expires")) { 28475 if (sscanf(v->value, "%30d", &peer->stimer.st_max_se) != 1) { 28476 ast_log(LOG_WARNING, "Invalid session-expires '%s' at line %d of %s\n", v->value, v->lineno, config); 28477 peer->stimer.st_max_se = global_max_se; 28478 } 28479 } else if (!strcasecmp(v->name, "session-minse")) { 28480 if (sscanf(v->value, "%30d", &peer->stimer.st_min_se) != 1) { 28481 ast_log(LOG_WARNING, "Invalid session-minse '%s' at line %d of %s\n", v->value, v->lineno, config); 28482 peer->stimer.st_min_se = global_min_se; 28483 } 28484 if (peer->stimer.st_min_se < DEFAULT_MIN_SE) { 28485 ast_log(LOG_WARNING, "session-minse '%s' at line %d of %s is not allowed to be < %d secs\n", v->value, v->lineno, config, DEFAULT_MIN_SE); 28486 peer->stimer.st_min_se = global_min_se; 28487 } 28488 } else if (!strcasecmp(v->name, "session-refresher")) { 28489 int i = (int) str2strefresherparam(v->value); 28490 if (i < 0) { 28491 ast_log(LOG_WARNING, "Invalid session-refresher '%s' at line %d of %s\n", v->value, v->lineno, config); 28492 peer->stimer.st_ref = global_st_refresher; 28493 } else { 28494 peer->stimer.st_ref = i; 28495 } 28496 } else if (!strcasecmp(v->name, "disallowed_methods")) { 28497 char *disallow = ast_strdupa(v->value); 28498 mark_parsed_methods(&peer->disallowed_methods, disallow); 28499 } else if (!strcasecmp(v->name, "unsolicited_mailbox")) { 28500 ast_string_field_set(peer, unsolicited_mailbox, v->value); 28501 } else if (!strcasecmp(v->name, "use_q850_reason")) { 28502 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_Q850_REASON); 28503 } else if (!strcasecmp(v->name, "encryption")) { 28504 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_USE_SRTP); 28505 } else if (!strcasecmp(v->name, "snom_aoc_enabled")) { 28506 ast_set2_flag(&peer->flags[2], ast_true(v->value), SIP_PAGE3_SNOM_AOC); 28507 } 28508 } 28509 28510 /* These apply to devstate lookups */ 28511 if (realtime && !strcasecmp(v->name, "lastms")) { 28512 sscanf(v->value, "%30d", &peer->lastms); 28513 } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) { 28514 ast_sockaddr_parse(&peer->addr, v->value, PARSE_PORT_FORBID); 28515 } else if (realtime && !strcasecmp(v->name, "fullcontact")) { 28516 if (alt_fullcontact && !alt) { 28517 /* Reset, because the alternate also has a fullcontact and we 28518 * do NOT want the field value to be doubled. It might be 28519 * tempting to skip this, but the first table might not have 28520 * fullcontact and since we're here, we know that the alternate 28521 * absolutely does. */ 28522 alt_fullcontact = 0; 28523 ast_str_reset(fullcontact); 28524 } 28525 /* Reconstruct field, because realtime separates our value at the ';' */ 28526 if (ast_str_strlen(fullcontact) > 0) { 28527 ast_str_append(&fullcontact, 0, ";%s", v->value); 28528 } else { 28529 ast_str_set(&fullcontact, 0, "%s", v->value); 28530 } 28531 } else if (!strcasecmp(v->name, "qualify")) { 28532 if (!strcasecmp(v->value, "no")) { 28533 peer->maxms = 0; 28534 } else if (!strcasecmp(v->value, "yes")) { 28535 peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS; 28536 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) { 28537 ast_log(LOG_WARNING, "Qualification of peer '%s' should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", peer->name, v->lineno); 28538 peer->maxms = 0; 28539 } 28540 if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && peer->maxms > 0) { 28541 /* This would otherwise cause a network storm, where the 28542 * qualify response refreshes the peer from the database, 28543 * which in turn causes another qualify to be sent, ad 28544 * infinitum. */ 28545 ast_log(LOG_WARNING, "Qualify is incompatible with dynamic uncached realtime. Please either turn rtcachefriends on or turn qualify off on peer '%s'\n", peer->name); 28546 peer->maxms = 0; 28547 } 28548 } else if (!strcasecmp(v->name, "callcounter")) { 28549 peer->call_limit = ast_true(v->value) ? INT_MAX : 0; 28550 } else if (!strcasecmp(v->name, "call-limit")) { 28551 peer->call_limit = atoi(v->value); 28552 if (peer->call_limit < 0) { 28553 peer->call_limit = 0; 28554 } 28555 } else if (!strcasecmp(v->name, "busylevel")) { 28556 peer->busy_level = atoi(v->value); 28557 if (peer->busy_level < 0) { 28558 peer->busy_level = 0; 28559 } 28560 } else if (ast_cc_is_config_param(v->name)) { 28561 ast_cc_set_param(peer->cc_params, v->name, v->value); 28562 } 28563 } 28564 28565 if (!devstate_only) { 28566 struct sip_mailbox *mailbox; 28567 AST_LIST_TRAVERSE_SAFE_BEGIN(&peer->mailboxes, mailbox, entry) { 28568 if (mailbox->delme) { 28569 AST_LIST_REMOVE_CURRENT(entry); 28570 destroy_mailbox(mailbox); 28571 } 28572 } 28573 AST_LIST_TRAVERSE_SAFE_END; 28574 } 28575 28576 if (!can_parse_xml && (ast_get_cc_agent_policy(peer->cc_params) == AST_CC_AGENT_NATIVE)) { 28577 ast_log(LOG_WARNING, "Peer %s has a cc_agent_policy of 'native' but required libxml2 dependency is not installed. Changing policy to 'never'\n", peer->name); 28578 ast_set_cc_agent_policy(peer->cc_params, AST_CC_AGENT_NEVER); 28579 } 28580 28581 /* Note that Timer B is dependent upon T1 and MUST NOT be lower 28582 * than T1 * 64, according to RFC 3261, Section 17.1.1.2 */ 28583 if (peer->timer_b < peer->timer_t1 * 64) { 28584 if (timerb_set && timert1_set) { 28585 ast_log(LOG_WARNING, "Timer B has been set lower than recommended for peer %s (%d < 64 * Timer-T1=%d)\n", peer->name, peer->timer_b, peer->timer_t1); 28586 } else if (timerb_set) { 28587 if ((peer->timer_t1 = peer->timer_b / 64) < global_t1min) { 28588 ast_log(LOG_WARNING, "Timer B has been set lower than recommended (%d < 64 * timert1=%d). (RFC 3261, 17.1.1.2)\n", peer->timer_b, peer->timer_t1); 28589 peer->timer_t1 = global_t1min; 28590 peer->timer_b = peer->timer_t1 * 64; 28591 } 28592 peer->timer_t1 = peer->timer_b / 64; 28593 } else { 28594 peer->timer_b = peer->timer_t1 * 64; 28595 } 28596 } 28597 28598 if (!peer->default_outbound_transport) { 28599 /* Set default set of transports */ 28600 peer->transports = default_transports; 28601 /* Set default primary transport */ 28602 peer->default_outbound_transport = default_primary_transport; 28603 } 28604 28605 /* The default transport type set during build_peer should only replace the socket.type when... 28606 * 1. Registration is not present and the socket.type and default transport types are different. 28607 * 2. The socket.type is not an acceptable transport type after rebuilding peer. 28608 * 3. The socket.type is not set yet. */ 28609 if (((peer->socket.type != peer->default_outbound_transport) && (peer->expire == -1)) || 28610 !(peer->socket.type & peer->transports) || !(peer->socket.type)) { 28611 28612 set_socket_transport(&peer->socket, peer->default_outbound_transport); 28613 } 28614 28615 ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags); 28616 ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags); 28617 ast_copy_flags(&peer->flags[2], &peerflags[2], mask[2].flags); 28618 28619 if (ast_str_strlen(fullcontact)) { 28620 ast_string_field_set(peer, fullcontact, ast_str_buffer(fullcontact)); 28621 peer->rt_fromcontact = TRUE; 28622 /* We have a hostname in the fullcontact, but if we don't have an 28623 * address listed on the entry (or if it's 'dynamic'), then we need to 28624 * parse the entry to obtain the IP address, so a dynamic host can be 28625 * contacted immediately after reload (as opposed to waiting for it to 28626 * register once again). But if we have an address for this peer and NAT was 28627 * specified, use that address instead. */ 28628 /* XXX May need to revisit the final argument; does the realtime DB store whether 28629 * the original contact was over TLS or not? XXX */ 28630 if (!ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) || ast_sockaddr_isnull(&peer->addr)) { 28631 __set_address_from_contact(ast_str_buffer(fullcontact), &peer->addr, 0); 28632 } 28633 } 28634 28635 if (srvlookup && peer->dnsmgr == NULL) { 28636 char transport[MAXHOSTNAMELEN]; 28637 char _srvlookup[MAXHOSTNAMELEN]; 28638 char *params; 28639 28640 ast_copy_string(_srvlookup, srvlookup, sizeof(_srvlookup)); 28641 if ((params = strchr(_srvlookup, ';'))) { 28642 *params++ = '\0'; 28643 } 28644 28645 snprintf(transport, sizeof(transport), "_%s._%s", get_srv_service(peer->socket.type), get_srv_protocol(peer->socket.type)); 28646 28647 peer->addr.ss.ss_family = get_address_family_filter(peer->socket.type); /* Filter address family */ 28648 if (ast_dnsmgr_lookup_cb(_srvlookup, &peer->addr, &peer->dnsmgr, sip_cfg.srvlookup && !peer->portinuri ? transport : NULL, 28649 on_dns_update_peer, ref_peer(peer, "Store peer on dnsmgr"))) { 28650 ast_log(LOG_ERROR, "srvlookup failed for host: %s, on peer %s, removing peer\n", _srvlookup, peer->name); 28651 unref_peer(peer, "dnsmgr lookup failed, getting rid of peer dnsmgr ref"); 28652 unref_peer(peer, "getting rid of a peer pointer"); 28653 return NULL; 28654 } 28655 if (!peer->dnsmgr) { 28656 /* dnsmgr refresh disabeld, release reference */ 28657 unref_peer(peer, "dnsmgr disabled, unref peer"); 28658 } 28659 28660 ast_string_field_set(peer, tohost, srvlookup); 28661 28662 if (global_dynamic_exclude_static && !ast_sockaddr_isnull(&peer->addr)) { 28663 int ha_error = 0; 28664 sip_cfg.contact_ha = ast_append_ha("deny", ast_sockaddr_stringify_addr(&peer->addr), 28665 sip_cfg.contact_ha, &ha_error); 28666 if (ha_error) { 28667 ast_log(LOG_ERROR, "Bad or unresolved host/IP entry in configuration for peer %s, cannot add to contact ACL\n", peer->name); 28668 } 28669 } 28670 } else if (peer->dnsmgr && !peer->host_dynamic) { 28671 /* force a refresh here on reload if dnsmgr already exists and host is set. */ 28672 ast_dnsmgr_refresh(peer->dnsmgr); 28673 } 28674 28675 if (port && !realtime && peer->host_dynamic) { 28676 ast_sockaddr_set_port(&peer->defaddr, port); 28677 } else if (port) { 28678 ast_sockaddr_set_port(&peer->addr, port); 28679 } 28680 28681 if (ast_sockaddr_port(&peer->addr) == 0) { 28682 ast_sockaddr_set_port(&peer->addr, 28683 (peer->socket.type & SIP_TRANSPORT_TLS) ? 28684 STANDARD_TLS_PORT : STANDARD_SIP_PORT); 28685 } 28686 if (ast_sockaddr_port(&peer->defaddr) == 0) { 28687 ast_sockaddr_set_port(&peer->defaddr, 28688 (peer->socket.type & SIP_TRANSPORT_TLS) ? 28689 STANDARD_TLS_PORT : STANDARD_SIP_PORT); 28690 } 28691 if (!peer->socket.port) { 28692 peer->socket.port = htons(((peer->socket.type & SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT)); 28693 } 28694 28695 if (realtime) { 28696 int enablepoke = 1; 28697 28698 if (!sip_cfg.ignore_regexpire && peer->host_dynamic) { 28699 time_t nowtime = time(NULL); 28700 28701 if ((nowtime - regseconds) > 0) { 28702 destroy_association(peer); 28703 memset(&peer->addr, 0, sizeof(peer->addr)); 28704 peer->lastms = -1; 28705 enablepoke = 0; 28706 ast_debug(1, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 28707 } 28708 } 28709 28710 /* Startup regular pokes */ 28711 if (!devstate_only && enablepoke) { 28712 sip_poke_peer(peer, 0); 28713 } 28714 } 28715 28716 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) { 28717 sip_cfg.allowsubscribe = TRUE; /* No global ban any more */ 28718 } 28719 /* If read-only RT backend, then refresh from local DB cache */ 28720 if (peer->host_dynamic && (!peer->is_realtime || !sip_cfg.peer_rtupdate)) { 28721 reg_source_db(peer); 28722 } 28723 28724 /* If they didn't request that MWI is sent *only* on subscribe, go ahead and 28725 * subscribe to it now. */ 28726 if (!devstate_only && !ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) && 28727 !AST_LIST_EMPTY(&peer->mailboxes)) { 28728 add_peer_mwi_subs(peer); 28729 /* Send MWI from the event cache only. This is so we can send initial 28730 * MWI if app_voicemail got loaded before chan_sip. If it is the other 28731 * way, then we will get events when app_voicemail gets loaded. */ 28732 sip_send_mwi_to_peer(peer, 1); 28733 } 28734 28735 peer->the_mark = 0; 28736 28737 ast_free_ha(oldha); 28738 ast_free_ha(olddirectmediaha); 28739 if (!ast_strlen_zero(callback)) { /* build string from peer info */ 28740 char *reg_string; 28741 if (ast_asprintf(®_string, "%s?%s:%s@%s/%s", peer->name, peer->username, !ast_strlen_zero(peer->remotesecret) ? peer->remotesecret : peer->secret, peer->tohost, callback) >= 0) { 28742 sip_register(reg_string, 0); /* XXX TODO: count in registry_count */ 28743 ast_free(reg_string); 28744 } 28745 } 28746 return peer; 28747 }
| static int build_reply_digest | ( | struct sip_pvt * | p, | |
| int | method, | |||
| char * | digest, | |||
| int | digest_len | |||
| ) | [static] |
Build reply digest.
Definition at line 19923 of file chan_sip.c.
References ao2_lock, ao2_t_ref, ao2_unlock, append_history, ast_copy_string(), ast_debug, ast_md5_hash(), ast_mutex_lock, ast_mutex_unlock, ast_random(), ast_sockaddr_stringify_host_remote(), ast_strlen_zero(), find_realm_authentication(), secret, sip_methods, and text.
Referenced by reply_digest(), transmit_register(), and transmit_request_with_auth().
19924 { 19925 char a1[256]; 19926 char a2[256]; 19927 char a1_hash[256]; 19928 char a2_hash[256]; 19929 char resp[256]; 19930 char resp_hash[256]; 19931 char uri[256]; 19932 char opaque[256] = ""; 19933 char cnonce[80]; 19934 const char *username; 19935 const char *secret; 19936 const char *md5secret; 19937 struct sip_auth *auth; /* Realm authentication credential */ 19938 struct sip_auth_container *credentials; 19939 19940 if (!ast_strlen_zero(p->domain)) 19941 snprintf(uri, sizeof(uri), "%s:%s", p->socket.type == SIP_TRANSPORT_TLS ? "sips" : "sip", p->domain); 19942 else if (!ast_strlen_zero(p->uri)) 19943 ast_copy_string(uri, p->uri, sizeof(uri)); 19944 else 19945 snprintf(uri, sizeof(uri), "%s:%s@%s", p->socket.type == SIP_TRANSPORT_TLS ? "sips" : "sip", p->username, ast_sockaddr_stringify_host_remote(&p->sa)); 19946 19947 snprintf(cnonce, sizeof(cnonce), "%08lx", (unsigned long)ast_random()); 19948 19949 /* Check if we have peer credentials */ 19950 ao2_lock(p); 19951 credentials = p->peerauth; 19952 if (credentials) { 19953 ao2_t_ref(credentials, +1, "Ref peer auth for digest"); 19954 } 19955 ao2_unlock(p); 19956 auth = find_realm_authentication(credentials, p->realm); 19957 if (!auth) { 19958 /* If not, check global credentials */ 19959 if (credentials) { 19960 ao2_t_ref(credentials, -1, "Unref peer auth for digest"); 19961 } 19962 ast_mutex_lock(&authl_lock); 19963 credentials = authl; 19964 if (credentials) { 19965 ao2_t_ref(credentials, +1, "Ref global auth for digest"); 19966 } 19967 ast_mutex_unlock(&authl_lock); 19968 auth = find_realm_authentication(credentials, p->realm); 19969 } 19970 19971 if (auth) { 19972 ast_debug(3, "use realm [%s] from peer [%s][%s]\n", auth->username, p->peername, p->username); 19973 username = auth->username; 19974 secret = auth->secret; 19975 md5secret = auth->md5secret; 19976 if (sipdebug) 19977 ast_debug(1, "Using realm %s authentication for call %s\n", p->realm, p->callid); 19978 } else { 19979 /* No authentication, use peer or register= config */ 19980 username = p->authname; 19981 secret = p->relatedpeer 19982 && !ast_strlen_zero(p->relatedpeer->remotesecret) 19983 ? p->relatedpeer->remotesecret : p->peersecret; 19984 md5secret = p->peermd5secret; 19985 } 19986 if (ast_strlen_zero(username)) { 19987 /* We have no authentication */ 19988 if (credentials) { 19989 ao2_t_ref(credentials, -1, "Unref auth for digest"); 19990 } 19991 return -1; 19992 } 19993 19994 /* Calculate SIP digest response */ 19995 snprintf(a1, sizeof(a1), "%s:%s:%s", username, p->realm, secret); 19996 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[method].text, uri); 19997 if (!ast_strlen_zero(md5secret)) 19998 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 19999 else 20000 ast_md5_hash(a1_hash, a1); 20001 ast_md5_hash(a2_hash, a2); 20002 20003 p->noncecount++; 20004 if (!ast_strlen_zero(p->qop)) 20005 snprintf(resp, sizeof(resp), "%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, (unsigned)p->noncecount, cnonce, "auth", a2_hash); 20006 else 20007 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, p->nonce, a2_hash); 20008 ast_md5_hash(resp_hash, resp); 20009 20010 /* only include the opaque string if it's set */ 20011 if (!ast_strlen_zero(p->opaque)) { 20012 snprintf(opaque, sizeof(opaque), ", opaque=\"%s\"", p->opaque); 20013 } 20014 20015 /* XXX We hard code our qop to "auth" for now. XXX */ 20016 if (!ast_strlen_zero(p->qop)) 20017 snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\"%s, qop=auth, cnonce=\"%s\", nc=%08x", username, p->realm, uri, p->nonce, resp_hash, opaque, cnonce, (unsigned)p->noncecount); 20018 else 20019 snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\"%s", username, p->realm, uri, p->nonce, resp_hash, opaque); 20020 20021 append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount); 20022 20023 if (credentials) { 20024 ao2_t_ref(credentials, -1, "Unref auth for digest"); 20025 } 20026 return 0; 20027 }
| static void build_route | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| int | backwards, | |||
| int | resp | |||
| ) | [static] |
Build route list from Record-Route header.
| resp | the SIP response code or 0 for a request |
Definition at line 14699 of file chan_sip.c.
References __get_header(), ast_copy_string(), ast_debug, ast_malloc, ast_strdupa, ast_strlen_zero(), free_old_route(), get_header(), get_in_brackets(), get_in_brackets_const(), len(), list_route(), and sip_debug_test_pvt().
Referenced by handle_request_invite(), handle_request_subscribe(), and handle_response_invite().
14700 { 14701 struct sip_route *thishop, *head, *tail; 14702 int start = 0; 14703 int len; 14704 const char *rr, *c; 14705 14706 /* Once a persistent route is set, don't fool with it */ 14707 if (p->route && p->route_persistent) { 14708 ast_debug(1, "build_route: Retaining previous route: <%s>\n", p->route->hop); 14709 return; 14710 } 14711 14712 if (p->route) { 14713 free_old_route(p->route); 14714 p->route = NULL; 14715 } 14716 14717 /* We only want to create the route set the first time this is called except 14718 it is called from a provisional response.*/ 14719 if ((resp < 100) || (resp > 199)) { 14720 p->route_persistent = 1; 14721 } 14722 14723 /* Build a tailq, then assign it to p->route when done. 14724 * If backwards, we add entries from the head so they end up 14725 * in reverse order. However, we do need to maintain a correct 14726 * tail pointer because the contact is always at the end. 14727 */ 14728 head = NULL; 14729 tail = head; 14730 /* 1st we pass through all the hops in any Record-Route headers */ 14731 for (;;) { 14732 /* Each Record-Route header */ 14733 int len = 0; 14734 const char *uri; 14735 rr = __get_header(req, "Record-Route", &start); 14736 if (*rr == '\0') { 14737 break; 14738 } 14739 while (!get_in_brackets_const(rr, &uri, &len)) { 14740 len++; 14741 rr = strchr(rr, ','); 14742 if(rr >= uri && rr < (uri + len)) { 14743 /* comma inside brackets*/ 14744 const char *next_br = strchr(rr, '<'); 14745 if (next_br && next_br < (uri + len)) { 14746 rr++; 14747 continue; 14748 } 14749 continue; 14750 } 14751 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 14752 ast_copy_string(thishop->hop, uri, len); 14753 ast_debug(2, "build_route: Record-Route hop: <%s>\n", thishop->hop); 14754 /* Link in */ 14755 if (backwards) { 14756 /* Link in at head so they end up in reverse order */ 14757 thishop->next = head; 14758 head = thishop; 14759 /* If this was the first then it'll be the tail */ 14760 if (!tail) { 14761 tail = thishop; 14762 } 14763 } else { 14764 thishop->next = NULL; 14765 /* Link in at the end */ 14766 if (tail) { 14767 tail->next = thishop; 14768 } else { 14769 head = thishop; 14770 } 14771 tail = thishop; 14772 } 14773 } 14774 rr = strchr(uri + len, ','); 14775 if (rr == NULL) { 14776 /* No more field-values, we're done with this header */ 14777 break; 14778 } 14779 /* Advance past comma */ 14780 rr++; 14781 } 14782 } 14783 14784 /* Only append the contact if we are dealing with a strict router */ 14785 if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop, ";lr") == NULL) ) { 14786 /* 2nd append the Contact: if there is one */ 14787 /* Can be multiple Contact headers, comma separated values - we just take the first */ 14788 char *contact = ast_strdupa(get_header(req, "Contact")); 14789 if (!ast_strlen_zero(contact)) { 14790 ast_debug(2, "build_route: Contact hop: %s\n", contact); 14791 /* Look for <: delimited address */ 14792 c = get_in_brackets(contact); 14793 len = strlen(c) + 1; 14794 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 14795 /* ast_calloc is not needed because all fields are initialized in this block */ 14796 ast_copy_string(thishop->hop, c, len); 14797 thishop->next = NULL; 14798 /* Goes at the end */ 14799 if (tail) { 14800 tail->next = thishop; 14801 } else { 14802 head = thishop; 14803 } 14804 } 14805 } 14806 } 14807 14808 /* Store as new route */ 14809 p->route = head; 14810 14811 /* For debugging dump what we ended up with */ 14812 if (sip_debug_test_pvt(p)) { 14813 list_route(p->route); 14814 } 14815 }
| static void build_via | ( | struct sip_pvt * | p | ) | [static] |
Build a Via header for a request.
Definition at line 3559 of file chan_sip.c.
References ast_sockaddr_stringify_remote(), ast_test_flag, and get_transport_pvt().
Referenced by __sip_subscribe_mwi_do(), reqprep(), sip_alloc(), sip_cli_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_invite(), transmit_register(), and transmit_response_using_temp().
03560 { 03561 /* Work around buggy UNIDEN UIP200 firmware */ 03562 const char *rport = (ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT) || ast_test_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT)) ? ";rport" : ""; 03563 03564 /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ 03565 snprintf(p->via, sizeof(p->via), "SIP/2.0/%s %s;branch=z9hG4bK%08x%s", 03566 get_transport_pvt(p), 03567 ast_sockaddr_stringify_remote(&p->ourip), 03568 (unsigned)p->branch, rport); 03569 }
| static int cb_extensionstate | ( | char * | context, | |
| char * | exten, | |||
| int | state, | |||
| void * | data | |||
| ) | [static] |
Callback for the devicestate notification (SUBSCRIBE) support subsystem.
Definition at line 15097 of file chan_sip.c.
References append_history, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_REMOVED, ast_extension_state2str(), ast_set_flag, ast_test_flag, ast_verb, FALSE, NONE, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), and transmit_state_notify().
Referenced by dialog_unlink_all(), handle_request_subscribe(), and handle_response_notify().
15098 { 15099 struct sip_pvt *p = data; 15100 15101 sip_pvt_lock(p); 15102 15103 switch(state) { 15104 case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ 15105 case AST_EXTENSION_REMOVED: /* Extension is gone */ 15106 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); /* Delete subscription in 32 secs */ 15107 ast_verb(2, "Extension state: Watcher for hint %s %s. Notify User %s\n", exten, state == AST_EXTENSION_DEACTIVATED ? "deactivated" : "removed", p->username); 15108 p->subscribed = NONE; 15109 append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated"); 15110 break; 15111 default: /* Tell user */ 15112 p->laststate = state; 15113 break; 15114 } 15115 if (p->subscribed != NONE) { /* Only send state NOTIFY if we know the format */ 15116 if (!p->pendinginvite) { 15117 transmit_state_notify(p, state, 1, FALSE); 15118 } else { 15119 /* We already have a NOTIFY sent that is not answered. Queue the state up. 15120 if many state changes happen meanwhile, we will only send a notification of the last one */ 15121 ast_set_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 15122 } 15123 } 15124 ast_verb(2, "Extension Changed %s[%s] new state %s for Notify User %s %s\n", exten, context, ast_extension_state2str(state), p->username, 15125 ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE) ? "(queued)" : ""); 15126 15127 sip_pvt_unlock(p); 15128 15129 return 0; 15130 }
| static void cb_extensionstate_destroy | ( | int | id, | |
| void * | data | |||
| ) | [static] |
Definition at line 15087 of file chan_sip.c.
Referenced by handle_request_subscribe().
| static void cc_epa_destructor | ( | void * | data | ) | [static] |
Definition at line 880 of file chan_sip.c.
References ast_free.
00881 { 00882 struct sip_epa_entry *epa_entry = data; 00883 struct cc_epa_entry *cc_entry = epa_entry->instance_data; 00884 ast_free(cc_entry); 00885 }
| static void cc_handle_publish_error | ( | struct sip_pvt * | pvt, | |
| const int | resp, | |||
| struct sip_request * | req, | |||
| struct sip_epa_entry * | epa_entry | |||
| ) | [static] |
Definition at line 20556 of file chan_sip.c.
References ao2_callback, ao2_ref, ast_cc_monitor_failed(), ast_log(), ast_strlen_zero(), FALSE, find_sip_monitor_instance_by_suspension_entry(), get_header(), LOG_WARNING, and transmit_invite().
20557 { 20558 struct cc_epa_entry *cc_entry = epa_entry->instance_data; 20559 struct sip_monitor_instance *monitor_instance = ao2_callback(sip_monitor_instances, 0, 20560 find_sip_monitor_instance_by_suspension_entry, epa_entry); 20561 const char *min_expires; 20562 20563 if (!monitor_instance) { 20564 ast_log(LOG_WARNING, "Can't find monitor_instance corresponding to epa_entry %p.\n", epa_entry); 20565 return; 20566 } 20567 20568 if (resp != 423) { 20569 ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->device_name, 20570 "Received error response to our PUBLISH"); 20571 ao2_ref(monitor_instance, -1); 20572 return; 20573 } 20574 20575 /* Allrighty, the other end doesn't like our Expires value. They think it's 20576 * too small, so let's see if they've provided a more sensible value. If they 20577 * haven't, then we'll just double our Expires value and see if they like that 20578 * instead. 20579 * 20580 * XXX Ideally this logic could be placed into its own function so that SUBSCRIBE, 20581 * PUBLISH, and REGISTER could all benefit from the same shared code. 20582 */ 20583 min_expires = get_header(req, "Min-Expires"); 20584 if (ast_strlen_zero(min_expires)) { 20585 pvt->expiry *= 2; 20586 if (pvt->expiry < 0) { 20587 /* You dork! You overflowed! */ 20588 ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->device_name, 20589 "PUBLISH expiry overflowed"); 20590 ao2_ref(monitor_instance, -1); 20591 return; 20592 } 20593 } else if (sscanf(min_expires, "%d", &pvt->expiry) != 1) { 20594 ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->device_name, 20595 "Min-Expires has non-numeric value"); 20596 ao2_ref(monitor_instance, -1); 20597 return; 20598 } 20599 /* At this point, we have most certainly changed pvt->expiry, so try transmitting 20600 * again 20601 */ 20602 transmit_invite(pvt, SIP_PUBLISH, FALSE, 0, NULL); 20603 ao2_ref(monitor_instance, -1); 20604 }
| static void change_callid_pvt | ( | struct sip_pvt * | pvt, | |
| const char * | callid | |||
| ) | [static] |
Definition at line 7898 of file chan_sip.c.
References ao2_lock, ao2_t_link, ao2_unlock, ast_debug, ast_strdupa, ast_string_field_set, build_callid_pvt(), and CONTAINER_UNLINK.
Referenced by __sip_subscribe_mwi_do(), create_addr_from_peer(), sip_cli_notify(), sip_poke_peer(), sip_request_call(), and sip_send_mwi_to_peer().
07899 { 07900 int in_dialog_container; 07901 char *oldid = ast_strdupa(pvt->callid); 07902 07903 ao2_lock(dialogs); 07904 in_dialog_container = CONTAINER_UNLINK(dialogs, pvt, 07905 "About to change the callid -- remove the old name"); 07906 if (callid) { 07907 ast_string_field_set(pvt, callid, callid); 07908 } else { 07909 build_callid_pvt(pvt); 07910 } 07911 if (in_dialog_container) { 07912 ao2_t_link(dialogs, pvt, "New dialog callid -- inserted back into table"); 07913 } 07914 ao2_unlock(dialogs); 07915 07916 if (strcmp(oldid, pvt->callid)) { 07917 ast_debug(1, "SIP call-id changed from '%s' to '%s'\n", oldid, pvt->callid); 07918 } 07919 }
| static void change_hold_state | ( | struct sip_pvt * | dialog, | |
| struct sip_request * | req, | |||
| int | holdstate, | |||
| int | sendonly | |||
| ) | [static] |
Change hold state for a call.
Definition at line 8987 of file chan_sip.c.
References append_history, ast_clear_flag, ast_set_flag, ast_str_buffer(), ast_test_flag, EVENT_FLAG_CALL, manager_event, sip_cfg, and sip_peer_hold().
Referenced by handle_request_invite(), and process_sdp().
08988 { 08989 if (sip_cfg.notifyhold && (!holdstate || !ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD))) 08990 sip_peer_hold(dialog, holdstate); 08991 if (sip_cfg.callevents) 08992 manager_event(EVENT_FLAG_CALL, "Hold", 08993 "Status: %s\r\n" 08994 "Channel: %s\r\n" 08995 "Uniqueid: %s\r\n", 08996 holdstate ? "On" : "Off", 08997 dialog->owner->name, 08998 dialog->owner->uniqueid); 08999 append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", ast_str_buffer(req->data)); 09000 if (!holdstate) { /* Put off remote hold */ 09001 ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */ 09002 return; 09003 } 09004 /* No address for RTP, we're on hold */ 09005 09006 /* Ensure hold flags are cleared so that overlapping flags do not conflict */ 09007 ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD); 09008 09009 if (sendonly == 1) /* One directional hold (sendonly/recvonly) */ 09010 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR); 09011 else if (sendonly == 2) /* Inactive stream */ 09012 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE); 09013 else 09014 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE); 09015 return; 09016 }
| static void change_redirecting_information | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| struct ast_party_redirecting * | redirecting, | |||
| struct ast_set_party_redirecting * | update_redirecting, | |||
| int | set_call_forward | |||
| ) | [static] |
update redirecting information for a channel based on headers
Definition at line 20285 of file chan_sip.c.
References ast_debug, ast_free, AST_REDIRECTING_REASON_UNCONDITIONAL, ast_strdup, ast_strlen_zero(), ast_party_redirecting::from, ast_set_party_redirecting::from, get_header(), get_name_and_number(), get_rdnis(), ast_party_id::name, ast_set_party_id::name, ast_party_id::number, ast_set_party_id::number, parse_moved_contact(), ast_party_redirecting::reason, ast_party_name::str, ast_party_number::str, ast_party_id::tag, ast_set_party_redirecting::to, ast_party_redirecting::to, ast_party_name::valid, and ast_party_number::valid.
Referenced by handle_request_invite(), handle_response(), and handle_response_invite().
20288 { 20289 char *redirecting_from_name = NULL; 20290 char *redirecting_from_number = NULL; 20291 char *redirecting_to_name = NULL; 20292 char *redirecting_to_number = NULL; 20293 int reason = AST_REDIRECTING_REASON_UNCONDITIONAL; 20294 int is_response = req->method == SIP_RESPONSE; 20295 int res = 0; 20296 20297 res = get_rdnis(p, req, &redirecting_from_name, &redirecting_from_number, &reason); 20298 if (res == -1) { 20299 if (is_response) { 20300 get_name_and_number(get_header(req, "TO"), &redirecting_from_name, &redirecting_from_number); 20301 } else { 20302 return; 20303 } 20304 } 20305 20306 /* At this point, all redirecting "from" info should be filled in appropriately 20307 * on to the "to" info 20308 */ 20309 20310 if (is_response) { 20311 parse_moved_contact(p, req, &redirecting_to_name, &redirecting_to_number, set_call_forward); 20312 } else { 20313 get_name_and_number(get_header(req, "TO"), &redirecting_to_name, &redirecting_to_number); 20314 } 20315 20316 if (!ast_strlen_zero(redirecting_from_number)) { 20317 ast_debug(3, "Got redirecting from number %s\n", redirecting_from_number); 20318 update_redirecting->from.number = 1; 20319 redirecting->from.number.valid = 1; 20320 ast_free(redirecting->from.number.str); 20321 redirecting->from.number.str = redirecting_from_number; 20322 } 20323 if (!ast_strlen_zero(redirecting_from_name)) { 20324 ast_debug(3, "Got redirecting from name %s\n", redirecting_from_name); 20325 update_redirecting->from.name = 1; 20326 redirecting->from.name.valid = 1; 20327 ast_free(redirecting->from.name.str); 20328 redirecting->from.name.str = redirecting_from_name; 20329 } 20330 if (!ast_strlen_zero(p->cid_tag)) { 20331 ast_free(redirecting->from.tag); 20332 redirecting->from.tag = ast_strdup(p->cid_tag); 20333 ast_free(redirecting->to.tag); 20334 redirecting->to.tag = ast_strdup(p->cid_tag); 20335 } 20336 if (!ast_strlen_zero(redirecting_to_number)) { 20337 ast_debug(3, "Got redirecting to number %s\n", redirecting_to_number); 20338 update_redirecting->to.number = 1; 20339 redirecting->to.number.valid = 1; 20340 ast_free(redirecting->to.number.str); 20341 redirecting->to.number.str = redirecting_to_number; 20342 } 20343 if (!ast_strlen_zero(redirecting_to_name)) { 20344 ast_debug(3, "Got redirecting to name %s\n", redirecting_from_number); 20345 update_redirecting->to.name = 1; 20346 redirecting->to.name.valid = 1; 20347 ast_free(redirecting->to.name.str); 20348 redirecting->to.name.str = redirecting_to_name; 20349 } 20350 redirecting->reason = reason; 20351 }
| static void change_t38_state | ( | struct sip_pvt * | p, | |
| int | state | |||
| ) | [static] |
Change the T38 state on a SIP dialog.
Definition at line 5337 of file chan_sip.c.
References AST_CONTROL_T38_PARAMETERS, ast_debug, ast_queue_control_data(), AST_T38_NEGOTIATED, AST_T38_REFUSED, AST_T38_REQUEST_NEGOTIATE, AST_T38_TERMINATED, ast_udptl_get_far_max_ifp(), ast_udptl_set_tag(), ast_control_t38_parameters::max_ifp, and ast_control_t38_parameters::request_response.
Referenced by handle_response_invite(), interpret_t38_parameters(), process_sdp(), and sip_t38_abort().
05338 { 05339 int old = p->t38.state; 05340 struct ast_channel *chan = p->owner; 05341 struct ast_control_t38_parameters parameters = { .request_response = 0 }; 05342 05343 /* Don't bother changing if we are already in the state wanted */ 05344 if (old == state) 05345 return; 05346 05347 p->t38.state = state; 05348 ast_debug(2, "T38 state changed to %u on channel %s\n", p->t38.state, chan ? chan->name : "<none>"); 05349 05350 /* If no channel was provided we can't send off a control frame */ 05351 if (!chan) 05352 return; 05353 05354 /* Given the state requested and old state determine what control frame we want to queue up */ 05355 switch (state) { 05356 case T38_PEER_REINVITE: 05357 parameters = p->t38.their_parms; 05358 parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl); 05359 parameters.request_response = AST_T38_REQUEST_NEGOTIATE; 05360 ast_udptl_set_tag(p->udptl, "%s", chan->name); 05361 break; 05362 case T38_ENABLED: 05363 parameters = p->t38.their_parms; 05364 parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl); 05365 parameters.request_response = AST_T38_NEGOTIATED; 05366 ast_udptl_set_tag(p->udptl, "%s", chan->name); 05367 break; 05368 case T38_DISABLED: 05369 if (old == T38_ENABLED) { 05370 parameters.request_response = AST_T38_TERMINATED; 05371 } else if (old == T38_LOCAL_REINVITE) { 05372 parameters.request_response = AST_T38_REFUSED; 05373 } 05374 break; 05375 case T38_LOCAL_REINVITE: 05376 /* wait until we get a peer response before responding to local reinvite */ 05377 break; 05378 } 05379 05380 /* Woot we got a message, create a control frame and send it on! */ 05381 if (parameters.request_response) 05382 ast_queue_control_data(chan, AST_CONTROL_T38_PARAMETERS, ¶meters, sizeof(parameters)); 05383 }
| static enum check_auth_result check_auth | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| const char * | username, | |||
| const char * | secret, | |||
| const char * | md5secret, | |||
| int | sipmethod, | |||
| const char * | uri, | |||
| enum xmittype | reliable, | |||
| int | ignore | |||
| ) | [static] |
Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set).
XXX
XXX
Definition at line 14839 of file chan_sip.c.
References append_history, ast_copy_string(), AST_DYNSTR_BUILD_FAILED, ast_log(), ast_md5_hash(), ast_skip_blanks(), ast_str_set(), ast_str_thread_get(), ast_strlen_zero(), auth_headers(), BOGUS_PEER_MD5SECRET, CHECK_AUTH_BUF_INITLEN, FALSE, get_header(), LOG_NOTICE, LOG_WARNING, S_OR, set_nonce_randdata(), sip_methods, sip_scheddestroy(), text, transmit_response_with_auth(), and TRUE.
Referenced by check_peer_ok(), and register_verify().
14842 { 14843 const char *response; 14844 char *reqheader, *respheader; 14845 const char *authtoken; 14846 char a1_hash[256]; 14847 char resp_hash[256]=""; 14848 char *c; 14849 int is_bogus_peer = 0; 14850 int wrongnonce = FALSE; 14851 int good_response; 14852 const char *usednonce = p->randdata; 14853 struct ast_str *buf; 14854 int res; 14855 14856 /* table of recognised keywords, and their value in the digest */ 14857 enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST }; 14858 struct x { 14859 const char *key; 14860 const char *s; 14861 } *i, keys[] = { 14862 [K_RESP] = { "response=", "" }, 14863 [K_URI] = { "uri=", "" }, 14864 [K_USER] = { "username=", "" }, 14865 [K_NONCE] = { "nonce=", "" }, 14866 [K_LAST] = { NULL, NULL} 14867 }; 14868 14869 /* Always OK if no secret */ 14870 if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret)) 14871 return AUTH_SUCCESSFUL; 14872 14873 /* Always auth with WWW-auth since we're NOT a proxy */ 14874 /* Using proxy-auth in a B2BUA may block proxy authorization in the same transaction */ 14875 response = "401 Unauthorized"; 14876 14877 /* 14878 * Note the apparent swap of arguments below, compared to other 14879 * usages of auth_headers(). 14880 */ 14881 auth_headers(WWW_AUTH, &respheader, &reqheader); 14882 14883 authtoken = get_header(req, reqheader); 14884 if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 14885 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 14886 information */ 14887 if (!reliable) { 14888 /* Resend message if this was NOT a reliable delivery. Otherwise the 14889 retransmission should get it */ 14890 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 14891 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 14892 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14893 } 14894 return AUTH_CHALLENGE_SENT; 14895 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 14896 /* We have no auth, so issue challenge and request authentication */ 14897 set_nonce_randdata(p, 1); /* Create nonce for challenge */ 14898 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 14899 /* Schedule auto destroy in 32 seconds */ 14900 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14901 return AUTH_CHALLENGE_SENT; 14902 } 14903 14904 /* --- We have auth, so check it */ 14905 14906 /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting 14907 an example in the spec of just what it is you're doing a hash on. */ 14908 14909 if (!(buf = ast_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) { 14910 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 14911 } 14912 14913 /* Make a copy of the response and parse it */ 14914 res = ast_str_set(&buf, 0, "%s", authtoken); 14915 14916 if (res == AST_DYNSTR_BUILD_FAILED) { 14917 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 14918 } 14919 14920 c = buf->str; 14921 14922 while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */ 14923 for (i = keys; i->key != NULL; i++) { 14924 const char *separator = ","; /* default */ 14925 14926 if (strncasecmp(c, i->key, strlen(i->key)) != 0) { 14927 continue; 14928 } 14929 /* Found. Skip keyword, take text in quotes or up to the separator. */ 14930 c += strlen(i->key); 14931 if (*c == '"') { /* in quotes. Skip first and look for last */ 14932 c++; 14933 separator = "\""; 14934 } 14935 i->s = c; 14936 strsep(&c, separator); 14937 break; 14938 } 14939 if (i->key == NULL) { /* not found, jump after space or comma */ 14940 strsep(&c, " ,"); 14941 } 14942 } 14943 14944 /* We cannot rely on the bogus_peer having a bad md5 value. Someone could 14945 * use it to construct valid auth. */ 14946 if (md5secret && strcmp(md5secret, BOGUS_PEER_MD5SECRET) == 0) { 14947 is_bogus_peer = 1; 14948 } 14949 14950 /* Verify that digest username matches the username we auth as */ 14951 if (strcmp(username, keys[K_USER].s) && !is_bogus_peer) { 14952 ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n", 14953 username, keys[K_USER].s); 14954 /* Oops, we're trying something here */ 14955 return AUTH_USERNAME_MISMATCH; 14956 } 14957 14958 /* Verify nonce from request matches our nonce, and the nonce has not already been responded to. 14959 * If this check fails, send 401 with new nonce */ 14960 if (strcasecmp(p->randdata, keys[K_NONCE].s) || p->stalenonce) { /* XXX it was 'n'casecmp ? */ 14961 wrongnonce = TRUE; 14962 usednonce = keys[K_NONCE].s; 14963 } else { 14964 p->stalenonce = 1; /* now, since the nonce has a response, mark it as stale so it can't be sent or responded to again */ 14965 } 14966 14967 if (!ast_strlen_zero(md5secret)) { 14968 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 14969 } else { 14970 char a1[256]; 14971 14972 snprintf(a1, sizeof(a1), "%s:%s:%s", username, p->realm, secret); 14973 ast_md5_hash(a1_hash, a1); 14974 } 14975 14976 /* compute the expected response to compare with what we received */ 14977 { 14978 char a2[256]; 14979 char a2_hash[256]; 14980 char resp[256]; 14981 14982 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, 14983 S_OR(keys[K_URI].s, uri)); 14984 ast_md5_hash(a2_hash, a2); 14985 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash); 14986 ast_md5_hash(resp_hash, resp); 14987 } 14988 14989 good_response = keys[K_RESP].s && 14990 !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash)) && 14991 !is_bogus_peer; /* lastly, check that the peer isn't the fake peer */ 14992 if (wrongnonce) { 14993 if (good_response) { 14994 if (sipdebug) 14995 ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "From")); 14996 /* We got working auth token, based on stale nonce . */ 14997 set_nonce_randdata(p, 0); 14998 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE); 14999 } else { 15000 /* Everything was wrong, so give the device one more try with a new challenge */ 15001 if (!req->ignore) { 15002 if (sipdebug) { 15003 ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To")); 15004 } 15005 set_nonce_randdata(p, 1); 15006 } else { 15007 if (sipdebug) { 15008 ast_log(LOG_NOTICE, "Duplicate authentication received from '%s'\n", get_header(req, "To")); 15009 } 15010 } 15011 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 15012 } 15013 15014 /* Schedule auto destroy in 32 seconds */ 15015 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15016 return AUTH_CHALLENGE_SENT; 15017 } 15018 if (good_response) { 15019 append_history(p, "AuthOK", "Auth challenge successful for %s", username); 15020 return AUTH_SUCCESSFUL; 15021 } 15022 15023 /* Ok, we have a bad username/secret pair */ 15024 /* Tell the UAS not to re-send this authentication data, because 15025 it will continue to fail 15026 */ 15027 15028 return AUTH_SECRET_FAILED; 15029 }
| static enum message_integrity check_message_integrity | ( | struct ast_str ** | request, | |
| struct ast_str ** | overflow | |||
| ) | [static] |
Check that a message received over TCP is a full message.
This will take the information read in and then determine if 1) The message is a full SIP request 2) The message is a partial SIP request 3) The message contains a full SIP request along with another partial request
| data | The unparsed incoming SIP message. | |
| request | The resulting request with extra fragments removed. | |
| overflow | If the message contains more than a full request, this is the remainder of the message |
Definition at line 2592 of file chan_sip.c.
References ast_str_append(), ast_str_buffer(), ast_str_strlen(), ast_str_truncate(), MESSAGE_COMPLETE, MESSAGE_FRAGMENT, MESSAGE_FRAGMENT_COMPLETE, MESSAGE_INVALID, and read_raw_content_length().
Referenced by sip_tcptls_read().
02593 { 02594 char *message = ast_str_buffer(*request); 02595 char *body; 02596 int content_length; 02597 int message_len = ast_str_strlen(*request); 02598 int body_len; 02599 02600 /* Important pieces to search for in a SIP request are \r\n\r\n. This 02601 * marks either 02602 * 1) The division between the headers and body 02603 * 2) The end of the SIP request 02604 */ 02605 body = strstr(message, "\r\n\r\n"); 02606 if (!body) { 02607 /* This is clearly a partial message since we haven't reached an end 02608 * yet. 02609 */ 02610 return MESSAGE_FRAGMENT; 02611 } 02612 body += sizeof("\r\n\r\n") - 1; 02613 body_len = message_len - (body - message); 02614 02615 body[-1] = '\0'; 02616 content_length = read_raw_content_length(message); 02617 body[-1] = '\n'; 02618 02619 if (content_length < 0) { 02620 return MESSAGE_INVALID; 02621 } else if (content_length == 0) { 02622 /* We've definitely received an entire message. We need 02623 * to check if there's also a fragment of another message 02624 * in addition. 02625 */ 02626 if (body_len == 0) { 02627 return MESSAGE_COMPLETE; 02628 } else { 02629 ast_str_append(overflow, 0, "%s", body); 02630 ast_str_truncate(*request, message_len - body_len); 02631 return MESSAGE_FRAGMENT_COMPLETE; 02632 } 02633 } 02634 /* Positive content length. Let's see what sort of 02635 * message body we're dealing with. 02636 */ 02637 if (body_len < content_length) { 02638 /* We don't have the full message body yet */ 02639 return MESSAGE_FRAGMENT; 02640 } else if (body_len > content_length) { 02641 /* We have the full message plus a fragment of a further 02642 * message 02643 */ 02644 ast_str_append(overflow, 0, "%s", body + content_length); 02645 ast_str_truncate(*request, message_len - (body_len - content_length)); 02646 return MESSAGE_FRAGMENT_COMPLETE; 02647 } else { 02648 /* Yay! Full message with no extra content */ 02649 return MESSAGE_COMPLETE; 02650 } 02651 }
| static enum check_auth_result check_peer_ok | ( | struct sip_pvt * | p, | |
| char * | of, | |||
| struct sip_request * | req, | |||
| int | sipmethod, | |||
| struct ast_sockaddr * | addr, | |||
| struct sip_peer ** | authpeer, | |||
| enum xmittype | reliable, | |||
| char * | calleridname, | |||
| char * | uri2 | |||
| ) | [static] |
Validate device authentication.
Definition at line 16511 of file chan_sip.c.
References accountcode, ao2_t_ref, ast_apply_ha(), ast_cc_copy_config_params(), ast_copy_flags, ast_debug, ast_is_shrinkable_phonenumber(), ast_rtp_codecs_packetization_set(), AST_RTP_DTMF, ast_rtp_instance_get_codecs(), ast_set_flag, ast_shrink_phone_number(), ast_sockaddr_stringify(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_variables_destroy(), ast_verbose, check_auth(), cid_name, cid_num, context, copy_vars(), dialog_initialize_rtp(), do_setnat(), FALSE, find_peer(), get_rpid(), language, mohinterpret, mohsuggest, parkinglot, ref_peer(), set_pvt_allowed_methods(), set_t38_capabilities(), sip_cfg, sip_debug_test_addr(), TRUE, and unref_peer().
Referenced by check_user_full().
16515 { 16516 enum check_auth_result res; 16517 int debug = sip_debug_test_addr(addr); 16518 struct sip_peer *peer; 16519 16520 if (sipmethod == SIP_SUBSCRIBE) { 16521 /* For subscribes, match on device name only; for other methods, 16522 * match on IP address-port of the incoming request. 16523 */ 16524 peer = find_peer(of, NULL, TRUE, FINDALLDEVICES, FALSE, 0); 16525 } else { 16526 /* First find devices based on username (avoid all type=peer's) */ 16527 peer = find_peer(of, NULL, TRUE, FINDUSERS, FALSE, 0); 16528 16529 /* Then find devices based on IP */ 16530 if (!peer) { 16531 peer = find_peer(NULL, &p->recv, TRUE, FINDPEERS, FALSE, p->socket.type); 16532 } 16533 } 16534 16535 if (!peer) { 16536 if (debug) { 16537 ast_verbose("No matching peer for '%s' from '%s'\n", 16538 of, ast_sockaddr_stringify(&p->recv)); 16539 } 16540 16541 /* If you don't mind, we can return 404s for devices that do 16542 * not exist: username disclosure. If we allow guests, there 16543 * is no way around that. */ 16544 if (sip_cfg.allowguest || !sip_cfg.alwaysauthreject) { 16545 return AUTH_DONT_KNOW; 16546 } 16547 16548 /* If you do mind, we use a peer that will never authenticate. 16549 * This ensures that we follow the same code path as regular 16550 * auth: less chance for username disclosure. */ 16551 peer = bogus_peer; 16552 ref_peer(peer, "ref_peer: check_peer_ok: must ref bogus_peer so unreffing it does not fail"); 16553 } 16554 16555 if (!ast_apply_ha(peer->ha, addr)) { 16556 ast_debug(2, "Found peer '%s' for '%s', but fails host access\n", peer->name, of); 16557 unref_peer(peer, "unref_peer: check_peer_ok: from find_peer call, early return of AUTH_ACL_FAILED"); 16558 return AUTH_ACL_FAILED; 16559 } 16560 if (debug && peer != bogus_peer) { 16561 ast_verbose("Found peer '%s' for '%s' from %s\n", 16562 peer->name, of, ast_sockaddr_stringify(&p->recv)); 16563 } 16564 16565 /* XXX what about p->prefs = peer->prefs; ? */ 16566 /* Set Frame packetization */ 16567 if (p->rtp) { 16568 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &peer->prefs); 16569 p->autoframing = peer->autoframing; 16570 } 16571 16572 /* Take the peer */ 16573 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 16574 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 16575 ast_copy_flags(&p->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY); 16576 16577 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) && p->udptl) { 16578 p->t38_maxdatagram = peer->t38_maxdatagram; 16579 set_t38_capabilities(p); 16580 } 16581 16582 /* Copy SIP extensions profile to peer */ 16583 /* XXX is this correct before a successful auth ? */ 16584 if (p->sipoptions) 16585 peer->sipoptions = p->sipoptions; 16586 16587 do_setnat(p); 16588 16589 ast_string_field_set(p, peersecret, peer->secret); 16590 ast_string_field_set(p, peermd5secret, peer->md5secret); 16591 ast_string_field_set(p, subscribecontext, peer->subscribecontext); 16592 ast_string_field_set(p, mohinterpret, peer->mohinterpret); 16593 ast_string_field_set(p, mohsuggest, peer->mohsuggest); 16594 if (!ast_strlen_zero(peer->parkinglot)) { 16595 ast_string_field_set(p, parkinglot, peer->parkinglot); 16596 } 16597 ast_string_field_set(p, engine, peer->engine); 16598 p->disallowed_methods = peer->disallowed_methods; 16599 set_pvt_allowed_methods(p, req); 16600 ast_cc_copy_config_params(p->cc_params, peer->cc_params); 16601 if (peer->callingpres) /* Peer calling pres setting will override RPID */ 16602 p->callingpres = peer->callingpres; 16603 if (peer->maxms && peer->lastms) 16604 p->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 16605 else 16606 p->timer_t1 = peer->timer_t1; 16607 16608 /* Set timer B to control transaction timeouts */ 16609 if (peer->timer_b) 16610 p->timer_b = peer->timer_b; 16611 else 16612 p->timer_b = 64 * p->timer_t1; 16613 16614 p->allowtransfer = peer->allowtransfer; 16615 16616 if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) { 16617 /* Pretend there is no required authentication */ 16618 ast_string_field_set(p, peersecret, NULL); 16619 ast_string_field_set(p, peermd5secret, NULL); 16620 } 16621 if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, req->ignore))) { 16622 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 16623 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 16624 ast_copy_flags(&p->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY); 16625 /* If we have a call limit, set flag */ 16626 if (peer->call_limit) 16627 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 16628 ast_string_field_set(p, peername, peer->name); 16629 ast_string_field_set(p, authname, peer->name); 16630 16631 if (sipmethod == SIP_INVITE) { 16632 /* destroy old channel vars and copy in new ones. */ 16633 ast_variables_destroy(p->chanvars); 16634 p->chanvars = copy_vars(peer->chanvars); 16635 } 16636 16637 if (authpeer) { 16638 ao2_t_ref(peer, 1, "copy pointer into (*authpeer)"); 16639 (*authpeer) = peer; /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */ 16640 } 16641 16642 if (!ast_strlen_zero(peer->username)) { 16643 ast_string_field_set(p, username, peer->username); 16644 /* Use the default username for authentication on outbound calls */ 16645 /* XXX this takes the name from the caller... can we override ? */ 16646 ast_string_field_set(p, authname, peer->username); 16647 } 16648 if (!get_rpid(p, req)) { 16649 if (!ast_strlen_zero(peer->cid_num)) { 16650 char *tmp = ast_strdupa(peer->cid_num); 16651 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) 16652 ast_shrink_phone_number(tmp); 16653 ast_string_field_set(p, cid_num, tmp); 16654 } 16655 if (!ast_strlen_zero(peer->cid_name)) 16656 ast_string_field_set(p, cid_name, peer->cid_name); 16657 if (peer->callingpres) 16658 p->callingpres = peer->callingpres; 16659 } 16660 if (!ast_strlen_zero(peer->cid_tag)) { 16661 ast_string_field_set(p, cid_tag, peer->cid_tag); 16662 } 16663 ast_string_field_set(p, fullcontact, peer->fullcontact); 16664 16665 if (!ast_strlen_zero(peer->context)) { 16666 ast_string_field_set(p, context, peer->context); 16667 } 16668 if (!ast_strlen_zero(peer->mwi_from)) { 16669 ast_string_field_set(p, mwi_from, peer->mwi_from); 16670 } 16671 16672 ast_string_field_set(p, peersecret, peer->secret); 16673 ast_string_field_set(p, peermd5secret, peer->md5secret); 16674 ast_string_field_set(p, language, peer->language); 16675 ast_string_field_set(p, accountcode, peer->accountcode); 16676 p->amaflags = peer->amaflags; 16677 p->callgroup = peer->callgroup; 16678 p->pickupgroup = peer->pickupgroup; 16679 p->capability = peer->capability; 16680 p->prefs = peer->prefs; 16681 p->jointcapability = peer->capability; 16682 if (peer->maxforwards > 0) { 16683 p->maxforwards = peer->maxforwards; 16684 } 16685 if (p->peercapability) 16686 p->jointcapability &= p->peercapability; 16687 p->maxcallbitrate = peer->maxcallbitrate; 16688 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 16689 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 16690 p->noncodeccapability |= AST_RTP_DTMF; 16691 else 16692 p->noncodeccapability &= ~AST_RTP_DTMF; 16693 p->jointnoncodeccapability = p->noncodeccapability; 16694 p->rtptimeout = peer->rtptimeout; 16695 p->rtpholdtimeout = peer->rtpholdtimeout; 16696 p->rtpkeepalive = peer->rtpkeepalive; 16697 if (!dialog_initialize_rtp(p)) { 16698 if (p->rtp) { 16699 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &peer->prefs); 16700 p->autoframing = peer->autoframing; 16701 } 16702 } else { 16703 res = AUTH_RTP_FAILED; 16704 } 16705 } 16706 unref_peer(peer, "check_peer_ok: unref_peer: tossing temp ptr to peer from find_peer"); 16707 return res; 16708 }
| static void check_pendings | ( | struct sip_pvt * | p | ) | [static] |
Check pending actions on SIP call.
Definition at line 20471 of file chan_sip.c.
References ast_clear_flag, ast_debug, AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), ast_test_flag, FALSE, sip_scheddestroy(), transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), and TRUE.
Referenced by handle_incoming(), handle_response_invite(), reinvite_timeout(), retrans_pkt(), and sip_reinvite_retry().
20472 { 20473 if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 20474 if (p->reinviteid > -1) { 20475 /* Outstanding p->reinviteid timeout, so wait... */ 20476 return; 20477 } else if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) { 20478 /* if we can't BYE, then this is really a pending CANCEL */ 20479 p->invitestate = INV_CANCELLED; 20480 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 20481 /* If the cancel occurred on an initial invite, cancel the pending BYE */ 20482 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) { 20483 ast_clear_flag(&p->flags[0], SIP_PENDINGBYE); 20484 } 20485 /* Actually don't destroy us yet, wait for the 487 on our original 20486 INVITE, but do set an autodestruct just in case we never get it. */ 20487 } else { 20488 /* We have a pending outbound invite, don't send something 20489 * new in-transaction, unless it is a pending reinvite, then 20490 * by the time we are called here, we should probably just hang up. */ 20491 if (p->pendinginvite && !p->ongoing_reinvite) 20492 return; 20493 20494 if (p->owner) { 20495 ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV); 20496 } 20497 /* Perhaps there is an SD change INVITE outstanding */ 20498 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE); 20499 ast_clear_flag(&p->flags[0], SIP_PENDINGBYE); 20500 } 20501 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 20502 } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) { 20503 /* if we can't REINVITE, hold it for later */ 20504 if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) { 20505 ast_debug(2, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid); 20506 } else { 20507 ast_debug(2, "Sending pending reinvite on '%s'\n", p->callid); 20508 /* Didn't get to reinvite yet, so do it now */ 20509 transmit_reinvite_with_sdp(p, (p->t38.state == T38_LOCAL_REINVITE ? TRUE : FALSE), FALSE); 20510 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 20511 } 20512 } 20513 }
| static void check_rtp_timeout | ( | struct sip_pvt * | dialog, | |
| time_t | t | |||
| ) | [static] |
helper function for the monitoring thread -- seems to be called with the assumption that the dialog is locked
Do we need to move the lastrtptx to the RTP structure to have one for audio and one for video? It really does belong to the RTP structure.
Definition at line 26568 of file chan_sip.c.
References ast_channel_trylock, ast_channel_unlock, ast_log(), ast_rtp_instance_get_hold_timeout(), ast_rtp_instance_get_keepalive(), ast_rtp_instance_get_timeout(), ast_rtp_instance_sendcng(), ast_rtp_instance_set_hold_timeout(), ast_rtp_instance_set_timeout(), ast_sockaddr_isnull(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, ast_test_flag, and LOG_NOTICE.
Referenced by dialog_needdestroy().
26569 { 26570 /* If we have no RTP or no active owner, no need to check timers */ 26571 if (!dialog->rtp || !dialog->owner) 26572 return; 26573 /* If the call is not in UP state or redirected outside Asterisk, no need to check timers */ 26574 26575 if (dialog->owner->_state != AST_STATE_UP || !ast_sockaddr_isnull(&dialog->redirip)) 26576 return; 26577 26578 /* If the call is involved in a T38 fax session do not check RTP timeout */ 26579 if (dialog->t38.state == T38_ENABLED) 26580 return; 26581 26582 /* If we have no timers set, return now */ 26583 if (!ast_rtp_instance_get_keepalive(dialog->rtp) && !ast_rtp_instance_get_timeout(dialog->rtp) && !ast_rtp_instance_get_hold_timeout(dialog->rtp)) { 26584 return; 26585 } 26586 26587 /* Check AUDIO RTP keepalives */ 26588 if (dialog->lastrtptx && ast_rtp_instance_get_keepalive(dialog->rtp) && 26589 (t > dialog->lastrtptx + ast_rtp_instance_get_keepalive(dialog->rtp))) { 26590 /* Need to send an empty RTP packet */ 26591 dialog->lastrtptx = time(NULL); 26592 ast_rtp_instance_sendcng(dialog->rtp, 0); 26593 } 26594 26595 /*! \todo Check video RTP keepalives 26596 26597 Do we need to move the lastrtptx to the RTP structure to have one for audio and one 26598 for video? It really does belong to the RTP structure. 26599 */ 26600 26601 /* Check AUDIO RTP timers */ 26602 if (dialog->lastrtprx && (ast_rtp_instance_get_timeout(dialog->rtp) || ast_rtp_instance_get_hold_timeout(dialog->rtp)) && (t > dialog->lastrtprx + ast_rtp_instance_get_timeout(dialog->rtp))) { 26603 if (!ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD) || (ast_rtp_instance_get_hold_timeout(dialog->rtp) && (t > dialog->lastrtprx + ast_rtp_instance_get_hold_timeout(dialog->rtp)))) { 26604 /* Needs a hangup */ 26605 if (ast_rtp_instance_get_timeout(dialog->rtp)) { 26606 if (!dialog->owner || ast_channel_trylock(dialog->owner)) { 26607 /* 26608 * Don't block, just try again later. 26609 * If there was no owner, the call is dead already. 26610 */ 26611 return; 26612 } 26613 ast_log(LOG_NOTICE, "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", 26614 dialog->owner->name, (long) (t - dialog->lastrtprx)); 26615 /* Issue a softhangup */ 26616 ast_softhangup_nolock(dialog->owner, AST_SOFTHANGUP_DEV); 26617 ast_channel_unlock(dialog->owner); 26618 /* forget the timeouts for this call, since a hangup 26619 has already been requested and we don't want to 26620 repeatedly request hangups 26621 */ 26622 ast_rtp_instance_set_timeout(dialog->rtp, 0); 26623 ast_rtp_instance_set_hold_timeout(dialog->rtp, 0); 26624 if (dialog->vrtp) { 26625 ast_rtp_instance_set_timeout(dialog->vrtp, 0); 26626 ast_rtp_instance_set_hold_timeout(dialog->vrtp, 0); 26627 } 26628 } 26629 } 26630 } 26631 }
| static int check_sip_domain | ( | const char * | domain, | |
| char * | context, | |||
| size_t | len | |||
| ) | [static] |
check_sip_domain: Check if domain part of uri is local to our server
Definition at line 27781 of file chan_sip.c.
References ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_strlen_zero().
Referenced by func_check_sipdomain(), get_destination(), get_realm(), handle_request_refer(), and register_verify().
27782 { 27783 struct domain *d; 27784 int result = 0; 27785 27786 AST_LIST_LOCK(&domain_list); 27787 AST_LIST_TRAVERSE(&domain_list, d, list) { 27788 if (strcasecmp(d->domain, domain)) { 27789 continue; 27790 } 27791 27792 if (len && !ast_strlen_zero(d->context)) 27793 ast_copy_string(context, d->context, len); 27794 27795 result = 1; 27796 break; 27797 } 27798 AST_LIST_UNLOCK(&domain_list); 27799 27800 return result; 27801 }
| static int check_user | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| int | sipmethod, | |||
| const char * | uri, | |||
| enum xmittype | reliable, | |||
| struct ast_sockaddr * | addr | |||
| ) | [static] |
Find user If we get a match, this will add a reference pointer to the user object in ASTOBJ, that needs to be unreferenced.
Definition at line 16847 of file chan_sip.c.
References check_user_full().
Referenced by handle_request_options(), and handle_request_publish().
16848 { 16849 return check_user_full(p, req, sipmethod, uri, reliable, addr, NULL); 16850 }
| static enum check_auth_result check_user_full | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| int | sipmethod, | |||
| const char * | uri, | |||
| enum xmittype | reliable, | |||
| struct ast_sockaddr * | addr, | |||
| struct sip_peer ** | authpeer | |||
| ) | [static] |
Check if matching user or peer is defined Match user on From: user name and peer on IP/port This is used on first invite (not re-invites) and subscribe requests.
Definition at line 16716 of file chan_sip.c.
References ast_free, ast_is_shrinkable_phonenumber(), ast_log(), ast_set_flag, ast_shrink_phone_number(), ast_strdup, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, build_contact(), check_peer_ok(), cid_name, cid_num, dialog_initialize_rtp(), exten, extract_host_from_hostport(), get_calleridname(), get_header(), get_in_brackets(), get_rpid(), LOG_ERROR, LOG_NOTICE, name, parse_uri_legacy_check(), RAII_VAR, sip_cfg, SIP_PEDANTIC_DECODE, and terminate_uri().
Referenced by check_user(), handle_request_invite(), and handle_request_subscribe().
16719 { 16720 char *of, *name, *unused_password, *domain; 16721 RAII_VAR(char *, ofbuf, NULL, ast_free); /* beware, everyone starts pointing to this */ 16722 RAII_VAR(char *, namebuf, NULL, ast_free); 16723 enum check_auth_result res = AUTH_DONT_KNOW; 16724 char calleridname[256]; 16725 char *uri2 = ast_strdupa(uri); 16726 16727 terminate_uri(uri2); /* trim extra stuff */ 16728 16729 ofbuf = ast_strdup(get_header(req, "From")); 16730 /* XXX here tries to map the username for invite things */ 16731 16732 /* strip the display-name portion off the beginning of the FROM header. */ 16733 if (!(of = (char *) get_calleridname(ofbuf, calleridname, sizeof(calleridname)))) { 16734 ast_log(LOG_ERROR, "FROM header can not be parsed\n"); 16735 return res; 16736 } 16737 16738 if (calleridname[0]) { 16739 ast_string_field_set(p, cid_name, calleridname); 16740 } 16741 16742 if (ast_strlen_zero(p->exten)) { 16743 char *t = uri2; 16744 if (!strncasecmp(t, "sip:", 4)) 16745 t+= 4; 16746 else if (!strncasecmp(t, "sips:", 5)) 16747 t += 5; 16748 ast_string_field_set(p, exten, t); 16749 t = strchr(p->exten, '@'); 16750 if (t) 16751 *t = '\0'; 16752 16753 if (ast_strlen_zero(p->our_contact)) 16754 build_contact(p); 16755 } 16756 16757 of = get_in_brackets(of); 16758 16759 /* save the URI part of the From header */ 16760 ast_string_field_set(p, from, of); 16761 16762 if (parse_uri_legacy_check(of, "sip:,sips:", &name, &unused_password, &domain, NULL)) { 16763 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 16764 } 16765 16766 SIP_PEDANTIC_DECODE(name); 16767 SIP_PEDANTIC_DECODE(domain); 16768 16769 extract_host_from_hostport(&domain); 16770 16771 if (ast_strlen_zero(domain)) { 16772 /* <sip:name@[EMPTY]>, never good */ 16773 ast_log(LOG_ERROR, "Empty domain name in FROM header\n"); 16774 return res; 16775 } 16776 16777 if (ast_strlen_zero(name)) { 16778 /* <sip:[EMPTY][@]hostport>. Asterisk 1.4 and 1.6 have always 16779 * treated that as a username, so we continue the tradition: 16780 * uri is now <sip:host@hostport>. */ 16781 name = domain; 16782 } else { 16783 /* Non-empty name, try to get caller id from it */ 16784 char *tmp = ast_strdupa(name); 16785 /* We need to be able to handle from-headers looking like 16786 <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43> 16787 */ 16788 tmp = strsep(&tmp, ";"); 16789 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) { 16790 ast_shrink_phone_number(tmp); 16791 } 16792 ast_string_field_set(p, cid_num, tmp); 16793 } 16794 16795 if (global_match_auth_username) { 16796 /* 16797 * XXX This is experimental code to grab the search key from the 16798 * Auth header's username instead of the 'From' name, if available. 16799 * Do not enable this block unless you understand the side effects (if any!) 16800 * Note, the search for "username" should be done in a more robust way. 16801 * Note2, at the moment we check both fields, though maybe we should 16802 * pick one or another depending on the request ? XXX 16803 */ 16804 const char *hdr = get_header(req, "Authorization"); 16805 if (ast_strlen_zero(hdr)) { 16806 hdr = get_header(req, "Proxy-Authorization"); 16807 } 16808 16809 if (!ast_strlen_zero(hdr) && (hdr = strstr(hdr, "username=\""))) { 16810 namebuf = name = ast_strdup(hdr + strlen("username=\"")); 16811 name = strsep(&name, "\""); 16812 } 16813 } 16814 16815 res = check_peer_ok(p, name, req, sipmethod, addr, 16816 authpeer, reliable, calleridname, uri2); 16817 if (res != AUTH_DONT_KNOW) { 16818 return res; 16819 } 16820 16821 /* Finally, apply the guest policy */ 16822 if (sip_cfg.allowguest) { 16823 /* Ignore check_return warning from Coverity for get_rpid below. */ 16824 get_rpid(p, req); 16825 p->rtptimeout = global_rtptimeout; 16826 p->rtpholdtimeout = global_rtpholdtimeout; 16827 p->rtpkeepalive = global_rtpkeepalive; 16828 if (!dialog_initialize_rtp(p)) { 16829 res = AUTH_SUCCESSFUL; 16830 } else { 16831 res = AUTH_RTP_FAILED; 16832 } 16833 } else { 16834 res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */ 16835 } 16836 16837 if (ast_test_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT)) { 16838 ast_set_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT); 16839 } 16840 16841 return res; 16842 }
| static void check_via | ( | struct sip_pvt * | p, | |
| const struct sip_request * | req | |||
| ) | [static] |
check Via: header for hostname, port and rport request/answer
Definition at line 16446 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_set_flag, ast_skip_blanks(), ast_sockaddr_port, ast_sockaddr_resolve_first(), ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_verbose, get_header(), LOG_WARNING, sip_debug_test_pvt(), sip_nat_mode(), and sip_real_dst().
Referenced by handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_register(), and handle_request_subscribe().
16447 { 16448 char via[512]; 16449 char *c, *maddr; 16450 struct ast_sockaddr tmp = { { 0, } }; 16451 uint16_t port; 16452 16453 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 16454 16455 /* Work on the leftmost value of the topmost Via header */ 16456 c = strchr(via, ','); 16457 if (c) 16458 *c = '\0'; 16459 16460 /* Check for rport */ 16461 c = strstr(via, ";rport"); 16462 if (c && (c[6] != '=')) { /* rport query, not answer */ 16463 ast_set_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT); 16464 ast_set_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT); 16465 } 16466 16467 /* Check for maddr */ 16468 maddr = strstr(via, "maddr="); 16469 if (maddr) { 16470 maddr += 6; 16471 c = maddr + strspn(maddr, "abcdefghijklmnopqrstuvwxyz" 16472 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.:[]"); 16473 *c = '\0'; 16474 } 16475 16476 c = strchr(via, ';'); 16477 if (c) 16478 *c = '\0'; 16479 16480 c = strchr(via, ' '); 16481 if (c) { 16482 *c = '\0'; 16483 c = ast_skip_blanks(c+1); 16484 if (strcasecmp(via, "SIP/2.0/UDP") && strcasecmp(via, "SIP/2.0/TCP") && strcasecmp(via, "SIP/2.0/TLS")) { 16485 ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via); 16486 return; 16487 } 16488 16489 if (maddr && ast_sockaddr_resolve_first(&p->sa, maddr, 0)) { 16490 p->sa = p->recv; 16491 } 16492 16493 if (ast_sockaddr_resolve_first(&tmp, c, 0)) { 16494 ast_log(LOG_WARNING, "Could not resolve socket address for '%s'\n", c); 16495 port = STANDARD_SIP_PORT; 16496 } else if (!(port = ast_sockaddr_port(&tmp))) { 16497 port = STANDARD_SIP_PORT; 16498 } 16499 16500 ast_sockaddr_set_port(&p->sa, port); 16501 16502 if (sip_debug_test_pvt(p)) { 16503 ast_verbose("Sending to %s (%s)\n", 16504 ast_sockaddr_stringify(sip_real_dst(p)), 16505 sip_nat_mode(p)); 16506 } 16507 } 16508 }
| static attribute_unused void check_via_response | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
check received= and rport= in a SIP response. If we get a response with received= and/or rport= in the Via: line, use them as 'p->ourip' (see RFC 3581 for rport, and RFC 3261 for received). Using these two fields SIP can produce the correct address and port in the SIP headers without the need for STUN. The address part is also reused for the media sessions. Note that ast_sip_ouraddrfor() still rewrites p->ourip if you specify externaddr/seternaddr/.
Definition at line 16416 of file chan_sip.c.
References ast_copy_string(), ast_parse_arg(), ast_sockaddr_set_port, get_header(), and PARSE_ADDR.
16417 { 16418 char via[256]; 16419 char *cur, *opts; 16420 16421 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 16422 16423 /* Work on the leftmost value of the topmost Via header */ 16424 opts = strchr(via, ','); 16425 if (opts) 16426 *opts = '\0'; 16427 16428 /* parse all relevant options */ 16429 opts = strchr(via, ';'); 16430 if (!opts) 16431 return; /* no options to parse */ 16432 *opts++ = '\0'; 16433 while ( (cur = strsep(&opts, ";")) ) { 16434 if (!strncmp(cur, "rport=", 6)) { 16435 int port = strtol(cur+6, NULL, 10); 16436 /* XXX add error checking */ 16437 ast_sockaddr_set_port(&p->ourip, port); 16438 } else if (!strncmp(cur, "received=", 9)) { 16439 if (ast_parse_arg(cur + 9, PARSE_ADDR, &p->ourip)) 16440 ; /* XXX add error checking */ 16441 } 16442 } 16443 }
| static void cleanup_all_regs | ( | void | ) | [static] |
Definition at line 28768 of file chan_sip.c.
References ast_debug, ast_dnsmgr_release(), AST_SCHED_DEL_UNREF, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, dialog_unlink_all(), registry_unref(), and regl.
Referenced by reload_config(), and unload_module().
28769 { 28770 /* First, destroy all outstanding registry calls */ 28771 /* This is needed, since otherwise active registry entries will not be destroyed */ 28772 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { /* regl is locked */ 28773 ASTOBJ_WRLOCK(iterator); /* now regl is locked, and the object is also locked */ 28774 if (iterator->call) { 28775 ast_debug(3, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname); 28776 /* This will also remove references to the registry */ 28777 dialog_unlink_all(iterator->call); 28778 iterator->call = dialog_unref(iterator->call, "remove iterator->call from registry traversal"); 28779 } 28780 if (iterator->expire > -1) { 28781 AST_SCHED_DEL_UNREF(sched, iterator->expire, registry_unref(iterator, "reg ptr unref from reload config")); 28782 } 28783 if (iterator->timeout > -1) { 28784 AST_SCHED_DEL_UNREF(sched, iterator->timeout, registry_unref(iterator, "reg ptr unref from reload config")); 28785 } 28786 if (iterator->dnsmgr) { 28787 ast_dnsmgr_release(iterator->dnsmgr); 28788 iterator->dnsmgr = NULL; 28789 registry_unref(iterator, "reg ptr unref from dnsmgr"); 28790 } 28791 ASTOBJ_UNLOCK(iterator); 28792 } while(0)); 28793 }
| static void cleanup_stale_contexts | ( | char * | new, | |
| char * | old | |||
| ) | [static] |
Destroy disused contexts between reloads Only used in reload_config so the code for regcontext doesn't get ugly.
Definition at line 17623 of file chan_sip.c.
References ast_context_destroy(), ast_context_find(), ast_copy_string(), and AST_MAX_CONTEXT.
Referenced by reload_config().
17624 { 17625 char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT]; 17626 17627 while ((oldcontext = strsep(&old, "&"))) { 17628 stalecontext = '\0'; 17629 ast_copy_string(newlist, new, sizeof(newlist)); 17630 stringp = newlist; 17631 while ((newcontext = strsep(&stringp, "&"))) { 17632 if (!strcmp(newcontext, oldcontext)) { 17633 /* This is not the context you're looking for */ 17634 stalecontext = '\0'; 17635 break; 17636 } else if (strcmp(newcontext, oldcontext)) { 17637 stalecontext = oldcontext; 17638 } 17639 17640 } 17641 if (stalecontext) 17642 ast_context_destroy(ast_context_find(stalecontext), "SIP"); 17643 } 17644 }
| static void clear_peer_mailboxes | ( | struct sip_peer * | peer | ) | [static] |
Destroy all peer-related mailbox subscriptions
Definition at line 4810 of file chan_sip.c.
References AST_LIST_REMOVE_HEAD, destroy_mailbox(), and mailbox.
Referenced by set_peer_defaults(), and sip_destroy_peer().
04811 { 04812 struct sip_mailbox *mailbox; 04813 04814 while ((mailbox = AST_LIST_REMOVE_HEAD(&peer->mailboxes, entry))) 04815 destroy_mailbox(mailbox); 04816 }
| static void clear_sip_domains | ( | void | ) | [static] |
Clear our domain list (at reload).
Definition at line 27804 of file chan_sip.c.
References ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, and AST_LIST_UNLOCK.
Referenced by reload_config(), and unload_module().
27805 { 27806 struct domain *d; 27807 27808 AST_LIST_LOCK(&domain_list); 27809 while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list))) 27810 ast_free(d); 27811 AST_LIST_UNLOCK(&domain_list); 27812 }
| static char * complete_sip_peer | ( | const char * | word, | |
| int | state, | |||
| int | flags2 | |||
| ) | [static] |
Do completion on peer name.
Definition at line 19107 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ast_strdup, ast_test_flag, and unref_peer().
Referenced by complete_sip_show_peer(), complete_sipnotify(), sip_do_debug(), and sip_prune_realtime().
19108 { 19109 char *result = NULL; 19110 int wordlen = strlen(word); 19111 int which = 0; 19112 struct ao2_iterator i = ao2_iterator_init(peers, 0); 19113 struct sip_peer *peer; 19114 19115 while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) { 19116 /* locking of the object is not required because only the name and flags are being compared */ 19117 if (!strncasecmp(word, peer->name, wordlen) && 19118 (!flags2 || ast_test_flag(&peer->flags[1], flags2)) && 19119 ++which > state) 19120 result = ast_strdup(peer->name); 19121 unref_peer(peer, "toss iterator peer ptr before break"); 19122 if (result) { 19123 break; 19124 } 19125 } 19126 ao2_iterator_destroy(&i); 19127 return result; 19128 }
| static char * complete_sip_registered_peer | ( | const char * | word, | |
| int | state, | |||
| int | flags2 | |||
| ) | [static] |
Do completion on registered peer name.
Definition at line 19131 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ast_strdup, ast_test_flag, and unref_peer().
Referenced by complete_sip_unregister().
19132 { 19133 char *result = NULL; 19134 int wordlen = strlen(word); 19135 int which = 0; 19136 struct ao2_iterator i; 19137 struct sip_peer *peer; 19138 19139 i = ao2_iterator_init(peers, 0); 19140 while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) { 19141 if (!strncasecmp(word, peer->name, wordlen) && 19142 (!flags2 || ast_test_flag(&peer->flags[1], flags2)) && 19143 ++which > state && peer->expire > 0) 19144 result = ast_strdup(peer->name); 19145 if (result) { 19146 unref_peer(peer, "toss iterator peer ptr before break"); 19147 break; 19148 } 19149 unref_peer(peer, "toss iterator peer ptr"); 19150 } 19151 ao2_iterator_destroy(&i); 19152 return result; 19153 }
| static char * complete_sip_show_history | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Support routine for 'sip show history' CLI.
Definition at line 19156 of file chan_sip.c.
References complete_sipch().
Referenced by sip_show_history().
19157 { 19158 if (pos == 3) 19159 return complete_sipch(line, word, pos, state); 19160 19161 return NULL; 19162 }
| static char * complete_sip_show_peer | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Support routine for 'sip show peer' CLI.
Definition at line 19165 of file chan_sip.c.
References complete_sip_peer().
Referenced by sip_qualify_peer(), and sip_show_peer().
19166 { 19167 if (pos == 3) { 19168 return complete_sip_peer(word, state, 0); 19169 } 19170 19171 return NULL; 19172 }
| static char* complete_sip_show_user | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Support routine for 'sip show user' CLI.
Definition at line 18366 of file chan_sip.c.
References complete_sip_user().
Referenced by sip_show_user().
18367 { 18368 if (pos == 3) 18369 return complete_sip_user(word, state); 18370 18371 return NULL; 18372 }
| static char * complete_sip_unregister | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Support routine for 'sip unregister' CLI.
Definition at line 19175 of file chan_sip.c.
References complete_sip_registered_peer().
Referenced by sip_unregister().
19176 { 19177 if (pos == 2) 19178 return complete_sip_registered_peer(word, state, 0); 19179 19180 return NULL; 19181 }
| static char* complete_sip_user | ( | const char * | word, | |
| int | state | |||
| ) | [static] |
Do completion on user name.
Definition at line 18336 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_iterator_next, ao2_unlock, ast_strdup, and unref_peer().
Referenced by complete_sip_show_user().
18337 { 18338 char *result = NULL; 18339 int wordlen = strlen(word); 18340 int which = 0; 18341 struct ao2_iterator user_iter; 18342 struct sip_peer *user; 18343 18344 user_iter = ao2_iterator_init(peers, 0); 18345 while ((user = ao2_t_iterator_next(&user_iter, "iterate thru peers table"))) { 18346 ao2_lock(user); 18347 if (!(user->type & SIP_TYPE_USER)) { 18348 ao2_unlock(user); 18349 unref_peer(user, "complete sip user"); 18350 continue; 18351 } 18352 /* locking of the object is not required because only the name and flags are being compared */ 18353 if (!strncasecmp(word, user->name, wordlen) && ++which > state) { 18354 result = ast_strdup(user->name); 18355 } 18356 ao2_unlock(user); 18357 unref_peer(user, "complete sip user"); 18358 if (result) { 18359 break; 18360 } 18361 } 18362 ao2_iterator_destroy(&user_iter); 18363 return result; 18364 }
| static char* complete_sipch | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Support routine for 'sip show channel' and 'sip show history' CLI This is in charge of generating all strings that match a prefix in the given position. As many functions of this kind, each invokation has O(state) time complexity so be careful in using it.
Definition at line 19077 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ast_strdup, sip_pvt_lock, and sip_pvt_unlock.
Referenced by complete_sip_show_history(), and sip_show_channel().
19078 { 19079 int which=0; 19080 struct sip_pvt *cur; 19081 char *c = NULL; 19082 int wordlen = strlen(word); 19083 struct ao2_iterator i; 19084 19085 if (pos != 3) { 19086 return NULL; 19087 } 19088 19089 i = ao2_iterator_init(dialogs, 0); 19090 while ((cur = ao2_t_iterator_next(&i, "iterate thru dialogs"))) { 19091 sip_pvt_lock(cur); 19092 if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) { 19093 c = ast_strdup(cur->callid); 19094 sip_pvt_unlock(cur); 19095 dialog_unref(cur, "drop ref in iterator loop break"); 19096 break; 19097 } 19098 sip_pvt_unlock(cur); 19099 dialog_unref(cur, "drop ref in iterator loop"); 19100 } 19101 ao2_iterator_destroy(&i); 19102 return c; 19103 }
| static char * complete_sipnotify | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Support routine for 'sip notify' CLI.
Definition at line 19184 of file chan_sip.c.
References ast_category_browse(), ast_strdup, and complete_sip_peer().
Referenced by sip_cli_notify().
19185 { 19186 char *c = NULL; 19187 19188 if (pos == 2) { 19189 int which = 0; 19190 char *cat = NULL; 19191 int wordlen = strlen(word); 19192 19193 /* do completion for notify type */ 19194 19195 if (!notify_types) 19196 return NULL; 19197 19198 while ( (cat = ast_category_browse(notify_types, cat)) ) { 19199 if (!strncasecmp(word, cat, wordlen) && ++which > state) { 19200 c = ast_strdup(cat); 19201 break; 19202 } 19203 } 19204 return c; 19205 } 19206 19207 if (pos > 2) 19208 return complete_sip_peer(word, state, 0); 19209 19210 return NULL; 19211 }
| static int construct_pidf_body | ( | enum sip_cc_publish_state | state, | |
| char * | pidf_body, | |||
| size_t | size, | |||
| const char * | presentity | |||
| ) | [static] |
Definition at line 1950 of file chan_sip.c.
References ast_copy_string(), ast_str_alloca, ast_str_append(), ast_str_buffer(), and generate_random_string().
Referenced by handle_cc_notify(), sip_cc_monitor_suspend(), and sip_cc_monitor_unsuspend().
01951 { 01952 struct ast_str *body = ast_str_alloca(size); 01953 char tuple_id[32]; 01954 01955 generate_random_string(tuple_id, sizeof(tuple_id)); 01956 01957 /* We'll make this a bare-bones pidf body. In state_notify_build_xml, the PIDF 01958 * body gets a lot more extra junk that isn't necessary, so we'll leave it out here. 01959 */ 01960 ast_str_append(&body, 0, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); 01961 /* XXX The entity attribute is currently set to the peer name associated with the 01962 * dialog. This is because we currently only call this function for call-completion 01963 * PUBLISH bodies. In such cases, the entity is completely disregarded. For other 01964 * event packages, it may be crucial to have a proper URI as the presentity so this 01965 * should be revisited as support is expanded. 01966 */ 01967 ast_str_append(&body, 0, "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" entity=\"%s\">\n", presentity); 01968 ast_str_append(&body, 0, "<tuple id=\"%s\">\n", tuple_id); 01969 ast_str_append(&body, 0, "<status><basic>%s</basic></status>\n", state == CC_OPEN ? "open" : "closed"); 01970 ast_str_append(&body, 0, "</tuple>\n"); 01971 ast_str_append(&body, 0, "</presence>\n"); 01972 ast_copy_string(pidf_body, ast_str_buffer(body), size); 01973 return 0; 01974 }
| static int copy_all_header | ( | struct sip_request * | req, | |
| const struct sip_request * | orig, | |||
| const char * | field | |||
| ) | [static] |
Copy all headers from one request to another.
Definition at line 10299 of file chan_sip.c.
References __get_header(), add_header(), and ast_strlen_zero().
Referenced by respprep().
10300 { 10301 int start = 0; 10302 int copied = 0; 10303 for (;;) { 10304 const char *tmp = __get_header(orig, field, &start); 10305 10306 if (ast_strlen_zero(tmp)) 10307 break; 10308 /* Add what we're responding to */ 10309 add_header(req, field, tmp); 10310 copied++; 10311 } 10312 return copied ? 0 : -1; 10313 }
| static int copy_header | ( | struct sip_request * | req, | |
| const struct sip_request * | orig, | |||
| const char * | field | |||
| ) | [static] |
Copy one header field from one request to another.
Definition at line 10288 of file chan_sip.c.
References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE.
Referenced by reqprep(), and respprep().
10289 { 10290 const char *tmp = get_header(orig, field); 10291 10292 if (!ast_strlen_zero(tmp)) /* Add what we're responding to */ 10293 return add_header(req, field, tmp); 10294 ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field); 10295 return -1; 10296 }
| static void copy_request | ( | struct sip_request * | dst, | |
| const struct sip_request * | src | |||
| ) | [static] |
copy SIP request (mostly used to save request for responses)
Definition at line 12105 of file chan_sip.c.
References ast_str_copy_string(), ast_str_create(), and ast_str_strlen().
Referenced by handle_request_bye(), handle_request_invite(), handle_request_options(), handle_request_register(), handle_request_subscribe(), initialize_initreq(), parse_copy(), and sip_park().
12106 { 12107 /* XXX this function can encounter memory allocation errors, perhaps it 12108 * should return a value */ 12109 12110 struct ast_str *duplicate = dst->data; 12111 struct ast_str *duplicate_content = dst->content; 12112 12113 /* copy the entire request then restore the original data and content 12114 * members from the dst request */ 12115 *dst = *src; 12116 dst->data = duplicate; 12117 dst->content = duplicate_content; 12118 12119 /* copy the data into the dst request */ 12120 if (!dst->data && !(dst->data = ast_str_create(ast_str_strlen(src->data) + 1))) { 12121 return; 12122 } 12123 ast_str_copy_string(&dst->data, src->data); 12124 12125 /* copy the content into the dst request (if it exists) */ 12126 if (src->content) { 12127 if (!dst->content && !(dst->content = ast_str_create(ast_str_strlen(src->content) + 1))) { 12128 return; 12129 } 12130 ast_str_copy_string(&dst->content, src->content); 12131 } 12132 }
| static void copy_socket_data | ( | struct sip_socket * | to_sock, | |
| const struct sip_socket * | from_sock | |||
| ) | [static] |
Definition at line 5399 of file chan_sip.c.
References ao2_ref.
Referenced by create_addr_from_peer(), handle_request_do(), parse_register_contact(), sip_poke_peer(), and transmit_response_using_temp().
| static struct ast_variable * copy_vars | ( | struct ast_variable * | src | ) | [static, read] |
duplicate a list of channel variables,
Definition at line 2329 of file chan_sip.c.
References ast_variable_new(), and ast_variable::next.
Referenced by check_peer_ok(), and create_addr_from_peer().
02330 { 02331 struct ast_variable *res = NULL, *tmp, *v = NULL; 02332 02333 for (v = src ; v ; v = v->next) { 02334 if ((tmp = ast_variable_new(v->name, v->value, v->file))) { 02335 tmp->next = res; 02336 res = tmp; 02337 } 02338 } 02339 return res; 02340 }
| static int copy_via_headers | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| const struct sip_request * | orig, | |||
| const char * | field | |||
| ) | [static] |
Copy SIP VIA Headers from the request to the response.
We always add ;received=<ip address> to the topmost via header.
Definition at line 10323 of file chan_sip.c.
References __get_header(), add_header(), ast_copy_string(), ast_log(), ast_sockaddr_port, ast_sockaddr_stringify_addr_remote(), ast_strlen_zero(), ast_test_flag, and LOG_NOTICE.
Referenced by respprep().
10324 { 10325 int copied = 0; 10326 int start = 0; 10327 10328 for (;;) { 10329 char new[512]; 10330 const char *oh = __get_header(orig, field, &start); 10331 10332 if (ast_strlen_zero(oh)) 10333 break; 10334 10335 if (!copied) { /* Only check for empty rport in topmost via header */ 10336 char leftmost[512], *others, *rport; 10337 10338 /* Only work on leftmost value */ 10339 ast_copy_string(leftmost, oh, sizeof(leftmost)); 10340 others = strchr(leftmost, ','); 10341 if (others) 10342 *others++ = '\0'; 10343 10344 /* Find ;rport; (empty request) */ 10345 rport = strstr(leftmost, ";rport"); 10346 if (rport && *(rport+6) == '=') 10347 rport = NULL; /* We already have a parameter to rport */ 10348 10349 if (((ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT)) || (rport && ast_test_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT)))) { 10350 /* We need to add received port - rport */ 10351 char *end; 10352 10353 rport = strstr(leftmost, ";rport"); 10354 10355 if (rport) { 10356 end = strchr(rport + 1, ';'); 10357 if (end) 10358 memmove(rport, end, strlen(end) + 1); 10359 else 10360 *rport = '\0'; 10361 } 10362 10363 /* Add rport to first VIA header if requested */ 10364 snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s", 10365 leftmost, ast_sockaddr_stringify_addr_remote(&p->recv), 10366 ast_sockaddr_port(&p->recv), 10367 others ? "," : "", others ? others : ""); 10368 } else { 10369 /* We should *always* add a received to the topmost via */ 10370 snprintf(new, sizeof(new), "%s;received=%s%s%s", 10371 leftmost, ast_sockaddr_stringify_addr_remote(&p->recv), 10372 others ? "," : "", others ? others : ""); 10373 } 10374 oh = new; /* the header to copy */ 10375 } /* else add the following via headers untouched */ 10376 add_header(req, field, oh); 10377 copied++; 10378 } 10379 if (!copied) { 10380 ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field); 10381 return -1; 10382 } 10383 return 0; 10384 }
| static int create_addr | ( | struct sip_pvt * | dialog, | |
| const char * | opeer, | |||
| struct ast_sockaddr * | addr, | |||
| int | newdialog | |||
| ) | [static] |
create address structure from device name Or, if peer not found, find it in the global DNS returns TRUE (-1) on failure, FALSE on success
Definition at line 5629 of file chan_sip.c.
References AST_APP_ARG, ast_check_digits(), AST_DECLARE_APP_ARGS, ast_get_srv(), ast_log(), AST_NONSTANDARD_RAW_ARGS, ast_sockaddr_copy(), ast_sockaddr_port, ast_sockaddr_resolve_first_transport(), ast_sockaddr_set_port, ast_strdupa, ast_string_field_set, bindaddr, create_addr_from_peer(), default_sip_port(), dialog_initialize_rtp(), FALSE, find_peer(), get_srv_protocol(), get_srv_service(), LOG_WARNING, MAXHOSTNAMELEN, obproxy_get(), ref_peer(), ref_proxy(), service, set_socket_transport(), sip_cfg, TRUE, and unref_peer().
Referenced by __sip_subscribe_mwi_do(), manager_sipnotify(), sip_cc_monitor_request_cc(), sip_cli_notify(), sip_request_call(), transmit_publish(), and transmit_register().
05630 { 05631 struct sip_peer *peer; 05632 char *peername, *peername2, *hostn; 05633 char host[MAXHOSTNAMELEN]; 05634 char service[MAXHOSTNAMELEN]; 05635 int srv_ret = 0; 05636 int tportno; 05637 05638 AST_DECLARE_APP_ARGS(hostport, 05639 AST_APP_ARG(host); 05640 AST_APP_ARG(port); 05641 ); 05642 05643 peername = ast_strdupa(opeer); 05644 peername2 = ast_strdupa(opeer); 05645 AST_NONSTANDARD_RAW_ARGS(hostport, peername2, ':'); 05646 05647 if (hostport.port) 05648 dialog->portinuri = 1; 05649 05650 dialog->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */ 05651 dialog->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */ 05652 peer = find_peer(peername, NULL, TRUE, FINDPEERS, FALSE, 0); 05653 05654 if (peer) { 05655 int res; 05656 if (newdialog) { 05657 set_socket_transport(&dialog->socket, 0); 05658 } 05659 res = create_addr_from_peer(dialog, peer); 05660 dialog->relatedpeer = ref_peer(peer, "create_addr: setting dialog's relatedpeer pointer"); 05661 unref_peer(peer, "create_addr: unref peer from find_peer hashtab lookup"); 05662 return res; 05663 } else if (ast_check_digits(peername)) { 05664 /* Although an IPv4 hostname *could* be represented as a 32-bit integer, it is uncommon and 05665 * it makes dialing SIP/${EXTEN} for a peer that isn't defined resolve to an IP that is 05666 * almost certainly not intended. It is much better to just reject purely numeric hostnames */ 05667 ast_log(LOG_WARNING, "Purely numeric hostname (%s), and not a peer--rejecting!\n", peername); 05668 return -1; 05669 } else { 05670 dialog->rtptimeout = global_rtptimeout; 05671 dialog->rtpholdtimeout = global_rtpholdtimeout; 05672 dialog->rtpkeepalive = global_rtpkeepalive; 05673 if (dialog_initialize_rtp(dialog)) { 05674 return -1; 05675 } 05676 } 05677 05678 ast_string_field_set(dialog, tohost, hostport.host); 05679 dialog->allowed_methods &= ~sip_cfg.disallowed_methods; 05680 05681 /* Get the outbound proxy information */ 05682 ref_proxy(dialog, obproxy_get(dialog, NULL)); 05683 05684 if (addr) { 05685 /* This address should be updated using dnsmgr */ 05686 ast_sockaddr_copy(&dialog->sa, addr); 05687 } else { 05688 05689 /* Let's see if we can find the host in DNS. First try DNS SRV records, 05690 then hostname lookup */ 05691 /*! \todo Fix this function. When we ask for SRV, we should check all transports 05692 In the future, we should first check NAPTR to find out transport preference 05693 */ 05694 hostn = peername; 05695 /* Section 4.2 of RFC 3263 specifies that if a port number is specified, then 05696 * an A record lookup should be used instead of SRV. 05697 */ 05698 if (!hostport.port && sip_cfg.srvlookup) { 05699 snprintf(service, sizeof(service), "_%s._%s.%s", 05700 get_srv_service(dialog->socket.type), 05701 get_srv_protocol(dialog->socket.type), peername); 05702 if ((srv_ret = ast_get_srv(NULL, host, sizeof(host), &tportno, 05703 service)) > 0) { 05704 hostn = host; 05705 } 05706 } 05707 05708 if (ast_sockaddr_resolve_first_transport(&dialog->sa, hostn, 0, dialog->socket.type ? dialog->socket.type : SIP_TRANSPORT_UDP)) { 05709 ast_log(LOG_WARNING, "No such host: %s\n", peername); 05710 return -1; 05711 } 05712 05713 if (srv_ret > 0) { 05714 ast_sockaddr_set_port(&dialog->sa, tportno); 05715 } 05716 } 05717 05718 if (!dialog->socket.type) 05719 set_socket_transport(&dialog->socket, SIP_TRANSPORT_UDP); 05720 if (!dialog->socket.port) { 05721 dialog->socket.port = htons(ast_sockaddr_port(&bindaddr)); 05722 } 05723 05724 if (!ast_sockaddr_port(&dialog->sa)) { 05725 ast_sockaddr_set_port(&dialog->sa, default_sip_port(dialog->socket.type)); 05726 } 05727 ast_sockaddr_copy(&dialog->recv, &dialog->sa); 05728 return 0; 05729 }
| static int create_addr_from_peer | ( | struct sip_pvt * | dialog, | |
| struct sip_peer * | peer | |||
| ) | [static] |
Create address structure from peer reference. This function copies data from peer to the dialog, so we don't have to look up the peer again from memory or database during the life time of the dialog.
Definition at line 5474 of file chan_sip.c.
References accountcode, ao2_lock, ao2_t_ref, ao2_unlock, ast_alloca, ast_cc_copy_config_params(), ast_copy_flags, ast_duplicate_ha_list(), ast_rtp_codecs_packetization_set(), AST_RTP_DTMF, ast_rtp_instance_get_codecs(), ast_rtp_instance_set_prop(), AST_RTP_PROPERTY_DTMF, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_set_flag, ast_sockaddr_isnull(), ast_sockaddr_stringify_host_remote(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, change_callid_pvt(), check_request_transport, cid_name, cid_num, context, copy_socket_data(), copy_vars(), dialog_initialize_rtp(), language, mohinterpret, mohsuggest, obproxy_get(), parkinglot, and ref_proxy().
Referenced by create_addr(), and sip_send_mwi_to_peer().
05475 { 05476 struct sip_auth_container *credentials; 05477 05478 /* this checks that the dialog is contacting the peer on a valid 05479 * transport type based on the peers transport configuration, 05480 * otherwise, this function bails out */ 05481 if (dialog->socket.type && check_request_transport(peer, dialog)) 05482 return -1; 05483 copy_socket_data(&dialog->socket, &peer->socket); 05484 05485 if (!(ast_sockaddr_isnull(&peer->addr) && ast_sockaddr_isnull(&peer->defaddr)) && 05486 (!peer->maxms || ((peer->lastms >= 0) && (peer->lastms <= peer->maxms)))) { 05487 dialog->sa = ast_sockaddr_isnull(&peer->addr) ? peer->defaddr : peer->addr; 05488 dialog->recv = dialog->sa; 05489 } else 05490 return -1; 05491 05492 /* XXX TODO: get flags directly from peer only as they are needed using dialog->relatedpeer */ 05493 ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 05494 ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 05495 ast_copy_flags(&dialog->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY); 05496 dialog->capability = peer->capability; 05497 dialog->prefs = peer->prefs; 05498 dialog->amaflags = peer->amaflags; 05499 05500 ast_string_field_set(dialog, engine, peer->engine); 05501 05502 dialog->rtptimeout = peer->rtptimeout; 05503 dialog->rtpholdtimeout = peer->rtpholdtimeout; 05504 dialog->rtpkeepalive = peer->rtpkeepalive; 05505 if (dialog_initialize_rtp(dialog)) { 05506 return -1; 05507 } 05508 05509 if (dialog->rtp) { /* Audio */ 05510 ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 05511 ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 05512 /* Set Frame packetization */ 05513 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(dialog->rtp), dialog->rtp, &dialog->prefs); 05514 dialog->autoframing = peer->autoframing; 05515 } 05516 05517 /* XXX TODO: get fields directly from peer only as they are needed using dialog->relatedpeer */ 05518 ast_string_field_set(dialog, peername, peer->name); 05519 ast_string_field_set(dialog, authname, peer->username); 05520 ast_string_field_set(dialog, username, peer->username); 05521 ast_string_field_set(dialog, peersecret, peer->secret); 05522 ast_string_field_set(dialog, peermd5secret, peer->md5secret); 05523 ast_string_field_set(dialog, mohsuggest, peer->mohsuggest); 05524 ast_string_field_set(dialog, mohinterpret, peer->mohinterpret); 05525 ast_string_field_set(dialog, tohost, peer->tohost); 05526 ast_string_field_set(dialog, fullcontact, peer->fullcontact); 05527 ast_string_field_set(dialog, accountcode, peer->accountcode); 05528 ast_string_field_set(dialog, context, peer->context); 05529 ast_string_field_set(dialog, cid_num, peer->cid_num); 05530 ast_string_field_set(dialog, cid_name, peer->cid_name); 05531 ast_string_field_set(dialog, cid_tag, peer->cid_tag); 05532 ast_string_field_set(dialog, mwi_from, peer->mwi_from); 05533 if (!ast_strlen_zero(peer->parkinglot)) { 05534 ast_string_field_set(dialog, parkinglot, peer->parkinglot); 05535 } 05536 ast_string_field_set(dialog, engine, peer->engine); 05537 ref_proxy(dialog, obproxy_get(dialog, peer)); 05538 dialog->callgroup = peer->callgroup; 05539 dialog->pickupgroup = peer->pickupgroup; 05540 dialog->allowtransfer = peer->allowtransfer; 05541 dialog->jointnoncodeccapability = dialog->noncodeccapability; 05542 05543 /* Update dialog authorization credentials */ 05544 ao2_lock(peer); 05545 credentials = peer->auth; 05546 if (credentials) { 05547 ao2_t_ref(credentials, +1, "Ref peer auth for dialog"); 05548 } 05549 ao2_unlock(peer); 05550 ao2_lock(dialog); 05551 if (dialog->peerauth) { 05552 ao2_t_ref(dialog->peerauth, -1, "Unref old dialog peer auth"); 05553 } 05554 dialog->peerauth = credentials; 05555 ao2_unlock(dialog); 05556 05557 dialog->maxcallbitrate = peer->maxcallbitrate; 05558 dialog->disallowed_methods = peer->disallowed_methods; 05559 ast_cc_copy_config_params(dialog->cc_params, peer->cc_params); 05560 if (ast_strlen_zero(dialog->tohost)) 05561 ast_string_field_set(dialog, tohost, ast_sockaddr_stringify_host_remote(&dialog->sa)); 05562 if (!ast_strlen_zero(peer->fromdomain)) { 05563 ast_string_field_set(dialog, fromdomain, peer->fromdomain); 05564 if (!dialog->initreq.headers) { 05565 char *new_callid; 05566 char *tmpcall = ast_strdupa(dialog->callid); 05567 /* this sure looks to me like we are going to change the callid on this dialog!! */ 05568 new_callid = strchr(tmpcall, '@'); 05569 if (new_callid) { 05570 int callid_size; 05571 05572 *new_callid = '\0'; 05573 05574 /* Change the dialog callid. */ 05575 callid_size = strlen(tmpcall) + strlen(peer->fromdomain) + 2; 05576 new_callid = ast_alloca(callid_size); 05577 snprintf(new_callid, callid_size, "%s@%s", tmpcall, peer->fromdomain); 05578 change_callid_pvt(dialog, new_callid); 05579 } 05580 } 05581 } 05582 if (!ast_strlen_zero(peer->fromuser)) 05583 ast_string_field_set(dialog, fromuser, peer->fromuser); 05584 if (!ast_strlen_zero(peer->language)) 05585 ast_string_field_set(dialog, language, peer->language); 05586 /* Set timer T1 to RTT for this peer (if known by qualify=) */ 05587 /* Minimum is settable or default to 100 ms */ 05588 /* If there is a maxms and lastms from a qualify use that over a manual T1 05589 value. Otherwise, use the peer's T1 value. */ 05590 if (peer->maxms && peer->lastms) 05591 dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 05592 else 05593 dialog->timer_t1 = peer->timer_t1; 05594 05595 /* Set timer B to control transaction timeouts, the peer setting is the default and overrides 05596 the known timer */ 05597 if (peer->timer_b) 05598 dialog->timer_b = peer->timer_b; 05599 else 05600 dialog->timer_b = 64 * dialog->timer_t1; 05601 05602 if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 05603 (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 05604 dialog->noncodeccapability |= AST_RTP_DTMF; 05605 else 05606 dialog->noncodeccapability &= ~AST_RTP_DTMF; 05607 dialog->directmediaha = ast_duplicate_ha_list(peer->directmediaha); 05608 if (peer->call_limit) 05609 ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT); 05610 if (!dialog->portinuri) 05611 dialog->portinuri = peer->portinuri; 05612 dialog->chanvars = copy_vars(peer->chanvars); 05613 if (peer->fromdomainport) 05614 dialog->fromdomainport = peer->fromdomainport; 05615 dialog->callingpres = peer->callingpres; 05616 05617 return 0; 05618 }
| static struct sip_epa_entry* create_epa_entry | ( | const char *const | event_package, | |
| const char *const | destination | |||
| ) | [static, read] |
Definition at line 908 of file chan_sip.c.
References ao2_t_alloc, ast_copy_string(), and find_static_data().
Referenced by sip_cc_monitor_suspend().
00909 { 00910 struct sip_epa_entry *epa_entry; 00911 const struct epa_static_data *static_data; 00912 00913 if (!(static_data = find_static_data(event_package))) { 00914 return NULL; 00915 } 00916 00917 if (!(epa_entry = ao2_t_alloc(sizeof(*epa_entry), static_data->destructor, "Allocate new EPA entry"))) { 00918 return NULL; 00919 } 00920 00921 epa_entry->static_data = static_data; 00922 ast_copy_string(epa_entry->destination, destination, sizeof(epa_entry->destination)); 00923 return epa_entry; 00924 }
| static struct sip_esc_entry* create_esc_entry | ( | struct event_state_compositor * | esc, | |
| struct sip_request * | req, | |||
| const int | expires | |||
| ) | [static, read] |
Definition at line 1034 of file chan_sip.c.
References ao2_alloc, ao2_ref, ast_sched_add(), create_new_sip_etag(), esc_entry_destructor(), event_state_compositor::name, and publish_expire().
Referenced by handle_sip_publish_initial().
01035 { 01036 struct sip_esc_entry *esc_entry; 01037 int expires_ms; 01038 01039 if (!(esc_entry = ao2_alloc(sizeof(*esc_entry), esc_entry_destructor))) { 01040 return NULL; 01041 } 01042 01043 esc_entry->event = esc->name; 01044 01045 expires_ms = expires * 1000; 01046 /* Bump refcount for scheduler */ 01047 ao2_ref(esc_entry, +1); 01048 esc_entry->sched_id = ast_sched_add(sched, expires_ms, publish_expire, esc_entry); 01049 01050 /* Note: This links the esc_entry into the ESC properly */ 01051 create_new_sip_etag(esc_entry, 0); 01052 01053 return esc_entry; 01054 }
| static void create_new_sip_etag | ( | struct sip_esc_entry * | esc_entry, | |
| int | is_linked | |||
| ) | [static] |
Definition at line 1021 of file chan_sip.c.
References ao2_link, ao2_unlink, ast_assert, ast_atomic_fetchadd_int(), event_state_compositor::compositor, and get_esc().
Referenced by create_esc_entry(), and transmit_response_with_sip_etag().
01022 { 01023 int new_etag = ast_atomic_fetchadd_int(&esc_etag_counter, +1); 01024 struct event_state_compositor *esc = get_esc(esc_entry->event); 01025 01026 ast_assert(esc != NULL); 01027 if (is_linked) { 01028 ao2_unlink(esc->compositor, esc_entry); 01029 } 01030 snprintf(esc_entry->entity_tag, sizeof(esc_entry->entity_tag), "%d", new_etag); 01031 ao2_link(esc->compositor, esc_entry); 01032 }
| static int default_sip_port | ( | enum sip_transport | type | ) | [inline, static] |
The default sip port for the given transport.
Definition at line 5621 of file chan_sip.c.
Referenced by create_addr(), on_dns_update_peer(), and parse_register_contact().
05622 { 05623 return type == SIP_TRANSPORT_TLS ? STANDARD_TLS_PORT : STANDARD_SIP_PORT; 05624 }
| static void deinit_req | ( | struct sip_request * | req | ) | [static] |
Deinitialize SIP response/request.
Definition at line 10540 of file chan_sip.c.
References ast_free.
Referenced by __sip_destroy(), _sip_tcp_helper_thread(), send_request(), send_response(), sip_park(), sip_park_thread(), and sipsock_read().
| static void destroy_association | ( | struct sip_peer * | peer | ) | [static] |
Remove registration data from realtime database or AST/DB when registration expires.
Definition at line 14187 of file chan_sip.c.
References ast_check_realtime(), ast_db_del(), ast_update_realtime(), SENTINEL, and sip_cfg.
Referenced by build_peer(), and expire_register().
14188 { 14189 int realtimeregs = ast_check_realtime("sipregs"); 14190 char *tablename = (realtimeregs) ? "sipregs" : "sippeers"; 14191 14192 if (!sip_cfg.ignore_regexpire) { 14193 if (peer->rt_fromcontact && sip_cfg.peer_rtupdate) { 14194 ast_update_realtime(tablename, "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "regserver", "", "useragent", "", "lastms", "0", SENTINEL); 14195 } else { 14196 ast_db_del("SIP/Registry", peer->name); 14197 ast_db_del("SIP/PeerMethods", peer->name); 14198 } 14199 } 14200 }
| static void destroy_escs | ( | void | ) | [static] |
Definition at line 1068 of file chan_sip.c.
References ao2_ref, ARRAY_LEN, and event_state_compositors.
Referenced by unload_module().
01069 { 01070 int i; 01071 for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) { 01072 ao2_ref(event_state_compositors[i].compositor, -1); 01073 } 01074 }
| static void destroy_mailbox | ( | struct sip_mailbox * | mailbox | ) | [static] |
Destroy mailbox subscriptions
Definition at line 4802 of file chan_sip.c.
References ast_event_unsubscribe(), and ast_free.
Referenced by build_peer(), and clear_peer_mailboxes().
04803 { 04804 if (mailbox->event_sub) 04805 ast_event_unsubscribe(mailbox->event_sub); 04806 ast_free(mailbox); 04807 }
| static void destroy_realm_authentication | ( | void * | obj | ) | [static] |
Definition at line 27822 of file chan_sip.c.
References ast_free, and AST_LIST_REMOVE_HEAD.
Referenced by add_realm_authentication().
27823 { 27824 struct sip_auth_container *credentials = obj; 27825 struct sip_auth *auth; 27826 27827 while ((auth = AST_LIST_REMOVE_HEAD(&credentials->list, node))) { 27828 ast_free(auth); 27829 } 27830 }
| static int determine_firstline_parts | ( | struct sip_request * | req | ) | [static] |
Parse first line of incoming SIP request.
Definition at line 12205 of file chan_sip.c.
References ast_debug, ast_skip_blanks(), ast_skip_nonblanks(), and ast_trim_blanks().
Referenced by parse_request().
12206 { 12207 char *e = ast_skip_blanks(req->data->str); /* there shouldn't be any */ 12208 char *local_rlPart1; 12209 12210 if (!*e) 12211 return -1; 12212 req->rlPart1 = e - req->data->str; /* method or protocol */ 12213 local_rlPart1 = e; 12214 e = ast_skip_nonblanks(e); 12215 if (*e) 12216 *e++ = '\0'; 12217 /* Get URI or status code */ 12218 e = ast_skip_blanks(e); 12219 if ( !*e ) 12220 return -1; 12221 ast_trim_blanks(e); 12222 12223 if (!strcasecmp(local_rlPart1, "SIP/2.0") ) { /* We have a response */ 12224 if (strlen(e) < 3) /* status code is 3 digits */ 12225 return -1; 12226 req->rlPart2 = e - req->data->str; 12227 } else { /* We have a request */ 12228 if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */ 12229 ast_debug(3, "Oops. Bogus uri in <> %s\n", e); 12230 e++; 12231 if (!*e) 12232 return -1; 12233 } 12234 req->rlPart2 = e - req->data->str; /* URI */ 12235 e = ast_skip_nonblanks(e); 12236 if (*e) 12237 *e++ = '\0'; 12238 e = ast_skip_blanks(e); 12239 if (strcasecmp(e, "SIP/2.0") ) { 12240 ast_debug(3, "Skipping packet - Bad request protocol %s\n", e); 12241 return -1; 12242 } 12243 } 12244 return 1; 12245 }
| static enum sip_publish_type determine_sip_publish_type | ( | struct sip_request * | req, | |
| const char *const | event, | |||
| const char *const | etag, | |||
| const char *const | expires, | |||
| int * | expires_int | |||
| ) | [static] |
Definition at line 24785 of file chan_sip.c.
References ast_assert, and ast_strlen_zero().
Referenced by handle_request_publish().
24786 { 24787 int etag_present = !ast_strlen_zero(etag); 24788 int body_present = req->lines > 0; 24789 24790 ast_assert(expires_int != NULL); 24791 24792 if (ast_strlen_zero(expires)) { 24793 /* Section 6, item 4, second bullet point of RFC 3903 says to 24794 * use a locally-configured default expiration if none is provided 24795 * in the request 24796 */ 24797 *expires_int = DEFAULT_PUBLISH_EXPIRES; 24798 } else if (sscanf(expires, "%30d", expires_int) != 1) { 24799 return SIP_PUBLISH_UNKNOWN; 24800 } 24801 24802 if (*expires_int == 0) { 24803 return SIP_PUBLISH_REMOVE; 24804 } else if (!etag_present && body_present) { 24805 return SIP_PUBLISH_INITIAL; 24806 } else if (etag_present && !body_present) { 24807 return SIP_PUBLISH_REFRESH; 24808 } else if (etag_present && body_present) { 24809 return SIP_PUBLISH_MODIFY; 24810 } 24811 24812 return SIP_PUBLISH_UNKNOWN; 24813 }
| static int dialog_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 30847 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 17512 of file chan_sip.c.
References ao2_t_ref, ast_cli(), and ast_cli_args::fd.
Referenced by sip_show_objects().
17513 { 17514 struct sip_pvt *pvt = userobj; 17515 int refc = ao2_t_ref(userobj, 0, ""); 17516 struct ast_cli_args *a = (struct ast_cli_args *) arg; 17517 17518 ast_cli(a->fd, "name: %s\ntype: dialog\nobjflags: %d\nrefcount: %d\n\n", 17519 pvt->callid, 0, refc); 17520 return 0; 17521 }
| static int dialog_find_multiple | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 30837 of file chan_sip.c.
References CMP_MATCH.
Referenced by find_call().
30838 { 30839 struct sip_pvt *pvt = obj, *pvt2 = arg; 30840 30841 return !strcasecmp(pvt->callid, pvt2->callid) ? CMP_MATCH : 0; 30842 }
| static int dialog_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 30827 of file chan_sip.c.
References ast_str_case_hash().
Referenced by load_module().
30828 { 30829 const struct sip_pvt *pvt = obj; 30830 30831 return ast_str_case_hash(pvt->callid); 30832 }
| static int dialog_initialize_rtp | ( | struct sip_pvt * | dialog | ) | [static] |
Initialize RTP portion of a dialog.
Definition at line 5416 of file chan_sip.c.
References AST_FORMAT_VIDEO_MASK, ast_rtp_instance_new(), ast_rtp_instance_set_hold_timeout(), ast_rtp_instance_set_keepalive(), ast_rtp_instance_set_prop(), ast_rtp_instance_set_qos(), ast_rtp_instance_set_timeout(), AST_RTP_PROPERTY_DTMF, AST_RTP_PROPERTY_DTMF_COMPENSATE, AST_RTP_PROPERTY_RTCP, ast_sockaddr_copy(), ast_test_flag, bindaddr, do_setnat(), cfsip_methods::need_rtp, and sip_methods.
Referenced by check_peer_ok(), check_user_full(), create_addr(), and create_addr_from_peer().
05417 { 05418 struct ast_sockaddr bindaddr_tmp; 05419 05420 if (!sip_methods[dialog->method].need_rtp) { 05421 return 0; 05422 } 05423 05424 ast_sockaddr_copy(&bindaddr_tmp, &bindaddr); 05425 if (!(dialog->rtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) { 05426 return -1; 05427 } 05428 05429 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS) || 05430 (ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) && (dialog->capability & AST_FORMAT_VIDEO_MASK))) { 05431 if (!(dialog->vrtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) { 05432 return -1; 05433 } 05434 ast_rtp_instance_set_timeout(dialog->vrtp, dialog->rtptimeout); 05435 ast_rtp_instance_set_hold_timeout(dialog->vrtp, dialog->rtpholdtimeout); 05436 ast_rtp_instance_set_keepalive(dialog->vrtp, dialog->rtpkeepalive); 05437 05438 ast_rtp_instance_set_prop(dialog->vrtp, AST_RTP_PROPERTY_RTCP, 1); 05439 ast_rtp_instance_set_qos(dialog->vrtp, global_tos_video, global_cos_video, "SIP VIDEO"); 05440 } 05441 05442 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_TEXTSUPPORT)) { 05443 if (!(dialog->trtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) { 05444 return -1; 05445 } 05446 /* Do not timeout text as its not constant*/ 05447 ast_rtp_instance_set_keepalive(dialog->trtp, dialog->rtpkeepalive); 05448 05449 ast_rtp_instance_set_prop(dialog->trtp, AST_RTP_PROPERTY_RTCP, 1); 05450 } 05451 05452 ast_rtp_instance_set_timeout(dialog->rtp, dialog->rtptimeout); 05453 ast_rtp_instance_set_hold_timeout(dialog->rtp, dialog->rtpholdtimeout); 05454 ast_rtp_instance_set_keepalive(dialog->rtp, dialog->rtpkeepalive); 05455 05456 ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_RTCP, 1); 05457 ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 05458 ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 05459 05460 ast_rtp_instance_set_qos(dialog->rtp, global_tos_audio, global_cos_audio, "SIP RTP"); 05461 05462 do_setnat(dialog); 05463 05464 return 0; 05465 }
| static int dialog_needdestroy | ( | void * | dialogobj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Match dialogs that need to be destroyed.
This is used with ao2_callback to unlink/delete all dialogs that are marked needdestroy.
Definition at line 17656 of file chan_sip.c.
References ao2_t_link, ast_debug, ast_rtp_instance_get_bridged(), check_rtp_timeout(), sip_methods, sip_pvt_trylock, sip_pvt_unlock, and cfsip_methods::text.
Referenced by do_monitor().
17657 { 17658 struct sip_pvt *dialog = dialogobj; 17659 time_t *t = arg; 17660 17661 if (sip_pvt_trylock(dialog)) { 17662 /* Don't block the monitor thread. This function is called often enough 17663 * that we can wait for the next time around. */ 17664 return 0; 17665 } 17666 17667 /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */ 17668 check_rtp_timeout(dialog, *t); 17669 17670 /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */ 17671 if (dialog->rtp && ast_rtp_instance_get_bridged(dialog->rtp)) { 17672 ast_debug(2, "Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text); 17673 sip_pvt_unlock(dialog); 17674 return 0; 17675 } 17676 17677 if (dialog->vrtp && ast_rtp_instance_get_bridged(dialog->vrtp)) { 17678 ast_debug(2, "Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text); 17679 sip_pvt_unlock(dialog); 17680 return 0; 17681 } 17682 17683 /* If we have sessions that needs to be destroyed, do it now */ 17684 /* Check if we have outstanding requests not responsed to or an active call 17685 - if that's the case, wait with destruction */ 17686 if (dialog->needdestroy && !dialog->packets && !dialog->owner) { 17687 /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */ 17688 if (dialog->rtp && ast_rtp_instance_get_bridged(dialog->rtp)) { 17689 ast_debug(2, "Bridge still active. Delaying destruction of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text); 17690 sip_pvt_unlock(dialog); 17691 return 0; 17692 } 17693 17694 if (dialog->vrtp && ast_rtp_instance_get_bridged(dialog->vrtp)) { 17695 ast_debug(2, "Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text); 17696 sip_pvt_unlock(dialog); 17697 return 0; 17698 } 17699 17700 sip_pvt_unlock(dialog); 17701 17702 /* This dialog needs to be destroyed. */ 17703 ao2_t_link(dialogs_to_destroy, dialog, "Link dialog for destruction"); 17704 return 0; 17705 } 17706 17707 sip_pvt_unlock(dialog); 17708 17709 return 0; 17710 }
| struct sip_pvt* dialog_ref_debug | ( | struct sip_pvt * | p, | |
| char * | tag, | |||
| char * | file, | |||
| int | line, | |||
| const char * | func | |||
| ) | [read] |
Definition at line 2221 of file chan_sip.c.
References __ao2_ref_debug(), ao2_ref, ast_log(), and LOG_ERROR.
02222 { 02223 if (p) 02224 #ifdef REF_DEBUG 02225 __ao2_ref_debug(p, 1, tag, file, line, func); 02226 #else 02227 ao2_ref(p, 1); 02228 #endif 02229 else 02230 ast_log(LOG_ERROR, "Attempt to Ref a null pointer\n"); 02231 return p; 02232 }
| void dialog_unlink_all | ( | struct sip_pvt * | dialog | ) |
Unlink a dialog from the dialogs container, as well as any other places that it may be currently stored.
Definition at line 3080 of file chan_sip.c.
References ao2_t_unlink, ast_channel_unlock, ast_channel_unref, ast_debug, ast_extension_state_del(), ast_free, AST_SCHED_DEL, AST_SCHED_DEL_UNREF, cb_extensionstate(), registry_unref(), sip_pvt_lock_full(), sip_pvt_unlock, stop_session_timer(), and ast_channel::tech_pvt.
Referenced by __sip_autodestruct(), __sip_subscribe_mwi_do(), cleanup_all_regs(), dialog_unlink_callback(), handle_request_subscribe(), manager_sipnotify(), sip_cli_notify(), sip_destroy_peer(), sip_poke_noanswer(), sip_poke_peer(), sip_registry_destroy(), sip_request_call(), sip_send_mwi_to_peer(), transmit_publish(), transmit_register(), and unload_module().
03081 { 03082 struct sip_pkt *cp; 03083 struct ast_channel *owner; 03084 03085 dialog_ref(dialog, "Let's bump the count in the unlink so it doesn't accidentally become dead before we are done"); 03086 03087 ao2_t_unlink(dialogs, dialog, "unlinking dialog via ao2_unlink"); 03088 03089 /* Unlink us from the owner (channel) if we have one */ 03090 owner = sip_pvt_lock_full(dialog); 03091 if (owner) { 03092 ast_debug(1, "Detaching from channel %s\n", owner->name); 03093 owner->tech_pvt = dialog_unref(owner->tech_pvt, "resetting channel dialog ptr in unlink_all"); 03094 ast_channel_unlock(owner); 03095 ast_channel_unref(owner); 03096 dialog->owner = NULL; 03097 } 03098 sip_pvt_unlock(dialog); 03099 03100 if (dialog->registry) { 03101 if (dialog->registry->call == dialog) { 03102 dialog->registry->call = dialog_unref(dialog->registry->call, "nulling out the registry's call dialog field in unlink_all"); 03103 } 03104 dialog->registry = registry_unref(dialog->registry, "delete dialog->registry"); 03105 } 03106 if (dialog->stateid != -1) { 03107 ast_extension_state_del(dialog->stateid, cb_extensionstate); 03108 dialog->stateid = -1; 03109 } 03110 /* Remove link from peer to subscription of MWI */ 03111 if (dialog->relatedpeer && dialog->relatedpeer->mwipvt == dialog) { 03112 dialog->relatedpeer->mwipvt = dialog_unref(dialog->relatedpeer->mwipvt, "delete ->relatedpeer->mwipvt"); 03113 } 03114 if (dialog->relatedpeer && dialog->relatedpeer->call == dialog) { 03115 dialog->relatedpeer->call = dialog_unref(dialog->relatedpeer->call, "unset the relatedpeer->call field in tandem with relatedpeer field itself"); 03116 } 03117 03118 /* remove all current packets in this dialog */ 03119 while((cp = dialog->packets)) { 03120 dialog->packets = dialog->packets->next; 03121 AST_SCHED_DEL(sched, cp->retransid); 03122 dialog_unref(cp->owner, "remove all current packets in this dialog, and the pointer to the dialog too as part of __sip_destroy"); 03123 if (cp->data) { 03124 ast_free(cp->data); 03125 } 03126 ast_free(cp); 03127 } 03128 03129 AST_SCHED_DEL_UNREF(sched, dialog->waitid, dialog_unref(dialog, "when you delete the waitid sched, you should dec the refcount for the stored dialog ptr")); 03130 03131 AST_SCHED_DEL_UNREF(sched, dialog->initid, dialog_unref(dialog, "when you delete the initid sched, you should dec the refcount for the stored dialog ptr")); 03132 03133 if (dialog->autokillid > -1) { 03134 AST_SCHED_DEL_UNREF(sched, dialog->autokillid, dialog_unref(dialog, "when you delete the autokillid sched, you should dec the refcount for the stored dialog ptr")); 03135 } 03136 03137 if (dialog->request_queue_sched_id > -1) { 03138 AST_SCHED_DEL_UNREF(sched, dialog->request_queue_sched_id, dialog_unref(dialog, "when you delete the request_queue_sched_id sched, you should dec the refcount for the stored dialog ptr")); 03139 } 03140 03141 AST_SCHED_DEL_UNREF(sched, dialog->provisional_keepalive_sched_id, dialog_unref(dialog, "when you delete the provisional_keepalive_sched_id, you should dec the refcount for the stored dialog ptr")); 03142 03143 if (dialog->t38id > -1) { 03144 AST_SCHED_DEL_UNREF(sched, dialog->t38id, dialog_unref(dialog, "when you delete the t38id sched, you should dec the refcount for the stored dialog ptr")); 03145 } 03146 03147 if (dialog->stimer) { 03148 stop_session_timer(dialog); 03149 } 03150 03151 dialog_unref(dialog, "Let's unbump the count in the unlink so the poor pvt can disappear if it is time"); 03152 }
| static int dialog_unlink_callback | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 17722 of file chan_sip.c.
References CMP_MATCH, and dialog_unlink_all().
Referenced by do_monitor().
17723 { 17724 struct sip_pvt *dialog = obj; 17725 17726 dialog_unlink_all(dialog); 17727 17728 return CMP_MATCH; 17729 }
| struct sip_pvt* dialog_unref_debug | ( | struct sip_pvt * | p, | |
| char * | tag, | |||
| char * | file, | |||
| int | line, | |||
| const char * | func | |||
| ) | [read] |
Definition at line 2234 of file chan_sip.c.
References __ao2_ref_debug(), and ao2_ref.
02235 { 02236 if (p) 02237 #ifdef REF_DEBUG 02238 __ao2_ref_debug(p, -1, tag, file, line, func); 02239 #else 02240 ao2_ref(p, -1); 02241 #endif 02242 return NULL; 02243 }
| static void disable_dsp_detect | ( | struct sip_pvt * | p | ) | [static] |
Definition at line 4485 of file chan_sip.c.
References ast_dsp_free().
Referenced by sip_dtmfmode(), sip_hangup(), and sip_setoption().
04486 { 04487 if (p->dsp) { 04488 ast_dsp_free(p->dsp); 04489 p->dsp = NULL; 04490 } 04491 }
| static void display_nat_warning | ( | const char * | cat, | |
| int | reason, | |||
| struct ast_flags * | flags | |||
| ) | [static] |
Definition at line 28756 of file chan_sip.c.
References AST_CLI_YESNO, ast_log(), ast_test_flag, CHANNEL_MODULE_LOAD, and LOG_WARNING.
Referenced by reload_config().
28756 { 28757 int global_nat, specific_nat; 28758 28759 if (reason == CHANNEL_MODULE_LOAD && (specific_nat = ast_test_flag(&flags[0], SIP_NAT_FORCE_RPORT)) != (global_nat = ast_test_flag(&global_flags[0], SIP_NAT_FORCE_RPORT))) { 28760 ast_log(LOG_WARNING, "!!! PLEASE NOTE: Setting 'nat' for a peer/user that differs from the global setting can make\n"); 28761 ast_log(LOG_WARNING, "!!! the name of that peer/user discoverable by an attacker. Replies for non-existent peers/users\n"); 28762 ast_log(LOG_WARNING, "!!! will be sent to a different port than replies for an existing peer/user. If at all possible,\n"); 28763 ast_log(LOG_WARNING, "!!! use the global 'nat' setting and do not set 'nat' per peer/user.\n"); 28764 ast_log(LOG_WARNING, "!!! (config category='%s' global force_rport='%s' peer/user force_rport='%s')\n", cat, AST_CLI_YESNO(global_nat), AST_CLI_YESNO(specific_nat)); 28765 } 28766 }
| static int do_magic_pickup | ( | struct ast_channel * | channel, | |
| const char * | extension, | |||
| const char * | context | |||
| ) | [static] |
Definition at line 22900 of file chan_sip.c.
References ast_debug, ast_log(), AST_MAX_CONTEXT, AST_MAX_EXTENSION, ast_str_alloca, ast_str_buffer(), ast_str_set(), LOG_ERROR, pbx_exec(), pbx_findapp(), sip_cfg, and str.
Referenced by handle_request_invite().
22901 { 22902 struct ast_str *str = ast_str_alloca(AST_MAX_EXTENSION + AST_MAX_CONTEXT + 2); 22903 struct ast_app *pickup = pbx_findapp("Pickup"); 22904 22905 if (!pickup) { 22906 ast_log(LOG_ERROR, "Unable to perform pickup: Application 'Pickup' not loaded (app_directed_pickup.so).\n"); 22907 return -1; 22908 } 22909 22910 ast_str_set(&str, 0, "%s@%s", extension, sip_cfg.notifycid == IGNORE_CONTEXT ? "PICKUPMARK" : context); 22911 22912 ast_debug(2, "About to call Pickup(%s)\n", ast_str_buffer(str)); 22913 22914 /* There is no point in capturing the return value since pickup_exec 22915 doesn't return anything meaningful unless the passed data is an empty 22916 string (which in our case it will not be) */ 22917 pbx_exec(channel, pickup, ast_str_buffer(str)); 22918 22919 return 0; 22920 }
| static void * do_monitor | ( | void * | data | ) | [static] |
The SIP monitoring thread.
Definition at line 26637 of file chan_sip.c.
References ao2_container_count(), ao2_t_callback, ast_debug, ast_io_add(), ast_io_change(), AST_IO_IN, ast_io_remove(), ast_io_wait(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_sched_runq(), ast_sched_wait(), ast_verb, dialog_needdestroy(), dialog_unlink_callback(), FALSE, LOG_WARNING, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, sip_do_reload(), and sipsock_read().
Referenced by restart_monitor().
26638 { 26639 int res; 26640 time_t t; 26641 int reloading; 26642 26643 /* Add an I/O event to our SIP UDP socket */ 26644 if (sipsock > -1) 26645 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 26646 26647 /* From here on out, we die whenever asked */ 26648 for(;;) { 26649 /* Check for a reload request */ 26650 ast_mutex_lock(&sip_reload_lock); 26651 reloading = sip_reloading; 26652 sip_reloading = FALSE; 26653 ast_mutex_unlock(&sip_reload_lock); 26654 if (reloading) { 26655 ast_verb(1, "Reloading SIP\n"); 26656 sip_do_reload(sip_reloadreason); 26657 26658 /* Change the I/O fd of our UDP socket */ 26659 if (sipsock > -1) { 26660 if (sipsock_read_id) 26661 sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL); 26662 else 26663 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 26664 } else if (sipsock_read_id) { 26665 ast_io_remove(io, sipsock_read_id); 26666 sipsock_read_id = NULL; 26667 } 26668 } 26669 26670 /* Check for dialogs needing to be killed */ 26671 t = time(NULL); 26672 /* don't scan the dialogs list if it hasn't been a reasonable period 26673 of time since the last time we did it (when MWI is being sent, we can 26674 get back to this point every millisecond or less) 26675 */ 26676 /* 26677 * We cannot hold the dialogs container lock when we destroy a 26678 * dialog because of potential deadlocks. Instead we link the 26679 * doomed dialog into dialogs_to_destroy and then iterate over 26680 * that container destroying the dialogs. 26681 */ 26682 ao2_t_callback(dialogs, OBJ_NODATA | OBJ_MULTIPLE, dialog_needdestroy, &t, 26683 "callback to monitor dialog status"); 26684 if (ao2_container_count(dialogs_to_destroy)) { 26685 /* Now destroy the found dialogs that need to be destroyed. */ 26686 ao2_t_callback(dialogs_to_destroy, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, 26687 dialog_unlink_callback, NULL, "callback to dialog_unlink_all"); 26688 } 26689 26690 /* XXX TODO The scheduler usage in this module does not have sufficient 26691 * synchronization being done between running the scheduler and places 26692 * scheduling tasks. As it is written, any scheduled item may not run 26693 * any sooner than about 1 second, regardless of whether a sooner time 26694 * was asked for. */ 26695 26696 pthread_testcancel(); 26697 /* Wait for sched or io */ 26698 res = ast_sched_wait(sched); 26699 if ((res < 0) || (res > 1000)) 26700 res = 1000; 26701 res = ast_io_wait(io, res); 26702 if (res > 20) 26703 ast_debug(1, "chan_sip: ast_io_wait ran %d all at once\n", res); 26704 ast_mutex_lock(&monlock); 26705 res = ast_sched_runq(sched); 26706 if (res >= 20) 26707 ast_debug(1, "chan_sip: ast_sched_runq ran %d all at once\n", res); 26708 if (global_store_sip_cause && res >= 100) 26709 ast_log(LOG_WARNING, "scheduler delays detected, setting 'storesipcause' to 'no' in %s will improve performance\n", config); 26710 ast_mutex_unlock(&monlock); 26711 } 26712 26713 /* Never reached */ 26714 return NULL; 26715 }
| static int do_proxy_auth | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| enum sip_auth_type | code, | |||
| int | sipmethod, | |||
| int | init | |||
| ) | [static] |
Add authentication on outbound SIP packet.
Definition at line 19823 of file chan_sip.c.
References ast_calloc, ast_debug, auth_headers(), reply_digest(), sip_methods, cfsip_methods::text, and transmit_invite().
Referenced by handle_response(), handle_response_invite(), handle_response_notify(), handle_response_publish(), handle_response_refer(), handle_response_subscribe(), and handle_response_update().
19824 { 19825 char *header, *respheader; 19826 char digest[1024]; 19827 19828 if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options)))) 19829 return -2; 19830 19831 p->authtries++; 19832 auth_headers(code, &header, &respheader); 19833 ast_debug(2, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text); 19834 memset(digest, 0, sizeof(digest)); 19835 if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) { 19836 /* No way to authenticate */ 19837 return -1; 19838 } 19839 /* Now we have a reply digest */ 19840 p->options->auth = digest; 19841 p->options->authheader = respheader; 19842 return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init, NULL); 19843 }
| static int do_register_auth | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| enum sip_auth_type | code | |||
| ) | [static] |
Authenticate for outbound registration.
Definition at line 19799 of file chan_sip.c.
References append_history, ast_verbose, auth_headers(), reply_digest(), sip_debug_test_pvt(), and transmit_register().
Referenced by handle_response_register().
19800 { 19801 char *header, *respheader; 19802 char digest[1024]; 19803 19804 p->authtries++; 19805 auth_headers(code, &header, &respheader); 19806 memset(digest, 0, sizeof(digest)); 19807 if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) { 19808 /* There's nothing to use for authentication */ 19809 /* No digest challenge in request */ 19810 if (sip_debug_test_pvt(p) && p->registry) 19811 ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); 19812 /* No old challenge */ 19813 return -1; 19814 } 19815 if (p->do_history) 19816 append_history(p, "RegistryAuth", "Try: %d", p->authtries); 19817 if (sip_debug_test_pvt(p) && p->registry) 19818 ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); 19819 return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 19820 }
| static void do_setnat | ( | struct sip_pvt * | p | ) | [static] |
Set nat mode on the various data sockets.
Definition at line 5310 of file chan_sip.c.
References ast_debug, ast_rtp_instance_set_prop(), AST_RTP_PROPERTY_NAT, ast_test_flag, and ast_udptl_setnat().
Referenced by check_peer_ok(), dialog_initialize_rtp(), sip_alloc(), and transmit_response_using_temp().
05311 { 05312 const char *mode; 05313 int natflags; 05314 05315 natflags = ast_test_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP); 05316 mode = natflags ? "On" : "Off"; 05317 05318 if (p->rtp) { 05319 ast_debug(1, "Setting NAT on RTP to %s\n", mode); 05320 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_NAT, natflags); 05321 } 05322 if (p->vrtp) { 05323 ast_debug(1, "Setting NAT on VRTP to %s\n", mode); 05324 ast_rtp_instance_set_prop(p->vrtp, AST_RTP_PROPERTY_NAT, natflags); 05325 } 05326 if (p->udptl) { 05327 ast_debug(1, "Setting NAT on UDPTL to %s\n", mode); 05328 ast_udptl_setnat(p->udptl, natflags); 05329 } 05330 if (p->trtp) { 05331 ast_debug(1, "Setting NAT on TRTP to %s\n", mode); 05332 ast_rtp_instance_set_prop(p->trtp, AST_RTP_PROPERTY_NAT, natflags); 05333 } 05334 }
| static const char * domain_mode_to_text | ( | const enum domain_mode | mode | ) | [static] |
Print domain mode to cli.
Definition at line 17891 of file chan_sip.c.
Referenced by sip_show_domains().
| static const char * dtmfmode2str | ( | int | mode | ) | [static] |
Convert DTMF mode to printable string.
Definition at line 17570 of file chan_sip.c.
References map_x_s().
Referenced by _sip_show_peer(), sip_show_channel(), and sip_show_settings().
| static void enable_dsp_detect | ( | struct sip_pvt * | p | ) | [static] |
Definition at line 4451 of file chan_sip.c.
References ast_dsp_new(), ast_dsp_set_digitmode(), ast_dsp_set_features(), AST_RTP_DTMF_MODE_INBAND, ast_rtp_instance_dtmf_mode_set(), ast_test_flag, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_RELAXDTMF, DSP_FEATURE_DIGIT_DETECT, and DSP_FEATURE_FAX_DETECT.
Referenced by sip_dtmfmode(), sip_new(), and sip_setoption().
04452 { 04453 int features = 0; 04454 04455 if (p->dsp) { 04456 return; 04457 } 04458 04459 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || 04460 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) { 04461 if (p->rtp) { 04462 ast_rtp_instance_dtmf_mode_set(p->rtp, AST_RTP_DTMF_MODE_INBAND); 04463 } 04464 features |= DSP_FEATURE_DIGIT_DETECT; 04465 } 04466 04467 if (ast_test_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_CNG)) { 04468 features |= DSP_FEATURE_FAX_DETECT; 04469 } 04470 04471 if (!features) { 04472 return; 04473 } 04474 04475 if (!(p->dsp = ast_dsp_new())) { 04476 return; 04477 } 04478 04479 ast_dsp_set_features(p->dsp, features); 04480 if (global_relaxdtmf) { 04481 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); 04482 } 04483 }
| static int esc_cmp_fn | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 980 of file chan_sip.c.
References CMP_MATCH, and CMP_STOP.
Referenced by initialize_escs().
| static void esc_entry_destructor | ( | void * | obj | ) | [static] |
Definition at line 966 of file chan_sip.c.
References AST_SCHED_DEL.
Referenced by create_esc_entry().
00967 { 00968 struct sip_esc_entry *esc_entry = obj; 00969 if (esc_entry->sched_id > -1) { 00970 AST_SCHED_DEL(sched, esc_entry->sched_id); 00971 } 00972 }
| static int esc_hash_fn | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 974 of file chan_sip.c.
References ast_str_hash().
Referenced by initialize_escs().
00975 { 00976 const struct sip_esc_entry *entry = obj; 00977 return ast_str_hash(entry->entity_tag); 00978 }
| static int expire_register | ( | const void * | data | ) | [static] |
Expire registration of SIP peer.
Definition at line 14216 of file chan_sip.c.
References ao2_ref, ao2_t_unlink, ast_debug, AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_sockaddr_isnull(), ast_test_flag, destroy_association(), EVENT_FLAG_SYSTEM, FALSE, manager_event, register_peer_exten(), set_socket_transport(), and unref_peer().
Referenced by parse_register_contact(), realtime_peer(), reg_source_db(), sip_show_sched(), and sip_unregister().
14217 { 14218 struct sip_peer *peer = (struct sip_peer *)data; 14219 14220 if (!peer) { /* Hmmm. We have no peer. Weird. */ 14221 return 0; 14222 } 14223 14224 peer->expire = -1; 14225 peer->portinuri = 0; 14226 14227 destroy_association(peer); /* remove registration data from storage */ 14228 set_socket_transport(&peer->socket, peer->default_outbound_transport); 14229 14230 if (peer->socket.tcptls_session) { 14231 ao2_ref(peer->socket.tcptls_session, -1); 14232 peer->socket.tcptls_session = NULL; 14233 } 14234 14235 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 14236 register_peer_exten(peer, FALSE); /* Remove regexten */ 14237 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", peer->name); 14238 14239 /* Do we need to release this peer from memory? 14240 Only for realtime peers and autocreated peers 14241 */ 14242 if (peer->is_realtime) { 14243 ast_debug(3, "-REALTIME- peer expired registration. Name: %s. Realtime peer objects now %d\n", peer->name, rpeerobjs); 14244 } 14245 14246 if (peer->selfdestruct || 14247 ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 14248 ao2_t_unlink(peers, peer, "ao2_unlink of peer from peers table"); 14249 } 14250 if (!ast_sockaddr_isnull(&peer->addr)) { 14251 /* We still need to unlink the peer from the peers_by_ip table, 14252 * otherwise we end up with multiple copies hanging around each 14253 * time a registration expires and the peer re-registers. */ 14254 ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table"); 14255 } 14256 14257 /* Only clear the addr after we check for destruction. The addr must remain 14258 * in order to unlink from the peers_by_ip container correctly */ 14259 memset(&peer->addr, 0, sizeof(peer->addr)); 14260 14261 unref_peer(peer, "removing peer ref for expire_register"); 14262 14263 return 0; 14264 }
| static void extract_host_from_hostport | ( | char ** | hostport | ) | [static] |
Terminate a host:port at the ':'.
| hostport | The address of the hostport string |
Definition at line 15252 of file chan_sip.c.
References ast_sockaddr_split_hostport(), and PARSE_PORT_IGNORE.
Referenced by check_user_full(), get_destination(), and register_verify().
15253 { 15254 char *dont_care; 15255 ast_sockaddr_split_hostport(*hostport, hostport, &dont_care, PARSE_PORT_IGNORE); 15256 }
| static void extract_uri | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Check Contact: URI of SIP message.
Definition at line 12313 of file chan_sip.c.
References ast_copy_string(), ast_string_field_set, ast_strlen_zero(), get_header(), get_in_brackets(), and remove_uri_parameters().
Referenced by handle_incoming(), and handle_request_invite().
12314 { 12315 char stripped[SIPBUFSIZE]; 12316 char *c; 12317 12318 ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped)); 12319 c = get_in_brackets(stripped); 12320 /* Cut the URI at the at sign after the @, not in the username part */ 12321 c = remove_uri_parameters(c); 12322 if (!ast_strlen_zero(c)) { 12323 ast_string_field_set(p, uri, c); 12324 } 12325 12326 }
| static const char* faxec2str | ( | int | faxec | ) | [static] |
Definition at line 18055 of file chan_sip.c.
References map_x_s().
Referenced by _sip_show_peer(), and sip_show_settings().
18056 { 18057 return map_x_s(faxecmodes, faxec, "Unknown"); 18058 }
| static int finalize_content | ( | struct sip_request * | req | ) | [static] |
Add 'Content-Length' header and content to SIP message.
Definition at line 10256 of file chan_sip.c.
References add_header(), ast_log(), ast_str_append(), ast_str_buffer(), ast_str_strlen(), and LOG_WARNING.
Referenced by send_request(), and send_response().
10257 { 10258 char clen[10]; 10259 10260 if (req->lines) { 10261 ast_log(LOG_WARNING, "finalize_content() called on a message that has already been finalized\n"); 10262 return -1; 10263 } 10264 10265 snprintf(clen, sizeof(clen), "%zu", ast_str_strlen(req->content)); 10266 add_header(req, "Content-Length", clen); 10267 10268 if (ast_str_strlen(req->content)) { 10269 ast_str_append(&req->data, 0, "\r\n%s", ast_str_buffer(req->content)); 10270 } 10271 req->lines = ast_str_strlen(req->content) ? 1 : 0; 10272 return 0; 10273 }
| static const char * find_alias | ( | const char * | name, | |
| const char * | _default | |||
| ) | [static] |
Find compressed SIP alias.
Structure for conversion between compressed SIP and "normal" SIP
Definition at line 7606 of file chan_sip.c.
References aliases, and ARRAY_LEN.
Referenced by __get_header(), and add_header().
07607 { 07608 /*! \brief Structure for conversion between compressed SIP and "normal" SIP */ 07609 static const struct cfalias { 07610 char * const fullname; 07611 char * const shortname; 07612 } aliases[] = { 07613 { "Content-Type", "c" }, 07614 { "Content-Encoding", "e" }, 07615 { "From", "f" }, 07616 { "Call-ID", "i" }, 07617 { "Contact", "m" }, 07618 { "Content-Length", "l" }, 07619 { "Subject", "s" }, 07620 { "To", "t" }, 07621 { "Supported", "k" }, 07622 { "Refer-To", "r" }, 07623 { "Referred-By", "b" }, 07624 { "Allow-Events", "u" }, 07625 { "Event", "o" }, 07626 { "Via", "v" }, 07627 { "Accept-Contact", "a" }, 07628 { "Reject-Contact", "j" }, 07629 { "Request-Disposition", "d" }, 07630 { "Session-Expires", "x" }, 07631 { "Identity", "y" }, 07632 { "Identity-Info", "n" }, 07633 }; 07634 int x; 07635 07636 for (x = 0; x < ARRAY_LEN(aliases); x++) { 07637 if (!strcasecmp(aliases[x].fullname, name)) 07638 return aliases[x].shortname; 07639 } 07640 07641 return _default; 07642 }
| static int find_by_callid_helper | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1684 of file chan_sip.c.
References CMP_MATCH, CMP_STOP, and ast_cc_agent::private_data.
Referenced by find_sip_cc_agent_by_original_callid().
01685 { 01686 struct ast_cc_agent *agent = obj; 01687 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01688 struct sip_pvt *call_pvt = arg; 01689 01690 return !strcmp(agent_pvt->original_callid, call_pvt->callid) ? CMP_MATCH | CMP_STOP : 0; 01691 }
| static int find_by_name | ( | void * | obj, | |
| void * | arg, | |||
| void * | data, | |||
| int | flags | |||
| ) | [static] |
Definition at line 5221 of file chan_sip.c.
References CMP_MATCH, CMP_STOP, and match().
Referenced by find_peer().
05222 { 05223 struct sip_peer *search = obj, *match = arg; 05224 int *which_objects = data; 05225 05226 /* Usernames in SIP uri's are case sensitive. Domains are not */ 05227 if (strcmp(search->name, match->name)) { 05228 return 0; 05229 } 05230 05231 switch (*which_objects) { 05232 case FINDUSERS: 05233 if (!(search->type & SIP_TYPE_USER)) { 05234 return 0; 05235 } 05236 break; 05237 case FINDPEERS: 05238 if (!(search->type & SIP_TYPE_PEER)) { 05239 return 0; 05240 } 05241 break; 05242 case FINDALLDEVICES: 05243 break; 05244 } 05245 05246 return CMP_MATCH | CMP_STOP; 05247 }
| static int find_by_notify_uri_helper | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1654 of file chan_sip.c.
References CMP_MATCH, CMP_STOP, ast_cc_agent::private_data, and sip_uri_cmp().
Referenced by find_sip_cc_agent_by_notify_uri().
01655 { 01656 struct ast_cc_agent *agent = obj; 01657 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01658 const char *uri = arg; 01659 01660 return !sip_uri_cmp(agent_pvt->notify_uri, uri) ? CMP_MATCH | CMP_STOP : 0; 01661 }
| static int find_by_subscribe_uri_helper | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1669 of file chan_sip.c.
References CMP_MATCH, CMP_STOP, ast_cc_agent::private_data, and sip_uri_cmp().
Referenced by find_sip_cc_agent_by_subscribe_uri().
01670 { 01671 struct ast_cc_agent *agent = obj; 01672 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01673 const char *uri = arg; 01674 01675 return !sip_uri_cmp(agent_pvt->subscribe_uri, uri) ? CMP_MATCH | CMP_STOP : 0; 01676 }
| static struct sip_pvt * find_call | ( | struct sip_request * | req, | |
| struct ast_sockaddr * | addr, | |||
| const int | intended_method | |||
| ) | [static, read] |
find or create a dialog structure for an incoming SIP message. Connect incoming SIP message to current dialog or create new dialog structure Returns a reference to the sip_pvt object, remember to give it back once done. Called by handle_request_do
Definition at line 8382 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_next, ao2_t_callback, ao2_t_find, args, ast_debug, ast_strlen_zero(), match_req_args::authentication_present, match_req_args::callid, dialog_find_multiple(), free_via(), match_req_args::fromtag, get_header(), gettag(), match_req_to_dialog(), match_req_args::method, OBJ_MULTIPLE, OBJ_POINTER, parse_via(), match_req_args::ruri, match_req_args::seqno, sip_alloc(), sip_cfg, sip_methods, sip_pvt_lock, sip_pvt_unlock, SIP_REQ_LOOP_DETECTED, SIP_REQ_MATCH, SIP_REQ_NOT_MATCH, cfsip_methods::text, match_req_args::totag, transmit_response_using_temp(), match_req_args::viabranch, and match_req_args::viasentby.
Referenced by handle_request_do().
08383 { 08384 char totag[128]; 08385 char fromtag[128]; 08386 const char *callid = get_header(req, "Call-ID"); 08387 const char *from = get_header(req, "From"); 08388 const char *to = get_header(req, "To"); 08389 const char *cseq = get_header(req, "Cseq"); 08390 struct sip_pvt *sip_pvt_ptr; 08391 uint32_t seqno; 08392 /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */ 08393 /* get_header always returns non-NULL so we must use ast_strlen_zero() */ 08394 if (ast_strlen_zero(callid) || ast_strlen_zero(to) || 08395 ast_strlen_zero(from) || ast_strlen_zero(cseq) || 08396 (sscanf(cseq, "%30u", &seqno) != 1)) { 08397 08398 /* RFC 3261 section 24.4.1. Send a 400 Bad Request if the request is malformed. */ 08399 if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) { 08400 transmit_response_using_temp(callid, addr, 1, intended_method, 08401 req, "400 Bad Request"); 08402 } 08403 return NULL; /* Invalid packet */ 08404 } 08405 08406 if (sip_cfg.pedanticsipchecking) { 08407 /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy 08408 we need more to identify a branch - so we have to check branch, from 08409 and to tags to identify a call leg. 08410 For Asterisk to behave correctly, you need to turn on pedanticsipchecking 08411 in sip.conf 08412 */ 08413 if (gettag(req, "To", totag, sizeof(totag))) 08414 req->has_to_tag = 1; /* Used in handle_request/response */ 08415 gettag(req, "From", fromtag, sizeof(fromtag)); 08416 08417 ast_debug(5, "= Looking for Call ID: %s (Checking %s) --From tag %s --To-tag %s \n", callid, req->method==SIP_RESPONSE ? "To" : "From", fromtag, totag); 08418 08419 /* All messages must always have From: tag */ 08420 if (ast_strlen_zero(fromtag)) { 08421 ast_debug(5, "%s request has no from tag, dropping callid: %s from: %s\n", sip_methods[req->method].text , callid, from ); 08422 return NULL; 08423 } 08424 /* reject requests that must always have a To: tag */ 08425 if (ast_strlen_zero(totag) && (req->method == SIP_ACK || req->method == SIP_BYE || req->method == SIP_INFO )) { 08426 ast_debug(5, "%s must have a to tag. dropping callid: %s from: %s\n", sip_methods[req->method].text , callid, from ); 08427 return NULL; 08428 } 08429 } 08430 08431 if (!sip_cfg.pedanticsipchecking) { 08432 struct sip_pvt tmp_dialog = { 08433 .callid = callid, 08434 }; 08435 sip_pvt_ptr = ao2_t_find(dialogs, &tmp_dialog, OBJ_POINTER, "ao2_find in dialogs"); 08436 if (sip_pvt_ptr) { /* well, if we don't find it-- what IS in there? */ 08437 /* Found the call */ 08438 return sip_pvt_ptr; 08439 } 08440 } else { /* in pedantic mode! -- do the fancy search */ 08441 struct sip_pvt tmp_dialog = { 08442 .callid = callid, 08443 }; 08444 struct match_req_args args = { 0, }; 08445 int found; 08446 struct ao2_iterator *iterator = ao2_t_callback(dialogs, 08447 OBJ_POINTER | OBJ_MULTIPLE, 08448 dialog_find_multiple, 08449 &tmp_dialog, 08450 "pedantic ao2_find in dialogs"); 08451 struct sip_via *via = NULL; 08452 08453 args.method = req->method; 08454 args.callid = NULL; /* we already matched this. */ 08455 args.totag = totag; 08456 args.fromtag = fromtag; 08457 args.seqno = seqno; 08458 08459 /* If this is a Request, set the Via and Authorization header arguments */ 08460 if (req->method != SIP_RESPONSE) { 08461 args.ruri = REQ_OFFSET_TO_STR(req, rlPart2); 08462 via = parse_via(get_header(req, "Via")); 08463 if (via) { 08464 args.viasentby = via->sent_by; 08465 args.viabranch = via->branch; 08466 } 08467 if (!ast_strlen_zero(get_header(req, "Authorization")) || 08468 !ast_strlen_zero(get_header(req, "Proxy-Authorization"))) { 08469 args.authentication_present = 1; 08470 } 08471 } 08472 08473 /* Iterate a list of dialogs already matched by Call-id */ 08474 while (iterator && (sip_pvt_ptr = ao2_iterator_next(iterator))) { 08475 sip_pvt_lock(sip_pvt_ptr); 08476 found = match_req_to_dialog(sip_pvt_ptr, &args); 08477 sip_pvt_unlock(sip_pvt_ptr); 08478 08479 switch (found) { 08480 case SIP_REQ_MATCH: 08481 ao2_iterator_destroy(iterator); 08482 free_via(via); 08483 return sip_pvt_ptr; /* return pvt with ref */ 08484 case SIP_REQ_LOOP_DETECTED: 08485 /* This is likely a forked Request that somehow resulted in us receiving multiple parts of the fork. 08486 * RFC 3261 section 8.2.2.2, Indicate that we want to merge requests by sending a 482 response. */ 08487 transmit_response_using_temp(callid, addr, 1, intended_method, req, "482 (Loop Detected)"); 08488 dialog_unref(sip_pvt_ptr, "pvt did not match incoming SIP msg, unref from search."); 08489 ao2_iterator_destroy(iterator); 08490 free_via(via); 08491 return NULL; 08492 case SIP_REQ_NOT_MATCH: 08493 default: 08494 dialog_unref(sip_pvt_ptr, "pvt did not match incoming SIP msg, unref from search"); 08495 break; 08496 } 08497 } 08498 if (iterator) { 08499 ao2_iterator_destroy(iterator); 08500 } 08501 08502 free_via(via); 08503 } /* end of pedantic mode Request/Reponse to Dialog matching */ 08504 08505 /* See if the method is capable of creating a dialog */ 08506 if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) { 08507 struct sip_pvt *p = NULL; 08508 08509 if (intended_method == SIP_REFER) { 08510 /* We do support REFER, but not outside of a dialog yet */ 08511 transmit_response_using_temp(callid, addr, 1, intended_method, req, "603 Declined (no dialog)"); 08512 08513 /* Ok, time to create a new SIP dialog object, a pvt */ 08514 } else if (!(p = sip_alloc(callid, addr, 1, intended_method, req))) { 08515 /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not 08516 getting a dialog from sip_alloc. 08517 08518 Without a dialog we can't retransmit and handle ACKs and all that, but at least 08519 send an error message. 08520 08521 Sorry, we apologize for the inconvienience 08522 */ 08523 transmit_response_using_temp(callid, addr, 1, intended_method, req, "500 Server internal error"); 08524 ast_debug(4, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n"); 08525 } 08526 return p; /* can be NULL */ 08527 } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) { 08528 /* A method we do not support, let's take it on the volley */ 08529 transmit_response_using_temp(callid, addr, 1, intended_method, req, "501 Method Not Implemented"); 08530 ast_debug(2, "Got a request with unsupported SIP method.\n"); 08531 } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) { 08532 /* This is a request outside of a dialog that we don't know about */ 08533 transmit_response_using_temp(callid, addr, 1, intended_method, req, "481 Call leg/transaction does not exist"); 08534 ast_debug(2, "That's odd... Got a request in unknown dialog. Callid %s\n", callid ? callid : "<unknown>"); 08535 } 08536 /* We do not respond to responses for dialogs that we don't know about, we just drop 08537 the session quickly */ 08538 if (intended_method == SIP_RESPONSE) 08539 ast_debug(2, "That's odd... Got a response on a call we don't know about. Callid %s\n", callid ? callid : "<unknown>"); 08540 08541 return NULL; 08542 }
| static int find_calling_channel | ( | void * | obj, | |
| void * | arg, | |||
| void * | data, | |||
| int | flags | |||
| ) | [static] |
Find the channel that is causing the RINGING update.
Definition at line 12948 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, CMP_MATCH, CMP_STOP, ast_channel::context, ast_channel::exten, ast_channel::macroexten, ast_channel::pbx, and sip_cfg.
Referenced by state_notify_build_xml().
12949 { 12950 struct ast_channel *c = obj; 12951 struct sip_pvt *p = data; 12952 int res; 12953 12954 ast_channel_lock(c); 12955 12956 res = (c->pbx && 12957 (!strcasecmp(c->macroexten, p->exten) || !strcasecmp(c->exten, p->exten)) && 12958 (sip_cfg.notifycid == IGNORE_CONTEXT || !strcasecmp(c->context, p->context))); 12959 12960 ast_channel_unlock(c); 12961 12962 return res ? CMP_MATCH | CMP_STOP : 0; 12963 }
| const char* find_closing_quote | ( | const char * | start, | |
| const char * | lim | |||
| ) |
Locate closing quote in a string, skipping escaped quotes. optionally with a limit on the search. start must be past the first quote.
Definition at line 4626 of file chan_sip.c.
Referenced by get_comma(), get_in_brackets_const(), get_in_brackets_full(), and parse_moved_contact().
| 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 5262 of file chan_sip.c.
References ao2_t_callback_data, ao2_t_find, ast_copy_string(), ast_set_flag, ast_sockaddr_copy(), find_by_name(), OBJ_POINTER, realtime_peer(), and unref_peer().
Referenced by _sip_qualify_peer(), _sip_show_peer(), check_peer_ok(), create_addr(), function_sippeer(), handle_request_notify(), register_verify(), sip_devicestate(), sip_do_debug_peer(), sip_show_user(), sip_unregister(), and transmit_register().
05263 { 05264 struct sip_peer *p = NULL; 05265 struct sip_peer tmp_peer; 05266 05267 if (peer) { 05268 ast_copy_string(tmp_peer.name, peer, sizeof(tmp_peer.name)); 05269 p = ao2_t_callback_data(peers, OBJ_POINTER, find_by_name, &tmp_peer, &which_objects, "ao2_find in peers table"); 05270 } else if (addr) { /* search by addr? */ 05271 ast_sockaddr_copy(&tmp_peer.addr, addr); 05272 tmp_peer.flags[0].flags = 0; 05273 tmp_peer.transports = transport; 05274 p = ao2_t_find(peers_by_ip, &tmp_peer, OBJ_POINTER, "ao2_find in peers_by_ip table"); /* WAS: p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp); */ 05275 if (!p) { 05276 ast_set_flag(&tmp_peer.flags[0], SIP_INSECURE_PORT); 05277 p = ao2_t_find(peers_by_ip, &tmp_peer, OBJ_POINTER, "ao2_find in peers_by_ip table 2"); /* WAS: p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp); */ 05278 if (p) { 05279 return p; 05280 } 05281 } 05282 } 05283 05284 if (!p && (realtime || devstate_only)) { 05285 p = realtime_peer(peer, addr, devstate_only, which_objects); 05286 if (p) { 05287 switch (which_objects) { 05288 case FINDUSERS: 05289 if (!(p->type & SIP_TYPE_USER)) { 05290 unref_peer(p, "Wrong type of realtime SIP endpoint"); 05291 return NULL; 05292 } 05293 break; 05294 case FINDPEERS: 05295 if (!(p->type & SIP_TYPE_PEER)) { 05296 unref_peer(p, "Wrong type of realtime SIP endpoint"); 05297 return NULL; 05298 } 05299 break; 05300 case FINDALLDEVICES: 05301 break; 05302 } 05303 } 05304 } 05305 05306 return p; 05307 }
| static struct sip_auth * find_realm_authentication | ( | struct sip_auth_container * | credentials, | |
| const char * | realm | |||
| ) | [static, read] |
Definition at line 27911 of file chan_sip.c.
References AST_LIST_TRAVERSE.
Referenced by build_reply_digest().
27912 { 27913 struct sip_auth *auth; 27914 27915 if (credentials) { 27916 AST_LIST_TRAVERSE(&credentials->list, auth, node) { 27917 if (!strcasecmp(auth->realm, realm)) { 27918 break; 27919 } 27920 } 27921 } else { 27922 auth = NULL; 27923 } 27924 27925 return auth; 27926 }
| static int find_sdp | ( | struct sip_request * | req | ) | [static] |
Determine whether a SIP message contains an SDP in its body.
| req | the SIP request to process |
Also updates req->sdp_start and req->sdp_count to indicate where the SDP lives in the message body.
Definition at line 8894 of file chan_sip.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), FALSE, get_header(), LOG_WARNING, and TRUE.
Referenced by handle_incoming(), handle_request_invite(), handle_response(), and handle_response_invite().
08895 { 08896 const char *content_type; 08897 const char *content_length; 08898 const char *search; 08899 char *boundary; 08900 unsigned int x; 08901 int boundaryisquoted = FALSE; 08902 int found_application_sdp = FALSE; 08903 int found_end_of_headers = FALSE; 08904 08905 content_length = get_header(req, "Content-Length"); 08906 08907 if (!ast_strlen_zero(content_length)) { 08908 if (sscanf(content_length, "%30u", &x) != 1) { 08909 ast_log(LOG_WARNING, "Invalid Content-Length: %s\n", content_length); 08910 return 0; 08911 } 08912 08913 /* Content-Length of zero means there can't possibly be an 08914 SDP here, even if the Content-Type says there is */ 08915 if (x == 0) 08916 return 0; 08917 } 08918 08919 content_type = get_header(req, "Content-Type"); 08920 08921 /* if the body contains only SDP, this is easy */ 08922 if (!strncasecmp(content_type, "application/sdp", 15)) { 08923 req->sdp_start = 0; 08924 req->sdp_count = req->lines; 08925 return req->lines ? 1 : 0; 08926 } 08927 08928 /* if it's not multipart/mixed, there cannot be an SDP */ 08929 if (strncasecmp(content_type, "multipart/mixed", 15)) 08930 return 0; 08931 08932 /* if there is no boundary marker, it's invalid */ 08933 if ((search = strcasestr(content_type, ";boundary="))) 08934 search += 10; 08935 else if ((search = strcasestr(content_type, "; boundary="))) 08936 search += 11; 08937 else 08938 return 0; 08939 08940 if (ast_strlen_zero(search)) 08941 return 0; 08942 08943 /* If the boundary is quoted with ", remove quote */ 08944 if (*search == '\"') { 08945 search++; 08946 boundaryisquoted = TRUE; 08947 } 08948 08949 /* make a duplicate of the string, with two extra characters 08950 at the beginning */ 08951 boundary = ast_strdupa(search - 2); 08952 boundary[0] = boundary[1] = '-'; 08953 /* Remove final quote */ 08954 if (boundaryisquoted) 08955 boundary[strlen(boundary) - 1] = '\0'; 08956 08957 /* search for the boundary marker, the empty line delimiting headers from 08958 sdp part and the end boundry if it exists */ 08959 08960 for (x = 0; x < (req->lines); x++) { 08961 const char *line = REQ_OFFSET_TO_STR(req, line[x]); 08962 if (!strncasecmp(line, boundary, strlen(boundary))){ 08963 if (found_application_sdp && found_end_of_headers) { 08964 req->sdp_count = (x - 1) - req->sdp_start; 08965 return 1; 08966 } 08967 found_application_sdp = FALSE; 08968 } 08969 if (!strcasecmp(line, "Content-Type: application/sdp")) 08970 found_application_sdp = TRUE; 08971 08972 if (ast_strlen_zero(line)) { 08973 if (found_application_sdp && !found_end_of_headers){ 08974 req->sdp_start = x; 08975 found_end_of_headers = TRUE; 08976 } 08977 } 08978 } 08979 if (found_application_sdp && found_end_of_headers) { 08980 req->sdp_count = x - req->sdp_start; 08981 return TRUE; 08982 } 08983 return FALSE; 08984 }
| static struct ast_cc_agent* find_sip_cc_agent_by_notify_uri | ( | const char *const | uri | ) | [static, read] |
Definition at line 1663 of file chan_sip.c.
References ast_cc_agent_callback(), and find_by_notify_uri_helper().
Referenced by get_destination().
01664 { 01665 struct ast_cc_agent *agent = ast_cc_agent_callback(0, find_by_notify_uri_helper, (char *)uri, "SIP"); 01666 return agent; 01667 }
| static struct ast_cc_agent* find_sip_cc_agent_by_original_callid | ( | struct sip_pvt * | pvt | ) | [static, read] |
Definition at line 1693 of file chan_sip.c.
References ast_cc_agent_callback(), and find_by_callid_helper().
Referenced by add_cc_call_info_to_response().
01694 { 01695 struct ast_cc_agent *agent = ast_cc_agent_callback(0, find_by_callid_helper, pvt, "SIP"); 01696 return agent; 01697 }
| static struct ast_cc_agent* find_sip_cc_agent_by_subscribe_uri | ( | const char *const | uri | ) | [static, read] |
Definition at line 1678 of file chan_sip.c.
References ast_cc_agent_callback(), and find_by_subscribe_uri_helper().
Referenced by handle_cc_subscribe().
01679 { 01680 struct ast_cc_agent *agent = ast_cc_agent_callback(0, find_by_subscribe_uri_helper, (char *)uri, "SIP"); 01681 return agent; 01682 }
| static int find_sip_method | ( | const char * | msg | ) | [static] |
find_sip_method: Find SIP method from header
Definition at line 3347 of file chan_sip.c.
References ARRAY_LEN, ast_strlen_zero(), cfsip_methods::id, method_match(), and sip_methods.
Referenced by __sip_pretend_ack(), handle_request_do(), handle_response(), mark_parsed_methods(), and sip_hangup().
03348 { 03349 int i, res = 0; 03350 03351 if (ast_strlen_zero(msg)) { 03352 return 0; 03353 } 03354 for (i = 1; i < ARRAY_LEN(sip_methods) && !res; i++) { 03355 if (method_match(i, msg)) { 03356 res = sip_methods[i].id; 03357 } 03358 } 03359 return res; 03360 }
| static int find_sip_monitor_instance_by_subscription_pvt | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1891 of file chan_sip.c.
References CMP_MATCH, and CMP_STOP.
Referenced by handle_cc_notify(), and handle_response_subscribe().
| static int find_sip_monitor_instance_by_suspension_entry | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1897 of file chan_sip.c.
References CMP_MATCH, and CMP_STOP.
Referenced by cc_handle_publish_error().
| static struct epa_static_data* find_static_data | ( | const char *const | event_package | ) | [static, read] |
Definition at line 894 of file chan_sip.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, and AST_LIST_UNLOCK.
Referenced by create_epa_entry().
00895 { 00896 const struct epa_backend *backend = NULL; 00897 00898 AST_LIST_LOCK(&epa_static_data_list); 00899 AST_LIST_TRAVERSE(&epa_static_data_list, backend, next) { 00900 if (!strcmp(backend->static_data->name, event_package)) { 00901 break; 00902 } 00903 } 00904 AST_LIST_UNLOCK(&epa_static_data_list); 00905 return backend ? backend->static_data : NULL; 00906 }
| static struct cfsubscription_types * find_subscription_type | ( | enum subscriptiontype | subtype | ) | [static, read] |
Find subscription type in array.
Definition at line 18958 of file chan_sip.c.
References ARRAY_LEN, subscription_types, and type.
Referenced by transmit_state_notify().
18959 { 18960 int i; 18961 18962 for (i = 1; i < ARRAY_LEN(subscription_types); i++) { 18963 if (subscription_types[i].type == subtype) { 18964 return &subscription_types[i]; 18965 } 18966 } 18967 return &subscription_types[0]; 18968 }
| static void free_old_route | ( | struct sip_route * | route | ) | [static] |
Remove route from route list.
Definition at line 14675 of file chan_sip.c.
References ast_free.
Referenced by __sip_destroy(), and build_route().
14676 { 14677 struct sip_route *next; 14678 14679 while (route) { 14680 next = route->next; 14681 ast_free(route); 14682 route = next; 14683 } 14684 }
| static int func_check_sipdomain | ( | struct ast_channel * | chan, | |
| const char * | cmd, | |||
| char * | data, | |||
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
Dial plan function to check if domain is local.
Definition at line 20094 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_strlen_zero(), check_sip_domain(), and LOG_WARNING.
20095 { 20096 if (ast_strlen_zero(data)) { 20097 ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n"); 20098 return -1; 20099 } 20100 if (check_sip_domain(data, NULL, 0)) 20101 ast_copy_string(buf, data, len); 20102 else 20103 buf[0] = '\0'; 20104 return 0; 20105 }
| static int func_header_read | ( | struct ast_channel * | chan, | |
| const char * | function, | |||
| char * | data, | |||
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
Read SIP header (dialplan function).
Definition at line 20030 of file chan_sip.c.
References __get_header(), args, AST_APP_ARG, ast_channel_lock, ast_channel_unlock, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_strlen_zero(), LOG_WARNING, ast_channel::tech, and ast_channel::tech_pvt.
20031 { 20032 struct sip_pvt *p; 20033 const char *content = NULL; 20034 AST_DECLARE_APP_ARGS(args, 20035 AST_APP_ARG(header); 20036 AST_APP_ARG(number); 20037 ); 20038 int i, number, start = 0; 20039 20040 if (!chan) { 20041 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function); 20042 return -1; 20043 } 20044 20045 if (ast_strlen_zero(data)) { 20046 ast_log(LOG_WARNING, "This function requires a header name.\n"); 20047 return -1; 20048 } 20049 20050 ast_channel_lock(chan); 20051 if (!IS_SIP_TECH(chan->tech)) { 20052 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 20053 ast_channel_unlock(chan); 20054 return -1; 20055 } 20056 20057 AST_STANDARD_APP_ARGS(args, data); 20058 if (!args.number) { 20059 number = 1; 20060 } else { 20061 sscanf(args.number, "%30d", &number); 20062 if (number < 1) 20063 number = 1; 20064 } 20065 20066 p = chan->tech_pvt; 20067 20068 /* If there is no private structure, this channel is no longer alive */ 20069 if (!p) { 20070 ast_channel_unlock(chan); 20071 return -1; 20072 } 20073 20074 for (i = 0; i < number; i++) 20075 content = __get_header(&p->initreq, args.header, &start); 20076 20077 if (ast_strlen_zero(content)) { 20078 ast_channel_unlock(chan); 20079 return -1; 20080 } 20081 20082 ast_copy_string(buf, content, len); 20083 ast_channel_unlock(chan); 20084 20085 return 0; 20086 }
| static int function_sipchaninfo_read | ( | struct ast_channel * | chan, | |
| const char * | cmd, | |||
| char * | data, | |||
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
${SIPCHANINFO()} Dialplan function - reads sip channel data
Definition at line 20212 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_log(), ast_sockaddr_stringify_addr(), LOG_WARNING, ast_channel::tech, and ast_channel::tech_pvt.
20213 { 20214 struct sip_pvt *p; 20215 static int deprecated = 0; 20216 20217 *buf = 0; 20218 20219 if (!chan) { 20220 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd); 20221 return -1; 20222 } 20223 20224 if (!data) { 20225 ast_log(LOG_WARNING, "This function requires a parameter name.\n"); 20226 return -1; 20227 } 20228 20229 ast_channel_lock(chan); 20230 if (!IS_SIP_TECH(chan->tech)) { 20231 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 20232 ast_channel_unlock(chan); 20233 return -1; 20234 } 20235 20236 if (deprecated++ % 20 == 0) { 20237 /* Deprecated in 1.6.1 */ 20238 ast_log(LOG_WARNING, "SIPCHANINFO() is deprecated. Please transition to using CHANNEL().\n"); 20239 } 20240 20241 p = chan->tech_pvt; 20242 20243 /* If there is no private structure, this channel is no longer alive */ 20244 if (!p) { 20245 ast_channel_unlock(chan); 20246 return -1; 20247 } 20248 20249 if (!strcasecmp(data, "peerip")) { 20250 ast_copy_string(buf, ast_sockaddr_stringify_addr(&p->sa), len); 20251 } else if (!strcasecmp(data, "recvip")) { 20252 ast_copy_string(buf, ast_sockaddr_stringify_addr(&p->recv), len); 20253 } else if (!strcasecmp(data, "from")) { 20254 ast_copy_string(buf, p->from, len); 20255 } else if (!strcasecmp(data, "uri")) { 20256 ast_copy_string(buf, p->uri, len); 20257 } else if (!strcasecmp(data, "useragent")) { 20258 ast_copy_string(buf, p->useragent, len); 20259 } else if (!strcasecmp(data, "peername")) { 20260 ast_copy_string(buf, p->peername, len); 20261 } else if (!strcasecmp(data, "t38passthrough")) { 20262 if (p->t38.state == T38_DISABLED) { 20263 ast_copy_string(buf, "0", len); 20264 } else { /* T38 is offered or enabled in this call */ 20265 ast_copy_string(buf, "1", len); 20266 } 20267 } else { 20268 ast_channel_unlock(chan); 20269 return -1; 20270 } 20271 ast_channel_unlock(chan); 20272 20273 return 0; 20274 }
| static int function_sippeer | ( | struct ast_channel * | chan, | |
| const char * | cmd, | |||
| char * | data, | |||
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
${SIPPEER()} Dialplan function - reads peer data
Definition at line 20113 of file chan_sip.c.
References ast_codec_pref_index(), ast_copy_string(), ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_print_group(), ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_str_alloca, ast_str_buffer(), ast_test_flag, chanvar, FALSE, find_peer(), LOG_WARNING, ast_variable::name, ast_variable::next, peer_mailboxes_to_str(), peer_status(), TRUE, unref_peer(), and ast_variable::value.
20114 { 20115 struct sip_peer *peer; 20116 char *colname; 20117 20118 if ((colname = strchr(data, ':'))) { /*! \todo Will be deprecated after 1.4 */ 20119 static int deprecation_warning = 0; 20120 *colname++ = '\0'; 20121 if (deprecation_warning++ % 10 == 0) 20122 ast_log(LOG_WARNING, "SIPPEER(): usage of ':' to separate arguments is deprecated. Please use ',' instead.\n"); 20123 } else if ((colname = strchr(data, ','))) 20124 *colname++ = '\0'; 20125 else 20126 colname = "ip"; 20127 20128 if (!(peer = find_peer(data, NULL, TRUE, FINDPEERS, FALSE, 0))) 20129 return -1; 20130 20131 if (!strcasecmp(colname, "ip")) { 20132 ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len); 20133 } else if (!strcasecmp(colname, "port")) { 20134 snprintf(buf, len, "%d", ast_sockaddr_port(&peer->addr)); 20135 } else if (!strcasecmp(colname, "status")) { 20136 peer_status(peer, buf, len); 20137 } else if (!strcasecmp(colname, "language")) { 20138 ast_copy_string(buf, peer->language, len); 20139 } else if (!strcasecmp(colname, "regexten")) { 20140 ast_copy_string(buf, peer->regexten, len); 20141 } else if (!strcasecmp(colname, "limit")) { 20142 snprintf(buf, len, "%d", peer->call_limit); 20143 } else if (!strcasecmp(colname, "busylevel")) { 20144 snprintf(buf, len, "%d", peer->busy_level); 20145 } else if (!strcasecmp(colname, "curcalls")) { 20146 snprintf(buf, len, "%d", peer->inUse); 20147 } else if (!strcasecmp(colname, "maxforwards")) { 20148 snprintf(buf, len, "%d", peer->maxforwards); 20149 } else if (!strcasecmp(colname, "accountcode")) { 20150 ast_copy_string(buf, peer->accountcode, len); 20151 } else if (!strcasecmp(colname, "callgroup")) { 20152 ast_print_group(buf, len, peer->callgroup); 20153 } else if (!strcasecmp(colname, "pickupgroup")) { 20154 ast_print_group(buf, len, peer->pickupgroup); 20155 } else if (!strcasecmp(colname, "useragent")) { 20156 ast_copy_string(buf, peer->useragent, len); 20157 } else if (!strcasecmp(colname, "mailbox")) { 20158 struct ast_str *mailbox_str = ast_str_alloca(512); 20159 peer_mailboxes_to_str(&mailbox_str, peer); 20160 ast_copy_string(buf, ast_str_buffer(mailbox_str), len); 20161 } else if (!strcasecmp(colname, "context")) { 20162 ast_copy_string(buf, peer->context, len); 20163 } else if (!strcasecmp(colname, "expire")) { 20164 snprintf(buf, len, "%d", peer->expire); 20165 } else if (!strcasecmp(colname, "dynamic")) { 20166 ast_copy_string(buf, peer->host_dynamic ? "yes" : "no", len); 20167 } else if (!strcasecmp(colname, "callerid_name")) { 20168 ast_copy_string(buf, peer->cid_name, len); 20169 } else if (!strcasecmp(colname, "callerid_num")) { 20170 ast_copy_string(buf, peer->cid_num, len); 20171 } else if (!strcasecmp(colname, "codecs")) { 20172 ast_getformatname_multiple(buf, len -1, peer->capability); 20173 } else if (!strcasecmp(colname, "encryption")) { 20174 snprintf(buf, len, "%u", ast_test_flag(&peer->flags[1], SIP_PAGE2_USE_SRTP)); 20175 } else if (!strncasecmp(colname, "chanvar[", 8)) { 20176 char *chanvar=colname + 8; 20177 struct ast_variable *v; 20178 20179 chanvar = strsep(&chanvar, "]"); 20180 for (v = peer->chanvars ; v ; v = v->next) { 20181 if (!strcasecmp(v->name, chanvar)) { 20182 ast_copy_string(buf, v->value, len); 20183 } 20184 } 20185 } else if (!strncasecmp(colname, "codec[", 6)) { 20186 char *codecnum; 20187 format_t codec = 0; 20188 20189 codecnum = colname + 6; /* move past the '[' */ 20190 codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */ 20191 if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) { 20192 ast_copy_string(buf, ast_getformatname(codec), len); 20193 } else { 20194 buf[0] = '\0'; 20195 } 20196 } else { 20197 buf[0] = '\0'; 20198 } 20199 20200 unref_peer(peer, "unref_peer from function_sippeer, just before return"); 20201 20202 return 0; 20203 }
| static char * generate_random_string | ( | char * | buf, | |
| size_t | size | |||
| ) | [static] |
Generate 32 byte random string for callid's etc.
Definition at line 7835 of file chan_sip.c.
References ast_random().
Referenced by build_callid_pvt(), build_callid_registry(), construct_pidf_body(), and generate_uri().
07836 { 07837 long val[4]; 07838 int x; 07839 07840 for (x=0; x<4; x++) 07841 val[x] = ast_random(); 07842 snprintf(buf, size, "%08lx%08lx%08lx%08lx", (unsigned long)val[0], (unsigned long)val[1], (unsigned long)val[2], (unsigned long)val[3]); 07843 07844 return buf; 07845 }
| static char* generate_uri | ( | struct sip_pvt * | pvt, | |
| char * | buf, | |||
| size_t | size | |||
| ) | [static] |
Definition at line 7847 of file chan_sip.c.
References ast_copy_string(), ast_sockaddr_stringify_remote(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_set(), and generate_random_string().
Referenced by add_cc_call_info_to_response(), and transmit_cc_notify().
07848 { 07849 struct ast_str *uri = ast_str_alloca(size); 07850 ast_str_set(&uri, 0, "%s", pvt->socket.type == SIP_TRANSPORT_TLS ? "sips:" : "sip:"); 07851 /* Here would be a great place to generate a UUID, but for now we'll 07852 * use the handy random string generation function we already have 07853 */ 07854 ast_str_append(&uri, 0, "%s", generate_random_string(buf, size)); 07855 ast_str_append(&uri, 0, "@%s", ast_sockaddr_stringify_remote(&pvt->ourip)); 07856 ast_copy_string(buf, ast_str_buffer(uri), size); 07857 return buf; 07858 }
| int get_address_family_filter | ( | unsigned int | transport | ) | [static] |
Helper for dns resolution to filter by address family.
Definition at line 26286 of file chan_sip.c.
References ast_sockaddr_is_any(), ast_sockaddr_is_ipv6(), bindaddr, ast_tcptls_session_args::local_address, and ast_sockaddr::ss.
Referenced by __sip_subscribe_mwi_do(), ast_sockaddr_resolve_first(), ast_sockaddr_resolve_first_transport(), build_peer(), proxy_update(), realtime_peer_by_name(), and transmit_register().
26287 { 26288 const struct ast_sockaddr *addr = NULL; 26289 26290 if ((transport == SIP_TRANSPORT_UDP) || !transport) { 26291 addr = &bindaddr; 26292 } 26293 else if (transport == SIP_TRANSPORT_TCP) { 26294 addr = &sip_tcp_desc.local_address; 26295 } 26296 else if (transport == SIP_TRANSPORT_TLS) { 26297 addr = &sip_tls_desc.local_address; 26298 } 26299 26300 if (ast_sockaddr_is_ipv6(addr) && ast_sockaddr_is_any(addr)) { 26301 return 0; 26302 } 26303 26304 return addr->ss.ss_family; 26305 }
| static int get_also_info | ( | struct sip_pvt * | p, | |
| struct sip_request * | oreq | |||
| ) | [static] |
Call transfer support (old way, deprecated by the IETF).
Definition at line 16348 of file chan_sip.c.
References ast_canmatch_extension(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_log(), ast_string_field_set, ast_strlen_zero(), ast_verbose, context, get_header(), get_in_brackets(), LOG_WARNING, parse_uri_legacy_check(), pbx_builtin_getvar_helper(), S_OR, sip_cfg, sip_debug_test_pvt(), SIP_PEDANTIC_DECODE, and sip_refer_allocate().
Referenced by handle_request_bye().
16349 { 16350 char tmp[256] = "", *c, *a; 16351 struct sip_request *req = oreq ? oreq : &p->initreq; 16352 struct sip_refer *referdata = NULL; 16353 const char *transfer_context = NULL; 16354 16355 if (!p->refer && !sip_refer_allocate(p)) 16356 return -1; 16357 16358 referdata = p->refer; 16359 16360 ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp)); 16361 c = get_in_brackets(tmp); 16362 16363 if (parse_uri_legacy_check(c, "sip:,sips:", &c, NULL, &a, NULL)) { 16364 ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c); 16365 return -1; 16366 } 16367 16368 SIP_PEDANTIC_DECODE(c); 16369 SIP_PEDANTIC_DECODE(a); 16370 16371 if (!ast_strlen_zero(a)) { 16372 ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain)); 16373 } 16374 16375 if (sip_debug_test_pvt(p)) 16376 ast_verbose("Looking for %s in %s\n", c, p->context); 16377 16378 /* Determine transfer context */ 16379 if (p->owner) { 16380 /* By default, use the context in the channel sending the REFER */ 16381 transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT"); 16382 if (ast_strlen_zero(transfer_context)) { 16383 transfer_context = p->owner->macrocontext; 16384 } 16385 } 16386 if (ast_strlen_zero(transfer_context)) { 16387 transfer_context = S_OR(p->context, sip_cfg.default_context); 16388 } 16389 16390 if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) { 16391 /* This is a blind transfer */ 16392 ast_debug(1, "SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context); 16393 ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to)); 16394 ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by)); 16395 ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact)); 16396 /* Set new context */ 16397 ast_string_field_set(p, context, transfer_context); 16398 return 0; 16399 } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) { 16400 return 1; 16401 } 16402 16403 return -1; 16404 }
| static char* get_body | ( | struct sip_request * | req, | |
| char * | name, | |||
| char | delimiter | |||
| ) | [static] |
Get a specific line from the message body.
Definition at line 7590 of file chan_sip.c.
References get_body_by_line(), and len().
Referenced by handle_cc_notify(), handle_request_info(), and handle_request_notify().
07591 { 07592 int x; 07593 int len = strlen(name); 07594 char *r; 07595 07596 for (x = 0; x < req->lines; x++) { 07597 r = get_body_by_line(REQ_OFFSET_TO_STR(req, line[x]), name, len, delimiter); 07598 if (r[0] != '\0') 07599 return r; 07600 } 07601 07602 return ""; 07603 }
| static char* get_body_by_line | ( | const char * | line, | |
| const char * | name, | |||
| int | nameLen, | |||
| char | delimiter | |||
| ) | [static] |
Reads one line of SIP message body.
Definition at line 7535 of file chan_sip.c.
References ast_skip_blanks().
Referenced by get_body(), and get_sdp_iterate().
07536 { 07537 if (!strncasecmp(line, name, nameLen) && line[nameLen] == delimiter) 07538 return ast_skip_blanks(line + nameLen + 1); 07539 07540 return ""; 07541 }
| static int get_cached_mwi | ( | struct sip_peer * | peer, | |
| int * | new, | |||
| int * | old | |||
| ) | [static] |
Get cached MWI info.
Definition at line 26441 of file chan_sip.c.
References ast_event_destroy(), ast_event_get_cached(), ast_event_get_ie_uint(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, AST_LIST_TRAVERSE, mailbox, and S_OR.
Referenced by sip_send_mwi_to_peer().
26442 { 26443 struct sip_mailbox *mailbox; 26444 int in_cache; 26445 26446 in_cache = 0; 26447 AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { 26448 struct ast_event *event; 26449 event = ast_event_get_cached(AST_EVENT_MWI, 26450 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox->mailbox, 26451 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, S_OR(mailbox->context, "default"), 26452 AST_EVENT_IE_END); 26453 if (!event) 26454 continue; 26455 *new += ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS); 26456 *old += ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS); 26457 ast_event_destroy(event); 26458 in_cache = 1; 26459 } 26460 26461 return in_cache; 26462 }
| static void get_crypto_attrib | ( | struct sip_srtp * | srtp, | |
| const char ** | a_crypto | |||
| ) | [static] |
Definition at line 11638 of file chan_sip.c.
References ast_log(), LOG_WARNING, sdp_crypto_attrib(), sdp_crypto_offer(), and sdp_crypto_setup().
Referenced by add_sdp().
11639 { 11640 /* Set encryption properties */ 11641 if (srtp) { 11642 if (!srtp->crypto) { 11643 srtp->crypto = sdp_crypto_setup(); 11644 } 11645 if (srtp->crypto && (sdp_crypto_offer(srtp->crypto) >= 0)) { 11646 *a_crypto = sdp_crypto_attrib(srtp->crypto); 11647 } 11648 11649 if (!*a_crypto) { 11650 ast_log(LOG_WARNING, "No SRTP key management enabled\n"); 11651 } 11652 } 11653 }
| static enum sip_get_dest_result get_destination | ( | struct sip_pvt * | p, | |
| struct sip_request * | oreq, | |||
| int * | cc_recall_core_id | |||
| ) | [static] |
Find out who the call is for.
We use the request uri as a destination. This code assumes authentication has been done, so that the device (peer/user) context is already set.
Definition at line 15892 of file chan_sip.c.
References ao2_ref, ast_canmatch_extension(), ast_cc_agent_recalling(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_free, ast_get_hint(), AST_LIST_EMPTY, ast_log(), AST_MAX_EXTENSION, ast_pickup_ext(), ast_strdup, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_verbose, check_sip_domain(), context, ast_cc_agent::core_id, ast_cc_agent::device_name, exten, extract_host_from_hostport(), find_sip_cc_agent_by_notify_uri(), get_header(), get_in_brackets(), LOG_WARNING, parse_uri_legacy_check(), ast_cc_agent::private_data, RAII_VAR, S_OR, sip_cfg, sip_debug_test_pvt(), sip_methods, SIP_PEDANTIC_DECODE, and cfsip_methods::text.
Referenced by handle_request_invite(), handle_request_options(), and handle_request_subscribe().
15893 { 15894 char tmp[256] = "", *uri, *unused_password, *domain; 15895 RAII_VAR(char *, tmpf, NULL, ast_free); 15896 char *from = NULL; 15897 struct sip_request *req; 15898 char *decoded_uri; 15899 15900 req = oreq; 15901 if (!req) { 15902 req = &p->initreq; 15903 } 15904 15905 /* Find the request URI */ 15906 if (req->rlPart2) 15907 ast_copy_string(tmp, REQ_OFFSET_TO_STR(req, rlPart2), sizeof(tmp)); 15908 15909 uri = ast_strdupa(get_in_brackets(tmp)); 15910 15911 if (parse_uri_legacy_check(uri, "sip:,sips:", &uri, &unused_password, &domain, NULL)) { 15912 ast_log(LOG_WARNING, "Not a SIP header (%s)?\n", uri); 15913 return SIP_GET_DEST_INVALID_URI; 15914 } 15915 15916 SIP_PEDANTIC_DECODE(domain); 15917 SIP_PEDANTIC_DECODE(uri); 15918 15919 extract_host_from_hostport(&domain); 15920 15921 if (ast_strlen_zero(uri)) { 15922 /* 15923 * Either there really was no extension found or the request 15924 * URI had encoded nulls that made the string "empty". Use "s" 15925 * as the extension. 15926 */ 15927 uri = "s"; 15928 } 15929 15930 ast_string_field_set(p, domain, domain); 15931 15932 /* Now find the From: caller ID and name */ 15933 /* XXX Why is this done in get_destination? Isn't it already done? 15934 Needs to be checked 15935 */ 15936 tmpf = ast_strdup(get_header(req, "From")); 15937 if (!ast_strlen_zero(tmpf)) { 15938 from = get_in_brackets(tmpf); 15939 if (parse_uri_legacy_check(from, "sip:,sips:", &from, NULL, &domain, NULL)) { 15940 ast_log(LOG_WARNING, "Not a SIP header (%s)?\n", from); 15941 return SIP_GET_DEST_INVALID_URI; 15942 } 15943 15944 SIP_PEDANTIC_DECODE(from); 15945 SIP_PEDANTIC_DECODE(domain); 15946 15947 extract_host_from_hostport(&domain); 15948 15949 ast_string_field_set(p, fromdomain, domain); 15950 } 15951 15952 if (!AST_LIST_EMPTY(&domain_list)) { 15953 char domain_context[AST_MAX_EXTENSION]; 15954 15955 domain_context[0] = '\0'; 15956 if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) { 15957 if (!sip_cfg.allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) { 15958 ast_debug(1, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain); 15959 return SIP_GET_DEST_REFUSED; 15960 } 15961 } 15962 /* If we don't have a peer (i.e. we're a guest call), 15963 * overwrite the original context */ 15964 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_HAVEPEERCONTEXT) && !ast_strlen_zero(domain_context)) { 15965 ast_string_field_set(p, context, domain_context); 15966 } 15967 } 15968 15969 /* If the request coming in is a subscription and subscribecontext has been specified use it */ 15970 if (req->method == SIP_SUBSCRIBE && !ast_strlen_zero(p->subscribecontext)) { 15971 ast_string_field_set(p, context, p->subscribecontext); 15972 } 15973 15974 if (sip_debug_test_pvt(p)) { 15975 ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain); 15976 } 15977 15978 /* Since extensions.conf can have unescaped characters, try matching a 15979 * decoded uri in addition to the non-decoded uri. */ 15980 decoded_uri = ast_strdupa(uri); 15981 ast_uri_decode(decoded_uri); 15982 15983 /* If this is a subscription we actually just need to see if a hint exists for the extension */ 15984 if (req->method == SIP_SUBSCRIBE) { 15985 char hint[AST_MAX_EXTENSION]; 15986 int which = 0; 15987 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, uri) || 15988 (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, decoded_uri) && (which = 1))) { 15989 if (!oreq) { 15990 ast_string_field_set(p, exten, which ? decoded_uri : uri); 15991 } 15992 return SIP_GET_DEST_EXTEN_FOUND; 15993 } else { 15994 return SIP_GET_DEST_EXTEN_NOT_FOUND; 15995 } 15996 } else { 15997 struct ast_cc_agent *agent; 15998 /* Check the dialplan for the username part of the request URI, 15999 the domain will be stored in the SIPDOMAIN variable 16000 Return 0 if we have a matching extension */ 16001 if (ast_exists_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from))) { 16002 if (!oreq) { 16003 ast_string_field_set(p, exten, uri); 16004 } 16005 return SIP_GET_DEST_EXTEN_FOUND; 16006 } 16007 if (ast_exists_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from)) 16008 || !strcmp(decoded_uri, ast_pickup_ext())) { 16009 if (!oreq) { 16010 ast_string_field_set(p, exten, decoded_uri); 16011 } 16012 return SIP_GET_DEST_EXTEN_FOUND; 16013 } 16014 if ((agent = find_sip_cc_agent_by_notify_uri(tmp))) { 16015 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 16016 /* This is a CC recall. We can set p's extension to the exten from 16017 * the original INVITE 16018 */ 16019 ast_string_field_set(p, exten, agent_pvt->original_exten); 16020 /* And we need to let the CC core know that the caller is attempting 16021 * his recall 16022 */ 16023 ast_cc_agent_recalling(agent->core_id, "SIP caller %s is attempting recall", 16024 agent->device_name); 16025 if (cc_recall_core_id) { 16026 *cc_recall_core_id = agent->core_id; 16027 } 16028 ao2_ref(agent, -1); 16029 return SIP_GET_DEST_EXTEN_FOUND; 16030 } 16031 } 16032 16033 if (ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) 16034 && (ast_canmatch_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from)) 16035 || ast_canmatch_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from)) 16036 || !strncmp(decoded_uri, ast_pickup_ext(), strlen(decoded_uri)))) { 16037 /* Overlap dialing is enabled and we need more digits to match an extension. */ 16038 return SIP_GET_DEST_EXTEN_MATCHMORE; 16039 } 16040 16041 return SIP_GET_DEST_EXTEN_NOT_FOUND; 16042 }
| static int get_domain | ( | const char * | str, | |
| char * | domain, | |||
| int | len | |||
| ) | [static] |
Extract domain from SIP To/From header.
Definition at line 11104 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_strlen_zero(), get_in_brackets(), and LOG_WARNING.
Referenced by get_realm().
11105 { 11106 char tmpf[256]; 11107 char *a, *from; 11108 11109 *domain = '\0'; 11110 ast_copy_string(tmpf, str, sizeof(tmpf)); 11111 from = get_in_brackets(tmpf); 11112 if (!ast_strlen_zero(from)) { 11113 if (strncasecmp(from, "sip:", 4)) { 11114 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from); 11115 return -1; 11116 } 11117 from += 4; 11118 } else 11119 from = NULL; 11120 11121 if (from) { 11122 int bracket = 0; 11123 11124 /* Strip any params or options from user */ 11125 if ((a = strchr(from, ';'))) 11126 *a = '\0'; 11127 /* Strip port from domain if present */ 11128 for (a = from; *a != '\0'; ++a) { 11129 if (*a == ':' && bracket == 0) { 11130 *a = '\0'; 11131 break; 11132 } else if (*a == '[') { 11133 ++bracket; 11134 } else if (*a == ']') { 11135 --bracket; 11136 } 11137 } 11138 if ((a = strchr(from, '@'))) { 11139 *a = '\0'; 11140 ast_copy_string(domain, a + 1, len); 11141 } else 11142 ast_copy_string(domain, from, len); 11143 } 11144 11145 return ast_strlen_zero(domain); 11146 }
| static struct event_state_compositor* get_esc | ( | const char *const | event_package | ) | [static, read] |
Definition at line 988 of file chan_sip.c.
References ARRAY_LEN, event_state_compositors, and name.
Referenced by create_new_sip_etag(), handle_request_publish(), and publish_expire().
00988 { 00989 int i; 00990 for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) { 00991 if (!strcasecmp(event_package, event_state_compositors[i].name)) { 00992 return &event_state_compositors[i]; 00993 } 00994 } 00995 return NULL; 00996 }
| static struct sip_esc_entry* get_esc_entry | ( | const char * | entity_tag, | |
| struct event_state_compositor * | esc | |||
| ) | [static, read] |
Definition at line 998 of file chan_sip.c.
References ao2_find, ast_copy_string(), event_state_compositor::compositor, and OBJ_POINTER.
Referenced by handle_sip_publish_modify(), handle_sip_publish_refresh(), and handle_sip_publish_remove().
00998 { 00999 struct sip_esc_entry *entry; 01000 struct sip_esc_entry finder; 01001 01002 ast_copy_string(finder.entity_tag, entity_tag, sizeof(finder.entity_tag)); 01003 01004 entry = ao2_find(esc->compositor, &finder, OBJ_POINTER); 01005 01006 return entry; 01007 }
| static const char * get_header | ( | const struct sip_request * | req, | |
| const char * | name | |||
| ) | [static] |
Get header from SIP request.
Definition at line 7684 of file chan_sip.c.
References __get_header().
Referenced by __transmit_response(), build_route(), cc_handle_publish_error(), change_redirecting_information(), check_auth(), check_user_full(), check_via(), check_via_response(), copy_header(), extract_uri(), find_call(), find_sdp(), get_also_info(), get_destination(), get_pai(), get_rdnis(), get_realm(), get_refer_info(), get_rpid(), gettag(), handle_cc_notify(), handle_cc_subscribe(), handle_incoming(), handle_request_bye(), handle_request_do(), handle_request_info(), handle_request_invite(), handle_request_invite_st(), handle_request_notify(), handle_request_options(), handle_request_publish(), handle_request_register(), handle_request_subscribe(), handle_request_update(), handle_response(), handle_response_invite(), handle_response_notify(), handle_response_publish(), handle_response_refer(), handle_response_register(), handle_response_subscribe(), handle_response_update(), parse_allowed_methods(), parse_moved_contact(), parse_ok_contact(), parse_register_contact(), proc_422_rsp(), process_via(), receive_message(), register_verify(), reply_digest(), reqprep(), respprep(), send_request(), send_response(), sip_alloc(), sip_get_cc_information(), sip_sipredirect(), transmit_fake_auth_response(), transmit_refer(), transmit_response_with_auth(), transmit_response_with_sdp(), transmit_response_with_t38_sdp(), and transmit_state_notify().
07685 { 07686 int start = 0; 07687 return __get_header(req, name, &start); 07688 }
| static struct ast_variable * get_insecure_variable_from_config | ( | struct ast_config * | config | ) | [static, read] |
Definition at line 4891 of file chan_sip.c.
References ast_category_browse(), ast_category_root(), ast_test_flag, ast_variable_retrieve(), set_insecure_flags(), and var.
Referenced by get_insecure_variable_from_sippeers().
04892 { 04893 struct ast_variable *var = NULL; 04894 struct ast_flags flags = {0}; 04895 char *cat = NULL; 04896 const char *insecure; 04897 while ((cat = ast_category_browse(cfg, cat))) { 04898 insecure = ast_variable_retrieve(cfg, cat, "insecure"); 04899 set_insecure_flags(&flags, insecure, -1); 04900 if (ast_test_flag(&flags, SIP_INSECURE_PORT)) { 04901 var = ast_category_root(cfg, cat); 04902 break; 04903 } 04904 } 04905 return var; 04906 }
| static struct ast_variable* get_insecure_variable_from_sippeers | ( | const char * | column, | |
| const char * | value | |||
| ) | [static, read] |
Definition at line 4908 of file chan_sip.c.
References ast_config_destroy(), ast_load_realtime_multientry(), ast_variables_dup(), get_insecure_variable_from_config(), SENTINEL, and var.
Referenced by realtime_peer_by_addr().
04909 { 04910 struct ast_config *peerlist; 04911 struct ast_variable *var = NULL; 04912 if ((peerlist = ast_load_realtime_multientry("sippeers", column, value, "insecure LIKE", "%port%", SENTINEL))) { 04913 if ((var = get_insecure_variable_from_config(peerlist))) { 04914 /* Must clone, because var will get freed along with 04915 * peerlist. */ 04916 var = ast_variables_dup(var); 04917 } 04918 ast_config_destroy(peerlist); 04919 } 04920 return var; 04921 }
| static struct ast_variable* get_insecure_variable_from_sipregs | ( | const char * | column, | |
| const char * | value, | |||
| struct ast_variable ** | var | |||
| ) | [static, read] |
Definition at line 4928 of file chan_sip.c.
References ast_category_browse(), ast_category_root(), ast_config_destroy(), ast_load_realtime_multientry(), ast_test_flag, ast_variable_retrieve(), ast_variables_destroy(), ast_variables_dup(), SENTINEL, and set_insecure_flags().
Referenced by realtime_peer_by_addr().
04929 { 04930 struct ast_variable *varregs = NULL; 04931 struct ast_config *regs, *peers; 04932 char *regscat; 04933 const char *regname; 04934 04935 if (!(regs = ast_load_realtime_multientry("sipregs", column, value, SENTINEL))) { 04936 return NULL; 04937 } 04938 04939 /* Load *all* peers that are probably insecure=port */ 04940 if (!(peers = ast_load_realtime_multientry("sippeers", "insecure LIKE", "%port%", SENTINEL))) { 04941 ast_config_destroy(regs); 04942 return NULL; 04943 } 04944 04945 /* Loop over the sipregs that match IP address and attempt to find an 04946 * insecure=port match to it in sippeers. */ 04947 regscat = NULL; 04948 while ((regscat = ast_category_browse(regs, regscat)) && (regname = ast_variable_retrieve(regs, regscat, "name"))) { 04949 char *peerscat; 04950 const char *peername; 04951 04952 peerscat = NULL; 04953 while ((peerscat = ast_category_browse(peers, peerscat)) && (peername = ast_variable_retrieve(peers, peerscat, "name"))) { 04954 if (!strcasecmp(regname, peername)) { 04955 /* Ensure that it really is insecure=port and 04956 * not something else. */ 04957 const char *insecure = ast_variable_retrieve(peers, peerscat, "insecure"); 04958 struct ast_flags flags = {0}; 04959 set_insecure_flags(&flags, insecure, -1); 04960 if (ast_test_flag(&flags, SIP_INSECURE_PORT)) { 04961 /* ENOMEM checks till the bitter end. */ 04962 if ((varregs = ast_variables_dup(ast_category_root(regs, regscat)))) { 04963 if (!(*var = ast_variables_dup(ast_category_root(peers, peerscat)))) { 04964 ast_variables_destroy(varregs); 04965 varregs = NULL; 04966 } 04967 } 04968 goto done; 04969 } 04970 } 04971 } 04972 } 04973 04974 done: 04975 ast_config_destroy(regs); 04976 ast_config_destroy(peers); 04977 return varregs; 04978 }
| static int get_ip_and_port_from_sdp | ( | struct sip_request * | req, | |
| const enum media_type | media, | |||
| struct ast_sockaddr * | addr | |||
| ) | [static] |
Definition at line 9019 of file chan_sip.c.
References ast_log(), ast_sockaddr_resolve_first_af(), ast_strlen_zero(), get_sdp_iterate(), len(), and LOG_WARNING.
Referenced by handle_request_invite().
09020 { 09021 const char *m; 09022 const char *c; 09023 int miterator = req->sdp_start; 09024 int citerator = req->sdp_start; 09025 unsigned int x = 0; 09026 unsigned int numberofports; 09027 int len; 09028 int af; 09029 char proto[4], host[258] = ""; /*Initialize to empty so we will know if we have any input */ 09030 09031 c = get_sdp_iterate(&citerator, req, "c"); 09032 if (sscanf(c, "IN %3s %256s", proto, host) != 2) { 09033 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 09034 /* Continue since there may be a valid host in a c= line specific to the audio stream */ 09035 } 09036 /* We only want the m and c lines for audio */ 09037 for (m = get_sdp_iterate(&miterator, req, "m"); !ast_strlen_zero(m); m = get_sdp_iterate(&miterator, req, "m")) { 09038 if ((media == SDP_AUDIO && ((sscanf(m, "audio %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 09039 (sscanf(m, "audio %30u RTP/AVP %n", &x, &len) == 1 && len > 0))) || 09040 (media == SDP_VIDEO && ((sscanf(m, "video %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 09041 (sscanf(m, "video %30u RTP/AVP %n", &x, &len) == 1 && len > 0)))) { 09042 /* See if there's a c= line for this media stream. 09043 * XXX There is no guarantee that we'll be grabbing the c= line for this 09044 * particular media stream here. However, this is the same logic used in process_sdp. 09045 */ 09046 c = get_sdp_iterate(&citerator, req, "c"); 09047 if (!ast_strlen_zero(c)) { 09048 sscanf(c, "IN %3s %256s", proto, host); 09049 } 09050 break; 09051 } 09052 } 09053 09054 if (!strcmp("IP4", proto)) { 09055 af = AF_INET; 09056 } else if (!strcmp("IP6", proto)) { 09057 af = AF_INET6; 09058 } else { 09059 ast_log(LOG_WARNING, "Unknown protocol '%s'.\n", proto); 09060 return -1; 09061 } 09062 09063 if (ast_strlen_zero(host) || x == 0) { 09064 ast_log(LOG_WARNING, "Failed to read an alternate host or port in SDP. Expect %s problems\n", media == SDP_AUDIO ? "audio" : "video"); 09065 return -1; 09066 } 09067 09068 if (ast_sockaddr_resolve_first_af(addr, host, 0, af)) { 09069 ast_log(LOG_WARNING, "Could not look up IP address of alternate hostname. Expect %s problems\n", media == SDP_AUDIO? "audio" : "video"); 09070 return -1; 09071 } 09072 09073 return 0; 09074 }
| static int get_msg_text | ( | char * | buf, | |
| int | len, | |||
| struct sip_request * | req | |||
| ) | [static] |
Get message body from a SIP request.
| buf | Destination buffer | |
| len | Destination buffer size | |
| req | The SIP request |
When parsing the request originally, the lines are split by LF or CRLF. This function adds a single LF after every line.
Definition at line 16860 of file chan_sip.c.
Referenced by handle_request_info(), handle_request_notify(), and receive_message().
16861 { 16862 int x; 16863 int linelen; 16864 16865 buf[0] = '\0'; 16866 --len; /* reserve strncat null */ 16867 for (x = 0; len && x < req->lines; ++x) { 16868 const char *line = REQ_OFFSET_TO_STR(req, line[x]); 16869 strncat(buf, line, len); /* safe */ 16870 linelen = strlen(buf); 16871 buf += linelen; 16872 len -= linelen; 16873 if (len) { 16874 strcat(buf, "\n"); /* safe */ 16875 ++buf; 16876 --len; 16877 } 16878 } 16879 return 0; 16880 }
| static const char * get_name_from_variable | ( | const struct ast_variable * | var | ) | [static] |
Definition at line 4980 of file chan_sip.c.
References ast_strlen_zero(), ast_variable::name, ast_variable::next, and ast_variable::value.
Referenced by realtime_peer_by_addr(), and realtime_peer_get_sippeer_helper().
04981 { 04982 /* Don't expect this to return non-NULL. Both NULL and empty 04983 * values can cause the option to get removed from the variable 04984 * list. This is called on ast_variables gotten from both 04985 * ast_load_realtime and ast_load_realtime_multientry. 04986 * - ast_load_realtime removes options with empty values 04987 * - ast_load_realtime_multientry does not! 04988 * For consistent behaviour, we check for the empty name and 04989 * return NULL instead. */ 04990 const struct ast_variable *tmp; 04991 for (tmp = var; tmp; tmp = tmp->next) { 04992 if (!strcasecmp(tmp->name, "name")) { 04993 if (!ast_strlen_zero(tmp->value)) { 04994 return tmp->value; 04995 } 04996 break; 04997 } 04998 } 04999 return NULL; 05000 }
| static void get_our_media_address | ( | struct sip_pvt * | p, | |
| int | needvideo, | |||
| int | needtext, | |||
| struct ast_sockaddr * | addr, | |||
| struct ast_sockaddr * | vaddr, | |||
| struct ast_sockaddr * | taddr, | |||
| struct ast_sockaddr * | dest, | |||
| struct ast_sockaddr * | vdest, | |||
| struct ast_sockaddr * | tdest | |||
| ) | [static] |
Set all IP media addresses for this call.
Definition at line 11545 of file chan_sip.c.
References ast_rtp_instance_get_local_address(), ast_sockaddr_cmp_addr(), ast_sockaddr_copy(), ast_sockaddr_is_any(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_set_port, and media_address.
Referenced by add_sdp().
11549 { 11550 int use_externip = 0; 11551 11552 /* First, get our address */ 11553 ast_rtp_instance_get_local_address(p->rtp, addr); 11554 if (p->vrtp) { 11555 ast_rtp_instance_get_local_address(p->vrtp, vaddr); 11556 } 11557 if (p->trtp) { 11558 ast_rtp_instance_get_local_address(p->trtp, taddr); 11559 } 11560 11561 /* If our real IP differs from the local address returned by the RTP engine, use it. */ 11562 /* The premise is that if we are already using that IP to communicate with the client, */ 11563 /* we should be using it for RTP too. */ 11564 use_externip = ast_sockaddr_cmp_addr(&p->ourip, addr); 11565 11566 /* Now, try to figure out where we want them to send data */ 11567 /* Is this a re-invite to move the media out, then use the original offer from caller */ 11568 if (!ast_sockaddr_isnull(&p->redirip)) { /* If we have a redirection IP, use it */ 11569 ast_sockaddr_copy(dest, &p->redirip); 11570 } else { 11571 /* 11572 * Audio Destination IP: 11573 * 11574 * 1. Specifically configured media address. 11575 * 2. Local address as specified by the RTP engine. 11576 * 3. The local IP as defined by chan_sip. 11577 * 11578 * Audio Destination Port: 11579 * 11580 * 1. Provided by the RTP engine. 11581 */ 11582 ast_sockaddr_copy(dest, 11583 !ast_sockaddr_isnull(&media_address) ? &media_address : 11584 !ast_sockaddr_is_any(addr) && !use_externip ? addr : 11585 &p->ourip); 11586 ast_sockaddr_set_port(dest, ast_sockaddr_port(addr)); 11587 } 11588 11589 if (needvideo) { 11590 /* Determine video destination */ 11591 if (!ast_sockaddr_isnull(&p->vredirip)) { 11592 ast_sockaddr_copy(vdest, &p->vredirip); 11593 } else { 11594 /* 11595 * Video Destination IP: 11596 * 11597 * 1. Specifically configured media address. 11598 * 2. Local address as specified by the RTP engine. 11599 * 3. The local IP as defined by chan_sip. 11600 * 11601 * Video Destination Port: 11602 * 11603 * 1. Provided by the RTP engine. 11604 */ 11605 ast_sockaddr_copy(vdest, 11606 !ast_sockaddr_isnull(&media_address) ? &media_address : 11607 !ast_sockaddr_is_any(vaddr) && !use_externip ? vaddr : 11608 &p->ourip); 11609 ast_sockaddr_set_port(vdest, ast_sockaddr_port(vaddr)); 11610 } 11611 } 11612 11613 if (needtext) { 11614 /* Determine text destination */ 11615 if (!ast_sockaddr_isnull(&p->tredirip)) { 11616 ast_sockaddr_copy(tdest, &p->tredirip); 11617 } else { 11618 /* 11619 * Text Destination IP: 11620 * 11621 * 1. Specifically configured media address. 11622 * 2. Local address as specified by the RTP engine. 11623 * 3. The local IP as defined by chan_sip. 11624 * 11625 * Text Destination Port: 11626 * 11627 * 1. Provided by the RTP engine. 11628 */ 11629 ast_sockaddr_copy(tdest, 11630 !ast_sockaddr_isnull(&media_address) ? &media_address : 11631 !ast_sockaddr_is_any(taddr) && !use_externip ? taddr : 11632 &p->ourip); 11633 ast_sockaddr_set_port(tdest, ast_sockaddr_port(taddr)); 11634 } 11635 } 11636 }
| static int get_pai | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Parse the parts of the P-Asserted-Identity header on an incoming packet. Returns 1 if a valid header is found and it is different from the current caller id.
Definition at line 15599 of file chan_sip.c.
References ast_copy_string(), ast_free, ast_is_shrinkable_phonenumber(), AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, ast_set_callerid(), ast_shrink_phone_number(), ast_string_field_set, ast_strlen_zero(), cid_name, cid_num, get_header(), get_in_brackets(), and get_name_and_number().
Referenced by get_rpid().
15600 { 15601 char pai[256]; 15602 char privacy[64]; 15603 char *cid_num = NULL; 15604 char *cid_name = NULL; 15605 char emptyname[1] = ""; 15606 int callingpres = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 15607 char *uri = NULL; 15608 int is_anonymous = 0, do_update = 1, no_name = 0; 15609 15610 ast_copy_string(pai, get_header(req, "P-Asserted-Identity"), sizeof(pai)); 15611 15612 if (ast_strlen_zero(pai)) { 15613 return 0; 15614 } 15615 15616 /* use the reqresp_parser function get_name_and_number*/ 15617 if (get_name_and_number(pai, &cid_name, &cid_num)) { 15618 return 0; 15619 } 15620 15621 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(cid_num)) { 15622 ast_shrink_phone_number(cid_num); 15623 } 15624 15625 uri = get_in_brackets(pai); 15626 if (!strncasecmp(uri, "sip:anonymous@anonymous.invalid", 31)) { 15627 callingpres = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 15628 /*XXX Assume no change in cid_num. Perhaps it should be 15629 * blanked? 15630 */ 15631 ast_free(cid_num); 15632 is_anonymous = 1; 15633 cid_num = (char *)p->cid_num; 15634 } 15635 15636 ast_copy_string(privacy, get_header(req, "Privacy"), sizeof(privacy)); 15637 if (!ast_strlen_zero(privacy) && !strncmp(privacy, "id", 2)) { 15638 callingpres = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 15639 } 15640 if (!cid_name) { 15641 no_name = 1; 15642 cid_name = (char *)emptyname; 15643 } 15644 /* Only return true if the supplied caller id is different */ 15645 if (!strcasecmp(p->cid_num, cid_num) && !strcasecmp(p->cid_name, cid_name) && p->callingpres == callingpres) { 15646 do_update = 0; 15647 } else { 15648 15649 ast_string_field_set(p, cid_num, cid_num); 15650 ast_string_field_set(p, cid_name, cid_name); 15651 p->callingpres = callingpres; 15652 15653 if (p->owner) { 15654 ast_set_callerid(p->owner, cid_num, cid_name, NULL); 15655 p->owner->caller.id.name.presentation = callingpres; 15656 p->owner->caller.id.number.presentation = callingpres; 15657 } 15658 } 15659 15660 /* get_name_and_number allocates memory for cid_num and cid_name so we have to free it */ 15661 if (!is_anonymous) { 15662 ast_free(cid_num); 15663 } 15664 if (!no_name) { 15665 ast_free(cid_name); 15666 } 15667 15668 return do_update; 15669 }
| static int get_rdnis | ( | struct sip_pvt * | p, | |
| struct sip_request * | oreq, | |||
| char ** | name, | |||
| char ** | number, | |||
| int * | reason | |||
| ) | [static] |
Get referring dnis.
Definition at line 15792 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_strdup, ast_strip_quoted(), ast_strlen_zero(), ast_verbose, exten, get_header(), get_in_brackets(), LOG_WARNING, pbx_builtin_setvar_helper(), S_OR, sip_debug_test_pvt(), sip_reason_str_to_code(), and sip_set_redirstr().
Referenced by change_redirecting_information().
15793 { 15794 char tmp[256], *exten, *rexten, *rdomain, *rname = NULL; 15795 char *params, *reason_param = NULL; 15796 struct sip_request *req; 15797 15798 req = oreq ? oreq : &p->initreq; 15799 15800 ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp)); 15801 if (ast_strlen_zero(tmp)) 15802 return -1; 15803 15804 if ((params = strchr(tmp, '>'))) { 15805 params = strchr(params, ';'); 15806 } 15807 15808 exten = get_in_brackets(tmp); 15809 if (!strncasecmp(exten, "sip:", 4)) { 15810 exten += 4; 15811 } else if (!strncasecmp(exten, "sips:", 5)) { 15812 exten += 5; 15813 } else { 15814 ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", exten); 15815 return -1; 15816 } 15817 15818 /* Get diversion-reason param if present */ 15819 if (params) { 15820 *params = '\0'; /* Cut off parameters */ 15821 params++; 15822 while (*params == ';' || *params == ' ') 15823 params++; 15824 /* Check if we have a reason parameter */ 15825 if ((reason_param = strcasestr(params, "reason="))) { 15826 char *end; 15827 reason_param+=7; 15828 if ((end = strchr(reason_param, ';'))) { 15829 *end = '\0'; 15830 } 15831 /* Remove enclosing double-quotes */ 15832 if (*reason_param == '"') 15833 reason_param = ast_strip_quoted(reason_param, "\"", "\""); 15834 if (!ast_strlen_zero(reason_param)) { 15835 sip_set_redirstr(p, reason_param); 15836 if (p->owner) { 15837 pbx_builtin_setvar_helper(p->owner, "__PRIREDIRECTREASON", p->redircause); 15838 pbx_builtin_setvar_helper(p->owner, "__SIPREDIRECTREASON", reason_param); 15839 } 15840 } 15841 } 15842 } 15843 15844 rdomain = exten; 15845 rexten = strsep(&rdomain, "@"); /* trim anything after @ */ 15846 if (p->owner) 15847 pbx_builtin_setvar_helper(p->owner, "__SIPRDNISDOMAIN", rdomain); 15848 15849 if (sip_debug_test_pvt(p)) 15850 ast_verbose("RDNIS for this call is %s (reason %s)\n", exten, S_OR(reason_param, "")); 15851 15852 /*ast_string_field_set(p, rdnis, rexten);*/ 15853 15854 if (*tmp == '\"') { 15855 char *end_quote; 15856 rname = tmp + 1; 15857 end_quote = strchr(rname, '\"'); 15858 if (end_quote) { 15859 *end_quote = '\0'; 15860 } 15861 } 15862 15863 if (number) { 15864 *number = ast_strdup(rexten); 15865 } 15866 15867 if (name && rname) { 15868 *name = ast_strdup(rname); 15869 } 15870 15871 if (reason && !ast_strlen_zero(reason_param)) { 15872 *reason = sip_reason_str_to_code(reason_param); 15873 } 15874 15875 return 0; 15876 }
| static void get_realm | ( | struct sip_pvt * | p, | |
| const struct sip_request * | req | |||
| ) | [static] |
Choose realm based on From header and then To header or use globaly configured realm. Realm from From/To header should be listed among served domains in config file: domain=...
Definition at line 11152 of file chan_sip.c.
References AST_LIST_EMPTY, ast_string_field_set, ast_strlen_zero(), check_sip_domain(), get_domain(), get_header(), MAXHOSTNAMELEN, and sip_cfg.
Referenced by transmit_response_with_auth().
11153 { 11154 char domain[MAXHOSTNAMELEN]; 11155 11156 if (!ast_strlen_zero(p->realm)) 11157 return; 11158 11159 if (sip_cfg.domainsasrealm && 11160 !AST_LIST_EMPTY(&domain_list)) 11161 { 11162 /* Check From header first */ 11163 if (!get_domain(get_header(req, "From"), domain, sizeof(domain))) { 11164 if (check_sip_domain(domain, NULL, 0)) { 11165 ast_string_field_set(p, realm, domain); 11166 return; 11167 } 11168 } 11169 /* Check To header */ 11170 if (!get_domain(get_header(req, "To"), domain, sizeof(domain))) { 11171 if (check_sip_domain(domain, NULL, 0)) { 11172 ast_string_field_set(p, realm, domain); 11173 return; 11174 } 11175 } 11176 } 11177 11178 /* Use default realm from config file */ 11179 ast_string_field_set(p, realm, sip_cfg.realm); 11180 }
| static int get_refer_info | ( | struct sip_pvt * | transferer, | |
| struct sip_request * | outgoing_req | |||
| ) | [static] |
Call transfer support (the REFER method) Extracts Refer headers into pvt dialog structure.
Definition at line 16139 of file chan_sip.c.
References ast_bridged_channel(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_uri_decode(), ast_verbose, ast_channel::context, get_header(), get_in_brackets(), LOG_WARNING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), S_OR, sip_cfg, sip_debug_test_pvt(), and SIP_PEDANTIC_DECODE.
Referenced by handle_request_refer().
16140 { 16141 16142 const char *p_referred_by = NULL; 16143 char *h_refer_to = NULL; 16144 char *h_referred_by = NULL; 16145 char *refer_to; 16146 const char *p_refer_to; 16147 char *referred_by_uri = NULL; 16148 char *ptr; 16149 struct sip_request *req = NULL; 16150 const char *transfer_context = NULL; 16151 struct sip_refer *referdata; 16152 16153 16154 req = outgoing_req; 16155 referdata = transferer->refer; 16156 16157 if (!req) { 16158 req = &transferer->initreq; 16159 } 16160 16161 p_refer_to = get_header(req, "Refer-To"); 16162 if (ast_strlen_zero(p_refer_to)) { 16163 ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n"); 16164 return -2; /* Syntax error */ 16165 } 16166 h_refer_to = ast_strdupa(p_refer_to); 16167 refer_to = get_in_brackets(h_refer_to); 16168 if (!strncasecmp(refer_to, "sip:", 4)) { 16169 refer_to += 4; /* Skip sip: */ 16170 } else if (!strncasecmp(refer_to, "sips:", 5)) { 16171 refer_to += 5; 16172 } else { 16173 ast_log(LOG_WARNING, "Can't transfer to non-sip: URI. (Refer-to: %s)?\n", refer_to); 16174 return -3; 16175 } 16176 16177 /* Get referred by header if it exists */ 16178 p_referred_by = get_header(req, "Referred-By"); 16179 16180 /* Give useful transfer information to the dialplan */ 16181 if (transferer->owner) { 16182 struct ast_channel *peer = ast_bridged_channel(transferer->owner); 16183 if (peer) { 16184 pbx_builtin_setvar_helper(peer, "SIPREFERRINGCONTEXT", transferer->context); 16185 pbx_builtin_setvar_helper(peer, "SIPREFERREDBYHDR", p_referred_by); 16186 } 16187 } 16188 16189 if (!ast_strlen_zero(p_referred_by)) { 16190 char *lessthan; 16191 h_referred_by = ast_strdupa(p_referred_by); 16192 16193 /* Store referrer's caller ID name */ 16194 ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name)); 16195 if ((lessthan = strchr(referdata->referred_by_name, '<'))) { 16196 *(lessthan - 1) = '\0'; /* Space */ 16197 } 16198 16199 referred_by_uri = get_in_brackets(h_referred_by); 16200 16201 if (!strncasecmp(referred_by_uri, "sip:", 4)) { 16202 referred_by_uri += 4; /* Skip sip: */ 16203 } else if (!strncasecmp(referred_by_uri, "sips:", 5)) { 16204 referred_by_uri += 5; /* Skip sips: */ 16205 } else { 16206 ast_log(LOG_WARNING, "Huh? Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri); 16207 referred_by_uri = NULL; 16208 } 16209 } 16210 16211 /* Check for arguments in the refer_to header */ 16212 if ((ptr = strcasestr(refer_to, "replaces="))) { 16213 char *to = NULL, *from = NULL; 16214 16215 /* This is an attended transfer */ 16216 referdata->attendedtransfer = 1; 16217 ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid)); 16218 ast_uri_decode(referdata->replaces_callid); 16219 if ((ptr = strchr(referdata->replaces_callid, ';'))) /* Find options */ { 16220 *ptr++ = '\0'; 16221 } 16222 16223 if (ptr) { 16224 /* Find the different tags before we destroy the string */ 16225 to = strcasestr(ptr, "to-tag="); 16226 from = strcasestr(ptr, "from-tag="); 16227 } 16228 16229 /* Grab the to header */ 16230 if (to) { 16231 ptr = to + 7; 16232 if ((to = strchr(ptr, '&'))) { 16233 *to = '\0'; 16234 } 16235 if ((to = strchr(ptr, ';'))) { 16236 *to = '\0'; 16237 } 16238 ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag)); 16239 } 16240 16241 if (from) { 16242 ptr = from + 9; 16243 if ((to = strchr(ptr, '&'))) { 16244 *to = '\0'; 16245 } 16246 if ((to = strchr(ptr, ';'))) { 16247 *to = '\0'; 16248 } 16249 ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag)); 16250 } 16251 16252 if (!strcmp(referdata->replaces_callid, transferer->callid) && 16253 (!sip_cfg.pedanticsipchecking || 16254 (!strcmp(referdata->replaces_callid_fromtag, transferer->theirtag) && 16255 !strcmp(referdata->replaces_callid_totag, transferer->tag)))) { 16256 ast_log(LOG_WARNING, "Got an attempt to replace own Call-ID on %s\n", transferer->callid); 16257 return -4; 16258 } 16259 16260 if (!sip_cfg.pedanticsipchecking) { 16261 ast_debug(2, "Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid ); 16262 } else { 16263 ast_debug(2, "Attended transfer: Will use Replace-Call-ID : %s F-tag: %s T-tag: %s\n", referdata->replaces_callid, referdata->replaces_callid_fromtag ? referdata->replaces_callid_fromtag : "<none>", referdata->replaces_callid_totag ? referdata->replaces_callid_totag : "<none>" ); 16264 } 16265 } 16266 16267 if ((ptr = strchr(refer_to, '@'))) { /* Separate domain */ 16268 char *urioption = NULL, *domain; 16269 int bracket = 0; 16270 *ptr++ = '\0'; 16271 16272 if ((urioption = strchr(ptr, ';'))) { /* Separate urioptions */ 16273 *urioption++ = '\0'; 16274 } 16275 16276 domain = ptr; 16277 16278 /* Remove :port */ 16279 for (; *ptr != '\0'; ++ptr) { 16280 if (*ptr == ':' && bracket == 0) { 16281 *ptr = '\0'; 16282 break; 16283 } else if (*ptr == '[') { 16284 ++bracket; 16285 } else if (*ptr == ']') { 16286 --bracket; 16287 } 16288 } 16289 16290 SIP_PEDANTIC_DECODE(domain); 16291 SIP_PEDANTIC_DECODE(urioption); 16292 16293 /* Save the domain for the dial plan */ 16294 ast_copy_string(referdata->refer_to_domain, domain, sizeof(referdata->refer_to_domain)); 16295 if (urioption) { 16296 ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption)); 16297 } 16298 } 16299 16300 if ((ptr = strchr(refer_to, ';'))) /* Remove options */ 16301 *ptr = '\0'; 16302 16303 SIP_PEDANTIC_DECODE(refer_to); 16304 ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to)); 16305 16306 if (referred_by_uri) { 16307 if ((ptr = strchr(referred_by_uri, ';'))) /* Remove options */ 16308 *ptr = '\0'; 16309 SIP_PEDANTIC_DECODE(referred_by_uri); 16310 ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by)); 16311 } else { 16312 referdata->referred_by[0] = '\0'; 16313 } 16314 16315 /* Determine transfer context */ 16316 if (transferer->owner) { 16317 /* By default, use the context in the channel sending the REFER */ 16318 transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT"); 16319 if (ast_strlen_zero(transfer_context)) { 16320 transfer_context = transferer->owner->macrocontext; 16321 } 16322 } 16323 if (ast_strlen_zero(transfer_context)) { 16324 transfer_context = S_OR(transferer->context, sip_cfg.default_context); 16325 } 16326 16327 ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context)); 16328 16329 /* Either an existing extension or the parking extension */ 16330 if (referdata->attendedtransfer || ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) { 16331 if (sip_debug_test_pvt(transferer)) { 16332 ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri); 16333 } 16334 /* We are ready to transfer to the extension */ 16335 return 0; 16336 } 16337 if (sip_debug_test_pvt(transferer)) 16338 ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context); 16339 16340 /* Failure, we can't find this extension */ 16341 return -1; 16342 }
| static int get_rpid | ( | struct sip_pvt * | p, | |
| struct sip_request * | oreq | |||
| ) | [static] |
Get name, number and presentation from remote party id header, returns true if a valid header was found and it was different from the current caller id.
Definition at line 15675 of file chan_sip.c.
References ast_copy_string(), ast_is_shrinkable_phonenumber(), AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, ast_set_callerid(), ast_shrink_phone_number(), ast_skip_blanks(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, cid_name, cid_num, get_header(), and get_pai().
Referenced by check_peer_ok(), check_user_full(), handle_request_invite(), handle_request_update(), and handle_response_invite().
15676 { 15677 char tmp[256]; 15678 struct sip_request *req; 15679 char *cid_num = ""; 15680 char *cid_name = ""; 15681 int callingpres = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 15682 char *privacy = ""; 15683 char *screen = ""; 15684 char *start, *end; 15685 15686 if (!ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) 15687 return 0; 15688 req = oreq; 15689 if (!req) 15690 req = &p->initreq; 15691 ast_copy_string(tmp, get_header(req, "Remote-Party-ID"), sizeof(tmp)); 15692 if (ast_strlen_zero(tmp)) { 15693 return get_pai(p, req); 15694 } 15695 15696 /* 15697 * RPID is not: 15698 * rpid = (name-addr / addr-spec) *(SEMI rpi-token) 15699 * But it is: 15700 * rpid = [display-name] LAQUOT addr-spec RAQUOT *(SEMI rpi-token) 15701 * Ergo, calling parse_name_andor_addr() on it wouldn't be 15702 * correct because that would allow addr-spec style too. 15703 */ 15704 start = tmp; 15705 /* Quoted (note that we're not dealing with escapes properly) */ 15706 if (*start == '"') { 15707 *start++ = '\0'; 15708 end = strchr(start, '"'); 15709 if (!end) 15710 return 0; 15711 *end++ = '\0'; 15712 cid_name = start; 15713 start = ast_skip_blanks(end); 15714 /* Unquoted */ 15715 } else { 15716 cid_name = start; 15717 start = end = strchr(start, '<'); 15718 if (!start) { 15719 return 0; 15720 } 15721 /* trim blanks if there are any. the mandatory NUL is done below */ 15722 while (--end >= cid_name && *end < 33) { 15723 *end = '\0'; 15724 } 15725 } 15726 15727 if (*start != '<') 15728 return 0; 15729 *start++ = '\0'; 15730 end = strchr(start, '@'); 15731 if (!end) 15732 return 0; 15733 *end++ = '\0'; 15734 if (strncasecmp(start, "sip:", 4)) 15735 return 0; 15736 cid_num = start + 4; 15737 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(cid_num)) 15738 ast_shrink_phone_number(cid_num); 15739 start = end; 15740 15741 end = strchr(start, '>'); 15742 if (!end) 15743 return 0; 15744 *end++ = '\0'; 15745 if (*end) { 15746 start = end; 15747 if (*start != ';') 15748 return 0; 15749 *start++ = '\0'; 15750 while (!ast_strlen_zero(start)) { 15751 end = strchr(start, ';'); 15752 if (end) 15753 *end++ = '\0'; 15754 if (!strncasecmp(start, "privacy=", 8)) 15755 privacy = start + 8; 15756 else if (!strncasecmp(start, "screen=", 7)) 15757 screen = start + 7; 15758 start = end; 15759 } 15760 15761 if (!strcasecmp(privacy, "full")) { 15762 if (!strcasecmp(screen, "yes")) 15763 callingpres = AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN; 15764 else if (!strcasecmp(screen, "no")) 15765 callingpres = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 15766 } else { 15767 if (!strcasecmp(screen, "yes")) 15768 callingpres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 15769 else if (!strcasecmp(screen, "no")) 15770 callingpres = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 15771 } 15772 } 15773 15774 /* Only return true if the supplied caller id is different */ 15775 if (!strcasecmp(p->cid_num, cid_num) && !strcasecmp(p->cid_name, cid_name) && p->callingpres == callingpres) 15776 return 0; 15777 15778 ast_string_field_set(p, cid_num, cid_num); 15779 ast_string_field_set(p, cid_name, cid_name); 15780 p->callingpres = callingpres; 15781 15782 if (p->owner) { 15783 ast_set_callerid(p->owner, cid_num, cid_name, NULL); 15784 p->owner->caller.id.name.presentation = callingpres; 15785 p->owner->caller.id.number.presentation = callingpres; 15786 } 15787 15788 return 1; 15789 }
| static const char * get_sdp_iterate | ( | int * | start, | |
| struct sip_request * | req, | |||
| const char * | name | |||
| ) | [static] |
Lookup 'name' in the SDP starting at the 'start' line. Returns the matching line, and 'start' is updated with the next line number.
Definition at line 7547 of file chan_sip.c.
References get_body_by_line(), and len().
Referenced by get_ip_and_port_from_sdp(), and process_sdp().
07548 { 07549 int len = strlen(name); 07550 07551 while (*start < (req->sdp_start + req->sdp_count)) { 07552 const char *r = get_body_by_line(REQ_OFFSET_TO_STR(req, line[(*start)++]), name, len, '='); 07553 if (r[0] != '\0') 07554 return r; 07555 } 07556 07557 /* if the line was not found, ensure that *start points past the SDP */ 07558 (*start)++; 07559 07560 return ""; 07561 }
| static char get_sdp_line | ( | int * | start, | |
| int | stop, | |||
| struct sip_request * | req, | |||
| const char ** | value | |||
| ) | [static] |
Fetches the next valid SDP line between the 'start' line (inclusive) and the 'stop' line (exclusive). Returns the type ('a', 'c', ...) and matching line in reference 'start' is updated with the next line number.
Definition at line 7568 of file chan_sip.c.
References ast_skip_blanks(), and type.
Referenced by process_sdp().
07569 { 07570 char type = '\0'; 07571 const char *line = NULL; 07572 07573 if (stop > (req->sdp_start + req->sdp_count)) { 07574 stop = req->sdp_start + req->sdp_count; 07575 } 07576 07577 while (*start < stop) { 07578 line = REQ_OFFSET_TO_STR(req, line[(*start)++]); 07579 if (line[1] == '=') { 07580 type = line[0]; 07581 *value = ast_skip_blanks(line + 2); 07582 break; 07583 } 07584 } 07585 07586 return type; 07587 }
| static struct sip_pvt * get_sip_pvt_byid_locked | ( | const char * | callid, | |
| const char * | totag, | |||
| const char * | fromtag | |||
| ) | [static, read] |
Lock dialog lock and find matching pvt lock.
Definition at line 16047 of file chan_sip.c.
References ao2_t_find, ast_channel_trylock, ast_debug, ast_strlen_zero(), ast_test_flag, OBJ_POINTER, sip_cfg, sip_pvt_lock, sip_pvt_unlock, and TRUE.
Referenced by handle_request_invite(), and local_attended_transfer().
16048 { 16049 struct sip_pvt *sip_pvt_ptr; 16050 struct sip_pvt tmp_dialog = { 16051 .callid = callid, 16052 }; 16053 16054 if (totag) { 16055 ast_debug(4, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>"); 16056 } 16057 16058 /* Search dialogs and find the match */ 16059 16060 sip_pvt_ptr = ao2_t_find(dialogs, &tmp_dialog, OBJ_POINTER, "ao2_find of dialog in dialogs table"); 16061 if (sip_pvt_ptr) { 16062 /* Go ahead and lock it (and its owner) before returning */ 16063 sip_pvt_lock(sip_pvt_ptr); 16064 if (sip_cfg.pedanticsipchecking) { 16065 unsigned char frommismatch = 0, tomismatch = 0; 16066 16067 if (ast_strlen_zero(fromtag)) { 16068 sip_pvt_unlock(sip_pvt_ptr); 16069 ast_debug(4, "Matched %s call for callid=%s - no from tag specified, pedantic check fails\n", 16070 sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid); 16071 return NULL; 16072 } 16073 16074 if (ast_strlen_zero(totag)) { 16075 sip_pvt_unlock(sip_pvt_ptr); 16076 ast_debug(4, "Matched %s call for callid=%s - no to tag specified, pedantic check fails\n", 16077 sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid); 16078 return NULL; 16079 } 16080 /* RFC 3891 16081 * > 3. User Agent Server Behavior: Receiving a Replaces Header 16082 * > The Replaces header contains information used to match an existing 16083 * > SIP dialog (call-id, to-tag, and from-tag). Upon receiving an INVITE 16084 * > with a Replaces header, the User Agent (UA) attempts to match this 16085 * > information with a confirmed or early dialog. The User Agent Server 16086 * > (UAS) matches the to-tag and from-tag parameters as if they were tags 16087 * > present in an incoming request. In other words, the to-tag parameter 16088 * > is compared to the local tag, and the from-tag parameter is compared 16089 * > to the remote tag. 16090 * 16091 * Thus, the totag is always compared to the local tag, regardless if 16092 * this our call is an incoming or outgoing call. 16093 */ 16094 frommismatch = !!strcmp(fromtag, sip_pvt_ptr->theirtag); 16095 tomismatch = !!strcmp(totag, sip_pvt_ptr->tag); 16096 16097 /* Don't check from if the dialog is not established, due to multi forking the from 16098 * can change when the call is not answered yet. 16099 */ 16100 if ((frommismatch && ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) || tomismatch) { 16101 sip_pvt_unlock(sip_pvt_ptr); 16102 if (frommismatch) { 16103 ast_debug(4, "Matched %s call for callid=%s - pedantic from tag check fails; their tag is %s our tag is %s\n", 16104 sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid, 16105 fromtag, sip_pvt_ptr->theirtag); 16106 } 16107 if (tomismatch) { 16108 ast_debug(4, "Matched %s call for callid=%s - pedantic to tag check fails; their tag is %s our tag is %s\n", 16109 sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid, 16110 totag, sip_pvt_ptr->tag); 16111 } 16112 return NULL; 16113 } 16114 } 16115 16116 if (totag) 16117 ast_debug(4, "Matched %s call - their tag is %s Our tag is %s\n", 16118 sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", 16119 sip_pvt_ptr->theirtag, sip_pvt_ptr->tag); 16120 16121 /* deadlock avoidance... */ 16122 while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) { 16123 sip_pvt_unlock(sip_pvt_ptr); 16124 usleep(1); 16125 sip_pvt_lock(sip_pvt_ptr); 16126 } 16127 } 16128 16129 return sip_pvt_ptr; 16130 }
| static const char* get_srv_protocol | ( | enum sip_transport | t | ) | [inline, static] |
Return protocol string for srv dns query.
Definition at line 3469 of file chan_sip.c.
Referenced by __sip_subscribe_mwi_do(), build_peer(), create_addr(), and transmit_register().
| static const char* get_srv_service | ( | enum sip_transport | t | ) | [inline, static] |
Return service string for srv dns query.
Definition at line 3483 of file chan_sip.c.
Referenced by __sip_subscribe_mwi_do(), build_peer(), create_addr(), and transmit_register().
| static const char* get_transport | ( | enum sip_transport | t | ) | [inline, static] |
Return transport as string.
Definition at line 3454 of file chan_sip.c.
Referenced by _sip_show_peer(), ast_sip_ouraddrfor(), build_contact(), get_transport_pvt(), handle_request_do(), parse_moved_contact(), sip_show_settings(), sip_show_tcp(), and transmit_notify_with_mwi().
| static const char* get_transport_list | ( | unsigned int | transports | ) | [inline, static] |
Return configuration of transports for a device.
Definition at line 3433 of file chan_sip.c.
Referenced by _sip_show_peer(), peers_data_provider_get(), and sip_show_settings().
03433 { 03434 switch (transports) { 03435 case SIP_TRANSPORT_UDP: 03436 return "UDP"; 03437 case SIP_TRANSPORT_TCP: 03438 return "TCP"; 03439 case SIP_TRANSPORT_TLS: 03440 return "TLS"; 03441 case SIP_TRANSPORT_UDP | SIP_TRANSPORT_TCP: 03442 return "TCP,UDP"; 03443 case SIP_TRANSPORT_UDP | SIP_TRANSPORT_TLS: 03444 return "TLS,UDP"; 03445 case SIP_TRANSPORT_TCP | SIP_TRANSPORT_TLS: 03446 return "TLS,TCP"; 03447 default: 03448 return transports ? 03449 "TLS,TCP,UDP" : "UNKNOWN"; 03450 } 03451 }
| static const char* get_transport_pvt | ( | struct sip_pvt * | p | ) | [inline, static] |
Return transport of dialog.
Definition at line 3501 of file chan_sip.c.
References get_transport(), and set_socket_transport().
Referenced by __sip_xmit(), and build_via().
03502 { 03503 if (p->outboundproxy && p->outboundproxy->transport) { 03504 set_socket_transport(&p->socket, p->outboundproxy->transport); 03505 } 03506 03507 return get_transport(p->socket.type); 03508 }
| static int get_transport_str2enum | ( | const char * | transport | ) | [static] |
Return int representing a bit field of transport types found in const char *transport.
Definition at line 3411 of file chan_sip.c.
References ast_strlen_zero().
Referenced by __set_address_from_contact(), and parse_register_contact().
03412 { 03413 int res = 0; 03414 03415 if (ast_strlen_zero(transport)) { 03416 return res; 03417 } 03418 03419 if (!strcasecmp(transport, "udp")) { 03420 res |= SIP_TRANSPORT_UDP; 03421 } 03422 if (!strcasecmp(transport, "tcp")) { 03423 res |= SIP_TRANSPORT_TCP; 03424 } 03425 if (!strcasecmp(transport, "tls")) { 03426 res |= SIP_TRANSPORT_TLS; 03427 } 03428 03429 return res; 03430 }
| static const char * gettag | ( | const struct sip_request * | req, | |
| const char * | header, | |||
| char * | tagbuf, | |||
| int | tagbufsize | |||
| ) | [static] |
Get tag from packet.
Definition at line 22439 of file chan_sip.c.
References ast_copy_string(), and get_header().
Referenced by find_call(), handle_incoming(), handle_request_subscribe(), and handle_response().
22440 { 22441 const char *thetag; 22442 22443 if (!tagbuf) 22444 return NULL; 22445 tagbuf[0] = '\0'; /* reset the buffer */ 22446 thetag = get_header(req, header); 22447 thetag = strcasestr(thetag, ";tag="); 22448 if (thetag) { 22449 thetag += 5; 22450 ast_copy_string(tagbuf, thetag, tagbufsize); 22451 return strsep(&tagbuf, ";"); 22452 } 22453 return NULL; 22454 }
| static int handle_cc_notify | ( | struct sip_pvt * | pvt, | |
| struct sip_request * | req | |||
| ) | [static] |
Definition at line 22456 of file chan_sip.c.
References ao2_callback, ao2_ref, ast_cc_monitor_callee_available(), ast_cc_monitor_request_acked(), ast_string_field_set, ast_strlen_zero(), construct_pidf_body(), find_sip_monitor_instance_by_subscription_pvt(), get_body(), get_header(), get_in_brackets(), status, transmit_publish(), and transmit_response().
Referenced by handle_request_notify().
22457 { 22458 struct sip_monitor_instance *monitor_instance = ao2_callback(sip_monitor_instances, 0, 22459 find_sip_monitor_instance_by_subscription_pvt, pvt); 22460 const char *status = get_body(req, "cc-state", ':'); 22461 struct cc_epa_entry *cc_entry; 22462 char *uri; 22463 22464 if (!monitor_instance) { 22465 transmit_response(pvt, "400 Bad Request", req); 22466 return -1; 22467 } 22468 22469 if (ast_strlen_zero(status)) { 22470 ao2_ref(monitor_instance, -1); 22471 transmit_response(pvt, "400 Bad Request", req); 22472 return -1; 22473 } 22474 22475 if (!strcmp(status, "queued")) { 22476 /* We've been told that we're queued. This is the endpoint's way of telling 22477 * us that it has accepted our CC request. We need to alert the core of this 22478 * development 22479 */ 22480 ast_cc_monitor_request_acked(monitor_instance->core_id, "SIP endpoint %s accepted request", monitor_instance->device_name); 22481 transmit_response(pvt, "200 OK", req); 22482 ao2_ref(monitor_instance, -1); 22483 return 0; 22484 } 22485 22486 /* It's open! Yay! */ 22487 uri = get_body(req, "cc-URI", ':'); 22488 if (ast_strlen_zero(uri)) { 22489 uri = get_in_brackets((char *)get_header(req, "From")); 22490 } 22491 22492 ast_string_field_set(monitor_instance, notify_uri, uri); 22493 if (monitor_instance->suspension_entry) { 22494 cc_entry = monitor_instance->suspension_entry->instance_data; 22495 if (cc_entry->current_state == CC_CLOSED) { 22496 /* If we've created a suspension entry and the current state is closed, then that means 22497 * we got a notice from the CC core earlier to suspend monitoring, but because this particular 22498 * call leg had not yet notified us that it was ready for recall, it meant that we 22499 * could not yet send a PUBLISH. Now, however, we can. 22500 */ 22501 construct_pidf_body(CC_CLOSED, monitor_instance->suspension_entry->body, 22502 sizeof(monitor_instance->suspension_entry->body), monitor_instance->peername); 22503 transmit_publish(monitor_instance->suspension_entry, SIP_PUBLISH_INITIAL, monitor_instance->notify_uri); 22504 } else { 22505 ast_cc_monitor_callee_available(monitor_instance->core_id, "SIP monitored callee has become available"); 22506 } 22507 } else { 22508 ast_cc_monitor_callee_available(monitor_instance->core_id, "SIP monitored callee has become available"); 22509 } 22510 ao2_ref(monitor_instance, -1); 22511 transmit_response(pvt, "200 OK", req); 22512 22513 return 0; 22514 }
| static int handle_cc_subscribe | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Definition at line 25309 of file chan_sip.c.
References ao2_ref, ast_cc_agent_accept_request(), ast_cc_failed(), ast_log(), ast_strlen_zero(), ast_cc_agent::core_id, ast_cc_agent::device_name, find_sip_cc_agent_by_subscribe_uri(), get_header(), LOG_WARNING, ast_cc_agent::private_data, and transmit_response().
Referenced by handle_request_subscribe().
25310 { 25311 const char *uri = REQ_OFFSET_TO_STR(req, rlPart2); 25312 char *param_separator; 25313 struct ast_cc_agent *agent; 25314 struct sip_cc_agent_pvt *agent_pvt; 25315 const char *expires_str = get_header(req, "Expires"); 25316 int expires = -1; /* Just need it to be non-zero */ 25317 25318 if (!ast_strlen_zero(expires_str)) { 25319 sscanf(expires_str, "%d", &expires); 25320 } 25321 25322 if ((param_separator = strchr(uri, ';'))) { 25323 *param_separator = '\0'; 25324 } 25325 25326 p->subscribed = CALL_COMPLETION; 25327 25328 if (!(agent = find_sip_cc_agent_by_subscribe_uri(uri))) { 25329 if (!expires) { 25330 /* Typically, if a 0 Expires reaches us and we can't find 25331 * the corresponding agent, it means that the CC transaction 25332 * has completed and so the calling side is just trying to 25333 * clean up its subscription. We'll just respond with a 25334 * 200 OK and be done with it 25335 */ 25336 transmit_response(p, "200 OK", req); 25337 return 0; 25338 } 25339 ast_log(LOG_WARNING, "Invalid URI '%s' in CC subscribe\n", uri); 25340 transmit_response(p, "404 Not Found", req); 25341 return -1; 25342 } 25343 25344 agent_pvt = agent->private_data; 25345 25346 if (!expires) { 25347 /* We got sent a SUBSCRIBE and found an agent. This means that CC 25348 * is being canceled. 25349 */ 25350 ast_cc_failed(agent->core_id, "CC is being canceled by %s", agent->device_name); 25351 transmit_response(p, "200 OK", req); 25352 ao2_ref(agent, -1); 25353 return 0; 25354 } 25355 25356 agent_pvt->subscribe_pvt = dialog_ref(p, "SIP CC agent gains reference to subscription dialog"); 25357 ast_cc_agent_accept_request(agent->core_id, "SIP caller %s has requested CC via SUBSCRIBE", 25358 agent->device_name); 25359 25360 /* We don't send a response here. That is done in the agent's ack callback or in the 25361 * agent destructor, should a failure occur before we have responded 25362 */ 25363 ao2_ref(agent, -1); 25364 return 0; 25365 }
| static int handle_common_options | ( | struct ast_flags * | flags, | |
| struct ast_flags * | mask, | |||
| struct ast_variable * | v | |||
| ) | [static] |
Handle flag-type options common to configuration of devices - peers.
| 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 27584 of file chan_sip.c.
References ast_clear_flag, ast_copy_string(), ast_false(), ast_log(), ast_set2_flag, ast_set_flag, ast_strdupa, ast_true(), ast_variable::lineno, LOG_WARNING, ast_variable::name, set_insecure_flags(), ast_variable::value, and word.
Referenced by build_peer(), and reload_config().
27585 { 27586 int res = 1; 27587 27588 if (!strcasecmp(v->name, "trustrpid")) { 27589 ast_set_flag(&mask[0], SIP_TRUSTRPID); 27590 ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID); 27591 } else if (!strcasecmp(v->name, "sendrpid")) { 27592 ast_set_flag(&mask[0], SIP_SENDRPID); 27593 if (!strcasecmp(v->value, "pai")) { 27594 ast_set_flag(&flags[0], SIP_SENDRPID_PAI); 27595 } else if (!strcasecmp(v->value, "rpid")) { 27596 ast_set_flag(&flags[0], SIP_SENDRPID_RPID); 27597 } else if (ast_true(v->value)) { 27598 ast_set_flag(&flags[0], SIP_SENDRPID_RPID); 27599 } 27600 } else if (!strcasecmp(v->name, "rpid_update")) { 27601 ast_set_flag(&mask[1], SIP_PAGE2_RPID_UPDATE); 27602 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RPID_UPDATE); 27603 } else if (!strcasecmp(v->name, "rpid_immediate")) { 27604 ast_set_flag(&mask[1], SIP_PAGE2_RPID_IMMEDIATE); 27605 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RPID_IMMEDIATE); 27606 } else if (!strcasecmp(v->name, "trust_id_outbound")) { 27607 ast_set_flag(&mask[1], SIP_PAGE2_TRUST_ID_OUTBOUND); 27608 ast_clear_flag(&flags[1], SIP_PAGE2_TRUST_ID_OUTBOUND); 27609 if (!strcasecmp(v->value, "legacy")) { 27610 ast_set_flag(&flags[1], SIP_PAGE2_TRUST_ID_OUTBOUND_LEGACY); 27611 } else if (ast_true(v->value)) { 27612 ast_set_flag(&flags[1], SIP_PAGE2_TRUST_ID_OUTBOUND_YES); 27613 } else if (ast_false(v->value)) { 27614 ast_set_flag(&flags[1], SIP_PAGE2_TRUST_ID_OUTBOUND_NO); 27615 } else { 27616 ast_log(LOG_WARNING, "Unknown trust_id_outbound mode '%s' on line %d, using legacy\n", v->value, v->lineno); 27617 ast_set_flag(&flags[1], SIP_PAGE2_TRUST_ID_OUTBOUND_LEGACY); 27618 } 27619 } else if (!strcasecmp(v->name, "g726nonstandard")) { 27620 ast_set_flag(&mask[0], SIP_G726_NONSTANDARD); 27621 ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD); 27622 } else if (!strcasecmp(v->name, "useclientcode")) { 27623 ast_set_flag(&mask[0], SIP_USECLIENTCODE); 27624 ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE); 27625 } else if (!strcasecmp(v->name, "dtmfmode")) { 27626 ast_set_flag(&mask[0], SIP_DTMF); 27627 ast_clear_flag(&flags[0], SIP_DTMF); 27628 if (!strcasecmp(v->value, "inband")) 27629 ast_set_flag(&flags[0], SIP_DTMF_INBAND); 27630 else if (!strcasecmp(v->value, "rfc2833")) 27631 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 27632 else if (!strcasecmp(v->value, "info")) 27633 ast_set_flag(&flags[0], SIP_DTMF_INFO); 27634 else if (!strcasecmp(v->value, "shortinfo")) 27635 ast_set_flag(&flags[0], SIP_DTMF_SHORTINFO); 27636 else if (!strcasecmp(v->value, "auto")) 27637 ast_set_flag(&flags[0], SIP_DTMF_AUTO); 27638 else { 27639 ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno); 27640 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 27641 } 27642 } else if (!strcasecmp(v->name, "nat")) { 27643 ast_set_flag(&mask[0], SIP_NAT_FORCE_RPORT); 27644 ast_set_flag(&mask[1], SIP_PAGE2_SYMMETRICRTP); 27645 if (!strcasecmp(v->value, "yes")) { 27646 ast_set_flag(&flags[0], SIP_NAT_FORCE_RPORT); 27647 ast_set_flag(&flags[1], SIP_PAGE2_SYMMETRICRTP); 27648 } else if (!strcasecmp(v->value, "force_rport")) { 27649 ast_set_flag(&flags[0], SIP_NAT_FORCE_RPORT); 27650 } else if (!strcasecmp(v->value, "comedia")) { 27651 ast_set_flag(&flags[1], SIP_PAGE2_SYMMETRICRTP); 27652 } 27653 } else if (!strcasecmp(v->name, "directmedia") || !strcasecmp(v->name, "canreinvite")) { 27654 ast_set_flag(&mask[0], SIP_REINVITE); 27655 ast_clear_flag(&flags[0], SIP_REINVITE); 27656 if (ast_true(v->value)) { 27657 ast_set_flag(&flags[0], SIP_DIRECT_MEDIA | SIP_DIRECT_MEDIA_NAT); 27658 } else if (!ast_false(v->value)) { 27659 char buf[64]; 27660 char *word, *next = buf; 27661 27662 ast_copy_string(buf, v->value, sizeof(buf)); 27663 while ((word = strsep(&next, ","))) { 27664 if (!strcasecmp(word, "update")) { 27665 ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_DIRECT_MEDIA); 27666 } else if (!strcasecmp(word, "nonat")) { 27667 ast_set_flag(&flags[0], SIP_DIRECT_MEDIA); 27668 ast_clear_flag(&flags[0], SIP_DIRECT_MEDIA_NAT); 27669 } else if (!strcasecmp(word, "outgoing")) { 27670 ast_set_flag(&flags[0], SIP_DIRECT_MEDIA); 27671 ast_set_flag(&mask[2], SIP_PAGE3_DIRECT_MEDIA_OUTGOING); 27672 ast_set_flag(&flags[2], SIP_PAGE3_DIRECT_MEDIA_OUTGOING); 27673 } else { 27674 ast_log(LOG_WARNING, "Unknown directmedia mode '%s' on line %d\n", v->value, v->lineno); 27675 } 27676 } 27677 } 27678 } else if (!strcasecmp(v->name, "insecure")) { 27679 ast_set_flag(&mask[0], SIP_INSECURE); 27680 ast_clear_flag(&flags[0], SIP_INSECURE); 27681 set_insecure_flags(&flags[0], v->value, v->lineno); 27682 } else if (!strcasecmp(v->name, "progressinband")) { 27683 ast_set_flag(&mask[0], SIP_PROG_INBAND); 27684 ast_clear_flag(&flags[0], SIP_PROG_INBAND); 27685 if (ast_true(v->value)) 27686 ast_set_flag(&flags[0], SIP_PROG_INBAND_YES); 27687 else if (strcasecmp(v->value, "never")) 27688 ast_set_flag(&flags[0], SIP_PROG_INBAND_NO); 27689 } else if (!strcasecmp(v->name, "promiscredir")) { 27690 ast_set_flag(&mask[0], SIP_PROMISCREDIR); 27691 ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR); 27692 } else if (!strcasecmp(v->name, "videosupport")) { 27693 if (!strcasecmp(v->value, "always")) { 27694 ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS); 27695 ast_set_flag(&flags[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS); 27696 } else { 27697 ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT); 27698 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT); 27699 } 27700 } else if (!strcasecmp(v->name, "textsupport")) { 27701 ast_set_flag(&mask[1], SIP_PAGE2_TEXTSUPPORT); 27702 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_TEXTSUPPORT); 27703 res = 1; 27704 } else if (!strcasecmp(v->name, "allowoverlap")) { 27705 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP); 27706 ast_clear_flag(&flags[1], SIP_PAGE2_ALLOWOVERLAP); 27707 if (ast_true(v->value)) { 27708 ast_set_flag(&flags[1], SIP_PAGE2_ALLOWOVERLAP_YES); 27709 } else if (!strcasecmp(v->value, "dtmf")){ 27710 ast_set_flag(&flags[1], SIP_PAGE2_ALLOWOVERLAP_DTMF); 27711 } 27712 } else if (!strcasecmp(v->name, "allowsubscribe")) { 27713 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE); 27714 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE); 27715 } else if (!strcasecmp(v->name, "ignoresdpversion")) { 27716 ast_set_flag(&mask[1], SIP_PAGE2_IGNORESDPVERSION); 27717 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_IGNORESDPVERSION); 27718 } else if (!strcasecmp(v->name, "faxdetect")) { 27719 ast_set_flag(&mask[1], SIP_PAGE2_FAX_DETECT); 27720 if (ast_true(v->value)) { 27721 ast_set_flag(&flags[1], SIP_PAGE2_FAX_DETECT_BOTH); 27722 } else if (ast_false(v->value)) { 27723 ast_clear_flag(&flags[1], SIP_PAGE2_FAX_DETECT_BOTH); 27724 } else { 27725 char *buf = ast_strdupa(v->value); 27726 char *word, *next = buf; 27727 27728 while ((word = strsep(&next, ","))) { 27729 if (!strcasecmp(word, "cng")) { 27730 ast_set_flag(&flags[1], SIP_PAGE2_FAX_DETECT_CNG); 27731 } else if (!strcasecmp(word, "t38")) { 27732 ast_set_flag(&flags[1], SIP_PAGE2_FAX_DETECT_T38); 27733 } else { 27734 ast_log(LOG_WARNING, "Unknown faxdetect mode '%s' on line %d.\n", word, v->lineno); 27735 } 27736 } 27737 } 27738 } else if (!strcasecmp(v->name, "rfc2833compensate")) { 27739 ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE); 27740 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE); 27741 } else if (!strcasecmp(v->name, "buggymwi")) { 27742 ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI); 27743 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI); 27744 } else 27745 res = 0; 27746 27747 return res; 27748 }
| static int handle_incoming | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| struct ast_sockaddr * | addr, | |||
| int * | recount, | |||
| int * | nounlock | |||
| ) | [static] |
Handle incoming SIP requests (methods).
Definition at line 25821 of file chan_sip.c.
References __get_header(), __sip_ack(), ast_channel_ref, ast_channel_unlock, ast_channel_unref, AST_CONTROL_SRCCHANGE, ast_debug, ast_log(), ast_queue_control(), ast_random(), ast_skip_blanks(), ast_sockaddr_stringify(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose, check_pendings(), extract_uri(), find_sdp(), get_header(), gettag(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_message(), handle_request_notify(), handle_request_options(), handle_request_publish(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_request_update(), handle_response(), cfsip_methods::id, len(), LOG_ERROR, LOG_NOTICE, LOG_WARNING, pbx_builtin_setvar_helper(), process_sdp(), pvt_set_needdestroy(), sip_cfg, sip_debug_test_pvt(), sip_methods, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), cfsip_methods::text, transmit_response(), transmit_response_reliable(), transmit_response_with_allow(), and transmit_response_with_retry_after().
Referenced by handle_request_do().
25822 { 25823 /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things 25824 relatively static */ 25825 const char *cmd; 25826 const char *cseq; 25827 const char *useragent; 25828 const char *via; 25829 const char *callid; 25830 int via_pos = 0; 25831 uint32_t seqno; 25832 int len; 25833 int respid; 25834 int res = 0; 25835 int debug = sip_debug_test_pvt(p); 25836 const char *e; 25837 int error = 0; 25838 int oldmethod = p->method; 25839 int acked = 0; 25840 25841 /* RFC 3261 - 8.1.1 A valid SIP request must contain To, From, CSeq, Call-ID and Via. 25842 * 8.2.6.2 Response must have To, From, Call-ID CSeq, and Via related to the request, 25843 * so we can check to make sure these fields exist for all requests and responses */ 25844 cseq = get_header(req, "Cseq"); 25845 cmd = REQ_OFFSET_TO_STR(req, header[0]); 25846 /* Save the via_pos so we can check later that responses only have 1 Via header */ 25847 via = __get_header(req, "Via", &via_pos); 25848 /* This must exist already because we've called find_call by now */ 25849 callid = get_header(req, "Call-ID"); 25850 25851 /* Must have Cseq */ 25852 if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq) || ast_strlen_zero(via)) { 25853 ast_log(LOG_ERROR, "Dropping this SIP message with Call-ID '%s', it's incomplete.\n", callid); 25854 error = 1; 25855 } 25856 if (!error && sscanf(cseq, "%30u%n", &seqno, &len) != 1) { 25857 ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd); 25858 error = 1; 25859 } 25860 if (error) { 25861 if (!p->initreq.headers) { /* New call */ 25862 pvt_set_needdestroy(p, "no headers"); 25863 } 25864 return -1; 25865 } 25866 /* Get the command XXX */ 25867 25868 cmd = REQ_OFFSET_TO_STR(req, rlPart1); 25869 e = ast_skip_blanks(REQ_OFFSET_TO_STR(req, rlPart2)); 25870 25871 /* Save useragent of the client */ 25872 useragent = get_header(req, "User-Agent"); 25873 if (!ast_strlen_zero(useragent)) 25874 ast_string_field_set(p, useragent, useragent); 25875 25876 /* Find out SIP method for incoming request */ 25877 if (req->method == SIP_RESPONSE) { /* Response to our request */ 25878 /* ignore means "don't do anything with it" but still have to 25879 * respond appropriately. 25880 * But in this case this is a response already, so we really 25881 * have nothing to do with this message, and even setting the 25882 * ignore flag is pointless. 25883 */ 25884 if (ast_strlen_zero(e)) { 25885 return 0; 25886 } 25887 if (sscanf(e, "%30d %n", &respid, &len) != 1) { 25888 ast_log(LOG_WARNING, "Invalid response: '%s'\n", e); 25889 return 0; 25890 } 25891 if (respid <= 0) { 25892 ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid); 25893 return 0; 25894 } 25895 /* RFC 3261 - 8.1.3.3 If more than one Via header field value is present in a reponse 25896 * the UAC SHOULD discard the message. This is not perfect, as it will not catch multiple 25897 * headers joined with a comma. Fixing that would pretty much involve writing a new parser */ 25898 if (!ast_strlen_zero(__get_header(req, "via", &via_pos))) { 25899 ast_log(LOG_WARNING, "Misrouted SIP response '%s' with Call-ID '%s', too many vias\n", e, callid); 25900 return 0; 25901 } 25902 if (p->ocseq && (p->ocseq < seqno)) { 25903 ast_debug(1, "Ignoring out of order response %u (expecting %u)\n", seqno, p->ocseq); 25904 return -1; 25905 } else { 25906 char causevar[256], causeval[256]; 25907 25908 if ((respid == 200) || ((respid >= 300) && (respid <= 399))) { 25909 extract_uri(p, req); 25910 } 25911 25912 handle_response(p, respid, e + len, req, seqno); 25913 25914 if (global_store_sip_cause && p->owner) { 25915 struct ast_channel *owner = p->owner; 25916 25917 snprintf(causevar, sizeof(causevar), "MASTER_CHANNEL(HASH(SIP_CAUSE,%s))", owner->name); 25918 snprintf(causeval, sizeof(causeval), "SIP %s", REQ_OFFSET_TO_STR(req, rlPart2)); 25919 25920 ast_channel_ref(owner); 25921 sip_pvt_unlock(p); 25922 ast_channel_unlock(owner); 25923 *nounlock = 1; 25924 pbx_builtin_setvar_helper(owner, causevar, causeval); 25925 ast_channel_unref(owner); 25926 sip_pvt_lock(p); 25927 } 25928 } 25929 return 0; 25930 } 25931 25932 /* New SIP request coming in 25933 (could be new request in existing SIP dialog as well...) 25934 */ 25935 25936 p->method = req->method; /* Find out which SIP method they are using */ 25937 ast_debug(4, "**** Received %s (%u) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 25938 25939 if (p->icseq && (p->icseq > seqno) ) { 25940 if (p->pendinginvite && seqno == p->pendinginvite && (req->method == SIP_ACK || req->method == SIP_CANCEL)) { 25941 ast_debug(2, "Got CANCEL or ACK on INVITE with transactions in between.\n"); 25942 } else { 25943 ast_debug(1, "Ignoring too old SIP packet packet %u (expecting >= %u)\n", seqno, p->icseq); 25944 if (req->method == SIP_INVITE) { 25945 unsigned int ran = (ast_random() % 10) + 1; 25946 char seconds[4]; 25947 snprintf(seconds, sizeof(seconds), "%u", ran); 25948 transmit_response_with_retry_after(p, "500 Server error", req, seconds); /* respond according to RFC 3261 14.2 with Retry-After betwewn 0 and 10 */ 25949 } else if (req->method != SIP_ACK) { 25950 transmit_response(p, "500 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */ 25951 } 25952 return -1; 25953 } 25954 } else if (p->icseq && 25955 p->icseq == seqno && 25956 req->method != SIP_ACK && 25957 (p->method != SIP_CANCEL || p->alreadygone)) { 25958 /* ignore means "don't do anything with it" but still have to 25959 respond appropriately. We do this if we receive a repeat of 25960 the last sequence number */ 25961 req->ignore = 1; 25962 ast_debug(3, "Ignoring SIP message because of retransmit (%s Seqno %u, ours %u)\n", sip_methods[p->method].text, p->icseq, seqno); 25963 } 25964 25965 /* RFC 3261 section 9. "CANCEL has no effect on a request to which a UAS has 25966 * already given a final response." */ 25967 if (!p->pendinginvite && (req->method == SIP_CANCEL)) { 25968 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 25969 return res; 25970 } 25971 25972 if (seqno >= p->icseq) 25973 /* Next should follow monotonically (but not necessarily 25974 incrementally -- thanks again to the genius authors of SIP -- 25975 increasing */ 25976 p->icseq = seqno; 25977 25978 /* Find their tag if we haven't got it */ 25979 if (ast_strlen_zero(p->theirtag)) { 25980 char tag[128]; 25981 25982 gettag(req, "From", tag, sizeof(tag)); 25983 ast_string_field_set(p, theirtag, tag); 25984 } 25985 snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd); 25986 25987 if (sip_cfg.pedanticsipchecking) { 25988 /* If this is a request packet without a from tag, it's not 25989 correct according to RFC 3261 */ 25990 /* Check if this a new request in a new dialog with a totag already attached to it, 25991 RFC 3261 - section 12.2 - and we don't want to mess with recovery */ 25992 if (!p->initreq.headers && req->has_to_tag) { 25993 /* If this is a first request and it got a to-tag, it is not for us */ 25994 if (!req->ignore && req->method == SIP_INVITE) { 25995 /* Just because we think this is a dialog-starting INVITE with a to-tag 25996 * doesn't mean it actually is. It could be a reinvite for an established, but 25997 * unknown dialog. In such a case, we need to change our tag to the 25998 * incoming INVITE's to-tag so that they will recognize the 481 we send and 25999 * so that we will properly match their incoming ACK. 26000 */ 26001 char totag[128]; 26002 gettag(req, "To", totag, sizeof(totag)); 26003 ast_string_field_set(p, tag, totag); 26004 p->pendinginvite = p->icseq; 26005 transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req); 26006 /* Will cease to exist after ACK */ 26007 return res; 26008 } else if (req->method != SIP_ACK) { 26009 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 26010 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 26011 return res; 26012 } 26013 /* Otherwise, this is an ACK. It will always have a to-tag */ 26014 } 26015 } 26016 26017 if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY || p->method == SIP_PUBLISH)) { 26018 transmit_response(p, "400 Bad request", req); 26019 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 26020 return -1; 26021 } 26022 26023 /* Handle various incoming SIP methods in requests */ 26024 switch (p->method) { 26025 case SIP_OPTIONS: 26026 res = handle_request_options(p, req, addr, e); 26027 break; 26028 case SIP_INVITE: 26029 res = handle_request_invite(p, req, debug, seqno, addr, recount, e, nounlock); 26030 break; 26031 case SIP_REFER: 26032 res = handle_request_refer(p, req, debug, seqno, nounlock); 26033 break; 26034 case SIP_CANCEL: 26035 res = handle_request_cancel(p, req); 26036 break; 26037 case SIP_BYE: 26038 res = handle_request_bye(p, req); 26039 break; 26040 case SIP_MESSAGE: 26041 res = handle_request_message(p, req); 26042 break; 26043 case SIP_PUBLISH: 26044 res = handle_request_publish(p, req, addr, seqno, e); 26045 break; 26046 case SIP_SUBSCRIBE: 26047 res = handle_request_subscribe(p, req, addr, seqno, e); 26048 break; 26049 case SIP_REGISTER: 26050 res = handle_request_register(p, req, addr, e); 26051 break; 26052 case SIP_INFO: 26053 if (req->debug) 26054 ast_verbose("Receiving INFO!\n"); 26055 if (!req->ignore) 26056 handle_request_info(p, req); 26057 else /* if ignoring, transmit response */ 26058 transmit_response(p, "200 OK", req); 26059 break; 26060 case SIP_NOTIFY: 26061 res = handle_request_notify(p, req, addr, seqno, e); 26062 break; 26063 case SIP_UPDATE: 26064 res = handle_request_update(p, req); 26065 break; 26066 case SIP_ACK: 26067 /* Make sure we don't ignore this */ 26068 if (seqno == p->pendinginvite) { 26069 p->invitestate = INV_TERMINATED; 26070 p->pendinginvite = 0; 26071 acked = __sip_ack(p, seqno, 1 /* response */, 0); 26072 if (p->owner && find_sdp(req)) { 26073 if (process_sdp(p, req, SDP_T38_NONE)) { 26074 return -1; 26075 } 26076 if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) { 26077 ast_queue_control(p->owner, AST_CONTROL_SRCCHANGE); 26078 } 26079 } 26080 check_pendings(p); 26081 } else if (p->glareinvite == seqno) { 26082 /* handle ack for the 491 pending sent for glareinvite */ 26083 p->glareinvite = 0; 26084 acked = __sip_ack(p, seqno, 1, 0); 26085 } 26086 if (!acked) { 26087 /* Got an ACK that did not match anything. Ignore 26088 * silently and restore previous method */ 26089 p->method = oldmethod; 26090 } 26091 if (!p->lastinvite && ast_strlen_zero(p->randdata)) { 26092 pvt_set_needdestroy(p, "unmatched ACK"); 26093 } 26094 break; 26095 default: 26096 transmit_response_with_allow(p, "501 Method Not Implemented", req, 0); 26097 ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 26098 cmd, ast_sockaddr_stringify(&p->sa)); 26099 /* If this is some new method, and we don't have a call, destroy it now */ 26100 if (!p->initreq.headers) { 26101 pvt_set_needdestroy(p, "unimplemented method"); 26102 } 26103 break; 26104 } 26105 return res; 26106 }
| static int handle_invite_replaces | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| int | debug, | |||
| uint32_t | seqno, | |||
| struct ast_sockaddr * | addr, | |||
| int * | nounlock | |||
| ) | [static] |
Handle the transfer part of INVITE with a replaces: header, meaning a target pickup or an attended transfer. Used only once. XXX 'ignore' is unused.
Definition at line 22769 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), AST_CAUSE_SWITCH_CONGESTION, AST_CEL_ANSWER, AST_CEL_PICKUP, ast_cel_report_event(), ast_channel_lock, ast_channel_masquerade(), ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_debug, ast_do_masquerade(), ast_hangup(), ast_log(), ast_quiet_chan(), ast_set_flag, ast_setstate(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, FALSE, ast_channel::hangupcause, LOG_ERROR, LOG_NOTICE, LOG_WARNING, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), ast_channel::tech_pvt, transmit_response(), transmit_response_reliable(), and transmit_response_with_sdp().
Referenced by handle_request_invite().
22770 { 22771 int earlyreplace = 0; 22772 int oneleggedreplace = 0; /* Call with no bridge, propably IVR or voice message */ 22773 struct ast_channel *c = p->owner; /* Our incoming call */ 22774 struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */ 22775 struct ast_channel *targetcall; /* The bridge to the take-over target */ 22776 22777 /* Check if we're in ring state */ 22778 if (replacecall->_state == AST_STATE_RING) 22779 earlyreplace = 1; 22780 22781 /* Check if we have a bridge */ 22782 if (!(targetcall = ast_bridged_channel(replacecall))) { 22783 /* We have no bridge */ 22784 if (!earlyreplace) { 22785 ast_debug(2, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name); 22786 oneleggedreplace = 1; 22787 } 22788 } 22789 if (targetcall && targetcall->_state == AST_STATE_RINGING) 22790 ast_debug(4, "SIP transfer: Target channel is in ringing state\n"); 22791 22792 if (targetcall) 22793 ast_debug(4, "SIP transfer: Invite Replace incoming channel should bridge to channel %s while hanging up channel %s\n", targetcall->name, replacecall->name); 22794 else 22795 ast_debug(4, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name); 22796 22797 if (req->ignore) { 22798 ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n"); 22799 /* We should answer something here. If we are here, the 22800 call we are replacing exists, so an accepted 22801 can't harm */ 22802 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE, FALSE, FALSE); 22803 /* Do something more clever here */ 22804 if (c) { 22805 *nounlock = 1; 22806 ast_channel_unlock(c); 22807 } 22808 ast_channel_unlock(replacecall); 22809 sip_pvt_unlock(p->refer->refer_call); 22810 return 1; 22811 } 22812 if (!c) { 22813 /* What to do if no channel ??? */ 22814 ast_log(LOG_ERROR, "Unable to create new channel. Invite/replace failed.\n"); 22815 transmit_response_reliable(p, "503 Service Unavailable", req); 22816 append_history(p, "Xfer", "INVITE/Replace Failed. No new channel."); 22817 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22818 ast_channel_unlock(replacecall); 22819 sip_pvt_unlock(p->refer->refer_call); 22820 return 1; 22821 } 22822 append_history(p, "Xfer", "INVITE/Replace received"); 22823 /* We have three channels to play with 22824 channel c: New incoming call 22825 targetcall: Call from PBX to target 22826 p->refer->refer_call: SIP pvt dialog from transferer to pbx. 22827 replacecall: The owner of the previous 22828 We need to masq C into refer_call to connect to 22829 targetcall; 22830 If we are talking to internal audio stream, target call is null. 22831 */ 22832 22833 /* Fake call progress */ 22834 transmit_response(p, "100 Trying", req); 22835 ast_setstate(c, AST_STATE_RING); 22836 22837 /* Masquerade the new call into the referred call to connect to target call 22838 Targetcall is not touched by the masq */ 22839 22840 /* Answer the incoming call and set channel to UP state */ 22841 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE, FALSE, FALSE); 22842 22843 /* Is this a call pickup? */ 22844 if (earlyreplace || oneleggedreplace) { 22845 /* Report pickup event, in this order: PICKUP, CHAN_UP, ANSWER */ 22846 ast_cel_report_event(replacecall, AST_CEL_PICKUP, NULL, NULL, c); 22847 ast_setstate(c, AST_STATE_UP); 22848 ast_cel_report_event(c, AST_CEL_ANSWER, NULL, NULL, NULL); 22849 } else { 22850 ast_setstate(c, AST_STATE_UP); 22851 } 22852 22853 /* Stop music on hold and other generators */ 22854 ast_quiet_chan(replacecall); 22855 ast_quiet_chan(targetcall); 22856 ast_debug(4, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name); 22857 22858 /* Make sure that the masq does not free our PVT for the old call */ 22859 if (! earlyreplace && ! oneleggedreplace ) 22860 ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 22861 22862 /* Prepare the masquerade - if this does not happen, we will be gone */ 22863 if(ast_channel_masquerade(replacecall, c)) 22864 ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n"); 22865 else 22866 ast_debug(4, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name); 22867 22868 /* C should now be in place of replacecall. all channel locks and pvt locks should be removed 22869 * before issuing the masq. Since we are unlocking both the pvt (p) and its owner channel (c) 22870 * it is possible for channel c to be destroyed on us. To prevent this, we must give c a reference 22871 * before any unlocking takes place and remove it only once we are completely done with it */ 22872 ast_channel_ref(c); 22873 ast_channel_unlock(replacecall); 22874 ast_channel_unlock(c); 22875 sip_pvt_unlock(p->refer->refer_call); 22876 sip_pvt_unlock(p); 22877 if (ast_do_masquerade(replacecall)) { 22878 ast_log(LOG_WARNING, "Failed to perform masquerade with INVITE replaces\n"); 22879 } 22880 if (earlyreplace || oneleggedreplace ) { 22881 ast_channel_lock(c); 22882 c->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 22883 ast_channel_unlock(c); 22884 } 22885 22886 /* The call should be down with no ast_channel, so hang it up */ 22887 c->tech_pvt = dialog_unref(c->tech_pvt, "unref dialog c->tech_pvt"); 22888 22889 /* c and c's tech pvt must be unlocked at this point for ast_hangup */ 22890 ast_hangup(c); 22891 /* this indicates to handle_request_do that the owner channel has already been unlocked */ 22892 *nounlock = 1; 22893 /* lock PVT structure again after hangup */ 22894 sip_pvt_lock(p); 22895 ast_channel_unref(c); 22896 return 0; 22897 }
| static int handle_request_bye | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Handle incoming BYE request.
Definition at line 24620 of file chan_sip.c.
References __sip_pretend_ack(), append_history, ARRAY_LEN, ast_async_goto(), ast_bridged_channel(), AST_CAUSE_PROTOCOL_ERROR, ast_channel_lock, ast_channel_trylock, ast_channel_unlock, ast_clear_flag, AST_CONTROL_UNHOLD, ast_debug, ast_log(), AST_MAX_USER_FIELD, ast_queue_control(), ast_queue_hangup(), ast_queue_hangup_with_cause(), ast_rtp_instance_get_quality(), ast_rtp_instance_set_stats_vars(), AST_RTP_INSTANCE_STAT_FIELD_QUALITY, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_JITTER, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_LOSS, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_RTT, AST_SCHED_DEL_UNREF, ast_sockaddr_stringify(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, check_via(), ast_channel::context, context, copy_request(), get_also_info(), get_header(), LOG_NOTICE, LOG_WARNING, parse_sip_options(), pbx_builtin_setvar_helper(), quality, sip_alreadygone(), sip_cfg, sip_methods, sip_pvt_lock, sip_pvt_unlock, sip_queue_hangup_cause(), sip_scheddestroy_final(), stop_media_flows(), stop_session_timer(), ast_channel::tech, ast_channel::tech_pvt, cfsip_methods::text, transmit_response(), transmit_response_reliable(), and transmit_response_with_unsupported().
Referenced by handle_incoming().
24621 { 24622 struct ast_channel *c=NULL; 24623 int res; 24624 struct ast_channel *bridged_to; 24625 const char *required; 24626 24627 /* If we have an INCOMING invite that we haven't answered, terminate that transaction */ 24628 if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !req->ignore) { 24629 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 24630 } 24631 24632 __sip_pretend_ack(p); 24633 24634 p->invitestate = INV_TERMINATED; 24635 24636 copy_request(&p->initreq, req); 24637 if (sipdebug) 24638 ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid); 24639 check_via(p, req); 24640 sip_alreadygone(p); 24641 24642 /* Get RTCP quality before end of call */ 24643 if (p->do_history || p->owner) { 24644 char quality_buf[AST_MAX_USER_FIELD], *quality; 24645 struct ast_channel *bridge = p->owner ? ast_bridged_channel(p->owner) : NULL; 24646 24647 /* We need to get the lock on bridge because ast_rtp_instance_set_stats_vars will attempt 24648 * to lock the bridge. This may get hairy... 24649 */ 24650 while (bridge && ast_channel_trylock(bridge)) { 24651 ast_channel_unlock(p->owner); 24652 do { 24653 /* Can't use DEADLOCK_AVOIDANCE since p is an ao2 object */ 24654 sip_pvt_unlock(p); 24655 usleep(1); 24656 sip_pvt_lock(p); 24657 } while (p->owner && ast_channel_trylock(p->owner)); 24658 bridge = p->owner ? ast_bridged_channel(p->owner) : NULL; 24659 } 24660 24661 24662 if (p->rtp && (quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) { 24663 if (p->do_history) { 24664 append_history(p, "RTCPaudio", "Quality:%s", quality); 24665 24666 if ((quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_JITTER, quality_buf, sizeof(quality_buf)))) { 24667 append_history(p, "RTCPaudioJitter", "Quality:%s", quality); 24668 } 24669 if ((quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_LOSS, quality_buf, sizeof(quality_buf)))) { 24670 append_history(p, "RTCPaudioLoss", "Quality:%s", quality); 24671 } 24672 if ((quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_RTT, quality_buf, sizeof(quality_buf)))) { 24673 append_history(p, "RTCPaudioRTT", "Quality:%s", quality); 24674 } 24675 } 24676 24677 if (p->owner) { 24678 ast_rtp_instance_set_stats_vars(p->owner, p->rtp); 24679 } 24680 24681 } 24682 24683 if (bridge) { 24684 struct sip_pvt *q = bridge->tech_pvt; 24685 24686 if (IS_SIP_TECH(bridge->tech) && q && q->rtp) { 24687 ast_rtp_instance_set_stats_vars(bridge, q->rtp); 24688 } 24689 ast_channel_unlock(bridge); 24690 } 24691 24692 if (p->vrtp && (quality = ast_rtp_instance_get_quality(p->vrtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) { 24693 if (p->do_history) { 24694 append_history(p, "RTCPvideo", "Quality:%s", quality); 24695 } 24696 if (p->owner) { 24697 pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", quality); 24698 } 24699 } 24700 if (p->trtp && (quality = ast_rtp_instance_get_quality(p->trtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) { 24701 if (p->do_history) { 24702 append_history(p, "RTCPtext", "Quality:%s", quality); 24703 } 24704 if (p->owner) { 24705 pbx_builtin_setvar_helper(p->owner, "RTPTEXTQOS", quality); 24706 } 24707 } 24708 } 24709 24710 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 24711 if (p->stimer) { 24712 stop_session_timer(p); /* Stop Session-Timer */ 24713 } 24714 24715 if (!ast_strlen_zero(get_header(req, "Also"))) { 24716 ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n", 24717 ast_sockaddr_stringify(&p->recv)); 24718 if (ast_strlen_zero(p->context)) 24719 ast_string_field_set(p, context, sip_cfg.default_context); 24720 res = get_also_info(p, req); 24721 if (!res) { 24722 c = p->owner; 24723 if (c) { 24724 bridged_to = ast_bridged_channel(c); 24725 if (bridged_to) { 24726 /* Don't actually hangup here... */ 24727 ast_queue_control(c, AST_CONTROL_UNHOLD); 24728 ast_channel_unlock(c); /* async_goto can do a masquerade, no locks can be held during a masq */ 24729 ast_async_goto(bridged_to, p->context, p->refer->refer_to, 1); 24730 ast_channel_lock(c); 24731 } else 24732 ast_queue_hangup(p->owner); 24733 } 24734 } else { 24735 ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_sockaddr_stringify(&p->recv)); 24736 if (p->owner) 24737 ast_queue_hangup_with_cause(p->owner, AST_CAUSE_PROTOCOL_ERROR); 24738 } 24739 } else if (p->owner) { 24740 sip_queue_hangup_cause(p, 0); 24741 sip_scheddestroy_final(p, DEFAULT_TRANS_TIMEOUT); 24742 ast_debug(3, "Received bye, issuing owner hangup\n"); 24743 } else { 24744 sip_scheddestroy_final(p, DEFAULT_TRANS_TIMEOUT); 24745 ast_debug(3, "Received bye, no owner, selfdestruct soon.\n"); 24746 } 24747 ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 24748 24749 /* Find out what they require */ 24750 required = get_header(req, "Require"); 24751 if (!ast_strlen_zero(required)) { 24752 char unsupported[256] = { 0, }; 24753 parse_sip_options(required, unsupported, ARRAY_LEN(unsupported)); 24754 /* If there are any options required that we do not support, 24755 * then send a 420 with only those unsupported options listed */ 24756 if (!ast_strlen_zero(unsupported)) { 24757 transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, unsupported); 24758 ast_log(LOG_WARNING, "Received SIP BYE with unsupported required extension: required:%s unsupported:%s\n", required, unsupported); 24759 } else { 24760 transmit_response(p, "200 OK", req); 24761 } 24762 } else { 24763 transmit_response(p, "200 OK", req); 24764 } 24765 24766 /* Destroy any pending invites so we won't try to do another 24767 * scheduled reINVITE. */ 24768 AST_SCHED_DEL_UNREF(sched, p->waitid, dialog_unref(p, "decrement refcount from sip_destroy because waitid won't be scheduled")); 24769 24770 return 1; 24771 }
| static int handle_request_cancel | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Handle incoming CANCEL request.
Definition at line 24552 of file chan_sip.c.
References __sip_pretend_ack(), ast_debug, ast_free, AST_SCHED_DEL, AST_STATE_UP, ast_str_strlen(), ast_test_flag, check_via(), sip_alreadygone(), sip_queue_hangup_cause(), sip_scheddestroy(), stop_media_flows(), transmit_response(), transmit_response_reliable(), UNLINK, and update_call_counter().
Referenced by handle_incoming().
24553 { 24554 24555 check_via(p, req); 24556 sip_alreadygone(p); 24557 24558 if (p->owner && p->owner->_state == AST_STATE_UP) { 24559 /* This call is up, cancel is ignored, we need a bye */ 24560 transmit_response(p, "200 OK", req); 24561 ast_debug(1, "Got CANCEL on an answered call. Ignoring... \n"); 24562 return 0; 24563 } 24564 24565 /* At this point, we could have cancelled the invite at the same time 24566 as the other side sends a CANCEL. Our final reply with error code 24567 might not have been received by the other side before the CANCEL 24568 was sent, so let's just give up retransmissions and waiting for 24569 ACK on our error code. The call is hanging up any way. */ 24570 if (p->invitestate == INV_TERMINATED || p->invitestate == INV_COMPLETED) { 24571 __sip_pretend_ack(p); 24572 } 24573 if (p->invitestate != INV_TERMINATED) 24574 p->invitestate = INV_CANCELLED; 24575 24576 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 24577 update_call_counter(p, DEC_CALL_LIMIT); 24578 24579 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 24580 if (p->owner) { 24581 sip_queue_hangup_cause(p, 0); 24582 } else { 24583 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 24584 } 24585 if (ast_str_strlen(p->initreq.data) > 0) { 24586 struct sip_pkt *pkt, *prev_pkt; 24587 /* If the CANCEL we are receiving is a retransmission, and we already have scheduled 24588 * a reliable 487, then we don't want to schedule another one on top of the previous 24589 * one. 24590 * 24591 * As odd as this may sound, we can't rely on the previously-transmitted "reliable" 24592 * response in this situation. What if we've sent all of our reliable responses 24593 * already and now all of a sudden, we get this second CANCEL? 24594 * 24595 * The only way to do this correctly is to cancel our previously-scheduled reliably- 24596 * transmitted response and send a new one in its place. 24597 */ 24598 for (pkt = p->packets, prev_pkt = NULL; pkt; prev_pkt = pkt, pkt = pkt->next) { 24599 if (pkt->seqno == p->lastinvite && pkt->response_code == 487) { 24600 AST_SCHED_DEL(sched, pkt->retransid); 24601 UNLINK(pkt, p->packets, prev_pkt); 24602 dialog_unref(pkt->owner, "unref packet->owner from dialog"); 24603 if (pkt->data) { 24604 ast_free(pkt->data); 24605 } 24606 ast_free(pkt); 24607 break; 24608 } 24609 } 24610 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 24611 transmit_response(p, "200 OK", req); 24612 return 1; 24613 } else { 24614 transmit_response(p, "481 Call Leg Does Not Exist", req); 24615 return 0; 24616 } 24617 }
| static int handle_request_do | ( | struct sip_request * | req, | |
| struct ast_sockaddr * | addr | |||
| ) | [static] |
Handle incoming SIP message - request or response.
This is used for all transports (udp, tcp and tcp/tls)
Definition at line 26158 of file chan_sip.c.
References ao2_t_ref, append_history, ast_channel_unlock, ast_channel_unref, ast_debug, ast_mutex_lock, ast_mutex_unlock, ast_sockaddr_copy(), ast_sockaddr_stringify(), ast_str_buffer(), ast_str_reset(), ast_str_strlen(), ast_update_use_count(), ast_verbose, copy_socket_data(), find_call(), find_sip_method(), get_header(), get_transport(), handle_incoming(), lws2sws(), parse_request(), sip_cfg, sip_debug_test_addr(), sip_pvt_lock_full(), and sip_pvt_unlock.
Referenced by _sip_tcp_helper_thread(), and sipsock_read().
26159 { 26160 struct sip_pvt *p; 26161 struct ast_channel *owner_chan_ref = NULL; 26162 int recount = 0; 26163 int nounlock = 0; 26164 26165 if (sip_debug_test_addr(addr)) /* Set the debug flag early on packet level */ 26166 req->debug = 1; 26167 if (sip_cfg.pedanticsipchecking) 26168 lws2sws(req->data); /* Fix multiline headers */ 26169 if (req->debug) { 26170 ast_verbose("\n<--- SIP read from %s:%s --->\n%s\n<------------->\n", 26171 get_transport(req->socket.type), ast_sockaddr_stringify(addr), ast_str_buffer(req->data)); 26172 } 26173 26174 if (parse_request(req) == -1) { /* Bad packet, can't parse */ 26175 ast_str_reset(req->data); /* nulling this out is NOT a good idea here. */ 26176 return 1; 26177 } 26178 req->method = find_sip_method(REQ_OFFSET_TO_STR(req, rlPart1)); 26179 26180 if (req->debug) 26181 ast_verbose("--- (%d headers %d lines)%s ---\n", req->headers, req->lines, (req->headers + req->lines == 0) ? " Nat keepalive" : ""); 26182 26183 if (req->headers < 2) { /* Must have at least two headers */ 26184 ast_str_reset(req->data); /* nulling this out is NOT a good idea here. */ 26185 return 1; 26186 } 26187 26188 /* Process request, with netlock held, and with usual deadlock avoidance */ 26189 ast_mutex_lock(&netlock); 26190 26191 /* Find the active SIP dialog or create a new one */ 26192 p = find_call(req, addr, req->method); /* returns p with a reference only. _NOT_ locked*/ 26193 if (p == NULL) { 26194 ast_debug(1, "Invalid SIP message - rejected , no callid, len %zu\n", ast_str_strlen(req->data)); 26195 ast_mutex_unlock(&netlock); 26196 return 1; 26197 } 26198 26199 /* Lock both the pvt and the owner if owner is present. This will 26200 * not fail. */ 26201 owner_chan_ref = sip_pvt_lock_full(p); 26202 26203 copy_socket_data(&p->socket, &req->socket); 26204 26205 ast_sockaddr_copy(&p->recv, addr); 26206 26207 /* if we have an owner, then this request has been authenticated */ 26208 if (p->owner) { 26209 req->authenticated = 1; 26210 } 26211 26212 if (p->do_history) /* This is a request or response, note what it was for */ 26213 append_history(p, "Rx", "%s / %s / %s", ast_str_buffer(req->data), get_header(req, "CSeq"), REQ_OFFSET_TO_STR(req, rlPart2)); 26214 26215 if (handle_incoming(p, req, addr, &recount, &nounlock) == -1) { 26216 /* Request failed */ 26217 ast_debug(1, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 26218 } 26219 26220 if (recount) { 26221 ast_update_use_count(); 26222 } 26223 26224 if (p->owner && !nounlock) { 26225 ast_channel_unlock(p->owner); 26226 } 26227 if (owner_chan_ref) { 26228 ast_channel_unref(owner_chan_ref); 26229 } 26230 sip_pvt_unlock(p); 26231 ao2_t_ref(p, -1, "throw away dialog ptr from find_call at end of routine"); /* p is gone after the return */ 26232 ast_mutex_unlock(&netlock); 26233 26234 return 1; 26235 }
| static void handle_request_info | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Receive SIP INFO Message.
Definition at line 19439 of file chan_sip.c.
References ast_bridged_channel(), ast_cdr_setuserfield(), AST_CONTROL_FLASH, AST_CONTROL_VIDUPDATE, ast_copy_string(), ast_debug, ast_find_call_feature(), AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_log(), AST_LOG_WARNING, ast_queue_control(), ast_queue_frame(), ast_rdlock_call_features(), ast_strlen_zero(), ast_test_flag, ast_unlock_call_features(), ast_verbose, ast_channel::cdr, ast_call_feature::exten, f, get_body(), get_header(), get_msg_text(), ast_frame_subclass::integer, ast_frame::len, LOG_WARNING, sip_scheddestroy(), ast_frame::subclass, and transmit_response().
Referenced by handle_incoming().
19440 { 19441 char buf[1024] = ""; 19442 unsigned int event; 19443 const char *c = get_header(req, "Content-Type"); 19444 19445 /* Need to check the media/type */ 19446 if (!strcasecmp(c, "application/dtmf-relay") || 19447 !strcasecmp(c, "application/vnd.nortelnetworks.digits") || 19448 !strcasecmp(c, "application/dtmf")) { 19449 unsigned int duration = 0; 19450 19451 if (!p->owner) { /* not a PBX call */ 19452 transmit_response(p, "481 Call leg/transaction does not exist", req); 19453 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 19454 return; 19455 } 19456 19457 /* If dtmf-relay or vnd.nortelnetworks.digits, parse the signal and duration; 19458 * otherwise use the body as the signal */ 19459 if (strcasecmp(c, "application/dtmf")) { 19460 const char *msg_body; 19461 19462 if ( ast_strlen_zero(msg_body = get_body(req, "Signal", '=')) 19463 && ast_strlen_zero(msg_body = get_body(req, "d", '='))) { 19464 ast_log(LOG_WARNING, "Unable to retrieve DTMF signal for INFO message on " 19465 "call %s\n", p->callid); 19466 transmit_response(p, "200 OK", req); 19467 return; 19468 } 19469 ast_copy_string(buf, msg_body, sizeof(buf)); 19470 19471 if (!ast_strlen_zero((msg_body = get_body(req, "Duration", '=')))) { 19472 sscanf(msg_body, "%30u", &duration); 19473 } 19474 } else { 19475 /* Type is application/dtmf, simply use what's in the message body */ 19476 get_msg_text(buf, sizeof(buf), req); 19477 } 19478 19479 /* An empty message body requires us to send a 200 OK */ 19480 if (ast_strlen_zero(buf)) { 19481 transmit_response(p, "200 OK", req); 19482 return; 19483 } 19484 19485 if (!duration) { 19486 duration = 100; /* 100 ms */ 19487 } 19488 19489 if (buf[0] == '*') { 19490 event = 10; 19491 } else if (buf[0] == '#') { 19492 event = 11; 19493 } else if (buf[0] == '!') { 19494 event = 16; 19495 } else if ('A' <= buf[0] && buf[0] <= 'D') { 19496 event = 12 + buf[0] - 'A'; 19497 } else if ('a' <= buf[0] && buf[0] <= 'd') { 19498 event = 12 + buf[0] - 'a'; 19499 } else if ((sscanf(buf, "%30u", &event) != 1) || event > 16) { 19500 ast_log(AST_LOG_WARNING, "Unable to convert DTMF event signal code to a valid " 19501 "value for INFO message on call %s\n", p->callid); 19502 transmit_response(p, "200 OK", req); 19503 return; 19504 } 19505 19506 if (event == 16) { 19507 /* send a FLASH event */ 19508 struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_FLASH, } }; 19509 ast_queue_frame(p->owner, &f); 19510 if (sipdebug) { 19511 ast_verbose("* DTMF-relay event received: FLASH\n"); 19512 } 19513 } else { 19514 /* send a DTMF event */ 19515 struct ast_frame f = { AST_FRAME_DTMF, }; 19516 if (event < 10) { 19517 f.subclass.integer = '0' + event; 19518 } else if (event == 10) { 19519 f.subclass.integer = '*'; 19520 } else if (event == 11) { 19521 f.subclass.integer = '#'; 19522 } else { 19523 f.subclass.integer = 'A' + (event - 12); 19524 } 19525 f.len = duration; 19526 ast_queue_frame(p->owner, &f); 19527 if (sipdebug) { 19528 ast_verbose("* DTMF-relay event received: %c\n", (int) f.subclass.integer); 19529 } 19530 } 19531 transmit_response(p, "200 OK", req); 19532 return; 19533 } else if (!strcasecmp(c, "application/media_control+xml")) { 19534 /* Eh, we'll just assume it's a fast picture update for now */ 19535 if (p->owner) 19536 ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE); 19537 transmit_response(p, "200 OK", req); 19538 return; 19539 } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) { 19540 /* Client code (from SNOM phone) */ 19541 if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) { 19542 if (p->owner && p->owner->cdr) 19543 ast_cdr_setuserfield(p->owner, c); 19544 if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr) 19545 ast_cdr_setuserfield(ast_bridged_channel(p->owner), c); 19546 transmit_response(p, "200 OK", req); 19547 } else { 19548 transmit_response(p, "403 Forbidden", req); 19549 } 19550 return; 19551 } else if (!ast_strlen_zero(c = get_header(req, "Record"))) { 19552 /* INFO messages generated by some phones to start/stop recording 19553 on phone calls. 19554 OEJ: I think this should be something that is enabled/disabled 19555 per device. I don't want incoming callers to record calls in my 19556 pbx. 19557 */ 19558 19559 struct ast_call_feature *feat; 19560 int j; 19561 struct ast_frame f = { AST_FRAME_DTMF, }; 19562 19563 if (!p->owner) { /* not a PBX call */ 19564 transmit_response(p, "481 Call leg/transaction does not exist", req); 19565 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 19566 return; 19567 } 19568 19569 /* first, get the feature string, if it exists */ 19570 ast_rdlock_call_features(); 19571 feat = ast_find_call_feature("automon"); 19572 if (!feat || ast_strlen_zero(feat->exten)) { 19573 ast_log(LOG_WARNING, "Recording requested, but no One Touch Monitor registered. (See features.conf)\n"); 19574 /* 403 means that we don't support this feature, so don't request it again */ 19575 transmit_response(p, "403 Forbidden", req); 19576 ast_unlock_call_features(); 19577 return; 19578 } 19579 /* Send the feature code to the PBX as DTMF, just like the handset had sent it */ 19580 f.len = 100; 19581 for (j=0; j < strlen(feat->exten); j++) { 19582 f.subclass.integer = feat->exten[j]; 19583 ast_queue_frame(p->owner, &f); 19584 if (sipdebug) 19585 ast_verbose("* DTMF-relay event faked: %c\n", f.subclass.integer); 19586 } 19587 ast_unlock_call_features(); 19588 19589 ast_debug(1, "Got a Request to Record the channel, state %s\n", c); 19590 transmit_response(p, "200 OK", req); 19591 return; 19592 } else if (ast_strlen_zero(c = get_header(req, "Content-Length")) || !strcasecmp(c, "0")) { 19593 /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */ 19594 transmit_response(p, "200 OK", req); 19595 return; 19596 } 19597 19598 /* Other type of INFO message, not really understood by Asterisk */ 19599 /* if (get_msg_text(buf, sizeof(buf), req)) { */ 19600 19601 ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf); 19602 transmit_response(p, "415 Unsupported media type", req); 19603 return; 19604 }
| static int handle_request_invite | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| int | debug, | |||
| uint32_t | seqno, | |||
| struct ast_sockaddr * | addr, | |||
| int * | recount, | |||
| const char * | e, | |||
| int * | nounlock | |||
| ) | [static] |
Handle incoming INVITE request.
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 23135 of file chan_sip.c.
References __get_header(), __sip_ack(), ast_channel::_state, append_history, ARRAY_LEN, AST_CAUSE_FAILURE, ast_cc_agent_set_interfaces_chanvar(), ast_channel_queue_connected_line_update(), ast_channel_set_redirecting(), ast_channel_unlock, ast_clear_flag, AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, AST_CONTROL_BUSY, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, ast_copy_string(), ast_debug, ast_hangup(), ast_log(), AST_MAX_CONTEXT, AST_MAX_EXTENSION, ast_null_frame, ast_party_connected_line_init(), ast_party_redirecting_free(), ast_party_redirecting_init(), AST_PBX_CALL_LIMIT, AST_PBX_FAILED, ast_pbx_start(), AST_PBX_SUCCESS, ast_pickup_ext(), ast_queue_control(), ast_queue_frame(), ast_rtp_instance_set_alt_remote_address(), ast_rtp_instance_set_prop(), AST_RTP_PROPERTY_DTMF, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_sched_add(), AST_SCHED_DEL_UNREF, ast_set_flag, ast_setstate(), ast_setup_cc_recall_datastore(), ast_skip_blanks(), ast_sockaddr_stringify(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_verbose, build_contact(), build_route(), change_hold_state(), change_redirecting_information(), check_user_full(), check_via(), connected, context, copy_request(), do_magic_pickup(), ast_channel::exten, exten, extract_uri(), FALSE, find_sdp(), get_destination(), get_header(), get_ip_and_port_from_sdp(), get_rpid(), get_sip_pvt_byid_locked(), handle_invite_replaces(), handle_request_invite_st(), ast_channel::hangupcause, ast_party_connected_line::id, ast_set_party_connected_line::id, LOG_NOTICE, LOG_WARNING, make_our_tag(), ast_party_id::name, ast_set_party_id::name, ast_party_id::number, ast_set_party_id::number, parse_ok_contact(), parse_sip_options(), ast_party_name::presentation, ast_party_number::presentation, process_sdp(), ref_peer(), restart_session_timer(), S_OR, set_pvt_allowed_methods(), sip_alreadygone(), sip_cancel_destroy(), sip_cfg, sip_methods, sip_new(), sip_pickup(), sip_pvt_lock, sip_pvt_unlock, sip_refer_allocate(), sip_scheddestroy(), sip_t38_abort(), sip_uri_cmp(), ast_party_connected_line::source, ast_party_name::str, ast_party_number::str, ast_party_id::tag, cfsip_methods::text, transmit_provisional_response(), transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), transmit_response_with_t38_sdp(), transmit_response_with_unsupported(), TRUE, unref_peer(), update_call_counter(), update_redirecting(), ast_party_name::valid, and ast_party_number::valid.
Referenced by handle_incoming().
23136 { 23137 int res = 1; 23138 int gotdest; 23139 const char *p_replaces; 23140 char *replace_id = NULL; 23141 int refer_locked = 0; 23142 const char *required; 23143 unsigned int required_profile = 0; 23144 struct ast_channel *c = NULL; /* New channel */ 23145 struct sip_peer *authpeer = NULL; /* Matching Peer */ 23146 int reinvite = 0; 23147 struct ast_party_redirecting redirecting; 23148 struct ast_set_party_redirecting update_redirecting; 23149 int supported_start = 0; 23150 int require_start = 0; 23151 char unsupported[256] = { 0, }; 23152 struct { 23153 char exten[AST_MAX_EXTENSION]; 23154 char context[AST_MAX_CONTEXT]; 23155 } pickup = { 23156 .exten = "", 23157 }; 23158 23159 /* Find out what they support */ 23160 if (!p->sipoptions) { 23161 const char *supported = NULL; 23162 do { 23163 supported = __get_header(req, "Supported", &supported_start); 23164 if (!ast_strlen_zero(supported)) { 23165 p->sipoptions |= parse_sip_options(supported, NULL, 0); 23166 } 23167 } while (!ast_strlen_zero(supported)); 23168 } 23169 23170 /* Find out what they require */ 23171 do { 23172 required = __get_header(req, "Require", &require_start); 23173 if (!ast_strlen_zero(required)) { 23174 required_profile |= parse_sip_options(required, unsupported, ARRAY_LEN(unsupported)); 23175 } 23176 } while (!ast_strlen_zero(required)); 23177 23178 /* If there are any options required that we do not support, 23179 * then send a 420 with only those unsupported options listed */ 23180 if (!ast_strlen_zero(unsupported)) { 23181 transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, unsupported); 23182 ast_log(LOG_WARNING, "Received SIP INVITE with unsupported required extension: required:%s unsupported:%s\n", required, unsupported); 23183 p->invitestate = INV_COMPLETED; 23184 if (!p->lastinvite) { 23185 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23186 } 23187 res = -1; 23188 goto request_invite_cleanup; 23189 } 23190 23191 23192 /* The option tags may be present in Supported: or Require: headers. 23193 Include the Require: option tags for further processing as well */ 23194 p->sipoptions |= required_profile; 23195 p->reqsipoptions = required_profile; 23196 23197 /* Check if this is a loop */ 23198 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->invitestate != INV_TERMINATED && p->invitestate != INV_CONFIRMED) && p->owner->_state != AST_STATE_UP) { 23199 /* This is a call to ourself. Send ourselves an error code and stop 23200 processing immediately, as SIP really has no good mechanism for 23201 being able to call yourself */ 23202 /* If pedantic is on, we need to check the tags. If they're different, this is 23203 in fact a forked call through a SIP proxy somewhere. */ 23204 int different; 23205 const char *initial_rlPart2 = REQ_OFFSET_TO_STR(&p->initreq, rlPart2); 23206 const char *this_rlPart2 = REQ_OFFSET_TO_STR(req, rlPart2); 23207 if (sip_cfg.pedanticsipchecking) 23208 different = sip_uri_cmp(initial_rlPart2, this_rlPart2); 23209 else 23210 different = strcmp(initial_rlPart2, this_rlPart2); 23211 if (!different) { 23212 transmit_response(p, "482 Loop Detected", req); 23213 p->invitestate = INV_COMPLETED; 23214 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23215 res = 0; 23216 goto request_invite_cleanup; 23217 } else { 23218 /*! This is a spiral. What we need to do is to just change the outgoing INVITE 23219 * so that it now routes to the new Request URI. Since we created the INVITE ourselves 23220 * that should be all we need to do. 23221 * 23222 * \todo XXX This needs to be reviewed. YOu don't change the request URI really, you route the packet 23223 * correctly instead... 23224 */ 23225 char *uri = ast_strdupa(this_rlPart2); 23226 char *at = strchr(uri, '@'); 23227 char *peerorhost; 23228 ast_debug(2, "Potential spiral detected. Original RURI was %s, new RURI is %s\n", initial_rlPart2, this_rlPart2); 23229 transmit_response(p, "100 Trying", req); 23230 if (at) { 23231 *at = '\0'; 23232 } 23233 /* Parse out "sip:" */ 23234 if ((peerorhost = strchr(uri, ':'))) { 23235 *peerorhost++ = '\0'; 23236 } 23237 ast_string_field_set(p, theirtag, NULL); 23238 /* Treat this as if there were a call forward instead... 23239 */ 23240 ast_string_field_set(p->owner, call_forward, peerorhost); 23241 ast_queue_control(p->owner, AST_CONTROL_BUSY); 23242 res = 0; 23243 goto request_invite_cleanup; 23244 } 23245 } 23246 23247 if (!req->ignore && p->pendinginvite) { 23248 if (!ast_test_flag(&p->flags[0], SIP_OUTGOING) && (p->invitestate == INV_COMPLETED || p->invitestate == INV_TERMINATED)) { 23249 /* What do these circumstances mean? We have received an INVITE for an "incoming" dialog for which we 23250 * have sent a final response. We have not yet received an ACK, though (which is why p->pendinginvite is non-zero). 23251 * We also know that the INVITE is not a retransmission, because otherwise the "ignore" flag would be set. 23252 * This means that either we are receiving a reinvite for a terminated dialog, or we are receiving an INVITE with 23253 * credentials based on one we challenged earlier. 23254 * 23255 * The action to take in either case is to treat the INVITE as though it contains an implicit ACK for the previous 23256 * transaction. Calling __sip_ack will take care of this by clearing the p->pendinginvite and removing the response 23257 * from the previous transaction from the list of outstanding packets. 23258 */ 23259 __sip_ack(p, p->pendinginvite, 1, 0); 23260 } else { 23261 /* We already have a pending invite. Sorry. You are on hold. */ 23262 p->glareinvite = seqno; 23263 if (p->rtp && find_sdp(req)) { 23264 struct ast_sockaddr addr; 23265 if (get_ip_and_port_from_sdp(req, SDP_AUDIO, &addr)) { 23266 ast_log(LOG_WARNING, "Failed to set an alternate media source on glared reinvite. Audio may not work properly on this call.\n"); 23267 } else { 23268 ast_rtp_instance_set_alt_remote_address(p->rtp, &addr); 23269 } 23270 if (p->vrtp) { 23271 if (get_ip_and_port_from_sdp(req, SDP_VIDEO, &addr)) { 23272 ast_log(LOG_WARNING, "Failed to set an alternate media source on glared reinvite. Video may not work properly on this call.\n"); 23273 } else { 23274 ast_rtp_instance_set_alt_remote_address(p->vrtp, &addr); 23275 } 23276 } 23277 } 23278 transmit_response_reliable(p, "491 Request Pending", req); 23279 check_via(p, req); 23280 ast_debug(1, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid); 23281 /* Don't destroy dialog here */ 23282 res = 0; 23283 goto request_invite_cleanup; 23284 } 23285 } 23286 23287 p_replaces = get_header(req, "Replaces"); 23288 if (!ast_strlen_zero(p_replaces)) { 23289 /* We have a replaces header */ 23290 char *ptr; 23291 char *fromtag = NULL; 23292 char *totag = NULL; 23293 char *start, *to; 23294 int error = 0; 23295 23296 if (p->owner) { 23297 ast_debug(3, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid); 23298 transmit_response_reliable(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 23299 check_via(p, req); 23300 copy_request(&p->initreq, req); 23301 /* Do not destroy existing call */ 23302 res = -1; 23303 goto request_invite_cleanup; 23304 } 23305 23306 if (sipdebug) 23307 ast_debug(3, "INVITE part of call transfer. Replaces [%s]\n", p_replaces); 23308 /* Create a buffer we can manipulate */ 23309 replace_id = ast_strdupa(p_replaces); 23310 ast_uri_decode(replace_id); 23311 23312 if (!p->refer && !sip_refer_allocate(p)) { 23313 transmit_response_reliable(p, "500 Server Internal Error", req); 23314 append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory."); 23315 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23316 p->invitestate = INV_COMPLETED; 23317 check_via(p, req); 23318 copy_request(&p->initreq, req); 23319 res = -1; 23320 goto request_invite_cleanup; 23321 } 23322 23323 /* Todo: (When we find phones that support this) 23324 if the replaces header contains ";early-only" 23325 we can only replace the call in early 23326 stage, not after it's up. 23327 23328 If it's not in early mode, 486 Busy. 23329 */ 23330 23331 /* Skip leading whitespace */ 23332 replace_id = ast_skip_blanks(replace_id); 23333 23334 start = replace_id; 23335 while ( (ptr = strsep(&start, ";")) ) { 23336 ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */ 23337 if ( (to = strcasestr(ptr, "to-tag=") ) ) 23338 totag = to + 7; /* skip the keyword */ 23339 else if ( (to = strcasestr(ptr, "from-tag=") ) ) { 23340 fromtag = to + 9; /* skip the keyword */ 23341 fromtag = strsep(&fromtag, "&"); /* trim what ? */ 23342 } 23343 } 23344 23345 if (sipdebug) 23346 ast_debug(4, "Invite/replaces: Will use Replace-Call-ID : %s Fromtag: %s Totag: %s\n", 23347 replace_id, 23348 fromtag ? fromtag : "<no from tag>", 23349 totag ? totag : "<no to tag>"); 23350 23351 /* Try to find call that we are replacing. 23352 If we have a Replaces header, we need to cancel that call if we succeed with this call. 23353 First we cheat a little and look for a magic call-id from phones that support 23354 dialog-info+xml so we can do technology independent pickup... */ 23355 if (strncmp(replace_id, "pickup-", 7) == 0) { 23356 struct sip_pvt *subscription = NULL; 23357 replace_id += 7; /* Worst case we are looking at \0 */ 23358 23359 if ((subscription = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) { 23360 ast_log(LOG_NOTICE, "Unable to find subscription with call-id: %s\n", replace_id); 23361 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replaces)", req); 23362 error = 1; 23363 } else { 23364 ast_log(LOG_NOTICE, "Trying to pick up %s@%s\n", subscription->exten, subscription->context); 23365 ast_copy_string(pickup.exten, subscription->exten, sizeof(pickup.exten)); 23366 ast_copy_string(pickup.context, subscription->context, sizeof(pickup.context)); 23367 sip_pvt_unlock(subscription); 23368 if (subscription->owner) { 23369 ast_channel_unlock(subscription->owner); 23370 } 23371 subscription = dialog_unref(subscription, "unref dialog subscription"); 23372 } 23373 } 23374 23375 /* This locks both refer_call pvt and refer_call pvt's owner!!!*/ 23376 if (!error && ast_strlen_zero(pickup.exten) && (p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) { 23377 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id); 23378 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replaces)", req); 23379 error = 1; 23380 } else { 23381 refer_locked = 1; 23382 } 23383 23384 /* The matched call is the call from the transferer to Asterisk . 23385 We want to bridge the bridged part of the call to the 23386 incoming invite, thus taking over the refered call */ 23387 23388 if (p->refer->refer_call == p) { 23389 ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid); 23390 transmit_response_reliable(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 23391 error = 1; 23392 } 23393 23394 if (!error && ast_strlen_zero(pickup.exten) && !p->refer->refer_call->owner) { 23395 /* Oops, someting wrong anyway, no owner, no call */ 23396 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id); 23397 /* Check for better return code */ 23398 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replace)", req); 23399 error = 1; 23400 } 23401 23402 if (!error && ast_strlen_zero(pickup.exten) && p->refer->refer_call->owner->_state != AST_STATE_RINGING && p->refer->refer_call->owner->_state != AST_STATE_RING && p->refer->refer_call->owner->_state != AST_STATE_UP) { 23403 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id); 23404 transmit_response_reliable(p, "603 Declined (Replaces)", req); 23405 error = 1; 23406 } 23407 23408 if (error) { /* Give up this dialog */ 23409 append_history(p, "Xfer", "INVITE/Replace Failed."); 23410 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23411 sip_pvt_unlock(p); 23412 if (p->refer->refer_call) { 23413 sip_pvt_unlock(p->refer->refer_call); 23414 if (p->refer->refer_call->owner) { 23415 ast_channel_unlock(p->refer->refer_call->owner); 23416 } 23417 p->refer->refer_call = dialog_unref(p->refer->refer_call, "unref dialog p->refer->refer_call"); 23418 } 23419 refer_locked = 0; 23420 p->invitestate = INV_COMPLETED; 23421 check_via(p, req); 23422 copy_request(&p->initreq, req); 23423 res = -1; 23424 goto request_invite_cleanup; 23425 } 23426 } 23427 23428 /* Check if this is an INVITE that sets up a new dialog or 23429 a re-invite in an existing dialog */ 23430 23431 if (!req->ignore) { 23432 int newcall = (p->initreq.headers ? TRUE : FALSE); 23433 23434 if (sip_cancel_destroy(p)) 23435 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 23436 /* This also counts as a pending invite */ 23437 p->pendinginvite = seqno; 23438 check_via(p, req); 23439 23440 copy_request(&p->initreq, req); /* Save this INVITE as the transaction basis */ 23441 if (sipdebug) 23442 ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid); 23443 if (!p->owner) { /* Not a re-invite */ 23444 if (debug) 23445 ast_verbose("Using INVITE request as basis request - %s\n", p->callid); 23446 if (newcall) 23447 append_history(p, "Invite", "New call: %s", p->callid); 23448 parse_ok_contact(p, req); 23449 } else { /* Re-invite on existing call */ 23450 ast_clear_flag(&p->flags[0], SIP_OUTGOING); /* This is now an inbound dialog */ 23451 if (get_rpid(p, req)) { 23452 struct ast_party_connected_line connected; 23453 struct ast_set_party_connected_line update_connected; 23454 23455 ast_party_connected_line_init(&connected); 23456 memset(&update_connected, 0, sizeof(update_connected)); 23457 23458 update_connected.id.number = 1; 23459 connected.id.number.valid = 1; 23460 connected.id.number.str = (char *) p->cid_num; 23461 connected.id.number.presentation = p->callingpres; 23462 23463 update_connected.id.name = 1; 23464 connected.id.name.valid = 1; 23465 connected.id.name.str = (char *) p->cid_name; 23466 connected.id.name.presentation = p->callingpres; 23467 23468 connected.id.tag = (char *) p->cid_tag; 23469 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER; 23470 ast_channel_queue_connected_line_update(p->owner, &connected, 23471 &update_connected); 23472 } 23473 /* Handle SDP here if we already have an owner */ 23474 if (find_sdp(req)) { 23475 if (process_sdp(p, req, SDP_T38_INITIATE)) { 23476 if (!ast_strlen_zero(get_header(req, "Content-Encoding"))) { 23477 /* Asterisk does not yet support any Content-Encoding methods. Always 23478 * attempt to process the sdp, but return a 415 if a Content-Encoding header 23479 * was present after processing failed. */ 23480 transmit_response_reliable(p, "415 Unsupported Media type", req); 23481 } else { 23482 transmit_response_reliable(p, "488 Not acceptable here", req); 23483 } 23484 if (!p->lastinvite) 23485 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23486 res = -1; 23487 goto request_invite_cleanup; 23488 } 23489 ast_queue_control(p->owner, AST_CONTROL_SRCUPDATE); 23490 } else { 23491 p->jointcapability = p->capability; 23492 ast_debug(1, "Hm.... No sdp for the moment\n"); 23493 /* Some devices signal they want to be put off hold by sending a re-invite 23494 *without* an SDP, which is supposed to mean "Go back to your state" 23495 and since they put os on remote hold, we go back to off hold */ 23496 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 23497 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 23498 /* Activate a re-invite */ 23499 ast_queue_frame(p->owner, &ast_null_frame); 23500 change_hold_state(p, req, FALSE, 0); 23501 } 23502 } 23503 if (p->do_history) /* This is a response, note what it was for */ 23504 append_history(p, "ReInv", "Re-invite received"); 23505 } 23506 } else if (debug) 23507 ast_verbose("Ignoring this INVITE request\n"); 23508 23509 if (!p->lastinvite && !req->ignore && !p->owner) { 23510 /* This is a new invite */ 23511 /* Handle authentication if this is our first invite */ 23512 int cc_recall_core_id = -1; 23513 set_pvt_allowed_methods(p, req); 23514 res = check_user_full(p, req, SIP_INVITE, e, XMIT_RELIABLE, addr, &authpeer); 23515 if (res == AUTH_CHALLENGE_SENT) { 23516 p->invitestate = INV_COMPLETED; /* Needs to restart in another INVITE transaction */ 23517 res = 0; 23518 goto request_invite_cleanup; 23519 } 23520 if (res < 0) { /* Something failed in authentication */ 23521 ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From")); 23522 transmit_response_reliable(p, "403 Forbidden", req); 23523 p->invitestate = INV_COMPLETED; 23524 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23525 res = 0; 23526 goto request_invite_cleanup; 23527 } 23528 23529 /* Successful authentication and peer matching so record the peer related to this pvt (for easy access to peer settings) */ 23530 if (p->relatedpeer) { 23531 p->relatedpeer = unref_peer(p->relatedpeer,"unsetting the relatedpeer field in the dialog, before it is set to something else."); 23532 } 23533 if (authpeer) { 23534 p->relatedpeer = ref_peer(authpeer, "setting dialog's relatedpeer pointer"); 23535 } 23536 23537 req->authenticated = 1; 23538 23539 /* We have a successful authentication, process the SDP portion if there is one */ 23540 if (find_sdp(req)) { 23541 if (process_sdp(p, req, SDP_T38_INITIATE)) { 23542 /* Asterisk does not yet support any Content-Encoding methods. Always 23543 * attempt to process the sdp, but return a 415 if a Content-Encoding header 23544 * was present after processing fails. */ 23545 if (!ast_strlen_zero(get_header(req, "Content-Encoding"))) { 23546 transmit_response_reliable(p, "415 Unsupported Media type", req); 23547 } else { 23548 /* Unacceptable codecs */ 23549 transmit_response_reliable(p, "488 Not acceptable here", req); 23550 } 23551 p->invitestate = INV_COMPLETED; 23552 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23553 ast_debug(1, "No compatible codecs for this SIP call.\n"); 23554 res = -1; 23555 goto request_invite_cleanup; 23556 } 23557 } else { /* No SDP in invite, call control session */ 23558 p->jointcapability = p->capability; 23559 ast_debug(2, "No SDP in Invite, third party call control\n"); 23560 } 23561 23562 /* Initialize the context if it hasn't been already */ 23563 if (ast_strlen_zero(p->context)) 23564 ast_string_field_set(p, context, sip_cfg.default_context); 23565 23566 23567 /* Check number of concurrent calls -vs- incoming limit HERE */ 23568 ast_debug(1, "Checking SIP call limits for device %s\n", p->username); 23569 if ((res = update_call_counter(p, INC_CALL_LIMIT))) { 23570 if (res < 0) { 23571 ast_log(LOG_NOTICE, "Failed to place call for device %s, too many calls\n", p->username); 23572 transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req); 23573 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23574 p->invitestate = INV_COMPLETED; 23575 } 23576 res = 0; 23577 goto request_invite_cleanup; 23578 } 23579 gotdest = get_destination(p, NULL, &cc_recall_core_id); /* Get destination right away */ 23580 extract_uri(p, req); /* Get the Contact URI */ 23581 build_contact(p); /* Build our contact header */ 23582 23583 if (p->rtp) { 23584 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 23585 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 23586 } 23587 23588 if (!replace_id && (gotdest != SIP_GET_DEST_EXTEN_FOUND)) { /* No matching extension found */ 23589 switch(gotdest) { 23590 case SIP_GET_DEST_INVALID_URI: 23591 transmit_response_reliable(p, "416 Unsupported URI scheme", req); 23592 break; 23593 case SIP_GET_DEST_EXTEN_MATCHMORE: 23594 if (ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP) 23595 == SIP_PAGE2_ALLOWOVERLAP_YES) { 23596 transmit_response_reliable(p, "484 Address Incomplete", req); 23597 break; 23598 } 23599 /* 23600 * XXX We would have to implement collecting more digits in 23601 * chan_sip for any other schemes of overlap dialing. 23602 * 23603 * For SIP_PAGE2_ALLOWOVERLAP_DTMF it is better to do this in 23604 * the dialplan using the Incomplete application rather than 23605 * having the channel driver do it. 23606 */ 23607 /* Fall through */ 23608 case SIP_GET_DEST_EXTEN_NOT_FOUND: 23609 { 23610 char *decoded_exten = ast_strdupa(p->exten); 23611 transmit_response_reliable(p, "404 Not Found", req); 23612 ast_uri_decode(decoded_exten); 23613 ast_log(LOG_NOTICE, "Call from '%s' (%s) to extension" 23614 " '%s' rejected because extension not found in context '%s'.\n", 23615 S_OR(p->username, p->peername), ast_sockaddr_stringify(&p->recv), decoded_exten, p->context); 23616 } 23617 break; 23618 case SIP_GET_DEST_REFUSED: 23619 default: 23620 transmit_response_reliable(p, "403 Forbidden", req); 23621 } /* end switch */ 23622 23623 p->invitestate = INV_COMPLETED; 23624 update_call_counter(p, DEC_CALL_LIMIT); 23625 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23626 res = 0; 23627 goto request_invite_cleanup; 23628 } else { 23629 23630 /* If no extension was specified, use the s one */ 23631 /* Basically for calling to IP/Host name only */ 23632 if (ast_strlen_zero(p->exten)) 23633 ast_string_field_set(p, exten, "s"); 23634 /* Initialize our tag */ 23635 23636 make_our_tag(p); 23637 23638 if (handle_request_invite_st(p, req, required, reinvite)) { 23639 p->invitestate = INV_COMPLETED; 23640 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23641 res = -1; 23642 goto request_invite_cleanup; 23643 } 23644 23645 /* First invitation - create the channel. Allocation 23646 * failures are handled below. */ 23647 c = sip_new(p, AST_STATE_DOWN, S_OR(p->peername, NULL), NULL); 23648 if (cc_recall_core_id != -1) { 23649 ast_setup_cc_recall_datastore(c, cc_recall_core_id); 23650 ast_cc_agent_set_interfaces_chanvar(c); 23651 } 23652 *recount = 1; 23653 23654 /* Save Record-Route for any later requests we make on this dialogue */ 23655 build_route(p, req, 0, 0); 23656 23657 if (c) { 23658 ast_party_redirecting_init(&redirecting); 23659 memset(&update_redirecting, 0, sizeof(update_redirecting)); 23660 change_redirecting_information(p, req, &redirecting, &update_redirecting, 23661 FALSE); /*Will return immediately if no Diversion header is present */ 23662 ast_channel_set_redirecting(c, &redirecting, &update_redirecting); 23663 ast_party_redirecting_free(&redirecting); 23664 } 23665 } 23666 } else { 23667 ast_party_redirecting_init(&redirecting); 23668 memset(&update_redirecting, 0, sizeof(update_redirecting)); 23669 if (sipdebug) { 23670 if (!req->ignore) 23671 ast_debug(2, "Got a SIP re-invite for call %s\n", p->callid); 23672 else 23673 ast_debug(2, "Got a SIP re-transmit of INVITE for call %s\n", p->callid); 23674 } 23675 if (!req->ignore) 23676 reinvite = 1; 23677 23678 if (handle_request_invite_st(p, req, required, reinvite)) { 23679 p->invitestate = INV_COMPLETED; 23680 if (!p->lastinvite) { 23681 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23682 } 23683 res = -1; 23684 goto request_invite_cleanup; 23685 } 23686 23687 c = p->owner; 23688 change_redirecting_information(p, req, &redirecting, &update_redirecting, FALSE); /*Will return immediately if no Diversion header is present */ 23689 if (c) { 23690 ast_channel_set_redirecting(c, &redirecting, &update_redirecting); 23691 } 23692 ast_party_redirecting_free(&redirecting); 23693 } 23694 23695 if (reinvite && p->stimer->st_active == TRUE) { 23696 restart_session_timer(p); 23697 } 23698 23699 if (!req->ignore && p) 23700 p->lastinvite = seqno; 23701 23702 if (c && replace_id) { /* Attended transfer or call pickup - we're the target */ 23703 if (!ast_strlen_zero(pickup.exten)) { 23704 append_history(p, "Xfer", "INVITE/Replace received"); 23705 23706 /* Let the caller know we're giving it a shot */ 23707 transmit_response(p, "100 Trying", req); 23708 p->invitestate = INV_PROCEEDING; 23709 ast_setstate(c, AST_STATE_RING); 23710 23711 /* Do the pickup itself */ 23712 ast_channel_unlock(c); 23713 *nounlock = 1; 23714 23715 /* since p->owner (c) is unlocked, we need to go ahead and unlock pvt for both 23716 * magic pickup and ast_hangup. Both of these functions will attempt to lock 23717 * p->owner again, which can cause a deadlock if we already hold a lock on p. 23718 * Locking order is, channel then pvt. Dead lock avoidance must be used if 23719 * called the other way around. */ 23720 sip_pvt_unlock(p); 23721 do_magic_pickup(c, pickup.exten, pickup.context); 23722 /* Now we're either masqueraded or we failed to pickup, in either case we... */ 23723 ast_hangup(c); 23724 sip_pvt_lock(p); /* pvt is expected to remain locked on return, so re-lock it */ 23725 23726 res = 0; 23727 goto request_invite_cleanup; 23728 } else { 23729 /* Go and take over the target call */ 23730 if (sipdebug) 23731 ast_debug(4, "Sending this call to the invite/replcaes handler %s\n", p->callid); 23732 res = handle_invite_replaces(p, req, debug, seqno, addr, nounlock); 23733 refer_locked = 0; 23734 goto request_invite_cleanup; 23735 } 23736 } 23737 23738 23739 if (c) { /* We have a call -either a new call or an old one (RE-INVITE) */ 23740 enum ast_channel_state c_state = c->_state; 23741 23742 if (c_state != AST_STATE_UP && reinvite && 23743 (p->invitestate == INV_TERMINATED || p->invitestate == INV_CONFIRMED)) { 23744 /* If these conditions are true, and the channel is still in the 'ringing' 23745 * state, then this likely means that we have a situation where the initial 23746 * INVITE transaction has completed *but* the channel's state has not yet been 23747 * changed to UP. The reason this could happen is if the reinvite is received 23748 * on the SIP socket prior to an application calling ast_read on this channel 23749 * to read the answer frame we earlier queued on it. In this case, the reinvite 23750 * is completely legitimate so we need to handle this the same as if the channel 23751 * were already UP. Thus we are purposely falling through to the AST_STATE_UP case. 23752 */ 23753 c_state = AST_STATE_UP; 23754 } 23755 23756 switch(c_state) { 23757 case AST_STATE_DOWN: 23758 ast_debug(2, "%s: New call is still down.... Trying... \n", c->name); 23759 transmit_provisional_response(p, "100 Trying", req, 0); 23760 p->invitestate = INV_PROCEEDING; 23761 ast_setstate(c, AST_STATE_RING); 23762 if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */ 23763 enum ast_pbx_result result; 23764 23765 result = ast_pbx_start(c); 23766 23767 switch(result) { 23768 case AST_PBX_FAILED: 23769 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 23770 p->invitestate = INV_COMPLETED; 23771 transmit_response_reliable(p, "503 Unavailable", req); 23772 break; 23773 case AST_PBX_CALL_LIMIT: 23774 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n"); 23775 p->invitestate = INV_COMPLETED; 23776 transmit_response_reliable(p, "480 Temporarily Unavailable", req); 23777 break; 23778 case AST_PBX_SUCCESS: 23779 /* nothing to do */ 23780 break; 23781 } 23782 23783 if (result) { 23784 23785 /* Unlock locks so ast_hangup can do its magic */ 23786 ast_channel_unlock(c); 23787 *nounlock = 1; 23788 sip_pvt_unlock(p); 23789 ast_hangup(c); 23790 sip_pvt_lock(p); 23791 c = NULL; 23792 } 23793 } else { /* Pickup call in call group */ 23794 if (sip_pickup(c)) { 23795 ast_log(LOG_WARNING, "Failed to start Group pickup by %s\n", c->name); 23796 transmit_response_reliable(p, "480 Temporarily Unavailable", req); 23797 sip_alreadygone(p); 23798 c->hangupcause = AST_CAUSE_FAILURE; 23799 23800 /* Unlock locks so ast_hangup can do its magic */ 23801 ast_channel_unlock(c); 23802 *nounlock = 1; 23803 23804 p->invitestate = INV_COMPLETED; 23805 sip_pvt_unlock(p); 23806 ast_hangup(c); 23807 sip_pvt_lock(p); 23808 c = NULL; 23809 } 23810 } 23811 break; 23812 case AST_STATE_RING: 23813 transmit_provisional_response(p, "100 Trying", req, 0); 23814 p->invitestate = INV_PROCEEDING; 23815 break; 23816 case AST_STATE_RINGING: 23817 transmit_provisional_response(p, "180 Ringing", req, 0); 23818 p->invitestate = INV_PROCEEDING; 23819 break; 23820 case AST_STATE_UP: 23821 ast_debug(2, "%s: This call is UP.... \n", c->name); 23822 23823 transmit_response(p, "100 Trying", req); 23824 23825 if (p->t38.state == T38_PEER_REINVITE) { 23826 if (p->t38id > -1) { 23827 /* reset t38 abort timer */ 23828 AST_SCHED_DEL_UNREF(sched, p->t38id, dialog_unref(p, "remove ref for t38id")); 23829 } 23830 p->t38id = ast_sched_add(sched, 5000, sip_t38_abort, dialog_ref(p, "passing dialog ptr into sched structure based on t38id for sip_t38_abort.")); 23831 } else if (p->t38.state == T38_ENABLED) { 23832 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 23833 transmit_response_with_t38_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (req->ignore ? XMIT_UNRELIABLE : XMIT_CRITICAL))); 23834 } else if (p->t38.state == T38_DISABLED) { 23835 /* If this is not a re-invite or something to ignore - it's critical */ 23836 if (p->srtp && !ast_test_flag(p->srtp, SRTP_CRYPTO_OFFER_OK)) { 23837 ast_log(LOG_WARNING, "Target does not support required crypto\n"); 23838 transmit_response_reliable(p, "488 Not Acceptable Here (crypto)", req); 23839 } else { 23840 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 23841 transmit_response_with_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (req->ignore ? XMIT_UNRELIABLE : XMIT_CRITICAL)), p->session_modify == TRUE ? FALSE : TRUE, FALSE); 23842 ast_queue_control(p->owner, AST_CONTROL_UPDATE_RTP_PEER); 23843 } 23844 } 23845 23846 p->invitestate = INV_TERMINATED; 23847 break; 23848 default: 23849 ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %u\n", c->_state); 23850 transmit_response(p, "100 Trying", req); 23851 break; 23852 } 23853 } else { 23854 if (!req->ignore && p && (p->autokillid == -1)) { 23855 const char *msg; 23856 23857 if (!p->jointcapability) 23858 msg = "488 Not Acceptable Here (codec error)"; 23859 else { 23860 ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n"); 23861 msg = "503 Unavailable"; 23862 } 23863 transmit_response_reliable(p, msg, req); 23864 p->invitestate = INV_COMPLETED; 23865 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23866 } 23867 } 23868 23869 request_invite_cleanup: 23870 23871 if (refer_locked && p->refer && p->refer->refer_call) { 23872 sip_pvt_unlock(p->refer->refer_call); 23873 if (p->refer->refer_call->owner) { 23874 ast_channel_unlock(p->refer->refer_call->owner); 23875 } 23876 p->refer->refer_call = dialog_unref(p->refer->refer_call, "unref dialog p->refer->refer_call"); 23877 } 23878 if (authpeer) { 23879 authpeer = unref_peer(authpeer, "unref_peer, from handle_request_invite authpeer"); 23880 } 23881 23882 return res; 23883 }
| static int handle_request_invite_st | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| const char * | required, | |||
| int | reinvite | |||
| ) | [static] |
Definition at line 22995 of file chan_sip.c.
References ast_debug, ast_log(), ast_strlen_zero(), FALSE, get_header(), LOG_ERROR, LOG_WARNING, MAX, parse_minse(), parse_session_expires(), sip_st_alloc(), st_get_mode(), st_get_refresher(), st_get_se(), transmit_response_reliable(), transmit_response_with_minse(), transmit_response_with_unsupported(), and TRUE.
Referenced by handle_request_invite().
22997 { 22998 const char *p_uac_se_hdr; /* UAC's Session-Expires header string */ 22999 const char *p_uac_min_se; /* UAC's requested Min-SE interval (char string) */ 23000 int uac_max_se = -1; /* UAC's Session-Expires in integer format */ 23001 int uac_min_se = -1; /* UAC's Min-SE in integer format */ 23002 int st_active = FALSE; /* Session-Timer on/off boolean */ 23003 int st_interval = 0; /* Session-Timer negotiated refresh interval */ 23004 enum st_refresher tmp_st_ref = SESSION_TIMER_REFRESHER_AUTO; /* Session-Timer refresher */ 23005 int dlg_min_se = -1; 23006 int dlg_max_se = global_max_se; 23007 int rtn; 23008 23009 /* Session-Timers */ 23010 if ((p->sipoptions & SIP_OPT_TIMER)) { 23011 enum st_refresher_param st_ref_param = SESSION_TIMER_REFRESHER_PARAM_UNKNOWN; 23012 23013 /* The UAC has requested session-timers for this session. Negotiate 23014 the session refresh interval and who will be the refresher */ 23015 ast_debug(2, "Incoming INVITE with 'timer' option supported\n"); 23016 23017 /* Allocate Session-Timers struct w/in the dialog */ 23018 if (!p->stimer) { 23019 sip_st_alloc(p); 23020 } 23021 23022 /* Parse the Session-Expires header */ 23023 p_uac_se_hdr = get_header(req, "Session-Expires"); 23024 if (!ast_strlen_zero(p_uac_se_hdr)) { 23025 ast_debug(2, "INVITE also has \"Session-Expires\" header.\n"); 23026 rtn = parse_session_expires(p_uac_se_hdr, &uac_max_se, &st_ref_param); 23027 tmp_st_ref = (st_ref_param == SESSION_TIMER_REFRESHER_PARAM_UAC) ? SESSION_TIMER_REFRESHER_THEM : SESSION_TIMER_REFRESHER_US; 23028 if (rtn != 0) { 23029 transmit_response_reliable(p, "400 Session-Expires Invalid Syntax", req); 23030 return -1; 23031 } 23032 } 23033 23034 /* Parse the Min-SE header */ 23035 p_uac_min_se = get_header(req, "Min-SE"); 23036 if (!ast_strlen_zero(p_uac_min_se)) { 23037 ast_debug(2, "INVITE also has \"Min-SE\" header.\n"); 23038 rtn = parse_minse(p_uac_min_se, &uac_min_se); 23039 if (rtn != 0) { 23040 transmit_response_reliable(p, "400 Min-SE Invalid Syntax", req); 23041 return -1; 23042 } 23043 } 23044 23045 dlg_min_se = st_get_se(p, FALSE); 23046 switch (st_get_mode(p, 1)) { 23047 case SESSION_TIMER_MODE_ACCEPT: 23048 case SESSION_TIMER_MODE_ORIGINATE: 23049 if (uac_max_se > 0 && uac_max_se < dlg_min_se) { 23050 transmit_response_with_minse(p, "422 Session Interval Too Small", req, dlg_min_se); 23051 return -1; 23052 } 23053 23054 p->stimer->st_active_peer_ua = TRUE; 23055 st_active = TRUE; 23056 if (st_ref_param == SESSION_TIMER_REFRESHER_PARAM_UNKNOWN) { 23057 tmp_st_ref = st_get_refresher(p); 23058 } 23059 23060 dlg_max_se = st_get_se(p, TRUE); 23061 if (uac_max_se > 0) { 23062 if (dlg_max_se >= uac_min_se) { 23063 st_interval = (uac_max_se < dlg_max_se) ? uac_max_se : dlg_max_se; 23064 } else { 23065 st_interval = uac_max_se; 23066 } 23067 } else if (uac_min_se > 0) { 23068 st_interval = MAX(dlg_max_se, uac_min_se); 23069 } else { 23070 st_interval = dlg_max_se; 23071 } 23072 break; 23073 23074 case SESSION_TIMER_MODE_REFUSE: 23075 if (p->reqsipoptions & SIP_OPT_TIMER) { 23076 transmit_response_with_unsupported(p, "420 Option Disabled", req, required); 23077 ast_log(LOG_WARNING, "Received SIP INVITE with supported but disabled option: %s\n", required); 23078 return -1; 23079 } 23080 break; 23081 23082 default: 23083 ast_log(LOG_ERROR, "Internal Error %u at %s:%d\n", st_get_mode(p, 1), __FILE__, __LINE__); 23084 break; 23085 } 23086 } else { 23087 /* The UAC did not request session-timers. Asterisk (UAS), will now decide 23088 (based on session-timer-mode in sip.conf) whether to run session-timers for 23089 this session or not. */ 23090 switch (st_get_mode(p, 1)) { 23091 case SESSION_TIMER_MODE_ORIGINATE: 23092 st_active = TRUE; 23093 st_interval = st_get_se(p, TRUE); 23094 tmp_st_ref = SESSION_TIMER_REFRESHER_US; 23095 p->stimer->st_active_peer_ua = (p->sipoptions & SIP_OPT_TIMER) ? TRUE : FALSE; 23096 break; 23097 23098 default: 23099 break; 23100 } 23101 } 23102 23103 if (reinvite == 0) { 23104 /* Session-Timers: Start session refresh timer based on negotiation/config */ 23105 if (st_active == TRUE) { 23106 p->stimer->st_active = TRUE; 23107 p->stimer->st_interval = st_interval; 23108 p->stimer->st_ref = tmp_st_ref; 23109 } 23110 } else { 23111 if (p->stimer->st_active == TRUE) { 23112 /* Session-Timers: A re-invite request sent within a dialog will serve as 23113 a refresh request, no matter whether the re-invite was sent for refreshing 23114 the session or modifying it.*/ 23115 ast_debug (2, "Restarting session-timers on a refresh - %s\n", p->callid); 23116 23117 /* The UAC may be adjusting the session-timers mid-session */ 23118 if (st_interval > 0) { 23119 p->stimer->st_interval = st_interval; 23120 p->stimer->st_ref = tmp_st_ref; 23121 } 23122 } 23123 } 23124 23125 return 0; 23126 }
| static int handle_request_message | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Handle incoming MESSAGE request.
Definition at line 24774 of file chan_sip.c.
References ast_verbose, receive_message(), and transmit_response().
Referenced by handle_incoming().
24775 { 24776 if (!req->ignore) { 24777 if (req->debug) 24778 ast_verbose("Receiving message!\n"); 24779 receive_message(p, req); 24780 } else 24781 transmit_response(p, "202 Accepted", req); 24782 return 1; 24783 }
| static int handle_request_notify | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| struct ast_sockaddr * | addr, | |||
| uint32_t | seqno, | |||
| const char * | e | |||
| ) | [static] |
Handle incoming notifications.
Definition at line 22517 of file chan_sip.c.
References AST_CONTROL_TRANSFER, ast_debug, AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, ast_event_new(), ast_event_queue_and_cache(), ast_log(), ast_queue_control_data(), ast_skip_blanks(), ast_strdupa, ast_strlen_zero(), AST_TRANSFER_FAILED, AST_TRANSFER_SUCCESS, FALSE, find_peer(), get_body(), get_header(), get_msg_text(), handle_cc_notify(), LOG_NOTICE, LOG_WARNING, mailbox, sip_scheddestroy(), transmit_response(), TRUE, and unref_peer().
Referenced by handle_incoming().
22518 { 22519 /* This is mostly a skeleton for future improvements */ 22520 /* Mostly created to return proper answers on notifications on outbound REFER's */ 22521 int res = 0; 22522 const char *event = get_header(req, "Event"); 22523 char *sep; 22524 22525 if( (sep = strchr(event, ';')) ) { /* XXX bug here - overwriting string ? */ 22526 *sep++ = '\0'; 22527 } 22528 22529 if (sipdebug) 22530 ast_debug(2, "Got NOTIFY Event: %s\n", event); 22531 22532 if (!strcmp(event, "refer")) { 22533 /* Save nesting depth for now, since there might be other events we will 22534 support in the future */ 22535 22536 /* Handle REFER notifications */ 22537 22538 char buf[1024]; 22539 char *cmd, *code; 22540 int respcode; 22541 int success = TRUE; 22542 22543 /* EventID for each transfer... EventID is basically the REFER cseq 22544 22545 We are getting notifications on a call that we transferred 22546 We should hangup when we are getting a 200 OK in a sipfrag 22547 Check if we have an owner of this event */ 22548 22549 /* Check the content type */ 22550 if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) { 22551 /* We need a sipfrag */ 22552 transmit_response(p, "400 Bad request", req); 22553 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22554 return -1; 22555 } 22556 22557 /* Get the text of the attachment */ 22558 if (get_msg_text(buf, sizeof(buf), req)) { 22559 ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid); 22560 transmit_response(p, "400 Bad request", req); 22561 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22562 return -1; 22563 } 22564 22565 /* 22566 From the RFC... 22567 A minimal, but complete, implementation can respond with a single 22568 NOTIFY containing either the body: 22569 SIP/2.0 100 Trying 22570 22571 if the subscription is pending, the body: 22572 SIP/2.0 200 OK 22573 if the reference was successful, the body: 22574 SIP/2.0 503 Service Unavailable 22575 if the reference failed, or the body: 22576 SIP/2.0 603 Declined 22577 22578 if the REFER request was accepted before approval to follow the 22579 reference could be obtained and that approval was subsequently denied 22580 (see Section 2.4.7). 22581 22582 If there are several REFERs in the same dialog, we need to 22583 match the ID of the event header... 22584 */ 22585 ast_debug(3, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf); 22586 cmd = ast_skip_blanks(buf); 22587 code = cmd; 22588 /* We are at SIP/2.0 */ 22589 while(*code && (*code > 32)) { /* Search white space */ 22590 code++; 22591 } 22592 *code++ = '\0'; 22593 code = ast_skip_blanks(code); 22594 sep = code; 22595 sep++; 22596 while(*sep && (*sep > 32)) { /* Search white space */ 22597 sep++; 22598 } 22599 *sep++ = '\0'; /* Response string */ 22600 respcode = atoi(code); 22601 switch (respcode) { 22602 case 200: /* OK: The new call is up, hangup this call */ 22603 /* Hangup the call that we are replacing */ 22604 break; 22605 case 301: /* Moved permenantly */ 22606 case 302: /* Moved temporarily */ 22607 /* Do we get the header in the packet in this case? */ 22608 success = FALSE; 22609 break; 22610 case 503: /* Service Unavailable: The new call failed */ 22611 case 603: /* Declined: Not accepted */ 22612 /* Cancel transfer, continue the current call */ 22613 success = FALSE; 22614 break; 22615 case 0: /* Parse error */ 22616 /* Cancel transfer, continue the current call */ 22617 ast_log(LOG_NOTICE, "Error parsing sipfrag in NOTIFY in response to REFER.\n"); 22618 success = FALSE; 22619 break; 22620 default: 22621 if (respcode < 200) { 22622 /* ignore provisional responses */ 22623 success = -1; 22624 } else { 22625 ast_log(LOG_NOTICE, "Got unknown code '%d' in NOTIFY in response to REFER.\n", respcode); 22626 success = FALSE; 22627 } 22628 break; 22629 } 22630 if (success == FALSE) { 22631 ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n"); 22632 } 22633 22634 if (p->owner && success != -1) { 22635 enum ast_control_transfer message = success ? AST_TRANSFER_SUCCESS : AST_TRANSFER_FAILED; 22636 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 22637 } 22638 /* Confirm that we received this packet */ 22639 transmit_response(p, "200 OK", req); 22640 } else if (!strcmp(event, "message-summary")) { 22641 const char *mailbox = NULL; 22642 char *c = ast_strdupa(get_body(req, "Voice-Message", ':')); 22643 22644 if (!p->mwi) { 22645 struct sip_peer *peer = find_peer(NULL, &p->recv, TRUE, FINDPEERS, FALSE, p->socket.type); 22646 22647 if (peer) { 22648 mailbox = ast_strdupa(peer->unsolicited_mailbox); 22649 unref_peer(peer, "removing unsolicited mwi ref"); 22650 } 22651 } else { 22652 mailbox = p->mwi->mailbox; 22653 } 22654 22655 if (!ast_strlen_zero(mailbox) && !ast_strlen_zero(c)) { 22656 char *old = strsep(&c, " "); 22657 char *new = strsep(&old, "/"); 22658 struct ast_event *event; 22659 22660 if ((event = ast_event_new(AST_EVENT_MWI, 22661 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 22662 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, "SIP_Remote", 22663 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, atoi(new), 22664 AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, atoi(old), 22665 AST_EVENT_IE_END))) { 22666 ast_event_queue_and_cache(event); 22667 } 22668 transmit_response(p, "200 OK", req); 22669 } else { 22670 transmit_response(p, "489 Bad event", req); 22671 res = -1; 22672 } 22673 } else if (!strcmp(event, "keep-alive")) { 22674 /* Used by Sipura/Linksys for NAT pinhole, 22675 * just confirm that we received the packet. */ 22676 transmit_response(p, "200 OK", req); 22677 } else if (!strcmp(event, "call-completion")) { 22678 res = handle_cc_notify(p, req); 22679 } else { 22680 /* We don't understand this event. */ 22681 transmit_response(p, "489 Bad event", req); 22682 res = -1; 22683 } 22684 22685 if (!p->lastinvite) 22686 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22687 22688 return res; 22689 }
| static int handle_request_options | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| struct ast_sockaddr * | addr, | |||
| const char * | e | |||
| ) | [static] |
Handle incoming OPTIONS request An OPTIONS request should be answered like an INVITE from the same UA, including SDP.
Definition at line 22694 of file chan_sip.c.
References ast_log(), ast_shutting_down(), ast_string_field_set, ast_strlen_zero(), build_contact(), check_user(), context, copy_request(), get_destination(), get_header(), LOG_NOTICE, set_pvt_allowed_methods(), sip_cfg, sip_scheddestroy(), transmit_response(), and transmit_response_with_allow().
Referenced by handle_incoming().
22695 { 22696 const char *msg; 22697 enum sip_get_dest_result gotdest; 22698 int res; 22699 22700 if (p->lastinvite) { 22701 /* if this is a request in an active dialog, just confirm that the dialog exists. */ 22702 transmit_response_with_allow(p, "200 OK", req, 0); 22703 return 0; 22704 } 22705 22706 if (sip_cfg.auth_options_requests) { 22707 /* Do authentication if this OPTIONS request began the dialog */ 22708 copy_request(&p->initreq, req); 22709 set_pvt_allowed_methods(p, req); 22710 res = check_user(p, req, SIP_OPTIONS, e, XMIT_UNRELIABLE, addr); 22711 if (res == AUTH_CHALLENGE_SENT) { 22712 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22713 return 0; 22714 } 22715 if (res < 0) { /* Something failed in authentication */ 22716 ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From")); 22717 transmit_response(p, "403 Forbidden", req); 22718 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22719 return 0; 22720 } 22721 } 22722 22723 /* must go through authentication before getting here */ 22724 gotdest = get_destination(p, req, NULL); 22725 build_contact(p); 22726 22727 if (ast_strlen_zero(p->context)) 22728 ast_string_field_set(p, context, sip_cfg.default_context); 22729 22730 if (ast_shutting_down()) { 22731 msg = "503 Unavailable"; 22732 } else { 22733 msg = "404 Not Found"; 22734 switch (gotdest) { 22735 case SIP_GET_DEST_INVALID_URI: 22736 msg = "416 Unsupported URI scheme"; 22737 break; 22738 case SIP_GET_DEST_EXTEN_MATCHMORE: 22739 case SIP_GET_DEST_REFUSED: 22740 case SIP_GET_DEST_EXTEN_NOT_FOUND: 22741 //msg = "404 Not Found"; 22742 break; 22743 case SIP_GET_DEST_EXTEN_FOUND: 22744 msg = "200 OK"; 22745 break; 22746 } 22747 } 22748 transmit_response_with_allow(p, msg, req, 0); 22749 22750 /* Destroy if this OPTIONS was the opening request, but not if 22751 it's in the middle of a normal call flow. */ 22752 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22753 22754 return 0; 22755 }
| static int handle_request_publish | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| struct ast_sockaddr * | addr, | |||
| const uint32_t | seqno, | |||
| const char * | uri | |||
| ) | [static] |
Definition at line 25206 of file chan_sip.c.
References __sip_ack(), ast_log(), ast_string_field_set, ast_strlen_zero(), check_user(), determine_sip_publish_type(), get_esc(), get_header(), handle_sip_publish_initial(), handle_sip_publish_modify(), handle_sip_publish_refresh(), handle_sip_publish_remove(), LOG_NOTICE, pvt_set_needdestroy(), sip_scheddestroy(), transmit_response(), and transmit_response_with_minexpires().
Referenced by handle_incoming().
25207 { 25208 const char *etag = get_header(req, "SIP-If-Match"); 25209 const char *event = get_header(req, "Event"); 25210 struct event_state_compositor *esc; 25211 enum sip_publish_type publish_type; 25212 const char *expires_str = get_header(req, "Expires"); 25213 int expires_int; 25214 int auth_result; 25215 int handler_result = -1; 25216 25217 if (ast_strlen_zero(event)) { 25218 transmit_response(p, "489 Bad Event", req); 25219 pvt_set_needdestroy(p, "missing Event: header"); 25220 return -1; 25221 } 25222 25223 if (!(esc = get_esc(event))) { 25224 transmit_response(p, "489 Bad Event", req); 25225 pvt_set_needdestroy(p, "unknown event package in publish"); 25226 return -1; 25227 } 25228 25229 auth_result = check_user(p, req, SIP_PUBLISH, uri, XMIT_UNRELIABLE, addr); 25230 if (auth_result == AUTH_CHALLENGE_SENT) { 25231 p->lastinvite = seqno; 25232 return 0; 25233 } else if (auth_result < 0) { 25234 ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From")); 25235 transmit_response(p, "403 Forbidden", req); 25236 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 25237 ast_string_field_set(p, theirtag, NULL); 25238 return 0; 25239 } else if (auth_result == AUTH_SUCCESSFUL && p->lastinvite) { 25240 /* We need to stop retransmitting the 401 */ 25241 __sip_ack(p, p->lastinvite, 1, 0); 25242 } 25243 25244 publish_type = determine_sip_publish_type(req, event, etag, expires_str, &expires_int); 25245 25246 if (expires_int > max_expiry) { 25247 expires_int = max_expiry; 25248 } else if (expires_int < min_expiry && expires_int > 0) { 25249 transmit_response_with_minexpires(p, "423 Interval too small", req); 25250 pvt_set_needdestroy(p, "Expires is less that the min expires allowed."); 25251 return 0; 25252 } 25253 p->expiry = expires_int; 25254 25255 /* It is the responsibility of these handlers to formulate any response 25256 * sent for a PUBLISH 25257 */ 25258 switch (publish_type) { 25259 case SIP_PUBLISH_UNKNOWN: 25260 transmit_response(p, "400 Bad Request", req); 25261 break; 25262 case SIP_PUBLISH_INITIAL: 25263 handler_result = handle_sip_publish_initial(p, req, esc, expires_int); 25264 break; 25265 case SIP_PUBLISH_REFRESH: 25266 handler_result = handle_sip_publish_refresh(p, req, esc, etag, expires_int); 25267 break; 25268 case SIP_PUBLISH_MODIFY: 25269 handler_result = handle_sip_publish_modify(p, req, esc, etag, expires_int); 25270 break; 25271 case SIP_PUBLISH_REMOVE: 25272 handler_result = handle_sip_publish_remove(p, req, esc, etag); 25273 break; 25274 default: 25275 transmit_response(p, "400 Impossible Condition", req); 25276 break; 25277 } 25278 if (!handler_result && p->expiry > 0) { 25279 sip_scheddestroy(p, (p->expiry + 10) * 1000); 25280 } else { 25281 pvt_set_needdestroy(p, "forcing expiration"); 25282 } 25283 25284 return handler_result; 25285 }
| static int handle_request_refer | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| int | debug, | |||
| uint32_t | seqno, | |||
| int * | nounlock | |||
| ) | [static] |
Chan1: Call between asterisk and transferer Chan2: Call between asterisk and transferee
Definition at line 24158 of file chan_sip.c.
References append_history, ast_async_goto(), ast_bridged_channel(), AST_CAUSE_NORMAL_CLEARING, AST_CEL_ATTENDEDTRANSFER, AST_CEL_BLINDTRANSFER, ast_cel_report_event(), ast_channel_lock, ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_clear_flag, AST_CONTROL_UNHOLD, ast_debug, ast_indicate(), AST_LIST_EMPTY, ast_manager_event_multichan, ast_parking_ext_valid(), ast_queue_control(), ast_set_flag, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose, check_sip_domain(), context, EVENT_FLAG_CALL, FALSE, get_refer_info(), local_attended_transfer(), pbx_builtin_setvar_helper(), pvt_set_needdestroy(), sip_alreadygone(), sip_cfg, sip_park(), sip_pvt_lock, sip_pvt_unlock, sip_refer_allocate(), transmit_notify_with_sipfrag(), transmit_response(), and TRUE.
Referenced by handle_incoming().
24159 { 24160 /*! 24161 * Chan1: Call between asterisk and transferer 24162 * Chan2: Call between asterisk and transferee 24163 */ 24164 struct sip_dual current = { 0, }; 24165 struct ast_channel *chans[2] = { 0, }; 24166 char *refer_to = NULL; 24167 char *refer_to_domain = NULL; 24168 char *refer_to_context = NULL; 24169 char *referred_by = NULL; 24170 char *callid = NULL; 24171 int localtransfer = 0; 24172 int attendedtransfer = 0; 24173 int res = 0; 24174 24175 if (req->debug) { 24176 ast_verbose("Call %s got a SIP call transfer from %s: (REFER)!\n", 24177 p->callid, 24178 ast_test_flag(&p->flags[0], SIP_OUTGOING) ? "callee" : "caller"); 24179 } 24180 24181 if (!p->owner) { 24182 /* This is a REFER outside of an existing SIP dialog */ 24183 /* We can't handle that, so decline it */ 24184 ast_debug(3, "Call %s: Declined REFER, outside of dialog...\n", p->callid); 24185 transmit_response(p, "603 Declined (No dialog)", req); 24186 if (!req->ignore) { 24187 append_history(p, "Xfer", "Refer failed. Outside of dialog."); 24188 sip_alreadygone(p); 24189 pvt_set_needdestroy(p, "outside of dialog"); 24190 } 24191 res = 0; 24192 goto handle_refer_cleanup; 24193 } 24194 24195 /* Check if transfer is allowed from this device */ 24196 if (p->allowtransfer == TRANSFER_CLOSED ) { 24197 /* Transfer not allowed, decline */ 24198 transmit_response(p, "603 Declined (policy)", req); 24199 append_history(p, "Xfer", "Refer failed. Allowtransfer == closed."); 24200 /* Do not destroy SIP session */ 24201 res = 0; 24202 goto handle_refer_cleanup; 24203 } 24204 24205 if (!req->ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 24206 /* Already have a pending REFER */ 24207 transmit_response(p, "491 Request pending", req); 24208 append_history(p, "Xfer", "Refer failed. Request pending."); 24209 res = 0; 24210 goto handle_refer_cleanup; 24211 } 24212 24213 /* Allocate memory for call transfer data */ 24214 if (!p->refer && !sip_refer_allocate(p)) { 24215 transmit_response(p, "500 Internal Server Error", req); 24216 append_history(p, "Xfer", "Refer failed. Memory allocation error."); 24217 res = -3; 24218 goto handle_refer_cleanup; 24219 } 24220 24221 res = get_refer_info(p, req); /* Extract headers */ 24222 24223 p->refer->status = REFER_SENT; 24224 24225 if (res != 0) { 24226 switch (res) { 24227 case -2: /* Syntax error */ 24228 transmit_response(p, "400 Bad Request (Refer-to missing)", req); 24229 append_history(p, "Xfer", "Refer failed. Refer-to missing."); 24230 if (req->debug) { 24231 ast_debug(1, "SIP transfer to black hole can't be handled (no refer-to: )\n"); 24232 } 24233 break; 24234 case -3: 24235 transmit_response(p, "603 Declined (Non sip: uri)", req); 24236 append_history(p, "Xfer", "Refer failed. Non SIP uri"); 24237 if (req->debug) { 24238 ast_debug(1, "SIP transfer to non-SIP uri denied\n"); 24239 } 24240 break; 24241 default: 24242 /* Refer-to extension not found, fake a failed transfer */ 24243 transmit_response(p, "202 Accepted", req); 24244 append_history(p, "Xfer", "Refer failed. Bad extension."); 24245 transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE); 24246 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 24247 if (req->debug) { 24248 ast_debug(1, "SIP transfer to bad extension: %s\n", p->refer->refer_to); 24249 } 24250 break; 24251 } 24252 res = 0; 24253 goto handle_refer_cleanup; 24254 } 24255 if (ast_strlen_zero(p->context)) { 24256 ast_string_field_set(p, context, sip_cfg.default_context); 24257 } 24258 24259 /* If we do not support SIP domains, all transfers are local */ 24260 if (sip_cfg.allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 24261 p->refer->localtransfer = 1; 24262 if (sipdebug) { 24263 ast_debug(3, "This SIP transfer is local : %s\n", p->refer->refer_to_domain); 24264 } 24265 } else if (AST_LIST_EMPTY(&domain_list) || check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 24266 /* This PBX doesn't bother with SIP domains or domain is local, so this transfer is local */ 24267 p->refer->localtransfer = 1; 24268 } else if (sipdebug) { 24269 ast_debug(3, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain); 24270 } 24271 24272 /* Is this a repeat of a current request? Ignore it */ 24273 /* Don't know what else to do right now. */ 24274 if (req->ignore) { 24275 goto handle_refer_cleanup; 24276 } 24277 24278 /* If this is a blind transfer, we have the following 24279 channels to work with: 24280 - chan1, chan2: The current call between transferer and transferee (2 channels) 24281 - target_channel: A new call from the transferee to the target (1 channel) 24282 We need to stay tuned to what happens in order to be able 24283 to bring back the call to the transferer */ 24284 24285 /* If this is a attended transfer, we should have all call legs within reach: 24286 - chan1, chan2: The call between the transferer and transferee (2 channels) 24287 - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels) 24288 We want to bridge chan2 with targetcall_pvt! 24289 24290 The replaces call id in the refer message points 24291 to the call leg between Asterisk and the transferer. 24292 So we need to connect the target and the transferee channel 24293 and hangup the two other channels silently 24294 24295 If the target is non-local, the call ID could be on a remote 24296 machine and we need to send an INVITE with replaces to the 24297 target. We basically handle this as a blind transfer 24298 and let the sip_call function catch that we need replaces 24299 header in the INVITE. 24300 */ 24301 24302 /* Get the transferer's channel */ 24303 chans[0] = current.chan1 = p->owner; 24304 24305 /* Find the other part of the bridge (2) - transferee */ 24306 chans[1] = current.chan2 = ast_bridged_channel(current.chan1); 24307 24308 ast_channel_ref(current.chan1); 24309 if (current.chan2) { 24310 ast_channel_ref(current.chan2); 24311 } 24312 24313 if (sipdebug) { 24314 ast_debug(3, "SIP %s transfer: Transferer channel %s, transferee channel %s\n", 24315 p->refer->attendedtransfer ? "attended" : "blind", 24316 current.chan1->name, 24317 current.chan2 ? current.chan2->name : "<none>"); 24318 } 24319 24320 if (!current.chan2 && !p->refer->attendedtransfer) { 24321 /* No bridged channel, propably IVR or echo or similar... */ 24322 /* Guess we should masquerade or something here */ 24323 /* Until we figure it out, refuse transfer of such calls */ 24324 if (sipdebug) { 24325 ast_debug(3, "Refused SIP transfer on non-bridged channel.\n"); 24326 } 24327 p->refer->status = REFER_FAILED; 24328 append_history(p, "Xfer", "Refer failed. Non-bridged channel."); 24329 transmit_response(p, "603 Declined", req); 24330 res = -1; 24331 goto handle_refer_cleanup; 24332 } 24333 24334 if (current.chan2) { 24335 if (sipdebug) { 24336 ast_debug(4, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name); 24337 } 24338 ast_queue_control(current.chan1, AST_CONTROL_UNHOLD); 24339 } 24340 24341 ast_set_flag(&p->flags[0], SIP_GOTREFER); 24342 24343 /* From here on failures will be indicated with NOTIFY requests */ 24344 transmit_response(p, "202 Accepted", req); 24345 24346 /* Attended transfer: Find all call legs and bridge transferee with target*/ 24347 if (p->refer->attendedtransfer) { 24348 /* both p and p->owner _MUST_ be locked while calling local_attended_transfer */ 24349 if ((res = local_attended_transfer(p, ¤t, req, seqno, nounlock))) { 24350 goto handle_refer_cleanup; /* We're done with the transfer */ 24351 } 24352 /* Fall through for remote transfers that we did not find locally */ 24353 if (sipdebug) { 24354 ast_debug(4, "SIP attended transfer: Still not our call - generating INVITE with replaces\n"); 24355 } 24356 /* Fallthrough if we can't find the call leg internally */ 24357 } 24358 24359 /* Copy data we can not safely access after letting the pvt lock go. */ 24360 refer_to = ast_strdupa(p->refer->refer_to); 24361 refer_to_domain = ast_strdupa(p->refer->refer_to_domain); 24362 refer_to_context = ast_strdupa(p->refer->refer_to_context); 24363 referred_by = ast_strdupa(p->refer->referred_by); 24364 callid = ast_strdupa(p->callid); 24365 localtransfer = p->refer->localtransfer; 24366 attendedtransfer = p->refer->attendedtransfer; 24367 24368 if (!*nounlock) { 24369 ast_channel_unlock(p->owner); 24370 *nounlock = 1; 24371 } 24372 sip_pvt_unlock(p); 24373 24374 /* Parking a call. DO NOT hold any locks while calling ast_parking_ext_valid() */ 24375 if (localtransfer && ast_parking_ext_valid(refer_to, current.chan1, refer_to_context)) { 24376 sip_pvt_lock(p); 24377 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 24378 p->refer->status = REFER_200OK; 24379 append_history(p, "Xfer", "REFER to call parking."); 24380 sip_pvt_unlock(p); 24381 24382 ast_manager_event_multichan(EVENT_FLAG_CALL, "Transfer", 2, chans, 24383 "TransferMethod: SIP\r\n" 24384 "TransferType: Blind\r\n" 24385 "Channel: %s\r\n" 24386 "Uniqueid: %s\r\n" 24387 "SIP-Callid: %s\r\n" 24388 "TargetChannel: %s\r\n" 24389 "TargetUniqueid: %s\r\n" 24390 "TransferExten: %s\r\n" 24391 "Transfer2Parking: Yes\r\n", 24392 current.chan1->name, 24393 current.chan1->uniqueid, 24394 callid, 24395 current.chan2->name, 24396 current.chan2->uniqueid, 24397 refer_to); 24398 24399 if (sipdebug) { 24400 ast_debug(4, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name); 24401 } 24402 24403 /* DO NOT hold any locks while calling sip_park */ 24404 if (sip_park(current.chan2, current.chan1, req, seqno, refer_to, refer_to_context)) { 24405 sip_pvt_lock(p); 24406 transmit_notify_with_sipfrag(p, seqno, "500 Internal Server Error", TRUE); 24407 } else { 24408 sip_pvt_lock(p); 24409 } 24410 goto handle_refer_cleanup; 24411 } 24412 24413 /* Blind transfers and remote attended xfers. 24414 * Locks should not be held while calling pbx_builtin_setvar_helper. This function 24415 * locks the channel being passed into it.*/ 24416 if (current.chan1 && current.chan2) { 24417 ast_debug(3, "chan1->name: %s\n", current.chan1->name); 24418 pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name); 24419 } 24420 24421 if (current.chan2) { 24422 pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name); 24423 pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", refer_to_domain); 24424 pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes"); 24425 /* One for the new channel */ 24426 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes"); 24427 /* Attended transfer to remote host, prepare headers for the INVITE */ 24428 if (!ast_strlen_zero(referred_by)) { 24429 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", referred_by); 24430 } 24431 } 24432 24433 sip_pvt_lock(p); 24434 /* Generate a Replaces string to be used in the INVITE during attended transfer */ 24435 if (!ast_strlen_zero(p->refer->replaces_callid)) { 24436 char tempheader[SIPBUFSIZE]; 24437 snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid, 24438 p->refer->replaces_callid_totag ? ";to-tag=" : "", 24439 p->refer->replaces_callid_totag, 24440 p->refer->replaces_callid_fromtag ? ";from-tag=" : "", 24441 p->refer->replaces_callid_fromtag); 24442 24443 if (current.chan2) { 24444 sip_pvt_unlock(p); 24445 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader); 24446 sip_pvt_lock(p); 24447 } 24448 } 24449 24450 /* Connect the call */ 24451 24452 /* FAKE ringing if not attended transfer */ 24453 if (!p->refer->attendedtransfer) { 24454 transmit_notify_with_sipfrag(p, seqno, "180 Ringing", FALSE); 24455 } 24456 24457 /* For blind transfer, this will lead to a new call */ 24458 /* For attended transfer to remote host, this will lead to 24459 a new SIP call with a replaces header, if the dial plan allows it 24460 */ 24461 if (!current.chan2) { 24462 /* We have no bridge, so we're talking with Asterisk somehow */ 24463 /* We need to masquerade this call */ 24464 /* What to do to fix this situation: 24465 * Set up the new call in a new channel 24466 * Let the new channel masq into this channel 24467 Please add that code here :-) 24468 */ 24469 p->refer->status = REFER_FAILED; 24470 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE); 24471 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 24472 append_history(p, "Xfer", "Refer failed (only bridged calls)."); 24473 res = -1; 24474 goto handle_refer_cleanup; 24475 } 24476 ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 24477 24478 /* Do not hold the pvt lock during the indicate and async_goto. Those functions 24479 * lock channels which will invalidate locking order if the pvt lock is held.*/ 24480 /* For blind transfers, move the call to the new extensions. For attended transfers on multiple 24481 * servers - generate an INVITE with Replaces. Either way, let the dial plan decided 24482 * indicate before masquerade so the indication actually makes it to the real channel 24483 * when using local channels with MOH passthru */ 24484 sip_pvt_unlock(p); 24485 ast_indicate(current.chan2, AST_CONTROL_UNHOLD); 24486 res = ast_async_goto(current.chan2, refer_to_context, refer_to, 1); 24487 24488 if (!res) { 24489 ast_manager_event_multichan(EVENT_FLAG_CALL, "Transfer", 2, chans, 24490 "TransferMethod: SIP\r\n" 24491 "TransferType: Blind\r\n" 24492 "Channel: %s\r\n" 24493 "Uniqueid: %s\r\n" 24494 "SIP-Callid: %s\r\n" 24495 "TargetChannel: %s\r\n" 24496 "TargetUniqueid: %s\r\n" 24497 "TransferExten: %s\r\n" 24498 "TransferContext: %s\r\n", 24499 current.chan1->name, 24500 current.chan1->uniqueid, 24501 callid, 24502 current.chan2->name, 24503 current.chan2->uniqueid, 24504 refer_to, 24505 refer_to_context); 24506 /* Success - we have a new channel */ 24507 ast_debug(3, "%s transfer succeeded. Telling transferer.\n", attendedtransfer? "Attended" : "Blind"); 24508 24509 /* XXX - what to we put in CEL 'extra' for attended transfers to external systems? NULL for now */ 24510 ast_channel_lock(current.chan1); 24511 ast_cel_report_event(current.chan1, p->refer->attendedtransfer? AST_CEL_ATTENDEDTRANSFER : AST_CEL_BLINDTRANSFER, NULL, p->refer->attendedtransfer ? NULL : p->refer->refer_to, current.chan2); 24512 ast_channel_unlock(current.chan1); 24513 24514 sip_pvt_lock(p); 24515 transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE); 24516 if (p->refer->localtransfer) { 24517 p->refer->status = REFER_200OK; 24518 } 24519 if (p->owner) { 24520 p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING; 24521 } 24522 append_history(p, "Xfer", "Refer succeeded."); 24523 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 24524 /* Do not hangup call, the other side do that when we say 200 OK */ 24525 /* We could possibly implement a timer here, auto congestion */ 24526 res = 0; 24527 } else { 24528 sip_pvt_lock(p); 24529 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */ 24530 ast_debug(3, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 24531 append_history(p, "Xfer", "Refer failed."); 24532 /* Failure of some kind */ 24533 p->refer->status = REFER_FAILED; 24534 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE); 24535 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 24536 res = -1; 24537 } 24538 24539 handle_refer_cleanup: 24540 if (current.chan1) { 24541 ast_channel_unref(current.chan1); 24542 } 24543 if (current.chan2) { 24544 ast_channel_unref(current.chan2); 24545 } 24546 24547 /* Make sure we exit with the pvt locked */ 24548 return res; 24549 }
| static int handle_request_register | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| struct ast_sockaddr * | sin, | |||
| const char * | e | |||
| ) | [static] |
Handle incoming REGISTER request.
Definition at line 25752 of file chan_sip.c.
References append_history, ast_debug, ast_log(), ast_sockaddr_stringify(), check_via(), copy_request(), get_header(), LOG_NOTICE, LOG_WARNING, register_verify(), sip_methods, sip_scheddestroy(), and cfsip_methods::text.
Referenced by handle_incoming().
25753 { 25754 enum check_auth_result res; 25755 25756 /* If this is not the intial request, and the initial request isn't 25757 * a register, something screwy happened, so bail */ 25758 if (p->initreq.headers && p->initreq.method != SIP_REGISTER) { 25759 ast_log(LOG_WARNING, "Ignoring spurious REGISTER with Call-ID: %s\n", p->callid); 25760 return -1; 25761 } 25762 25763 /* Use this as the basis */ 25764 copy_request(&p->initreq, req); 25765 if (sipdebug) 25766 ast_debug(4, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid); 25767 check_via(p, req); 25768 if ((res = register_verify(p, addr, req, e)) < 0) { 25769 const char *reason; 25770 25771 switch (res) { 25772 case AUTH_SECRET_FAILED: 25773 reason = "Wrong password"; 25774 break; 25775 case AUTH_USERNAME_MISMATCH: 25776 reason = "Username/auth name mismatch"; 25777 break; 25778 case AUTH_NOT_FOUND: 25779 reason = "No matching peer found"; 25780 break; 25781 case AUTH_UNKNOWN_DOMAIN: 25782 reason = "Not a local domain"; 25783 break; 25784 case AUTH_PEER_NOT_DYNAMIC: 25785 reason = "Peer is not supposed to register"; 25786 break; 25787 case AUTH_ACL_FAILED: 25788 reason = "Device does not match ACL"; 25789 break; 25790 case AUTH_BAD_TRANSPORT: 25791 reason = "Device not configured to use this transport type"; 25792 break; 25793 default: 25794 reason = "Unknown failure"; 25795 break; 25796 } 25797 ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n", 25798 get_header(req, "To"), ast_sockaddr_stringify(addr), 25799 reason); 25800 append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason); 25801 } else { 25802 req->authenticated = 1; 25803 append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To")); 25804 } 25805 25806 if (res < 1) { 25807 /* Destroy the session, but keep us around for just a bit in case they don't 25808 get our 200 OK */ 25809 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 25810 } 25811 return res; 25812 }
| static int handle_request_subscribe | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| struct ast_sockaddr * | addr, | |||
| uint32_t | seqno, | |||
| const char * | e | |||
| ) | [static] |
Handle incoming SUBSCRIBE request.
Definition at line 25368 of file chan_sip.c.
References __get_header(), add_peer_mwi_subs(), ao2_lock, ao2_unlock, append_history, ast_debug, ast_extension_state(), ast_extension_state2str(), ast_extension_state_add_destroy(), ast_extension_state_del(), AST_LIST_EMPTY, ast_log(), ast_set_flag, ast_sockaddr_stringify(), ast_string_field_build, ast_strlen_zero(), ast_test_flag, ast_verbose, build_contact(), build_route(), cb_extensionstate(), cb_extensionstate_destroy(), check_user_full(), check_via(), copy_request(), dialog_unlink_all(), FALSE, get_destination(), get_header(), gettag(), handle_cc_subscribe(), LOG_DEBUG, LOG_NOTICE, LOG_WARNING, make_our_tag(), MAX, NONE, option_debug, parse_ok_contact(), pvt_set_needdestroy(), ref_peer(), S_OR, set_pvt_allowed_methods(), sip_cancel_destroy(), sip_cfg, sip_methods, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), sip_send_mwi_to_peer(), cfsip_methods::text, transmit_response(), transmit_response_with_minexpires(), transmit_state_notify(), and unref_peer().
Referenced by handle_incoming().
25369 { 25370 int gotdest = 0; 25371 int res = 0; 25372 int firststate; 25373 struct sip_peer *authpeer = NULL; 25374 const char *eventheader = get_header(req, "Event"); /* Get Event package name */ 25375 int resubscribe = (p->subscribed != NONE) && !req->ignore; 25376 char *event_end; 25377 ptrdiff_t event_len = 0; 25378 25379 if (p->initreq.headers) { 25380 /* We already have a dialog */ 25381 if (p->initreq.method != SIP_SUBSCRIBE) { 25382 /* This is a SUBSCRIBE within another SIP dialog, which we do not support */ 25383 /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */ 25384 transmit_response(p, "403 Forbidden (within dialog)", req); 25385 /* Do not destroy session, since we will break the call if we do */ 25386 ast_debug(1, "Got a subscription within the context of another call, can't handle that - %s (Method %s)\n", p->callid, sip_methods[p->initreq.method].text); 25387 return 0; 25388 } else if (req->debug) { 25389 if (resubscribe) 25390 ast_debug(1, "Got a re-subscribe on existing subscription %s\n", p->callid); 25391 else 25392 ast_debug(1, "Got a new subscription %s (possibly with auth) or retransmission\n", p->callid); 25393 } 25394 } 25395 25396 /* Check if we have a global disallow setting on subscriptions. 25397 if so, we don't have to check peer settings after auth, which saves a lot of processing 25398 */ 25399 if (!sip_cfg.allowsubscribe) { 25400 transmit_response(p, "403 Forbidden (policy)", req); 25401 pvt_set_needdestroy(p, "forbidden"); 25402 return 0; 25403 } 25404 25405 if (!req->ignore && !resubscribe) { /* Set up dialog, new subscription */ 25406 const char *to = get_header(req, "To"); 25407 char totag[128]; 25408 set_pvt_allowed_methods(p, req); 25409 25410 /* Check to see if a tag was provided, if so this is actually a resubscription of a dialog we no longer know about */ 25411 if (!ast_strlen_zero(to) && gettag(req, "To", totag, sizeof(totag))) { 25412 if (req->debug) 25413 ast_verbose("Received resubscription for a dialog we no longer know about. Telling remote side to subscribe again.\n"); 25414 transmit_response(p, "481 Subscription does not exist", req); 25415 pvt_set_needdestroy(p, "subscription does not exist"); 25416 return 0; 25417 } 25418 25419 /* Use this as the basis */ 25420 if (req->debug) 25421 ast_verbose("Creating new subscription\n"); 25422 25423 copy_request(&p->initreq, req); 25424 if (sipdebug) 25425 ast_debug(4, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid); 25426 check_via(p, req); 25427 build_route(p, req, 0, 0); 25428 } else if (req->debug && req->ignore) 25429 ast_verbose("Ignoring this SUBSCRIBE request\n"); 25430 25431 /* Find parameters to Event: header value and remove them for now */ 25432 if (ast_strlen_zero(eventheader)) { 25433 transmit_response(p, "489 Bad Event", req); 25434 ast_debug(2, "Received SIP subscribe for unknown event package: <none>\n"); 25435 pvt_set_needdestroy(p, "unknown event package in subscribe"); 25436 return 0; 25437 } 25438 25439 event_end = strchr(eventheader, ';'); 25440 if (event_end) { 25441 event_len = event_end - eventheader; 25442 } 25443 25444 /* Handle authentication if we're new and not a retransmission. We can't just 25445 * use if !req->ignore, because then we'll end up sending 25446 * a 200 OK if someone retransmits without sending auth */ 25447 if (p->subscribed == NONE || resubscribe) { 25448 res = check_user_full(p, req, SIP_SUBSCRIBE, e, XMIT_UNRELIABLE, addr, &authpeer); 25449 25450 /* if an authentication response was sent, we are done here */ 25451 if (res == AUTH_CHALLENGE_SENT) /* authpeer = NULL here */ 25452 return 0; 25453 if (res != AUTH_SUCCESSFUL) { 25454 ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From")); 25455 transmit_response(p, "403 Forbidden", req); 25456 25457 pvt_set_needdestroy(p, "authentication failed"); 25458 return 0; 25459 } 25460 } 25461 25462 /* At this point, we hold a reference to authpeer (if not NULL). It 25463 * must be released when done. 25464 */ 25465 25466 /* Check if this device is allowed to subscribe at all */ 25467 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) { 25468 transmit_response(p, "403 Forbidden (policy)", req); 25469 pvt_set_needdestroy(p, "subscription not allowed"); 25470 if (authpeer) { 25471 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 1)"); 25472 } 25473 return 0; 25474 } 25475 25476 if (strncmp(eventheader, "message-summary", MAX(event_len, 15)) && strncmp(eventheader, "call-completion", MAX(event_len, 15))) { 25477 /* Get destination right away */ 25478 gotdest = get_destination(p, NULL, NULL); 25479 } 25480 25481 /* Get full contact header - this needs to be used as a request URI in NOTIFY's */ 25482 parse_ok_contact(p, req); 25483 25484 build_contact(p); 25485 if (gotdest != SIP_GET_DEST_EXTEN_FOUND) { 25486 if (gotdest == SIP_GET_DEST_INVALID_URI) { 25487 transmit_response(p, "416 Unsupported URI scheme", req); 25488 } else { 25489 transmit_response(p, "404 Not Found", req); 25490 } 25491 pvt_set_needdestroy(p, "subscription target not found"); 25492 if (authpeer) { 25493 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 2)"); 25494 } 25495 return 0; 25496 } 25497 25498 /* Initialize tag for new subscriptions */ 25499 if (ast_strlen_zero(p->tag)) 25500 make_our_tag(p); 25501 25502 if (!strncmp(eventheader, "presence", MAX(event_len, 8)) || !strncmp(eventheader, "dialog", MAX(event_len, 6))) { /* Presence, RFC 3842 */ 25503 unsigned int pidf_xml; 25504 const char *accept; 25505 int start = 0; 25506 enum subscriptiontype subscribed = NONE; 25507 const char *unknown_acceptheader = NULL; 25508 25509 /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */ 25510 accept = __get_header(req, "Accept", &start); 25511 while ((subscribed == NONE) && !ast_strlen_zero(accept)) { 25512 pidf_xml = strstr(accept, "application/pidf+xml") ? 1 : 0; 25513 25514 /* Older versions of Polycom firmware will claim pidf+xml, but really 25515 * they only support xpidf+xml. */ 25516 if (pidf_xml && strstr(p->useragent, "Polycom")) { 25517 subscribed = XPIDF_XML; 25518 } else if (pidf_xml) { 25519 subscribed = PIDF_XML; /* RFC 3863 format */ 25520 } else if (strstr(accept, "application/dialog-info+xml")) { 25521 subscribed = DIALOG_INFO_XML; 25522 /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */ 25523 } else if (strstr(accept, "application/cpim-pidf+xml")) { 25524 subscribed = CPIM_PIDF_XML; /* RFC 3863 format */ 25525 } else if (strstr(accept, "application/xpidf+xml")) { 25526 subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */ 25527 } else { 25528 unknown_acceptheader = accept; 25529 } 25530 /* check to see if there is another Accept header present */ 25531 accept = __get_header(req, "Accept", &start); 25532 } 25533 25534 if (!start) { 25535 if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */ 25536 transmit_response(p, "489 Bad Event", req); 25537 ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: " 25538 "stateid: %d, laststate: %d, dialogver: %u, subscribecont: " 25539 "'%s', subscribeuri: '%s'\n", 25540 p->stateid, 25541 p->laststate, 25542 p->dialogver, 25543 p->subscribecontext, 25544 p->subscribeuri); 25545 pvt_set_needdestroy(p, "no Accept header"); 25546 if (authpeer) { 25547 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 2)"); 25548 } 25549 return 0; 25550 } 25551 /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least. 25552 so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */ 25553 } else if (subscribed == NONE) { 25554 /* Can't find a format for events that we know about */ 25555 char mybuf[200]; 25556 if (!ast_strlen_zero(unknown_acceptheader)) { 25557 snprintf(mybuf, sizeof(mybuf), "489 Bad Event (format %s)", unknown_acceptheader); 25558 } else { 25559 snprintf(mybuf, sizeof(mybuf), "489 Bad Event"); 25560 } 25561 transmit_response(p, mybuf, req); 25562 ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format:" 25563 "'%s' pvt: subscribed: %d, stateid: %d, laststate: %d," 25564 "dialogver: %u, subscribecont: '%s', subscribeuri: '%s'\n", 25565 unknown_acceptheader, 25566 (int)p->subscribed, 25567 p->stateid, 25568 p->laststate, 25569 p->dialogver, 25570 p->subscribecontext, 25571 p->subscribeuri); 25572 pvt_set_needdestroy(p, "unrecognized format"); 25573 if (authpeer) { 25574 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 2)"); 25575 } 25576 return 0; 25577 } else { 25578 p->subscribed = subscribed; 25579 } 25580 } else if (!strncmp(eventheader, "message-summary", MAX(event_len, 15))) { 25581 int start = 0; 25582 int found_supported = 0; 25583 const char *acceptheader; 25584 25585 acceptheader = __get_header(req, "Accept", &start); 25586 while (!found_supported && !ast_strlen_zero(acceptheader)) { 25587 found_supported = strcmp(acceptheader, "application/simple-message-summary") ? 0 : 1; 25588 if (!found_supported && (option_debug > 2)) { 25589 ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", acceptheader); 25590 } 25591 acceptheader = __get_header(req, "Accept", &start); 25592 } 25593 if (start && !found_supported) { 25594 /* Format requested that we do not support */ 25595 transmit_response(p, "406 Not Acceptable", req); 25596 ast_debug(2, "Received SIP mailbox subscription for unknown format: %s\n", acceptheader); 25597 pvt_set_needdestroy(p, "unknown format"); 25598 if (authpeer) { 25599 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 3)"); 25600 } 25601 return 0; 25602 } 25603 /* Looks like they actually want a mailbox status 25604 This version of Asterisk supports mailbox subscriptions 25605 The subscribed URI needs to exist in the dial plan 25606 In most devices, this is configurable to the voicemailmain extension you use 25607 */ 25608 if (!authpeer || AST_LIST_EMPTY(&authpeer->mailboxes)) { 25609 if (!authpeer) { 25610 transmit_response(p, "404 Not found", req); 25611 } else { 25612 transmit_response(p, "404 Not found (no mailbox)", req); 25613 ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", S_OR(authpeer->name, "")); 25614 } 25615 pvt_set_needdestroy(p, "received 404 response"); 25616 if (authpeer) { 25617 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 3)"); 25618 } 25619 return 0; 25620 } 25621 25622 p->subscribed = MWI_NOTIFICATION; 25623 if (ast_test_flag(&authpeer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY)) { 25624 ao2_unlock(p); 25625 add_peer_mwi_subs(authpeer); 25626 ao2_lock(p); 25627 } 25628 if (authpeer->mwipvt != p) { /* Destroy old PVT if this is a new one */ 25629 /* We only allow one subscription per peer */ 25630 if (authpeer->mwipvt) { 25631 dialog_unlink_all(authpeer->mwipvt); 25632 authpeer->mwipvt = dialog_unref(authpeer->mwipvt, "unref dialog authpeer->mwipvt"); 25633 } 25634 authpeer->mwipvt = dialog_ref(p, "setting peers' mwipvt to p"); 25635 } 25636 if (p->relatedpeer != authpeer) { 25637 if (p->relatedpeer) { 25638 unref_peer(p->relatedpeer, "Unref previously stored relatedpeer ptr"); 25639 } 25640 p->relatedpeer = ref_peer(authpeer, "setting dialog's relatedpeer pointer"); 25641 } 25642 /* Do not release authpeer here */ 25643 } else if (!strncmp(eventheader, "call-completion", MAX(event_len, 15))) { 25644 handle_cc_subscribe(p, req); 25645 } else { /* At this point, Asterisk does not understand the specified event */ 25646 transmit_response(p, "489 Bad Event", req); 25647 ast_debug(2, "Received SIP subscribe for unknown event package: %s\n", eventheader); 25648 pvt_set_needdestroy(p, "unknown event package"); 25649 if (authpeer) { 25650 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 5)"); 25651 } 25652 return 0; 25653 } 25654 25655 /* Add subscription for extension state from the PBX core */ 25656 if (p->subscribed != MWI_NOTIFICATION && p->subscribed != CALL_COMPLETION && !resubscribe) { 25657 if (p->stateid != -1) { 25658 ast_extension_state_del(p->stateid, cb_extensionstate); 25659 } 25660 dialog_ref(p, "copying dialog ptr into extension state struct"); 25661 p->stateid = ast_extension_state_add_destroy(p->context, p->exten, 25662 cb_extensionstate, cb_extensionstate_destroy, p); 25663 if (p->stateid == -1) { 25664 dialog_unref(p, "copying dialog ptr into extension state struct failed"); 25665 } 25666 } 25667 25668 if (!req->ignore) { 25669 p->lastinvite = seqno; 25670 } 25671 if (!p->needdestroy) { 25672 p->expiry = atoi(get_header(req, "Expires")); 25673 25674 /* check if the requested expiry-time is within the approved limits from sip.conf */ 25675 if (p->expiry > max_expiry) { 25676 p->expiry = max_expiry; 25677 } else if (p->expiry < min_expiry && p->expiry > 0) { 25678 transmit_response_with_minexpires(p, "423 Interval too small", req); 25679 ast_log(LOG_WARNING, "Received subscription for extension \"%s\" context \"%s\" " 25680 "with Expire header less that 'minexpire' limit. Received \"Expire: %d\" min is %d\n", 25681 p->exten, p->context, p->expiry, min_expiry); 25682 pvt_set_needdestroy(p, "Expires is less that the min expires allowed."); 25683 if (authpeer) { 25684 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 6)"); 25685 } 25686 return 0; 25687 } 25688 25689 if (sipdebug) { 25690 const char *action = p->expiry > 0 ? "Adding" : "Removing"; 25691 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) { 25692 ast_debug(2, "%s subscription for mailbox notification - peer %s\n", 25693 action, p->relatedpeer->name); 25694 } else if (p->subscribed == CALL_COMPLETION) { 25695 ast_debug(2, "%s CC subscription for peer %s\n", action, p->username); 25696 } else { 25697 ast_debug(2, "%s subscription for extension %s context %s for peer %s\n", 25698 action, p->exten, p->context, p->username); 25699 } 25700 } 25701 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 25702 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 25703 if (p->expiry > 0) 25704 sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */ 25705 25706 if (p->subscribed == MWI_NOTIFICATION) { 25707 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 25708 transmit_response(p, "200 OK", req); 25709 if (p->relatedpeer) { /* Send first notification */ 25710 struct sip_peer *peer = p->relatedpeer; 25711 ref_peer(peer, "ensure a peer ref is held during MWI sending"); 25712 ao2_unlock(p); 25713 sip_send_mwi_to_peer(peer, 0); 25714 ao2_lock(p); 25715 unref_peer(peer, "release a peer ref now that MWI is sent"); 25716 } 25717 } else if (p->subscribed != CALL_COMPLETION) { 25718 sip_pvt_unlock(p); 25719 firststate = ast_extension_state(NULL, p->context, p->exten); 25720 sip_pvt_lock(p); 25721 25722 if (firststate < 0) { 25723 ast_log(LOG_NOTICE, "Got SUBSCRIBE for extension %s@%s from %s, but there is no hint for that extension.\n", p->exten, p->context, ast_sockaddr_stringify(&p->sa)); 25724 transmit_response(p, "404 Not found", req); 25725 pvt_set_needdestroy(p, "no extension for SUBSCRIBE"); 25726 if (authpeer) { 25727 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 6)"); 25728 } 25729 return 0; 25730 } 25731 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 25732 transmit_response(p, "200 OK", req); 25733 transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */ 25734 append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate)); 25735 /* hide the 'complete' exten/context in the refer_to field for later display */ 25736 ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context); 25737 /* Deleted the slow iteration of all sip dialogs to find old subscribes from this peer for exten@context */ 25738 25739 } 25740 if (!p->expiry) { 25741 pvt_set_needdestroy(p, "forcing expiration"); 25742 } 25743 } 25744 25745 if (authpeer) { 25746 unref_peer(authpeer, "unref pointer into (*authpeer)"); 25747 } 25748 return 1; 25749 }
| static int handle_request_update | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
bare-bones support for SIP UPDATE
XXX This is not even close to being RFC 3311-compliant. We don't advertise that we support the UPDATE method, so no one should ever try sending us an UPDATE anyway. However, Asterisk can send an UPDATE to change connected line information, so we need to be prepared to handle this. The way we distinguish such an UPDATE is through the X-Asterisk-rpid-update header.
Actually updating the media session may be some future work.
Definition at line 22954 of file chan_sip.c.
References ast_channel_queue_connected_line_update(), AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, ast_party_connected_line_init(), ast_strlen_zero(), connected, get_header(), get_rpid(), ast_party_connected_line::id, ast_set_party_connected_line::id, ast_party_id::name, ast_set_party_id::name, ast_party_id::number, ast_set_party_id::number, ast_party_name::presentation, ast_party_number::presentation, ast_party_connected_line::source, ast_party_name::str, ast_party_number::str, ast_party_id::tag, transmit_response(), ast_party_name::valid, and ast_party_number::valid.
Referenced by handle_incoming().
22955 { 22956 if (ast_strlen_zero(get_header(req, "X-Asterisk-rpid-update"))) { 22957 transmit_response(p, "501 Method Not Implemented", req); 22958 return 0; 22959 } 22960 if (!p->owner) { 22961 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 22962 return 0; 22963 } 22964 if (get_rpid(p, req)) { 22965 struct ast_party_connected_line connected; 22966 struct ast_set_party_connected_line update_connected; 22967 22968 ast_party_connected_line_init(&connected); 22969 memset(&update_connected, 0, sizeof(update_connected)); 22970 22971 update_connected.id.number = 1; 22972 connected.id.number.valid = 1; 22973 connected.id.number.str = (char *) p->cid_num; 22974 connected.id.number.presentation = p->callingpres; 22975 22976 update_connected.id.name = 1; 22977 connected.id.name.valid = 1; 22978 connected.id.name.str = (char *) p->cid_name; 22979 connected.id.name.presentation = p->callingpres; 22980 22981 connected.id.tag = (char *) p->cid_tag; 22982 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER; 22983 ast_channel_queue_connected_line_update(p->owner, &connected, &update_connected); 22984 } 22985 transmit_response(p, "200 OK", req); 22986 return 0; 22987 }
| static void handle_response | ( | struct sip_pvt * | p, | |
| int | resp, | |||
| const char * | rest, | |||
| struct sip_request * | req, | |||
| uint32_t | seqno | |||
| ) | [static] |
Handle SIP response in dialogue.
Definition at line 21717 of file chan_sip.c.
References __sip_ack(), __sip_semi_ack(), append_history, AST_CC_CCBS, ast_channel_set_redirecting(), ast_clear_flag, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, ast_debug, ast_log(), ast_party_redirecting_free(), ast_party_redirecting_init(), ast_queue_control(), ast_queue_hangup_with_cause(), ast_set_flag, ast_skip_blanks(), ast_skip_nonblanks(), ast_sockaddr_stringify(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verb, ast_verbose, change_redirecting_information(), do_proxy_auth(), FALSE, find_sdp(), find_sip_method(), get_header(), gettag(), handle_response_info(), handle_response_invite(), handle_response_message(), handle_response_notify(), handle_response_peerpoke(), handle_response_publish(), handle_response_refer(), handle_response_register(), handle_response_subscribe(), handle_response_update(), hangup_sip2cause(), ast_channel::hangupcause, LOG_NOTICE, LOG_WARNING, mark_method_allowed(), mark_method_unallowed(), process_sdp(), pvt_set_needdestroy(), rh, sip_alreadygone(), sip_cancel_destroy(), sip_handle_cc(), sip_methods, stop_media_flows(), text, transmit_request(), TRUE, and update_redirecting().
Referenced by handle_incoming().
21718 { 21719 struct ast_channel *owner; 21720 int sipmethod; 21721 const char *c = get_header(req, "Cseq"); 21722 /* GCC 4.2 complains if I try to cast c as a char * when passing it to ast_skip_nonblanks, so make a copy of it */ 21723 char *c_copy = ast_strdupa(c); 21724 /* Skip the Cseq and its subsequent spaces */ 21725 const char *msg = ast_skip_blanks(ast_skip_nonblanks(c_copy)); 21726 21727 if (!msg) 21728 msg = ""; 21729 21730 sipmethod = find_sip_method(msg); 21731 21732 owner = p->owner; 21733 if (owner) { 21734 const char *rp = NULL, *rh = NULL; 21735 21736 owner->hangupcause = 0; 21737 if (ast_test_flag(&p->flags[1], SIP_PAGE2_Q850_REASON) && (rh = get_header(req, "Reason"))) { 21738 rh = ast_skip_blanks(rh); 21739 if (!strncasecmp(rh, "Q.850", 5)) { 21740 rp = strstr(rh, "cause="); 21741 if (rp && sscanf(rp + 6, "%30d", &owner->hangupcause) == 1) { 21742 owner->hangupcause &= 0x7f; 21743 if (req->debug) 21744 ast_verbose("Using Reason header for cause code: %d\n", owner->hangupcause); 21745 } 21746 } 21747 } 21748 21749 if (!owner->hangupcause) 21750 owner->hangupcause = hangup_sip2cause(resp); 21751 } 21752 21753 if (p->socket.type == SIP_TRANSPORT_UDP) { 21754 int ack_res = FALSE; 21755 21756 /* Acknowledge whatever it is destined for */ 21757 if ((resp >= 100) && (resp <= 199)) { 21758 /* NON-INVITE messages do not ack a 1XX response. RFC 3261 section 17.1.2.2 */ 21759 if (sipmethod == SIP_INVITE) { 21760 ack_res = __sip_semi_ack(p, seqno, 0, sipmethod); 21761 } 21762 } else { 21763 ack_res = __sip_ack(p, seqno, 0, sipmethod); 21764 } 21765 21766 if (ack_res == FALSE) { 21767 /* RFC 3261 13.2.2.4 and 17.1.1.2 - We must re-send ACKs to re-transmitted final responses */ 21768 if (sipmethod == SIP_INVITE && resp >= 200) { 21769 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, resp < 300 ? TRUE: FALSE); 21770 } 21771 21772 append_history(p, "Ignore", "Ignoring this retransmit\n"); 21773 return; 21774 } 21775 } 21776 21777 /* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */ 21778 if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite) { 21779 p->pendinginvite = 0; 21780 } 21781 21782 /* Get their tag if we haven't already */ 21783 if (ast_strlen_zero(p->theirtag) || (resp >= 200)) { 21784 char tag[128]; 21785 21786 gettag(req, "To", tag, sizeof(tag)); 21787 ast_string_field_set(p, theirtag, tag); 21788 } else { 21789 /* Store theirtag to track for changes when 200 responses to invites are received without SDP */ 21790 ast_string_field_set(p, theirprovtag, p->theirtag); 21791 } 21792 21793 /* This needs to be configurable on a channel/peer level, 21794 not mandatory for all communication. Sadly enough, NAT implementations 21795 are not so stable so we can always rely on these headers. 21796 Temporarily disabled, while waiting for fix. 21797 Fix assigned to Rizzo :-) 21798 */ 21799 /* check_via_response(p, req); */ 21800 21801 /* RFC 3261 Section 15 specifies that if we receive a 408 or 481 21802 * in response to a BYE, then we should end the current dialog 21803 * and session. It is known that at least one phone manufacturer 21804 * potentially will send a 404 in response to a BYE, so we'll be 21805 * liberal in what we accept and end the dialog and session if we 21806 * receive any of those responses to a BYE. 21807 */ 21808 if ((resp == 404 || resp == 408 || resp == 481) && sipmethod == SIP_BYE) { 21809 pvt_set_needdestroy(p, "received 4XX response to a BYE"); 21810 return; 21811 } 21812 21813 if (p->relatedpeer && sipmethod == SIP_OPTIONS) { 21814 /* We don't really care what the response is, just that it replied back. 21815 Well, as long as it's not a 100 response... since we might 21816 need to hang around for something more "definitive" */ 21817 if (resp != 100) 21818 handle_response_peerpoke(p, resp, req); 21819 } else if (sipmethod == SIP_REFER && resp >= 200) { 21820 handle_response_refer(p, resp, rest, req, seqno); 21821 } else if (sipmethod == SIP_PUBLISH) { 21822 /* SIP PUBLISH transcends this morass of doodoo and instead 21823 * we just always call the response handler. Good gravy! 21824 */ 21825 handle_response_publish(p, resp, rest, req, seqno); 21826 } else if (sipmethod == SIP_INFO) { 21827 /* More good gravy! */ 21828 handle_response_info(p, resp, rest, req, seqno); 21829 } else if (sipmethod == SIP_MESSAGE) { 21830 /* More good gravy! */ 21831 handle_response_message(p, resp, rest, req, seqno); 21832 } else if (sipmethod == SIP_NOTIFY) { 21833 /* The gravy train continues to roll */ 21834 handle_response_notify(p, resp, rest, req, seqno); 21835 } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 21836 switch(resp) { 21837 case 100: /* 100 Trying */ 21838 case 101: /* 101 Dialog establishment */ 21839 case 183: /* 183 Session Progress */ 21840 case 180: /* 180 Ringing */ 21841 case 182: /* 182 Queued */ 21842 case 181: /* 181 Call Is Being Forwarded */ 21843 if (sipmethod == SIP_INVITE) 21844 handle_response_invite(p, resp, rest, req, seqno); 21845 break; 21846 case 200: /* 200 OK */ 21847 p->authtries = 0; /* Reset authentication counter */ 21848 if (sipmethod == SIP_INVITE) { 21849 handle_response_invite(p, resp, rest, req, seqno); 21850 } else if (sipmethod == SIP_REGISTER) { 21851 handle_response_register(p, resp, rest, req, seqno); 21852 } else if (sipmethod == SIP_SUBSCRIBE) { 21853 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 21854 handle_response_subscribe(p, resp, rest, req, seqno); 21855 } else if (sipmethod == SIP_BYE) { /* Ok, we're ready to go */ 21856 pvt_set_needdestroy(p, "received 200 response"); 21857 ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 21858 } 21859 break; 21860 case 401: /* Not www-authorized on SIP method */ 21861 case 407: /* Proxy auth required */ 21862 if (sipmethod == SIP_INVITE) 21863 handle_response_invite(p, resp, rest, req, seqno); 21864 else if (sipmethod == SIP_SUBSCRIBE) 21865 handle_response_subscribe(p, resp, rest, req, seqno); 21866 else if (p->registry && sipmethod == SIP_REGISTER) 21867 handle_response_register(p, resp, rest, req, seqno); 21868 else if (sipmethod == SIP_UPDATE) { 21869 handle_response_update(p, resp, rest, req, seqno); 21870 } else if (sipmethod == SIP_BYE) { 21871 if (p->options) 21872 p->options->auth_type = resp; 21873 if (ast_strlen_zero(p->authname)) { 21874 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s but we have no matching peer!\n", 21875 msg, ast_sockaddr_stringify(&p->recv)); 21876 pvt_set_needdestroy(p, "unable to authenticate BYE"); 21877 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, resp, sipmethod, 0)) { 21878 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 21879 pvt_set_needdestroy(p, "failed to authenticate BYE"); 21880 } 21881 } else { 21882 ast_log(LOG_WARNING, "Got authentication request (%d) on %s to '%s'\n", resp, sip_methods[sipmethod].text, get_header(req, "To")); 21883 pvt_set_needdestroy(p, "received 407 response"); 21884 } 21885 break; 21886 case 403: /* Forbidden - we failed authentication */ 21887 if (sipmethod == SIP_INVITE) 21888 handle_response_invite(p, resp, rest, req, seqno); 21889 else if (sipmethod == SIP_SUBSCRIBE) 21890 handle_response_subscribe(p, resp, rest, req, seqno); 21891 else if (p->registry && sipmethod == SIP_REGISTER) 21892 handle_response_register(p, resp, rest, req, seqno); 21893 else { 21894 ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg); 21895 pvt_set_needdestroy(p, "received 403 response"); 21896 } 21897 break; 21898 case 400: /* Bad Request */ 21899 case 414: /* Request URI too long */ 21900 case 493: /* Undecipherable */ 21901 case 404: /* Not found */ 21902 if (p->registry && sipmethod == SIP_REGISTER) 21903 handle_response_register(p, resp, rest, req, seqno); 21904 else if (sipmethod == SIP_INVITE) 21905 handle_response_invite(p, resp, rest, req, seqno); 21906 else if (sipmethod == SIP_SUBSCRIBE) 21907 handle_response_subscribe(p, resp, rest, req, seqno); 21908 else if (owner) 21909 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 21910 break; 21911 case 423: /* Interval too brief */ 21912 if (sipmethod == SIP_REGISTER) 21913 handle_response_register(p, resp, rest, req, seqno); 21914 break; 21915 case 408: /* Request timeout - terminate dialog */ 21916 if (sipmethod == SIP_INVITE) 21917 handle_response_invite(p, resp, rest, req, seqno); 21918 else if (sipmethod == SIP_REGISTER) 21919 handle_response_register(p, resp, rest, req, seqno); 21920 else if (sipmethod == SIP_BYE) { 21921 pvt_set_needdestroy(p, "received 408 response"); 21922 ast_debug(4, "Got timeout on bye. Thanks for the answer. Now, kill this call\n"); 21923 } else { 21924 if (owner) 21925 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 21926 pvt_set_needdestroy(p, "received 408 response"); 21927 } 21928 break; 21929 21930 case 428: 21931 case 422: /* Session-Timers: Session Interval Too Small */ 21932 if (sipmethod == SIP_INVITE) { 21933 handle_response_invite(p, resp, rest, req, seqno); 21934 } 21935 break; 21936 21937 case 481: /* Call leg does not exist */ 21938 if (sipmethod == SIP_INVITE) { 21939 handle_response_invite(p, resp, rest, req, seqno); 21940 } else if (sipmethod == SIP_SUBSCRIBE) { 21941 handle_response_subscribe(p, resp, rest, req, seqno); 21942 } else if (sipmethod == SIP_BYE) { 21943 /* The other side has no transaction to bye, 21944 just assume it's all right then */ 21945 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 21946 } else if (sipmethod == SIP_CANCEL) { 21947 /* The other side has no transaction to cancel, 21948 just assume it's all right then */ 21949 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 21950 } else { 21951 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 21952 /* Guessing that this is not an important request */ 21953 } 21954 break; 21955 case 487: 21956 if (sipmethod == SIP_INVITE) 21957 handle_response_invite(p, resp, rest, req, seqno); 21958 break; 21959 case 415: /* Unsupported media type */ 21960 case 488: /* Not acceptable here - codec error */ 21961 case 606: /* Not Acceptable */ 21962 if (sipmethod == SIP_INVITE) 21963 handle_response_invite(p, resp, rest, req, seqno); 21964 break; 21965 case 491: /* Pending */ 21966 if (sipmethod == SIP_INVITE) 21967 handle_response_invite(p, resp, rest, req, seqno); 21968 else { 21969 ast_debug(1, "Got 491 on %s, unsupported. Call ID %s\n", sip_methods[sipmethod].text, p->callid); 21970 pvt_set_needdestroy(p, "received 491 response"); 21971 } 21972 break; 21973 case 405: /* Method not allowed */ 21974 case 501: /* Not Implemented */ 21975 mark_method_unallowed(&p->allowed_methods, sipmethod); 21976 if (p->relatedpeer) { 21977 mark_method_allowed(&p->relatedpeer->disallowed_methods, sipmethod); 21978 } 21979 if (sipmethod == SIP_INVITE) 21980 handle_response_invite(p, resp, rest, req, seqno); 21981 else 21982 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_sockaddr_stringify(&p->sa), msg); 21983 break; 21984 default: 21985 if ((resp >= 300) && (resp < 700)) { 21986 /* Fatal response */ 21987 if ((resp != 487)) 21988 ast_verb(3, "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_sockaddr_stringify(&p->sa)); 21989 21990 if (sipmethod == SIP_INVITE) 21991 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 21992 21993 /* XXX Locking issues?? XXX */ 21994 switch(resp) { 21995 case 300: /* Multiple Choices */ 21996 case 301: /* Moved permanently */ 21997 case 302: /* Moved temporarily */ 21998 case 305: /* Use Proxy */ 21999 if (p->owner) { 22000 struct ast_party_redirecting redirecting; 22001 struct ast_set_party_redirecting update_redirecting; 22002 22003 ast_party_redirecting_init(&redirecting); 22004 memset(&update_redirecting, 0, sizeof(update_redirecting)); 22005 change_redirecting_information(p, req, &redirecting, 22006 &update_redirecting, TRUE); 22007 ast_channel_set_redirecting(p->owner, &redirecting, 22008 &update_redirecting); 22009 ast_party_redirecting_free(&redirecting); 22010 } 22011 /* Fall through */ 22012 case 486: /* Busy here */ 22013 case 600: /* Busy everywhere */ 22014 case 603: /* Decline */ 22015 if (p->owner) { 22016 sip_handle_cc(p, req, AST_CC_CCBS); 22017 ast_queue_control(p->owner, AST_CONTROL_BUSY); 22018 } 22019 break; 22020 case 482: /* Loop Detected */ 22021 case 480: /* Temporarily Unavailable */ 22022 case 404: /* Not Found */ 22023 case 410: /* Gone */ 22024 case 400: /* Bad Request */ 22025 case 500: /* Server error */ 22026 if (sipmethod == SIP_SUBSCRIBE) { 22027 handle_response_subscribe(p, resp, rest, req, seqno); 22028 break; 22029 } 22030 /* Fall through */ 22031 case 502: /* Bad gateway */ 22032 case 503: /* Service Unavailable */ 22033 case 504: /* Server Timeout */ 22034 if (owner) 22035 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 22036 break; 22037 case 484: /* Address Incomplete */ 22038 if (owner && sipmethod != SIP_BYE) { 22039 switch (ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) { 22040 case SIP_PAGE2_ALLOWOVERLAP_YES: 22041 ast_queue_hangup_with_cause(p->owner, hangup_sip2cause(resp)); 22042 break; 22043 default: 22044 ast_queue_hangup_with_cause(p->owner, hangup_sip2cause(404)); 22045 break; 22046 } 22047 } 22048 break; 22049 default: 22050 /* Send hangup */ 22051 if (owner && sipmethod != SIP_BYE) 22052 ast_queue_hangup_with_cause(p->owner, hangup_sip2cause(resp)); 22053 break; 22054 } 22055 /* ACK on invite */ 22056 if (sipmethod == SIP_INVITE) 22057 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 22058 sip_alreadygone(p); 22059 if (!p->owner) { 22060 pvt_set_needdestroy(p, "transaction completed"); 22061 } 22062 } else if ((resp >= 100) && (resp < 200)) { 22063 if (sipmethod == SIP_INVITE) { 22064 if (!req->ignore && sip_cancel_destroy(p)) 22065 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 22066 if (find_sdp(req)) 22067 process_sdp(p, req, SDP_T38_NONE); 22068 if (p->owner) { 22069 /* Queue a progress frame */ 22070 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 22071 } 22072 } 22073 } else 22074 ast_log(LOG_NOTICE, "Don't know how to handle a %d %s response from %s\n", resp, rest, p->owner ? p->owner->name : ast_sockaddr_stringify(&p->sa)); 22075 } 22076 } else { 22077 /* Responses to OUTGOING SIP requests on INCOMING calls 22078 get handled here. As well as out-of-call message responses */ 22079 if (req->debug) 22080 ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg); 22081 22082 if (sipmethod == SIP_INVITE && resp == 200) { 22083 /* Tags in early session is replaced by the tag in 200 OK, which is 22084 the final reply to our INVITE */ 22085 char tag[128]; 22086 22087 gettag(req, "To", tag, sizeof(tag)); 22088 ast_string_field_set(p, theirtag, tag); 22089 } 22090 22091 switch(resp) { 22092 case 200: 22093 if (sipmethod == SIP_INVITE) { 22094 handle_response_invite(p, resp, rest, req, seqno); 22095 } else if (sipmethod == SIP_CANCEL) { 22096 ast_debug(1, "Got 200 OK on CANCEL\n"); 22097 22098 /* Wait for 487, then destroy */ 22099 } else if (sipmethod == SIP_BYE) { 22100 pvt_set_needdestroy(p, "transaction completed"); 22101 } 22102 break; 22103 case 401: /* www-auth */ 22104 case 407: 22105 if (sipmethod == SIP_INVITE) 22106 handle_response_invite(p, resp, rest, req, seqno); 22107 else if (sipmethod == SIP_BYE) { 22108 if (p->authtries == MAX_AUTHTRIES || do_proxy_auth(p, req, resp, sipmethod, 0)) { 22109 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 22110 pvt_set_needdestroy(p, "failed to authenticate BYE"); 22111 } 22112 } 22113 break; 22114 case 481: /* Call leg does not exist */ 22115 if (sipmethod == SIP_INVITE) { 22116 /* Re-invite failed */ 22117 handle_response_invite(p, resp, rest, req, seqno); 22118 } else if (sipmethod == SIP_BYE) { 22119 pvt_set_needdestroy(p, "received 481 response"); 22120 } else if (sipdebug) { 22121 ast_debug(1, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid); 22122 } 22123 break; 22124 case 501: /* Not Implemented */ 22125 if (sipmethod == SIP_INVITE) 22126 handle_response_invite(p, resp, rest, req, seqno); 22127 break; 22128 default: /* Errors without handlers */ 22129 if ((resp >= 100) && (resp < 200)) { 22130 if (sipmethod == SIP_INVITE) { /* re-invite */ 22131 if (!req->ignore && sip_cancel_destroy(p)) 22132 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 22133 } 22134 } 22135 if ((resp >= 300) && (resp < 700)) { 22136 if ((resp != 487)) 22137 ast_verb(3, "Incoming call: Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_sockaddr_stringify(&p->sa)); 22138 switch(resp) { 22139 case 415: /* Unsupported media type */ 22140 case 488: /* Not acceptable here - codec error */ 22141 case 603: /* Decline */ 22142 case 500: /* Server error */ 22143 case 502: /* Bad gateway */ 22144 case 503: /* Service Unavailable */ 22145 case 504: /* Server timeout */ 22146 22147 /* re-invite failed */ 22148 if (sipmethod == SIP_INVITE && sip_cancel_destroy(p)) 22149 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 22150 break; 22151 } 22152 } 22153 break; 22154 } 22155 } 22156 }
| static void handle_response_info | ( | struct sip_pvt * | p, | |
| int | resp, | |||
| const char * | rest, | |||
| struct sip_request * | req, | |||
| uint32_t | seqno | |||
| ) | [static] |
Definition at line 21631 of file chan_sip.c.
References ast_log(), ast_sockaddr_stringify(), ast_verb, LOG_WARNING, mark_method_allowed(), mark_method_unallowed(), sip_methods, text, and cfsip_methods::text.
Referenced by handle_response().
21632 { 21633 int sipmethod = SIP_INFO; 21634 21635 switch (resp) { 21636 case 401: /* Not www-authorized on SIP method */ 21637 case 407: /* Proxy auth required */ 21638 ast_log(LOG_WARNING, "Host '%s' requests authentication (%d) for '%s'\n", 21639 ast_sockaddr_stringify(&p->sa), resp, sip_methods[sipmethod].text); 21640 break; 21641 case 405: /* Method not allowed */ 21642 case 501: /* Not Implemented */ 21643 mark_method_unallowed(&p->allowed_methods, sipmethod); 21644 if (p->relatedpeer) { 21645 mark_method_allowed(&p->relatedpeer->disallowed_methods, sipmethod); 21646 } 21647 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", 21648 ast_sockaddr_stringify(&p->sa), sip_methods[sipmethod].text); 21649 break; 21650 default: 21651 if (300 <= resp && resp < 700) { 21652 ast_verb(3, "Got SIP %s response %d \"%s\" back from host '%s'\n", 21653 sip_methods[sipmethod].text, resp, rest, ast_sockaddr_stringify(&p->sa)); 21654 } 21655 break; 21656 } 21657 }
| static void handle_response_invite | ( | struct sip_pvt * | p, | |
| int | resp, | |||
| const char * | rest, | |||
| struct sip_request * | req, | |||
| uint32_t | seqno | |||
| ) | [static] |
Handle SIP response to INVITE dialogue.
Definition at line 20692 of file chan_sip.c.
References append_history, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_NORMAL_CLEARING, AST_CC_CCNR, ast_channel_queue_connected_line_update(), ast_channel_queue_redirecting_update(), AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER, AST_CONTROL_ANSWER, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_UPDATE_RTP_PEER, ast_debug, ast_log(), ast_null_frame, ast_party_connected_line_init(), ast_party_redirecting_free(), ast_party_redirecting_init(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, ast_queue_control(), ast_queue_frame(), ast_queue_hangup_with_cause(), ast_random(), ast_rtp_instance_activate(), ast_rtp_instance_get_remote_address(), ast_sched_add(), AST_SCHED_DEL_UNREF, ast_set_flag, ast_setstate(), ast_sockaddr_isnull(), AST_STATE_RINGING, AST_STATE_UP, ast_string_field_set, ast_strlen_zero(), ast_test_flag, build_route(), change_redirecting_information(), change_t38_state(), check_pendings(), connected, do_proxy_auth(), EVENT_FLAG_SYSTEM, FALSE, find_sdp(), get_header(), get_rpid(), hangup_sip2cause(), ast_party_connected_line::id, ast_set_party_connected_line::id, LOG_NOTICE, LOG_WARNING, manager_event, ast_party_id::name, ast_set_party_id::name, ast_party_id::number, ast_set_party_id::number, parse_ok_contact(), parse_session_expires(), ast_party_name::presentation, ast_party_number::presentation, proc_422_rsp(), process_sdp(), pvt_set_needdestroy(), set_address_from_contact(), set_pvt_allowed_methods(), sip_alreadygone(), sip_cancel_destroy(), sip_cfg, sip_handle_cc(), sip_queue_hangup_cause(), sip_reinvite_retry(), sip_scheddestroy(), ast_party_connected_line::source, st_get_mode(), st_get_se(), start_session_timer(), ast_party_name::str, ast_party_number::str, ast_party_id::tag, transmit_reinvite_with_sdp(), transmit_request(), TRUE, update_call_counter(), update_redirecting(), ast_party_name::valid, and ast_party_number::valid.
Referenced by handle_response().
20693 { 20694 int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING); 20695 int res = 0; 20696 int xmitres = 0; 20697 int reinvite = ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 20698 char *p_hdrval; 20699 int rtn; 20700 struct ast_party_connected_line connected; 20701 struct ast_set_party_connected_line update_connected; 20702 20703 if (reinvite) 20704 ast_debug(4, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid); 20705 else 20706 ast_debug(4, "SIP response %d to standard invite\n", resp); 20707 20708 if (p->alreadygone) { /* This call is already gone */ 20709 ast_debug(1, "Got response on call that is already terminated: %s (ignoring)\n", p->callid); 20710 return; 20711 } 20712 20713 /* Acknowledge sequence number - This only happens on INVITE from SIP-call */ 20714 /* Don't auto congest anymore since we've gotten something useful back */ 20715 AST_SCHED_DEL_UNREF(sched, p->initid, dialog_unref(p, "when you delete the initid sched, you should dec the refcount for the stored dialog ptr")); 20716 20717 /* RFC3261 says we must treat every 1xx response (but not 100) 20718 that we don't recognize as if it was 183. 20719 */ 20720 if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 181 && resp != 182 && resp != 183) 20721 resp = 183; 20722 20723 /* Any response between 100 and 199 is PROCEEDING */ 20724 if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING) 20725 p->invitestate = INV_PROCEEDING; 20726 20727 /* Final response, not 200 ? */ 20728 if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA )) 20729 p->invitestate = INV_COMPLETED; 20730 20731 if ((resp >= 200 && reinvite)) { 20732 p->ongoing_reinvite = 0; 20733 if (p->reinviteid > -1) { 20734 AST_SCHED_DEL_UNREF(sched, p->reinviteid, dialog_unref(p, "unref dialog for reinvite timeout because of a final response")); 20735 } 20736 } 20737 20738 /* Final response, clear out pending invite */ 20739 if ((resp == 200 || resp >= 300) && p->pendinginvite && seqno == p->pendinginvite) { 20740 p->pendinginvite = 0; 20741 } 20742 20743 /* If this is a response to our initial INVITE, we need to set what we can use 20744 * for this peer. 20745 */ 20746 if (!reinvite) { 20747 set_pvt_allowed_methods(p, req); 20748 } 20749 20750 switch (resp) { 20751 case 100: /* Trying */ 20752 case 101: /* Dialog establishment */ 20753 if (!req->ignore && p->invitestate != INV_CANCELLED && sip_cancel_destroy(p)) 20754 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 20755 check_pendings(p); 20756 break; 20757 20758 case 180: /* 180 Ringing */ 20759 case 182: /* 182 Queued */ 20760 if (!req->ignore && p->invitestate != INV_CANCELLED && sip_cancel_destroy(p)) 20761 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 20762 /* Store Route-set from provisional SIP responses so 20763 * early-dialog request can be routed properly 20764 * */ 20765 parse_ok_contact(p, req); 20766 if (!reinvite) { 20767 build_route(p, req, 1, resp); 20768 } 20769 if (!req->ignore && p->owner) { 20770 if (get_rpid(p, req)) { 20771 /* Queue a connected line update */ 20772 ast_party_connected_line_init(&connected); 20773 memset(&update_connected, 0, sizeof(update_connected)); 20774 20775 update_connected.id.number = 1; 20776 connected.id.number.valid = 1; 20777 connected.id.number.str = (char *) p->cid_num; 20778 connected.id.number.presentation = p->callingpres; 20779 20780 update_connected.id.name = 1; 20781 connected.id.name.valid = 1; 20782 connected.id.name.str = (char *) p->cid_name; 20783 connected.id.name.presentation = p->callingpres; 20784 20785 connected.id.tag = (char *) p->cid_tag; 20786 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; 20787 ast_channel_queue_connected_line_update(p->owner, &connected, 20788 &update_connected); 20789 } 20790 sip_handle_cc(p, req, AST_CC_CCNR); 20791 ast_queue_control(p->owner, AST_CONTROL_RINGING); 20792 if (p->owner->_state != AST_STATE_UP) { 20793 ast_setstate(p->owner, AST_STATE_RINGING); 20794 } 20795 } 20796 if (find_sdp(req)) { 20797 if (p->invitestate != INV_CANCELLED) 20798 p->invitestate = INV_EARLY_MEDIA; 20799 res = process_sdp(p, req, SDP_T38_NONE); 20800 if (!req->ignore && p->owner) { 20801 /* Queue a progress frame only if we have SDP in 180 or 182 */ 20802 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 20803 } 20804 ast_rtp_instance_activate(p->rtp); 20805 } 20806 check_pendings(p); 20807 break; 20808 20809 case 181: /* Call Is Being Forwarded */ 20810 if (!req->ignore && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 20811 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 20812 /* Store Route-set from provisional SIP responses so 20813 * early-dialog request can be routed properly 20814 * */ 20815 parse_ok_contact(p, req); 20816 if (!reinvite) { 20817 build_route(p, req, 1, resp); 20818 } 20819 if (!req->ignore && p->owner) { 20820 struct ast_party_redirecting redirecting; 20821 struct ast_set_party_redirecting update_redirecting; 20822 20823 ast_party_redirecting_init(&redirecting); 20824 memset(&update_redirecting, 0, sizeof(update_redirecting)); 20825 change_redirecting_information(p, req, &redirecting, &update_redirecting, 20826 FALSE); 20827 ast_channel_queue_redirecting_update(p->owner, &redirecting, 20828 &update_redirecting); 20829 ast_party_redirecting_free(&redirecting); 20830 sip_handle_cc(p, req, AST_CC_CCNR); 20831 } 20832 check_pendings(p); 20833 break; 20834 20835 case 183: /* Session progress */ 20836 if (!req->ignore && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 20837 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 20838 /* Store Route-set from provisional SIP responses so 20839 * early-dialog request can be routed properly 20840 * */ 20841 parse_ok_contact(p, req); 20842 if (!reinvite) { 20843 build_route(p, req, 1, resp); 20844 } 20845 if (!req->ignore && p->owner) { 20846 if (get_rpid(p, req)) { 20847 /* Queue a connected line update */ 20848 ast_party_connected_line_init(&connected); 20849 memset(&update_connected, 0, sizeof(update_connected)); 20850 20851 update_connected.id.number = 1; 20852 connected.id.number.valid = 1; 20853 connected.id.number.str = (char *) p->cid_num; 20854 connected.id.number.presentation = p->callingpres; 20855 20856 update_connected.id.name = 1; 20857 connected.id.name.valid = 1; 20858 connected.id.name.str = (char *) p->cid_name; 20859 connected.id.name.presentation = p->callingpres; 20860 20861 connected.id.tag = (char *) p->cid_tag; 20862 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; 20863 ast_channel_queue_connected_line_update(p->owner, &connected, 20864 &update_connected); 20865 } 20866 sip_handle_cc(p, req, AST_CC_CCNR); 20867 } 20868 if (find_sdp(req)) { 20869 if (p->invitestate != INV_CANCELLED) 20870 p->invitestate = INV_EARLY_MEDIA; 20871 res = process_sdp(p, req, SDP_T38_NONE); 20872 if (!req->ignore && p->owner) { 20873 /* Queue a progress frame */ 20874 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 20875 } 20876 ast_rtp_instance_activate(p->rtp); 20877 } else { 20878 /* Alcatel PBXs are known to send 183s with no SDP after sending 20879 * a 100 Trying response. We're just going to treat this sort of thing 20880 * the same as we would treat a 180 Ringing 20881 */ 20882 if (!req->ignore && p->owner) { 20883 ast_queue_control(p->owner, AST_CONTROL_RINGING); 20884 } 20885 } 20886 check_pendings(p); 20887 break; 20888 20889 case 200: /* 200 OK on invite - someone's answering our call */ 20890 if (!req->ignore && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 20891 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 20892 p->authtries = 0; 20893 if (find_sdp(req)) { 20894 if ((res = process_sdp(p, req, SDP_T38_ACCEPT)) && !req->ignore) { 20895 if (!reinvite) { 20896 /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */ 20897 /* For re-invites, we try to recover */ 20898 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 20899 p->hangupcause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 20900 if (p->owner) { 20901 p->owner->hangupcause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 20902 sip_queue_hangup_cause(p, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 20903 } 20904 } 20905 } 20906 ast_rtp_instance_activate(p->rtp); 20907 } else if (!reinvite) { 20908 struct ast_sockaddr remote_address = {{0,}}; 20909 20910 ast_rtp_instance_get_remote_address(p->rtp, &remote_address); 20911 if (ast_sockaddr_isnull(&remote_address) || (!ast_strlen_zero(p->theirprovtag) && strcmp(p->theirtag, p->theirprovtag))) { 20912 ast_log(LOG_WARNING, "Received response: \"200 OK\" from '%s' without SDP\n", p->relatedpeer->name); 20913 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 20914 ast_rtp_instance_activate(p->rtp); 20915 } 20916 } 20917 20918 if (!req->ignore && p->owner) { 20919 int rpid_changed; 20920 20921 rpid_changed = get_rpid(p, req); 20922 if (rpid_changed || !reinvite) { 20923 /* Queue a connected line update */ 20924 ast_party_connected_line_init(&connected); 20925 memset(&update_connected, 0, sizeof(update_connected)); 20926 if (rpid_changed 20927 || !ast_strlen_zero(p->cid_num) 20928 || (p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) { 20929 update_connected.id.number = 1; 20930 connected.id.number.valid = 1; 20931 connected.id.number.str = (char *) p->cid_num; 20932 connected.id.number.presentation = p->callingpres; 20933 } 20934 if (rpid_changed 20935 || !ast_strlen_zero(p->cid_name) 20936 || (p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) { 20937 update_connected.id.name = 1; 20938 connected.id.name.valid = 1; 20939 connected.id.name.str = (char *) p->cid_name; 20940 connected.id.name.presentation = p->callingpres; 20941 } 20942 if (update_connected.id.number || update_connected.id.name) { 20943 connected.id.tag = (char *) p->cid_tag; 20944 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; 20945 ast_channel_queue_connected_line_update(p->owner, &connected, 20946 &update_connected); 20947 } 20948 } 20949 } 20950 20951 /* Parse contact header for continued conversation */ 20952 /* When we get 200 OK, we know which device (and IP) to contact for this call */ 20953 /* This is important when we have a SIP proxy between us and the phone */ 20954 if (outgoing) { 20955 update_call_counter(p, DEC_CALL_RINGING); 20956 parse_ok_contact(p, req); 20957 /* Save Record-Route for any later requests we make on this dialogue */ 20958 if (!reinvite) { 20959 build_route(p, req, 1, resp); 20960 } 20961 if(set_address_from_contact(p)) { 20962 /* Bad contact - we don't know how to reach this device */ 20963 /* We need to ACK, but then send a bye */ 20964 if (!p->route && !req->ignore) 20965 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 20966 } 20967 20968 } 20969 20970 if (!req->ignore && p->owner) { 20971 if (!reinvite && !res) { 20972 ast_queue_control(p->owner, AST_CONTROL_ANSWER); 20973 if (sip_cfg.callevents) 20974 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", 20975 "Channel: %s\r\nChanneltype: %s\r\nUniqueid: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\nPeername: %s\r\n", 20976 p->owner->name, "SIP", p->owner->uniqueid, p->callid, p->fullcontact, p->peername); 20977 } else { /* RE-invite */ 20978 if (p->t38.state == T38_DISABLED) { 20979 ast_queue_control(p->owner, AST_CONTROL_UPDATE_RTP_PEER); 20980 } else { 20981 ast_queue_frame(p->owner, &ast_null_frame); 20982 } 20983 } 20984 } else { 20985 /* It's possible we're getting an 200 OK after we've tried to disconnect 20986 by sending CANCEL */ 20987 /* First send ACK, then send bye */ 20988 if (!req->ignore) 20989 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 20990 } 20991 20992 /* Check for Session-Timers related headers */ 20993 if (st_get_mode(p, 0) != SESSION_TIMER_MODE_REFUSE) { 20994 p_hdrval = (char*)get_header(req, "Session-Expires"); 20995 if (!ast_strlen_zero(p_hdrval)) { 20996 /* UAS supports Session-Timers */ 20997 enum st_refresher_param st_ref_param; 20998 int tmp_st_interval = 0; 20999 rtn = parse_session_expires(p_hdrval, &tmp_st_interval, &st_ref_param); 21000 if (rtn != 0) { 21001 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 21002 } else if (tmp_st_interval < st_get_se(p, FALSE)) { 21003 ast_log(LOG_WARNING, "Got Session-Expires less than local Min-SE in 200 OK, tearing down call\n"); 21004 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 21005 } 21006 if (st_ref_param == SESSION_TIMER_REFRESHER_PARAM_UAC) { 21007 p->stimer->st_ref = SESSION_TIMER_REFRESHER_US; 21008 } else if (st_ref_param == SESSION_TIMER_REFRESHER_PARAM_UAS) { 21009 p->stimer->st_ref = SESSION_TIMER_REFRESHER_THEM; 21010 } else { 21011 ast_log(LOG_WARNING, "Unknown refresher on %s\n", p->callid); 21012 } 21013 if (tmp_st_interval) { 21014 p->stimer->st_interval = tmp_st_interval; 21015 } 21016 p->stimer->st_active = TRUE; 21017 p->stimer->st_active_peer_ua = TRUE; 21018 start_session_timer(p); 21019 } else { 21020 /* UAS doesn't support Session-Timers */ 21021 if (st_get_mode(p, 0) == SESSION_TIMER_MODE_ORIGINATE) { 21022 p->stimer->st_ref = SESSION_TIMER_REFRESHER_US; 21023 p->stimer->st_active_peer_ua = FALSE; 21024 start_session_timer(p); 21025 } 21026 } 21027 } 21028 21029 21030 /* If I understand this right, the branch is different for a non-200 ACK only */ 21031 p->invitestate = INV_TERMINATED; 21032 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 21033 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE); 21034 check_pendings(p); 21035 break; 21036 21037 case 407: /* Proxy authentication */ 21038 case 401: /* Www auth */ 21039 /* First we ACK */ 21040 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 21041 if (p->options) 21042 p->options->auth_type = resp; 21043 21044 /* Then we AUTH */ 21045 ast_string_field_set(p, theirtag, NULL); /* forget their old tag, so we don't match tags when getting response */ 21046 if (!req->ignore) { 21047 if (p->authtries < MAX_AUTHTRIES) 21048 p->invitestate = INV_CALLING; 21049 if (p->authtries == MAX_AUTHTRIES || do_proxy_auth(p, req, resp, SIP_INVITE, 1)) { 21050 ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); 21051 pvt_set_needdestroy(p, "failed to authenticate on INVITE"); 21052 sip_alreadygone(p); 21053 if (p->owner) 21054 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 21055 } 21056 } 21057 break; 21058 21059 case 403: /* Forbidden */ 21060 /* First we ACK */ 21061 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 21062 ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From")); 21063 if (!req->ignore && p->owner) { 21064 sip_queue_hangup_cause(p, hangup_sip2cause(resp)); 21065 } 21066 break; 21067 21068 case 414: /* Bad request URI */ 21069 case 493: /* Undecipherable */ 21070 case 404: /* Not found */ 21071 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 21072 if (p->owner && !req->ignore) { 21073 sip_queue_hangup_cause(p, hangup_sip2cause(resp)); 21074 } 21075 break; 21076 21077 case 481: /* Call leg does not exist */ 21078 /* Could be REFER caused INVITE with replaces */ 21079 ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid); 21080 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 21081 if (p->owner) { 21082 ast_queue_hangup_with_cause(p->owner, hangup_sip2cause(resp)); 21083 } 21084 break; 21085 21086 case 422: /* Session-Timers: Session interval too small */ 21087 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 21088 ast_string_field_set(p, theirtag, NULL); 21089 proc_422_rsp(p, req); 21090 break; 21091 21092 case 428: /* Use identity header - rfc 4474 - not supported by Asterisk yet */ 21093 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 21094 append_history(p, "Identity", "SIP identity is required. Not supported by Asterisk."); 21095 ast_log(LOG_WARNING, "SIP identity required by proxy. SIP dialog '%s'. Giving up.\n", p->callid); 21096 if (p->owner && !req->ignore) { 21097 ast_queue_hangup_with_cause(p->owner, hangup_sip2cause(resp)); 21098 } 21099 break; 21100 21101 case 487: /* Cancelled transaction */ 21102 /* We have sent CANCEL on an outbound INVITE 21103 This transaction is already scheduled to be killed by sip_hangup(). 21104 */ 21105 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 21106 if (p->owner && !req->ignore) { 21107 ast_queue_hangup_with_cause(p->owner, AST_CAUSE_NORMAL_CLEARING); 21108 append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request"); 21109 } else if (!req->ignore) { 21110 update_call_counter(p, DEC_CALL_LIMIT); 21111 append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog."); 21112 } 21113 check_pendings(p); 21114 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 21115 break; 21116 case 415: /* Unsupported media type */ 21117 case 488: /* Not acceptable here */ 21118 case 606: /* Not Acceptable */ 21119 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 21120 if (p->udptl && p->t38.state == T38_LOCAL_REINVITE) { 21121 change_t38_state(p, T38_DISABLED); 21122 /* Try to reset RTP timers */ 21123 //ast_rtp_set_rtptimers_onhold(p->rtp); 21124 21125 /* Trigger a reinvite back to audio */ 21126 transmit_reinvite_with_sdp(p, FALSE, FALSE); 21127 } else { 21128 /* We can't set up this call, so give up */ 21129 if (p->owner && !req->ignore) { 21130 ast_queue_hangup_with_cause(p->owner, hangup_sip2cause(resp)); 21131 } 21132 } 21133 break; 21134 case 491: /* Pending */ 21135 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 21136 if (p->owner && !req->ignore) { 21137 if (p->owner->_state != AST_STATE_UP) { 21138 ast_queue_hangup_with_cause(p->owner, hangup_sip2cause(resp)); 21139 } else { 21140 /* This is a re-invite that failed. */ 21141 /* Reset the flag after a while 21142 */ 21143 int wait; 21144 /* RFC 3261, if owner of call, wait between 2.1 to 4 seconds, 21145 * if not owner of call, wait 0 to 2 seconds */ 21146 if (p->outgoing_call) { 21147 wait = 2100 + ast_random() % 2000; 21148 } else { 21149 wait = ast_random() % 2000; 21150 } 21151 p->waitid = ast_sched_add(sched, wait, sip_reinvite_retry, dialog_ref(p, "passing dialog ptr into sched structure based on waitid for sip_reinvite_retry.")); 21152 ast_debug(2, "Reinvite race. Scheduled sip_reinvite_retry in %d secs in handle_response_invite (waitid %d, dialog '%s')\n", 21153 wait, p->waitid, p->callid); 21154 } 21155 } 21156 break; 21157 21158 case 408: /* Request timeout */ 21159 case 405: /* Not allowed */ 21160 case 501: /* Not implemented */ 21161 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 21162 if (p->owner) { 21163 ast_queue_hangup_with_cause(p->owner, hangup_sip2cause(resp)); 21164 } 21165 break; 21166 } 21167 if (xmitres == XMIT_ERROR) 21168 ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid); 21169 }
| static void handle_response_message | ( | struct sip_pvt * | p, | |
| int | resp, | |||
| const char * | rest, | |||
| struct sip_request * | req, | |||
| uint32_t | seqno | |||
| ) | [static] |
Definition at line 21667 of file chan_sip.c.
References ast_log(), ast_sockaddr_stringify(), ast_verb, LOG_WARNING, mark_method_allowed(), mark_method_unallowed(), sip_methods, text, and cfsip_methods::text.
Referenced by handle_response().
21668 { 21669 int sipmethod = SIP_MESSAGE; 21670 /* Out-of-dialog MESSAGE currently not supported. */ 21671 //int in_dialog = ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 21672 21673 switch (resp) { 21674 case 401: /* Not www-authorized on SIP method */ 21675 case 407: /* Proxy auth required */ 21676 ast_log(LOG_WARNING, "Host '%s' requests authentication (%d) for '%s'\n", 21677 ast_sockaddr_stringify(&p->sa), resp, sip_methods[sipmethod].text); 21678 break; 21679 case 405: /* Method not allowed */ 21680 case 501: /* Not Implemented */ 21681 mark_method_unallowed(&p->allowed_methods, sipmethod); 21682 if (p->relatedpeer) { 21683 mark_method_allowed(&p->relatedpeer->disallowed_methods, sipmethod); 21684 } 21685 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", 21686 ast_sockaddr_stringify(&p->sa), sip_methods[sipmethod].text); 21687 break; 21688 default: 21689 if (100 <= resp && resp < 200) { 21690 /* Must allow provisional responses for out-of-dialog requests. */ 21691 } else if (200 <= resp && resp < 300) { 21692 p->authtries = 0; /* Reset authentication counter */ 21693 } else if (300 <= resp && resp < 700) { 21694 ast_verb(3, "Got SIP %s response %d \"%s\" back from host '%s'\n", 21695 sip_methods[sipmethod].text, resp, rest, ast_sockaddr_stringify(&p->sa)); 21696 } 21697 break; 21698 } 21699 }
| static void handle_response_notify | ( | struct sip_pvt * | p, | |
| int | resp, | |||
| const char * | rest, | |||
| struct sip_request * | req, | |||
| uint32_t | seqno | |||
| ) | [static] |
Definition at line 21174 of file chan_sip.c.
References ast_clear_flag, ast_debug, ast_log(), ast_sockaddr_stringify(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, cb_extensionstate(), do_proxy_auth(), get_header(), LOG_NOTICE, LOG_WARNING, NONE, and pvt_set_needdestroy().
Referenced by handle_response().
21175 { 21176 switch (resp) { 21177 case 200: /* Notify accepted */ 21178 /* They got the notify, this is the end */ 21179 if (p->owner) { 21180 if (p->refer) { 21181 ast_log(LOG_NOTICE, "Got OK on REFER Notify message\n"); 21182 } else { 21183 ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name); 21184 } 21185 } else { 21186 if (p->subscribed == NONE && !p->refer) { 21187 ast_debug(4, "Got 200 accepted on NOTIFY %s\n", p->callid); 21188 pvt_set_needdestroy(p, "received 200 response"); 21189 } 21190 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 21191 /* Ready to send the next state we have on queue */ 21192 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 21193 cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p); 21194 } 21195 } 21196 break; 21197 case 401: /* Not www-authorized on SIP method */ 21198 case 407: /* Proxy auth */ 21199 if (!p->notify) { 21200 break; /* Only device notify can use NOTIFY auth */ 21201 } 21202 ast_string_field_set(p, theirtag, NULL); 21203 if (ast_strlen_zero(p->authname)) { 21204 ast_log(LOG_WARNING, "Asked to authenticate NOTIFY to %s but we have no matching peer or realm auth!\n", ast_sockaddr_stringify(&p->recv)); 21205 pvt_set_needdestroy(p, "unable to authenticate NOTIFY"); 21206 } 21207 if (p->authtries > 1 || do_proxy_auth(p, req, resp, SIP_NOTIFY, 0)) { 21208 ast_log(LOG_NOTICE, "Failed to authenticate on NOTIFY to '%s'\n", get_header(&p->initreq, "From")); 21209 pvt_set_needdestroy(p, "failed to authenticate NOTIFY"); 21210 } 21211 break; 21212 case 481: /* Call leg does not exist */ 21213 pvt_set_needdestroy(p, "Received 481 response for NOTIFY"); 21214 break; 21215 } 21216 }
| static void handle_response_peerpoke | ( | struct sip_pvt * | p, | |
| int | resp, | |||
| struct sip_request * | req | |||
| ) | [static] |
Handle qualification responses (OPTIONS).
Definition at line 21564 of file chan_sip.c.
References ast_check_realtime(), AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_log(), AST_SCHED_REPLACE_UNREF, ast_tvdiff_ms(), ast_tvnow(), ast_update_realtime(), DEFAULT_FREQ_NOTOK, EVENT_FLAG_SYSTEM, LOG_NOTICE, manager_event, pvt_set_needdestroy(), ref_peer(), register_peer_exten(), SENTINEL, sip_cfg, sip_poke_peer_s(), TRUE, and unref_peer().
Referenced by handle_response().
21565 { 21566 struct sip_peer *peer = /* ref_peer( */ p->relatedpeer /* , "bump refcount on p, as it is being used in this function(handle_response_peerpoke)")*/ ; /* hope this is already refcounted! */ 21567 int statechanged, is_reachable, was_reachable; 21568 int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps); 21569 21570 /* 21571 * Compute the response time to a ping (goes in peer->lastms.) 21572 * -1 means did not respond, 0 means unknown, 21573 * 1..maxms is a valid response, >maxms means late response. 21574 */ 21575 if (pingtime < 1) { /* zero = unknown, so round up to 1 */ 21576 pingtime = 1; 21577 } 21578 21579 if (!peer->maxms) { /* this should never happens */ 21580 pvt_set_needdestroy(p, "got OPTIONS response but qualify is not enabled"); 21581 return; 21582 } 21583 21584 /* Now determine new state and whether it has changed. 21585 * Use some helper variables to simplify the writing 21586 * of the expressions. 21587 */ 21588 was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms; 21589 is_reachable = pingtime <= peer->maxms; 21590 statechanged = peer->lastms == 0 /* yes, unknown before */ 21591 || was_reachable != is_reachable; 21592 21593 peer->lastms = pingtime; 21594 peer->call = dialog_unref(peer->call, "unref dialog peer->call"); 21595 if (statechanged) { 21596 const char *s = is_reachable ? "Reachable" : "Lagged"; 21597 char str_lastms[20]; 21598 snprintf(str_lastms, sizeof(str_lastms), "%d", pingtime); 21599 21600 ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n", 21601 peer->name, s, pingtime, peer->maxms); 21602 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", peer->name); 21603 if (sip_cfg.peer_rtupdate) { 21604 ast_update_realtime(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", "name", peer->name, "lastms", str_lastms, SENTINEL); 21605 } 21606 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 21607 "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n", 21608 peer->name, s, pingtime); 21609 if (is_reachable && sip_cfg.regextenonqualify) 21610 register_peer_exten(peer, TRUE); 21611 } 21612 21613 pvt_set_needdestroy(p, "got OPTIONS response"); 21614 21615 /* Try again eventually */ 21616 AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, 21617 is_reachable ? peer->qualifyfreq : DEFAULT_FREQ_NOTOK, 21618 sip_poke_peer_s, peer, 21619 unref_peer(_data, "removing poke peer ref"), 21620 unref_peer(peer, "removing poke peer ref"), 21621 ref_peer(peer, "adding poke peer ref")); 21622 }
| static void handle_response_publish | ( | struct sip_pvt * | p, | |
| int | resp, | |||
| const char * | rest, | |||
| struct sip_request * | req, | |||
| uint32_t | seqno | |||
| ) | [static] |
Definition at line 20606 of file chan_sip.c.
References ast_assert, ast_copy_string(), ast_log(), ast_string_field_set, ast_strlen_zero(), do_proxy_auth(), get_header(), LOG_NOTICE, mark_method_unallowed(), pvt_set_needdestroy(), and sip_alreadygone().
Referenced by handle_response().
20607 { 20608 struct sip_epa_entry *epa_entry = p->epa_entry; 20609 const char *etag = get_header(req, "Sip-ETag"); 20610 20611 ast_assert(epa_entry != NULL); 20612 20613 if (resp == 401 || resp == 407) { 20614 ast_string_field_set(p, theirtag, NULL); 20615 if (p->options) { 20616 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 20617 } 20618 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, resp, SIP_PUBLISH, 0)) { 20619 ast_log(LOG_NOTICE, "Failed to authenticate on PUBLISH to '%s'\n", get_header(&p->initreq, "From")); 20620 pvt_set_needdestroy(p, "Failed to authenticate on PUBLISH"); 20621 sip_alreadygone(p); 20622 } 20623 return; 20624 } 20625 20626 if (resp == 501 || resp == 405) { 20627 mark_method_unallowed(&p->allowed_methods, SIP_PUBLISH); 20628 } 20629 20630 if (resp == 200) { 20631 p->authtries = 0; 20632 /* If I've read section 6, item 6 of RFC 3903 correctly, 20633 * an ESC will only generate a new etag when it sends a 200 OK 20634 */ 20635 if (!ast_strlen_zero(etag)) { 20636 ast_copy_string(epa_entry->entity_tag, etag, sizeof(epa_entry->entity_tag)); 20637 } 20638 /* The nominal case. Everything went well. Everybody is happy. 20639 * Each EPA will have a specific action to take as a result of this 20640 * development, so ... callbacks! 20641 */ 20642 if (epa_entry->static_data->handle_ok) { 20643 epa_entry->static_data->handle_ok(p, req, epa_entry); 20644 } 20645 } else { 20646 /* Rather than try to make individual callbacks for each error 20647 * type, there is just a single error callback. The callback 20648 * can distinguish between error messages and do what it needs to 20649 */ 20650 if (epa_entry->static_data->handle_error) { 20651 epa_entry->static_data->handle_error(p, resp, req, epa_entry); 20652 } 20653 } 20654 }
| static void handle_response_refer | ( | struct sip_pvt * | p, | |
| int | resp, | |||
| const char * | rest, | |||
| struct sip_request * | req, | |||
| uint32_t | seqno | |||
| ) | [static] |
Definition at line 21309 of file chan_sip.c.
References AST_CONTROL_CONGESTION, AST_CONTROL_TRANSFER, ast_debug, ast_log(), ast_queue_control(), ast_queue_control_data(), ast_sockaddr_stringify(), ast_strlen_zero(), AST_TRANSFER_FAILED, do_proxy_auth(), get_header(), LOG_NOTICE, LOG_WARNING, and pvt_set_needdestroy().
Referenced by handle_response().
21310 { 21311 enum ast_control_transfer message = AST_TRANSFER_FAILED; 21312 21313 /* If no refer structure exists, then do nothing */ 21314 if (!p->refer) 21315 return; 21316 21317 switch (resp) { 21318 case 202: /* Transfer accepted */ 21319 /* We need to do something here */ 21320 /* The transferee is now sending INVITE to target */ 21321 p->refer->status = REFER_ACCEPTED; 21322 /* Now wait for next message */ 21323 ast_debug(3, "Got 202 accepted on transfer\n"); 21324 /* We should hang along, waiting for NOTIFY's here */ 21325 break; 21326 21327 case 401: /* Not www-authorized on SIP method */ 21328 case 407: /* Proxy auth */ 21329 if (ast_strlen_zero(p->authname)) { 21330 ast_log(LOG_WARNING, "Asked to authenticate REFER to %s but we have no matching peer or realm auth!\n", 21331 ast_sockaddr_stringify(&p->recv)); 21332 if (p->owner) { 21333 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 21334 } 21335 pvt_set_needdestroy(p, "unable to authenticate REFER"); 21336 } 21337 if (p->authtries > 1 || do_proxy_auth(p, req, resp, SIP_REFER, 0)) { 21338 ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From")); 21339 p->refer->status = REFER_NOAUTH; 21340 if (p->owner) { 21341 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 21342 } 21343 pvt_set_needdestroy(p, "failed to authenticate REFER"); 21344 } 21345 break; 21346 21347 case 405: /* Method not allowed */ 21348 /* Return to the current call onhold */ 21349 /* Status flag needed to be reset */ 21350 ast_log(LOG_NOTICE, "SIP transfer to %s failed, REFER not allowed. \n", p->refer->refer_to); 21351 pvt_set_needdestroy(p, "received 405 response"); 21352 p->refer->status = REFER_FAILED; 21353 if (p->owner) { 21354 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 21355 } 21356 break; 21357 21358 case 481: /* Call leg does not exist */ 21359 21360 /* A transfer with Replaces did not work */ 21361 /* OEJ: We should Set flag, cancel the REFER, go back 21362 to original call - but right now we can't */ 21363 ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid); 21364 if (p->owner) 21365 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 21366 pvt_set_needdestroy(p, "received 481 response"); 21367 break; 21368 21369 case 500: /* Server error */ 21370 case 501: /* Method not implemented */ 21371 /* Return to the current call onhold */ 21372 /* Status flag needed to be reset */ 21373 ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to); 21374 pvt_set_needdestroy(p, "received 500/501 response"); 21375 p->refer->status = REFER_FAILED; 21376 if (p->owner) { 21377 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 21378 } 21379 break; 21380 case 603: /* Transfer declined */ 21381 ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to); 21382 p->refer->status = REFER_FAILED; 21383 pvt_set_needdestroy(p, "received 603 response"); 21384 if (p->owner) { 21385 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 21386 } 21387 break; 21388 default: 21389 /* We should treat unrecognized 9xx as 900. 400 is actually 21390 specified as a possible response, but any 4-6xx is 21391 theoretically possible. */ 21392 21393 if (resp < 299) { /* 1xx cases don't get here */ 21394 ast_log(LOG_WARNING, "SIP transfer to %s had unxpected 2xx response (%d), confusion is possible. \n", p->refer->refer_to, resp); 21395 } else { 21396 ast_log(LOG_WARNING, "SIP transfer to %s with response (%d). \n", p->refer->refer_to, resp); 21397 } 21398 21399 p->refer->status = REFER_FAILED; 21400 pvt_set_needdestroy(p, "received failure response"); 21401 if (p->owner) { 21402 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 21403 } 21404 break; 21405 } 21406 }
| static int handle_response_register | ( | struct sip_pvt * | p, | |
| int | resp, | |||
| const char * | rest, | |||
| struct sip_request * | req, | |||
| uint32_t | seqno | |||
| ) | [static] |
Handle responses on REGISTER to services.
Definition at line 21409 of file chan_sip.c.
References __get_header(), ast_debug, ast_log(), AST_SCHED_DEL_UNREF, AST_SCHED_REPLACE_UNREF, ast_string_field_set, ast_strlen_zero(), ast_tvnow(), do_register_auth(), EVENT_FLAG_SYSTEM, get_header(), LOG_NOTICE, LOG_WARNING, manager_event, MAX, pvt_set_needdestroy(), REG_STATE_NOAUTH, REG_STATE_REGISTERED, REG_STATE_REJECTED, REG_STATE_UNREGISTERED, registry_addref(), registry_unref(), regstate2str(), S_OR, sip_reregister(), and transmit_register().
Referenced by handle_response().
21410 { 21411 int expires, expires_ms; 21412 struct sip_registry *r; 21413 r=p->registry; 21414 21415 switch (resp) { 21416 case 401: /* Unauthorized */ 21417 if (p->authtries == MAX_AUTHTRIES || do_register_auth(p, req, resp)) { 21418 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries); 21419 pvt_set_needdestroy(p, "failed to authenticate REGISTER"); 21420 } 21421 break; 21422 case 403: /* Forbidden */ 21423 if (global_reg_retry_403) { 21424 ast_log(LOG_NOTICE, "Treating 403 response to REGISTER as non-fatal for %s@%s\n", 21425 p->registry->username, p->registry->hostname); 21426 ast_string_field_set(r, nonce, ""); 21427 ast_string_field_set(p, nonce, ""); 21428 break; 21429 } 21430 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); 21431 AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 403")); 21432 r->regstate = REG_STATE_NOAUTH; 21433 pvt_set_needdestroy(p, "received 403 response"); 21434 break; 21435 case 404: /* Not found */ 21436 ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username, p->registry->hostname); 21437 pvt_set_needdestroy(p, "received 404 response"); 21438 if (r->call) 21439 r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 404"); 21440 r->regstate = REG_STATE_REJECTED; 21441 AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 404")); 21442 break; 21443 case 407: /* Proxy auth */ 21444 if (p->authtries == MAX_AUTHTRIES || do_register_auth(p, req, resp)) { 21445 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries); 21446 pvt_set_needdestroy(p, "failed to authenticate REGISTER"); 21447 } 21448 break; 21449 case 408: /* Request timeout */ 21450 /* Got a timeout response, so reset the counter of failed responses */ 21451 if (r) { 21452 r->regattempts = 0; 21453 } else { 21454 ast_log(LOG_WARNING, "Got a 408 response to our REGISTER on call %s after we had destroyed the registry object\n", p->callid); 21455 } 21456 break; 21457 case 423: /* Interval too brief */ 21458 r->expiry = atoi(get_header(req, "Min-Expires")); 21459 ast_log(LOG_WARNING, "Got 423 Interval too brief for service %s@%s, minimum is %d seconds\n", p->registry->username, p->registry->hostname, r->expiry); 21460 AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 423")); 21461 if (r->call) { 21462 r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 423"); 21463 pvt_set_needdestroy(p, "received 423 response"); 21464 } 21465 if (r->expiry > max_expiry) { 21466 ast_log(LOG_WARNING, "Required expiration time from %s@%s is too high, giving up\n", p->registry->username, p->registry->hostname); 21467 r->expiry = r->configured_expiry; 21468 r->regstate = REG_STATE_REJECTED; 21469 } else { 21470 r->regstate = REG_STATE_UNREGISTERED; 21471 transmit_register(r, SIP_REGISTER, NULL, NULL); 21472 } 21473 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: SIP\r\nUsername: %s\r\nDomain: %s\r\nStatus: %s\r\n", r->username, r->hostname, regstate2str(r->regstate)); 21474 break; 21475 case 400: /* Bad request */ 21476 case 414: /* Request URI too long */ 21477 case 493: /* Undecipherable */ 21478 case 479: /* Kamailio/OpenSIPS: Not able to process the URI - address is wrong in register*/ 21479 ast_log(LOG_WARNING, "Got error %d on register to %s@%s, giving up (check config)\n", resp, p->registry->username, p->registry->hostname); 21480 pvt_set_needdestroy(p, "received 4xx response"); 21481 if (r->call) 21482 r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 4xx"); 21483 r->regstate = REG_STATE_REJECTED; 21484 AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 479")); 21485 break; 21486 case 200: /* 200 OK */ 21487 if (!r) { 21488 ast_log(LOG_WARNING, "Got 200 OK on REGISTER, but there isn't a registry entry for '%s' (we probably already got the OK)\n", S_OR(p->peername, p->username)); 21489 pvt_set_needdestroy(p, "received erroneous 200 response"); 21490 return 0; 21491 } 21492 21493 r->regstate = REG_STATE_REGISTERED; 21494 r->regtime = ast_tvnow(); /* Reset time of last successful registration */ 21495 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: SIP\r\nUsername: %s\r\nDomain: %s\r\nStatus: %s\r\n", r->username, r->hostname, regstate2str(r->regstate)); 21496 r->regattempts = 0; 21497 ast_debug(1, "Registration successful\n"); 21498 if (r->timeout > -1) { 21499 ast_debug(1, "Cancelling timeout %d\n", r->timeout); 21500 } 21501 AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 200")); 21502 if (r->call) 21503 r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 200"); 21504 p->registry = registry_unref(p->registry, "unref registry entry p->registry"); 21505 21506 /* destroy dialog now to avoid interference with next register */ 21507 pvt_set_needdestroy(p, "Registration successfull"); 21508 21509 /* set us up for re-registering 21510 * figure out how long we got registered for 21511 * according to section 6.13 of RFC, contact headers override 21512 * expires headers, so check those first */ 21513 expires = 0; 21514 21515 /* XXX todo: try to save the extra call */ 21516 if (!ast_strlen_zero(get_header(req, "Contact"))) { 21517 const char *contact = NULL; 21518 const char *tmptmp = NULL; 21519 int start = 0; 21520 for(;;) { 21521 contact = __get_header(req, "Contact", &start); 21522 /* this loop ensures we get a contact header about our register request */ 21523 if(!ast_strlen_zero(contact)) { 21524 if( (tmptmp=strstr(contact, p->our_contact))) { 21525 contact=tmptmp; 21526 break; 21527 } 21528 } else 21529 break; 21530 } 21531 tmptmp = strcasestr(contact, "expires="); 21532 if (tmptmp) { 21533 if (sscanf(tmptmp + 8, "%30d", &expires) != 1) { 21534 expires = 0; 21535 } 21536 } 21537 21538 } 21539 if (!expires) 21540 expires=atoi(get_header(req, "expires")); 21541 if (!expires) 21542 expires=default_expiry; 21543 21544 expires_ms = expires * 1000; 21545 if (expires <= EXPIRY_GUARD_LIMIT) 21546 expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT), EXPIRY_GUARD_MIN); 21547 else 21548 expires_ms -= EXPIRY_GUARD_SECS * 1000; 21549 if (sipdebug) 21550 ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 21551 21552 r->refresh= (int) expires_ms / 1000; 21553 21554 /* Schedule re-registration before we expire */ 21555 AST_SCHED_REPLACE_UNREF(r->expire, sched, expires_ms, sip_reregister, r, 21556 registry_unref(_data,"unref in REPLACE del fail"), 21557 registry_unref(r,"unref in REPLACE add fail"), 21558 registry_addref(r,"The Addition side of REPLACE")); 21559 } 21560 return 1; 21561 }
| static void handle_response_subscribe | ( | struct sip_pvt * | p, | |
| int | resp, | |||
| const char * | rest, | |||
| struct sip_request * | req, | |||
| uint32_t | seqno | |||
| ) | [static] |
Definition at line 21219 of file chan_sip.c.
References ao2_callback, ao2_ref, ast_cc_monitor_failed(), ast_debug, ast_free, ast_log(), ast_sched_add(), ast_string_field_set, ASTOBJ_REF, ASTOBJ_UNREF, do_proxy_auth(), find_sip_monitor_instance_by_subscription_pvt(), get_header(), LOG_NOTICE, LOG_WARNING, pvt_set_needdestroy(), set_pvt_allowed_methods(), sip_alreadygone(), sip_subscribe_mwi_destroy(), sip_subscribe_mwi_do(), and transmit_response_with_date().
Referenced by handle_response().
21220 { 21221 if (p->subscribed == CALL_COMPLETION) { 21222 struct sip_monitor_instance *monitor_instance; 21223 21224 if (resp < 300) { 21225 return; 21226 } 21227 21228 /* Final failure response received. */ 21229 monitor_instance = ao2_callback(sip_monitor_instances, 0, 21230 find_sip_monitor_instance_by_subscription_pvt, p); 21231 if (monitor_instance) { 21232 ast_cc_monitor_failed(monitor_instance->core_id, 21233 monitor_instance->device_name, 21234 "Received error response to our SUBSCRIBE"); 21235 } 21236 return; 21237 } 21238 21239 if (p->subscribed != MWI_NOTIFICATION) { 21240 return; 21241 } 21242 if (!p->mwi) { 21243 return; 21244 } 21245 21246 switch (resp) { 21247 case 200: /* Subscription accepted */ 21248 ast_debug(3, "Got 200 OK on subscription for MWI\n"); 21249 set_pvt_allowed_methods(p, req); 21250 if (p->options) { 21251 if (p->options->outboundproxy) { 21252 ao2_ref(p->options->outboundproxy, -1); 21253 } 21254 ast_free(p->options); 21255 p->options = NULL; 21256 } 21257 p->mwi->subscribed = 1; 21258 if ((p->mwi->resub = ast_sched_add(sched, mwi_expiry * 1000, sip_subscribe_mwi_do, ASTOBJ_REF(p->mwi))) < 0) { 21259 ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); 21260 } 21261 break; 21262 case 401: 21263 case 407: 21264 ast_string_field_set(p, theirtag, NULL); 21265 if (p->authtries > 1 || do_proxy_auth(p, req, resp, SIP_SUBSCRIBE, 0)) { 21266 ast_log(LOG_NOTICE, "Failed to authenticate on SUBSCRIBE to '%s'\n", get_header(&p->initreq, "From")); 21267 p->mwi->call = NULL; 21268 ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); 21269 pvt_set_needdestroy(p, "failed to authenticate SUBSCRIBE"); 21270 } 21271 break; 21272 case 403: 21273 transmit_response_with_date(p, "200 OK", req); 21274 ast_log(LOG_WARNING, "Authentication failed while trying to subscribe for MWI.\n"); 21275 p->mwi->call = NULL; 21276 ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); 21277 pvt_set_needdestroy(p, "received 403 response"); 21278 sip_alreadygone(p); 21279 break; 21280 case 404: 21281 ast_log(LOG_WARNING, "Subscription failed for MWI. The remote side said that a mailbox may not have been configured.\n"); 21282 p->mwi->call = NULL; 21283 ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); 21284 pvt_set_needdestroy(p, "received 404 response"); 21285 break; 21286 case 481: 21287 ast_log(LOG_WARNING, "Subscription failed for MWI. The remote side said that our dialog did not exist.\n"); 21288 p->mwi->call = NULL; 21289 ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); 21290 pvt_set_needdestroy(p, "received 481 response"); 21291 break; 21292 21293 case 400: /* Bad Request */ 21294 case 414: /* Request URI too long */ 21295 case 493: /* Undecipherable */ 21296 case 500: 21297 case 501: 21298 ast_log(LOG_WARNING, "Subscription failed for MWI. The remote side may have suffered a heart attack.\n"); 21299 p->mwi->call = NULL; 21300 ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); 21301 pvt_set_needdestroy(p, "received serious error (500/501/493/414/400) response"); 21302 break; 21303 } 21304 }
| static void handle_response_update | ( | struct sip_pvt * | p, | |
| int | resp, | |||
| const char * | rest, | |||
| struct sip_request * | req, | |||
| uint32_t | seqno | |||
| ) | [static] |
Handle authentication challenge for SIP UPDATE.
This function is only called upon the receipt of a 401/407 response to an UPDATE.
Definition at line 20546 of file chan_sip.c.
References ast_log(), do_proxy_auth(), get_header(), and LOG_NOTICE.
Referenced by handle_response().
20547 { 20548 if (p->options) { 20549 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 20550 } 20551 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, resp, SIP_UPDATE, 1)) { 20552 ast_log(LOG_NOTICE, "Failed to authenticate on UPDATE to '%s'\n", get_header(&p->initreq, "From")); 20553 } 20554 }
| static int handle_sip_publish_initial | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| struct event_state_compositor * | esc, | |||
| const int | expires | |||
| ) | [static] |
Definition at line 25100 of file chan_sip.c.
References ao2_ref, event_state_compositor::callbacks, create_esc_entry(), transmit_response(), and transmit_response_with_sip_etag().
Referenced by handle_request_publish().
25101 { 25102 struct sip_esc_entry *esc_entry = create_esc_entry(esc, req, expires); 25103 int res = 0; 25104 25105 if (!esc_entry) { 25106 transmit_response(p, "503 Internal Server Failure", req); 25107 return -1; 25108 } 25109 25110 if (esc->callbacks->initial_handler) { 25111 res = esc->callbacks->initial_handler(p, req, esc, esc_entry); 25112 } 25113 25114 if (!res) { 25115 transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 0); 25116 } 25117 25118 ao2_ref(esc_entry, -1); 25119 return res; 25120 }
| static int handle_sip_publish_modify | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| struct event_state_compositor * | esc, | |||
| const char *const | etag, | |||
| const int | expires | |||
| ) | [static] |
Definition at line 25150 of file chan_sip.c.
References ao2_ref, AST_SCHED_REPLACE_UNREF, event_state_compositor::callbacks, get_esc_entry(), publish_expire(), transmit_response(), and transmit_response_with_sip_etag().
Referenced by handle_request_publish().
25151 { 25152 struct sip_esc_entry *esc_entry = get_esc_entry(etag, esc); 25153 int expires_ms = expires * 1000; 25154 int res = 0; 25155 25156 if (!esc_entry) { 25157 transmit_response(p, "412 Conditional Request Failed", req); 25158 return -1; 25159 } 25160 25161 AST_SCHED_REPLACE_UNREF(esc_entry->sched_id, sched, expires_ms, publish_expire, esc_entry, 25162 ao2_ref(_data, -1), 25163 ao2_ref(esc_entry, -1), 25164 ao2_ref(esc_entry, +1)); 25165 25166 if (esc->callbacks->modify_handler) { 25167 res = esc->callbacks->modify_handler(p, req, esc, esc_entry); 25168 } 25169 25170 if (!res) { 25171 transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 1); 25172 } 25173 25174 ao2_ref(esc_entry, -1); 25175 return res; 25176 }
| static int handle_sip_publish_refresh | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| struct event_state_compositor * | esc, | |||
| const char *const | etag, | |||
| const int | expires | |||
| ) | [static] |
Definition at line 25122 of file chan_sip.c.
References ao2_ref, AST_SCHED_REPLACE_UNREF, event_state_compositor::callbacks, get_esc_entry(), publish_expire(), transmit_response(), and transmit_response_with_sip_etag().
Referenced by handle_request_publish().
25123 { 25124 struct sip_esc_entry *esc_entry = get_esc_entry(etag, esc); 25125 int expires_ms = expires * 1000; 25126 int res = 0; 25127 25128 if (!esc_entry) { 25129 transmit_response(p, "412 Conditional Request Failed", req); 25130 return -1; 25131 } 25132 25133 AST_SCHED_REPLACE_UNREF(esc_entry->sched_id, sched, expires_ms, publish_expire, esc_entry, 25134 ao2_ref(_data, -1), 25135 ao2_ref(esc_entry, -1), 25136 ao2_ref(esc_entry, +1)); 25137 25138 if (esc->callbacks->refresh_handler) { 25139 res = esc->callbacks->refresh_handler(p, req, esc, esc_entry); 25140 } 25141 25142 if (!res) { 25143 transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 1); 25144 } 25145 25146 ao2_ref(esc_entry, -1); 25147 return res; 25148 }
| static int handle_sip_publish_remove | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| struct event_state_compositor * | esc, | |||
| const char *const | etag | |||
| ) | [static] |
Definition at line 25178 of file chan_sip.c.
References ao2_ref, ao2_unlink, AST_SCHED_DEL, event_state_compositor::callbacks, event_state_compositor::compositor, get_esc_entry(), transmit_response(), and transmit_response_with_sip_etag().
Referenced by handle_request_publish().
25179 { 25180 struct sip_esc_entry *esc_entry = get_esc_entry(etag, esc); 25181 int res = 0; 25182 25183 if (!esc_entry) { 25184 transmit_response(p, "412 Conditional Request Failed", req); 25185 return -1; 25186 } 25187 25188 AST_SCHED_DEL(sched, esc_entry->sched_id); 25189 /* Scheduler's ref of the esc_entry */ 25190 ao2_ref(esc_entry, -1); 25191 25192 if (esc->callbacks->remove_handler) { 25193 res = esc->callbacks->remove_handler(p, req, esc, esc_entry); 25194 } 25195 25196 if (!res) { 25197 transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 1); 25198 } 25199 25200 /* Ref from finding the esc_entry earlier in function */ 25201 ao2_unlink(esc->compositor, esc_entry); 25202 ao2_ref(esc_entry, -1); 25203 return res; 25204 }
| static int handle_t38_options | ( | struct ast_flags * | flags, | |
| struct ast_flags * | mask, | |||
| struct ast_variable * | v, | |||
| unsigned int * | maxdatagram | |||
| ) | [static] |
Handle T.38 configuration options common to users and peers.
Definition at line 27539 of file chan_sip.c.
References ast_clear_flag, ast_log(), ast_set2_flag, ast_set_flag, ast_strdupa, ast_true(), ast_variable::lineno, LOG_WARNING, ast_variable::name, ast_variable::value, and word.
Referenced by build_peer(), and reload_config().
27541 { 27542 int res = 1; 27543 27544 if (!strcasecmp(v->name, "t38pt_udptl")) { 27545 char *buf = ast_strdupa(v->value); 27546 char *word, *next = buf; 27547 27548 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT); 27549 27550 while ((word = strsep(&next, ","))) { 27551 if (ast_true(word) || !strcasecmp(word, "fec")) { 27552 ast_clear_flag(&flags[1], SIP_PAGE2_T38SUPPORT); 27553 ast_set_flag(&flags[1], SIP_PAGE2_T38SUPPORT_UDPTL_FEC); 27554 } else if (!strcasecmp(word, "redundancy")) { 27555 ast_clear_flag(&flags[1], SIP_PAGE2_T38SUPPORT); 27556 ast_set_flag(&flags[1], SIP_PAGE2_T38SUPPORT_UDPTL_REDUNDANCY); 27557 } else if (!strcasecmp(word, "none")) { 27558 ast_clear_flag(&flags[1], SIP_PAGE2_T38SUPPORT); 27559 ast_set_flag(&flags[1], SIP_PAGE2_T38SUPPORT_UDPTL); 27560 } else if (!strncasecmp(word, "maxdatagram=", 12)) { 27561 if (sscanf(&word[12], "%30u", maxdatagram) != 1) { 27562 ast_log(LOG_WARNING, "Invalid maxdatagram '%s' at line %d of %s\n", v->value, v->lineno, config); 27563 *maxdatagram = global_t38_maxdatagram; 27564 } 27565 } 27566 } 27567 } else if (!strcasecmp(v->name, "t38pt_usertpsource")) { 27568 ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION); 27569 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION); 27570 } else { 27571 res = 0; 27572 } 27573 27574 return res; 27575 }
| const char* hangup_cause2sip | ( | int | cause | ) |
Convert Asterisk hangup causes to SIP codes.
Possible values from causes.h
AST_CAUSE_NOTDEFINED AST_CAUSE_NORMAL AST_CAUSE_BUSY
AST_CAUSE_FAILURE AST_CAUSE_CONGESTION AST_CAUSE_UNALLOCATED
In addition to these, a lot of PRI codes is defined in causes.h
...should we take care of them too ?
Quote RFC 3398
ISUP Cause value SIP response
---------------- ------------
1 unallocated number 404 Not Found
2 no route to network 404 Not found
3 no route to destination 404 Not found
16 normal call clearing --- (*)
17 user busy 486 Busy here
18 no user responding 408 Request Timeout
19 no answer from the user 480 Temporarily unavailable
20 subscriber absent 480 Temporarily unavailable
21 call rejected 403 Forbidden (+)
22 number changed (w/o diagnostic) 410 Gone
22 number changed (w/ diagnostic) 301 Moved Permanently
23 redirection to new destination 410 Gone
26 non-selected user clearing 404 Not Found (=)
27 destination out of order 502 Bad Gateway
28 address incomplete 484 Address incomplete
29 facility rejected 501 Not implemented
31 normal unspecified 480 Temporarily unavailable
Definition at line 6426 of file chan_sip.c.
References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_CALL_REJECTED, AST_CAUSE_CHAN_NOT_IMPLEMENTED, AST_CAUSE_CONGESTION, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_FACILITY_REJECTED, AST_CAUSE_FAILURE, AST_CAUSE_INVALID_NUMBER_FORMAT, AST_CAUSE_NO_ANSWER, AST_CAUSE_NO_ROUTE_DESTINATION, AST_CAUSE_NO_ROUTE_TRANSIT_NET, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_NORMAL_UNSPECIFIED, AST_CAUSE_NOTDEFINED, AST_CAUSE_NUMBER_CHANGED, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNALLOCATED, AST_CAUSE_UNREGISTERED, AST_CAUSE_USER_BUSY, and ast_debug.
Referenced by sip_hangup().
06427 { 06428 switch (cause) { 06429 case AST_CAUSE_UNALLOCATED: /* 1 */ 06430 case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */ 06431 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */ 06432 return "404 Not Found"; 06433 case AST_CAUSE_CONGESTION: /* 34 */ 06434 case AST_CAUSE_SWITCH_CONGESTION: /* 42 */ 06435 return "503 Service Unavailable"; 06436 case AST_CAUSE_NO_USER_RESPONSE: /* 18 */ 06437 return "408 Request Timeout"; 06438 case AST_CAUSE_NO_ANSWER: /* 19 */ 06439 case AST_CAUSE_UNREGISTERED: /* 20 */ 06440 return "480 Temporarily unavailable"; 06441 case AST_CAUSE_CALL_REJECTED: /* 21 */ 06442 return "403 Forbidden"; 06443 case AST_CAUSE_NUMBER_CHANGED: /* 22 */ 06444 return "410 Gone"; 06445 case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */ 06446 return "480 Temporarily unavailable"; 06447 case AST_CAUSE_INVALID_NUMBER_FORMAT: 06448 return "484 Address incomplete"; 06449 case AST_CAUSE_USER_BUSY: 06450 return "486 Busy here"; 06451 case AST_CAUSE_FAILURE: 06452 return "500 Server internal failure"; 06453 case AST_CAUSE_FACILITY_REJECTED: /* 29 */ 06454 return "501 Not Implemented"; 06455 case AST_CAUSE_CHAN_NOT_IMPLEMENTED: 06456 return "503 Service Unavailable"; 06457 /* Used in chan_iax2 */ 06458 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 06459 return "502 Bad Gateway"; 06460 case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */ 06461 return "488 Not Acceptable Here"; 06462 06463 case AST_CAUSE_NOTDEFINED: 06464 default: 06465 ast_debug(1, "AST hangup cause %d (no match found in SIP)\n", cause); 06466 return NULL; 06467 } 06468 06469 /* Never reached */ 06470 return 0; 06471 }
| int hangup_sip2cause | ( | int | cause | ) |
Convert SIP hangup causes to Asterisk hangup causes.
Definition at line 6304 of file chan_sip.c.
References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CALL_REJECTED, AST_CAUSE_CONGESTION, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_FACILITY_REJECTED, AST_CAUSE_FAILURE, AST_CAUSE_INTERWORKING, AST_CAUSE_INVALID_NUMBER_FORMAT, AST_CAUSE_NO_ANSWER, AST_CAUSE_NO_ROUTE_DESTINATION, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_NORMAL, AST_CAUSE_NORMAL_TEMPORARY_FAILURE, AST_CAUSE_NUMBER_CHANGED, AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE, AST_CAUSE_UNALLOCATED, and AST_CAUSE_USER_BUSY.
Referenced by __transmit_response(), handle_response(), and handle_response_invite().
06305 { 06306 /* Possible values taken from causes.h */ 06307 06308 switch(cause) { 06309 case 401: /* Unauthorized */ 06310 return AST_CAUSE_CALL_REJECTED; 06311 case 403: /* Not found */ 06312 return AST_CAUSE_CALL_REJECTED; 06313 case 404: /* Not found */ 06314 return AST_CAUSE_UNALLOCATED; 06315 case 405: /* Method not allowed */ 06316 return AST_CAUSE_INTERWORKING; 06317 case 407: /* Proxy authentication required */ 06318 return AST_CAUSE_CALL_REJECTED; 06319 case 408: /* No reaction */ 06320 return AST_CAUSE_NO_USER_RESPONSE; 06321 case 409: /* Conflict */ 06322 return AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 06323 case 410: /* Gone */ 06324 return AST_CAUSE_NUMBER_CHANGED; 06325 case 411: /* Length required */ 06326 return AST_CAUSE_INTERWORKING; 06327 case 413: /* Request entity too large */ 06328 return AST_CAUSE_INTERWORKING; 06329 case 414: /* Request URI too large */ 06330 return AST_CAUSE_INTERWORKING; 06331 case 415: /* Unsupported media type */ 06332 return AST_CAUSE_INTERWORKING; 06333 case 420: /* Bad extension */ 06334 return AST_CAUSE_NO_ROUTE_DESTINATION; 06335 case 480: /* No answer */ 06336 return AST_CAUSE_NO_ANSWER; 06337 case 481: /* No answer */ 06338 return AST_CAUSE_INTERWORKING; 06339 case 482: /* Loop detected */ 06340 return AST_CAUSE_INTERWORKING; 06341 case 483: /* Too many hops */ 06342 return AST_CAUSE_NO_ANSWER; 06343 case 484: /* Address incomplete */ 06344 return AST_CAUSE_INVALID_NUMBER_FORMAT; 06345 case 485: /* Ambiguous */ 06346 return AST_CAUSE_UNALLOCATED; 06347 case 486: /* Busy everywhere */ 06348 return AST_CAUSE_BUSY; 06349 case 487: /* Request terminated */ 06350 return AST_CAUSE_INTERWORKING; 06351 case 488: /* No codecs approved */ 06352 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 06353 case 491: /* Request pending */ 06354 return AST_CAUSE_INTERWORKING; 06355 case 493: /* Undecipherable */ 06356 return AST_CAUSE_INTERWORKING; 06357 case 500: /* Server internal failure */ 06358 return AST_CAUSE_FAILURE; 06359 case 501: /* Call rejected */ 06360 return AST_CAUSE_FACILITY_REJECTED; 06361 case 502: 06362 return AST_CAUSE_DESTINATION_OUT_OF_ORDER; 06363 case 503: /* Service unavailable */ 06364 return AST_CAUSE_CONGESTION; 06365 case 504: /* Gateway timeout */ 06366 return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE; 06367 case 505: /* SIP version not supported */ 06368 return AST_CAUSE_INTERWORKING; 06369 case 600: /* Busy everywhere */ 06370 return AST_CAUSE_USER_BUSY; 06371 case 603: /* Decline */ 06372 return AST_CAUSE_CALL_REJECTED; 06373 case 604: /* Does not exist anywhere */ 06374 return AST_CAUSE_UNALLOCATED; 06375 case 606: /* Not acceptable */ 06376 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 06377 default: 06378 if (cause < 500 && cause >= 400) { 06379 /* 4xx class error that is unknown - someting wrong with our request */ 06380 return AST_CAUSE_INTERWORKING; 06381 } else if (cause < 600 && cause >= 500) { 06382 /* 5xx class error - problem in the remote end */ 06383 return AST_CAUSE_CONGESTION; 06384 } else if (cause < 700 && cause >= 600) { 06385 /* 6xx - global errors in the 4xx class */ 06386 return AST_CAUSE_INTERWORKING; 06387 } 06388 return AST_CAUSE_NORMAL; 06389 } 06390 /* Never reached */ 06391 return 0; 06392 }
| static int init_req | ( | struct sip_request * | req, | |
| int | sipmethod, | |||
| const char * | recip | |||
| ) | [static] |
Initialize SIP request.
Definition at line 10518 of file chan_sip.c.
References ast_free, ast_str_create(), ast_str_set(), sip_methods, and cfsip_methods::text.
Referenced by initreqprep(), reqprep(), and transmit_register().
10519 { 10520 /* Initialize a request */ 10521 memset(req, 0, sizeof(*req)); 10522 if (!(req->data = ast_str_create(SIP_MIN_PACKET))) 10523 goto e_return; 10524 if (!(req->content = ast_str_create(SIP_MIN_PACKET))) 10525 goto e_free_data; 10526 req->method = sipmethod; 10527 req->header[0] = 0; 10528 ast_str_set(&req->data, 0, "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip); 10529 req->headers++; 10530 return 0; 10531 10532 e_free_data: 10533 ast_free(req->data); 10534 req->data = NULL; 10535 e_return: 10536 return -1; 10537 }
| static int init_resp | ( | struct sip_request * | resp, | |
| const char * | msg | |||
| ) | [static] |
Initialize SIP response, based on SIP request.
Definition at line 10496 of file chan_sip.c.
References ast_free, ast_str_create(), and ast_str_set().
Referenced by respprep().
10497 { 10498 /* Initialize a response */ 10499 memset(resp, 0, sizeof(*resp)); 10500 resp->method = SIP_RESPONSE; 10501 if (!(resp->data = ast_str_create(SIP_MIN_PACKET))) 10502 goto e_return; 10503 if (!(resp->content = ast_str_create(SIP_MIN_PACKET))) 10504 goto e_free_data; 10505 resp->header[0] = 0; 10506 ast_str_set(&resp->data, 0, "SIP/2.0 %s\r\n", msg); 10507 resp->headers++; 10508 return 0; 10509 10510 e_free_data: 10511 ast_free(resp->data); 10512 resp->data = NULL; 10513 e_return: 10514 return -1; 10515 }
| static int initialize_escs | ( | void | ) | [static] |
Definition at line 1056 of file chan_sip.c.
References ao2_container_alloc, ARRAY_LEN, esc_cmp_fn(), esc_hash_fn(), and event_state_compositors.
Referenced by load_module().
01057 { 01058 int i, res = 0; 01059 for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) { 01060 if (!((event_state_compositors[i].compositor) = 01061 ao2_container_alloc(ESC_MAX_BUCKETS, esc_hash_fn, esc_cmp_fn))) { 01062 res = -1; 01063 } 01064 } 01065 return res; 01066 }
| static void initialize_initreq | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Initialize the initital request packet in the pvt structure. This packet is used for creating replies and future requests in a dialog.
Definition at line 3197 of file chan_sip.c.
References ast_debug, ast_verbose, copy_request(), parse_request(), sip_methods, and cfsip_methods::text.
Referenced by transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_reinvite_with_sdp(), and update_connectedline().
03198 { 03199 if (p->initreq.headers) { 03200 ast_debug(1, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid); 03201 } else { 03202 ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid); 03203 } 03204 /* Use this as the basis */ 03205 copy_request(&p->initreq, req); 03206 parse_request(&p->initreq); 03207 if (req->debug) { 03208 ast_verbose("Initreq: %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 03209 } 03210 }
| static int initialize_udptl | ( | struct sip_pvt * | p | ) | [static] |
Definition at line 7091 of file chan_sip.c.
References ast_channel_set_fd(), ast_clear_flag, ast_debug, ast_log(), AST_LOG_WARNING, ast_test_flag, ast_udptl_fd(), ast_udptl_new_with_bindaddr(), ast_udptl_setnat(), ast_udptl_setqos(), bindaddr, and set_t38_capabilities().
Referenced by process_sdp(), process_sdp_a_image(), and sip_indicate().
07092 { 07093 int natflags = ast_test_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP); 07094 07095 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) { 07096 return 1; 07097 } 07098 07099 /* If we've already initialized T38, don't take any further action */ 07100 if (p->udptl) { 07101 return 0; 07102 } 07103 07104 /* T38 can be supported by this dialog, create it and set the derived properties */ 07105 if ((p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, &bindaddr))) { 07106 if (p->owner) { 07107 ast_channel_set_fd(p->owner, 5, ast_udptl_fd(p->udptl)); 07108 } 07109 07110 ast_udptl_setqos(p->udptl, global_tos_audio, global_cos_audio); 07111 p->t38_maxdatagram = p->relatedpeer ? p->relatedpeer->t38_maxdatagram : global_t38_maxdatagram; 07112 set_t38_capabilities(p); 07113 07114 ast_debug(1, "Setting NAT on UDPTL to %s\n", natflags ? "On" : "Off"); 07115 ast_udptl_setnat(p->udptl, natflags); 07116 } else { 07117 ast_log(AST_LOG_WARNING, "UDPTL creation failed - disabling T38 for this dialog\n"); 07118 ast_clear_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT); 07119 return 1; 07120 } 07121 07122 return 0; 07123 }
| static void initreqprep | ( | struct sip_request * | req, | |
| struct sip_pvt * | p, | |||
| int | sipmethod, | |||
| const char *const | explicit_uri | |||
| ) | [static] |
Initiate new SIP request to peer/user.
Definition at line 12345 of file chan_sip.c.
References add_header(), add_header_max_forwards(), add_route(), ast_copy_string(), AST_DIGIT_ANYNUM, ast_escape_quoted(), ast_party_id_presentation(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, ast_sockaddr_port, ast_sockaddr_stringify_host_remote(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_set(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_encode(), build_contact(), exten, init_req(), ourport, sip_cfg, sip_methods, sip_standard_port(), and cfsip_methods::text.
Referenced by transmit_invite(), and transmit_notify_with_mwi().
12346 { 12347 struct ast_str *invite = ast_str_alloca(256); 12348 char from[256]; 12349 char to[256]; 12350 char tmp_n[SIPBUFSIZE/2]; /* build a local copy of 'n' if needed */ 12351 char tmp_l[SIPBUFSIZE/2]; /* build a local copy of 'l' if needed */ 12352 const char *l = NULL; /* XXX what is this, exactly ? */ 12353 const char *n = NULL; /* XXX what is this, exactly ? */ 12354 const char *d = NULL; /* domain in from header */ 12355 const char *urioptions = ""; 12356 int ourport; 12357 12358 if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) { 12359 const char *s = p->username; /* being a string field, cannot be NULL */ 12360 12361 /* Test p->username against allowed characters in AST_DIGIT_ANY 12362 If it matches the allowed characters list, then sipuser = ";user=phone" 12363 If not, then sipuser = "" 12364 */ 12365 /* + is allowed in first position in a tel: uri */ 12366 if (*s == '+') 12367 s++; 12368 for (; *s; s++) { 12369 if (!strchr(AST_DIGIT_ANYNUM, *s) ) 12370 break; 12371 } 12372 /* If we have only digits, add ;user=phone to the uri */ 12373 if (!*s) 12374 urioptions = ";user=phone"; 12375 } 12376 12377 12378 snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text); 12379 12380 if (ast_strlen_zero(p->fromdomain)) { 12381 d = ast_sockaddr_stringify_host_remote(&p->ourip); 12382 } 12383 if (p->owner) { 12384 if ((ast_party_id_presentation(&p->owner->connected.id) & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED) { 12385 l = p->owner->connected.id.number.valid ? p->owner->connected.id.number.str : NULL; 12386 n = p->owner->connected.id.name.valid ? p->owner->connected.id.name.str : NULL; 12387 } else { 12388 /* Even if we are using RPID, we shouldn't leak information in the From if the user wants 12389 * their callerid restricted */ 12390 l = "anonymous"; 12391 n = CALLERID_UNKNOWN; 12392 d = FROMDOMAIN_INVALID; 12393 } 12394 } 12395 12396 /* Hey, it's a NOTIFY! See if they've configured a mwi_from. 12397 * XXX Right now, this logic works because the only place that mwi_from 12398 * is set on the sip_pvt is in sip_send_mwi_to_peer. If things changed, then 12399 * we might end up putting the mwi_from setting into other types of NOTIFY 12400 * messages as well. 12401 */ 12402 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->mwi_from)) { 12403 l = p->mwi_from; 12404 } 12405 12406 if (ast_strlen_zero(l)) 12407 l = default_callerid; 12408 if (ast_strlen_zero(n)) 12409 n = l; 12410 /* Allow user to be overridden */ 12411 if (!ast_strlen_zero(p->fromuser)) 12412 l = p->fromuser; 12413 else /* Save for any further attempts */ 12414 ast_string_field_set(p, fromuser, l); 12415 12416 /* Allow user to be overridden */ 12417 if (!ast_strlen_zero(p->fromname)) 12418 n = p->fromname; 12419 else /* Save for any further attempts */ 12420 ast_string_field_set(p, fromname, n); 12421 12422 /* Allow domain to be overridden */ 12423 if (!ast_strlen_zero(p->fromdomain)) 12424 d = p->fromdomain; 12425 else /* Save for any further attempts */ 12426 ast_string_field_set(p, fromdomain, d); 12427 12428 ast_copy_string(tmp_l, l, sizeof(tmp_l)); 12429 if (sip_cfg.pedanticsipchecking) { 12430 ast_escape_quoted(n, tmp_n, sizeof(tmp_n)); 12431 n = tmp_n; 12432 ast_uri_encode(l, tmp_l, sizeof(tmp_l), 0); 12433 } 12434 12435 ourport = (p->fromdomainport && (p->fromdomainport != STANDARD_SIP_PORT)) ? p->fromdomainport : ast_sockaddr_port(&p->ourip); 12436 if (!sip_standard_port(p->socket.type, ourport)) { 12437 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%s", n, tmp_l, d, ourport, p->tag); 12438 } else { 12439 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, tmp_l, d, p->tag); 12440 } 12441 12442 if (!ast_strlen_zero(explicit_uri)) { 12443 ast_str_set(&invite, 0, "%s", explicit_uri); 12444 } else { 12445 /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */ 12446 if (!ast_strlen_zero(p->fullcontact)) { 12447 /* If we have full contact, trust it */ 12448 ast_str_append(&invite, 0, "%s", p->fullcontact); 12449 } else { 12450 /* Otherwise, use the username while waiting for registration */ 12451 ast_str_append(&invite, 0, "sip:"); 12452 if (!ast_strlen_zero(p->username)) { 12453 n = p->username; 12454 if (sip_cfg.pedanticsipchecking) { 12455 ast_uri_encode(n, tmp_n, sizeof(tmp_n), 0); 12456 n = tmp_n; 12457 } 12458 ast_str_append(&invite, 0, "%s@", n); 12459 } 12460 ast_str_append(&invite, 0, "%s", p->tohost); 12461 if (p->portinuri) { 12462 ast_str_append(&invite, 0, ":%d", ast_sockaddr_port(&p->sa)); 12463 } 12464 ast_str_append(&invite, 0, "%s", urioptions); 12465 } 12466 } 12467 12468 /* If custom URI options have been provided, append them */ 12469 if (p->options && !ast_strlen_zero(p->options->uri_options)) 12470 ast_str_append(&invite, 0, ";%s", p->options->uri_options); 12471 12472 /* This is the request URI, which is the next hop of the call 12473 which may or may not be the destination of the call 12474 */ 12475 ast_string_field_set(p, uri, ast_str_buffer(invite)); 12476 12477 if (!ast_strlen_zero(p->todnid)) { 12478 /*! \todo Need to add back the VXML URL here at some point, possibly use build_string for all this junk */ 12479 if (!strchr(p->todnid, '@')) { 12480 /* We have no domain in the dnid */ 12481 snprintf(to, sizeof(to), "<sip:%s@%s>%s%s", p->todnid, p->tohost, ast_strlen_zero(p->theirtag) ? "" : ";tag=", p->theirtag); 12482 } else { 12483 snprintf(to, sizeof(to), "<sip:%s>%s%s", p->todnid, ast_strlen_zero(p->theirtag) ? "" : ";tag=", p->theirtag); 12484 } 12485 } else { 12486 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 12487 /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ 12488 snprintf(to, sizeof(to), "<%s%s>;tag=%s", (strncasecmp(p->uri, "sip:", 4) ? "sip:" : ""), p->uri, p->theirtag); 12489 } else if (p->options && p->options->vxml_url) { 12490 /* If there is a VXML URL append it to the SIP URL */ 12491 snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); 12492 } else { 12493 snprintf(to, sizeof(to), "<%s>", p->uri); 12494 } 12495 } 12496 12497 init_req(req, sipmethod, p->uri); 12498 /* now tmp_n is available so reuse it to build the CSeq */ 12499 snprintf(tmp_n, sizeof(tmp_n), "%u %s", ++p->ocseq, sip_methods[sipmethod].text); 12500 12501 add_header(req, "Via", p->via); 12502 add_header_max_forwards(p, req); 12503 /* This will be a no-op most of the time. However, under certain circumstances, 12504 * NOTIFY messages will use this function for preparing the request and should 12505 * have Route headers present. 12506 */ 12507 add_route(req, p->route); 12508 12509 add_header(req, "From", from); 12510 add_header(req, "To", to); 12511 ast_string_field_set(p, exten, l); 12512 build_contact(p); 12513 add_header(req, "Contact", p->our_contact); 12514 add_header(req, "Call-ID", p->callid); 12515 add_header(req, "CSeq", tmp_n); 12516 if (!ast_strlen_zero(global_useragent)) { 12517 add_header(req, "User-Agent", global_useragent); 12518 } 12519 }
| static const char * insecure2str | ( | int | mode | ) | [static] |
Convert Insecure setting to printable string.
Definition at line 17590 of file chan_sip.c.
References map_x_s().
Referenced by _sip_show_peer().
17591 { 17592 return map_x_s(insecurestr, mode, "<error>"); 17593 }
| static int interpret_t38_parameters | ( | struct sip_pvt * | p, | |
| const struct ast_control_t38_parameters * | parameters | |||
| ) | [static] |
Helper function which updates T.38 capability information and triggers a reinvite.
Definition at line 6997 of file chan_sip.c.
References AST_CONTROL_T38_PARAMETERS, ast_queue_control_data(), AST_SCHED_DEL_UNREF, ast_set_flag, AST_T38_NEGOTIATED, AST_T38_REFUSED, AST_T38_REQUEST_NEGOTIATE, AST_T38_REQUEST_PARMS, AST_T38_REQUEST_TERMINATE, AST_T38_TERMINATED, ast_test_flag, ast_udptl_get_far_max_ifp(), ast_udptl_set_local_max_ifp(), change_t38_state(), FALSE, ast_control_t38_parameters::fill_bit_removal, ast_control_t38_parameters::max_ifp, MIN, ast_control_t38_parameters::request_response, transmit_reinvite_with_sdp(), transmit_response_reliable(), transmit_response_with_t38_sdp(), and TRUE.
Referenced by sip_indicate().
06998 { 06999 int res = 0; 07000 07001 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) || !p->udptl) { 07002 return -1; 07003 } 07004 switch (parameters->request_response) { 07005 case AST_T38_NEGOTIATED: 07006 case AST_T38_REQUEST_NEGOTIATE: /* Request T38 */ 07007 /* Negotiation can not take place without a valid max_ifp value. */ 07008 if (!parameters->max_ifp) { 07009 change_t38_state(p, T38_DISABLED); 07010 if (p->t38.state == T38_PEER_REINVITE) { 07011 AST_SCHED_DEL_UNREF(sched, p->t38id, dialog_unref(p, "when you delete the t38id sched, you should dec the refcount for the stored dialog ptr")); 07012 transmit_response_reliable(p, "488 Not acceptable here", &p->initreq); 07013 } 07014 break; 07015 } else if (p->t38.state == T38_PEER_REINVITE) { 07016 AST_SCHED_DEL_UNREF(sched, p->t38id, dialog_unref(p, "when you delete the t38id sched, you should dec the refcount for the stored dialog ptr")); 07017 p->t38.our_parms = *parameters; 07018 /* modify our parameters to conform to the peer's parameters, 07019 * based on the rules in the ITU T.38 recommendation 07020 */ 07021 if (!p->t38.their_parms.fill_bit_removal) { 07022 p->t38.our_parms.fill_bit_removal = FALSE; 07023 } 07024 if (!p->t38.their_parms.transcoding_mmr) { 07025 p->t38.our_parms.transcoding_mmr = FALSE; 07026 } 07027 if (!p->t38.their_parms.transcoding_jbig) { 07028 p->t38.our_parms.transcoding_jbig = FALSE; 07029 } 07030 p->t38.our_parms.version = MIN(p->t38.our_parms.version, p->t38.their_parms.version); 07031 p->t38.our_parms.rate_management = p->t38.their_parms.rate_management; 07032 ast_udptl_set_local_max_ifp(p->udptl, p->t38.our_parms.max_ifp); 07033 change_t38_state(p, T38_ENABLED); 07034 transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 07035 } else if (p->t38.state != T38_ENABLED) { 07036 p->t38.our_parms = *parameters; 07037 ast_udptl_set_local_max_ifp(p->udptl, p->t38.our_parms.max_ifp); 07038 change_t38_state(p, T38_LOCAL_REINVITE); 07039 if (!p->pendinginvite) { 07040 transmit_reinvite_with_sdp(p, TRUE, FALSE); 07041 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 07042 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 07043 } 07044 } 07045 break; 07046 case AST_T38_TERMINATED: 07047 case AST_T38_REFUSED: 07048 case AST_T38_REQUEST_TERMINATE: /* Shutdown T38 */ 07049 if (p->t38.state == T38_PEER_REINVITE) { 07050 AST_SCHED_DEL_UNREF(sched, p->t38id, dialog_unref(p, "when you delete the t38id sched, you should dec the refcount for the stored dialog ptr")); 07051 change_t38_state(p, T38_DISABLED); 07052 transmit_response_reliable(p, "488 Not acceptable here", &p->initreq); 07053 } else if (p->t38.state == T38_ENABLED) 07054 transmit_reinvite_with_sdp(p, FALSE, FALSE); 07055 break; 07056 case AST_T38_REQUEST_PARMS: { /* Application wants remote's parameters re-sent */ 07057 struct ast_control_t38_parameters parameters = p->t38.their_parms; 07058 07059 if (p->t38.state == T38_PEER_REINVITE) { 07060 AST_SCHED_DEL_UNREF(sched, p->t38id, dialog_unref(p, "when you delete the t38id sched, you should dec the refcount for the stored dialog ptr")); 07061 parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl); 07062 parameters.request_response = AST_T38_REQUEST_NEGOTIATE; 07063 if (p->owner) { 07064 ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, ¶meters, sizeof(parameters)); 07065 } 07066 /* we need to return a positive value here, so that applications that 07067 * send this request can determine conclusively whether it was accepted or not... 07068 * older versions of chan_sip would just silently accept it and return zero. 07069 */ 07070 res = AST_T38_REQUEST_PARMS; 07071 } 07072 break; 07073 } 07074 default: 07075 res = -1; 07076 break; 07077 } 07078 07079 return res; 07080 }
| static int is_method_allowed | ( | unsigned int * | allowed_methods, | |
| enum sipmethod | method | |||
| ) | [static] |
Check if method is allowed for a device or a dialog.
Definition at line 8658 of file chan_sip.c.
Referenced by sip_sendtext(), and update_connectedline().
| static void list_route | ( | struct sip_route * | route | ) | [static] |
List all routes - mostly for debugging.
Definition at line 14687 of file chan_sip.c.
References ast_verbose.
Referenced by build_route().
14688 { 14689 if (!route) { 14690 ast_verbose("list_route: no route\n"); 14691 } else { 14692 for (;route; route = route->next) 14693 ast_verbose("list_route: hop: <%s>\n", route->hop); 14694 } 14695 }
| static int load_module | ( | void | ) | [static] |
PBX load module - initialization.
Definition at line 31814 of file chan_sip.c.
References ao2_container_alloc, ao2_t_container_alloc, ao2_t_ref, ARRAY_LEN, ast_cc_agent_register(), ast_cc_monitor_register(), ast_channel_register(), ast_check_realtime(), ast_clear_flag, ast_cli_register_multiple(), ast_custom_function_register, ast_data_register_multiple, ast_log(), ast_manager_register_xml, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_realtime_require_field(), ast_register_application_xml, ast_rtp_glue_register, ast_string_field_set, AST_TEST_REGISTER, ast_udptl_proto_register(), ast_verbose, ASTOBJ_CONTAINER_INIT, BOGUS_PEER_MD5SECRET, CHANNEL_MODULE_LOAD, dialog_cmp_cb(), dialog_hash_cb(), EVENT_FLAG_REPORTING, EVENT_FLAG_SYSTEM, initialize_escs(), io_context_create(), io_context_destroy(), LOG_ERROR, manager_show_registry(), manager_sip_qualify_peer(), manager_sip_show_peer(), manager_sip_show_peers(), manager_sipnotify(), network_change_event_subscribe(), peer_cmp_cb(), peer_hash_cb(), peer_ipcmp_cb(), peer_iphash_cb(), regl, reload_config(), restart_monitor(), RQ_CHAR, RQ_INTEGER4, RQ_UINTEGER2, sched_context_create(), sched_context_destroy(), ast_channel_tech::send_digit_begin, SENTINEL, sip_addheader(), sip_dtmfmode(), sip_epa_register(), sip_is_xml_parsable(), sip_monitor_instance_cmp_fn(), sip_monitor_instance_hash_fn(), sip_poke_all_peers(), sip_register_tests(), sip_removeheader(), sip_reqresp_parser_init(), sip_send_all_mwi_subscriptions(), sip_send_all_registers(), sip_tech_info, submwil, temp_peer(), threadt_cmp_cb(), and threadt_hash_cb().
31815 { 31816 ast_verbose("SIP channel loading...\n"); 31817 31818 /* the fact that ao2_containers can't resize automatically is a major worry! */ 31819 /* if the number of objects gets above MAX_XXX_BUCKETS, things will slow down */ 31820 peers = ao2_t_container_alloc(HASH_PEER_SIZE, peer_hash_cb, peer_cmp_cb, "allocate peers"); 31821 peers_by_ip = ao2_t_container_alloc(HASH_PEER_SIZE, peer_iphash_cb, peer_ipcmp_cb, "allocate peers_by_ip"); 31822 dialogs = ao2_t_container_alloc(HASH_DIALOG_SIZE, dialog_hash_cb, dialog_cmp_cb, "allocate dialogs"); 31823 dialogs_to_destroy = ao2_t_container_alloc(1, NULL, NULL, "allocate dialogs_to_destroy"); 31824 threadt = ao2_t_container_alloc(HASH_DIALOG_SIZE, threadt_hash_cb, threadt_cmp_cb, "allocate threadt table"); 31825 if (!peers || !peers_by_ip || !dialogs || !dialogs_to_destroy || !threadt) { 31826 ast_log(LOG_ERROR, "Unable to create primary SIP container(s)\n"); 31827 return AST_MODULE_LOAD_FAILURE; 31828 } 31829 31830 ASTOBJ_CONTAINER_INIT(®l); /* Registry object list -- not searched for anything */ 31831 ASTOBJ_CONTAINER_INIT(&submwil); /* MWI subscription object list */ 31832 31833 if (!(sched = sched_context_create())) { 31834 ast_log(LOG_ERROR, "Unable to create scheduler context\n"); 31835 return AST_MODULE_LOAD_FAILURE; 31836 } 31837 31838 if (!(io = io_context_create())) { 31839 ast_log(LOG_ERROR, "Unable to create I/O context\n"); 31840 sched_context_destroy(sched); 31841 return AST_MODULE_LOAD_FAILURE; 31842 } 31843 31844 sip_reloadreason = CHANNEL_MODULE_LOAD; 31845 31846 can_parse_xml = sip_is_xml_parsable(); 31847 if (reload_config(sip_reloadreason)) { /* Load the configuration from sip.conf */ 31848 return AST_MODULE_LOAD_DECLINE; 31849 } 31850 31851 /* Initialize bogus peer. Can be done first after reload_config() */ 31852 if (!(bogus_peer = temp_peer("(bogus_peer)"))) { 31853 ast_log(LOG_ERROR, "Unable to create bogus_peer for authentication\n"); 31854 io_context_destroy(io); 31855 sched_context_destroy(sched); 31856 return AST_MODULE_LOAD_FAILURE; 31857 } 31858 /* Make sure the auth will always fail. */ 31859 ast_string_field_set(bogus_peer, md5secret, BOGUS_PEER_MD5SECRET); 31860 ast_clear_flag(&bogus_peer->flags[0], SIP_INSECURE); 31861 31862 /* Prepare the version that does not require DTMF BEGIN frames. 31863 * We need to use tricks such as memcpy and casts because the variable 31864 * has const fields. 31865 */ 31866 memcpy(&sip_tech_info, &sip_tech, sizeof(sip_tech)); 31867 memset((void *) &sip_tech_info.send_digit_begin, 0, sizeof(sip_tech_info.send_digit_begin)); 31868 31869 /* Make sure we can register our sip channel type */ 31870 if (ast_channel_register(&sip_tech)) { 31871 ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n"); 31872 ao2_t_ref(bogus_peer, -1, "unref the bogus_peer"); 31873 io_context_destroy(io); 31874 sched_context_destroy(sched); 31875 return AST_MODULE_LOAD_FAILURE; 31876 } 31877 31878 #ifdef TEST_FRAMEWORK 31879 AST_TEST_REGISTER(test_sip_peers_get); 31880 AST_TEST_REGISTER(test_sip_mwi_subscribe_parse); 31881 AST_TEST_REGISTER(test_tcp_message_fragmentation); 31882 AST_TEST_REGISTER(get_in_brackets_const_test); 31883 #endif 31884 31885 /* Register AstData providers */ 31886 ast_data_register_multiple(sip_data_providers, ARRAY_LEN(sip_data_providers)); 31887 31888 /* Register all CLI functions for SIP */ 31889 ast_cli_register_multiple(cli_sip, ARRAY_LEN(cli_sip)); 31890 31891 /* Tell the UDPTL subdriver that we're here */ 31892 ast_udptl_proto_register(&sip_udptl); 31893 31894 /* Tell the RTP engine about our RTP glue */ 31895 ast_rtp_glue_register(&sip_rtp_glue); 31896 31897 /* Register dialplan applications */ 31898 ast_register_application_xml(app_dtmfmode, sip_dtmfmode); 31899 ast_register_application_xml(app_sipaddheader, sip_addheader); 31900 ast_register_application_xml(app_sipremoveheader, sip_removeheader); 31901 31902 /* Register dialplan functions */ 31903 ast_custom_function_register(&sip_header_function); 31904 ast_custom_function_register(&sippeer_function); 31905 ast_custom_function_register(&sipchaninfo_function); 31906 ast_custom_function_register(&checksipdomain_function); 31907 31908 /* Register manager commands */ 31909 ast_manager_register_xml("SIPpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_sip_show_peers); 31910 ast_manager_register_xml("SIPshowpeer", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_sip_show_peer); 31911 ast_manager_register_xml("SIPqualifypeer", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_sip_qualify_peer); 31912 ast_manager_register_xml("SIPshowregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_show_registry); 31913 ast_manager_register_xml("SIPnotify", EVENT_FLAG_SYSTEM, manager_sipnotify); 31914 sip_poke_all_peers(); 31915 sip_send_all_registers(); 31916 sip_send_all_mwi_subscriptions(); 31917 initialize_escs(); 31918 31919 if (sip_epa_register(&cc_epa_static_data)) { 31920 return AST_MODULE_LOAD_DECLINE; 31921 } 31922 31923 if (sip_reqresp_parser_init() == -1) { 31924 ast_log(LOG_ERROR, "Unable to initialize the SIP request and response parser\n"); 31925 return AST_MODULE_LOAD_DECLINE; 31926 } 31927 31928 if (can_parse_xml) { 31929 /* SIP CC agents require the ability to parse XML PIDF bodies 31930 * in incoming PUBLISH requests 31931 */ 31932 if (ast_cc_agent_register(&sip_cc_agent_callbacks)) { 31933 return AST_MODULE_LOAD_DECLINE; 31934 } 31935 } 31936 if (ast_cc_monitor_register(&sip_cc_monitor_callbacks)) { 31937 return AST_MODULE_LOAD_DECLINE; 31938 } 31939 if (!(sip_monitor_instances = ao2_container_alloc(37, sip_monitor_instance_hash_fn, sip_monitor_instance_cmp_fn))) { 31940 return AST_MODULE_LOAD_DECLINE; 31941 } 31942 31943 /* And start the monitor for the first time */ 31944 restart_monitor(); 31945 31946 ast_realtime_require_field(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", 31947 "name", RQ_CHAR, 10, 31948 "ipaddr", RQ_CHAR, INET6_ADDRSTRLEN - 1, 31949 "port", RQ_UINTEGER2, 5, 31950 "regseconds", RQ_INTEGER4, 11, 31951 "defaultuser", RQ_CHAR, 10, 31952 "fullcontact", RQ_CHAR, 35, 31953 "regserver", RQ_CHAR, 20, 31954 "useragent", RQ_CHAR, 20, 31955 "lastms", RQ_INTEGER4, 11, 31956 SENTINEL); 31957 31958 31959 sip_register_tests(); 31960 network_change_event_subscribe(); 31961 31962 return AST_MODULE_LOAD_SUCCESS; 31963 }
| static int local_attended_transfer | ( | struct sip_pvt * | transferer, | |
| struct sip_dual * | current, | |||
| struct sip_request * | req, | |||
| uint32_t | seqno, | |||
| int * | nounlock | |||
| ) | [static] |
Find all call legs and bridge transferee with target called from handle_request_refer.
If this function is successful, only the transferer pvt lock will remain on return. Setting nounlock indicates to handle_request_do() that the pvt's owner it locked does not require an unlock.
Definition at line 23898 of file chan_sip.c.
References ao2_t_ref, append_history, ast_alloca, ast_bridged_channel(), AST_CEL_ATTENDEDTRANSFER, ast_cel_report_event(), ast_channel_queue_connected_line_update(), ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_clear_flag, ast_connected_line_build_data(), AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, AST_CONTROL_READ_ACTION, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, ast_copy_string(), ast_debug, ast_do_masquerade(), AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO, ast_indicate(), ast_manager_event_multichan, ast_party_connected_line_copy(), ast_party_connected_line_free(), ast_party_connected_line_init(), ast_queue_control_data(), ast_set_flag, ast_state2str(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_streamfile(), ast_strlen_zero(), ast_waitstream(), attempt_transfer(), EVENT_FLAG_CALL, frame_size, get_sip_pvt_byid_locked(), pbx_builtin_getvar_helper(), sip_pvt_lock, sip_pvt_unlock, ast_party_connected_line::source, transmit_notify_with_sipfrag(), TRUE, and xfersound.
Referenced by handle_request_refer().
23899 { 23900 struct sip_dual target; /* Chan 1: Call from tranferer to Asterisk */ 23901 /* Chan 2: Call from Asterisk to target */ 23902 int res = 0; 23903 struct sip_pvt *targetcall_pvt; 23904 struct ast_party_connected_line connected_to_transferee; 23905 struct ast_party_connected_line connected_to_target; 23906 char transferer_linkedid[32]; 23907 struct ast_channel *chans[2]; 23908 23909 /* Check if the call ID of the replaces header does exist locally */ 23910 if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 23911 transferer->refer->replaces_callid_fromtag))) { 23912 if (transferer->refer->localtransfer) { 23913 /* We did not find the refered call. Sorry, can't accept then */ 23914 /* Let's fake a response from someone else in order 23915 to follow the standard */ 23916 transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE); 23917 append_history(transferer, "Xfer", "Refer failed"); 23918 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 23919 transferer->refer->status = REFER_FAILED; 23920 return -1; 23921 } 23922 /* Fall through for remote transfers that we did not find locally */ 23923 ast_debug(3, "SIP attended transfer: Not our call - generating INVITE with replaces\n"); 23924 return 0; 23925 } 23926 23927 /* Ok, we can accept this transfer */ 23928 append_history(transferer, "Xfer", "Refer accepted"); 23929 if (!targetcall_pvt->owner) { /* No active channel */ 23930 ast_debug(4, "SIP attended transfer: Error: No owner of target call\n"); 23931 /* Cancel transfer */ 23932 transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE); 23933 append_history(transferer, "Xfer", "Refer failed"); 23934 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 23935 transferer->refer->status = REFER_FAILED; 23936 sip_pvt_unlock(targetcall_pvt); 23937 if (targetcall_pvt) 23938 ao2_t_ref(targetcall_pvt, -1, "Drop targetcall_pvt pointer"); 23939 return -1; 23940 } 23941 23942 /* We have a channel, find the bridge */ 23943 target.chan1 = ast_channel_ref(targetcall_pvt->owner); /* Transferer to Asterisk */ 23944 target.chan2 = ast_bridged_channel(targetcall_pvt->owner); /* Asterisk to target */ 23945 if (target.chan2) { 23946 ast_channel_ref(target.chan2); 23947 } 23948 23949 if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) { 23950 /* Wrong state of new channel */ 23951 if (target.chan2) 23952 ast_debug(4, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state)); 23953 else if (target.chan1->_state != AST_STATE_RING) 23954 ast_debug(4, "SIP attended transfer: Error: No target channel\n"); 23955 else 23956 ast_debug(4, "SIP attended transfer: Attempting transfer in ringing state\n"); 23957 } 23958 23959 /* Transfer */ 23960 if (sipdebug) { 23961 if (current->chan2) /* We have two bridges */ 23962 ast_debug(4, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name); 23963 else /* One bridge, propably transfer of IVR/voicemail etc */ 23964 ast_debug(4, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name); 23965 } 23966 23967 ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 23968 23969 ast_copy_string(transferer_linkedid, transferer->owner->linkedid, sizeof(transferer_linkedid)); 23970 23971 /* Perform the transfer */ 23972 chans[0] = transferer->owner; 23973 chans[1] = target.chan1; 23974 ast_manager_event_multichan(EVENT_FLAG_CALL, "Transfer", 2, chans, 23975 "TransferMethod: SIP\r\n" 23976 "TransferType: Attended\r\n" 23977 "Channel: %s\r\n" 23978 "Uniqueid: %s\r\n" 23979 "SIP-Callid: %s\r\n" 23980 "TargetChannel: %s\r\n" 23981 "TargetUniqueid: %s\r\n", 23982 transferer->owner->name, 23983 transferer->owner->uniqueid, 23984 transferer->callid, 23985 target.chan1->name, 23986 target.chan1->uniqueid); 23987 ast_party_connected_line_init(&connected_to_transferee); 23988 ast_party_connected_line_init(&connected_to_target); 23989 /* No need to lock current->chan1 here since it was locked in sipsock_read */ 23990 ast_party_connected_line_copy(&connected_to_transferee, ¤t->chan1->connected); 23991 /* No need to lock target.chan1 here since it was locked in get_sip_pvt_byid_locked */ 23992 ast_party_connected_line_copy(&connected_to_target, &target.chan1->connected); 23993 connected_to_target.source = connected_to_transferee.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER; 23994 res = attempt_transfer(current, &target); 23995 if (res) { 23996 /* Failed transfer */ 23997 transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE); 23998 append_history(transferer, "Xfer", "Refer failed"); 23999 ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); 24000 /* if transfer failed, go ahead and unlock targetcall_pvt and it's owner channel */ 24001 sip_pvt_unlock(targetcall_pvt); 24002 ast_channel_unlock(target.chan1); 24003 } else { 24004 /* Transfer succeeded! */ 24005 const char *xfersound = pbx_builtin_getvar_helper(target.chan1, "ATTENDED_TRANSFER_COMPLETE_SOUND"); 24006 24007 /* target.chan1 was locked in get_sip_pvt_byid_locked, do not unlock target.chan1 before this */ 24008 ast_cel_report_event(target.chan1, AST_CEL_ATTENDEDTRANSFER, NULL, transferer_linkedid, target.chan2); 24009 24010 /* Tell transferer that we're done. */ 24011 transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE); 24012 append_history(transferer, "Xfer", "Refer succeeded"); 24013 transferer->refer->status = REFER_200OK; 24014 if (target.chan2 && !ast_strlen_zero(xfersound) && ast_streamfile(target.chan2, xfersound, target.chan2->language) >= 0) { 24015 ast_waitstream(target.chan2, ""); 24016 } 24017 24018 /* By forcing the masquerade, we know that target.chan1 and target.chan2 are bridged. We then 24019 * can queue connected line updates where they need to go. 24020 * 24021 * before a masquerade, all channel and pvt locks must be unlocked. Any recursive 24022 * channel locks held before this function invalidates channel container locking order. 24023 * Since we are unlocking both the pvt (transferer) and its owner channel (current.chan1) 24024 * it is possible for current.chan1 to be destroyed in the pbx thread. To prevent this 24025 * we must give c a reference before any unlocking takes place. 24026 */ 24027 24028 ast_channel_ref(current->chan1); 24029 ast_channel_unlock(current->chan1); /* current.chan1 is p->owner before the masq, it was locked by socket_read()*/ 24030 ast_channel_unlock(target.chan1); 24031 *nounlock = 1; /* we just unlocked the dialog's channel and have no plans of locking it again. */ 24032 sip_pvt_unlock(targetcall_pvt); 24033 sip_pvt_unlock(transferer); 24034 24035 ast_do_masquerade(target.chan1); 24036 24037 if (target.chan2) { 24038 ast_indicate(target.chan2, AST_CONTROL_UNHOLD); 24039 } 24040 24041 if (current->chan2 && current->chan2->_state == AST_STATE_RING) { 24042 ast_indicate(target.chan1, AST_CONTROL_RINGING); 24043 } 24044 24045 if (target.chan2) { 24046 ast_channel_queue_connected_line_update(target.chan1, &connected_to_transferee, NULL); 24047 ast_channel_queue_connected_line_update(target.chan2, &connected_to_target, NULL); 24048 } else { 24049 /* Since target.chan1 isn't actually connected to another channel, there is no way for us 24050 * to queue a frame so that its connected line status will be updated. 24051 * 24052 * Instead, we use the somewhat hackish approach of using a special control frame type that 24053 * instructs ast_read to perform a specific action. In this case, the frame we queue tells 24054 * ast_read to call the connected line interception macro configured for target.chan1. 24055 */ 24056 struct ast_control_read_action_payload *frame_payload; 24057 int payload_size; 24058 int frame_size; 24059 unsigned char connected_line_data[1024]; 24060 payload_size = ast_connected_line_build_data(connected_line_data, 24061 sizeof(connected_line_data), &connected_to_target, NULL); 24062 frame_size = payload_size + sizeof(*frame_payload); 24063 if (payload_size != -1) { 24064 frame_payload = ast_alloca(frame_size); 24065 frame_payload->payload_size = payload_size; 24066 memcpy(frame_payload->payload, connected_line_data, payload_size); 24067 frame_payload->action = AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO; 24068 ast_queue_control_data(target.chan1, AST_CONTROL_READ_ACTION, frame_payload, frame_size); 24069 } 24070 /* In addition to queueing the read action frame so that target.chan1's connected line info 24071 * will be updated, we also are going to queue a plain old connected line update on target.chan1. This 24072 * way, either Dial or Queue can apply this connected line update to the outgoing ringing channel. 24073 */ 24074 ast_channel_queue_connected_line_update(target.chan1, &connected_to_transferee, NULL); 24075 24076 } 24077 sip_pvt_lock(transferer); /* the transferer pvt is expected to remain locked on return */ 24078 24079 ast_channel_unref(current->chan1); 24080 } 24081 24082 /* at this point if the transfer is successful only the transferer pvt should be locked. */ 24083 ast_party_connected_line_free(&connected_to_target); 24084 ast_party_connected_line_free(&connected_to_transferee); 24085 ast_channel_unref(target.chan1); 24086 if (target.chan2) { 24087 ast_channel_unref(target.chan2); 24088 } 24089 if (targetcall_pvt) 24090 ao2_t_ref(targetcall_pvt, -1, "drop targetcall_pvt"); 24091 return 1; 24092 }
| static void lws2sws | ( | struct ast_str * | msgbuf | ) | [static] |
Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled.
Definition at line 8746 of file chan_sip.c.
References ast_str_strlen(), and len().
Referenced by handle_request_do(), and read_raw_content_length().
08747 { 08748 char *msgbuf = data->str; 08749 int len = ast_str_strlen(data); 08750 int h = 0, t = 0; 08751 int lws = 0; 08752 08753 for (; h < len;) { 08754 /* Eliminate all CRs */ 08755 if (msgbuf[h] == '\r') { 08756 h++; 08757 continue; 08758 } 08759 /* Check for end-of-line */ 08760 if (msgbuf[h] == '\n') { 08761 /* Check for end-of-message */ 08762 if (h + 1 == len) 08763 break; 08764 /* Check for a continuation line */ 08765 if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 08766 /* Merge continuation line */ 08767 h++; 08768 continue; 08769 } 08770 /* Propagate LF and start new line */ 08771 msgbuf[t++] = msgbuf[h++]; 08772 lws = 0; 08773 continue; 08774 } 08775 if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 08776 if (lws) { 08777 h++; 08778 continue; 08779 } 08780 msgbuf[t++] = msgbuf[h++]; 08781 lws = 1; 08782 continue; 08783 } 08784 msgbuf[t++] = msgbuf[h++]; 08785 if (lws) 08786 lws = 0; 08787 } 08788 msgbuf[t] = '\0'; 08789 data->used = t; 08790 }
| static void make_our_tag | ( | struct sip_pvt * | pvt | ) | [static] |
Make our SIP dialog tag.
Definition at line 7938 of file chan_sip.c.
References ast_random(), and ast_string_field_build.
Referenced by handle_request_invite(), handle_request_subscribe(), sip_alloc(), and transmit_response_using_temp().
07939 { 07940 ast_string_field_build(pvt, tag, "as%08lx", (unsigned long)ast_random()); 07941 }
| static int manager_show_registry | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Show SIP registrations in the manager API.
Definition at line 17187 of file chan_sip.c.
References ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_listack(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, regl, regstate2str(), S_OR, and total.
Referenced by load_module().
17188 { 17189 const char *id = astman_get_header(m, "ActionID"); 17190 char idtext[256] = ""; 17191 int total = 0; 17192 17193 if (!ast_strlen_zero(id)) 17194 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 17195 17196 astman_send_listack(s, m, "Registrations will follow", "start"); 17197 17198 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 17199 ASTOBJ_RDLOCK(iterator); 17200 astman_append(s, 17201 "Event: RegistryEntry\r\n" 17202 "%s" 17203 "Host: %s\r\n" 17204 "Port: %d\r\n" 17205 "Username: %s\r\n" 17206 "Domain: %s\r\n" 17207 "DomainPort: %d\r\n" 17208 "Refresh: %d\r\n" 17209 "State: %s\r\n" 17210 "RegistrationTime: %ld\r\n" 17211 "\r\n", 17212 idtext, 17213 iterator->hostname, 17214 iterator->portno ? iterator->portno : STANDARD_SIP_PORT, 17215 iterator->username, 17216 S_OR(iterator->regdomain,iterator->hostname), 17217 iterator->regdomainport ? iterator->regdomainport : STANDARD_SIP_PORT, 17218 iterator->refresh, 17219 regstate2str(iterator->regstate), 17220 (long) iterator->regtime.tv_sec); 17221 ASTOBJ_UNLOCK(iterator); 17222 total++; 17223 } while(0)); 17224 17225 astman_append(s, 17226 "Event: RegistrationsComplete\r\n" 17227 "EventList: Complete\r\n" 17228 "ListItems: %d\r\n" 17229 "%s" 17230 "\r\n", total, idtext); 17231 17232 return 0; 17233 }
| static int manager_sip_qualify_peer | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Qualify SIP peers in the manager API.
Definition at line 17997 of file chan_sip.c.
References _sip_qualify_peer(), ast_strlen_zero(), astman_append(), astman_get_header(), and astman_send_error().
Referenced by load_module().
17998 { 17999 const char *a[4]; 18000 const char *peer; 18001 18002 peer = astman_get_header(m, "Peer"); 18003 if (ast_strlen_zero(peer)) { 18004 astman_send_error(s, m, "Peer: <name> missing."); 18005 return 0; 18006 } 18007 a[0] = "sip"; 18008 a[1] = "qualify"; 18009 a[2] = "peer"; 18010 a[3] = peer; 18011 18012 _sip_qualify_peer(1, -1, s, m, 4, a); 18013 astman_append(s, "\r\n\r\n" ); 18014 return 0; 18015 }
| static int manager_sip_show_peer | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Show SIP peers in the manager API.
Definition at line 17938 of file chan_sip.c.
References _sip_show_peer(), ast_strlen_zero(), astman_append(), astman_get_header(), and astman_send_error().
Referenced by load_module().
17939 { 17940 const char *a[4]; 17941 const char *peer; 17942 17943 peer = astman_get_header(m, "Peer"); 17944 if (ast_strlen_zero(peer)) { 17945 astman_send_error(s, m, "Peer: <name> missing."); 17946 return 0; 17947 } 17948 a[0] = "sip"; 17949 a[1] = "show"; 17950 a[2] = "peer"; 17951 a[3] = peer; 17952 17953 _sip_show_peer(1, -1, s, m, 4, a); 17954 astman_append(s, "\r\n" ); 17955 return 0; 17956 }
| static int manager_sip_show_peers | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Show SIP peers in the manager API.
Definition at line 17237 of file chan_sip.c.
References _sip_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_listack(), and total.
Referenced by load_module().
17238 { 17239 const char *id = astman_get_header(m, "ActionID"); 17240 const char *a[] = {"sip", "show", "peers"}; 17241 char idtext[256] = ""; 17242 int total = 0; 17243 17244 if (!ast_strlen_zero(id)) 17245 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 17246 17247 astman_send_listack(s, m, "Peer status list will follow", "start"); 17248 /* List the peers in separate manager events */ 17249 _sip_show_peers(-1, &total, s, m, 3, a); 17250 /* Send final confirmation */ 17251 astman_append(s, 17252 "Event: PeerlistComplete\r\n" 17253 "EventList: Complete\r\n" 17254 "ListItems: %d\r\n" 17255 "%s" 17256 "\r\n", total, idtext); 17257 return 0; 17258 }
| static int manager_sipnotify | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 13406 of file chan_sip.c.
References ast_log(), ast_set_flag, ast_str_append(), ast_str_strlen(), ast_strlen_zero(), ast_variable_new(), ast_variables_destroy(), astman_get_header(), astman_get_variables_order(), astman_send_ack(), astman_send_error(), create_addr(), dialog_unlink_all(), LOG_WARNING, ast_variable::name, ast_variable::next, ORDER_NATURAL, sip_alloc(), sip_notify_allocate(), sip_scheddestroy(), transmit_invite(), ast_variable::value, and var.
Referenced by load_module().
13407 { 13408 const char *channame = astman_get_header(m, "Channel"); 13409 struct ast_variable *vars = astman_get_variables_order(m, ORDER_NATURAL); 13410 struct sip_pvt *p; 13411 struct ast_variable *header, *var; 13412 13413 if (ast_strlen_zero(channame)) { 13414 astman_send_error(s, m, "SIPNotify requires a channel name"); 13415 return 0; 13416 } 13417 13418 if (!strncasecmp(channame, "sip/", 4)) { 13419 channame += 4; 13420 } 13421 13422 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) { 13423 astman_send_error(s, m, "Unable to build sip pvt data for notify (memory/socket error)"); 13424 return 0; 13425 } 13426 13427 if (create_addr(p, channame, NULL, 0)) { 13428 /* Maybe they're not registered, etc. */ 13429 dialog_unlink_all(p); 13430 dialog_unref(p, "unref dialog inside for loop" ); 13431 /* sip_destroy(p); */ 13432 astman_send_error(s, m, "Could not create address"); 13433 return 0; 13434 } 13435 13436 /* Notify is outgoing call */ 13437 ast_set_flag(&p->flags[0], SIP_OUTGOING); 13438 sip_notify_allocate(p); 13439 13440 p->notify->headers = header = ast_variable_new("Subscription-State", "terminated", ""); 13441 13442 for (var = vars; var; var = var->next) { 13443 if (!strcasecmp(var->name, "Content")) { 13444 if (ast_str_strlen(p->notify->content)) 13445 ast_str_append(&p->notify->content, 0, "\r\n"); 13446 ast_str_append(&p->notify->content, 0, "%s", var->value); 13447 } else if (!strcasecmp(var->name, "Content-Length")) { 13448 ast_log(LOG_WARNING, "it is not necessary to specify Content-Length, ignoring\n"); 13449 } else { 13450 header->next = ast_variable_new(var->name, var->value, ""); 13451 header = header->next; 13452 } 13453 } 13454 13455 sip_scheddestroy(p, SIP_TRANS_TIMEOUT); 13456 transmit_invite(p, SIP_NOTIFY, 0, 2, NULL); 13457 dialog_unref(p, "bump down the count of p since we're done with it."); 13458 13459 astman_send_ack(s, m, "Notify Sent"); 13460 ast_variables_destroy(vars); 13461 return 0; 13462 }
| static int map_s_x | ( | const struct _map_x_s * | table, | |
| const char * | s, | |||
| int | errorvalue | |||
| ) | [static] |
map from a string to an integer value, case insensitive. If no match is found, return errorvalue.
Definition at line 2261 of file chan_sip.c.
Referenced by str2dtmfmode(), str2stmode(), and str2strefresherparam().
02262 { 02263 const struct _map_x_s *cur; 02264 02265 for (cur = table; cur->s; cur++) 02266 if (!strcasecmp(cur->s, s)) 02267 return cur->x; 02268 return errorvalue; 02269 }
| static const char* map_x_s | ( | const struct _map_x_s * | table, | |
| int | x, | |||
| const char * | errorstring | |||
| ) | [static] |
map from an integer value to a string. If no match is found, return errorstring
Definition at line 2248 of file chan_sip.c.
Referenced by allowoverlap2str(), dtmfmode2str(), faxec2str(), insecure2str(), referstatus2str(), regstate2str(), stmode2str(), strefresher2str(), strefresherparam2str(), and trust_id_outbound2str().
02249 { 02250 const struct _map_x_s *cur; 02251 02252 for (cur = table; cur->s; cur++) 02253 if (cur->x == x) 02254 return cur->s; 02255 return errorstring; 02256 }
| static void mark_method_allowed | ( | unsigned int * | allowed_methods, | |
| enum sipmethod | method | |||
| ) | [static] |
Definition at line 8647 of file chan_sip.c.
Referenced by handle_response(), handle_response_info(), handle_response_message(), mark_parsed_methods(), and set_pvt_allowed_methods().
| static void mark_method_unallowed | ( | unsigned int * | allowed_methods, | |
| enum sipmethod | method | |||
| ) | [static] |
Definition at line 8652 of file chan_sip.c.
Referenced by handle_response(), handle_response_info(), handle_response_message(), and handle_response_publish().
| static void mark_parsed_methods | ( | unsigned int * | methods, | |
| char * | methods_str | |||
| ) | [static] |
Definition at line 8663 of file chan_sip.c.
References ast_skip_blanks(), ast_strlen_zero(), find_sip_method(), and mark_method_allowed().
Referenced by build_peer(), parse_allowed_methods(), and reload_config().
08664 { 08665 char *method; 08666 for (method = strsep(&methods_str, ","); !ast_strlen_zero(method); method = strsep(&methods_str, ",")) { 08667 int id = find_sip_method(ast_skip_blanks(method)); 08668 if (id == SIP_UNKNOWN) { 08669 continue; 08670 } 08671 mark_method_allowed(methods, id); 08672 } 08673 }
| static int match_and_cleanup_peer_sched | ( | void * | peerobj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 3011 of file chan_sip.c.
References ast_dnsmgr_release(), CMP_MATCH, peer_sched_cleanup(), SIP_PEERS_ALL, and unref_peer().
Referenced by unlink_peers_from_tables().
03012 { 03013 struct sip_peer *peer = peerobj; 03014 peer_unlink_flag_t which = *(peer_unlink_flag_t *)arg; 03015 03016 if (which == SIP_PEERS_ALL || peer->the_mark) { 03017 peer_sched_cleanup(peer); 03018 if (peer->dnsmgr) { 03019 ast_dnsmgr_release(peer->dnsmgr); 03020 peer->dnsmgr = NULL; 03021 unref_peer(peer, "Release peer from dnsmgr"); 03022 } 03023 return CMP_MATCH; 03024 } 03025 return 0; 03026 }
| static enum match_req_res match_req_to_dialog | ( | struct sip_pvt * | sip_pvt_ptr, | |
| struct match_req_args * | arg | |||
| ) | [static] |
Definition at line 8184 of file chan_sip.c.
References ast_strlen_zero(), ast_test_flag, match_req_args::authentication_present, match_req_args::callid, match_req_args::fromtag, match_req_args::method, match_req_args::ruri, match_req_args::seqno, SIP_REQ_LOOP_DETECTED, SIP_REQ_MATCH, SIP_REQ_NOT_MATCH, sip_uri_cmp(), match_req_args::totag, match_req_args::viabranch, and match_req_args::viasentby.
Referenced by find_call().
08185 { 08186 const char *init_ruri = NULL; 08187 if (sip_pvt_ptr->initreq.headers) { 08188 init_ruri = REQ_OFFSET_TO_STR(&sip_pvt_ptr->initreq, rlPart2); 08189 } 08190 08191 /* 08192 * Match Tags and call-id to Dialog 08193 */ 08194 if (!ast_strlen_zero(arg->callid) && strcmp(sip_pvt_ptr->callid, arg->callid)) { 08195 /* call-id does not match. */ 08196 return SIP_REQ_NOT_MATCH; 08197 } 08198 if (arg->method == SIP_RESPONSE) { 08199 /* Verify totag if we have one stored for this dialog, but never be strict about this for 08200 * a response until the dialog is established */ 08201 if (!ast_strlen_zero(sip_pvt_ptr->theirtag) && ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) { 08202 if (ast_strlen_zero(arg->totag)) { 08203 /* missing totag when they already gave us one earlier */ 08204 return SIP_REQ_NOT_MATCH; 08205 } 08206 if (strcmp(arg->totag, sip_pvt_ptr->theirtag)) { 08207 /* The totag of the response does not match the one we have stored */ 08208 return SIP_REQ_NOT_MATCH; 08209 } 08210 } 08211 /* Verify fromtag of response matches the tag we gave them. */ 08212 if (strcmp(arg->fromtag, sip_pvt_ptr->tag)) { 08213 /* fromtag from response does not match our tag */ 08214 return SIP_REQ_NOT_MATCH; 08215 } 08216 } else { 08217 /* Verify the fromtag of Request matches the tag they provided earlier. 08218 * If this is a Request with authentication credentials, forget their old 08219 * tag as it is not valid after the 401 or 407 response. */ 08220 if (!arg->authentication_present && strcmp(arg->fromtag, sip_pvt_ptr->theirtag)) { 08221 /* their tag does not match the one was have stored for them */ 08222 return SIP_REQ_NOT_MATCH; 08223 } 08224 /* Verify if totag is present in Request, that it matches what we gave them as our tag earlier */ 08225 if (!ast_strlen_zero(arg->totag) && (strcmp(arg->totag, sip_pvt_ptr->tag))) { 08226 /* totag from Request does not match our tag */ 08227 return SIP_REQ_NOT_MATCH; 08228 } 08229 } 08230 08231 /* 08232 * Compare incoming request against initial transaction. 08233 * 08234 * This is a best effort attempt at distinguishing forked requests from 08235 * our initial transaction. If all the elements are NOT in place to evaluate 08236 * this, this block is ignored and the dialog match is made regardless. 08237 * Once the totag is established after the dialog is confirmed, this is not necessary. 08238 * 08239 * CRITERIA required for initial transaction matching. 08240 * 08241 * 1. Is a Request 08242 * 2. Callid and theirtag match (this is done in the dialog matching block) 08243 * 3. totag is NOT present 08244 * 4. CSeq matchs our initial transaction's cseq number 08245 * 5. pvt has init via branch parameter stored 08246 */ 08247 if ((arg->method != SIP_RESPONSE) && /* must be a Request */ 08248 ast_strlen_zero(arg->totag) && /* must not have a totag */ 08249 (sip_pvt_ptr->init_icseq == arg->seqno) && /* the cseq must be the same as this dialogs initial cseq */ 08250 !ast_strlen_zero(sip_pvt_ptr->initviabranch) && /* The dialog must have started with a RFC3261 compliant branch tag */ 08251 init_ruri) { /* the dialog must have an initial request uri associated with it */ 08252 /* This Request matches all the criteria required for Loop/Merge detection. 08253 * Now we must go down the path of comparing VIA's and RURIs. */ 08254 if (ast_strlen_zero(arg->viabranch) || 08255 strcmp(arg->viabranch, sip_pvt_ptr->initviabranch) || 08256 ast_strlen_zero(arg->viasentby) || 08257 strcmp(arg->viasentby, sip_pvt_ptr->initviasentby)) { 08258 /* At this point, this request does not match this Dialog.*/ 08259 08260 /* if methods are different this is just a mismatch */ 08261 if ((sip_pvt_ptr->method != arg->method)) { 08262 return SIP_REQ_NOT_MATCH; 08263 } 08264 08265 /* If RUIs are different, this is a forked request to a separate URI. 08266 * Returning a mismatch allows this Request to be processed separately. */ 08267 if (sip_uri_cmp(init_ruri, arg->ruri)) { 08268 /* not a match, request uris are different */ 08269 return SIP_REQ_NOT_MATCH; 08270 } 08271 08272 /* Loop/Merge Detected 08273 * 08274 * ---Current Matches to Initial Request--- 08275 * request uri 08276 * Call-id 08277 * their-tag 08278 * no totag present 08279 * method 08280 * cseq 08281 * 08282 * --- Does not Match Initial Request --- 08283 * Top Via 08284 * 08285 * Without the same Via, this can not match our initial transaction for this dialog, 08286 * but given that this Request matches everything else associated with that initial 08287 * Request this is most certainly a Forked request in which we have already received 08288 * part of the fork. 08289 */ 08290 return SIP_REQ_LOOP_DETECTED; 08291 } 08292 } /* end of Request Via check */ 08293 08294 /* Match Authentication Request. 08295 * 08296 * A Request with an Authentication header must come back with the 08297 * same Request URI. Otherwise it is not a match. 08298 */ 08299 if ((arg->method != SIP_RESPONSE) && /* Must be a Request type to even begin checking this */ 08300 ast_strlen_zero(arg->totag) && /* no totag is present to match */ 08301 arg->authentication_present && /* Authentication header is present in Request */ 08302 sip_uri_cmp(init_ruri, arg->ruri)) { /* Compare the Request URI of both the last Request and this new one */ 08303 08304 /* Authentication was provided, but the Request URI did not match the last one on this dialog. */ 08305 return SIP_REQ_NOT_MATCH; 08306 } 08307 08308 return SIP_REQ_MATCH; 08309 }
| static int method_match | ( | enum sipmethod | id, | |
| const char * | name | |||
| ) | [static] |
returns true if 'name' (with optional trailing whitespace) matches the sip method 'id'. Strictly speaking, SIP methods are case SENSITIVE, but we do a case-insensitive comparison to be more tolerant. following Jon Postel's rule: Be gentle in what you accept, strict with what you send
Definition at line 3337 of file chan_sip.c.
References len(), sip_methods, and text.
Referenced by __sip_autodestruct(), __sip_semi_ack(), and find_sip_method().
03338 { 03339 int len = strlen(sip_methods[id].text); 03340 int l_name = name ? strlen(name) : 0; 03341 /* true if the string is long enough, and ends with whitespace, and matches */ 03342 return (l_name >= len && name && name[len] < 33 && 03343 !strncasecmp(sip_methods[id].text, name, len)); 03344 }
| static void mwi_event_cb | ( | const struct ast_event * | event, | |
| void * | userdata | |||
| ) | [static] |
Receive MWI events that we have subscribed to.
Definition at line 15049 of file chan_sip.c.
References sip_send_mwi_to_peer().
Referenced by add_peer_mwi_subs().
15050 { 15051 struct sip_peer *peer = userdata; 15052 15053 sip_send_mwi_to_peer(peer, 0); 15054 }
| static void network_change_event_cb | ( | const struct ast_event * | event, | |
| void * | userdata | |||
| ) | [static] |
Definition at line 15079 of file chan_sip.c.
References ast_debug, ast_sched_add(), and network_change_event_sched_cb().
Referenced by network_change_event_subscribe().
15080 { 15081 ast_debug(1, "SIP, got a network change event, renewing all SIP registrations.\n"); 15082 if (network_change_event_sched_id == -1) { 15083 network_change_event_sched_id = ast_sched_add(sched, 1000, network_change_event_sched_cb, NULL); 15084 } 15085 }
| static int network_change_event_sched_cb | ( | const void * | data | ) | [static] |
Definition at line 15071 of file chan_sip.c.
References sip_send_all_mwi_subscriptions(), and sip_send_all_registers().
Referenced by network_change_event_cb().
15072 { 15073 network_change_event_sched_id = -1; 15074 sip_send_all_registers(); 15075 sip_send_all_mwi_subscriptions(); 15076 return 0; 15077 }
| static void network_change_event_subscribe | ( | void | ) | [static] |
Definition at line 15056 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().
15057 { 15058 if (!network_change_event_subscription) { 15059 network_change_event_subscription = ast_event_subscribe(AST_EVENT_NETWORK_CHANGE, 15060 network_change_event_cb, "SIP Network Change", NULL, AST_EVENT_IE_END); 15061 } 15062 }
| static void network_change_event_unsubscribe | ( | void | ) | [static] |
Definition at line 15064 of file chan_sip.c.
References ast_event_unsubscribe().
Referenced by reload_config(), and unload_module().
15065 { 15066 if (network_change_event_subscription) { 15067 network_change_event_subscription = ast_event_unsubscribe(network_change_event_subscription); 15068 } 15069 }
| static struct sip_proxy* obproxy_get | ( | struct sip_pvt * | dialog, | |
| struct sip_peer * | peer | |||
| ) | [static, read] |
Get default outbound proxy or global proxy.
Definition at line 3302 of file chan_sip.c.
References append_history, ast_debug, and sip_cfg.
Referenced by __sip_subscribe_mwi_do(), create_addr(), create_addr_from_peer(), sip_poke_peer(), and transmit_register().
03303 { 03304 if (dialog && dialog->options && dialog->options->outboundproxy) { 03305 if (sipdebug) { 03306 ast_debug(1, "OBPROXY: Applying dialplan set OBproxy to this call\n"); 03307 } 03308 append_history(dialog, "OBproxy", "Using dialplan obproxy %s", dialog->options->outboundproxy->name); 03309 return dialog->options->outboundproxy; 03310 } 03311 if (peer && peer->outboundproxy) { 03312 if (sipdebug) { 03313 ast_debug(1, "OBPROXY: Applying peer OBproxy to this call\n"); 03314 } 03315 append_history(dialog, "OBproxy", "Using peer obproxy %s", peer->outboundproxy->name); 03316 return peer->outboundproxy; 03317 } 03318 if (sip_cfg.outboundproxy.name[0]) { 03319 if (sipdebug) { 03320 ast_debug(1, "OBPROXY: Applying global OBproxy to this call\n"); 03321 } 03322 append_history(dialog, "OBproxy", "Using global obproxy %s", sip_cfg.outboundproxy.name); 03323 return &sip_cfg.outboundproxy; 03324 } 03325 if (sipdebug) { 03326 ast_debug(1, "OBPROXY: Not applying OBproxy to this call\n"); 03327 } 03328 return NULL; 03329 }
| static void on_dns_update_mwi | ( | struct ast_sockaddr * | old, | |
| struct ast_sockaddr * | new, | |||
| void * | data | |||
| ) | [static] |
Definition at line 12845 of file chan_sip.c.
References ast_debug, ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_stringify(), and ast_strdupa.
Referenced by __sip_subscribe_mwi_do().
12846 { 12847 struct sip_subscription_mwi *mwi = data; 12848 const char *old_str; 12849 12850 /* This shouldn't happen, but just in case */ 12851 if (ast_sockaddr_isnull(new)) { 12852 ast_debug(1, "Empty sockaddr change...ignoring!\n"); 12853 return; 12854 } 12855 12856 old_str = ast_strdupa(ast_sockaddr_stringify(old)); 12857 ast_debug(1, "Changing mwi %s from %s to %s\n", mwi->hostname, old_str, ast_sockaddr_stringify(new)); 12858 ast_sockaddr_copy(&mwi->us, new); 12859 }
| static void on_dns_update_peer | ( | struct ast_sockaddr * | old, | |
| struct ast_sockaddr * | new, | |||
| void * | data | |||
| ) | [static] |
Definition at line 12816 of file chan_sip.c.
References ao2_link, ao2_lock, ao2_unlink, ao2_unlock, ast_debug, ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_strdupa, and default_sip_port().
Referenced by build_peer(), and transmit_register().
12817 { 12818 struct sip_peer *peer = data; 12819 const char *old_str; 12820 12821 /* This shouldn't happen, but just in case */ 12822 if (ast_sockaddr_isnull(new)) { 12823 ast_debug(1, "Empty sockaddr change...ignoring!\n"); 12824 return; 12825 } 12826 12827 if (!ast_sockaddr_isnull(&peer->addr)) { 12828 ao2_unlink(peers_by_ip, peer); 12829 } 12830 12831 if (!ast_sockaddr_port(new)) { 12832 ast_sockaddr_set_port(new, default_sip_port(peer->socket.type)); 12833 } 12834 12835 old_str = ast_strdupa(ast_sockaddr_stringify(old)); 12836 ast_debug(1, "Changing peer %s address from %s to %s\n", peer->name, old_str, ast_sockaddr_stringify(new)); 12837 12838 ao2_lock(peer); 12839 ast_sockaddr_copy(&peer->addr, new); 12840 ao2_unlock(peer); 12841 12842 ao2_link(peers_by_ip, peer); 12843 }
| static void on_dns_update_registry | ( | struct ast_sockaddr * | old, | |
| struct ast_sockaddr * | new, | |||
| void * | data | |||
| ) | [static] |
Definition at line 12795 of file chan_sip.c.
References ast_debug, ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_strdupa, and S_OR.
Referenced by transmit_register().
12796 { 12797 struct sip_registry *reg = data; 12798 const char *old_str; 12799 12800 /* This shouldn't happen, but just in case */ 12801 if (ast_sockaddr_isnull(new)) { 12802 ast_debug(1, "Empty sockaddr change...ignoring!\n"); 12803 return; 12804 } 12805 12806 if (!ast_sockaddr_port(new)) { 12807 ast_sockaddr_set_port(new, reg->portno); 12808 } 12809 12810 old_str = ast_strdupa(ast_sockaddr_stringify(old)); 12811 12812 ast_debug(1, "Changing registry %s from %s to %s\n", S_OR(reg->peername, reg->hostname), old_str, ast_sockaddr_stringify(new)); 12813 ast_sockaddr_copy(®->us, new); 12814 }
| static unsigned int parse_allowed_methods | ( | struct sip_request * | req | ) | [static] |
parse the Allow header to see what methods the endpoint we are communicating with allows.
We parse the allow header on incoming Registrations and save the result to the SIP peer that is registering. When the registration expires, we clear what we know about the peer's allowed methods. When the peer re-registers, we once again parse to see if the list of allowed methods has changed.
For peers that do not register, we parse the first message we receive during a call to see what is allowed, and save the information for the duration of the call.
| req | The SIP request we are parsing |
| The | methods allowed |
Definition at line 8690 of file chan_sip.c.
References ast_strdupa, ast_strip_quoted(), ast_strlen_zero(), get_header(), and mark_parsed_methods().
Referenced by set_pvt_allowed_methods().
08691 { 08692 char *allow = ast_strdupa(get_header(req, "Allow")); 08693 unsigned int allowed_methods = SIP_UNKNOWN; 08694 08695 if (ast_strlen_zero(allow)) { 08696 /* I have witnessed that REGISTER requests from Polycom phones do not 08697 * place the phone's allowed methods in an Allow header. Instead, they place the 08698 * allowed methods in a methods= parameter in the Contact header. 08699 */ 08700 char *contact = ast_strdupa(get_header(req, "Contact")); 08701 char *methods = strstr(contact, ";methods="); 08702 08703 if (ast_strlen_zero(methods)) { 08704 /* RFC 3261 states: 08705 * 08706 * "The absence of an Allow header field MUST NOT be 08707 * interpreted to mean that the UA sending the message supports no 08708 * methods. Rather, it implies that the UA is not providing any 08709 * information on what methods it supports." 08710 * 08711 * For simplicity, we'll assume that the peer allows all known 08712 * SIP methods if they have no Allow header. We can then clear out the necessary 08713 * bits if the peer lets us know that we have sent an unsupported method. 08714 */ 08715 return UINT_MAX; 08716 } 08717 allow = ast_strip_quoted(methods + 9, "\"", "\""); 08718 } 08719 mark_parsed_methods(&allowed_methods, allow); 08720 return allowed_methods; 08721 }
| static void parse_copy | ( | struct sip_request * | dst, | |
| const struct sip_request * | src | |||
| ) | [static] |
Copy SIP request, parse it.
Definition at line 4262 of file chan_sip.c.
References copy_request(), and parse_request().
Referenced by send_request(), and send_response().
04263 { 04264 copy_request(dst, src); 04265 parse_request(dst); 04266 }
| int parse_minse | ( | const char * | p_hdrval, | |
| int *const | p_interval | |||
| ) | [static] |
Session-Timers: Function for parsing Min-SE header.
Definition at line 26881 of file chan_sip.c.
References ast_debug, ast_log(), ast_skip_blanks(), ast_strlen_zero(), and LOG_WARNING.
Referenced by handle_request_invite_st(), and proc_422_rsp().
26882 { 26883 if (ast_strlen_zero(p_hdrval)) { 26884 ast_log(LOG_WARNING, "Null Min-SE header\n"); 26885 return -1; 26886 } 26887 26888 *p_interval = 0; 26889 p_hdrval = ast_skip_blanks(p_hdrval); 26890 if (!sscanf(p_hdrval, "%30d", p_interval)) { 26891 ast_log(LOG_WARNING, "Parsing of Min-SE header failed %s\n", p_hdrval); 26892 return -1; 26893 } 26894 26895 ast_debug(2, "Received Min-SE: %d\n", *p_interval); 26896 return 0; 26897 }
| static void parse_moved_contact | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| char ** | name, | |||
| char ** | number, | |||
| int | set_call_forward | |||
| ) | [static] |
Parse 302 Moved temporalily response.
Definition at line 20359 of file chan_sip.c.
References ao2_ref, ast_copy_string(), ast_debug, ast_log(), ast_strdup, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), find_closing_quote(), get_header(), get_in_brackets(), get_transport(), LOG_NOTICE, pbx_builtin_setvar_helper(), remove_uri_parameters(), and set_socket_transport().
Referenced by change_redirecting_information().
20360 { 20361 char contact[SIPBUFSIZE]; 20362 char *contact_name = NULL; 20363 char *contact_number = NULL; 20364 char *separator, *trans; 20365 char *domain; 20366 enum sip_transport transport = SIP_TRANSPORT_UDP; 20367 20368 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 20369 if ((separator = strchr(contact, ','))) 20370 *separator = '\0'; 20371 20372 contact_number = get_in_brackets(contact); 20373 if ((trans = strcasestr(contact_number, ";transport="))) { 20374 trans += 11; 20375 20376 if ((separator = strchr(trans, ';'))) 20377 *separator = '\0'; 20378 20379 if (!strncasecmp(trans, "tcp", 3)) 20380 transport = SIP_TRANSPORT_TCP; 20381 else if (!strncasecmp(trans, "tls", 3)) 20382 transport = SIP_TRANSPORT_TLS; 20383 else { 20384 if (strncasecmp(trans, "udp", 3)) 20385 ast_debug(1, "received contact with an invalid transport, '%s'\n", contact_number); 20386 /* This will assume UDP for all unknown transports */ 20387 transport = SIP_TRANSPORT_UDP; 20388 } 20389 } 20390 contact_number = remove_uri_parameters(contact_number); 20391 20392 if (p->socket.tcptls_session) { 20393 ao2_ref(p->socket.tcptls_session, -1); 20394 p->socket.tcptls_session = NULL; 20395 } 20396 20397 set_socket_transport(&p->socket, transport); 20398 20399 if (set_call_forward && ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) { 20400 char *host = NULL; 20401 if (!strncasecmp(contact_number, "sip:", 4)) 20402 contact_number += 4; 20403 else if (!strncasecmp(contact_number, "sips:", 5)) 20404 contact_number += 5; 20405 separator = strchr(contact_number, '/'); 20406 if (separator) 20407 *separator = '\0'; 20408 if ((host = strchr(contact_number, '@'))) { 20409 *host++ = '\0'; 20410 ast_debug(2, "Found promiscuous redirection to 'SIP/%s::::%s@%s'\n", contact_number, get_transport(transport), host); 20411 if (p->owner) 20412 ast_string_field_build(p->owner, call_forward, "SIP/%s::::%s@%s", contact_number, get_transport(transport), host); 20413 } else { 20414 ast_debug(2, "Found promiscuous redirection to 'SIP/::::%s@%s'\n", get_transport(transport), contact_number); 20415 if (p->owner) 20416 ast_string_field_build(p->owner, call_forward, "SIP/::::%s@%s", get_transport(transport), contact_number); 20417 } 20418 } else { 20419 separator = strchr(contact, '@'); 20420 if (separator) { 20421 *separator++ = '\0'; 20422 domain = separator; 20423 } else { 20424 /* No username part */ 20425 domain = contact; 20426 } 20427 separator = strchr(contact, '/'); /* WHEN do we hae a forward slash in the URI? */ 20428 if (separator) 20429 *separator = '\0'; 20430 20431 if (!strncasecmp(contact_number, "sip:", 4)) 20432 contact_number += 4; 20433 else if (!strncasecmp(contact_number, "sips:", 5)) 20434 contact_number += 5; 20435 separator = strchr(contact_number, ';'); /* And username ; parameters? */ 20436 if (separator) 20437 *separator = '\0'; 20438 ast_uri_decode(contact_number); 20439 if (set_call_forward) { 20440 ast_debug(2, "Received 302 Redirect to extension '%s' (domain %s)\n", contact_number, domain); 20441 if (p->owner) { 20442 pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain); 20443 ast_string_field_set(p->owner, call_forward, contact_number); 20444 } 20445 } 20446 } 20447 20448 /* We've gotten the number for the contact, now get the name */ 20449 20450 if (*contact == '\"') { 20451 contact_name = contact + 1; 20452 if (!(separator = (char *)find_closing_quote(contact_name, NULL))) { 20453 ast_log(LOG_NOTICE, "No closing quote on name in Contact header? %s\n", contact); 20454 } 20455 *separator = '\0'; 20456 } 20457 20458 if (name && !ast_strlen_zero(contact_name)) { 20459 *name = ast_strdup(contact_name); 20460 } 20461 if (number) { 20462 *number = ast_strdup(contact_number); 20463 } 20464 }
| static int parse_ok_contact | ( | struct sip_pvt * | pvt, | |
| struct sip_request * | req | |||
| ) | [static] |
Save contact header for 200 OK on INVITE.
Definition at line 14356 of file chan_sip.c.
References ast_copy_string(), ast_string_field_set, get_header(), get_in_brackets(), and TRUE.
Referenced by handle_request_invite(), handle_request_subscribe(), and handle_response_invite().
14357 { 14358 char contact[SIPBUFSIZE]; 14359 char *c; 14360 14361 /* Look for brackets */ 14362 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 14363 c = get_in_brackets(contact); 14364 14365 /* Save full contact to call pvt for later bye or re-invite */ 14366 ast_string_field_set(pvt, fullcontact, c); 14367 14368 /* Save URI for later ACKs, BYE or RE-invites */ 14369 ast_string_field_set(pvt, okcontacturi, c); 14370 14371 /* We should return false for URI:s we can't handle, 14372 like tel:, mailto:,ldap: etc */ 14373 return TRUE; 14374 }
| static enum parse_register_result parse_register_contact | ( | struct sip_pvt * | pvt, | |
| struct sip_peer * | p, | |||
| struct sip_request * | req | |||
| ) | [static] |
Parse contact header and save registration (peer registration).
Definition at line 14463 of file chan_sip.c.
References __get_header(), ao2_t_link, ao2_t_unlink, ast_apply_ha(), ast_copy_string(), ast_db_put(), ast_debug, ast_log(), ast_sched_add(), AST_SCHED_DEL_UNREF, ast_sched_when(), AST_SENSE_ALLOW, ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_resolve_first_transport(), ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verb, ast_verbose, copy_socket_data(), default_sip_port(), EVENT_FLAG_SYSTEM, expire_register(), FALSE, get_header(), get_in_brackets(), get_transport_str2enum(), LOG_NOTICE, LOG_WARNING, manager_event, parse_uri_legacy_check(), ref_peer(), register_peer_exten(), set_socket_transport(), sip_cfg, sip_poke_peer(), sip_pvt_lock, sip_pvt_unlock, TRUE, unref_peer(), VERBOSE_PREFIX_3, and VERBOSITY_ATLEAST.
Referenced by register_verify().
14464 { 14465 char contact[SIPBUFSIZE]; 14466 char data[SIPBUFSIZE]; 14467 const char *expires = get_header(req, "Expires"); 14468 int expire = atoi(expires); 14469 char *curi = NULL, *hostport = NULL, *transport = NULL; 14470 int transport_type; 14471 const char *useragent; 14472 struct ast_sockaddr oldsin, testsa; 14473 char *firstcuri = NULL; 14474 int start = 0; 14475 int wildcard_found = 0; 14476 int single_binding_found = 0; 14477 14478 ast_copy_string(contact, __get_header(req, "Contact", &start), sizeof(contact)); 14479 14480 if (ast_strlen_zero(expires)) { /* No expires header, try look in Contact: */ 14481 char *s = strcasestr(contact, ";expires="); 14482 if (s) { 14483 expires = strsep(&s, ";"); /* trim ; and beyond */ 14484 if (sscanf(expires + 9, "%30d", &expire) != 1) { 14485 expire = default_expiry; 14486 } 14487 } else { 14488 /* Nothing has been specified */ 14489 expire = default_expiry; 14490 } 14491 } 14492 14493 if (expire > max_expiry) { 14494 expire = max_expiry; 14495 } 14496 if (expire < min_expiry && expire != 0) { 14497 expire = min_expiry; 14498 } 14499 pvt->expiry = expire; 14500 14501 copy_socket_data(&pvt->socket, &req->socket); 14502 14503 do { 14504 /* Look for brackets */ 14505 curi = contact; 14506 if (strchr(contact, '<') == NULL) /* No <, check for ; and strip it */ 14507 strsep(&curi, ";"); /* This is Header options, not URI options */ 14508 curi = get_in_brackets(contact); 14509 if (!firstcuri) { 14510 firstcuri = ast_strdupa(curi); 14511 } 14512 14513 if (!strcasecmp(curi, "*")) { 14514 wildcard_found = 1; 14515 } else { 14516 single_binding_found = 1; 14517 } 14518 14519 if (wildcard_found && (ast_strlen_zero(expires) || expire != 0 || single_binding_found)) { 14520 /* Contact header parameter "*" detected, so punt if: Expires header is missing, 14521 * Expires value is not zero, or another Contact header is present. */ 14522 return PARSE_REGISTER_FAILED; 14523 } 14524 14525 ast_copy_string(contact, __get_header(req, "Contact", &start), sizeof(contact)); 14526 } while (!ast_strlen_zero(contact)); 14527 curi = firstcuri; 14528 14529 /* if they did not specify Contact: or Expires:, they are querying 14530 what we currently have stored as their contact address, so return 14531 it 14532 */ 14533 if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) { 14534 /* If we have an active registration, tell them when the registration is going to expire */ 14535 if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact)) { 14536 pvt->expiry = ast_sched_when(sched, peer->expire); 14537 } 14538 return PARSE_REGISTER_QUERY; 14539 } else if (!strcasecmp(curi, "*") || !expire) { /* Unregister this peer */ 14540 /* This means remove all registrations and return OK */ 14541 AST_SCHED_DEL_UNREF(sched, peer->expire, 14542 unref_peer(peer, "remove register expire ref")); 14543 ast_verb(3, "Unregistered SIP '%s'\n", peer->name); 14544 expire_register(ref_peer(peer,"add ref for explicit expire_register")); 14545 return PARSE_REGISTER_UPDATE; 14546 } 14547 14548 /* Store whatever we got as a contact from the client */ 14549 ast_string_field_set(peer, fullcontact, curi); 14550 14551 /* For the 200 OK, we should use the received contact */ 14552 ast_string_field_build(pvt, our_contact, "<%s>", curi); 14553 14554 /* Make sure it's a SIP URL */ 14555 if (ast_strlen_zero(curi) || parse_uri_legacy_check(curi, "sip:,sips:", &curi, NULL, &hostport, &transport)) { 14556 ast_log(LOG_NOTICE, "Not a valid SIP contact (missing sip:/sips:) trying to use anyway\n"); 14557 } 14558 14559 /* handle the transport type specified in Contact header. */ 14560 if (!(transport_type = get_transport_str2enum(transport))) { 14561 transport_type = pvt->socket.type; 14562 } 14563 14564 /* if the peer's socket type is different than the Registration 14565 * transport type, change it. If it got this far, it is a 14566 * supported type, but check just in case */ 14567 if ((peer->socket.type != transport_type) && (peer->transports & transport_type)) { 14568 set_socket_transport(&peer->socket, transport_type); 14569 } 14570 14571 oldsin = peer->addr; 14572 14573 /* If we were already linked into the peers_by_ip container unlink ourselves so nobody can find us */ 14574 if (!ast_sockaddr_isnull(&peer->addr) && (!peer->is_realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS))) { 14575 ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table"); 14576 } 14577 14578 if (!ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) && !ast_test_flag(&peer->flags[0], SIP_NAT_RPORT_PRESENT)) { 14579 /* use the data provided in the Contact header for call routing */ 14580 ast_debug(1, "Store REGISTER's Contact header for call routing.\n"); 14581 /* XXX This could block for a long time XXX */ 14582 /*! \todo Check NAPTR/SRV if we have not got a port in the URI */ 14583 if (ast_sockaddr_resolve_first_transport(&testsa, hostport, 0, peer->socket.type)) { 14584 ast_log(LOG_WARNING, "Invalid hostport '%s'\n", hostport); 14585 ast_string_field_set(peer, fullcontact, ""); 14586 ast_string_field_set(pvt, our_contact, ""); 14587 return PARSE_REGISTER_FAILED; 14588 } 14589 14590 /* If we have a port number in the given URI, make sure we do remember to not check for NAPTR/SRV records. 14591 The hostport part is actually a host. */ 14592 peer->portinuri = ast_sockaddr_port(&testsa) ? TRUE : FALSE; 14593 14594 if (!ast_sockaddr_port(&testsa)) { 14595 ast_sockaddr_set_port(&testsa, default_sip_port(transport_type)); 14596 } 14597 14598 ast_sockaddr_copy(&peer->addr, &testsa); 14599 } else { 14600 /* Don't trust the contact field. Just use what they came to us 14601 with */ 14602 ast_debug(1, "Store REGISTER's src-IP:port for call routing.\n"); 14603 peer->addr = pvt->recv; 14604 } 14605 14606 /* Check that they're allowed to register at this IP */ 14607 if (ast_apply_ha(sip_cfg.contact_ha, &peer->addr) != AST_SENSE_ALLOW || 14608 ast_apply_ha(peer->contactha, &peer->addr) != AST_SENSE_ALLOW) { 14609 ast_log(LOG_WARNING, "Domain '%s' disallowed by contact ACL (violating IP %s)\n", hostport, 14610 ast_sockaddr_stringify_addr(&peer->addr)); 14611 ast_string_field_set(peer, fullcontact, ""); 14612 ast_string_field_set(pvt, our_contact, ""); 14613 return PARSE_REGISTER_DENIED; 14614 } 14615 14616 /* if the Contact header information copied into peer->addr matches the 14617 * received address, and the transport types are the same, then copy socket 14618 * data into the peer struct */ 14619 if ((peer->socket.type == pvt->socket.type) && 14620 !ast_sockaddr_cmp(&peer->addr, &pvt->recv)) { 14621 copy_socket_data(&peer->socket, &pvt->socket); 14622 } 14623 14624 /* Now that our address has been updated put ourselves back into the container for lookups */ 14625 if (!peer->is_realtime || ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 14626 ao2_t_link(peers_by_ip, peer, "ao2_link into peers_by_ip table"); 14627 } 14628 14629 /* Save SIP options profile */ 14630 peer->sipoptions = pvt->sipoptions; 14631 14632 if (!ast_strlen_zero(curi) && ast_strlen_zero(peer->username)) { 14633 ast_string_field_set(peer, username, curi); 14634 } 14635 14636 AST_SCHED_DEL_UNREF(sched, peer->expire, 14637 unref_peer(peer, "remove register expire ref")); 14638 14639 if (peer->is_realtime && !ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 14640 peer->expire = -1; 14641 } else { 14642 peer->expire = ast_sched_add(sched, (expire + 10) * 1000, expire_register, 14643 ref_peer(peer, "add registration ref")); 14644 if (peer->expire == -1) { 14645 unref_peer(peer, "remote registration ref"); 14646 } 14647 } 14648 snprintf(data, sizeof(data), "%s:%d:%s:%s", ast_sockaddr_stringify(&peer->addr), 14649 expire, peer->username, peer->fullcontact); 14650 /* We might not immediately be able to reconnect via TCP, but try caching it anyhow */ 14651 if (!peer->rt_fromcontact || !sip_cfg.peer_rtupdate) 14652 ast_db_put("SIP/Registry", peer->name, data); 14653 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Registered\r\nAddress: %s\r\n", peer->name, ast_sockaddr_stringify(&peer->addr)); 14654 14655 /* Is this a new IP address for us? */ 14656 if (VERBOSITY_ATLEAST(2) && ast_sockaddr_cmp(&peer->addr, &oldsin)) { 14657 ast_verbose(VERBOSE_PREFIX_3 "Registered SIP '%s' at %s\n", peer->name, 14658 ast_sockaddr_stringify(&peer->addr)); 14659 } 14660 sip_pvt_unlock(pvt); 14661 sip_poke_peer(peer, 0); 14662 sip_pvt_lock(pvt); 14663 register_peer_exten(peer, 1); 14664 14665 /* Save User agent */ 14666 useragent = get_header(req, "User-Agent"); 14667 if (strcasecmp(useragent, peer->useragent)) { 14668 ast_string_field_set(peer, useragent, useragent); 14669 ast_verb(4, "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name); 14670 } 14671 return PARSE_REGISTER_UPDATE; 14672 }
| static int parse_request | ( | struct sip_request * | req | ) | [static] |
Parse a SIP message.
Definition at line 8795 of file chan_sip.c.
References ast_debug, ast_log(), ast_str_buffer(), ast_str_strlen(), ast_strlen_zero(), determine_firstline_parts(), and LOG_WARNING.
Referenced by handle_request_do(), initialize_initreq(), and parse_copy().
08796 { 08797 char *c = req->data->str; 08798 ptrdiff_t *dst = req->header; 08799 int i = 0, lim = SIP_MAX_HEADERS - 1; 08800 unsigned int skipping_headers = 0; 08801 ptrdiff_t current_header_offset = 0; 08802 char *previous_header = ""; 08803 08804 req->header[0] = 0; 08805 req->headers = -1; /* mark that we are working on the header */ 08806 for (; *c; c++) { 08807 if (*c == '\r') { /* remove \r */ 08808 *c = '\0'; 08809 } else if (*c == '\n') { /* end of this line */ 08810 *c = '\0'; 08811 current_header_offset = (c + 1) - ast_str_buffer(req->data); 08812 previous_header = ast_str_buffer(req->data) + dst[i]; 08813 if (skipping_headers) { 08814 /* check to see if this line is blank; if so, turn off 08815 the skipping flag, so the next line will be processed 08816 as a body line */ 08817 if (ast_strlen_zero(previous_header)) { 08818 skipping_headers = 0; 08819 } 08820 dst[i] = current_header_offset; /* record start of next line */ 08821 continue; 08822 } 08823 if (sipdebug) { 08824 ast_debug(4, "%7s %2d [%3d]: %s\n", 08825 req->headers < 0 ? "Header" : "Body", 08826 i, (int) strlen(previous_header), previous_header); 08827 } 08828 if (ast_strlen_zero(previous_header) && req->headers < 0) { 08829 req->headers = i; /* record number of header lines */ 08830 dst = req->line; /* start working on the body */ 08831 i = 0; 08832 lim = SIP_MAX_LINES - 1; 08833 } else { /* move to next line, check for overflows */ 08834 if (i++ == lim) { 08835 /* if we're processing headers, then skip any remaining 08836 headers and move on to processing the body, otherwise 08837 we're done */ 08838 if (req->headers != -1) { 08839 break; 08840 } else { 08841 req->headers = i; 08842 dst = req->line; 08843 i = 0; 08844 lim = SIP_MAX_LINES - 1; 08845 skipping_headers = 1; 08846 } 08847 } 08848 } 08849 dst[i] = current_header_offset; /* record start of next line */ 08850 } 08851 } 08852 08853 /* Check for last header or body line without CRLF. The RFC for SDP requires CRLF, 08854 but since some devices send without, we'll be generous in what we accept. However, 08855 if we've already reached the maximum number of lines for portion of the message 08856 we were parsing, we can't accept any more, so just ignore it. 08857 */ 08858 previous_header = ast_str_buffer(req->data) + dst[i]; 08859 if ((i < lim) && !ast_strlen_zero(previous_header)) { 08860 if (sipdebug) { 08861 ast_debug(4, "%7s %2d [%3d]: %s\n", 08862 req->headers < 0 ? "Header" : "Body", 08863 i, (int) strlen(previous_header), previous_header ); 08864 } 08865 i++; 08866 } 08867 08868 /* update count of header or body lines */ 08869 if (req->headers >= 0) { /* we are in the body */ 08870 req->lines = i; 08871 } else { /* no body */ 08872 req->headers = i; 08873 req->lines = 0; 08874 /* req->data->used will be a NULL byte */ 08875 req->line[0] = ast_str_strlen(req->data); 08876 } 08877 08878 if (*c) { 08879 ast_log(LOG_WARNING, "Too many lines, skipping <%s>\n", c); 08880 } 08881 08882 /* Split up the first line parts */ 08883 return determine_firstline_parts(req); 08884 }
| int parse_session_expires | ( | const char * | p_hdrval, | |
| int *const | p_interval, | |||
| enum st_refresher_param *const | p_ref | |||
| ) | [static] |
Session-Timers: Function for parsing Session-Expires header.
Definition at line 26901 of file chan_sip.c.
References ast_debug, ast_log(), ast_skip_blanks(), ast_strdupa, ast_strlen_zero(), and LOG_WARNING.
Referenced by handle_request_invite_st(), and handle_response_invite().
26902 { 26903 char *p_token; 26904 int ref_idx; 26905 char *p_se_hdr; 26906 26907 if (ast_strlen_zero(p_hdrval)) { 26908 ast_log(LOG_WARNING, "Null Session-Expires header\n"); 26909 return -1; 26910 } 26911 26912 *p_ref = SESSION_TIMER_REFRESHER_PARAM_UNKNOWN; 26913 *p_interval = 0; 26914 26915 p_se_hdr = ast_strdupa(p_hdrval); 26916 p_se_hdr = ast_skip_blanks(p_se_hdr); 26917 26918 while ((p_token = strsep(&p_se_hdr, ";"))) { 26919 p_token = ast_skip_blanks(p_token); 26920 if (!sscanf(p_token, "%30d", p_interval)) { 26921 ast_log(LOG_WARNING, "Parsing of Session-Expires failed\n"); 26922 return -1; 26923 } 26924 26925 ast_debug(2, "Session-Expires: %d\n", *p_interval); 26926 26927 if (!p_se_hdr) 26928 continue; 26929 26930 p_se_hdr = ast_skip_blanks(p_se_hdr); 26931 ref_idx = strlen("refresher="); 26932 if (!strncasecmp(p_se_hdr, "refresher=", ref_idx)) { 26933 p_se_hdr += ref_idx; 26934 p_se_hdr = ast_skip_blanks(p_se_hdr); 26935 26936 if (!strncasecmp(p_se_hdr, "uac", strlen("uac"))) { 26937 *p_ref = SESSION_TIMER_REFRESHER_PARAM_UAC; 26938 ast_debug(2, "Refresher: UAC\n"); 26939 } else if (!strncasecmp(p_se_hdr, "uas", strlen("uas"))) { 26940 *p_ref = SESSION_TIMER_REFRESHER_PARAM_UAS; 26941 ast_debug(2, "Refresher: UAS\n"); 26942 } else { 26943 ast_log(LOG_WARNING, "Invalid refresher value %s\n", p_se_hdr); 26944 return -1; 26945 } 26946 break; 26947 } 26948 } 26949 return 0; 26950 }
| static int parse_uri_legacy_check | ( | char * | uri, | |
| const char * | scheme, | |||
| char ** | user, | |||
| char ** | pass, | |||
| char ** | hostport, | |||
| char ** | transport | |||
| ) | [static] |
parse uri in a way that allows semicolon stripping if legacy mode is enabled
Definition at line 14382 of file chan_sip.c.
References parse_uri(), and sip_cfg.
Referenced by __set_address_from_contact(), check_user_full(), get_also_info(), get_destination(), parse_register_contact(), and register_verify().
14383 { 14384 int ret = parse_uri(uri, scheme, user, pass, hostport, transport); 14385 if (sip_cfg.legacy_useroption_parsing) { /* if legacy mode is active, strip semis from the user field */ 14386 char *p; 14387 if ((p = strchr(uri, (int)';'))) { 14388 *p = '\0'; 14389 } 14390 } 14391 return ret; 14392 }
| static int peer_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 30736 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 17501 of file chan_sip.c.
References ao2_t_ref, ast_cli(), and ast_cli_args::fd.
Referenced by sip_show_objects().
17502 { 17503 struct sip_peer *peer = userobj; 17504 int refc = ao2_t_ref(userobj, 0, ""); 17505 struct ast_cli_args *a = (struct ast_cli_args *) arg; 17506 17507 ast_cli(a->fd, "name: %s\ntype: peer\nobjflags: %d\nrefcount: %d\n\n", 17508 peer->name, 0, refc); 17509 return 0; 17510 }
| static int peer_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 30726 of file chan_sip.c.
References ast_str_case_hash().
Referenced by load_module().
30727 { 30728 const struct sip_peer *peer = obj; 30729 30730 return ast_str_case_hash(peer->name); 30731 }
| static int peer_ipcmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Match Peers by IP and Port number.
This function has two modes.
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 30784 of file chan_sip.c.
References ast_sockaddr_cmp_addr(), ast_sockaddr_port, ast_test_flag, CMP_MATCH, and CMP_STOP.
Referenced by load_module().
30785 { 30786 struct sip_peer *peer = obj, *peer2 = arg; 30787 30788 if (ast_sockaddr_cmp_addr(&peer->addr, &peer2->addr)) { 30789 /* IP doesn't match */ 30790 return 0; 30791 } 30792 30793 /* We matched the IP, check to see if we need to match by port as well. */ 30794 if ((peer->transports & peer2->transports) & (SIP_TRANSPORT_TLS | SIP_TRANSPORT_TCP)) { 30795 /* peer matching on port is not possible with TCP/TLS */ 30796 return CMP_MATCH | CMP_STOP; 30797 } else if (ast_test_flag(&peer2->flags[0], SIP_INSECURE_PORT)) { 30798 /* We are allowing match without port for peers configured that 30799 * way in this pass through the peers. */ 30800 return ast_test_flag(&peer->flags[0], SIP_INSECURE_PORT) ? 30801 (CMP_MATCH | CMP_STOP) : 0; 30802 } 30803 30804 /* Now only return a match if the port matches, as well. */ 30805 return ast_sockaddr_port(&peer->addr) == ast_sockaddr_port(&peer2->addr) ? 30806 (CMP_MATCH | CMP_STOP) : 0; 30807 }
| static int peer_iphash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Hash function based on the the peer's ip address. For IPv6, we use the end of the address.
Definition at line 30748 of file chan_sip.c.
References ast_log(), ast_sockaddr_hash(), ast_sockaddr_isnull(), and LOG_ERROR.
Referenced by load_module().
30749 { 30750 const struct sip_peer *peer = obj; 30751 int ret = 0; 30752 30753 if (ast_sockaddr_isnull(&peer->addr)) { 30754 ast_log(LOG_ERROR, "Empty address\n"); 30755 } 30756 30757 ret = ast_sockaddr_hash(&peer->addr); 30758 30759 if (ret < 0) { 30760 ret = -ret; 30761 } 30762 30763 return ret; 30764 }
| static void peer_mailboxes_to_str | ( | struct ast_str ** | mailbox_str, | |
| struct sip_peer * | peer | |||
| ) | [static] |
list peer mailboxes to CLI
Definition at line 18035 of file chan_sip.c.
References AST_LIST_NEXT, AST_LIST_TRAVERSE, ast_str_append(), ast_strlen_zero(), mailbox, and S_OR.
Referenced by _sip_show_peer(), function_sippeer(), show_channels_cb(), and sip_send_mwi_to_peer().
18036 { 18037 struct sip_mailbox *mailbox; 18038 18039 AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { 18040 ast_str_append(mailbox_str, 0, "%s%s%s%s", 18041 mailbox->mailbox, 18042 ast_strlen_zero(mailbox->context) ? "" : "@", 18043 S_OR(mailbox->context, ""), 18044 AST_LIST_NEXT(mailbox, entry) ? "," : ""); 18045 } 18046 }
| static int peer_markall_func | ( | void * | device, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 28749 of file chan_sip.c.
Referenced by reload_config().
| static void peer_sched_cleanup | ( | struct sip_peer * | peer | ) | [static] |
Definition at line 2992 of file chan_sip.c.
References AST_SCHED_DEL_UNREF, and unref_peer().
Referenced by match_and_cleanup_peer_sched().
02993 { 02994 if (peer->pokeexpire != -1) { 02995 AST_SCHED_DEL_UNREF(sched, peer->pokeexpire, 02996 unref_peer(peer, "removing poke peer ref")); 02997 } 02998 if (peer->expire != -1) { 02999 AST_SCHED_DEL_UNREF(sched, peer->expire, 03000 unref_peer(peer, "remove register expire ref")); 03001 } 03002 }
| static int peer_status | ( | struct sip_peer * | peer, | |
| char * | status, | |||
| int | statuslen | |||
| ) | [static] |
Definition at line 17052 of file chan_sip.c.
References ast_copy_string().
Referenced by _sip_show_peer(), _sip_show_peers_one(), and function_sippeer().
17053 { 17054 int res = 0; 17055 if (peer->maxms) { 17056 if (peer->lastms < 0) { 17057 ast_copy_string(status, "UNREACHABLE", statuslen); 17058 } else if (peer->lastms > peer->maxms) { 17059 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 17060 res = 1; 17061 } else if (peer->lastms) { 17062 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 17063 res = 1; 17064 } else { 17065 ast_copy_string(status, "UNKNOWN", statuslen); 17066 } 17067 } else { 17068 ast_copy_string(status, "Unmonitored", statuslen); 17069 /* Checking if port is 0 */ 17070 res = -1; 17071 } 17072 return res; 17073 }
| int peercomparefunc | ( | const void * | a, | |
| const void * | b | |||
| ) |
Definition at line 17280 of file chan_sip.c.
Referenced by _sip_show_peers().
| static int peers_data_provider_get | ( | const struct ast_data_search * | search, | |
| struct ast_data * | data_root | |||
| ) | [static] |
Definition at line 31694 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, ARRAY_LEN, ast_cdr_flags2str(), ast_data_add_bool(), ast_data_add_codecs(), ast_data_add_int(), ast_data_add_node(), ast_data_add_str(), ast_data_add_structure, ast_data_remove_node(), ast_data_search_match(), ast_describe_caller_presentation(), AST_LIST_TRAVERSE, get_transport_list(), mailbox, text, and transfermode2str().
31696 { 31697 struct sip_peer *peer; 31698 struct ao2_iterator i; 31699 struct ast_data *data_peer, *data_peer_mailboxes = NULL, *data_peer_mailbox, *enum_node; 31700 struct ast_data *data_sip_options; 31701 int total_mailboxes, x; 31702 struct sip_mailbox *mailbox; 31703 31704 i = ao2_iterator_init(peers, 0); 31705 while ((peer = ao2_iterator_next(&i))) { 31706 ao2_lock(peer); 31707 31708 data_peer = ast_data_add_node(data_root, "peer"); 31709 if (!data_peer) { 31710 ao2_unlock(peer); 31711 ao2_ref(peer, -1); 31712 continue; 31713 } 31714 31715 ast_data_add_structure(sip_peer, data_peer, peer); 31716 31717 /* transfer mode */ 31718 enum_node = ast_data_add_node(data_peer, "allowtransfer"); 31719 if (!enum_node) { 31720 ao2_unlock(peer); 31721 ao2_ref(peer, -1); 31722 continue; 31723 } 31724 ast_data_add_str(enum_node, "text", transfermode2str(peer->allowtransfer)); 31725 ast_data_add_int(enum_node, "value", peer->allowtransfer); 31726 31727 /* transports */ 31728 ast_data_add_str(data_peer, "transports", get_transport_list(peer->transports)); 31729 31730 /* peer type */ 31731 if ((peer->type & SIP_TYPE_USER) && (peer->type & SIP_TYPE_PEER)) { 31732 ast_data_add_str(data_peer, "type", "friend"); 31733 } else if (peer->type & SIP_TYPE_PEER) { 31734 ast_data_add_str(data_peer, "type", "peer"); 31735 } else if (peer->type & SIP_TYPE_USER) { 31736 ast_data_add_str(data_peer, "type", "user"); 31737 } 31738 31739 /* mailboxes */ 31740 total_mailboxes = 0; 31741 AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { 31742 if (!total_mailboxes) { 31743 data_peer_mailboxes = ast_data_add_node(data_peer, "mailboxes"); 31744 if (!data_peer_mailboxes) { 31745 break; 31746 } 31747 total_mailboxes++; 31748 } 31749 31750 data_peer_mailbox = ast_data_add_node(data_peer_mailboxes, "mailbox"); 31751 if (!data_peer_mailbox) { 31752 continue; 31753 } 31754 ast_data_add_str(data_peer_mailbox, "mailbox", mailbox->mailbox); 31755 ast_data_add_str(data_peer_mailbox, "context", mailbox->context); 31756 } 31757 31758 /* amaflags */ 31759 enum_node = ast_data_add_node(data_peer, "amaflags"); 31760 if (!enum_node) { 31761 ao2_unlock(peer); 31762 ao2_ref(peer, -1); 31763 continue; 31764 } 31765 ast_data_add_int(enum_node, "value", peer->amaflags); 31766 ast_data_add_str(enum_node, "text", ast_cdr_flags2str(peer->amaflags)); 31767 31768 /* sip options */ 31769 data_sip_options = ast_data_add_node(data_peer, "sipoptions"); 31770 if (!data_sip_options) { 31771 ao2_unlock(peer); 31772 ao2_ref(peer, -1); 31773 continue; 31774 } 31775 for (x = 0 ; x < ARRAY_LEN(sip_options); x++) { 31776 ast_data_add_bool(data_sip_options, sip_options[x].text, peer->sipoptions & sip_options[x].id); 31777 } 31778 31779 /* callingpres */ 31780 enum_node = ast_data_add_node(data_peer, "callingpres"); 31781 if (!enum_node) { 31782 ao2_unlock(peer); 31783 ao2_ref(peer, -1); 31784 continue; 31785 } 31786 ast_data_add_int(enum_node, "value", peer->callingpres); 31787 ast_data_add_str(enum_node, "text", ast_describe_caller_presentation(peer->callingpres)); 31788 31789 /* codecs */ 31790 ast_data_add_codecs(data_peer, "codecs", peer->capability); 31791 31792 if (!ast_data_search_match(search, data_peer)) { 31793 ast_data_remove_node(data_root, data_peer); 31794 } 31795 31796 ao2_unlock(peer); 31797 ao2_ref(peer, -1); 31798 } 31799 ao2_iterator_destroy(&i); 31800 31801 return 0; 31802 }
| unsigned int port_str2int | ( | const char * | pt, | |
| unsigned int | standard | |||
| ) |
converts ascii port to int representation. If no pt buffer is provided or the pt has errors when being converted to an int value, the port provided as the standard is used.
Definition at line 3291 of file chan_sip.c.
References ast_strlen_zero().
Referenced by build_peer(), reload_config(), and sip_parse_register_line().
03292 { 03293 int port = standard; 03294 if (ast_strlen_zero(pt) || (sscanf(pt, "%30d", &port) != 1) || (port < 1) || (port > 65535)) { 03295 port = standard; 03296 } 03297 03298 return port; 03299 }
| static void print_codec_to_cli | ( | int | fd, | |
| struct ast_codec_pref * | pref | |||
| ) | [static] |
Print codec list from preference to CLI/manager.
Definition at line 17872 of file chan_sip.c.
References ast_cli(), ast_codec_pref_index(), ast_getformatname(), and ast_codec_pref::framing.
Referenced by _sip_show_peer(), sip_show_settings(), and sip_show_user().
17873 { 17874 int x; 17875 format_t codec; 17876 17877 for(x = 0; x < 64 ; x++) { 17878 codec = ast_codec_pref_index(pref, x); 17879 if (!codec) 17880 break; 17881 ast_cli(fd, "%s", ast_getformatname(codec)); 17882 ast_cli(fd, ":%d", pref->framing[x]); 17883 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 17884 ast_cli(fd, ","); 17885 } 17886 if (!x) 17887 ast_cli(fd, "none"); 17888 }
| static void print_group | ( | int | fd, | |
| ast_group_t | group, | |||
| int | crlf | |||
| ) | [static] |
Print call group and pickup group.
Definition at line 17553 of file chan_sip.c.
References ast_cli(), and ast_print_group().
Referenced by _sip_show_peer(), and sip_show_user().
17554 { 17555 char buf[256]; 17556 ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) ); 17557 }
| static void proc_422_rsp | ( | struct sip_pvt * | p, | |
| struct sip_request * | rsp | |||
| ) | [static] |
Handle 422 response to INVITE with session-timer requested.
Session-Timers: An INVITE originated by Asterisk that asks for session-timers support from the UAS can result into a 422 response. This is how a UAS or an intermediary proxy server tells Asterisk that the session refresh interval offered by Asterisk is too low for them. The proc_422_rsp() function handles a 422 response. It extracts the Min-SE header that comes back in 422 and sends a new INVITE accordingly.
Definition at line 26960 of file chan_sip.c.
References ast_log(), ast_strlen_zero(), get_header(), LOG_WARNING, parse_minse(), and transmit_invite().
Referenced by handle_response_invite().
26961 { 26962 int rtn; 26963 const char *p_hdrval; 26964 int minse; 26965 26966 p_hdrval = get_header(rsp, "Min-SE"); 26967 if (ast_strlen_zero(p_hdrval)) { 26968 ast_log(LOG_WARNING, "422 response without a Min-SE header %s\n", p_hdrval); 26969 return; 26970 } 26971 rtn = parse_minse(p_hdrval, &minse); 26972 if (rtn != 0) { 26973 ast_log(LOG_WARNING, "Parsing of Min-SE header failed %s\n", p_hdrval); 26974 return; 26975 } 26976 p->stimer->st_cached_min_se = minse; 26977 if (p->stimer->st_interval < minse) { 26978 p->stimer->st_interval = minse; 26979 } 26980 transmit_invite(p, SIP_INVITE, 1, 2, NULL); 26981 }
| static int proc_session_timer | ( | const void * | vp | ) | [static] |
Session-Timers: Process session refresh timeout event.
Definition at line 26811 of file chan_sip.c.
References ast_channel_trylock, ast_channel_unlock, ast_debug, ast_log(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, FALSE, LOG_WARNING, sip_pvt_lock, sip_pvt_unlock, stop_session_timer(), transmit_reinvite_with_sdp(), and TRUE.
Referenced by start_session_timer().
26812 { 26813 struct sip_pvt *p = (struct sip_pvt *) vp; 26814 int res = 0; 26815 26816 if (!p->stimer) { 26817 ast_log(LOG_WARNING, "Null stimer in proc_session_timer - %s\n", p->callid); 26818 goto return_unref; 26819 } 26820 26821 ast_debug(2, "Session timer expired: %d - %s\n", p->stimer->st_schedid, p->callid); 26822 26823 if (!p->owner) { 26824 goto return_unref; 26825 } 26826 26827 if ((p->stimer->st_active != TRUE) || (p->owner->_state != AST_STATE_UP)) { 26828 goto return_unref; 26829 } 26830 26831 if (p->stimer->st_ref == SESSION_TIMER_REFRESHER_US) { 26832 res = 1; 26833 if (T38_ENABLED == p->t38.state) { 26834 transmit_reinvite_with_sdp(p, TRUE, TRUE); 26835 } else { 26836 transmit_reinvite_with_sdp(p, FALSE, TRUE); 26837 } 26838 } else { 26839 if (p->stimer->quit_flag) { 26840 goto return_unref; 26841 } 26842 ast_log(LOG_WARNING, "Session-Timer expired - %s\n", p->callid); 26843 sip_pvt_lock(p); 26844 while (p->owner && ast_channel_trylock(p->owner)) { 26845 sip_pvt_unlock(p); 26846 usleep(1); 26847 if (p->stimer && p->stimer->quit_flag) { 26848 goto return_unref; 26849 } 26850 sip_pvt_lock(p); 26851 } 26852 26853 ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV); 26854 ast_channel_unlock(p->owner); 26855 sip_pvt_unlock(p); 26856 } 26857 26858 return_unref: 26859 if (!res) { 26860 /* An error occurred. Stop session timer processing */ 26861 if (p->stimer) { 26862 ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid); 26863 /* Don't pass go, don't collect $200.. we are the scheduled 26864 * callback. We can rip ourself out here. */ 26865 p->stimer->st_schedid = -1; 26866 /* Calling stop_session_timer is nice for consistent debug 26867 * logs. */ 26868 stop_session_timer(p); 26869 } 26870 26871 /* If we are not asking to be rescheduled, then we need to release our 26872 * reference to the dialog. */ 26873 dialog_unref(p, "removing session timer ref"); 26874 } 26875 26876 return res; 26877 }
| static int process_crypto | ( | struct sip_pvt * | p, | |
| struct ast_rtp_instance * | rtp, | |||
| struct sip_srtp ** | srtp, | |||
| const char * | a | |||
| ) | [static] |
Definition at line 30564 of file chan_sip.c.
References ast_debug, ast_log(), ast_set_flag, ast_test_flag, FALSE, LOG_WARNING, sdp_crypto_process(), sdp_crypto_setup(), setup_srtp(), and TRUE.
Referenced by process_sdp().
30565 { 30566 /* If no RTP instance exists for this media stream don't bother processing the crypto line */ 30567 if (!rtp) { 30568 ast_debug(3, "Received offer with crypto line for media stream that is not enabled\n"); 30569 return FALSE; 30570 } 30571 30572 if (strncasecmp(a, "crypto:", 7)) { 30573 return FALSE; 30574 } 30575 if (!*srtp) { 30576 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 30577 ast_log(LOG_WARNING, "Ignoring unexpected crypto attribute in SDP answer\n"); 30578 return FALSE; 30579 } 30580 30581 if (setup_srtp(srtp) < 0) { 30582 return FALSE; 30583 } 30584 } 30585 30586 if (!(*srtp)->crypto && !((*srtp)->crypto = sdp_crypto_setup())) { 30587 return FALSE; 30588 } 30589 30590 if (sdp_crypto_process((*srtp)->crypto, a, rtp) < 0) { 30591 return FALSE; 30592 } 30593 30594 ast_set_flag(*srtp, SRTP_CRYPTO_OFFER_OK); 30595 30596 return TRUE; 30597 }
| static int process_sdp | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| int | t38action | |||
| ) | [static] |
Process SIP SDP offer, select formats and activate media channels If offer is rejected, we will not change any properties of the call Return 0 on success, a negative value on errors. Must be called after find_sdp().
< RTP audio destination IP address
< RTP video destination IP address
< RTP text destination IP address
< UDPTL image destination IP address
< RTP audio destination port number
< RTP video destination port number
< RTP text destination port number
< UDPTL image destination port number
Definition at line 9092 of file chan_sip.c.
References ast_async_goto(), ast_channel_lock, ast_channel_set_fd(), ast_channel_unlock, ast_clear_flag, ast_codec_choose(), AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, ast_copy_string(), ast_debug, ast_exists_extension(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_T140RED, ast_getformatname_multiple(), ast_log(), ast_null_frame, ast_queue_control(), ast_queue_control_data(), ast_queue_frame(), ast_rtp_codecs_payload_formats(), ast_rtp_codecs_payloads_clear(), ast_rtp_codecs_payloads_copy(), ast_rtp_codecs_payloads_set_m_type(), AST_RTP_DTMF, ast_rtp_instance_fd(), ast_rtp_instance_get_codecs(), ast_rtp_instance_get_remote_address(), ast_rtp_instance_set_prop(), ast_rtp_instance_set_remote_address(), ast_rtp_instance_stop(), ast_rtp_lookup_mime_multiple2(), AST_RTP_PROPERTY_DTMF, AST_RTP_PROPERTY_DTMF_COMPENSATE, AST_RTP_PROPERTY_RTCP, ast_rtp_red_init(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), ast_skip_blanks(), ast_sockaddr_isnull(), ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_str_alloca, ast_strlen_zero(), ast_test_flag, ast_udptl_get_far_max_datagram(), ast_udptl_set_error_correction_scheme(), ast_udptl_set_far_max_datagram(), ast_udptl_set_peer(), ast_udptl_stop(), ast_verbose, change_hold_state(), change_t38_state(), FALSE, get_sdp_iterate(), get_sdp_line(), initialize_udptl(), len(), LOG_ERROR, LOG_NOTICE, LOG_WARNING, pbx_builtin_setvar_helper(), process_crypto(), process_sdp_a_audio(), process_sdp_a_image(), process_sdp_a_sendonly(), process_sdp_a_text(), process_sdp_a_video(), process_sdp_c(), process_sdp_o(), S_COR, S_OR, sip_debug_test_pvt(), sockaddr_is_null_or_any(), text, TRUE, type, UDPTL_ERROR_CORRECTION_NONE, value, and VERBOSE_PREFIX_2.
Referenced by handle_incoming(), handle_request_invite(), handle_response(), and handle_response_invite().
09093 { 09094 /* Iterators for SDP parsing */ 09095 int start = req->sdp_start; 09096 int next = start; 09097 int iterator = start; 09098 09099 /* Temporary vars for SDP parsing */ 09100 char type = '\0'; 09101 const char *value = NULL; 09102 const char *m = NULL; /* SDP media offer */ 09103 const char *nextm = NULL; 09104 int len = -1; 09105 09106 /* Host information */ 09107 struct ast_sockaddr sessionsa; 09108 struct ast_sockaddr audiosa; 09109 struct ast_sockaddr videosa; 09110 struct ast_sockaddr textsa; 09111 struct ast_sockaddr imagesa; 09112 struct ast_sockaddr *sa = NULL; /*!< RTP audio destination IP address */ 09113 struct ast_sockaddr *vsa = NULL; /*!< RTP video destination IP address */ 09114 struct ast_sockaddr *tsa = NULL; /*!< RTP text destination IP address */ 09115 struct ast_sockaddr *isa = NULL; /*!< UDPTL image destination IP address */ 09116 int portno = -1; /*!< RTP audio destination port number */ 09117 int vportno = -1; /*!< RTP video destination port number */ 09118 int tportno = -1; /*!< RTP text destination port number */ 09119 int udptlportno = -1; /*!< UDPTL image destination port number */ 09120 09121 /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */ 09122 format_t peercapability = 0, vpeercapability = 0, tpeercapability = 0; 09123 int peernoncodeccapability = 0, vpeernoncodeccapability = 0, tpeernoncodeccapability = 0; 09124 09125 struct ast_rtp_codecs newaudiortp, newvideortp, newtextrtp; 09126 format_t newjointcapability; /* Negotiated capability */ 09127 format_t newpeercapability; 09128 int newnoncodeccapability; 09129 09130 const char *codecs; 09131 unsigned int codec; 09132 09133 /* SRTP */ 09134 int secure_audio = FALSE; 09135 int secure_video = FALSE; 09136 09137 /* Others */ 09138 int sendonly = -1; 09139 unsigned int numberofports; 09140 int numberofmediastreams = 0; 09141 int last_rtpmap_codec = 0; 09142 int red_data_pt[10]; /* For T.140 RED */ 09143 int red_num_gen = 0; /* For T.140 RED */ 09144 char red_fmtp[100] = "empty"; /* For T.140 RED */ 09145 int debug = sip_debug_test_pvt(p); 09146 09147 /* START UNKNOWN */ 09148 char buf[SIPBUFSIZE]; 09149 /* END UNKNOWN */ 09150 09151 /* Initial check */ 09152 if (!p->rtp) { 09153 ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n"); 09154 return -1; 09155 } 09156 09157 /* Make sure that the codec structures are all cleared out */ 09158 ast_rtp_codecs_payloads_clear(&newaudiortp, NULL); 09159 ast_rtp_codecs_payloads_clear(&newvideortp, NULL); 09160 ast_rtp_codecs_payloads_clear(&newtextrtp, NULL); 09161 09162 /* Update our last rtprx when we receive an SDP, too */ 09163 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 09164 09165 memset(p->offered_media, 0, sizeof(p->offered_media)); 09166 09167 /* default: novideo and notext set */ 09168 p->novideo = TRUE; 09169 p->notext = TRUE; 09170 09171 /* Scan for the first media stream (m=) line to limit scanning of globals */ 09172 nextm = get_sdp_iterate(&next, req, "m"); 09173 if (ast_strlen_zero(nextm)) { 09174 ast_log(LOG_WARNING, "Insufficient information for SDP (m= not found)\n"); 09175 return -1; 09176 } 09177 09178 /* Scan session level SDP parameters (lines before first media stream) */ 09179 while ((type = get_sdp_line(&iterator, next - 1, req, &value)) != '\0') { 09180 int processed = FALSE; 09181 switch (type) { 09182 case 'o': 09183 /* If we end up receiving SDP that doesn't actually modify the session we don't want to treat this as a fatal 09184 * error. We just want to ignore the SDP and let the rest of the packet be handled as normal. 09185 */ 09186 if (!process_sdp_o(value, p)) { 09187 return (p->session_modify == FALSE) ? 0 : -1; 09188 } 09189 processed = TRUE; 09190 break; 09191 case 'c': 09192 if (process_sdp_c(value, &sessionsa)) { 09193 processed = TRUE; 09194 sa = &sessionsa; 09195 vsa = sa; 09196 tsa = sa; 09197 isa = sa; 09198 } 09199 break; 09200 case 'a': 09201 if (process_sdp_a_sendonly(value, &sendonly)) { 09202 processed = TRUE; 09203 } 09204 else if (process_sdp_a_audio(value, p, &newaudiortp, &last_rtpmap_codec)) 09205 processed = TRUE; 09206 else if (process_sdp_a_video(value, p, &newvideortp, &last_rtpmap_codec)) 09207 processed = TRUE; 09208 else if (process_sdp_a_text(value, p, &newtextrtp, red_fmtp, &red_num_gen, red_data_pt, &last_rtpmap_codec)) 09209 processed = TRUE; 09210 else if (process_sdp_a_image(value, p)) 09211 processed = TRUE; 09212 break; 09213 } 09214 09215 ast_debug(3, "Processing session-level SDP %c=%s... %s\n", type, value, (processed == TRUE)? "OK." : "UNSUPPORTED OR FAILED."); 09216 } 09217 09218 /* Scan media stream (m=) specific parameters loop */ 09219 while (!ast_strlen_zero(nextm)) { 09220 int audio = FALSE; 09221 int video = FALSE; 09222 int image = FALSE; 09223 int text = FALSE; 09224 int processed_crypto = FALSE; 09225 char protocol[18] = {0,}; 09226 unsigned int x; 09227 09228 numberofports = 0; 09229 len = -1; 09230 start = next; 09231 m = nextm; 09232 iterator = next; 09233 nextm = get_sdp_iterate(&next, req, "m"); 09234 09235 /* Check for 'audio' media offer */ 09236 if (strncmp(m, "audio ", 6) == 0) { 09237 if ((sscanf(m, "audio %30u/%30u RTP/%4s %n", &x, &numberofports, protocol, &len) == 3 && len > 0) || 09238 (sscanf(m, "audio %30u RTP/%4s %n", &x, protocol, &len) == 2 && len > 0)) { 09239 if (x == 0) { 09240 ast_log(LOG_WARNING, "Ignoring audio media offer because port number is zero\n"); 09241 continue; 09242 } 09243 09244 /* Check number of ports offered for stream */ 09245 if (numberofports > 1) { 09246 ast_log(LOG_WARNING, "%u ports offered for audio media, not supported by Asterisk. Will try anyway...\n", numberofports); 09247 } 09248 09249 if (!strcmp(protocol, "SAVP")) { 09250 secure_audio = 1; 09251 } else if (strcmp(protocol, "AVP")) { 09252 ast_log(LOG_WARNING, "Unknown RTP profile in audio offer: %s\n", m); 09253 continue; 09254 } 09255 09256 if (p->offered_media[SDP_AUDIO].order_offered) { 09257 ast_log(LOG_WARNING, "Rejecting non-primary audio stream: %s\n", m); 09258 return -1; 09259 } 09260 09261 audio = TRUE; 09262 p->offered_media[SDP_AUDIO].order_offered = ++numberofmediastreams; 09263 portno = x; 09264 09265 /* Scan through the RTP payload types specified in a "m=" line: */ 09266 codecs = m + len; 09267 ast_copy_string(p->offered_media[SDP_AUDIO].codecs, codecs, sizeof(p->offered_media[SDP_AUDIO].codecs)); 09268 for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 09269 if (sscanf(codecs, "%30u%n", &codec, &len) != 1) { 09270 ast_log(LOG_WARNING, "Invalid syntax in RTP audio format list: %s\n", codecs); 09271 return -1; 09272 } 09273 if (debug) { 09274 ast_verbose("Found RTP audio format %u\n", codec); 09275 } 09276 09277 ast_rtp_codecs_payloads_set_m_type(&newaudiortp, NULL, codec); 09278 } 09279 } else { 09280 ast_log(LOG_WARNING, "Rejecting audio media offer due to invalid or unsupported syntax: %s\n", m); 09281 return -1; 09282 } 09283 } 09284 /* Check for 'video' media offer */ 09285 else if (strncmp(m, "video ", 6) == 0) { 09286 if ((sscanf(m, "video %30u/%30u RTP/%4s %n", &x, &numberofports, protocol, &len) == 3 && len > 0) || 09287 (sscanf(m, "video %30u RTP/%4s %n", &x, protocol, &len) == 2 && len > 0)) { 09288 if (x == 0) { 09289 ast_log(LOG_WARNING, "Ignoring video media offer because port number is zero\n"); 09290 continue; 09291 } 09292 09293 /* Check number of ports offered for stream */ 09294 if (numberofports > 1) { 09295 ast_log(LOG_WARNING, "%u ports offered for video media, not supported by Asterisk. Will try anyway...\n", numberofports); 09296 } 09297 09298 if (!strcmp(protocol, "SAVP")) { 09299 secure_video = 1; 09300 } else if (strcmp(protocol, "AVP")) { 09301 ast_log(LOG_WARNING, "Unknown RTP profile in video offer: %s\n", m); 09302 continue; 09303 } 09304 09305 if (p->offered_media[SDP_VIDEO].order_offered) { 09306 ast_log(LOG_WARNING, "Rejecting non-primary video stream: %s\n", m); 09307 return -1; 09308 } 09309 09310 video = TRUE; 09311 p->novideo = FALSE; 09312 p->offered_media[SDP_VIDEO].order_offered = ++numberofmediastreams; 09313 vportno = x; 09314 09315 /* Scan through the RTP payload types specified in a "m=" line: */ 09316 codecs = m + len; 09317 ast_copy_string(p->offered_media[SDP_VIDEO].codecs, codecs, sizeof(p->offered_media[SDP_VIDEO].codecs)); 09318 for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 09319 if (sscanf(codecs, "%30u%n", &codec, &len) != 1) { 09320 ast_log(LOG_WARNING, "Invalid syntax in RTP video format list: %s\n", codecs); 09321 return -1; 09322 } 09323 if (debug) { 09324 ast_verbose("Found RTP video format %u\n", codec); 09325 } 09326 ast_rtp_codecs_payloads_set_m_type(&newvideortp, NULL, codec); 09327 } 09328 } else { 09329 ast_log(LOG_WARNING, "Rejecting video media offer due to invalid or unsupported syntax: %s\n", m); 09330 return -1; 09331 } 09332 } 09333 /* Check for 'text' media offer */ 09334 else if (strncmp(m, "text ", 5) == 0) { 09335 if ((sscanf(m, "text %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 09336 (sscanf(m, "text %30u RTP/AVP %n", &x, &len) == 1 && len > 0)) { 09337 if (x == 0) { 09338 ast_log(LOG_WARNING, "Ignoring text media offer because port number is zero\n"); 09339 continue; 09340 } 09341 09342 /* Check number of ports offered for stream */ 09343 if (numberofports > 1) { 09344 ast_log(LOG_WARNING, "%u ports offered for text media, not supported by Asterisk. Will try anyway...\n", numberofports); 09345 } 09346 09347 if (p->offered_media[SDP_TEXT].order_offered) { 09348 ast_log(LOG_WARNING, "Rejecting non-primary text stream: %s\n", m); 09349 return -1; 09350 } 09351 09352 text = TRUE; 09353 p->notext = FALSE; 09354 p->offered_media[SDP_TEXT].order_offered = ++numberofmediastreams; 09355 tportno = x; 09356 09357 /* Scan through the RTP payload types specified in a "m=" line: */ 09358 codecs = m + len; 09359 ast_copy_string(p->offered_media[SDP_TEXT].codecs, codecs, sizeof(p->offered_media[SDP_TEXT].codecs)); 09360 for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 09361 if (sscanf(codecs, "%30u%n", &codec, &len) != 1) { 09362 ast_log(LOG_WARNING, "Invalid syntax in RTP video format list: %s\n", codecs); 09363 return -1; 09364 } 09365 if (debug) { 09366 ast_verbose("Found RTP text format %u\n", codec); 09367 } 09368 ast_rtp_codecs_payloads_set_m_type(&newtextrtp, NULL, codec); 09369 } 09370 } else { 09371 ast_log(LOG_WARNING, "Rejecting text media offer due to invalid or unsupported syntax: %s\n", m); 09372 return -1; 09373 } 09374 } 09375 /* Check for 'image' media offer */ 09376 else if (strncmp(m, "image ", 6) == 0) { 09377 if (((sscanf(m, "image %30u udptl t38%n", &x, &len) == 1 && len > 0) || 09378 (sscanf(m, "image %30u UDPTL t38%n", &x, &len) == 1 && len > 0))) { 09379 if (x == 0) { 09380 ast_log(LOG_WARNING, "Ignoring image media offer because port number is zero\n"); 09381 continue; 09382 } 09383 09384 if (initialize_udptl(p)) { 09385 ast_log(LOG_WARNING, "Rejecting offer with image stream due to UDPTL initialization failure\n"); 09386 return -1; 09387 } 09388 09389 if (p->offered_media[SDP_IMAGE].order_offered) { 09390 ast_log(LOG_WARNING, "Rejecting non-primary image stream: %s\n", m); 09391 return -1; 09392 } 09393 09394 image = TRUE; 09395 if (debug) { 09396 ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid); 09397 } 09398 09399 p->offered_media[SDP_IMAGE].order_offered = ++numberofmediastreams; 09400 udptlportno = x; 09401 09402 if (p->t38.state != T38_ENABLED) { 09403 memset(&p->t38.their_parms, 0, sizeof(p->t38.their_parms)); 09404 09405 /* default EC to none, the remote end should 09406 * respond with the EC they want to use */ 09407 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 09408 } 09409 } else if (sscanf(m, "image %30u %17s t38%n", &x, protocol, &len) == 2 && len > 0) { 09410 ast_log(LOG_WARNING, "Declining image stream due to unsupported transport: %s\n", m); 09411 continue; 09412 } else { 09413 ast_log(LOG_WARNING, "Rejecting image media offer due to invalid or unsupported syntax: %s\n", m); 09414 return -1; 09415 } 09416 } else { 09417 ast_log(LOG_WARNING, "Unsupported top-level media type in offer: %s\n", m); 09418 continue; 09419 } 09420 09421 /* Media stream specific parameters */ 09422 while ((type = get_sdp_line(&iterator, next - 1, req, &value)) != '\0') { 09423 int processed = FALSE; 09424 09425 switch (type) { 09426 case 'c': 09427 if (audio) { 09428 if (process_sdp_c(value, &audiosa)) { 09429 processed = TRUE; 09430 sa = &audiosa; 09431 } 09432 } else if (video) { 09433 if (process_sdp_c(value, &videosa)) { 09434 processed = TRUE; 09435 vsa = &videosa; 09436 } 09437 } else if (text) { 09438 if (process_sdp_c(value, &textsa)) { 09439 processed = TRUE; 09440 tsa = &textsa; 09441 } 09442 } else if (image) { 09443 if (process_sdp_c(value, &imagesa)) { 09444 processed = TRUE; 09445 isa = &imagesa; 09446 } 09447 } 09448 break; 09449 case 'a': 09450 /* Audio specific scanning */ 09451 if (audio) { 09452 if (process_sdp_a_sendonly(value, &sendonly)) { 09453 processed = TRUE; 09454 } else if (!processed_crypto && process_crypto(p, p->rtp, &p->srtp, value)) { 09455 processed_crypto = TRUE; 09456 processed = TRUE; 09457 } else if (process_sdp_a_audio(value, p, &newaudiortp, &last_rtpmap_codec)) { 09458 processed = TRUE; 09459 } 09460 } 09461 /* Video specific scanning */ 09462 else if (video) { 09463 if (!processed_crypto && process_crypto(p, p->vrtp, &p->vsrtp, value)) { 09464 processed_crypto = TRUE; 09465 processed = TRUE; 09466 } else if (process_sdp_a_video(value, p, &newvideortp, &last_rtpmap_codec)) { 09467 processed = TRUE; 09468 } 09469 } 09470 /* Text (T.140) specific scanning */ 09471 else if (text) { 09472 if (process_sdp_a_text(value, p, &newtextrtp, red_fmtp, &red_num_gen, red_data_pt, &last_rtpmap_codec)) { 09473 processed = TRUE; 09474 } else if (!processed_crypto && process_crypto(p, p->trtp, &p->tsrtp, value)) { 09475 processed_crypto = TRUE; 09476 processed = TRUE; 09477 } 09478 } 09479 /* Image (T.38 FAX) specific scanning */ 09480 else if (image) { 09481 if (process_sdp_a_image(value, p)) 09482 processed = TRUE; 09483 } 09484 break; 09485 } 09486 09487 ast_debug(3, "Processing media-level (%s) SDP %c=%s... %s\n", 09488 (audio == TRUE)? "audio" : (video == TRUE)? "video" : (text == TRUE)? "text" : "image", 09489 type, value, 09490 (processed == TRUE)? "OK." : "UNSUPPORTED OR FAILED."); 09491 } 09492 09493 /* Ensure crypto lines are provided where necessary */ 09494 if (audio && secure_audio && !processed_crypto) { 09495 ast_log(LOG_WARNING, "Rejecting secure audio stream without encryption details: %s\n", m); 09496 return -1; 09497 } else if (video && secure_video && !processed_crypto) { 09498 ast_log(LOG_WARNING, "Rejecting secure video stream without encryption details: %s\n", m); 09499 return -1; 09500 } 09501 } 09502 09503 /* Sanity checks */ 09504 if (!sa && !vsa && !tsa && !isa) { 09505 ast_log(LOG_WARNING, "Insufficient information in SDP (c=)...\n"); 09506 return -1; 09507 } 09508 09509 if ((portno == -1) && 09510 (vportno == -1) && 09511 (tportno == -1) && 09512 (udptlportno == -1)) { 09513 ast_log(LOG_WARNING, "Failing due to no acceptable offer found\n"); 09514 return -1; 09515 } 09516 09517 if (secure_audio && !(p->srtp && (ast_test_flag(p->srtp, SRTP_CRYPTO_OFFER_OK)))) { 09518 ast_log(LOG_WARNING, "Can't provide secure audio requested in SDP offer\n"); 09519 return -1; 09520 } 09521 09522 if (!secure_audio && p->srtp) { 09523 ast_log(LOG_WARNING, "We are requesting SRTP for audio, but they responded without it!\n"); 09524 return -1; 09525 } 09526 09527 if (secure_video && !(p->vsrtp && (ast_test_flag(p->vsrtp, SRTP_CRYPTO_OFFER_OK)))) { 09528 ast_log(LOG_WARNING, "Can't provide secure video requested in SDP offer\n"); 09529 return -1; 09530 } 09531 09532 if (!p->novideo && !secure_video && p->vsrtp) { 09533 ast_log(LOG_WARNING, "We are requesting SRTP for video, but they responded without it!\n"); 09534 return -1; 09535 } 09536 09537 if (!(secure_audio || secure_video) && ast_test_flag(&p->flags[1], SIP_PAGE2_USE_SRTP)) { 09538 ast_log(LOG_WARNING, "Matched device setup to use SRTP, but request was not!\n"); 09539 return -1; 09540 } 09541 09542 if (udptlportno == -1) { 09543 change_t38_state(p, T38_DISABLED); 09544 } 09545 09546 /* Now gather all of the codecs that we are asked for: */ 09547 ast_rtp_codecs_payload_formats(&newaudiortp, &peercapability, &peernoncodeccapability); 09548 ast_rtp_codecs_payload_formats(&newvideortp, &vpeercapability, &vpeernoncodeccapability); 09549 ast_rtp_codecs_payload_formats(&newtextrtp, &tpeercapability, &tpeernoncodeccapability); 09550 09551 newjointcapability = p->capability & (peercapability | vpeercapability | tpeercapability); 09552 newpeercapability = (peercapability | vpeercapability | tpeercapability); 09553 newnoncodeccapability = p->noncodeccapability & peernoncodeccapability; 09554 09555 if (debug) { 09556 /* shame on whoever coded this.... */ 09557 char s1[SIPBUFSIZE], s2[SIPBUFSIZE], s3[SIPBUFSIZE], s4[SIPBUFSIZE], s5[SIPBUFSIZE]; 09558 09559 ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s/text=%s, combined - %s\n", 09560 ast_getformatname_multiple(s1, SIPBUFSIZE, p->capability), 09561 ast_getformatname_multiple(s2, SIPBUFSIZE, peercapability), 09562 ast_getformatname_multiple(s3, SIPBUFSIZE, vpeercapability), 09563 ast_getformatname_multiple(s4, SIPBUFSIZE, tpeercapability), 09564 ast_getformatname_multiple(s5, SIPBUFSIZE, newjointcapability)); 09565 } 09566 if (debug) { 09567 struct ast_str *s1 = ast_str_alloca(SIPBUFSIZE); 09568 struct ast_str *s2 = ast_str_alloca(SIPBUFSIZE); 09569 struct ast_str *s3 = ast_str_alloca(SIPBUFSIZE); 09570 09571 ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n", 09572 ast_rtp_lookup_mime_multiple2(s1, p->noncodeccapability, 0, 0), 09573 ast_rtp_lookup_mime_multiple2(s2, peernoncodeccapability, 0, 0), 09574 ast_rtp_lookup_mime_multiple2(s3, newnoncodeccapability, 0, 0)); 09575 } 09576 if (!newjointcapability && udptlportno == -1) { 09577 ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n"); 09578 /* Do NOT Change current setting */ 09579 return -1; 09580 } 09581 09582 if (portno != -1 || vportno != -1 || tportno != -1) { 09583 /* We are now ready to change the sip session and RTP structures with the offered codecs, since 09584 they are acceptable */ 09585 p->jointcapability = newjointcapability; /* Our joint codec profile for this call */ 09586 p->peercapability = newpeercapability; /* The other side's capability in latest offer */ 09587 p->jointnoncodeccapability = newnoncodeccapability; /* DTMF capabilities */ 09588 09589 /* respond with single most preferred joint codec, limiting the other side's choice */ 09590 if (ast_test_flag(&p->flags[1], SIP_PAGE2_PREFERRED_CODEC)) { 09591 p->jointcapability = ast_codec_choose(&p->prefs, p->jointcapability, 1); 09592 } 09593 } 09594 09595 /* Setup audio address and port */ 09596 if (p->rtp) { 09597 if (sa && portno > 0) { 09598 ast_sockaddr_set_port(sa, portno); 09599 ast_rtp_instance_set_remote_address(p->rtp, sa); 09600 if (debug) { 09601 ast_verbose("Peer audio RTP is at port %s\n", 09602 ast_sockaddr_stringify(sa)); 09603 } 09604 09605 ast_rtp_codecs_payloads_copy(&newaudiortp, ast_rtp_instance_get_codecs(p->rtp), p->rtp); 09606 /* Ensure RTCP is enabled since it may be inactive 09607 if we're coming back from a T.38 session */ 09608 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_RTCP, 1); 09609 /* Ensure audio RTCP reads are enabled */ 09610 if (p->owner) { 09611 ast_channel_set_fd(p->owner, 1, ast_rtp_instance_fd(p->rtp, 1)); 09612 } 09613 09614 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) { 09615 ast_clear_flag(&p->flags[0], SIP_DTMF); 09616 if (newnoncodeccapability & AST_RTP_DTMF) { 09617 /* XXX Would it be reasonable to drop the DSP at this point? XXX */ 09618 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 09619 /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */ 09620 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF, 1); 09621 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 09622 } else { 09623 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 09624 } 09625 } 09626 } else if (udptlportno > 0) { 09627 if (debug) 09628 ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session.\n"); 09629 /* Prevent audio RTCP reads */ 09630 if (p->owner) { 09631 ast_channel_set_fd(p->owner, 1, -1); 09632 } 09633 /* Silence RTCP while audio RTP is inactive */ 09634 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_RTCP, 0); 09635 } else { 09636 ast_rtp_instance_stop(p->rtp); 09637 if (debug) 09638 ast_verbose("Peer doesn't provide audio\n"); 09639 } 09640 } 09641 09642 /* Setup video address and port */ 09643 if (p->vrtp) { 09644 if (vsa && vportno > 0) { 09645 ast_sockaddr_set_port(vsa, vportno); 09646 ast_rtp_instance_set_remote_address(p->vrtp, vsa); 09647 if (debug) { 09648 ast_verbose("Peer video RTP is at port %s\n", 09649 ast_sockaddr_stringify(vsa)); 09650 } 09651 ast_rtp_codecs_payloads_copy(&newvideortp, ast_rtp_instance_get_codecs(p->vrtp), p->vrtp); 09652 } else { 09653 ast_rtp_instance_stop(p->vrtp); 09654 if (debug) 09655 ast_verbose("Peer doesn't provide video\n"); 09656 } 09657 } 09658 09659 /* Setup text address and port */ 09660 if (p->trtp) { 09661 if (tsa && tportno > 0) { 09662 ast_sockaddr_set_port(tsa, tportno); 09663 ast_rtp_instance_set_remote_address(p->trtp, tsa); 09664 if (debug) { 09665 ast_verbose("Peer T.140 RTP is at port %s\n", 09666 ast_sockaddr_stringify(tsa)); 09667 } 09668 if ((p->jointcapability & AST_FORMAT_T140RED)) { 09669 p->red = 1; 09670 ast_rtp_red_init(p->trtp, 300, red_data_pt, 2); 09671 } else { 09672 p->red = 0; 09673 } 09674 ast_rtp_codecs_payloads_copy(&newtextrtp, ast_rtp_instance_get_codecs(p->trtp), p->trtp); 09675 } else { 09676 ast_rtp_instance_stop(p->trtp); 09677 if (debug) 09678 ast_verbose("Peer doesn't provide T.140\n"); 09679 } 09680 } 09681 09682 /* Setup image address and port */ 09683 if (p->udptl) { 09684 if (isa && udptlportno > 0) { 09685 if (ast_test_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP) && ast_test_flag(&p->flags[1], SIP_PAGE2_UDPTL_DESTINATION)) { 09686 ast_rtp_instance_get_remote_address(p->rtp, isa); 09687 if (!ast_sockaddr_isnull(isa) && debug) { 09688 ast_debug(1, "Peer T.38 UDPTL is set behind NAT and with destination, destination address now %s\n", ast_sockaddr_stringify(isa)); 09689 } 09690 } 09691 ast_sockaddr_set_port(isa, udptlportno); 09692 ast_udptl_set_peer(p->udptl, isa); 09693 if (debug) 09694 ast_debug(1,"Peer T.38 UDPTL is at port %s\n", ast_sockaddr_stringify(isa)); 09695 09696 /* verify the far max ifp can be calculated. this requires far max datagram to be set. */ 09697 if (!ast_udptl_get_far_max_datagram(p->udptl)) { 09698 /* setting to zero will force a default if none was provided by the SDP */ 09699 ast_udptl_set_far_max_datagram(p->udptl, 0); 09700 } 09701 09702 /* Remote party offers T38, we need to update state */ 09703 if ((t38action == SDP_T38_ACCEPT) && 09704 (p->t38.state == T38_LOCAL_REINVITE)) { 09705 change_t38_state(p, T38_ENABLED); 09706 } else if ((t38action == SDP_T38_INITIATE) && 09707 p->owner && p->lastinvite) { 09708 change_t38_state(p, T38_PEER_REINVITE); /* T38 Offered in re-invite from remote party */ 09709 /* If fax detection is enabled then send us off to the fax extension */ 09710 if (ast_test_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_T38)) { 09711 ast_channel_lock(p->owner); 09712 if (strcmp(p->owner->exten, "fax")) { 09713 const char *target_context = S_OR(p->owner->macrocontext, p->owner->context); 09714 ast_channel_unlock(p->owner); 09715 if (ast_exists_extension(p->owner, target_context, "fax", 1, 09716 S_COR(p->owner->caller.id.number.valid, p->owner->caller.id.number.str, NULL))) { 09717 ast_verbose(VERBOSE_PREFIX_2 "Redirecting '%s' to fax extension due to peer T.38 re-INVITE\n", p->owner->name); 09718 pbx_builtin_setvar_helper(p->owner, "FAXEXTEN", p->owner->exten); 09719 if (ast_async_goto(p->owner, target_context, "fax", 1)) { 09720 ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", p->owner->name, target_context); 09721 } 09722 } else { 09723 ast_log(LOG_NOTICE, "T.38 re-INVITE detected but no fax extension\n"); 09724 } 09725 } else { 09726 ast_channel_unlock(p->owner); 09727 } 09728 } 09729 } 09730 } else { 09731 change_t38_state(p, T38_DISABLED); 09732 ast_udptl_stop(p->udptl); 09733 if (debug) 09734 ast_debug(1, "Peer doesn't provide T.38 UDPTL\n"); 09735 } 09736 } 09737 09738 if ((portno == -1) && (p->t38.state != T38_DISABLED)) { 09739 ast_debug(3, "Have T.38 but no audio, accepting offer anyway\n"); 09740 return 0; 09741 } 09742 09743 /* Ok, we're going with this offer */ 09744 ast_debug(2, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, p->jointcapability)); 09745 09746 if (!p->owner) /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */ 09747 return 0; 09748 09749 ast_debug(4, "We have an owner, now see if we need to change this call\n"); 09750 09751 if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 09752 if (debug) { 09753 char s1[SIPBUFSIZE], s2[SIPBUFSIZE]; 09754 ast_debug(1, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n", 09755 ast_getformatname_multiple(s1, SIPBUFSIZE, p->jointcapability), 09756 ast_getformatname_multiple(s2, SIPBUFSIZE, p->owner->nativeformats)); 09757 } 09758 p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability) | (p->capability & tpeercapability); 09759 ast_set_read_format(p->owner, p->owner->readformat); 09760 ast_set_write_format(p->owner, p->owner->writeformat); 09761 } 09762 09763 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && (!ast_sockaddr_isnull(sa) || !ast_sockaddr_isnull(vsa) || !ast_sockaddr_isnull(tsa) || !ast_sockaddr_isnull(isa)) && (!sendonly || sendonly == -1)) { 09764 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 09765 /* Activate a re-invite */ 09766 ast_queue_frame(p->owner, &ast_null_frame); 09767 change_hold_state(p, req, FALSE, sendonly); 09768 } else if ((sockaddr_is_null_or_any(sa) && sockaddr_is_null_or_any(vsa) && sockaddr_is_null_or_any(tsa) && sockaddr_is_null_or_any(isa)) || (sendonly && sendonly != -1)) { 09769 ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 09770 S_OR(p->mohsuggest, NULL), 09771 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 09772 if (sendonly) 09773 ast_rtp_instance_stop(p->rtp); 09774 /* RTCP needs to go ahead, even if we're on hold!!! */ 09775 /* Activate a re-invite */ 09776 ast_queue_frame(p->owner, &ast_null_frame); 09777 change_hold_state(p, req, TRUE, sendonly); 09778 } 09779 09780 return 0; 09781 }
| static int process_sdp_a_audio | ( | const char * | a, | |
| struct sip_pvt * | p, | |||
| struct ast_rtp_codecs * | newaudiortp, | |||
| int * | last_rtpmap_codec | |||
| ) | [static] |
Definition at line 9909 of file chan_sip.c.
References ast_codec_pref_setsize(), ast_debug, AST_FORMAT_G719, AST_FORMAT_SIREN14, AST_FORMAT_SIREN7, ast_getformatname(), ast_log(), ast_rtp_codecs_packetization_set(), ast_rtp_codecs_payload_lookup(), ast_rtp_codecs_payloads_set_rtpmap_type_rate(), ast_rtp_codecs_payloads_unset(), ast_rtp_instance_get_codecs(), AST_RTP_MAX_PT, AST_RTP_OPT_G726_NONSTANDARD, ast_test_flag, ast_verbose, ast_rtp_payload_type::asterisk_format, ast_rtp_payload_type::code, FALSE, format, LOG_WARNING, ast_rtp_codecs::pref, sip_debug_test_pvt(), and TRUE.
Referenced by process_sdp().
09910 { 09911 int found = FALSE; 09912 unsigned int codec; 09913 char mimeSubtype[128]; 09914 char fmtp_string[64]; 09915 unsigned int sample_rate; 09916 int debug = sip_debug_test_pvt(p); 09917 09918 if (!strncasecmp(a, "ptime", 5)) { 09919 char *tmp = strrchr(a, ':'); 09920 long int framing = 0; 09921 if (tmp) { 09922 tmp++; 09923 framing = strtol(tmp, NULL, 10); 09924 if (framing == LONG_MIN || framing == LONG_MAX) { 09925 framing = 0; 09926 ast_debug(1, "Can't read framing from SDP: %s\n", a); 09927 } 09928 } 09929 if (framing && p->autoframing) { 09930 struct ast_codec_pref *pref = &ast_rtp_instance_get_codecs(p->rtp)->pref; 09931 int codec_n; 09932 for (codec_n = 0; codec_n < AST_RTP_MAX_PT; codec_n++) { 09933 struct ast_rtp_payload_type format = ast_rtp_codecs_payload_lookup(ast_rtp_instance_get_codecs(p->rtp), codec_n); 09934 if (!format.asterisk_format || !format.code) /* non-codec or not found */ 09935 continue; 09936 ast_debug(1, "Setting framing for %s to %ld\n", ast_getformatname(format.code), framing); 09937 ast_codec_pref_setsize(pref, format.code, framing); 09938 } 09939 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, pref); 09940 } 09941 found = TRUE; 09942 } else if (sscanf(a, "rtpmap: %30u %127[^/]/%30u", &codec, mimeSubtype, &sample_rate) == 3) { 09943 /* We have a rtpmap to handle */ 09944 if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 09945 if (!(ast_rtp_codecs_payloads_set_rtpmap_type_rate(newaudiortp, NULL, codec, "audio", mimeSubtype, 09946 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0, sample_rate))) { 09947 if (debug) 09948 ast_verbose("Found audio description format %s for ID %u\n", mimeSubtype, codec); 09949 //found_rtpmap_codecs[last_rtpmap_codec] = codec; 09950 (*last_rtpmap_codec)++; 09951 found = TRUE; 09952 } else { 09953 ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec); 09954 if (debug) 09955 ast_verbose("Found unknown media description format %s for ID %u\n", mimeSubtype, codec); 09956 } 09957 } else { 09958 if (debug) 09959 ast_verbose("Discarded description format %s for ID %u\n", mimeSubtype, codec); 09960 } 09961 } else if (sscanf(a, "fmtp: %30u %63[^\t\n]", &codec, fmtp_string) == 2) { 09962 struct ast_rtp_payload_type payload; 09963 09964 payload = ast_rtp_codecs_payload_lookup(newaudiortp, codec); 09965 if (payload.code && payload.asterisk_format) { 09966 unsigned int bit_rate; 09967 09968 switch (payload.code) { 09969 case AST_FORMAT_SIREN7: 09970 if (sscanf(fmtp_string, "bitrate=%30u", &bit_rate) == 1) { 09971 if (bit_rate != 32000) { 09972 ast_log(LOG_WARNING, "Got Siren7 offer at %u bps, but only 32000 bps supported; ignoring.\n", bit_rate); 09973 ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec); 09974 } else { 09975 found = TRUE; 09976 } 09977 } 09978 break; 09979 case AST_FORMAT_SIREN14: 09980 if (sscanf(fmtp_string, "bitrate=%30u", &bit_rate) == 1) { 09981 if (bit_rate != 48000) { 09982 ast_log(LOG_WARNING, "Got Siren14 offer at %u bps, but only 48000 bps supported; ignoring.\n", bit_rate); 09983 ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec); 09984 } else { 09985 found = TRUE; 09986 } 09987 } 09988 break; 09989 case AST_FORMAT_G719: 09990 if (sscanf(fmtp_string, "bitrate=%30u", &bit_rate) == 1) { 09991 if (bit_rate != 64000) { 09992 ast_log(LOG_WARNING, "Got G.719 offer at %u bps, but only 64000 bps supported; ignoring.\n", bit_rate); 09993 ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec); 09994 } else { 09995 found = TRUE; 09996 } 09997 } 09998 } 09999 } 10000 } 10001 10002 return found; 10003 }
| static int process_sdp_a_image | ( | const char * | a, | |
| struct sip_pvt * | p | |||
| ) | [static] |
Definition at line 10088 of file chan_sip.c.
References ast_debug, ast_strdupa, AST_T38_RATE_12000, AST_T38_RATE_14400, AST_T38_RATE_2400, AST_T38_RATE_4800, AST_T38_RATE_7200, AST_T38_RATE_9600, AST_T38_RATE_MANAGEMENT_LOCAL_TCF, AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF, ast_udptl_set_error_correction_scheme(), ast_udptl_set_far_max_datagram(), FALSE, initialize_udptl(), TRUE, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, and UDPTL_ERROR_CORRECTION_REDUNDANCY.
Referenced by process_sdp().
10089 { 10090 int found = FALSE; 10091 char s[256]; 10092 unsigned int x; 10093 char *attrib = ast_strdupa(a); 10094 char *pos; 10095 10096 if (initialize_udptl(p)) { 10097 return found; 10098 } 10099 10100 /* Due to a typo in an IANA registration of one of the T.38 attributes, 10101 * RFC5347 section 2.5.2 recommends that all T.38 attributes be parsed in 10102 * a case insensitive manner. Hence, the importance of proof reading (and 10103 * code reviews). 10104 */ 10105 for (pos = attrib; *pos; ++pos) { 10106 *pos = tolower(*pos); 10107 } 10108 10109 if ((sscanf(attrib, "t38faxmaxbuffer:%30u", &x) == 1)) { 10110 ast_debug(3, "MaxBufferSize:%u\n", x); 10111 found = TRUE; 10112 } else if ((sscanf(attrib, "t38maxbitrate:%30u", &x) == 1) || (sscanf(attrib, "t38faxmaxrate:%30u", &x) == 1)) { 10113 ast_debug(3, "T38MaxBitRate: %u\n", x); 10114 switch (x) { 10115 case 14400: 10116 p->t38.their_parms.rate = AST_T38_RATE_14400; 10117 break; 10118 case 12000: 10119 p->t38.their_parms.rate = AST_T38_RATE_12000; 10120 break; 10121 case 9600: 10122 p->t38.their_parms.rate = AST_T38_RATE_9600; 10123 break; 10124 case 7200: 10125 p->t38.their_parms.rate = AST_T38_RATE_7200; 10126 break; 10127 case 4800: 10128 p->t38.their_parms.rate = AST_T38_RATE_4800; 10129 break; 10130 case 2400: 10131 p->t38.their_parms.rate = AST_T38_RATE_2400; 10132 break; 10133 } 10134 found = TRUE; 10135 } else if ((sscanf(attrib, "t38faxversion:%30u", &x) == 1)) { 10136 ast_debug(3, "FaxVersion: %u\n", x); 10137 p->t38.their_parms.version = x; 10138 found = TRUE; 10139 } else if ((sscanf(attrib, "t38faxmaxdatagram:%30u", &x) == 1) || (sscanf(attrib, "t38maxdatagram:%30u", &x) == 1)) { 10140 /* override the supplied value if the configuration requests it */ 10141 if (((signed int) p->t38_maxdatagram >= 0) && ((unsigned int) p->t38_maxdatagram > x)) { 10142 ast_debug(1, "Overriding T38FaxMaxDatagram '%u' with '%u'\n", x, p->t38_maxdatagram); 10143 x = p->t38_maxdatagram; 10144 } 10145 ast_debug(3, "FaxMaxDatagram: %u\n", x); 10146 ast_udptl_set_far_max_datagram(p->udptl, x); 10147 found = TRUE; 10148 } else if ((strncmp(attrib, "t38faxfillbitremoval", 20) == 0)) { 10149 if (sscanf(attrib, "t38faxfillbitremoval:%30u", &x) == 1) { 10150 ast_debug(3, "FillBitRemoval: %u\n", x); 10151 if (x == 1) { 10152 p->t38.their_parms.fill_bit_removal = TRUE; 10153 } 10154 } else { 10155 ast_debug(3, "FillBitRemoval\n"); 10156 p->t38.their_parms.fill_bit_removal = TRUE; 10157 } 10158 found = TRUE; 10159 } else if ((strncmp(attrib, "t38faxtranscodingmmr", 20) == 0)) { 10160 if (sscanf(attrib, "t38faxtranscodingmmr:%30u", &x) == 1) { 10161 ast_debug(3, "Transcoding MMR: %u\n", x); 10162 if (x == 1) { 10163 p->t38.their_parms.transcoding_mmr = TRUE; 10164 } 10165 } else { 10166 ast_debug(3, "Transcoding MMR\n"); 10167 p->t38.their_parms.transcoding_mmr = TRUE; 10168 } 10169 found = TRUE; 10170 } else if ((strncmp(attrib, "t38faxtranscodingjbig", 21) == 0)) { 10171 if (sscanf(attrib, "t38faxtranscodingjbig:%30u", &x) == 1) { 10172 ast_debug(3, "Transcoding JBIG: %u\n", x); 10173 if (x == 1) { 10174 p->t38.their_parms.transcoding_jbig = TRUE; 10175 } 10176 } else { 10177 ast_debug(3, "Transcoding JBIG\n"); 10178 p->t38.their_parms.transcoding_jbig = TRUE; 10179 } 10180 found = TRUE; 10181 } else if ((sscanf(attrib, "t38faxratemanagement:%255s", s) == 1)) { 10182 ast_debug(3, "RateManagement: %s\n", s); 10183 if (!strcasecmp(s, "localTCF")) 10184 p->t38.their_parms.rate_management = AST_T38_RATE_MANAGEMENT_LOCAL_TCF; 10185 else if (!strcasecmp(s, "transferredTCF")) 10186 p->t38.their_parms.rate_management = AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF; 10187 found = TRUE; 10188 } else if ((sscanf(attrib, "t38faxudpec:%255s", s) == 1)) { 10189 ast_debug(3, "UDP EC: %s\n", s); 10190 if (!strcasecmp(s, "t38UDPRedundancy")) { 10191 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY); 10192 } else if (!strcasecmp(s, "t38UDPFEC")) { 10193 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC); 10194 } else { 10195 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 10196 } 10197 found = TRUE; 10198 } 10199 10200 return found; 10201 }
| static int process_sdp_a_sendonly | ( | const char * | a, | |
| int * | sendonly | |||
| ) | [static] |
Definition at line 9889 of file chan_sip.c.
Referenced by process_sdp().
09890 { 09891 int found = FALSE; 09892 09893 if (!strcasecmp(a, "sendonly")) { 09894 if (*sendonly == -1) 09895 *sendonly = 1; 09896 found = TRUE; 09897 } else if (!strcasecmp(a, "inactive")) { 09898 if (*sendonly == -1) 09899 *sendonly = 2; 09900 found = TRUE; 09901 } else if (!strcasecmp(a, "sendrecv")) { 09902 if (*sendonly == -1) 09903 *sendonly = 0; 09904 found = TRUE; 09905 } 09906 return found; 09907 }
| static int process_sdp_a_text | ( | const char * | a, | |
| struct sip_pvt * | p, | |||
| struct ast_rtp_codecs * | newtextrtp, | |||
| char * | red_fmtp, | |||
| int * | red_num_gen, | |||
| int * | red_data_pt, | |||
| int * | last_rtpmap_codec | |||
| ) | [static] |
Definition at line 10039 of file chan_sip.c.
References AST_RED_MAX_GENERATION, ast_rtp_codecs_payloads_set_rtpmap_type_rate(), ast_verbose, FALSE, sip_debug_test_pvt(), and TRUE.
Referenced by process_sdp().
10040 { 10041 int found = FALSE; 10042 unsigned int codec; 10043 char mimeSubtype[128]; 10044 unsigned int sample_rate; 10045 char *red_cp; 10046 int debug = sip_debug_test_pvt(p); 10047 10048 if (sscanf(a, "rtpmap: %30u %127[^/]/%30u", &codec, mimeSubtype, &sample_rate) == 3) { 10049 /* We have a rtpmap to handle */ 10050 if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 10051 if (!strncasecmp(mimeSubtype, "T140", 4)) { /* Text */ 10052 if (p->trtp) { 10053 /* ast_verbose("Adding t140 mimeSubtype to textrtp struct\n"); */ 10054 ast_rtp_codecs_payloads_set_rtpmap_type_rate(newtextrtp, NULL, codec, "text", mimeSubtype, 0, sample_rate); 10055 found = TRUE; 10056 } 10057 } else if (!strncasecmp(mimeSubtype, "RED", 3)) { /* Text with Redudancy */ 10058 if (p->trtp) { 10059 ast_rtp_codecs_payloads_set_rtpmap_type_rate(newtextrtp, NULL, codec, "text", mimeSubtype, 0, sample_rate); 10060 sprintf(red_fmtp, "fmtp:%u ", codec); 10061 if (debug) 10062 ast_verbose("RED submimetype has payload type: %u\n", codec); 10063 found = TRUE; 10064 } 10065 } 10066 } else { 10067 if (debug) 10068 ast_verbose("Discarded description format %s for ID %u\n", mimeSubtype, codec); 10069 } 10070 } else if (!strncmp(a, red_fmtp, strlen(red_fmtp))) { 10071 /* count numbers of generations in fmtp */ 10072 red_cp = &red_fmtp[strlen(red_fmtp)]; 10073 strncpy(red_fmtp, a, 100); 10074 10075 sscanf(red_cp, "%30u", (unsigned *)&red_data_pt[*red_num_gen]); 10076 red_cp = strtok(red_cp, "/"); 10077 while (red_cp && (*red_num_gen)++ < AST_RED_MAX_GENERATION) { 10078 sscanf(red_cp, "%30u", (unsigned *)&red_data_pt[*red_num_gen]); 10079 red_cp = strtok(NULL, "/"); 10080 } 10081 red_cp = red_fmtp; 10082 found = TRUE; 10083 } 10084 10085 return found; 10086 }
| static int process_sdp_a_video | ( | const char * | a, | |
| struct sip_pvt * | p, | |||
| struct ast_rtp_codecs * | newvideortp, | |||
| int * | last_rtpmap_codec | |||
| ) | [static] |
Definition at line 10005 of file chan_sip.c.
References ast_rtp_codecs_payloads_set_rtpmap_type_rate(), ast_rtp_codecs_payloads_unset(), ast_verbose, FALSE, sip_debug_test_pvt(), and TRUE.
Referenced by process_sdp().
10006 { 10007 int found = FALSE; 10008 unsigned int codec; 10009 char mimeSubtype[128]; 10010 unsigned int sample_rate; 10011 int debug = sip_debug_test_pvt(p); 10012 10013 if (sscanf(a, "rtpmap: %30u %127[^/]/%30u", &codec, mimeSubtype, &sample_rate) == 3) { 10014 /* We have a rtpmap to handle */ 10015 if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 10016 /* Note: should really look at the '#chans' params too */ 10017 if (!strncasecmp(mimeSubtype, "H26", 3) || !strncasecmp(mimeSubtype, "MP4", 3)) { 10018 if (!(ast_rtp_codecs_payloads_set_rtpmap_type_rate(newvideortp, NULL, codec, "video", mimeSubtype, 0, sample_rate))) { 10019 if (debug) 10020 ast_verbose("Found video description format %s for ID %u\n", mimeSubtype, codec); 10021 //found_rtpmap_codecs[last_rtpmap_codec] = codec; 10022 (*last_rtpmap_codec)++; 10023 found = TRUE; 10024 } else { 10025 ast_rtp_codecs_payloads_unset(newvideortp, NULL, codec); 10026 if (debug) 10027 ast_verbose("Found unknown media description format %s for ID %u\n", mimeSubtype, codec); 10028 } 10029 } 10030 } else { 10031 if (debug) 10032 ast_verbose("Discarded description format %s for ID %u\n", mimeSubtype, codec); 10033 } 10034 } 10035 10036 return found; 10037 }
| static int process_sdp_c | ( | const char * | c, | |
| struct ast_sockaddr * | addr | |||
| ) | [static] |
Definition at line 9862 of file chan_sip.c.
References ast_log(), ast_sockaddr_resolve_first_af(), FALSE, LOG_WARNING, and TRUE.
Referenced by process_sdp().
09863 { 09864 char proto[4], host[258]; 09865 int af; 09866 09867 /* Check for Media-description-level-address */ 09868 if (sscanf(c, "IN %3s %255s", proto, host) == 2) { 09869 if (!strcmp("IP4", proto)) { 09870 af = AF_INET; 09871 } else if (!strcmp("IP6", proto)) { 09872 af = AF_INET6; 09873 } else { 09874 ast_log(LOG_WARNING, "Unknown protocol '%s'.\n", proto); 09875 return FALSE; 09876 } 09877 if (ast_sockaddr_resolve_first_af(addr, host, 0, af)) { 09878 ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in c= line, '%s'\n", c); 09879 return FALSE; 09880 } 09881 return TRUE; 09882 } else { 09883 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 09884 return FALSE; 09885 } 09886 return FALSE; 09887 }
| static int process_sdp_o | ( | const char * | o, | |
| struct sip_pvt * | p | |||
| ) | [static] |
Definition at line 9783 of file chan_sip.c.
References ast_debug, ast_log(), ast_strdupa, ast_strlen_zero(), ast_test_flag, FALSE, LOG_WARNING, and TRUE.
Referenced by process_sdp().
09784 { 09785 char *o_copy; 09786 char *token; 09787 int64_t rua_version; 09788 09789 /* Store the SDP version number of remote UA. This will allow us to 09790 distinguish between session modifications and session refreshes. If 09791 the remote UA does not send an incremented SDP version number in a 09792 subsequent RE-INVITE then that means its not changing media session. 09793 The RE-INVITE may have been sent to update connected party, remote 09794 target or to refresh the session (Session-Timers). Asterisk must not 09795 change media session and increment its own version number in answer 09796 SDP in this case. */ 09797 09798 p->session_modify = TRUE; 09799 09800 if (ast_strlen_zero(o)) { 09801 ast_log(LOG_WARNING, "SDP syntax error. SDP without an o= line\n"); 09802 return FALSE; 09803 } 09804 09805 o_copy = ast_strdupa(o); 09806 token = strsep(&o_copy, " "); /* Skip username */ 09807 if (!o_copy) { 09808 ast_log(LOG_WARNING, "SDP syntax error in o= line username\n"); 09809 return FALSE; 09810 } 09811 token = strsep(&o_copy, " "); /* Skip session-id */ 09812 if (!o_copy) { 09813 ast_log(LOG_WARNING, "SDP syntax error in o= line session-id\n"); 09814 return FALSE; 09815 } 09816 token = strsep(&o_copy, " "); /* Version */ 09817 if (!o_copy) { 09818 ast_log(LOG_WARNING, "SDP syntax error in o= line\n"); 09819 return FALSE; 09820 } 09821 if (!sscanf(token, "%30" SCNd64, &rua_version)) { 09822 ast_log(LOG_WARNING, "SDP syntax error in o= line version\n"); 09823 return FALSE; 09824 } 09825 09826 /* we need to check the SDP version number the other end sent us; 09827 * our rules for deciding what to accept are a bit complex. 09828 * 09829 * 1) if 'ignoresdpversion' has been set for this dialog, then 09830 * we will just accept whatever they sent and assume it is 09831 * a modification of the session, even if it is not 09832 * 2) otherwise, if this is the first SDP we've seen from them 09833 * we accept it 09834 * 3) otherwise, if the new SDP version number is higher than the 09835 * old one, we accept it 09836 * 4) otherwise, if this SDP is in response to us requesting a switch 09837 * to T.38, we accept the SDP, but also generate a warning message 09838 * that this peer should have the 'ignoresdpversion' option set, 09839 * because it is not following the SDP offer/answer RFC; if we did 09840 * not request a switch to T.38, then we stop parsing the SDP, as it 09841 * has not changed from the previous version 09842 */ 09843 09844 if (ast_test_flag(&p->flags[1], SIP_PAGE2_IGNORESDPVERSION) || 09845 (p->sessionversion_remote < 0) || 09846 (p->sessionversion_remote < rua_version)) { 09847 p->sessionversion_remote = rua_version; 09848 } else { 09849 if (p->t38.state == T38_LOCAL_REINVITE) { 09850 p->sessionversion_remote = rua_version; 09851 ast_log(LOG_WARNING, "Call %s responded to our T.38 reinvite without changing SDP version; 'ignoresdpversion' should be set for this peer.\n", p->callid); 09852 } else { 09853 p->session_modify = FALSE; 09854 ast_debug(2, "Call %s responded to our reinvite without changing SDP version; ignoring SDP.\n", p->callid); 09855 return FALSE; 09856 } 09857 } 09858 09859 return TRUE; 09860 }
| static int process_via | ( | struct sip_pvt * | p, | |
| const struct sip_request * | req | |||
| ) | [static] |
Process the Via header according to RFC 3261 section 18.2.2.
| p | a sip_pvt structure that will be modified according to the received header | |
| req | a sip request with a Via header to process |
This function will update the destination of the response according to the Via header in the request and RFC 3261 section 18.2.2. We do not have a transport layer so we ignore certain values like the 'received' param (we set the destination address to the addres the request came from in the respprep() function).
| -1 | error | |
| 0 | success |
Definition at line 8128 of file chan_sip.c.
References addr_is_multicast(), ast_log(), ast_sockaddr_resolve_first_transport(), ast_sockaddr_set_port, free_via(), get_header(), LOG_ERROR, LOG_WARNING, PARSE_PORT_FORBID, and parse_via().
Referenced by respprep().
08129 { 08130 struct sip_via *via = parse_via(get_header(req, "Via")); 08131 08132 if (!via) { 08133 ast_log(LOG_ERROR, "error processing via header\n"); 08134 return -1; 08135 } 08136 08137 if (via->maddr) { 08138 if (ast_sockaddr_resolve_first_transport(&p->sa, via->maddr, PARSE_PORT_FORBID, p->socket.type)) { 08139 ast_log(LOG_WARNING, "Can't find address for maddr '%s'\n", via->maddr); 08140 ast_log(LOG_ERROR, "error processing via header\n"); 08141 free_via(via); 08142 return -1; 08143 } 08144 08145 if (addr_is_multicast(&p->sa)) { 08146 setsockopt(sipsock, IPPROTO_IP, IP_MULTICAST_TTL, &via->ttl, sizeof(via->ttl)); 08147 } 08148 } 08149 08150 ast_sockaddr_set_port(&p->sa, via->port ? via->port : STANDARD_SIP_PORT); 08151 08152 free_via(via); 08153 return 0; 08154 }
| static struct sip_proxy* proxy_from_config | ( | const char * | proxy, | |
| int | sipconf_lineno, | |||
| struct sip_proxy * | dest | |||
| ) | [static, read] |
Parse proxy string and return an ao2_alloc'd proxy. If dest is non-NULL, no allocation is performed and dest is used instead. On error NULL is returned.
Definition at line 3244 of file chan_sip.c.
References ao2_alloc, ao2_ref, ast_copy_string(), ast_log(), ast_skip_blanks(), ast_strdupa, ast_strlen_zero(), FALSE, LOG_WARNING, name, proxy_update(), and sip_parse_host().
Referenced by build_peer(), reload_config(), and sip_request_call().
03245 { 03246 char *mutable_proxy, *sep, *name; 03247 int allocated = 0; 03248 03249 if (!dest) { 03250 dest = ao2_alloc(sizeof(struct sip_proxy), NULL); 03251 if (!dest) { 03252 ast_log(LOG_WARNING, "Unable to allocate config storage for proxy\n"); 03253 return NULL; 03254 } 03255 allocated = 1; 03256 } 03257 03258 /* Format is: [transport://]name[:port][,force] */ 03259 mutable_proxy = ast_skip_blanks(ast_strdupa(proxy)); 03260 sep = strchr(mutable_proxy, ','); 03261 if (sep) { 03262 *sep++ = '\0'; 03263 dest->force = !strncasecmp(ast_skip_blanks(sep), "force", 5); 03264 } else { 03265 dest->force = FALSE; 03266 } 03267 03268 sip_parse_host(mutable_proxy, sipconf_lineno, &name, &dest->port, &dest->transport); 03269 03270 /* Check that there is a name at all */ 03271 if (ast_strlen_zero(name)) { 03272 if (allocated) { 03273 ao2_ref(dest, -1); 03274 } else { 03275 dest->name[0] = '\0'; 03276 } 03277 return NULL; 03278 } 03279 ast_copy_string(dest->name, name, sizeof(dest->name)); 03280 03281 /* Resolve host immediately */ 03282 proxy_update(dest); 03283 03284 return dest; 03285 }
| static int proxy_update | ( | struct sip_proxy * | proxy | ) | [static] |
Resolve DNS srv name or host name in a sip_proxy structure
Definition at line 3220 of file chan_sip.c.
References ast_get_ip_or_srv(), ast_log(), ast_sockaddr_parse(), ast_sockaddr_set_port, FALSE, get_address_family_filter(), LOG_WARNING, sip_cfg, and TRUE.
Referenced by proxy_from_config().
03221 { 03222 /* if it's actually an IP address and not a name, 03223 there's no need for a managed lookup */ 03224 if (!ast_sockaddr_parse(&proxy->ip, proxy->name, 0)) { 03225 /* Ok, not an IP address, then let's check if it's a domain or host */ 03226 /* XXX Todo - if we have proxy port, don't do SRV */ 03227 proxy->ip.ss.ss_family = get_address_family_filter(SIP_TRANSPORT_UDP); /* Filter address family */ 03228 if (ast_get_ip_or_srv(&proxy->ip, proxy->name, sip_cfg.srvlookup ? "_sip._udp" : NULL) < 0) { 03229 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", proxy->name); 03230 return FALSE; 03231 } 03232 03233 } 03234 03235 ast_sockaddr_set_port(&proxy->ip, proxy->port); 03236 03237 proxy->last_dnsupdate = time(NULL); 03238 return TRUE; 03239 }
| static int publish_expire | ( | const void * | data | ) | [static] |
Definition at line 1009 of file chan_sip.c.
References ao2_ref, ao2_unlink, ast_assert, event_state_compositor::compositor, and get_esc().
Referenced by create_esc_entry(), handle_sip_publish_modify(), and handle_sip_publish_refresh().
01010 { 01011 struct sip_esc_entry *esc_entry = (struct sip_esc_entry *) data; 01012 struct event_state_compositor *esc = get_esc(esc_entry->event); 01013 01014 ast_assert(esc != NULL); 01015 01016 ao2_unlink(esc->compositor, esc_entry); 01017 ao2_ref(esc_entry, -1); 01018 return 0; 01019 }
| static void pvt_set_needdestroy | ( | struct sip_pvt * | pvt, | |
| const char * | reason | |||
| ) | [inline, static] |
Definition at line 3185 of file chan_sip.c.
References append_history.
Referenced by __sip_autodestruct(), handle_incoming(), handle_request_publish(), handle_request_refer(), handle_request_subscribe(), handle_response(), handle_response_invite(), handle_response_notify(), handle_response_peerpoke(), handle_response_publish(), handle_response_refer(), handle_response_register(), handle_response_subscribe(), retrans_pkt(), sip_hangup(), and sip_reg_timeout().
03186 { 03187 if (pvt->final_destruction_scheduled) { 03188 return; /* This is already scheduled for final destruction, let the scheduler take care of it. */ 03189 } 03190 append_history(pvt, "NeedDestroy", "Setting needdestroy because %s", reason); 03191 pvt->needdestroy = 1; 03192 }
| static int read_raw_content_length | ( | const char * | message | ) | [static] |
Get the content length from an unparsed SIP message.
Definition at line 2532 of file chan_sip.c.
References ast_free, ast_str_buffer(), ast_str_create(), ast_str_set(), lws2sws(), and sip_cfg.
Referenced by check_message_integrity().
02533 { 02534 char *content_length_str; 02535 int content_length = -1; 02536 02537 struct ast_str *msg_copy; 02538 char *msg; 02539 02540 /* Using a ast_str because lws2sws takes one of those */ 02541 if (!(msg_copy = ast_str_create(strlen(message) + 1))) { 02542 return -1; 02543 } 02544 ast_str_set(&msg_copy, 0, "%s", message); 02545 02546 if (sip_cfg.pedanticsipchecking) { 02547 lws2sws(msg_copy); 02548 } 02549 02550 msg = ast_str_buffer(msg_copy); 02551 02552 /* Let's find a Content-Length header */ 02553 if ((content_length_str = strcasestr(msg, "\nContent-Length:"))) { 02554 content_length_str += sizeof("\nContent-Length:") - 1; 02555 } else if ((content_length_str = strcasestr(msg, "\nl:"))) { 02556 content_length_str += sizeof("\nl:") - 1; 02557 } else { 02558 /* RFC 3261 18.3 02559 * "In the case of stream-oriented transports such as TCP, the Content- 02560 * Length header field indicates the size of the body. The Content- 02561 * Length header field MUST be used with stream oriented transports." 02562 */ 02563 goto done; 02564 } 02565 02566 /* Double-check that this is a complete header */ 02567 if (!strchr(content_length_str, '\n')) { 02568 goto done; 02569 } 02570 02571 if (sscanf(content_length_str, "%30d", &content_length) != 1) { 02572 content_length = -1; 02573 } 02574 02575 done: 02576 ast_free(msg_copy); 02577 return content_length; 02578 }
| static struct sip_peer * realtime_peer | ( | const char * | newpeername, | |
| struct ast_sockaddr * | addr, | |||
| int | devstate_only, | |||
| int | which_objects | |||
| ) | [static, read] |
realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf Checks the "sipregs" realtime family from extconfig.conf if it's configured. This returns a pointer to a peer and because we use build_peer, we can rest assured that the refcount is bumped.
Definition at line 5145 of file chan_sip.c.
References ao2_t_link, ast_check_realtime(), ast_copy_flags, ast_copy_string(), ast_debug, AST_SCHED_REPLACE_UNREF, ast_sockaddr_isnull(), ast_sockaddr_stringify_addr(), ast_test_flag, ast_variables_destroy(), build_peer(), cleanup(), expire_register(), ipaddr, ast_variable::name, ast_variable::next, realtime_peer_by_addr(), realtime_peer_by_name(), ref_peer(), sip_cfg, TRUE, unref_peer(), ast_variable::value, and var.
Referenced by find_peer().
05146 { 05147 struct sip_peer *peer = NULL; 05148 struct ast_variable *var = NULL; 05149 struct ast_variable *varregs = NULL; 05150 char ipaddr[INET6_ADDRSTRLEN]; 05151 int realtimeregs = ast_check_realtime("sipregs"); 05152 05153 if (addr) { 05154 ast_copy_string(ipaddr, ast_sockaddr_stringify_addr(addr), sizeof(ipaddr)); 05155 } else { 05156 ipaddr[0] = '\0'; 05157 } 05158 05159 if (newpeername && realtime_peer_by_name(&newpeername, addr, ipaddr, &var, realtimeregs ? &varregs : NULL)) { 05160 ; 05161 } else if (addr && realtime_peer_by_addr(&newpeername, addr, ipaddr, &var, realtimeregs ? &varregs : NULL)) { 05162 ; 05163 } else { 05164 return NULL; 05165 } 05166 05167 /* If we're looking for users, don't return peers (although this check 05168 * should probably be done in realtime_peer_by_* instead...) */ 05169 if (which_objects == FINDUSERS) { 05170 struct ast_variable *tmp; 05171 for (tmp = var; tmp; tmp = tmp->next) { 05172 if (!strcasecmp(tmp->name, "type") && (!strcasecmp(tmp->value, "peer"))) { 05173 goto cleanup; 05174 } 05175 } 05176 } 05177 05178 /* Peer found in realtime, now build it in memory */ 05179 peer = build_peer(newpeername, var, varregs, TRUE, devstate_only); 05180 if (!peer) { 05181 goto cleanup; 05182 } 05183 05184 /* Previous versions of Asterisk did not require the type field to be 05185 * set for real time peers. This statement preserves that behavior. */ 05186 if (peer->type == 0) { 05187 if (which_objects == FINDUSERS) { 05188 peer->type = SIP_TYPE_USER; 05189 } else if (which_objects == FINDPEERS) { 05190 peer->type = SIP_TYPE_PEER; 05191 } else { 05192 peer->type = SIP_TYPE_PEER | SIP_TYPE_USER; 05193 } 05194 } 05195 05196 ast_debug(3, "-REALTIME- loading peer from database to memory. Name: %s. Peer objects: %d\n", peer->name, rpeerobjs); 05197 05198 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && !devstate_only) { 05199 /* Cache peer */ 05200 ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS); 05201 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 05202 AST_SCHED_REPLACE_UNREF(peer->expire, sched, sip_cfg.rtautoclear * 1000, expire_register, peer, 05203 unref_peer(_data, "remove registration ref"), 05204 unref_peer(peer, "remove registration ref"), 05205 ref_peer(peer, "add registration ref")); 05206 } 05207 ao2_t_link(peers, peer, "link peer into peers table"); 05208 if (!ast_sockaddr_isnull(&peer->addr)) { 05209 ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table"); 05210 } 05211 } 05212 peer->is_realtime = 1; 05213 05214 cleanup: 05215 ast_variables_destroy(var); 05216 ast_variables_destroy(varregs); 05217 return peer; 05218 }
| static int realtime_peer_by_addr | ( | const char ** | name, | |
| struct ast_sockaddr * | addr, | |||
| const char * | ipaddr, | |||
| struct ast_variable ** | var, | |||
| struct ast_variable ** | varregs | |||
| ) | [static] |
Definition at line 5076 of file chan_sip.c.
References ast_copy_string(), ast_load_realtime(), ast_log(), ast_sockaddr_stringify_port(), ast_variables_destroy(), get_insecure_variable_from_sippeers(), get_insecure_variable_from_sipregs(), get_name_from_variable(), LOG_WARNING, realtime_peer_get_sippeer_helper(), and SENTINEL.
Referenced by realtime_peer().
05077 { 05078 char portstring[6]; /* up to 5 digits plus null terminator */ 05079 ast_copy_string(portstring, ast_sockaddr_stringify_port(addr), sizeof(portstring)); 05080 05081 /* We're not finding this peer by this name anymore. Reset it. */ 05082 *name = NULL; 05083 05084 /* First check for fixed IP hosts */ 05085 if ((*var = ast_load_realtime("sippeers", "host", ipaddr, "port", portstring, SENTINEL))) { 05086 ; 05087 /* Check for registered hosts (in sipregs) */ 05088 } else if (varregs && (*varregs = ast_load_realtime("sipregs", "ipaddr", ipaddr, "port", portstring, SENTINEL)) && 05089 (*var = realtime_peer_get_sippeer_helper(name, varregs))) { 05090 ; 05091 /* Check for registered hosts (in sippeers) */ 05092 } else if (!varregs && (*var = ast_load_realtime("sippeers", "ipaddr", ipaddr, "port", portstring, SENTINEL))) { 05093 ; 05094 /* We couldn't match on ipaddress and port, so we need to check if port is insecure */ 05095 } else if ((*var = get_insecure_variable_from_sippeers("host", ipaddr))) { 05096 ; 05097 /* Same as above, but try the IP address field (in sipregs) 05098 * Observe that it fetches the name/var at the same time, without the 05099 * realtime_peer_get_sippeer_helper. Also note that it is quite inefficient. 05100 * Avoid sipregs if possible. */ 05101 } else if (varregs && (*varregs = get_insecure_variable_from_sipregs("ipaddr", ipaddr, var))) { 05102 ; 05103 /* Same as above, but try the IP address field (in sippeers) */ 05104 } else if (!varregs && (*var = get_insecure_variable_from_sippeers("ipaddr", ipaddr))) { 05105 ; 05106 } 05107 05108 /* Nothing found? */ 05109 if (!*var) { 05110 return 0; 05111 } 05112 05113 /* Check peer name. It must not be empty. There may exist a 05114 * different match that does have a name, but it's too late for 05115 * that now. */ 05116 if (!*name && !(*name = get_name_from_variable(*var))) { 05117 ast_log(LOG_WARNING, "Found peer for IP %s but it has no name\n", ipaddr); 05118 ast_variables_destroy(*var); 05119 *var = NULL; 05120 if (varregs && *varregs) { 05121 ast_variables_destroy(*varregs); 05122 *varregs = NULL; 05123 } 05124 return 0; 05125 } 05126 05127 /* Make sure varregs is populated if var is. The inverse, 05128 * ensuring that var is set when varregs is, is taken 05129 * care of by realtime_peer_get_sippeer_helper(). */ 05130 if (varregs && !*varregs) { 05131 *varregs = ast_load_realtime("sipregs", "name", *name, SENTINEL); 05132 } 05133 return 1; 05134 }
| static int realtime_peer_by_name | ( | const char *const * | name, | |
| struct ast_sockaddr * | addr, | |||
| const char * | ipaddr, | |||
| struct ast_variable ** | var, | |||
| struct ast_variable ** | varregs | |||
| ) | [static] |
Definition at line 5004 of file chan_sip.c.
References ast_free, ast_load_realtime(), ast_sockaddr_cmp(), ast_sockaddr_resolve(), ast_variables_destroy(), get_address_family_filter(), ast_variable::name, ast_variable::next, PARSE_PORT_FORBID, SENTINEL, and ast_variable::value.
Referenced by realtime_peer().
05005 { 05006 /* Peer by name and host=dynamic */ 05007 if ((*var = ast_load_realtime("sippeers", "name", *name, "host", "dynamic", SENTINEL))) { 05008 ; 05009 /* Peer by name and host=IP */ 05010 } else if (addr && !(*var = ast_load_realtime("sippeers", "name", *name, "host", ipaddr, SENTINEL))) { 05011 ; 05012 /* Peer by name and host=HOSTNAME */ 05013 } else if ((*var = ast_load_realtime("sippeers", "name", *name, SENTINEL))) { 05014 /*!\note 05015 * If this one loaded something, then we need to ensure that the host 05016 * field matched. The only reason why we can't have this as a criteria 05017 * is because we only have the IP address and the host field might be 05018 * set as a name (and the reverse PTR might not match). 05019 */ 05020 if (addr) { 05021 struct ast_variable *tmp; 05022 for (tmp = *var; tmp; tmp = tmp->next) { 05023 if (!strcasecmp(tmp->name, "host")) { 05024 struct ast_sockaddr *addrs = NULL; 05025 05026 if (ast_sockaddr_resolve(&addrs, 05027 tmp->value, 05028 PARSE_PORT_FORBID, 05029 get_address_family_filter(SIP_TRANSPORT_UDP)) <= 0 || 05030 ast_sockaddr_cmp(&addrs[0], addr)) { 05031 /* No match */ 05032 ast_variables_destroy(*var); 05033 *var = NULL; 05034 } 05035 ast_free(addrs); 05036 break; 05037 } 05038 } 05039 } 05040 } 05041 05042 /* Did we find anything? */ 05043 if (*var) { 05044 if (varregs) { 05045 *varregs = ast_load_realtime("sipregs", "name", *name, SENTINEL); 05046 } 05047 return 1; 05048 } 05049 return 0; 05050 }
| static struct ast_variable* realtime_peer_get_sippeer_helper | ( | const char ** | name, | |
| struct ast_variable ** | varregs | |||
| ) | [static, read] |
Definition at line 5058 of file chan_sip.c.
References ast_load_realtime(), ast_log(), ast_variables_destroy(), get_name_from_variable(), LOG_WARNING, SENTINEL, and var.
Referenced by realtime_peer_by_addr().
05058 { 05059 struct ast_variable *var = NULL; 05060 const char *old_name = *name; 05061 *name = get_name_from_variable(*varregs); 05062 if (!*name || !(var = ast_load_realtime("sippeers", "name", *name, SENTINEL))) { 05063 if (!*name) { 05064 ast_log(LOG_WARNING, "Found sipreg but it has no name\n"); 05065 } 05066 ast_variables_destroy(*varregs); 05067 *varregs = NULL; 05068 *name = old_name; 05069 } 05070 return var; 05071 }
| static void realtime_update_peer | ( | const char * | peername, | |
| struct ast_sockaddr * | addr, | |||
| const char * | username, | |||
| const char * | fullcontact, | |||
| const char * | useragent, | |||
| int | expirey, | |||
| unsigned short | deprecated_username, | |||
| int | lastms | |||
| ) | [static] |
Update peer object in realtime storage If the Asterisk system name is set in asterisk.conf, we will use that name and store that in the "regserver" field in the sippeers table to facilitate multi-server setups.
Definition at line 4714 of file chan_sip.c.
References ast_check_realtime(), ast_config_AST_SYSTEM_NAME, ast_copy_string(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_sockaddr_stringify_port(), ast_strlen_zero(), ast_update_realtime(), ipaddr, SENTINEL, and sip_cfg.
Referenced by update_peer().
04715 { 04716 char port[10]; 04717 char ipaddr[INET6_ADDRSTRLEN]; 04718 char regseconds[20]; 04719 char *tablename = NULL; 04720 char str_lastms[20]; 04721 04722 const char *sysname = ast_config_AST_SYSTEM_NAME; 04723 char *syslabel = NULL; 04724 04725 time_t nowtime = time(NULL) + expirey; 04726 const char *fc = fullcontact ? "fullcontact" : NULL; 04727 04728 int realtimeregs = ast_check_realtime("sipregs"); 04729 04730 tablename = realtimeregs ? "sipregs" : "sippeers"; 04731 04732 04733 snprintf(str_lastms, sizeof(str_lastms), "%d", lastms); 04734 snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); /* Expiration time */ 04735 ast_copy_string(ipaddr, ast_sockaddr_isnull(addr) ? "" : ast_sockaddr_stringify_addr(addr), sizeof(ipaddr)); 04736 ast_copy_string(port, ast_sockaddr_port(addr) ? ast_sockaddr_stringify_port(addr) : "", sizeof(port)); 04737 04738 if (ast_strlen_zero(sysname)) /* No system name, disable this */ 04739 sysname = NULL; 04740 else if (sip_cfg.rtsave_sysname) 04741 syslabel = "regserver"; 04742 04743 /* XXX IMPORTANT: Anytime you add a new parameter to be updated, you 04744 * must also add it to contrib/scripts/asterisk.ldap-schema, 04745 * contrib/scripts/asterisk.ldif, 04746 * and to configs/res_ldap.conf.sample as described in 04747 * bugs 15156 and 15895 04748 */ 04749 if (fc) { 04750 ast_update_realtime(tablename, "name", peername, "ipaddr", ipaddr, 04751 "port", port, "regseconds", regseconds, 04752 deprecated_username ? "username" : "defaultuser", defaultuser, 04753 "useragent", useragent, "lastms", str_lastms, 04754 fc, fullcontact, syslabel, sysname, SENTINEL); /* note fc and syslabel _can_ be NULL */ 04755 } else { 04756 ast_update_realtime(tablename, "name", peername, "ipaddr", ipaddr, 04757 "port", port, "regseconds", regseconds, 04758 "useragent", useragent, "lastms", str_lastms, 04759 deprecated_username ? "username" : "defaultuser", defaultuser, 04760 syslabel, sysname, SENTINEL); /* note syslabel _can_ be NULL */ 04761 } 04762 }
| static void receive_message | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Receive SIP MESSAGE method messages.
Definition at line 16886 of file chan_sip.c.
References AST_FRAME_TEXT, ast_log(), ast_queue_frame(), ast_verbose, ast_frame::data, ast_frame::datalen, f, ast_frame::frametype, get_header(), get_msg_text(), ast_frame_subclass::integer, LOG_WARNING, ast_frame::offset, ast_frame::ptr, sip_debug_test_pvt(), sip_scheddestroy(), ast_frame::subclass, and transmit_response().
Referenced by handle_request_message().
16887 { 16888 char buf[1400]; 16889 char *bufp; 16890 struct ast_frame f; 16891 const char *content_type = get_header(req, "Content-Type"); 16892 16893 if (strncmp(content_type, "text/plain", strlen("text/plain"))) { /* No text/plain attachment */ 16894 transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */ 16895 if (!p->owner) 16896 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16897 return; 16898 } 16899 16900 if (get_msg_text(buf, sizeof(buf), req)) { 16901 ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); 16902 transmit_response(p, "500 Internal Server Error", req); 16903 if (!p->owner) { 16904 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16905 } 16906 return; 16907 } 16908 16909 /* Strip trailing line feeds from message body. (get_msg_text may add 16910 * a trailing linefeed and we don't need any at the end) */ 16911 bufp = buf + strlen(buf); 16912 while (--bufp >= buf && *bufp == '\n') { 16913 *bufp = '\0'; 16914 } 16915 16916 if (p->owner) { 16917 if (sip_debug_test_pvt(p)) 16918 ast_verbose("SIP Text message received: '%s'\n", buf); 16919 memset(&f, 0, sizeof(f)); 16920 f.frametype = AST_FRAME_TEXT; 16921 f.subclass.integer = 0; 16922 f.offset = 0; 16923 f.data.ptr = buf; 16924 f.datalen = strlen(buf) + 1; 16925 ast_queue_frame(p->owner, &f); 16926 transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */ 16927 return; 16928 } 16929 16930 /* Message outside of a call, we do not support that */ 16931 ast_log(LOG_WARNING, "Received message to %s from %s, dropped it...\n Content-Type:%s\n Message: %s\n", get_header(req, "To"), get_header(req, "From"), content_type, buf); 16932 transmit_response(p, "405 Method Not Allowed", req); 16933 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16934 return; 16935 }
| static struct sip_peer* ref_peer | ( | struct sip_peer * | peer, | |
| char * | tag | |||
| ) | [static, read] |
Definition at line 2985 of file chan_sip.c.
References ao2_t_ref.
Referenced by build_peer(), check_peer_ok(), create_addr(), handle_request_invite(), handle_request_subscribe(), handle_response_peerpoke(), parse_register_contact(), realtime_peer(), reg_source_db(), register_verify(), sip_poke_all_peers(), sip_poke_noanswer(), sip_poke_peer(), sip_unregister(), and update_call_counter().
02986 { 02987 ao2_t_ref(peer, 1, tag); 02988 return peer; 02989 }
| static void ref_proxy | ( | struct sip_pvt * | pvt, | |
| struct sip_proxy * | proxy | |||
| ) | [static] |
maintain proper refcounts for a sip_pvt's outboundproxy
This function sets pvt's outboundproxy pointer to the one referenced by the proxy parameter. Because proxy may be a refcounted object, and because pvt's old outboundproxy may also be a refcounted object, we need to maintain the proper refcounts.
| pvt | The sip_pvt for which we wish to set the outboundproxy | |
| proxy | The sip_proxy which we will point pvt towards. |
Definition at line 3058 of file chan_sip.c.
References ao2_ref, and sip_cfg.
Referenced by __sip_ack(), __sip_destroy(), __sip_subscribe_mwi_do(), create_addr(), create_addr_from_peer(), and sip_poke_peer().
03059 { 03060 struct sip_proxy *old_obproxy = pvt->outboundproxy; 03061 /* The sip_cfg.outboundproxy is statically allocated, and so 03062 * we don't ever need to adjust refcounts for it 03063 */ 03064 if (proxy && proxy != &sip_cfg.outboundproxy) { 03065 ao2_ref(proxy, +1); 03066 } 03067 pvt->outboundproxy = proxy; 03068 if (old_obproxy && old_obproxy != &sip_cfg.outboundproxy) { 03069 ao2_ref(old_obproxy, -1); 03070 } 03071 }
| static const char * referstatus2str | ( | enum referstatus | rstatus | ) | [static] |
Convert transfer status to string.
Definition at line 3180 of file chan_sip.c.
References map_x_s().
Referenced by show_channels_cb().
03181 { 03182 return map_x_s(referstatusstrings, rstatus, ""); 03183 }
| static void reg_source_db | ( | struct sip_peer * | peer | ) | [static] |
Get registration details from Asterisk DB.
Definition at line 14292 of file chan_sip.c.
References args, AST_APP_ARG, ast_db_get(), ast_debug, AST_DECLARE_APP_ARGS, AST_NONSTANDARD_RAW_ARGS, ast_random(), AST_SCHED_REPLACE_UNREF, ast_sockaddr_copy(), ast_sockaddr_parse(), ast_sockaddr_stringify_host(), ast_string_field_set, expire_register(), ref_peer(), register_peer_exten(), sip_cfg, sip_poke_peer_s(), TRUE, and unref_peer().
Referenced by build_peer(), and temp_peer().
14293 { 14294 char data[256]; 14295 struct ast_sockaddr sa; 14296 int expire; 14297 char full_addr[128]; 14298 AST_DECLARE_APP_ARGS(args, 14299 AST_APP_ARG(addr); 14300 AST_APP_ARG(port); 14301 AST_APP_ARG(expiry_str); 14302 AST_APP_ARG(username); 14303 AST_APP_ARG(contact); 14304 ); 14305 14306 /* If read-only RT backend, then refresh from local DB cache */ 14307 if (peer->rt_fromcontact && sip_cfg.peer_rtupdate) { 14308 return; 14309 } 14310 if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) { 14311 return; 14312 } 14313 14314 AST_NONSTANDARD_RAW_ARGS(args, data, ':'); 14315 14316 snprintf(full_addr, sizeof(full_addr), "%s:%s", args.addr, args.port); 14317 14318 if (!ast_sockaddr_parse(&sa, full_addr, 0)) { 14319 return; 14320 } 14321 14322 if (args.expiry_str) { 14323 expire = atoi(args.expiry_str); 14324 } else { 14325 return; 14326 } 14327 14328 if (args.username) { 14329 ast_string_field_set(peer, username, args.username); 14330 } 14331 if (args.contact) { 14332 ast_string_field_set(peer, fullcontact, args.contact); 14333 } 14334 14335 ast_debug(2, "SIP Seeding peer from astdb: '%s' at %s@%s for %d\n", 14336 peer->name, peer->username, ast_sockaddr_stringify_host(&sa), expire); 14337 14338 ast_sockaddr_copy(&peer->addr, &sa); 14339 if (peer->maxms) { 14340 /* Don't poke peer immediately, just schedule it within qualifyfreq */ 14341 AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, 14342 ast_random() % ((peer->qualifyfreq) ? peer->qualifyfreq : global_qualifyfreq) + 1, 14343 sip_poke_peer_s, peer, 14344 unref_peer(_data, "removing poke peer ref"), 14345 unref_peer(peer, "removing poke peer ref"), 14346 ref_peer(peer, "adding poke peer ref")); 14347 } 14348 AST_SCHED_REPLACE_UNREF(peer->expire, sched, (expire + 10) * 1000, expire_register, peer, 14349 unref_peer(_data, "remove registration ref"), 14350 unref_peer(peer, "remove registration ref"), 14351 ref_peer(peer, "add registration ref")); 14352 register_peer_exten(peer, TRUE); 14353 }
| static void register_peer_exten | ( | struct sip_peer * | peer, | |
| int | onoff | |||
| ) | [static] |
Automatically add peer extension to dial plan.
Definition at line 4765 of file chan_sip.c.
References ast_add_extension(), ast_context_find(), ast_context_remove_extension(), ast_copy_string(), ast_exists_extension(), ast_free_ptr(), ast_log(), ast_strdup, ast_strlen_zero(), context, E_MATCH, ext, LOG_WARNING, pbx_find_extension(), S_OR, and sip_cfg.
Referenced by expire_register(), handle_response_peerpoke(), parse_register_contact(), reg_source_db(), sip_destroy_peer(), and sip_poke_noanswer().
04766 { 04767 char multi[256]; 04768 char *stringp, *ext, *context; 04769 struct pbx_find_info q = { .stacklen = 0 }; 04770 04771 /* XXX note that sip_cfg.regcontext is both a global 'enable' flag and 04772 * the name of the global regexten context, if not specified 04773 * individually. 04774 */ 04775 if (ast_strlen_zero(sip_cfg.regcontext)) 04776 return; 04777 04778 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 04779 stringp = multi; 04780 while ((ext = strsep(&stringp, "&"))) { 04781 if ((context = strchr(ext, '@'))) { 04782 *context++ = '\0'; /* split ext@context */ 04783 if (!ast_context_find(context)) { 04784 ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context); 04785 continue; 04786 } 04787 } else { 04788 context = sip_cfg.regcontext; 04789 } 04790 if (onoff) { 04791 if (!ast_exists_extension(NULL, context, ext, 1, NULL)) { 04792 ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop", 04793 ast_strdup(peer->name), ast_free_ptr, "SIP"); 04794 } 04795 } else if (pbx_find_extension(NULL, NULL, &q, context, ext, 1, NULL, "", E_MATCH)) { 04796 ast_context_remove_extension(context, ext, 1, NULL); 04797 } 04798 } 04799 }
| static enum check_auth_result register_verify | ( | struct sip_pvt * | p, | |
| struct ast_sockaddr * | addr, | |||
| struct sip_request * | req, | |||
| const char * | uri | |||
| ) | [static] |
Verify registration of user
Definition at line 15277 of file chan_sip.c.
References ao2_lock, ao2_t_link, ao2_unlock, ast_apply_ha(), ast_copy_flags, ast_copy_string(), AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), AST_LIST_EMPTY, ast_log(), ast_set_flag, ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_sockaddr_stringify_port(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), build_contact(), check_auth(), check_request_transport, check_sip_domain(), EVENT_FLAG_SYSTEM, exten, extract_host_from_hostport(), FALSE, find_peer(), get_header(), get_in_brackets(), LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event, name, parse_register_contact(), parse_uri_legacy_check(), ref_peer(), remove_uri_parameters(), sip_cancel_destroy(), sip_cfg, SIP_PEDANTIC_DECODE, sip_pvt_lock, sip_pvt_unlock, sip_send_mwi_to_peer(), temp_peer(), terminate_uri(), transmit_fake_auth_response(), transmit_response(), transmit_response_with_date(), TRUE, unref_peer(), update_peer(), and update_peer_lastmsgssent().
Referenced by handle_request_register().
15279 { 15280 enum check_auth_result res = AUTH_NOT_FOUND; 15281 struct sip_peer *peer; 15282 char tmp[256]; 15283 char *c, *name, *unused_password, *domain; 15284 char *uri2 = ast_strdupa(uri); 15285 int send_mwi = 0; 15286 15287 terminate_uri(uri2); 15288 15289 ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp)); 15290 15291 c = get_in_brackets(tmp); 15292 c = remove_uri_parameters(c); 15293 15294 if (parse_uri_legacy_check(c, "sip:,sips:", &name, &unused_password, &domain, NULL)) { 15295 ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_sockaddr_stringify_addr(addr)); 15296 return -1; 15297 } 15298 15299 SIP_PEDANTIC_DECODE(name); 15300 SIP_PEDANTIC_DECODE(domain); 15301 15302 extract_host_from_hostport(&domain); 15303 15304 if (ast_strlen_zero(domain)) { 15305 /* <sip:name@[EMPTY]>, never good */ 15306 transmit_response(p, "404 Not found", &p->initreq); 15307 return AUTH_UNKNOWN_DOMAIN; 15308 } 15309 15310 if (ast_strlen_zero(name)) { 15311 /* <sip:[EMPTY][@]hostport>, unsure whether valid for 15312 * registration. RFC 3261, 10.2 states: 15313 * "The To header field and the Request-URI field typically 15314 * differ, as the former contains a user name." 15315 * But, Asterisk has always treated the domain-only uri as a 15316 * username: we allow admins to create accounts described by 15317 * domain name. */ 15318 name = domain; 15319 } 15320 15321 /* This here differs from 1.4 and 1.6: the domain matching ACLs were 15322 * skipped if it was a domain-only URI (used as username). Here we treat 15323 * <sip:hostport> as <sip:host@hostport> and won't forget to test the 15324 * domain ACLs against host. */ 15325 if (!AST_LIST_EMPTY(&domain_list)) { 15326 if (!check_sip_domain(domain, NULL, 0)) { 15327 if (sip_cfg.alwaysauthreject) { 15328 transmit_fake_auth_response(p, &p->initreq, XMIT_UNRELIABLE); 15329 } else { 15330 transmit_response(p, "404 Not found (unknown domain)", &p->initreq); 15331 } 15332 return AUTH_UNKNOWN_DOMAIN; 15333 } 15334 } 15335 15336 ast_string_field_set(p, exten, name); 15337 build_contact(p); 15338 if (req->ignore) { 15339 /* Expires is a special case, where we only want to load the peer if this isn't a deregistration attempt */ 15340 const char *expires = get_header(req, "Expires"); 15341 int expire = atoi(expires); 15342 15343 if (ast_strlen_zero(expires)) { /* No expires header; look in Contact */ 15344 if ((expires = strcasestr(get_header(req, "Contact"), ";expires="))) { 15345 expire = atoi(expires + 9); 15346 } 15347 } 15348 if (!ast_strlen_zero(expires) && expire == 0) { 15349 transmit_response_with_date(p, "200 OK", req); 15350 return 0; 15351 } 15352 } 15353 peer = find_peer(name, NULL, TRUE, FINDPEERS, FALSE, 0); 15354 15355 /* If we don't want username disclosure, use the bogus_peer when a user 15356 * is not found. */ 15357 if (!peer && sip_cfg.alwaysauthreject && !sip_cfg.autocreatepeer) { 15358 peer = bogus_peer; 15359 ref_peer(peer, "register_verify: ref the bogus_peer"); 15360 } 15361 15362 if (!(peer && ast_apply_ha(peer->ha, addr))) { 15363 /* Peer fails ACL check */ 15364 if (peer) { 15365 unref_peer(peer, "register_verify: unref_peer: from find_peer operation"); 15366 peer = NULL; 15367 res = AUTH_ACL_FAILED; 15368 } else { 15369 res = AUTH_NOT_FOUND; 15370 } 15371 } 15372 15373 if (peer) { 15374 ao2_lock(peer); 15375 if (!peer->host_dynamic) { 15376 ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name); 15377 res = AUTH_PEER_NOT_DYNAMIC; 15378 } else { 15379 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT_FORCE_RPORT); 15380 if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri2, XMIT_UNRELIABLE, req->ignore))) { 15381 if (sip_cancel_destroy(p)) 15382 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 15383 15384 if (check_request_transport(peer, req)) { 15385 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 15386 transmit_response_with_date(p, "403 Forbidden", req); 15387 res = AUTH_BAD_TRANSPORT; 15388 } else { 15389 15390 /* We have a successful registration attempt with proper authentication, 15391 now, update the peer */ 15392 switch (parse_register_contact(p, peer, req)) { 15393 case PARSE_REGISTER_DENIED: 15394 ast_log(LOG_WARNING, "Registration denied because of contact ACL\n"); 15395 transmit_response_with_date(p, "603 Denied", req); 15396 res = 0; 15397 break; 15398 case PARSE_REGISTER_FAILED: 15399 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 15400 transmit_response_with_date(p, "400 Bad Request", req); 15401 res = 0; 15402 break; 15403 case PARSE_REGISTER_QUERY: 15404 ast_string_field_set(p, fullcontact, peer->fullcontact); 15405 transmit_response_with_date(p, "200 OK", req); 15406 res = 0; 15407 break; 15408 case PARSE_REGISTER_UPDATE: 15409 ast_string_field_set(p, fullcontact, peer->fullcontact); 15410 /* If expiry is 0, peer has been unregistered already */ 15411 if (p->expiry != 0) { 15412 update_peer(peer, p->expiry); 15413 } 15414 /* Say OK and ask subsystem to retransmit msg counter */ 15415 transmit_response_with_date(p, "200 OK", req); 15416 send_mwi = 1; 15417 res = 0; 15418 break; 15419 } 15420 } 15421 15422 } 15423 } 15424 ao2_unlock(peer); 15425 } 15426 if (!peer && sip_cfg.autocreatepeer) { 15427 /* Create peer if we have autocreate mode enabled */ 15428 peer = temp_peer(name); 15429 if (peer) { 15430 ao2_t_link(peers, peer, "link peer into peer table"); 15431 if (!ast_sockaddr_isnull(&peer->addr)) { 15432 ao2_t_link(peers_by_ip, peer, "link peer into peers-by-ip table"); 15433 } 15434 ao2_lock(peer); 15435 if (sip_cancel_destroy(p)) 15436 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 15437 switch (parse_register_contact(p, peer, req)) { 15438 case PARSE_REGISTER_DENIED: 15439 ast_log(LOG_WARNING, "Registration denied because of contact ACL\n"); 15440 transmit_response_with_date(p, "403 Forbidden", req); 15441 res = 0; 15442 break; 15443 case PARSE_REGISTER_FAILED: 15444 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 15445 transmit_response_with_date(p, "400 Bad Request", req); 15446 res = 0; 15447 break; 15448 case PARSE_REGISTER_QUERY: 15449 ast_string_field_set(p, fullcontact, peer->fullcontact); 15450 transmit_response_with_date(p, "200 OK", req); 15451 send_mwi = 1; 15452 res = 0; 15453 break; 15454 case PARSE_REGISTER_UPDATE: 15455 ast_string_field_set(p, fullcontact, peer->fullcontact); 15456 /* Say OK and ask subsystem to retransmit msg counter */ 15457 transmit_response_with_date(p, "200 OK", req); 15458 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Registered\r\nAddress: %s\r\n", peer->name, ast_sockaddr_stringify(addr)); 15459 send_mwi = 1; 15460 res = 0; 15461 break; 15462 } 15463 ao2_unlock(peer); 15464 } 15465 } 15466 if (!res) { 15467 if (send_mwi) { 15468 sip_pvt_unlock(p); 15469 sip_send_mwi_to_peer(peer, 0); 15470 sip_pvt_lock(p); 15471 } else { 15472 update_peer_lastmsgssent(peer, -1, 0); 15473 } 15474 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", peer->name); 15475 } 15476 if (res < 0) { 15477 switch (res) { 15478 case AUTH_SECRET_FAILED: 15479 /* Wrong password in authentication. Go away, don't try again until you fixed it */ 15480 transmit_response(p, "403 Forbidden", &p->initreq); 15481 if (global_authfailureevents) { 15482 const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr)); 15483 const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr)); 15484 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 15485 "ChannelType: SIP\r\n" 15486 "Peer: SIP/%s\r\n" 15487 "PeerStatus: Rejected\r\n" 15488 "Cause: AUTH_SECRET_FAILED\r\n" 15489 "Address: %s\r\n" 15490 "Port: %s\r\n", 15491 name, peer_addr, peer_port); 15492 } 15493 break; 15494 case AUTH_USERNAME_MISMATCH: 15495 /* Username and digest username does not match. 15496 Asterisk uses the From: username for authentication. We need the 15497 devices to use the same authentication user name until we support 15498 proper authentication by digest auth name */ 15499 case AUTH_NOT_FOUND: 15500 case AUTH_PEER_NOT_DYNAMIC: 15501 case AUTH_ACL_FAILED: 15502 if (sip_cfg.alwaysauthreject) { 15503 transmit_fake_auth_response(p, &p->initreq, XMIT_UNRELIABLE); 15504 if (global_authfailureevents) { 15505 const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr)); 15506 const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr)); 15507 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 15508 "ChannelType: SIP\r\n" 15509 "Peer: SIP/%s\r\n" 15510 "PeerStatus: Rejected\r\n" 15511 "Cause: %s\r\n" 15512 "Address: %s\r\n" 15513 "Port: %s\r\n", 15514 name, 15515 res == AUTH_PEER_NOT_DYNAMIC ? "AUTH_PEER_NOT_DYNAMIC" : "URI_NOT_FOUND", 15516 peer_addr, peer_port); 15517 } 15518 } else { 15519 /* URI not found */ 15520 if (res == AUTH_PEER_NOT_DYNAMIC) { 15521 transmit_response(p, "403 Forbidden", &p->initreq); 15522 if (global_authfailureevents) { 15523 const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr)); 15524 const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr)); 15525 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 15526 "ChannelType: SIP\r\n" 15527 "Peer: SIP/%s\r\n" 15528 "PeerStatus: Rejected\r\n" 15529 "Cause: AUTH_PEER_NOT_DYNAMIC\r\n" 15530 "Address: %s\r\n" 15531 "Port: %s\r\n", 15532 name, peer_addr, peer_port); 15533 } 15534 } else { 15535 transmit_response(p, "404 Not found", &p->initreq); 15536 if (global_authfailureevents) { 15537 const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr)); 15538 const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr)); 15539 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 15540 "ChannelType: SIP\r\n" 15541 "Peer: SIP/%s\r\n" 15542 "PeerStatus: Rejected\r\n" 15543 "Cause: %s\r\n" 15544 "Address: %s\r\n" 15545 "Port: %s\r\n", 15546 name, 15547 (res == AUTH_USERNAME_MISMATCH) ? "AUTH_USERNAME_MISMATCH" : "URI_NOT_FOUND", 15548 peer_addr, peer_port); 15549 } 15550 } 15551 } 15552 break; 15553 case AUTH_BAD_TRANSPORT: 15554 default: 15555 break; 15556 } 15557 } 15558 if (peer) { 15559 unref_peer(peer, "register_verify: unref_peer: tossing stack peer pointer at end of func"); 15560 } 15561 15562 return res; 15563 }
| static struct sip_registry* registry_addref | ( | struct sip_registry * | reg, | |
| char * | tag | |||
| ) | [static, read] |
Add object reference to SIP registry.
Definition at line 3162 of file chan_sip.c.
References ast_debug, and ASTOBJ_REF.
Referenced by handle_response_register(), sip_send_all_registers(), and transmit_register().
03163 { 03164 ast_debug(3, "SIP Registry %s: refcount now %u\n", reg->hostname, reg->refcount + 1); 03165 return ASTOBJ_REF(reg); /* Add pointer to registry in packet */ 03166 }
| void * registry_unref | ( | struct sip_registry * | reg, | |
| char * | tag | |||
| ) | [static] |
Definition at line 3154 of file chan_sip.c.
References ast_debug, ASTOBJ_UNREF, and sip_registry_destroy().
Referenced by __sip_destroy(), cleanup_all_regs(), dialog_unlink_all(), handle_response_register(), sip_reg_timeout(), sip_register(), sip_registry_destroy(), sip_reregister(), sip_send_all_registers(), and transmit_register().
03155 { 03156 ast_debug(3, "SIP Registry %s: refcount now %u\n", reg->hostname, reg->refcount - 1); 03157 ASTOBJ_UNREF(reg, sip_registry_destroy); 03158 return NULL; 03159 }
| static const char * regstate2str | ( | enum sipregistrystate | regstate | ) | [static] |
Convert registration state status to string.
Definition at line 13558 of file chan_sip.c.
References map_x_s().
Referenced by handle_response_register(), manager_show_registry(), sip_reg_timeout(), and sip_show_registry().
13559 { 13560 return map_x_s(regstatestrings, regstate, "Unknown"); 13561 }
| static int reinvite_timeout | ( | const void * | data | ) | [static] |
Definition at line 6473 of file chan_sip.c.
References ao2_unlock, ast_channel_unlock, ast_channel_unref, check_pendings(), and sip_pvt_lock_full().
Referenced by sip_hangup().
06474 { 06475 struct sip_pvt *dialog = (struct sip_pvt *) data; 06476 struct ast_channel *owner = sip_pvt_lock_full(dialog); 06477 dialog->reinviteid = -1; 06478 check_pendings(dialog); 06479 if (owner) { 06480 ast_channel_unlock(owner); 06481 ast_channel_unref(owner); 06482 } 06483 ao2_unlock(dialog); 06484 dialog_unref(dialog, "unref for reinvite timeout"); 06485 return 0; 06486 }
| static int reload | ( | void | ) | [static] |
Part of Asterisk module interface.
Definition at line 30672 of file chan_sip.c.
References sip_reload().
30673 { 30674 if (sip_reload(0, 0, NULL)) 30675 return 0; 30676 return 1; 30677 }
| static int reload_config | ( | enum channelreloadreason | reason | ) | [static] |
Re-read SIP.conf config file.
< Don't force proxy usage, use route: headers
< Keep track of hold status for a peer
< Match auth username if available instead of From: Default off.
< Default DTMF setting: RFC2833
< Allow re-invites
< Default to nat=force_rport
Definition at line 28801 of file chan_sip.c.
References ast_tcptls_session_args::accept_fd, add_realm_authentication(), add_sip_domain(), ao2_t_callback, ao2_t_link, ao2_t_ref, ast_append_ha(), ast_bind(), ast_category_browse(), AST_CERTFILE, ast_clear_flag, ast_config_AST_SYSTEM_NAME, ast_config_destroy(), ast_config_load, ast_context_find_or_create(), ast_copy_flags, ast_copy_string(), ast_debug, ast_enable_packet_fragmentation(), ast_false(), ast_find_ourip(), AST_FLAGS_ALL, ast_free, ast_free_ha(), ast_get_version(), ast_jb_read_conf(), AST_LIST_EMPTY, ast_log(), AST_MAX_CONTEXT, ast_mutex_lock, ast_mutex_unlock, ast_parse_allow_disallow(), ast_parse_arg(), ast_set2_flag, ast_set_flag, ast_set_qos(), ast_skip_blanks(), ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_is_any(), ast_sockaddr_is_ipv6(), ast_sockaddr_isnull(), ast_sockaddr_parse(), ast_sockaddr_port, ast_sockaddr_resolve_first(), ast_sockaddr_set_port, ast_sockaddr_setnull(), ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_ssl_setup(), ast_str2cos(), ast_str2tos(), ast_strdup, ast_strdupa, ast_strip(), ast_strlen_zero(), ast_tcptls_server_start(), ast_test_flag, ast_tls_read_conf(), ast_true(), ast_unload_realtime(), ast_variable_browse(), ast_variable_retrieve(), ast_verb, ASTOBJ_CONTAINER_DESTROYALL, bindaddr, build_peer(), ast_tls_config::cafile, ast_tls_config::capath, ast_tls_config::certfile, CHANNEL_MODULE_LOAD, channelreloadreason2txt(), ast_tls_config::cipher, cleanup_all_regs(), cleanup_stale_contexts(), clear_sip_domains(), CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, context, DEFAULT_AUTHLIMIT, DEFAULT_AUTHTIMEOUT, DEFAULT_CONTEXT, DEFAULT_MAXMS, DEFAULT_PARKINGLOT, default_prefs, DEFAULT_REALM, display_nat_warning(), ast_tls_config::enabled, errno, EVENT_FLAG_SYSTEM, externaddr, FALSE, gen, global_jbconf, handle_common_options(), handle_t38_options(), internip, ast_variable::lineno, ast_tcptls_session_args::local_address, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event, mark_parsed_methods(), MAXHOSTNAMELEN, media_address, ast_variable::name, network_change_event_subscribe(), network_change_event_unsubscribe(), ast_variable::next, OBJ_NODATA, PARSE_ADDR, PARSE_DEFAULT, PARSE_IN_RANGE, PARSE_INT32, peer_markall_func(), port_str2int(), proxy_from_config(), ast_tls_config::pvtfile, regl, S_OR, secret, sip_cfg, sip_register(), sip_registry_destroy(), sip_subscribe_mwi(), str2stmode(), str2strefresherparam(), ast_tcptls_session_args::tls_cfg, TRUE, unref_peer(), and ast_variable::value.
Referenced by load_module(), and sip_do_reload().
28802 { 28803 struct ast_config *cfg, *ucfg; 28804 struct ast_variable *v; 28805 struct sip_peer *peer; 28806 char *cat, *stringp, *context, *oldregcontext; 28807 char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT]; 28808 struct ast_flags mask[3] = {{0}}; 28809 struct ast_flags setflags[3] = {{0}}; 28810 struct ast_flags config_flags = { reason == CHANNEL_MODULE_LOAD ? 0 : ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? 0 : CONFIG_FLAG_FILEUNCHANGED }; 28811 int auto_sip_domains = FALSE; 28812 struct ast_sockaddr old_bindaddr = bindaddr; 28813 int registry_count = 0, peer_count = 0, timerb_set = 0, timert1_set = 0; 28814 int subscribe_network_change = 1; 28815 time_t run_start, run_end; 28816 int bindport = 0; 28817 28818 run_start = time(0); 28819 ast_unload_realtime("sipregs"); 28820 ast_unload_realtime("sippeers"); 28821 cfg = ast_config_load(config, config_flags); 28822 28823 /* We *must* have a config file otherwise stop immediately */ 28824 if (!cfg) { 28825 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 28826 return -1; 28827 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 28828 ucfg = ast_config_load("users.conf", config_flags); 28829 if (ucfg == CONFIG_STATUS_FILEUNCHANGED) { 28830 return 1; 28831 } else if (ucfg == CONFIG_STATUS_FILEINVALID) { 28832 ast_log(LOG_ERROR, "Contents of users.conf are invalid and cannot be parsed\n"); 28833 return 1; 28834 } 28835 /* Must reread both files, because one changed */ 28836 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 28837 if ((cfg = ast_config_load(config, config_flags)) == CONFIG_STATUS_FILEINVALID) { 28838 ast_log(LOG_ERROR, "Contents of %s are invalid and cannot be parsed\n", config); 28839 ast_config_destroy(ucfg); 28840 return 1; 28841 } 28842 if (!cfg) { 28843 /* should have been able to reload here */ 28844 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 28845 return -1; 28846 } 28847 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 28848 ast_log(LOG_ERROR, "Contents of %s are invalid and cannot be parsed\n", config); 28849 return 1; 28850 } else { 28851 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 28852 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 28853 ast_log(LOG_ERROR, "Contents of users.conf are invalid and cannot be parsed\n"); 28854 ast_config_destroy(cfg); 28855 return 1; 28856 } 28857 } 28858 28859 ast_free_ha(sip_cfg.contact_ha); 28860 sip_cfg.contact_ha = NULL; 28861 28862 default_tls_cfg.enabled = FALSE; /* Default: Disable TLS */ 28863 28864 if (reason != CHANNEL_MODULE_LOAD) { 28865 ast_debug(4, "--------------- SIP reload started\n"); 28866 28867 clear_sip_domains(); 28868 ast_mutex_lock(&authl_lock); 28869 if (authl) { 28870 ao2_t_ref(authl, -1, "Removing old global authentication"); 28871 authl = NULL; 28872 } 28873 ast_mutex_unlock(&authl_lock); 28874 28875 28876 cleanup_all_regs(); 28877 /* Then, actually destroy users and registry */ 28878 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 28879 ast_debug(4, "--------------- Done destroying registry list\n"); 28880 ao2_t_callback(peers, OBJ_NODATA, peer_markall_func, NULL, "callback to mark all peers"); 28881 } 28882 28883 /* Reset certificate handling for TLS sessions */ 28884 if (reason != CHANNEL_MODULE_LOAD) { 28885 ast_free(default_tls_cfg.certfile); 28886 ast_free(default_tls_cfg.pvtfile); 28887 ast_free(default_tls_cfg.cipher); 28888 ast_free(default_tls_cfg.cafile); 28889 ast_free(default_tls_cfg.capath); 28890 } 28891 default_tls_cfg.certfile = ast_strdup(AST_CERTFILE); /*XXX Not sure if this is useful */ 28892 default_tls_cfg.pvtfile = ast_strdup(""); 28893 default_tls_cfg.cipher = ast_strdup(""); 28894 default_tls_cfg.cafile = ast_strdup(""); 28895 default_tls_cfg.capath = ast_strdup(""); 28896 28897 /* Initialize copy of current sip_cfg.regcontext for later use in removing stale contexts */ 28898 ast_copy_string(oldcontexts, sip_cfg.regcontext, sizeof(oldcontexts)); 28899 oldregcontext = oldcontexts; 28900 28901 /* Clear all flags before setting default values */ 28902 /* Preserve debugging settings for console */ 28903 sipdebug &= sip_debug_console; 28904 ast_clear_flag(&global_flags[0], AST_FLAGS_ALL); 28905 ast_clear_flag(&global_flags[1], AST_FLAGS_ALL); 28906 ast_clear_flag(&global_flags[2], AST_FLAGS_ALL); 28907 28908 /* Reset IP addresses */ 28909 ast_sockaddr_parse(&bindaddr, "0.0.0.0:0", 0); 28910 memset(&internip, 0, sizeof(internip)); 28911 28912 /* Free memory for local network address mask */ 28913 ast_free_ha(localaddr); 28914 memset(&localaddr, 0, sizeof(localaddr)); 28915 memset(&externaddr, 0, sizeof(externaddr)); 28916 memset(&media_address, 0, sizeof(media_address)); 28917 memset(&default_prefs, 0 , sizeof(default_prefs)); 28918 memset(&sip_cfg.outboundproxy, 0, sizeof(struct sip_proxy)); 28919 sip_cfg.outboundproxy.force = FALSE; /*!< Don't force proxy usage, use route: headers */ 28920 default_transports = SIP_TRANSPORT_UDP; 28921 default_primary_transport = SIP_TRANSPORT_UDP; 28922 ourport_tcp = STANDARD_SIP_PORT; 28923 ourport_tls = STANDARD_TLS_PORT; 28924 externtcpport = STANDARD_SIP_PORT; 28925 externtlsport = STANDARD_TLS_PORT; 28926 sip_cfg.srvlookup = DEFAULT_SRVLOOKUP; 28927 global_tos_sip = DEFAULT_TOS_SIP; 28928 global_tos_audio = DEFAULT_TOS_AUDIO; 28929 global_tos_video = DEFAULT_TOS_VIDEO; 28930 global_tos_text = DEFAULT_TOS_TEXT; 28931 global_cos_sip = DEFAULT_COS_SIP; 28932 global_cos_audio = DEFAULT_COS_AUDIO; 28933 global_cos_video = DEFAULT_COS_VIDEO; 28934 global_cos_text = DEFAULT_COS_TEXT; 28935 28936 externhost[0] = '\0'; /* External host name (for behind NAT DynDNS support) */ 28937 externexpire = 0; /* Expiration for DNS re-issuing */ 28938 externrefresh = 10; 28939 28940 /* Reset channel settings to default before re-configuring */ 28941 sip_cfg.allow_external_domains = DEFAULT_ALLOW_EXT_DOM; /* Allow external invites */ 28942 sip_cfg.regcontext[0] = '\0'; 28943 sip_cfg.capability = DEFAULT_CAPABILITY; 28944 sip_cfg.regextenonqualify = DEFAULT_REGEXTENONQUALIFY; 28945 sip_cfg.legacy_useroption_parsing = DEFAULT_LEGACY_USEROPTION_PARSING; 28946 sip_cfg.notifyringing = DEFAULT_NOTIFYRINGING; 28947 sip_cfg.notifycid = DEFAULT_NOTIFYCID; 28948 sip_cfg.notifyhold = FALSE; /*!< Keep track of hold status for a peer */ 28949 sip_cfg.directrtpsetup = FALSE; /* Experimental feature, disabled by default */ 28950 sip_cfg.alwaysauthreject = DEFAULT_ALWAYSAUTHREJECT; 28951 sip_cfg.auth_options_requests = DEFAULT_AUTH_OPTIONS; 28952 sip_cfg.allowsubscribe = FALSE; 28953 sip_cfg.disallowed_methods = SIP_UNKNOWN; 28954 sip_cfg.contact_ha = NULL; /* Reset the contact ACL */ 28955 snprintf(global_useragent, sizeof(global_useragent), "%s %s", DEFAULT_USERAGENT, ast_get_version()); 28956 snprintf(global_sdpsession, sizeof(global_sdpsession), "%s %s", DEFAULT_SDPSESSION, ast_get_version()); 28957 snprintf(global_sdpowner, sizeof(global_sdpowner), "%s", DEFAULT_SDPOWNER); 28958 global_prematuremediafilter = TRUE; 28959 ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime)); 28960 ast_copy_string(sip_cfg.realm, S_OR(ast_config_AST_SYSTEM_NAME, DEFAULT_REALM), sizeof(sip_cfg.realm)); 28961 sip_cfg.domainsasrealm = DEFAULT_DOMAINSASREALM; 28962 ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid)); 28963 ast_copy_string(default_mwi_from, DEFAULT_MWI_FROM, sizeof(default_mwi_from)); 28964 sip_cfg.compactheaders = DEFAULT_COMPACTHEADERS; 28965 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 28966 global_regattempts_max = 0; 28967 global_reg_retry_403 = 0; 28968 sip_cfg.pedanticsipchecking = DEFAULT_PEDANTIC; 28969 sip_cfg.autocreatepeer = DEFAULT_AUTOCREATEPEER; 28970 global_autoframing = 0; 28971 sip_cfg.allowguest = DEFAULT_ALLOWGUEST; 28972 global_callcounter = DEFAULT_CALLCOUNTER; 28973 global_match_auth_username = FALSE; /*!< Match auth username if available instead of From: Default off. */ 28974 global_rtptimeout = 0; 28975 global_rtpholdtimeout = 0; 28976 global_rtpkeepalive = DEFAULT_RTPKEEPALIVE; 28977 sip_cfg.allowtransfer = TRANSFER_OPENFORALL; /* Merrily accept all transfers by default */ 28978 sip_cfg.rtautoclear = 120; 28979 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE); /* Default for all devices: TRUE */ 28980 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP_YES); /* Default for all devices: Yes */ 28981 sip_cfg.peer_rtupdate = TRUE; 28982 global_dynamic_exclude_static = 0; /* Exclude static peers */ 28983 sip_cfg.tcp_enabled = FALSE; 28984 28985 /* Session-Timers */ 28986 global_st_mode = SESSION_TIMER_MODE_ACCEPT; 28987 global_st_refresher = SESSION_TIMER_REFRESHER_PARAM_UAS; 28988 global_min_se = DEFAULT_MIN_SE; 28989 global_max_se = DEFAULT_MAX_SE; 28990 28991 /* Peer poking settings */ 28992 global_qualify_gap = DEFAULT_QUALIFY_GAP; 28993 global_qualify_peers = DEFAULT_QUALIFY_PEERS; 28994 28995 /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for devices */ 28996 ast_copy_string(sip_cfg.default_context, DEFAULT_CONTEXT, sizeof(sip_cfg.default_context)); 28997 sip_cfg.default_subscribecontext[0] = '\0'; 28998 sip_cfg.default_max_forwards = DEFAULT_MAX_FORWARDS; 28999 default_language[0] = '\0'; 29000 default_fromdomain[0] = '\0'; 29001 default_fromdomainport = 0; 29002 default_qualify = DEFAULT_QUALIFY; 29003 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 29004 ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret)); 29005 ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest)); 29006 ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten)); 29007 ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */ 29008 ast_set_flag(&global_flags[0], SIP_DIRECT_MEDIA); /*!< Allow re-invites */ 29009 ast_set_flag(&global_flags[0], SIP_NAT_FORCE_RPORT); /*!< Default to nat=force_rport */ 29010 ast_copy_string(default_engine, DEFAULT_ENGINE, sizeof(default_engine)); 29011 ast_copy_string(default_parkinglot, DEFAULT_PARKINGLOT, sizeof(default_parkinglot)); 29012 29013 /* Debugging settings, always default to off */ 29014 dumphistory = FALSE; 29015 recordhistory = FALSE; 29016 sipdebug &= ~sip_debug_config; 29017 29018 /* Misc settings for the channel */ 29019 global_relaxdtmf = FALSE; 29020 sip_cfg.callevents = DEFAULT_CALLEVENTS; 29021 global_authfailureevents = FALSE; 29022 global_t1 = DEFAULT_TIMER_T1; 29023 global_timer_b = 64 * DEFAULT_TIMER_T1; 29024 global_t1min = DEFAULT_T1MIN; 29025 global_qualifyfreq = DEFAULT_QUALIFYFREQ; 29026 global_t38_maxdatagram = -1; 29027 global_shrinkcallerid = 1; 29028 authlimit = DEFAULT_AUTHLIMIT; 29029 authtimeout = DEFAULT_AUTHTIMEOUT; 29030 global_store_sip_cause = DEFAULT_STORE_SIP_CAUSE; 29031 29032 sip_cfg.matchexternaddrlocally = DEFAULT_MATCHEXTERNADDRLOCALLY; 29033 29034 /* Copy the default jb config over global_jbconf */ 29035 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 29036 29037 ast_clear_flag(&global_flags[1], SIP_PAGE2_FAX_DETECT); 29038 ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT | SIP_PAGE2_VIDEOSUPPORT_ALWAYS); 29039 ast_clear_flag(&global_flags[1], SIP_PAGE2_TEXTSUPPORT); 29040 ast_clear_flag(&global_flags[1], SIP_PAGE2_IGNORESDPVERSION); 29041 29042 29043 /* Read the [general] config section of sip.conf (or from realtime config) */ 29044 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) { 29045 if (handle_common_options(&setflags[0], &mask[0], v)) { 29046 continue; 29047 } 29048 if (handle_t38_options(&setflags[0], &mask[0], v, &global_t38_maxdatagram)) { 29049 continue; 29050 } 29051 /* handle jb conf */ 29052 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 29053 continue; 29054 29055 /* handle tls conf, don't allow setting of tlsverifyclient as it isn't supported by chan_sip */ 29056 if (!strcasecmp(v->name, "tlsverifyclient")) { 29057 ast_log(LOG_WARNING, "Ignoring unsupported option 'tlsverifyclient'\n"); 29058 continue; 29059 } else if (!ast_tls_read_conf(&default_tls_cfg, &sip_tls_desc, v->name, v->value)) { 29060 continue; 29061 } 29062 29063 if (!strcasecmp(v->name, "context")) { 29064 ast_copy_string(sip_cfg.default_context, v->value, sizeof(sip_cfg.default_context)); 29065 } else if (!strcasecmp(v->name, "subscribecontext")) { 29066 ast_copy_string(sip_cfg.default_subscribecontext, v->value, sizeof(sip_cfg.default_subscribecontext)); 29067 } else if (!strcasecmp(v->name, "callcounter")) { 29068 global_callcounter = ast_true(v->value) ? 1 : 0; 29069 } else if (!strcasecmp(v->name, "allowguest")) { 29070 sip_cfg.allowguest = ast_true(v->value) ? 1 : 0; 29071 } else if (!strcasecmp(v->name, "realm")) { 29072 ast_copy_string(sip_cfg.realm, v->value, sizeof(sip_cfg.realm)); 29073 } else if (!strcasecmp(v->name, "domainsasrealm")) { 29074 sip_cfg.domainsasrealm = ast_true(v->value); 29075 } else if (!strcasecmp(v->name, "useragent")) { 29076 ast_copy_string(global_useragent, v->value, sizeof(global_useragent)); 29077 ast_debug(1, "Setting SIP channel User-Agent Name to %s\n", global_useragent); 29078 } else if (!strcasecmp(v->name, "sdpsession")) { 29079 ast_copy_string(global_sdpsession, v->value, sizeof(global_sdpsession)); 29080 } else if (!strcasecmp(v->name, "sdpowner")) { 29081 /* Field cannot contain spaces */ 29082 if (!strstr(v->value, " ")) { 29083 ast_copy_string(global_sdpowner, v->value, sizeof(global_sdpowner)); 29084 } else { 29085 ast_log(LOG_WARNING, "'%s' must not contain spaces at line %d. Using default.\n", v->value, v->lineno); 29086 } 29087 } else if (!strcasecmp(v->name, "allowtransfer")) { 29088 sip_cfg.allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 29089 } else if (!strcasecmp(v->name, "rtcachefriends")) { 29090 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 29091 } else if (!strcasecmp(v->name, "rtsavesysname")) { 29092 sip_cfg.rtsave_sysname = ast_true(v->value); 29093 } else if (!strcasecmp(v->name, "rtupdate")) { 29094 sip_cfg.peer_rtupdate = ast_true(v->value); 29095 } else if (!strcasecmp(v->name, "ignoreregexpire")) { 29096 sip_cfg.ignore_regexpire = ast_true(v->value); 29097 } else if (!strcasecmp(v->name, "timert1")) { 29098 /* Defaults to 500ms, but RFC 3261 states that it is recommended 29099 * for the value to be set higher, though a lower value is only 29100 * allowed on private networks unconnected to the Internet. */ 29101 global_t1 = atoi(v->value); 29102 } else if (!strcasecmp(v->name, "timerb")) { 29103 int tmp = atoi(v->value); 29104 if (tmp < 500) { 29105 global_timer_b = global_t1 * 64; 29106 ast_log(LOG_WARNING, "Invalid value for timerb ('%s'). Setting to default ('%d').\n", v->value, global_timer_b); 29107 } 29108 timerb_set = 1; 29109 } else if (!strcasecmp(v->name, "t1min")) { 29110 global_t1min = atoi(v->value); 29111 } else if (!strcasecmp(v->name, "transport")) { 29112 char *val = ast_strdupa(v->value); 29113 char *trans; 29114 29115 default_transports = default_primary_transport = 0; 29116 while ((trans = strsep(&val, ","))) { 29117 trans = ast_skip_blanks(trans); 29118 29119 if (!strncasecmp(trans, "udp", 3)) { 29120 default_transports |= SIP_TRANSPORT_UDP; 29121 } else if (!strncasecmp(trans, "tcp", 3)) { 29122 default_transports |= SIP_TRANSPORT_TCP; 29123 } else if (!strncasecmp(trans, "tls", 3)) { 29124 default_transports |= SIP_TRANSPORT_TLS; 29125 } else { 29126 ast_log(LOG_NOTICE, "'%s' is not a valid transport type. if no other is specified, udp will be used.\n", trans); 29127 } 29128 if (default_primary_transport == 0) { 29129 default_primary_transport = default_transports; 29130 } 29131 } 29132 } else if (!strcasecmp(v->name, "tcpenable")) { 29133 if (!ast_false(v->value)) { 29134 ast_debug(2, "Enabling TCP socket for listening\n"); 29135 sip_cfg.tcp_enabled = TRUE; 29136 } 29137 } else if (!strcasecmp(v->name, "tcpbindaddr")) { 29138 if (ast_parse_arg(v->value, PARSE_ADDR, 29139 &sip_tcp_desc.local_address)) { 29140 ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n", 29141 v->name, v->value, v->lineno, config); 29142 } 29143 ast_debug(2, "Setting TCP socket address to %s\n", 29144 ast_sockaddr_stringify(&sip_tcp_desc.local_address)); 29145 } else if (!strcasecmp(v->name, "dynamic_exclude_static") || !strcasecmp(v->name, "dynamic_excludes_static")) { 29146 global_dynamic_exclude_static = ast_true(v->value); 29147 } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) { 29148 int ha_error = 0; 29149 sip_cfg.contact_ha = ast_append_ha(v->name + 7, v->value, sip_cfg.contact_ha, &ha_error); 29150 if (ha_error) { 29151 ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value); 29152 } 29153 } else if (!strcasecmp(v->name, "rtautoclear")) { 29154 int i = atoi(v->value); 29155 if (i > 0) { 29156 sip_cfg.rtautoclear = i; 29157 } else { 29158 i = 0; 29159 } 29160 ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR); 29161 } else if (!strcasecmp(v->name, "usereqphone")) { 29162 ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE); 29163 } else if (!strcasecmp(v->name, "prematuremedia")) { 29164 global_prematuremediafilter = ast_true(v->value); 29165 } else if (!strcasecmp(v->name, "relaxdtmf")) { 29166 global_relaxdtmf = ast_true(v->value); 29167 } else if (!strcasecmp(v->name, "vmexten")) { 29168 ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten)); 29169 } else if (!strcasecmp(v->name, "rtptimeout")) { 29170 if ((sscanf(v->value, "%30d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) { 29171 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 29172 global_rtptimeout = 0; 29173 } 29174 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 29175 if ((sscanf(v->value, "%30d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) { 29176 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 29177 global_rtpholdtimeout = 0; 29178 } 29179 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 29180 if ((sscanf(v->value, "%30d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) { 29181 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 29182 global_rtpkeepalive = DEFAULT_RTPKEEPALIVE; 29183 } 29184 } else if (!strcasecmp(v->name, "compactheaders")) { 29185 sip_cfg.compactheaders = ast_true(v->value); 29186 } else if (!strcasecmp(v->name, "notifymimetype")) { 29187 ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime)); 29188 } else if (!strcasecmp(v->name, "directrtpsetup")) { 29189 sip_cfg.directrtpsetup = ast_true(v->value); 29190 } else if (!strcasecmp(v->name, "notifyringing")) { 29191 sip_cfg.notifyringing = ast_true(v->value); 29192 } else if (!strcasecmp(v->name, "notifyhold")) { 29193 sip_cfg.notifyhold = ast_true(v->value); 29194 } else if (!strcasecmp(v->name, "notifycid")) { 29195 if (!strcasecmp(v->value, "ignore-context")) { 29196 sip_cfg.notifycid = IGNORE_CONTEXT; 29197 } else { 29198 sip_cfg.notifycid = ast_true(v->value) ? ENABLED : DISABLED; 29199 } 29200 } else if (!strcasecmp(v->name, "alwaysauthreject")) { 29201 sip_cfg.alwaysauthreject = ast_true(v->value); 29202 } else if (!strcasecmp(v->name, "auth_options_requests")) { 29203 if (ast_true(v->value)) { 29204 sip_cfg.auth_options_requests = 1; 29205 } 29206 } else if (!strcasecmp(v->name, "mohinterpret")) { 29207 ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret)); 29208 } else if (!strcasecmp(v->name, "mohsuggest")) { 29209 ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest)); 29210 } else if (!strcasecmp(v->name, "language")) { 29211 ast_copy_string(default_language, v->value, sizeof(default_language)); 29212 } else if (!strcasecmp(v->name, "regcontext")) { 29213 ast_copy_string(newcontexts, v->value, sizeof(newcontexts)); 29214 stringp = newcontexts; 29215 /* Let's remove any contexts that are no longer defined in regcontext */ 29216 cleanup_stale_contexts(stringp, oldregcontext); 29217 /* Create contexts if they don't exist already */ 29218 while ((context = strsep(&stringp, "&"))) { 29219 ast_copy_string(used_context, context, sizeof(used_context)); 29220 ast_context_find_or_create(NULL, NULL, context, "SIP"); 29221 } 29222 ast_copy_string(sip_cfg.regcontext, v->value, sizeof(sip_cfg.regcontext)); 29223 } else if (!strcasecmp(v->name, "regextenonqualify")) { 29224 sip_cfg.regextenonqualify = ast_true(v->value); 29225 } else if (!strcasecmp(v->name, "legacy_useroption_parsing")) { 29226 sip_cfg.legacy_useroption_parsing = ast_true(v->value); 29227 } else if (!strcasecmp(v->name, "callerid")) { 29228 ast_copy_string(default_callerid, v->value, sizeof(default_callerid)); 29229 } else if (!strcasecmp(v->name, "mwi_from")) { 29230 ast_copy_string(default_mwi_from, v->value, sizeof(default_mwi_from)); 29231 } else if (!strcasecmp(v->name, "fromdomain")) { 29232 char *fromdomainport; 29233 ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain)); 29234 if ((fromdomainport = strchr(default_fromdomain, ':'))) { 29235 *fromdomainport++ = '\0'; 29236 if (!(default_fromdomainport = port_str2int(fromdomainport, 0))) { 29237 ast_log(LOG_NOTICE, "'%s' is not a valid port number for fromdomain.\n",fromdomainport); 29238 } 29239 } else { 29240 default_fromdomainport = STANDARD_SIP_PORT; 29241 } 29242 } else if (!strcasecmp(v->name, "outboundproxy")) { 29243 struct sip_proxy *proxy; 29244 if (ast_strlen_zero(v->value)) { 29245 ast_log(LOG_WARNING, "no value given for outbound proxy on line %d of sip.conf\n", v->lineno); 29246 continue; 29247 } 29248 proxy = proxy_from_config(v->value, v->lineno, &sip_cfg.outboundproxy); 29249 if (!proxy) { 29250 ast_log(LOG_WARNING, "failure parsing the outbound proxy on line %d of sip.conf.\n", v->lineno); 29251 continue; 29252 } 29253 } else if (!strcasecmp(v->name, "autocreatepeer")) { 29254 sip_cfg.autocreatepeer = ast_true(v->value); 29255 } else if (!strcasecmp(v->name, "match_auth_username")) { 29256 global_match_auth_username = ast_true(v->value); 29257 } else if (!strcasecmp(v->name, "srvlookup")) { 29258 sip_cfg.srvlookup = ast_true(v->value); 29259 } else if (!strcasecmp(v->name, "pedantic")) { 29260 sip_cfg.pedanticsipchecking = ast_true(v->value); 29261 } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) { 29262 max_expiry = atoi(v->value); 29263 if (max_expiry < 1) { 29264 max_expiry = DEFAULT_MAX_EXPIRY; 29265 } 29266 } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) { 29267 min_expiry = atoi(v->value); 29268 if (min_expiry < 1) { 29269 min_expiry = DEFAULT_MIN_EXPIRY; 29270 } 29271 } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) { 29272 default_expiry = atoi(v->value); 29273 if (default_expiry < 1) { 29274 default_expiry = DEFAULT_DEFAULT_EXPIRY; 29275 } 29276 } else if (!strcasecmp(v->name, "mwiexpiry") || !strcasecmp(v->name, "mwiexpirey")) { 29277 mwi_expiry = atoi(v->value); 29278 if (mwi_expiry < 1) { 29279 mwi_expiry = DEFAULT_MWI_EXPIRY; 29280 } 29281 } else if (!strcasecmp(v->name, "tcpauthtimeout")) { 29282 if (ast_parse_arg(v->value, PARSE_INT32|PARSE_DEFAULT|PARSE_IN_RANGE, 29283 &authtimeout, DEFAULT_AUTHTIMEOUT, 1, INT_MAX)) { 29284 ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n", 29285 v->name, v->value, v->lineno, config); 29286 } 29287 } else if (!strcasecmp(v->name, "tcpauthlimit")) { 29288 if (ast_parse_arg(v->value, PARSE_INT32|PARSE_DEFAULT|PARSE_IN_RANGE, 29289 &authlimit, DEFAULT_AUTHLIMIT, 1, INT_MAX)) { 29290 ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n", 29291 v->name, v->value, v->lineno, config); 29292 } 29293 } else if (!strcasecmp(v->name, "sipdebug")) { 29294 if (ast_true(v->value)) 29295 sipdebug |= sip_debug_config; 29296 } else if (!strcasecmp(v->name, "dumphistory")) { 29297 dumphistory = ast_true(v->value); 29298 } else if (!strcasecmp(v->name, "recordhistory")) { 29299 recordhistory = ast_true(v->value); 29300 } else if (!strcasecmp(v->name, "registertimeout")) { 29301 global_reg_timeout = atoi(v->value); 29302 if (global_reg_timeout < 1) { 29303 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 29304 } 29305 } else if (!strcasecmp(v->name, "registerattempts")) { 29306 global_regattempts_max = atoi(v->value); 29307 } else if (!strcasecmp(v->name, "register_retry_403")) { 29308 global_reg_retry_403 = ast_true(v->value); 29309 } else if (!strcasecmp(v->name, "bindaddr") || !strcasecmp(v->name, "udpbindaddr")) { 29310 if (ast_parse_arg(v->value, PARSE_ADDR, &bindaddr)) { 29311 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 29312 } 29313 } else if (!strcasecmp(v->name, "localnet")) { 29314 struct ast_ha *na; 29315 int ha_error = 0; 29316 29317 if (!(na = ast_append_ha("d", v->value, localaddr, &ha_error))) { 29318 ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value); 29319 } else { 29320 localaddr = na; 29321 } 29322 if (ha_error) { 29323 ast_log(LOG_ERROR, "Bad localnet configuration value line %d : %s\n", v->lineno, v->value); 29324 } 29325 } else if (!strcasecmp(v->name, "media_address")) { 29326 if (ast_parse_arg(v->value, PARSE_ADDR, &media_address)) 29327 ast_log(LOG_WARNING, "Invalid address for media_address keyword: %s\n", v->value); 29328 } else if (!strcasecmp(v->name, "externaddr") || !strcasecmp(v->name, "externip")) { 29329 if (ast_parse_arg(v->value, PARSE_ADDR, &externaddr)) { 29330 ast_log(LOG_WARNING, 29331 "Invalid address for externaddr keyword: %s\n", 29332 v->value); 29333 } 29334 externexpire = 0; 29335 } else if (!strcasecmp(v->name, "externhost")) { 29336 ast_copy_string(externhost, v->value, sizeof(externhost)); 29337 if (ast_sockaddr_resolve_first(&externaddr, externhost, 0)) { 29338 ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost); 29339 } 29340 externexpire = time(NULL); 29341 } else if (!strcasecmp(v->name, "externrefresh")) { 29342 if (sscanf(v->value, "%30d", &externrefresh) != 1) { 29343 ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno); 29344 externrefresh = 10; 29345 } 29346 } else if (!strcasecmp(v->name, "externtcpport")) { 29347 if (!(externtcpport = port_str2int(v->value, 0))) { 29348 ast_log(LOG_WARNING, "Invalid externtcpport value, must be a positive integer between 1 and 65535 at line %d\n", v->lineno); 29349 externtcpport = 0; 29350 } 29351 } else if (!strcasecmp(v->name, "externtlsport")) { 29352 if (!(externtlsport = port_str2int(v->value, STANDARD_TLS_PORT))) { 29353 ast_log(LOG_WARNING, "Invalid externtlsport value, must be a positive integer between 1 and 65535 at line %d\n", v->lineno); 29354 } 29355 } else if (!strcasecmp(v->name, "allow")) { 29356 int error = ast_parse_allow_disallow(&default_prefs, &sip_cfg.capability, v->value, TRUE); 29357 if (error) { 29358 ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value); 29359 } 29360 } else if (!strcasecmp(v->name, "disallow")) { 29361 int error = ast_parse_allow_disallow(&default_prefs, &sip_cfg.capability, v->value, FALSE); 29362 if (error) { 29363 ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value); 29364 } 29365 } else if (!strcasecmp(v->name, "preferred_codec_only")) { 29366 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_PREFERRED_CODEC); 29367 } else if (!strcasecmp(v->name, "autoframing")) { 29368 global_autoframing = ast_true(v->value); 29369 } else if (!strcasecmp(v->name, "allowexternaldomains")) { 29370 sip_cfg.allow_external_domains = ast_true(v->value); 29371 } else if (!strcasecmp(v->name, "autodomain")) { 29372 auto_sip_domains = ast_true(v->value); 29373 } else if (!strcasecmp(v->name, "domain")) { 29374 char *domain = ast_strdupa(v->value); 29375 char *cntx = strchr(domain, ','); 29376 29377 if (cntx) { 29378 *cntx++ = '\0'; 29379 } 29380 29381 if (ast_strlen_zero(cntx)) { 29382 ast_debug(1, "No context specified at line %d for domain '%s'\n", v->lineno, domain); 29383 } 29384 if (ast_strlen_zero(domain)) { 29385 ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno); 29386 } else { 29387 add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, cntx ? ast_strip(cntx) : ""); 29388 } 29389 } else if (!strcasecmp(v->name, "register")) { 29390 if (sip_register(v->value, v->lineno) == 0) { 29391 registry_count++; 29392 } 29393 } else if (!strcasecmp(v->name, "mwi")) { 29394 sip_subscribe_mwi(v->value, v->lineno); 29395 } else if (!strcasecmp(v->name, "tos_sip")) { 29396 if (ast_str2tos(v->value, &global_tos_sip)) { 29397 ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, refer to QoS documentation\n", v->lineno); 29398 } 29399 } else if (!strcasecmp(v->name, "tos_audio")) { 29400 if (ast_str2tos(v->value, &global_tos_audio)) { 29401 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, refer to QoS documentation\n", v->lineno); 29402 } 29403 } else if (!strcasecmp(v->name, "tos_video")) { 29404 if (ast_str2tos(v->value, &global_tos_video)) { 29405 ast_log(LOG_WARNING, "Invalid tos_video value at line %d, refer to QoS documentation\n", v->lineno); 29406 } 29407 } else if (!strcasecmp(v->name, "tos_text")) { 29408 if (ast_str2tos(v->value, &global_tos_text)) { 29409 ast_log(LOG_WARNING, "Invalid tos_text value at line %d, refer to QoS documentation\n", v->lineno); 29410 } 29411 } else if (!strcasecmp(v->name, "cos_sip")) { 29412 if (ast_str2cos(v->value, &global_cos_sip)) { 29413 ast_log(LOG_WARNING, "Invalid cos_sip value at line %d, refer to QoS documentation\n", v->lineno); 29414 } 29415 } else if (!strcasecmp(v->name, "cos_audio")) { 29416 if (ast_str2cos(v->value, &global_cos_audio)) { 29417 ast_log(LOG_WARNING, "Invalid cos_audio value at line %d, refer to QoS documentation\n", v->lineno); 29418 } 29419 } else if (!strcasecmp(v->name, "cos_video")) { 29420 if (ast_str2cos(v->value, &global_cos_video)) { 29421 ast_log(LOG_WARNING, "Invalid cos_video value at line %d, refer to QoS documentation\n", v->lineno); 29422 } 29423 } else if (!strcasecmp(v->name, "cos_text")) { 29424 if (ast_str2cos(v->value, &global_cos_text)) { 29425 ast_log(LOG_WARNING, "Invalid cos_text value at line %d, refer to QoS documentation\n", v->lineno); 29426 } 29427 } else if (!strcasecmp(v->name, "bindport")) { 29428 if (sscanf(v->value, "%5d", &bindport) != 1) { 29429 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 29430 } 29431 } else if (!strcasecmp(v->name, "qualify")) { 29432 if (!strcasecmp(v->value, "no")) { 29433 default_qualify = 0; 29434 } else if (!strcasecmp(v->value, "yes")) { 29435 default_qualify = DEFAULT_MAXMS; 29436 } else if (sscanf(v->value, "%30d", &default_qualify) != 1) { 29437 ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno); 29438 default_qualify = 0; 29439 } 29440 } else if (!strcasecmp(v->name, "qualifyfreq")) { 29441 int i; 29442 if (sscanf(v->value, "%30d", &i) == 1) { 29443 global_qualifyfreq = i * 1000; 29444 } else { 29445 ast_log(LOG_WARNING, "Invalid qualifyfreq number '%s' at line %d of %s\n", v->value, v->lineno, config); 29446 global_qualifyfreq = DEFAULT_QUALIFYFREQ; 29447 } 29448 } else if (!strcasecmp(v->name, "callevents")) { 29449 sip_cfg.callevents = ast_true(v->value); 29450 } else if (!strcasecmp(v->name, "authfailureevents")) { 29451 global_authfailureevents = ast_true(v->value); 29452 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 29453 default_maxcallbitrate = atoi(v->value); 29454 if (default_maxcallbitrate < 0) 29455 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 29456 } else if (!strcasecmp(v->name, "matchexternaddrlocally") || !strcasecmp(v->name, "matchexterniplocally")) { 29457 sip_cfg.matchexternaddrlocally = ast_true(v->value); 29458 } else if (!strcasecmp(v->name, "session-timers")) { 29459 int i = (int) str2stmode(v->value); 29460 if (i < 0) { 29461 ast_log(LOG_WARNING, "Invalid session-timers '%s' at line %d of %s\n", v->value, v->lineno, config); 29462 global_st_mode = SESSION_TIMER_MODE_ACCEPT; 29463 } else { 29464 global_st_mode = i; 29465 } 29466 } else if (!strcasecmp(v->name, "session-expires")) { 29467 if (sscanf(v->value, "%30d", &global_max_se) != 1) { 29468 ast_log(LOG_WARNING, "Invalid session-expires '%s' at line %d of %s\n", v->value, v->lineno, config); 29469 global_max_se = DEFAULT_MAX_SE; 29470 } 29471 } else if (!strcasecmp(v->name, "session-minse")) { 29472 if (sscanf(v->value, "%30d", &global_min_se) != 1) { 29473 ast_log(LOG_WARNING, "Invalid session-minse '%s' at line %d of %s\n", v->value, v->lineno, config); 29474 global_min_se = DEFAULT_MIN_SE; 29475 } 29476 if (global_min_se < DEFAULT_MIN_SE) { 29477 ast_log(LOG_WARNING, "session-minse '%s' at line %d of %s is not allowed to be < %d secs\n", v->value, v->lineno, config, DEFAULT_MIN_SE); 29478 global_min_se = DEFAULT_MIN_SE; 29479 } 29480 } else if (!strcasecmp(v->name, "session-refresher")) { 29481 int i = (int) str2strefresherparam(v->value); 29482 if (i < 0) { 29483 ast_log(LOG_WARNING, "Invalid session-refresher '%s' at line %d of %s\n", v->value, v->lineno, config); 29484 global_st_refresher = SESSION_TIMER_REFRESHER_PARAM_UAS; 29485 } else { 29486 global_st_refresher = i; 29487 } 29488 } else if (!strcasecmp(v->name, "storesipcause")) { 29489 global_store_sip_cause = ast_true(v->value); 29490 } else if (!strcasecmp(v->name, "qualifygap")) { 29491 if (sscanf(v->value, "%30d", &global_qualify_gap) != 1) { 29492 ast_log(LOG_WARNING, "Invalid qualifygap '%s' at line %d of %s\n", v->value, v->lineno, config); 29493 global_qualify_gap = DEFAULT_QUALIFY_GAP; 29494 } 29495 } else if (!strcasecmp(v->name, "qualifypeers")) { 29496 if (sscanf(v->value, "%30d", &global_qualify_peers) != 1) { 29497 ast_log(LOG_WARNING, "Invalid pokepeers '%s' at line %d of %s\n", v->value, v->lineno, config); 29498 global_qualify_peers = DEFAULT_QUALIFY_PEERS; 29499 } 29500 } else if (!strcasecmp(v->name, "disallowed_methods")) { 29501 char *disallow = ast_strdupa(v->value); 29502 mark_parsed_methods(&sip_cfg.disallowed_methods, disallow); 29503 } else if (!strcasecmp(v->name, "shrinkcallerid")) { 29504 if (ast_true(v->value)) { 29505 global_shrinkcallerid = 1; 29506 } else if (ast_false(v->value)) { 29507 global_shrinkcallerid = 0; 29508 } else { 29509 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno); 29510 } 29511 } else if (!strcasecmp(v->name, "use_q850_reason")) { 29512 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_Q850_REASON); 29513 } else if (!strcasecmp(v->name, "maxforwards")) { 29514 if (sscanf(v->value, "%30d", &sip_cfg.default_max_forwards) != 1 29515 || sip_cfg.default_max_forwards < 1 || 255 < sip_cfg.default_max_forwards) { 29516 ast_log(LOG_WARNING, "'%s' is not a valid maxforwards value at line %d. Using default.\n", v->value, v->lineno); 29517 sip_cfg.default_max_forwards = DEFAULT_MAX_FORWARDS; 29518 } 29519 } else if (!strcasecmp(v->name, "subscribe_network_change_event")) { 29520 if (ast_true(v->value)) { 29521 subscribe_network_change = 1; 29522 } else if (ast_false(v->value)) { 29523 subscribe_network_change = 0; 29524 } else { 29525 ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno); 29526 } 29527 } else if (!strcasecmp(v->name, "snom_aoc_enabled")) { 29528 ast_set2_flag(&global_flags[2], ast_true(v->value), SIP_PAGE3_SNOM_AOC); 29529 } else if (!strcasecmp(v->name, "parkinglot")) { 29530 ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot)); 29531 } 29532 } 29533 29534 /* Override global defaults if setting found in general section */ 29535 ast_copy_flags(&global_flags[0], &setflags[0], mask[0].flags); 29536 ast_copy_flags(&global_flags[1], &setflags[1], mask[1].flags); 29537 ast_copy_flags(&global_flags[2], &setflags[2], mask[2].flags); 29538 29539 if (subscribe_network_change) { 29540 network_change_event_subscribe(); 29541 } else { 29542 network_change_event_unsubscribe(); 29543 } 29544 29545 if (global_t1 < global_t1min) { 29546 ast_log(LOG_WARNING, "'t1min' (%d) cannot be greater than 't1timer' (%d). Resetting 't1timer' to the value of 't1min'\n", global_t1min, global_t1); 29547 global_t1 = global_t1min; 29548 } 29549 29550 if (global_timer_b < global_t1 * 64) { 29551 if (timerb_set && timert1_set) { 29552 ast_log(LOG_WARNING, "Timer B has been set lower than recommended (%d < 64 * timert1=%d). (RFC 3261, 17.1.1.2)\n", global_timer_b, global_t1); 29553 } else if (timerb_set) { 29554 if ((global_t1 = global_timer_b / 64) < global_t1min) { 29555 ast_log(LOG_WARNING, "Timer B has been set lower than recommended (%d < 64 * timert1=%d). (RFC 3261, 17.1.1.2)\n", global_timer_b, global_t1); 29556 global_t1 = global_t1min; 29557 global_timer_b = global_t1 * 64; 29558 } 29559 } else { 29560 global_timer_b = global_t1 * 64; 29561 } 29562 } 29563 if (!sip_cfg.allow_external_domains && AST_LIST_EMPTY(&domain_list)) { 29564 ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n"); 29565 sip_cfg.allow_external_domains = 1; 29566 } 29567 /* If not or badly configured, set default transports */ 29568 if (!sip_cfg.tcp_enabled && (default_transports & SIP_TRANSPORT_TCP)) { 29569 ast_log(LOG_WARNING, "Cannot use 'tcp' transport with tcpenable=no. Removing from available transports.\n"); 29570 default_primary_transport &= ~SIP_TRANSPORT_TCP; 29571 default_transports &= ~SIP_TRANSPORT_TCP; 29572 } 29573 if (!default_tls_cfg.enabled && (default_transports & SIP_TRANSPORT_TLS)) { 29574 ast_log(LOG_WARNING, "Cannot use 'tls' transport with tlsenable=no. Removing from available transports.\n"); 29575 default_primary_transport &= ~SIP_TRANSPORT_TLS; 29576 default_transports &= ~SIP_TRANSPORT_TLS; 29577 } 29578 if (!default_transports) { 29579 ast_log(LOG_WARNING, "No valid transports available, falling back to 'udp'.\n"); 29580 default_transports = default_primary_transport = SIP_TRANSPORT_UDP; 29581 } else if (!default_primary_transport) { 29582 ast_log(LOG_WARNING, "No valid default transport. Selecting 'udp' as default.\n"); 29583 default_primary_transport = SIP_TRANSPORT_UDP; 29584 } 29585 29586 /* Build list of authentication to various SIP realms, i.e. service providers */ 29587 for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) { 29588 /* Format for authentication is auth = username:password@realm */ 29589 if (!strcasecmp(v->name, "auth")) { 29590 add_realm_authentication(&authl, v->value, v->lineno); 29591 } 29592 } 29593 29594 if (bindport) { 29595 if (ast_sockaddr_port(&bindaddr)) { 29596 ast_log(LOG_WARNING, "bindport is also specified in bindaddr. " 29597 "Using %d.\n", bindport); 29598 } 29599 ast_sockaddr_set_port(&bindaddr, bindport); 29600 } 29601 29602 if (!ast_sockaddr_port(&bindaddr)) { 29603 ast_sockaddr_set_port(&bindaddr, STANDARD_SIP_PORT); 29604 } 29605 29606 /* Set UDP address and open socket */ 29607 ast_sockaddr_copy(&internip, &bindaddr); 29608 if (ast_find_ourip(&internip, &bindaddr, 0)) { 29609 ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n"); 29610 ast_config_destroy(cfg); 29611 return 0; 29612 } 29613 29614 ast_mutex_lock(&netlock); 29615 if ((sipsock > -1) && (ast_sockaddr_cmp(&old_bindaddr, &bindaddr))) { 29616 close(sipsock); 29617 sipsock = -1; 29618 } 29619 if (sipsock < 0) { 29620 sipsock = socket(ast_sockaddr_is_ipv6(&bindaddr) ? 29621 AF_INET6 : AF_INET, SOCK_DGRAM, 0); 29622 if (sipsock < 0) { 29623 ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno)); 29624 ast_config_destroy(cfg); 29625 ast_mutex_unlock(&netlock); 29626 return -1; 29627 } else { 29628 /* Allow SIP clients on the same host to access us: */ 29629 const int reuseFlag = 1; 29630 29631 setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR, 29632 (const char*)&reuseFlag, 29633 sizeof reuseFlag); 29634 29635 ast_enable_packet_fragmentation(sipsock); 29636 29637 if (ast_bind(sipsock, &bindaddr) < 0) { 29638 ast_log(LOG_WARNING, "Failed to bind to %s: %s\n", 29639 ast_sockaddr_stringify(&bindaddr), strerror(errno)); 29640 close(sipsock); 29641 sipsock = -1; 29642 } else { 29643 ast_verb(2, "SIP Listening on %s\n", ast_sockaddr_stringify(&bindaddr)); 29644 ast_set_qos(sipsock, global_tos_sip, global_cos_sip, "SIP"); 29645 } 29646 } 29647 } else { 29648 ast_set_qos(sipsock, global_tos_sip, global_cos_sip, "SIP"); 29649 } 29650 ast_mutex_unlock(&netlock); 29651 29652 /* Start TCP server */ 29653 if (sip_cfg.tcp_enabled) { 29654 if (ast_sockaddr_isnull(&sip_tcp_desc.local_address)) { 29655 ast_sockaddr_copy(&sip_tcp_desc.local_address, &bindaddr); 29656 } 29657 if (!ast_sockaddr_port(&sip_tcp_desc.local_address)) { 29658 ast_sockaddr_set_port(&sip_tcp_desc.local_address, STANDARD_SIP_PORT); 29659 } 29660 } else { 29661 ast_sockaddr_setnull(&sip_tcp_desc.local_address); 29662 } 29663 ast_tcptls_server_start(&sip_tcp_desc); 29664 if (sip_cfg.tcp_enabled && sip_tcp_desc.accept_fd == -1) { 29665 /* TCP server start failed. Tell the admin */ 29666 ast_log(LOG_ERROR, "SIP TCP Server start failed. Not listening on TCP socket.\n"); 29667 } else { 29668 ast_debug(2, "SIP TCP server started\n"); 29669 } 29670 29671 /* Start TLS server if needed */ 29672 memcpy(sip_tls_desc.tls_cfg, &default_tls_cfg, sizeof(default_tls_cfg)); 29673 29674 if (ast_ssl_setup(sip_tls_desc.tls_cfg)) { 29675 if (ast_sockaddr_isnull(&sip_tls_desc.local_address)) { 29676 ast_sockaddr_copy(&sip_tls_desc.local_address, &bindaddr); 29677 ast_sockaddr_set_port(&sip_tls_desc.local_address, 29678 STANDARD_TLS_PORT); 29679 } 29680 if (!ast_sockaddr_port(&sip_tls_desc.local_address)) { 29681 ast_sockaddr_set_port(&sip_tls_desc.local_address, 29682 STANDARD_TLS_PORT); 29683 } 29684 ast_tcptls_server_start(&sip_tls_desc); 29685 if (default_tls_cfg.enabled && sip_tls_desc.accept_fd == -1) { 29686 ast_log(LOG_ERROR, "TLS Server start failed. Not listening on TLS socket.\n"); 29687 sip_tls_desc.tls_cfg = NULL; 29688 } 29689 } else if (sip_tls_desc.tls_cfg->enabled) { 29690 sip_tls_desc.tls_cfg = NULL; 29691 ast_log(LOG_WARNING, "SIP TLS server did not load because of errors.\n"); 29692 } 29693 29694 if (ucfg) { 29695 struct ast_variable *gen; 29696 int genhassip, genregistersip; 29697 const char *hassip, *registersip; 29698 29699 genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip")); 29700 genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip")); 29701 gen = ast_variable_browse(ucfg, "general"); 29702 cat = ast_category_browse(ucfg, NULL); 29703 while (cat) { 29704 if (strcasecmp(cat, "general")) { 29705 hassip = ast_variable_retrieve(ucfg, cat, "hassip"); 29706 registersip = ast_variable_retrieve(ucfg, cat, "registersip"); 29707 if (ast_true(hassip) || (!hassip && genhassip)) { 29708 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0, 0); 29709 if (peer) { 29710 /* user.conf entries are always of type friend */ 29711 peer->type = SIP_TYPE_USER | SIP_TYPE_PEER; 29712 ao2_t_link(peers, peer, "link peer into peer table"); 29713 if ((peer->type & SIP_TYPE_PEER) && !ast_sockaddr_isnull(&peer->addr)) { 29714 ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table"); 29715 } 29716 29717 unref_peer(peer, "unref_peer: from reload_config"); 29718 peer_count++; 29719 } 29720 } 29721 if (ast_true(registersip) || (!registersip && genregistersip)) { 29722 char tmp[256]; 29723 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 29724 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 29725 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 29726 const char *contact = ast_variable_retrieve(ucfg, cat, "contact"); 29727 const char *authuser = ast_variable_retrieve(ucfg, cat, "authuser"); 29728 if (!host) { 29729 host = ast_variable_retrieve(ucfg, "general", "host"); 29730 } 29731 if (!username) { 29732 username = ast_variable_retrieve(ucfg, "general", "username"); 29733 } 29734 if (!secret) { 29735 secret = ast_variable_retrieve(ucfg, "general", "secret"); 29736 } 29737 if (!contact) { 29738 contact = "s"; 29739 } 29740 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 29741 if (!ast_strlen_zero(secret)) { 29742 if (!ast_strlen_zero(authuser)) { 29743 snprintf(tmp, sizeof(tmp), "%s?%s:%s:%s@%s/%s", cat, username, secret, authuser, host, contact); 29744 } else { 29745 snprintf(tmp, sizeof(tmp), "%s?%s:%s@%s/%s", cat, username, secret, host, contact); 29746 } 29747 } else if (!ast_strlen_zero(authuser)) { 29748 snprintf(tmp, sizeof(tmp), "%s?%s::%s@%s/%s", cat, username, authuser, host, contact); 29749 } else { 29750 snprintf(tmp, sizeof(tmp), "%s?%s@%s/%s", cat, username, host, contact); 29751 } 29752 if (sip_register(tmp, 0) == 0) { 29753 registry_count++; 29754 } 29755 } 29756 } 29757 } 29758 cat = ast_category_browse(ucfg, cat); 29759 } 29760 ast_config_destroy(ucfg); 29761 } 29762 29763 /* Load peers, users and friends */ 29764 cat = NULL; 29765 while ( (cat = ast_category_browse(cfg, cat)) ) { 29766 const char *utype; 29767 if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication")) 29768 continue; 29769 utype = ast_variable_retrieve(cfg, cat, "type"); 29770 if (!utype) { 29771 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 29772 continue; 29773 } else { 29774 if (!strcasecmp(utype, "user")) { 29775 ; 29776 } else if (!strcasecmp(utype, "friend")) { 29777 ; 29778 } else if (!strcasecmp(utype, "peer")) { 29779 ; 29780 } else { 29781 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf"); 29782 continue; 29783 } 29784 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0, 0); 29785 if (peer) { 29786 display_nat_warning(cat, reason, &peer->flags[0]); 29787 ao2_t_link(peers, peer, "link peer into peers table"); 29788 if ((peer->type & SIP_TYPE_PEER) && !ast_sockaddr_isnull(&peer->addr)) { 29789 ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table"); 29790 } 29791 unref_peer(peer, "unref the result of the build_peer call. Now, the links from the tables are the only ones left."); 29792 peer_count++; 29793 } 29794 } 29795 } 29796 29797 /* Add default domains - host name, IP address and IP:port 29798 * Only do this if user added any sip domain with "localdomains" 29799 * In order to *not* break backwards compatibility 29800 * Some phones address us at IP only, some with additional port number 29801 */ 29802 if (auto_sip_domains) { 29803 char temp[MAXHOSTNAMELEN]; 29804 29805 /* First our default IP address */ 29806 if (!ast_sockaddr_isnull(&bindaddr) && !ast_sockaddr_is_any(&bindaddr)) { 29807 add_sip_domain(ast_sockaddr_stringify_addr(&bindaddr), 29808 SIP_DOMAIN_AUTO, NULL); 29809 } else if (!ast_sockaddr_isnull(&internip) && !ast_sockaddr_is_any(&internip)) { 29810 /* Our internal IP address, if configured */ 29811 add_sip_domain(ast_sockaddr_stringify_addr(&internip), 29812 SIP_DOMAIN_AUTO, NULL); 29813 } else { 29814 ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n"); 29815 } 29816 29817 /* If TCP is running on a different IP than UDP, then add it too */ 29818 if (!ast_sockaddr_isnull(&sip_tcp_desc.local_address) && 29819 !ast_sockaddr_cmp(&bindaddr, &sip_tcp_desc.local_address)) { 29820 add_sip_domain(ast_sockaddr_stringify_addr(&sip_tcp_desc.local_address), 29821 SIP_DOMAIN_AUTO, NULL); 29822 } 29823 29824 /* If TLS is running on a different IP than UDP and TCP, then add that too */ 29825 if (!ast_sockaddr_isnull(&sip_tls_desc.local_address) && 29826 !ast_sockaddr_cmp(&bindaddr, &sip_tls_desc.local_address) && 29827 !ast_sockaddr_cmp(&sip_tcp_desc.local_address, 29828 &sip_tls_desc.local_address)) { 29829 add_sip_domain(ast_sockaddr_stringify_addr(&sip_tcp_desc.local_address), 29830 SIP_DOMAIN_AUTO, NULL); 29831 } 29832 29833 /* Our extern IP address, if configured */ 29834 if (!ast_sockaddr_isnull(&externaddr)) { 29835 add_sip_domain(ast_sockaddr_stringify_addr(&externaddr), 29836 SIP_DOMAIN_AUTO, NULL); 29837 } 29838 29839 /* Extern host name (NAT traversal support) */ 29840 if (!ast_strlen_zero(externhost)) { 29841 add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL); 29842 } 29843 29844 /* Our host name */ 29845 if (!gethostname(temp, sizeof(temp))) { 29846 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 29847 } 29848 } 29849 29850 /* Release configuration from memory */ 29851 ast_config_destroy(cfg); 29852 29853 /* Load the list of manual NOTIFY types to support */ 29854 if (notify_types) 29855 ast_config_destroy(notify_types); 29856 if ((notify_types = ast_config_load(notify_config, config_flags)) == CONFIG_STATUS_FILEINVALID) { 29857 ast_log(LOG_ERROR, "Contents of %s are invalid and cannot be parsed.\n", notify_config); 29858 notify_types = NULL; 29859 } 29860 29861 /* Done, tell the manager */ 29862 manager_event(EVENT_FLAG_SYSTEM, "ChannelReload", "ChannelType: SIP\r\nReloadReason: %s\r\nRegistry_Count: %d\r\nPeer_Count: %d\r\n", channelreloadreason2txt(reason), registry_count, peer_count); 29863 run_end = time(0); 29864 ast_debug(4, "SIP reload_config done...Runtime= %d sec\n", (int)(run_end-run_start)); 29865 29866 return 0; 29867 }
| static char * remove_uri_parameters | ( | char * | uri | ) | [static] |
Definition at line 12299 of file chan_sip.c.
Referenced by extract_uri(), parse_moved_contact(), register_verify(), reqprep(), and transmit_state_notify().
12300 { 12301 char *atsign; 12302 atsign = strchr(uri, '@'); /* First, locate the at sign */ 12303 if (!atsign) { 12304 atsign = uri; /* Ok hostname only, let's stick with the rest */ 12305 } 12306 atsign = strchr(atsign, ';'); /* Locate semi colon */ 12307 if (atsign) 12308 *atsign = '\0'; /* Kill at the semi colon */ 12309 return uri; 12310 }
| static int reply_digest | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| char * | header, | |||
| int | sipmethod, | |||
| char * | digest, | |||
| int | digest_len | |||
| ) | [static] |
reply to authentication for outbound registrations
Definition at line 19849 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_skip_blanks(), ast_string_field_ptr_set, ast_string_field_set, ast_strlen_zero(), build_reply_digest(), get_header(), and LOG_WARNING.
Referenced by do_proxy_auth(), and do_register_auth().
19850 { 19851 char tmp[512]; 19852 char *c; 19853 char oldnonce[256]; 19854 19855 /* table of recognised keywords, and places where they should be copied */ 19856 const struct x { 19857 const char *key; 19858 const ast_string_field *field; 19859 } *i, keys[] = { 19860 { "realm=", &p->realm }, 19861 { "nonce=", &p->nonce }, 19862 { "opaque=", &p->opaque }, 19863 { "qop=", &p->qop }, 19864 { "domain=", &p->domain }, 19865 { NULL, 0 }, 19866 }; 19867 19868 ast_copy_string(tmp, get_header(req, header), sizeof(tmp)); 19869 if (ast_strlen_zero(tmp)) 19870 return -1; 19871 if (strncasecmp(tmp, "Digest ", strlen("Digest "))) { 19872 ast_log(LOG_WARNING, "missing Digest.\n"); 19873 return -1; 19874 } 19875 c = tmp + strlen("Digest "); 19876 ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce)); 19877 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 19878 for (i = keys; i->key != NULL; i++) { 19879 char *src, *separator; 19880 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 19881 continue; 19882 /* Found. Skip keyword, take text in quotes or up to the separator. */ 19883 c += strlen(i->key); 19884 if (*c == '"') { 19885 src = ++c; 19886 separator = "\""; 19887 } else { 19888 src = c; 19889 separator = ","; 19890 } 19891 strsep(&c, separator); /* clear separator and move ptr */ 19892 ast_string_field_ptr_set(p, i->field, src); 19893 break; 19894 } 19895 if (i->key == NULL) /* not found, try ',' */ 19896 strsep(&c, ","); 19897 } 19898 /* Reset nonce count */ 19899 if (strcmp(p->nonce, oldnonce)) 19900 p->noncecount = 0; 19901 19902 /* Save auth data for following registrations */ 19903 if (p->registry) { 19904 struct sip_registry *r = p->registry; 19905 19906 if (strcmp(r->nonce, p->nonce)) { 19907 ast_string_field_set(r, realm, p->realm); 19908 ast_string_field_set(r, nonce, p->nonce); 19909 ast_string_field_set(r, authdomain, p->domain); 19910 ast_string_field_set(r, opaque, p->opaque); 19911 ast_string_field_set(r, qop, p->qop); 19912 r->noncecount = 0; 19913 } 19914 } 19915 return build_reply_digest(p, sipmethod, digest, digest_len); 19916 }
| static int reqprep | ( | struct sip_request * | req, | |
| struct sip_pvt * | p, | |||
| int | sipmethod, | |||
| uint32_t | seqno, | |||
| int | newbranch | |||
| ) | [static] |
Initialize a SIP request message (not the initial one in a dialog).
< Strict routing flag
Definition at line 10706 of file chan_sip.c.
References add_header(), add_header_max_forwards(), add_route(), ast_copy_string(), ast_debug, ast_random(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, build_via(), copy_header(), FALSE, get_header(), get_in_brackets(), init_req(), remove_uri_parameters(), set_destination(), sip_methods, st_get_se(), text, cfsip_methods::text, TRUE, and url.
Referenced by transmit_cc_notify(), transmit_info_with_aoc(), transmit_info_with_digit(), transmit_info_with_vidupdate(), transmit_invite(), transmit_message_with_text(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), transmit_state_notify(), and update_connectedline().
10707 { 10708 struct sip_request *orig = &p->initreq; 10709 char stripped[80]; 10710 char tmp[80]; 10711 char newto[256]; 10712 const char *c; 10713 const char *ot, *of; 10714 int is_strict = FALSE; /*!< Strict routing flag */ 10715 int is_outbound = ast_test_flag(&p->flags[0], SIP_OUTGOING); /* Session direction */ 10716 10717 snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text); 10718 10719 if (!seqno) { 10720 p->ocseq++; 10721 seqno = p->ocseq; 10722 } 10723 10724 /* A CANCEL must have the same branch as the INVITE that it is canceling. */ 10725 if (sipmethod == SIP_CANCEL) { 10726 p->branch = p->invite_branch; 10727 build_via(p); 10728 } else if (newbranch && (sipmethod == SIP_INVITE)) { 10729 p->branch ^= ast_random(); 10730 p->invite_branch = p->branch; 10731 build_via(p); 10732 } else if (newbranch) { 10733 p->branch ^= ast_random(); 10734 build_via(p); 10735 } 10736 10737 /* Check for strict or loose router */ 10738 if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop, ";lr") == NULL) { 10739 is_strict = TRUE; 10740 if (sipdebug) 10741 ast_debug(1, "Strict routing enforced for session %s\n", p->callid); 10742 } 10743 10744 if (sipmethod == SIP_CANCEL) 10745 c = REQ_OFFSET_TO_STR(&p->initreq, rlPart2); /* Use original URI */ 10746 else if (sipmethod == SIP_ACK) { 10747 /* Use URI from Contact: in 200 OK (if INVITE) 10748 (we only have the contacturi on INVITEs) */ 10749 if (!ast_strlen_zero(p->okcontacturi)) 10750 c = is_strict ? p->route->hop : p->okcontacturi; 10751 else 10752 c = REQ_OFFSET_TO_STR(&p->initreq, rlPart2); 10753 } else if (!ast_strlen_zero(p->okcontacturi)) 10754 c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */ 10755 else if (!ast_strlen_zero(p->uri)) 10756 c = p->uri; 10757 else { 10758 char *n; 10759 /* We have no URI, use To: or From: header as URI (depending on direction) */ 10760 ast_copy_string(stripped, get_header(orig, is_outbound ? "To" : "From"), 10761 sizeof(stripped)); 10762 n = get_in_brackets(stripped); 10763 c = remove_uri_parameters(n); 10764 } 10765 init_req(req, sipmethod, c); 10766 10767 snprintf(tmp, sizeof(tmp), "%u %s", seqno, sip_methods[sipmethod].text); 10768 10769 add_header(req, "Via", p->via); 10770 /* 10771 * Use the learned route set unless this is a CANCEL on an ACK for a non-2xx 10772 * final response. For a CANCEL or ACK, we have to send to the same destination 10773 * as the original INVITE. 10774 */ 10775 if (p->route && 10776 !(sipmethod == SIP_CANCEL || 10777 (sipmethod == SIP_ACK && (p->invitestate == INV_COMPLETED || p->invitestate == INV_CANCELLED)))) { 10778 set_destination(p, p->route->hop); 10779 add_route(req, is_strict ? p->route->next : p->route); 10780 } 10781 add_header_max_forwards(p, req); 10782 10783 ot = get_header(orig, "To"); 10784 of = get_header(orig, "From"); 10785 10786 /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly 10787 as our original request, including tag (or presumably lack thereof) */ 10788 if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) { 10789 /* Add the proper tag if we don't have it already. If they have specified 10790 their tag, use it. Otherwise, use our own tag */ 10791 if (is_outbound && !ast_strlen_zero(p->theirtag)) 10792 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 10793 else if (!is_outbound) 10794 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 10795 else 10796 snprintf(newto, sizeof(newto), "%s", ot); 10797 ot = newto; 10798 } 10799 10800 if (is_outbound) { 10801 add_header(req, "From", of); 10802 add_header(req, "To", ot); 10803 } else { 10804 add_header(req, "From", ot); 10805 add_header(req, "To", of); 10806 } 10807 /* Do not add Contact for MESSAGE, BYE and Cancel requests */ 10808 if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE) 10809 add_header(req, "Contact", p->our_contact); 10810 10811 copy_header(req, orig, "Call-ID"); 10812 add_header(req, "CSeq", tmp); 10813 10814 if (!ast_strlen_zero(global_useragent)) 10815 add_header(req, "User-Agent", global_useragent); 10816 10817 if (!ast_strlen_zero(p->url)) { 10818 add_header(req, "Access-URL", p->url); 10819 ast_string_field_set(p, url, NULL); 10820 } 10821 10822 /* Add Session-Timers related headers if the feature is active for this session. 10823 An exception to this behavior is the ACK request. Since Asterisk never requires 10824 session-timers support from a remote end-point (UAS) in an INVITE, it must 10825 not send 'Require: timer' header in the ACK request. 10826 This should only be added in the INVITE transactions, not MESSAGE or REFER or other 10827 in-dialog messages. 10828 */ 10829 if (p->stimer && p->stimer->st_active == TRUE && p->stimer->st_active_peer_ua == TRUE 10830 && sipmethod == SIP_INVITE) { 10831 char se_hdr[256]; 10832 snprintf(se_hdr, sizeof(se_hdr), "%d;refresher=%s", p->stimer->st_interval, 10833 p->stimer->st_ref == SESSION_TIMER_REFRESHER_US ? "uac" : "uas"); 10834 add_header(req, "Session-Expires", se_hdr); 10835 snprintf(se_hdr, sizeof(se_hdr), "%d", st_get_se(p, FALSE)); 10836 add_header(req, "Min-SE", se_hdr); 10837 } 10838 10839 return 0; 10840 }
| static int resp_needs_contact | ( | const char * | msg, | |
| enum sipmethod | method | |||
| ) | [inline, static] |
Test if this response needs a contact header.
Definition at line 10554 of file chan_sip.c.
Referenced by respprep().
10554 { 10555 /* Requirements for Contact header inclusion in responses generated 10556 * from the header tables found in the following RFCs. Where the 10557 * Contact header was marked mandatory (m) or optional (o) this 10558 * function returns 1. 10559 * 10560 * - RFC 3261 (ACK, BYE, CANCEL, INVITE, OPTIONS, REGISTER) 10561 * - RFC 2976 (INFO) 10562 * - RFC 3262 (PRACK) 10563 * - RFC 3265 (SUBSCRIBE, NOTIFY) 10564 * - RFC 3311 (UPDATE) 10565 * - RFC 3428 (MESSAGE) 10566 * - RFC 3515 (REFER) 10567 * - RFC 3903 (PUBLISH) 10568 */ 10569 10570 switch (method) { 10571 /* 1xx, 2xx, 3xx, 485 */ 10572 case SIP_INVITE: 10573 case SIP_UPDATE: 10574 case SIP_SUBSCRIBE: 10575 case SIP_NOTIFY: 10576 if ((msg[0] >= '1' && msg[0] <= '3') || !strncmp(msg, "485", 3)) 10577 return 1; 10578 break; 10579 10580 /* 2xx, 3xx, 485 */ 10581 case SIP_REGISTER: 10582 case SIP_OPTIONS: 10583 if (msg[0] == '2' || msg[0] == '3' || !strncmp(msg, "485", 3)) 10584 return 1; 10585 break; 10586 10587 /* 3xx, 485 */ 10588 case SIP_BYE: 10589 case SIP_PRACK: 10590 case SIP_MESSAGE: 10591 case SIP_PUBLISH: 10592 if (msg[0] == '3' || !strncmp(msg, "485", 3)) 10593 return 1; 10594 break; 10595 10596 /* 2xx, 3xx, 4xx, 5xx, 6xx */ 10597 case SIP_REFER: 10598 if (msg[0] >= '2' && msg[0] <= '6') 10599 return 1; 10600 break; 10601 10602 /* contact will not be included for everything else */ 10603 case SIP_ACK: 10604 case SIP_CANCEL: 10605 case SIP_INFO: 10606 case SIP_PING: 10607 default: 10608 return 0; 10609 } 10610 return 0; 10611 }
| static int respprep | ( | struct sip_request * | resp, | |
| struct sip_pvt * | p, | |||
| const char * | msg, | |||
| const struct sip_request * | req | |||
| ) | [static] |
Prepare SIP response packet.
Definition at line 10614 of file chan_sip.c.
References add_header(), add_supported_header(), ast_copy_string(), ast_log(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, copy_all_header(), copy_header(), copy_via_headers(), get_header(), init_resp(), LOG_WARNING, process_via(), resp_needs_contact(), TRUE, and url.
Referenced by __transmit_response(), transmit_response_with_allow(), transmit_response_with_auth(), transmit_response_with_date(), transmit_response_with_minexpires(), transmit_response_with_minse(), transmit_response_with_retry_after(), transmit_response_with_sdp(), transmit_response_with_sip_etag(), transmit_response_with_t38_sdp(), transmit_response_with_unsupported(), update_connectedline(), and update_redirecting().
10615 { 10616 char newto[256]; 10617 const char *ot; 10618 10619 init_resp(resp, msg); 10620 copy_via_headers(p, resp, req, "Via"); 10621 if (msg[0] == '1' || msg[0] == '2') 10622 copy_all_header(resp, req, "Record-Route"); 10623 copy_header(resp, req, "From"); 10624 ot = get_header(req, "To"); 10625 if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) { 10626 /* Add the proper tag if we don't have it already. If they have specified 10627 their tag, use it. Otherwise, use our own tag */ 10628 if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING)) 10629 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 10630 else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) 10631 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 10632 else 10633 ast_copy_string(newto, ot, sizeof(newto)); 10634 ot = newto; 10635 } 10636 add_header(resp, "To", ot); 10637 copy_header(resp, req, "Call-ID"); 10638 copy_header(resp, req, "CSeq"); 10639 if (!ast_strlen_zero(global_useragent)) 10640 add_header(resp, "Server", global_useragent); 10641 add_header(resp, "Allow", ALLOWED_METHODS); 10642 add_supported_header(p, resp); 10643 10644 /* If this is an invite, add Session-Timers related headers if the feature is active for this session */ 10645 if (p->method == SIP_INVITE && p->stimer && p->stimer->st_active == TRUE) { 10646 char se_hdr[256]; 10647 snprintf(se_hdr, sizeof(se_hdr), "%d;refresher=%s", p->stimer->st_interval, 10648 p->stimer->st_ref == SESSION_TIMER_REFRESHER_US ? "uas" : "uac"); 10649 add_header(resp, "Session-Expires", se_hdr); 10650 /* RFC 2048, Section 9 10651 * If the refresher parameter in the Session-Expires header field in the 10652 * 2xx response has a value of 'uac', the UAS MUST place a Require 10653 * header field into the response with the value 'timer'. 10654 * ... 10655 * If the refresher parameter in 10656 * the 2xx response has a value of 'uas' and the Supported header field 10657 * in the request contained the value 'timer', the UAS SHOULD place a 10658 * Require header field into the response with the value 'timer' 10659 */ 10660 if (p->stimer->st_ref == SESSION_TIMER_REFRESHER_THEM || 10661 (p->stimer->st_ref == SESSION_TIMER_REFRESHER_US && 10662 p->stimer->st_active_peer_ua == TRUE)) { 10663 resp->reqsipoptions |= SIP_OPT_TIMER; 10664 } 10665 } 10666 10667 if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_PUBLISH)) { 10668 /* For registration responses, we also need expiry and 10669 contact info */ 10670 char tmp[256]; 10671 10672 snprintf(tmp, sizeof(tmp), "%d", p->expiry); 10673 add_header(resp, "Expires", tmp); 10674 if (p->expiry) { /* Only add contact if we have an expiry time */ 10675 char contact[SIPBUFSIZE]; 10676 const char *contact_uri = p->method == SIP_SUBSCRIBE ? p->our_contact : p->fullcontact; 10677 char *brackets = strchr(contact_uri, '<'); 10678 snprintf(contact, sizeof(contact), "%s%s%s;expires=%d", brackets ? "" : "<", contact_uri, brackets ? "" : ">", p->expiry); 10679 add_header(resp, "Contact", contact); /* Not when we unregister */ 10680 } 10681 } else if (!ast_strlen_zero(p->our_contact) && resp_needs_contact(msg, p->method)) { 10682 add_header(resp, "Contact", p->our_contact); 10683 } 10684 10685 if (!ast_strlen_zero(p->url)) { 10686 add_header(resp, "Access-URL", p->url); 10687 ast_string_field_set(p, url, NULL); 10688 } 10689 10690 /* default to routing the response to the address where the request 10691 * came from. Since we don't have a transport layer, we do this here. 10692 * The process_via() function will update the port to either the port 10693 * specified in the via header or the default port later on (per RFC 10694 * 3261 section 18.2.2). 10695 */ 10696 p->sa = p->recv; 10697 10698 if (process_via(p, req)) { 10699 ast_log(LOG_WARNING, "error processing via header, will send response to originating address\n"); 10700 } 10701 10702 return 0; 10703 }
| static int restart_monitor | ( | void | ) | [static] |
Start the channel monitor thread.
Definition at line 26718 of file chan_sip.c.
References ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_pthread_create_background, AST_PTHREADT_NULL, AST_PTHREADT_STOP, do_monitor(), LOG_ERROR, and LOG_WARNING.
Referenced by load_module(), sip_reload(), and sip_request_call().
26719 { 26720 /* If we're supposed to be stopped -- stay stopped */ 26721 if (monitor_thread == AST_PTHREADT_STOP) 26722 return 0; 26723 ast_mutex_lock(&monlock); 26724 if (monitor_thread == pthread_self()) { 26725 ast_mutex_unlock(&monlock); 26726 ast_log(LOG_WARNING, "Cannot kill myself\n"); 26727 return -1; 26728 } 26729 if (monitor_thread != AST_PTHREADT_NULL) { 26730 /* Wake up the thread */ 26731 pthread_kill(monitor_thread, SIGURG); 26732 } else { 26733 /* Start a new monitor */ 26734 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 26735 ast_mutex_unlock(&monlock); 26736 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 26737 return -1; 26738 } 26739 } 26740 ast_mutex_unlock(&monlock); 26741 return 0; 26742 }
| static void restart_session_timer | ( | struct sip_pvt * | p | ) | [static] |
Session-Timers: Restart session timer.
Definition at line 26746 of file chan_sip.c.
References ast_debug, AST_SCHED_DEL_UNREF, start_session_timer(), and TRUE.
Referenced by handle_request_invite().
26747 { 26748 if (p->stimer->st_active == TRUE) { 26749 ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid); 26750 AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid, 26751 dialog_unref(p, "Removing session timer ref")); 26752 start_session_timer(p); 26753 } 26754 }
| static int retrans_pkt | ( | const void * | data | ) | [static] |
Retransmit SIP message if no answer (Called from scheduler).
Definition at line 3730 of file chan_sip.c.
References __sip_xmit(), append_history, AST_CAUSE_NO_USER_RESPONSE, ast_channel_trylock, ast_channel_unlock, ast_debug, ast_free, ast_log(), ast_queue_hangup_with_cause(), ast_sockaddr_stringify(), ast_str_buffer(), ast_test_flag, ast_tvdiff_ms(), ast_tvnow(), ast_verbose, check_pendings(), DEFAULT_RETRANS, LOG_WARNING, pvt_set_needdestroy(), sip_alreadygone(), sip_debug_test_pvt(), sip_methods, sip_nat_mode(), sip_pvt_lock, sip_pvt_unlock, sip_real_dst(), cfsip_methods::text, and UNLINK.
Referenced by __sip_reliable_xmit(), and sip_show_sched().
03731 { 03732 struct sip_pkt *pkt = (struct sip_pkt *)data, *prev, *cur = NULL; 03733 int reschedule = DEFAULT_RETRANS; 03734 int xmitres = 0; 03735 /* how many ms until retrans timeout is reached */ 03736 int64_t diff = pkt->retrans_stop_time - ast_tvdiff_ms(ast_tvnow(), pkt->time_sent); 03737 03738 /* Do not retransmit if time out is reached. This will be negative if the time between 03739 * the first transmission and now is larger than our timeout period. This is a fail safe 03740 * check in case the scheduler gets behind or the clock is changed. */ 03741 if ((diff <= 0) || (diff > pkt->retrans_stop_time)) { 03742 pkt->retrans_stop = 1; 03743 } 03744 03745 /* Lock channel PVT */ 03746 sip_pvt_lock(pkt->owner); 03747 03748 if (!pkt->retrans_stop) { 03749 pkt->retrans++; 03750 if (!pkt->timer_t1) { /* Re-schedule using timer_a and timer_t1 */ 03751 if (sipdebug) { 03752 ast_debug(4, "SIP TIMER: Not rescheduling id #%d:%s (Method %d) (No timer T1)\n", 03753 pkt->retransid, 03754 sip_methods[pkt->method].text, 03755 pkt->method); 03756 } 03757 } else { 03758 int siptimer_a; 03759 03760 if (sipdebug) { 03761 ast_debug(4, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", 03762 pkt->retransid, 03763 pkt->retrans, 03764 sip_methods[pkt->method].text, 03765 pkt->method); 03766 } 03767 if (!pkt->timer_a) { 03768 pkt->timer_a = 2 ; 03769 } else { 03770 pkt->timer_a = 2 * pkt->timer_a; 03771 } 03772 03773 /* For non-invites, a maximum of 4 secs */ 03774 siptimer_a = pkt->timer_t1 * pkt->timer_a; /* Double each time */ 03775 if (pkt->method != SIP_INVITE && siptimer_a > 4000) { 03776 siptimer_a = 4000; 03777 } 03778 03779 /* Reschedule re-transmit */ 03780 reschedule = siptimer_a; 03781 ast_debug(4, "** SIP timers: Rescheduling retransmission %d to %d ms (t1 %d ms (Retrans id #%d)) \n", 03782 pkt->retrans + 1, 03783 siptimer_a, 03784 pkt->timer_t1, 03785 pkt->retransid); 03786 } 03787 03788 if (sip_debug_test_pvt(pkt->owner)) { 03789 const struct ast_sockaddr *dst = sip_real_dst(pkt->owner); 03790 ast_verbose("Retransmitting #%d (%s) to %s:\n%s\n---\n", 03791 pkt->retrans, sip_nat_mode(pkt->owner), 03792 ast_sockaddr_stringify(dst), 03793 ast_str_buffer(pkt->data)); 03794 } 03795 03796 append_history(pkt->owner, "ReTx", "%d %s", reschedule, ast_str_buffer(pkt->data)); 03797 xmitres = __sip_xmit(pkt->owner, pkt->data); 03798 03799 /* If there was no error during the network transmission, schedule the next retransmission, 03800 * but if the next retransmission is going to be beyond our timeout period, mark the packet's 03801 * stop_retrans value and set the next retransmit to be the exact time of timeout. This will 03802 * allow any responses to the packet to be processed before the packet is destroyed on the next 03803 * call to this function by the scheduler. */ 03804 if (xmitres != XMIT_ERROR) { 03805 if (reschedule >= diff) { 03806 pkt->retrans_stop = 1; 03807 reschedule = diff; 03808 } 03809 sip_pvt_unlock(pkt->owner); 03810 return reschedule; 03811 } 03812 } 03813 03814 /* At this point, either the packet's retransmission timed out, or there was a 03815 * transmission error, either way destroy the scheduler item and this packet. */ 03816 03817 pkt->retransid = -1; /* Kill this scheduler item */ 03818 03819 if (pkt->method != SIP_OPTIONS && xmitres == 0) { 03820 if (pkt->is_fatal || sipdebug) { /* Tell us if it's critical or if we're debugging */ 03821 ast_log(LOG_WARNING, "Retransmission timeout reached on transmission %s for seqno %u (%s %s) -- See https://wiki.asterisk.org/wiki/display/AST/SIP+Retransmissions\n" 03822 "Packet timed out after %dms with no response\n", 03823 pkt->owner->callid, 03824 pkt->seqno, 03825 pkt->is_fatal ? "Critical" : "Non-critical", 03826 pkt->is_resp ? "Response" : "Request", 03827 (int) ast_tvdiff_ms(ast_tvnow(), pkt->time_sent)); 03828 } 03829 } else if (pkt->method == SIP_OPTIONS && sipdebug) { 03830 ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s) -- See https://wiki.asterisk.org/wiki/display/AST/SIP+Retransmissions\n", pkt->owner->callid); 03831 } 03832 03833 if (xmitres == XMIT_ERROR) { 03834 ast_log(LOG_WARNING, "Transmit error :: Cancelling transmission on Call ID %s\n", pkt->owner->callid); 03835 append_history(pkt->owner, "XmitErr", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)"); 03836 } else { 03837 append_history(pkt->owner, "MaxRetries", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)"); 03838 } 03839 03840 if (pkt->is_fatal) { 03841 while(pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) { 03842 sip_pvt_unlock(pkt->owner); /* SIP_PVT, not channel */ 03843 usleep(1); 03844 sip_pvt_lock(pkt->owner); 03845 } 03846 if (pkt->owner->owner && !pkt->owner->owner->hangupcause) { 03847 pkt->owner->owner->hangupcause = AST_CAUSE_NO_USER_RESPONSE; 03848 } 03849 if (pkt->owner->owner) { 03850 ast_log(LOG_WARNING, "Hanging up call %s - no reply to our critical packet (see https://wiki.asterisk.org/wiki/display/AST/SIP+Retransmissions).\n", pkt->owner->callid); 03851 03852 if (pkt->is_resp && 03853 (pkt->response_code >= 200) && 03854 (pkt->response_code < 300) && 03855 pkt->owner->pendinginvite && 03856 ast_test_flag(&pkt->owner->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) { 03857 /* This is a timeout of the 2XX response to a pending INVITE. In this case terminate the INVITE 03858 * transaction just as if we received the ACK, but immediately hangup with a BYE (sip_hangup 03859 * will send the BYE as long as the dialog is not set as "alreadygone") 03860 * RFC 3261 section 13.3.1.4. 03861 * "If the server retransmits the 2xx response for 64*T1 seconds without receiving 03862 * an ACK, the dialog is confirmed, but the session SHOULD be terminated. This is 03863 * accomplished with a BYE, as described in Section 15." */ 03864 pkt->owner->invitestate = INV_TERMINATED; 03865 pkt->owner->pendinginvite = 0; 03866 } else { 03867 /* there is nothing left to do, mark the dialog as gone */ 03868 sip_alreadygone(pkt->owner); 03869 } 03870 ast_queue_hangup_with_cause(pkt->owner->owner, AST_CAUSE_NO_USER_RESPONSE); 03871 ast_channel_unlock(pkt->owner->owner); 03872 } else { 03873 /* If no channel owner, destroy now */ 03874 03875 /* Let the peerpoke system expire packets when the timer expires for poke_noanswer */ 03876 if (pkt->method != SIP_OPTIONS && pkt->method != SIP_REGISTER) { 03877 pvt_set_needdestroy(pkt->owner, "no response to critical packet"); 03878 sip_alreadygone(pkt->owner); 03879 append_history(pkt->owner, "DialogKill", "Killing this failed dialog immediately"); 03880 } 03881 } 03882 } else if (pkt->owner->pendinginvite == pkt->seqno) { 03883 ast_log(LOG_WARNING, "Timeout on %s on non-critical invite transaction.\n", pkt->owner->callid); 03884 pkt->owner->invitestate = INV_TERMINATED; 03885 pkt->owner->pendinginvite = 0; 03886 check_pendings(pkt->owner); 03887 } 03888 03889 if (pkt->method == SIP_BYE) { 03890 /* We're not getting answers on SIP BYE's. Tear down the call anyway. */ 03891 sip_alreadygone(pkt->owner); 03892 if (pkt->owner->owner) { 03893 ast_channel_unlock(pkt->owner->owner); 03894 } 03895 append_history(pkt->owner, "ByeFailure", "Remote peer doesn't respond to bye. Destroying call anyway."); 03896 pvt_set_needdestroy(pkt->owner, "no response to BYE"); 03897 } 03898 03899 /* Remove the packet */ 03900 for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) { 03901 if (cur == pkt) { 03902 UNLINK(cur, pkt->owner->packets, prev); 03903 sip_pvt_unlock(pkt->owner); 03904 if (pkt->owner) { 03905 pkt->owner = dialog_unref(pkt->owner,"pkt is being freed, its dialog ref is dead now"); 03906 } 03907 if (pkt->data) { 03908 ast_free(pkt->data); 03909 } 03910 pkt->data = NULL; 03911 ast_free(pkt); 03912 return 0; 03913 } 03914 } 03915 /* error case */ 03916 ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n"); 03917 sip_pvt_unlock(pkt->owner); 03918 return 0; 03919 }
| static int send_provisional_keepalive | ( | const void * | data | ) | [static] |
Definition at line 4327 of file chan_sip.c.
References send_provisional_keepalive_full().
Referenced by update_provisional_keepalive().
04327 { 04328 struct sip_pvt *pvt = (struct sip_pvt *) data; 04329 04330 return send_provisional_keepalive_full(pvt, 0); 04331 }
| static int send_provisional_keepalive_full | ( | struct sip_pvt * | pvt, | |
| int | with_sdp | |||
| ) | [static] |
Definition at line 4277 of file chan_sip.c.
References ast_channel_unlock, ast_channel_unref, FALSE, S_OR, sip_pvt_lock_full(), sip_pvt_unlock, transmit_response(), and transmit_response_with_sdp().
Referenced by send_provisional_keepalive(), and send_provisional_keepalive_with_sdp().
04278 { 04279 const char *msg = NULL; 04280 struct ast_channel *chan; 04281 int res = 0; 04282 int old_sched_id = pvt->provisional_keepalive_sched_id; 04283 04284 chan = sip_pvt_lock_full(pvt); 04285 /* Check that nothing has changed while we were waiting for the lock */ 04286 if (old_sched_id != pvt->provisional_keepalive_sched_id) { 04287 /* Keepalive has been cancelled or rescheduled, clean up and leave */ 04288 if (chan) { 04289 ast_channel_unlock(chan); 04290 chan = ast_channel_unref(chan); 04291 } 04292 sip_pvt_unlock(pvt); 04293 dialog_unref(pvt, "dialog ref for provisional keepalive"); 04294 return 0; 04295 } 04296 04297 if (!pvt->last_provisional || !strncasecmp(pvt->last_provisional, "100", 3)) { 04298 msg = "183 Session Progress"; 04299 } 04300 04301 if (pvt->invitestate < INV_COMPLETED) { 04302 if (with_sdp) { 04303 transmit_response_with_sdp(pvt, S_OR(msg, pvt->last_provisional), &pvt->initreq, XMIT_UNRELIABLE, FALSE, FALSE); 04304 } else { 04305 transmit_response(pvt, S_OR(msg, pvt->last_provisional), &pvt->initreq); 04306 } 04307 res = PROVIS_KEEPALIVE_TIMEOUT; 04308 } 04309 04310 if (chan) { 04311 ast_channel_unlock(chan); 04312 chan = ast_channel_unref(chan); 04313 } 04314 04315 if (!res) { 04316 pvt->provisional_keepalive_sched_id = -1; 04317 } 04318 04319 sip_pvt_unlock(pvt); 04320 04321 if (!res) { 04322 dialog_unref(pvt, "dialog ref for provisional keepalive"); 04323 } 04324 return res; 04325 }
| static int send_provisional_keepalive_with_sdp | ( | const void * | data | ) | [static] |
Definition at line 4333 of file chan_sip.c.
References send_provisional_keepalive_full().
Referenced by update_provisional_keepalive().
04333 { 04334 struct sip_pvt *pvt = (void *)data; 04335 04336 return send_provisional_keepalive_full(pvt, 1); 04337 }
| static int send_request | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| enum xmittype | reliable, | |||
| uint32_t | seqno | |||
| ) | [static] |
Definition at line 4418 of file chan_sip.c.
References __sip_reliable_xmit(), __sip_xmit(), add_blank(), append_history, ast_sockaddr_stringify(), ast_str_buffer(), ast_test_flag, ast_verbose, deinit_req(), finalize_content(), get_header(), parse_copy(), sip_debug_test_pvt(), sip_methods, and cfsip_methods::text.
Referenced by transmit_cc_notify(), transmit_info_with_aoc(), transmit_info_with_digit(), transmit_info_with_vidupdate(), transmit_invite(), transmit_message_with_text(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_register(), transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), transmit_state_notify(), and update_connectedline().
04419 { 04420 int res; 04421 04422 /* If we have an outbound proxy, reset peer address 04423 Only do this once. 04424 */ 04425 if (p->outboundproxy) { 04426 p->sa = p->outboundproxy->ip; 04427 } 04428 04429 finalize_content(req); 04430 add_blank(req); 04431 if (sip_debug_test_pvt(p)) { 04432 if (ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT)) { 04433 ast_verbose("%sTransmitting (NAT) to %s:\n%s\n---\n", reliable ? "Reliably " : "", ast_sockaddr_stringify(&p->recv), ast_str_buffer(req->data)); 04434 } else { 04435 ast_verbose("%sTransmitting (no NAT) to %s:\n%s\n---\n", reliable ? "Reliably " : "", ast_sockaddr_stringify(&p->sa), ast_str_buffer(req->data)); 04436 } 04437 } 04438 if (p->do_history) { 04439 struct sip_request tmp = { .rlPart1 = 0, }; 04440 parse_copy(&tmp, req); 04441 append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", ast_str_buffer(tmp.data), get_header(&tmp, "CSeq"), sip_methods[tmp.method].text); 04442 deinit_req(&tmp); 04443 } 04444 res = (reliable) ? 04445 __sip_reliable_xmit(p, seqno, 0, req->data, (reliable == XMIT_CRITICAL), req->method) : 04446 __sip_xmit(p, req->data); 04447 deinit_req(req); 04448 return res; 04449 }
| static int send_response | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| enum xmittype | reliable, | |||
| uint32_t | seqno | |||
| ) | [static] |
Transmit response on SIP request.
Definition at line 4376 of file chan_sip.c.
References __sip_reliable_xmit(), __sip_xmit(), add_blank(), append_history, AST_SCHED_DEL_UNREF, ast_sockaddr_stringify(), ast_str_buffer(), ast_verbose, deinit_req(), finalize_content(), get_header(), parse_copy(), sip_debug_test_pvt(), sip_methods, sip_nat_mode(), sip_real_dst(), and cfsip_methods::text.
Referenced by __transmit_response(), transmit_response_with_allow(), transmit_response_with_auth(), transmit_response_with_date(), transmit_response_with_minexpires(), transmit_response_with_minse(), transmit_response_with_retry_after(), transmit_response_with_sdp(), transmit_response_with_sip_etag(), transmit_response_with_t38_sdp(), transmit_response_with_unsupported(), update_connectedline(), and update_redirecting().
04377 { 04378 int res; 04379 04380 finalize_content(req); 04381 add_blank(req); 04382 if (sip_debug_test_pvt(p)) { 04383 const struct ast_sockaddr *dst = sip_real_dst(p); 04384 04385 ast_verbose("\n<--- %sTransmitting (%s) to %s --->\n%s\n<------------>\n", 04386 reliable ? "Reliably " : "", sip_nat_mode(p), 04387 ast_sockaddr_stringify(dst), 04388 ast_str_buffer(req->data)); 04389 } 04390 if (p->do_history) { 04391 struct sip_request tmp = { .rlPart1 = 0, }; 04392 parse_copy(&tmp, req); 04393 append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", ast_str_buffer(tmp.data), get_header(&tmp, "CSeq"), 04394 (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? REQ_OFFSET_TO_STR(&tmp, rlPart2) : sip_methods[tmp.method].text); 04395 deinit_req(&tmp); 04396 } 04397 04398 /* If we are sending a final response to an INVITE, stop retransmitting provisional responses */ 04399 if (p->initreq.method == SIP_INVITE && reliable == XMIT_CRITICAL) { 04400 AST_SCHED_DEL_UNREF(sched, p->provisional_keepalive_sched_id, dialog_unref(p, "when you delete the provisional_keepalive_sched_id, you should dec the refcount for the stored dialog ptr")); 04401 } 04402 04403 res = (reliable) ? 04404 __sip_reliable_xmit(p, seqno, 1, req->data, (reliable == XMIT_CRITICAL), req->method) : 04405 __sip_xmit(p, req->data); 04406 deinit_req(req); 04407 if (res > 0) { 04408 return 0; 04409 } 04410 return res; 04411 }
| static enum ast_cc_service_type service_string_to_service_type | ( | const char *const | service_string | ) | [static] |
Definition at line 830 of file chan_sip.c.
References AST_CC_CCBS, AST_CC_CCNL, AST_CC_NONE, service, and sip_cc_service_map.
Referenced by sip_get_cc_information().
00831 { 00832 enum ast_cc_service_type service; 00833 for (service = AST_CC_CCBS; service <= AST_CC_CCNL; ++service) { 00834 if (!strcasecmp(service_string, sip_cc_service_map[service].service_string)) { 00835 return service; 00836 } 00837 } 00838 return AST_CC_NONE; 00839 }
| static int set_address_from_contact | ( | struct sip_pvt * | pvt | ) | [static] |
Change the other partys IP address based on given contact.
Definition at line 14449 of file chan_sip.c.
References __set_address_from_contact(), and ast_test_flag.
Referenced by handle_response_invite().
14450 { 14451 if (ast_test_flag(&pvt->flags[0], SIP_NAT_FORCE_RPORT)) { 14452 /* NAT: Don't trust the contact field. Just use what they came to us 14453 with. */ 14454 /*! \todo We need to save the TRANSPORT here too */ 14455 pvt->sa = pvt->recv; 14456 return 0; 14457 } 14458 14459 return __set_address_from_contact(pvt->fullcontact, &pvt->sa, pvt->socket.type == SIP_TRANSPORT_TLS ? 1 : 0); 14460 }
| static void set_destination | ( | struct sip_pvt * | p, | |
| char * | uri | |||
| ) | [static] |
Set destination from SIP URI.
Parse uri to h (host) and port - uri is already just the part inside the <> general form we are expecting is sip[s]:username[:password][;parameter][:port][;...] If there's a port given, turn NAPTR/SRV off. NAPTR might indicate SIPS preference even for SIP: uri's
If there's a sips: uri scheme, TLS will be required.
Definition at line 10423 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_sockaddr_port, ast_sockaddr_resolve_first_transport(), ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_verbose, FALSE, hostname, LOG_WARNING, PARSE_PORT_FORBID, sip_debug_test_pvt(), and TRUE.
Referenced by reqprep().
10424 { 10425 char *h, *maddr, hostname[256]; 10426 int hn; 10427 int debug=sip_debug_test_pvt(p); 10428 int tls_on = FALSE; 10429 10430 if (debug) 10431 ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri); 10432 10433 /* Find and parse hostname */ 10434 h = strchr(uri, '@'); 10435 if (h) 10436 ++h; 10437 else { 10438 h = uri; 10439 if (!strncasecmp(h, "sip:", 4)) { 10440 h += 4; 10441 } else if (!strncasecmp(h, "sips:", 5)) { 10442 h += 5; 10443 tls_on = TRUE; 10444 } 10445 } 10446 hn = strcspn(h, ";>") + 1; 10447 if (hn > sizeof(hostname)) 10448 hn = sizeof(hostname); 10449 ast_copy_string(hostname, h, hn); 10450 /* XXX bug here if string has been trimmed to sizeof(hostname) */ 10451 h += hn - 1; 10452 10453 /*! \todo XXX If we have sip_cfg.srvlookup on, then look for NAPTR/SRV, 10454 * otherwise, just look for A records */ 10455 if (ast_sockaddr_resolve_first_transport(&p->sa, hostname, 0, p->socket.type)) { 10456 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 10457 return; 10458 } 10459 10460 /* Got the hostname - but maybe there's a "maddr=" to override address? */ 10461 maddr = strstr(h, "maddr="); 10462 if (maddr) { 10463 int port; 10464 10465 maddr += 6; 10466 hn = strspn(maddr, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 10467 "0123456789-.:[]") + 1; 10468 if (hn > sizeof(hostname)) 10469 hn = sizeof(hostname); 10470 ast_copy_string(hostname, maddr, hn); 10471 10472 port = ast_sockaddr_port(&p->sa); 10473 10474 /*! \todo XXX If we have sip_cfg.srvlookup on, then look for 10475 * NAPTR/SRV, otherwise, just look for A records */ 10476 if (ast_sockaddr_resolve_first_transport(&p->sa, hostname, PARSE_PORT_FORBID, p->socket.type)) { 10477 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 10478 return; 10479 } 10480 10481 ast_sockaddr_set_port(&p->sa, port); 10482 } 10483 10484 if (!ast_sockaddr_port(&p->sa)) { 10485 ast_sockaddr_set_port(&p->sa, tls_on ? 10486 STANDARD_TLS_PORT : STANDARD_SIP_PORT); 10487 } 10488 10489 if (debug) { 10490 ast_verbose("set_destination: set destination to %s\n", 10491 ast_sockaddr_stringify(&p->sa)); 10492 } 10493 }
| static void set_insecure_flags | ( | struct ast_flags * | flags, | |
| const char * | value, | |||
| int | lineno | |||
| ) | [static] |
Parse insecure= setting in sip.conf and set flags according to setting.
Definition at line 27513 of file chan_sip.c.
References ast_copy_string(), ast_false(), ast_log(), ast_set_flag, ast_strlen_zero(), LOG_WARNING, and word.
Referenced by get_insecure_variable_from_config(), get_insecure_variable_from_sipregs(), and handle_common_options().
27514 { 27515 if (ast_strlen_zero(value)) 27516 return; 27517 27518 if (!ast_false(value)) { 27519 char buf[64]; 27520 char *word, *next; 27521 27522 ast_copy_string(buf, value, sizeof(buf)); 27523 next = buf; 27524 while ((word = strsep(&next, ","))) { 27525 if (!strcasecmp(word, "port")) 27526 ast_set_flag(&flags[0], SIP_INSECURE_PORT); 27527 else if (!strcasecmp(word, "invite")) 27528 ast_set_flag(&flags[0], SIP_INSECURE_INVITE); 27529 else 27530 ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno); 27531 } 27532 } 27533 }
| static void set_nonce_randdata | ( | struct sip_pvt * | p, | |
| int | forceupdate | |||
| ) | [static] |
builds the sip_pvt's randdata field which is used for the nonce challenge. When forceupdate is not set, the nonce is only updated if the current one is stale. In this case, a stalenonce is one which has already received a response, if a nonce has not received a response it is not always necessary or beneficial to create a new one.
Definition at line 14823 of file chan_sip.c.
References ast_random(), ast_string_field_build, and ast_strlen_zero().
Referenced by check_auth(), and transmit_fake_auth_response().
14824 { 14825 if (p->stalenonce || forceupdate || ast_strlen_zero(p->randdata)) { 14826 ast_string_field_build(p, randdata, "%08lx", (unsigned long)ast_random()); /* Create nonce for challenge */ 14827 p->stalenonce = 0; 14828 } 14829 }
| static void set_peer_defaults | ( | struct sip_peer * | peer | ) | [static] |
Set peer defaults before configuring specific configurations.
Definition at line 27947 of file chan_sip.c.
References ao2_ref, ast_copy_flags, ast_sockaddr_setnull(), ast_string_field_set, cid_name, cid_num, clear_peer_mailboxes(), context, default_prefs, language, mohinterpret, mohsuggest, secret, set_socket_transport(), and sip_cfg.
Referenced by build_peer(), and temp_peer().
27948 { 27949 if (peer->expire == 0) { 27950 /* Don't reset expire or port time during reload 27951 if we have an active registration 27952 */ 27953 peer->expire = -1; 27954 peer->pokeexpire = -1; 27955 set_socket_transport(&peer->socket, SIP_TRANSPORT_UDP); 27956 } 27957 peer->type = SIP_TYPE_PEER; 27958 ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 27959 ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 27960 ast_copy_flags(&peer->flags[2], &global_flags[2], SIP_PAGE3_FLAGS_TO_COPY); 27961 ast_string_field_set(peer, context, sip_cfg.default_context); 27962 ast_string_field_set(peer, subscribecontext, sip_cfg.default_subscribecontext); 27963 ast_string_field_set(peer, language, default_language); 27964 ast_string_field_set(peer, mohinterpret, default_mohinterpret); 27965 ast_string_field_set(peer, mohsuggest, default_mohsuggest); 27966 ast_string_field_set(peer, engine, default_engine); 27967 ast_sockaddr_setnull(&peer->addr); 27968 ast_sockaddr_setnull(&peer->defaddr); 27969 peer->capability = sip_cfg.capability; 27970 peer->maxcallbitrate = default_maxcallbitrate; 27971 peer->rtptimeout = global_rtptimeout; 27972 peer->rtpholdtimeout = global_rtpholdtimeout; 27973 peer->rtpkeepalive = global_rtpkeepalive; 27974 peer->allowtransfer = sip_cfg.allowtransfer; 27975 peer->autoframing = global_autoframing; 27976 peer->t38_maxdatagram = global_t38_maxdatagram; 27977 peer->qualifyfreq = global_qualifyfreq; 27978 if (global_callcounter) 27979 peer->call_limit=INT_MAX; 27980 ast_string_field_set(peer, vmexten, default_vmexten); 27981 ast_string_field_set(peer, secret, ""); 27982 ast_string_field_set(peer, remotesecret, ""); 27983 ast_string_field_set(peer, md5secret, ""); 27984 ast_string_field_set(peer, cid_num, ""); 27985 ast_string_field_set(peer, cid_name, ""); 27986 ast_string_field_set(peer, cid_tag, ""); 27987 ast_string_field_set(peer, fromdomain, ""); 27988 ast_string_field_set(peer, fromuser, ""); 27989 ast_string_field_set(peer, regexten, ""); 27990 peer->callgroup = 0; 27991 peer->pickupgroup = 0; 27992 peer->maxms = default_qualify; 27993 peer->prefs = default_prefs; 27994 peer->stimer.st_mode_oper = global_st_mode; /* Session-Timers */ 27995 peer->stimer.st_ref = global_st_refresher; 27996 peer->stimer.st_min_se = global_min_se; 27997 peer->stimer.st_max_se = global_max_se; 27998 peer->timer_t1 = global_t1; 27999 peer->timer_b = global_timer_b; 28000 clear_peer_mailboxes(peer); 28001 peer->disallowed_methods = sip_cfg.disallowed_methods; 28002 peer->transports = default_transports; 28003 peer->default_outbound_transport = default_primary_transport; 28004 if (peer->outboundproxy) { 28005 ao2_ref(peer->outboundproxy, -1); 28006 peer->outboundproxy = NULL; 28007 } 28008 }
| static unsigned int set_pvt_allowed_methods | ( | struct sip_pvt * | pvt, | |
| struct sip_request * | req | |||
| ) | [static] |
A wrapper for parse_allowed_methods geared toward sip_pvts
This function, in addition to setting the allowed methods for a sip_pvt also will take into account the setting of the SIP_PAGE2_RPID_UPDATE flag.
| pvt | The sip_pvt we are setting the allowed_methods for | |
| req | The request which we are parsing |
| The | methods alloweded by the sip_pvt |
Definition at line 8732 of file chan_sip.c.
References ast_test_flag, mark_method_allowed(), and parse_allowed_methods().
Referenced by check_peer_ok(), handle_request_invite(), handle_request_options(), handle_request_subscribe(), handle_response_invite(), and handle_response_subscribe().
08733 { 08734 pvt->allowed_methods = parse_allowed_methods(req); 08735 08736 if (ast_test_flag(&pvt->flags[1], SIP_PAGE2_RPID_UPDATE)) { 08737 mark_method_allowed(&pvt->allowed_methods, SIP_UPDATE); 08738 } 08739 pvt->allowed_methods &= ~(pvt->disallowed_methods); 08740 08741 return pvt->allowed_methods; 08742 }
| static void set_socket_transport | ( | struct sip_socket * | socket, | |
| int | transport | |||
| ) | [static] |
Definition at line 14202 of file chan_sip.c.
References ao2_ref.
Referenced by __sip_subscribe_mwi_do(), _sip_tcp_helper_thread(), build_peer(), create_addr(), expire_register(), get_transport_pvt(), parse_moved_contact(), parse_register_contact(), set_peer_defaults(), sip_alloc(), sip_request_call(), sip_send_mwi_to_peer(), sipsock_read(), and transmit_register().
14203 { 14204 /* if the transport type changes, clear all socket data */ 14205 if (socket->type != transport) { 14206 socket->fd = -1; 14207 socket->type = transport; 14208 if (socket->tcptls_session) { 14209 ao2_ref(socket->tcptls_session, -1); 14210 socket->tcptls_session = NULL; 14211 } 14212 } 14213 }
| static void set_t38_capabilities | ( | struct sip_pvt * | p | ) | [static] |
Set the global T38 capabilities on a SIP dialog structure.
Definition at line 5386 of file chan_sip.c.
References ast_test_flag, ast_udptl_set_error_correction_scheme(), UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, and UDPTL_ERROR_CORRECTION_REDUNDANCY.
Referenced by check_peer_ok(), and initialize_udptl().
05387 { 05388 if (p->udptl) { 05389 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) == SIP_PAGE2_T38SUPPORT_UDPTL_REDUNDANCY) { 05390 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY); 05391 } else if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) == SIP_PAGE2_T38SUPPORT_UDPTL_FEC) { 05392 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC); 05393 } else if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) == SIP_PAGE2_T38SUPPORT_UDPTL) { 05394 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 05395 } 05396 } 05397 }
| static int setup_srtp | ( | struct sip_srtp ** | srtp | ) | [static] |
Definition at line 30550 of file chan_sip.c.
References ast_log(), ast_rtp_engine_srtp_is_registered(), LOG_ERROR, and sip_srtp_alloc().
Referenced by process_crypto(), and sip_call().
30551 { 30552 if (!ast_rtp_engine_srtp_is_registered()) { 30553 ast_log(LOG_ERROR, "No SRTP module loaded, can't setup SRTP session.\n"); 30554 return -1; 30555 } 30556 30557 if (!(*srtp = sip_srtp_alloc())) { /* Allocate SRTP data structure */ 30558 return -1; 30559 } 30560 30561 return 0; 30562 }
| static int show_channels_cb | ( | void * | __cur, | |
| void * | __arg, | |||
| int | flags | |||
| ) | [static] |
callback for show channel|subscription
Definition at line 18983 of file chan_sip.c.
References ast_cli(), AST_CLI_YESNO, ast_extension_state2str(), ast_getformatname_multiple(), ast_sockaddr_stringify_addr(), ast_str_alloca, ast_str_buffer(), ast_test_flag, FORMAT, FORMAT4, NONE, peer_mailboxes_to_str(), referstatus2str(), S_OR, sip_pvt_lock, sip_pvt_unlock, sip_real_dst(), and subscription_type2str().
Referenced by sip_show_channels().
18984 { 18985 struct sip_pvt *cur = __cur; 18986 struct __show_chan_arg *arg = __arg; 18987 const struct ast_sockaddr *dst; 18988 18989 sip_pvt_lock(cur); 18990 dst = sip_real_dst(cur); 18991 18992 /* XXX indentation preserved to reduce diff. Will be fixed later */ 18993 if (cur->subscribed == NONE && !arg->subscriptions) { 18994 /* set if SIP transfer in progress */ 18995 const char *referstatus = cur->refer ? referstatus2str(cur->refer->status) : ""; 18996 char formatbuf[SIPBUFSIZE/2]; 18997 18998 ast_cli(arg->fd, FORMAT, ast_sockaddr_stringify_addr(dst), 18999 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 19000 cur->callid, 19001 ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0), 19002 AST_CLI_YESNO(ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD)), 19003 cur->needdestroy ? "(d)" : "", 19004 cur->lastmsg , 19005 referstatus, 19006 cur->relatedpeer ? cur->relatedpeer->name : "<guest>" 19007 ); 19008 arg->numchans++; 19009 } 19010 if (cur->subscribed != NONE && arg->subscriptions) { 19011 struct ast_str *mailbox_str = ast_str_alloca(512); 19012 if (cur->subscribed == MWI_NOTIFICATION && cur->relatedpeer) 19013 peer_mailboxes_to_str(&mailbox_str, cur->relatedpeer); 19014 ast_cli(arg->fd, FORMAT4, ast_sockaddr_stringify_addr(dst), 19015 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 19016 cur->callid, 19017 /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */ 19018 cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri, 19019 cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 19020 subscription_type2str(cur->subscribed), 19021 cur->subscribed == MWI_NOTIFICATION ? S_OR(ast_str_buffer(mailbox_str), "<none>") : "<none>", 19022 cur->expiry 19023 ); 19024 arg->numchans++; 19025 } 19026 sip_pvt_unlock(cur); 19027 return 0; /* don't care, we scan all channels */ 19028 }
| static int show_chanstats_cb | ( | void * | __cur, | |
| void * | __arg, | |||
| int | flags | |||
| ) | [static] |
Callback for show_chanstats.
Definition at line 18585 of file chan_sip.c.
References ast_cli(), ast_log(), ast_rtp_instance_get_stats(), AST_RTP_INSTANCE_STAT_ALL, ast_sockaddr_stringify_addr(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), ast_channel::cdr, invstate2stringtable::desc, FORMAT, invitestate2string, LOG_WARNING, NONE, ast_rtp_instance_stats::rxcount, ast_rtp_instance_stats::rxjitter, ast_rtp_instance_stats::rxploss, sip_pvt_lock, sip_pvt_unlock, ast_cdr::start, ast_rtp_instance_stats::txcount, ast_rtp_instance_stats::txjitter, and ast_rtp_instance_stats::txploss.
Referenced by sip_show_channelstats().
18586 { 18587 #define FORMAT2 "%-15.15s %-11.11s %-8.8s %-10.10s %-10.10s ( %%) %-6.6s %-10.10s %-10.10s ( %%) %-6.6s\n" 18588 #define FORMAT "%-15.15s %-11.11s %-8.8s %-10.10u%-1.1s %-10.10u (%5.2f%%) %-6.4lf %-10.10u%-1.1s %-10.10u (%5.2f%%) %-6.4lf\n" 18589 struct sip_pvt *cur = __cur; 18590 struct ast_rtp_instance_stats stats; 18591 char durbuf[10]; 18592 int duration; 18593 int durh, durm, durs; 18594 struct ast_channel *c; 18595 struct __show_chan_arg *arg = __arg; 18596 int fd = arg->fd; 18597 18598 sip_pvt_lock(cur); 18599 c = cur->owner; 18600 18601 if (cur->subscribed != NONE) { 18602 /* Subscriptions */ 18603 sip_pvt_unlock(cur); 18604 return 0; /* don't care, we scan all channels */ 18605 } 18606 18607 if (!cur->rtp) { 18608 if (sipdebug) { 18609 ast_cli(fd, "%-15.15s %-11.11s (inv state: %s) -- %s\n", 18610 ast_sockaddr_stringify_addr(&cur->sa), cur->callid, 18611 invitestate2string[cur->invitestate].desc, 18612 "-- No RTP active"); 18613 } 18614 sip_pvt_unlock(cur); 18615 return 0; /* don't care, we scan all channels */ 18616 } 18617 18618 if (ast_rtp_instance_get_stats(cur->rtp, &stats, AST_RTP_INSTANCE_STAT_ALL)) { 18619 sip_pvt_unlock(cur); 18620 ast_log(LOG_WARNING, "Could not get RTP stats.\n"); 18621 return 0; 18622 } 18623 18624 if (c && c->cdr && !ast_tvzero(c->cdr->start)) { 18625 duration = (int)(ast_tvdiff_ms(ast_tvnow(), c->cdr->start) / 1000); 18626 durh = duration / 3600; 18627 durm = (duration % 3600) / 60; 18628 durs = duration % 60; 18629 snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs); 18630 } else { 18631 durbuf[0] = '\0'; 18632 } 18633 18634 ast_cli(fd, FORMAT, 18635 ast_sockaddr_stringify_addr(&cur->sa), 18636 cur->callid, 18637 durbuf, 18638 stats.rxcount > (unsigned int) 100000 ? (unsigned int) (stats.rxcount)/(unsigned int) 1000 : stats.rxcount, 18639 stats.rxcount > (unsigned int) 100000 ? "K":" ", 18640 stats.rxploss, 18641 (stats.rxcount + stats.rxploss) > 0 ? (double) stats.rxploss / (stats.rxcount + stats.rxploss) * 100 : 0, 18642 stats.rxjitter, 18643 stats.txcount > (unsigned int) 100000 ? (unsigned int) (stats.txcount)/(unsigned int) 1000 : stats.txcount, 18644 stats.txcount > (unsigned int) 100000 ? "K":" ", 18645 stats.txploss, 18646 stats.txcount > 0 ? (double) stats.txploss / stats.txcount * 100 : 0, 18647 stats.txjitter 18648 ); 18649 arg->numchans++; 18650 sip_pvt_unlock(cur); 18651 18652 return 0; /* don't care, we scan all channels */ 18653 }
| static int sip_addheader | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Add a SIP header to an outbound INVITE.
Definition at line 30337 of file chan_sip.c.
References ast_alloca, ast_channel_lock, ast_channel_unlock, ast_debug, ast_get_encoded_str(), ast_log(), ast_strlen_zero(), FALSE, inbuf(), len(), LOG_WARNING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), and TRUE.
Referenced by load_module().
30338 { 30339 int no = 0; 30340 int ok = FALSE; 30341 char varbuf[30]; 30342 const char *inbuf = data; 30343 char *subbuf; 30344 30345 if (ast_strlen_zero(inbuf)) { 30346 ast_log(LOG_WARNING, "This application requires the argument: Header\n"); 30347 return 0; 30348 } 30349 ast_channel_lock(chan); 30350 30351 /* Check for headers */ 30352 while (!ok && no <= 50) { 30353 no++; 30354 snprintf(varbuf, sizeof(varbuf), "__SIPADDHEADER%.2d", no); 30355 30356 /* Compare without the leading underscores */ 30357 if ((pbx_builtin_getvar_helper(chan, (const char *) varbuf + 2) == (const char *) NULL)) { 30358 ok = TRUE; 30359 } 30360 } 30361 if (ok) { 30362 size_t len = strlen(inbuf); 30363 subbuf = ast_alloca(len + 1); 30364 ast_get_encoded_str(inbuf, subbuf, len + 1); 30365 pbx_builtin_setvar_helper(chan, varbuf, subbuf); 30366 if (sipdebug) { 30367 ast_debug(1, "SIP Header added \"%s\" as %s\n", inbuf, varbuf); 30368 } 30369 } else { 30370 ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n"); 30371 } 30372 ast_channel_unlock(chan); 30373 return 0; 30374 }
| struct sip_pvt* sip_alloc | ( | ast_string_field | callid, | |
| struct ast_sockaddr * | addr, | |||
| int | useglobal_nat, | |||
| const int | intended_method, | |||
| struct sip_request * | req | |||
| ) | [read] |
Allocate sip_pvt structure, set defaults and link in the container. Returns a reference to the object so whoever uses it later must remember to release the reference.
Definition at line 7967 of file chan_sip.c.
References ao2_t_alloc, ao2_t_link, ao2_t_ref, ast_cc_config_params_init, ast_copy_flags, ast_debug, AST_LIST_HEAD_INIT_NOLOCK, ast_random(), AST_RTP_DTMF, ast_sip_ouraddrfor(), ast_sockaddr_copy(), ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag, build_callid_pvt(), build_via(), context, default_prefs, do_setnat(), free_via(), get_header(), internip, make_our_tag(), mohinterpret, mohsuggest, NONE, parkinglot, parse_via(), set_socket_transport(), sip_cfg, sip_destroy_fn(), sip_methods, cfsip_methods::text, and TRUE.
Referenced by __sip_subscribe_mwi_do(), find_call(), manager_sipnotify(), sip_cc_monitor_request_cc(), sip_cli_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_publish(), and transmit_register().
07969 { 07970 struct sip_pvt *p; 07971 07972 if (!(p = ao2_t_alloc(sizeof(*p), sip_destroy_fn, "allocate a dialog(pvt) struct"))) 07973 return NULL; 07974 07975 if (ast_string_field_init(p, 512)) { 07976 ao2_t_ref(p, -1, "failed to string_field_init, drop p"); 07977 return NULL; 07978 } 07979 07980 if (!(p->cc_params = ast_cc_config_params_init())) { 07981 ao2_t_ref(p, -1, "Yuck, couldn't allocate cc_params struct. Get rid o' p"); 07982 return NULL; 07983 } 07984 07985 /* If this dialog is created as the result of an incoming Request. Lets store 07986 * some information about that request */ 07987 if (req) { 07988 struct sip_via *via; 07989 const char *cseq = get_header(req, "Cseq"); 07990 uint32_t seqno; 07991 07992 /* get branch parameter from initial Request that started this dialog */ 07993 via = parse_via(get_header(req, "Via")); 07994 if (via) { 07995 /* only store the branch if it begins with the magic prefix "z9hG4bK", otherwise 07996 * it is not useful to us to have it */ 07997 if (!ast_strlen_zero(via->branch) && !strncasecmp(via->branch, "z9hG4bK", 7)) { 07998 ast_string_field_set(p, initviabranch, via->branch); 07999 ast_string_field_set(p, initviasentby, via->sent_by); 08000 } 08001 free_via(via); 08002 } 08003 08004 /* Store initial incoming cseq. An error in sscanf here is ignored. There is no approperiate 08005 * except not storing the number. CSeq validation must take place before dialog creation in find_call */ 08006 if (!ast_strlen_zero(cseq) && (sscanf(cseq, "%30u", &seqno) == 1)) { 08007 p->init_icseq = seqno; 08008 } 08009 /* Later in ast_sip_ouraddrfor we need this to choose the right ip and port for the specific transport */ 08010 set_socket_transport(&p->socket, req->socket.type); 08011 } else { 08012 set_socket_transport(&p->socket, SIP_TRANSPORT_UDP); 08013 } 08014 08015 p->socket.fd = -1; 08016 p->method = intended_method; 08017 p->initid = -1; 08018 p->waitid = -1; 08019 p->reinviteid = -1; 08020 p->autokillid = -1; 08021 p->request_queue_sched_id = -1; 08022 p->provisional_keepalive_sched_id = -1; 08023 p->t38id = -1; 08024 p->subscribed = NONE; 08025 p->stateid = -1; 08026 p->sessionversion_remote = -1; 08027 p->session_modify = TRUE; 08028 p->stimer = NULL; 08029 p->prefs = default_prefs; /* Set default codecs for this call */ 08030 p->maxforwards = sip_cfg.default_max_forwards; 08031 08032 if (intended_method != SIP_OPTIONS) { /* Peerpoke has it's own system */ 08033 p->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */ 08034 p->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */ 08035 } 08036 08037 if (!addr) { 08038 p->ourip = internip; 08039 } else { 08040 ast_sockaddr_copy(&p->sa, addr); 08041 ast_sip_ouraddrfor(&p->sa, &p->ourip, p); 08042 } 08043 08044 /* Copy global flags to this PVT at setup. */ 08045 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 08046 ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 08047 ast_copy_flags(&p->flags[2], &global_flags[2], SIP_PAGE3_FLAGS_TO_COPY); 08048 08049 p->do_history = recordhistory; 08050 08051 p->branch = ast_random(); 08052 make_our_tag(p); 08053 p->ocseq = INITIAL_CSEQ; 08054 p->allowed_methods = UINT_MAX; 08055 08056 if (sip_methods[intended_method].need_rtp) { 08057 p->maxcallbitrate = default_maxcallbitrate; 08058 p->autoframing = global_autoframing; 08059 } 08060 08061 if (useglobal_nat && addr) { 08062 /* Setup NAT structure according to global settings if we have an address */ 08063 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT_FORCE_RPORT); 08064 ast_sockaddr_copy(&p->recv, addr); 08065 08066 do_setnat(p); 08067 } 08068 08069 if (p->method != SIP_REGISTER) { 08070 ast_string_field_set(p, fromdomain, default_fromdomain); 08071 p->fromdomainport = default_fromdomainport; 08072 } 08073 build_via(p); 08074 if (!callid) 08075 build_callid_pvt(p); 08076 else 08077 ast_string_field_set(p, callid, callid); 08078 /* Assign default music on hold class */ 08079 ast_string_field_set(p, mohinterpret, default_mohinterpret); 08080 ast_string_field_set(p, mohsuggest, default_mohsuggest); 08081 p->capability = sip_cfg.capability; 08082 p->allowtransfer = sip_cfg.allowtransfer; 08083 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 08084 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) { 08085 p->noncodeccapability |= AST_RTP_DTMF; 08086 } 08087 ast_string_field_set(p, context, sip_cfg.default_context); 08088 ast_string_field_set(p, parkinglot, default_parkinglot); 08089 ast_string_field_set(p, engine, default_engine); 08090 08091 AST_LIST_HEAD_INIT_NOLOCK(&p->request_queue); 08092 08093 /* Add to active dialog list */ 08094 08095 ao2_t_link(dialogs, p, "link pvt into dialogs table"); 08096 08097 ast_debug(1, "Allocating new SIP dialog for %s - %s (%s)\n", callid ? callid : p->callid, sip_methods[intended_method].text, p->rtp ? "With RTP" : "No RTP"); 08098 return p; 08099 }
| static void sip_alreadygone | ( | struct sip_pvt * | dialog | ) | [static] |
Encapsulate setting of SIP_ALREADYGONE to be able to trace it with debugging.
Definition at line 3213 of file chan_sip.c.
References ast_debug.
Referenced by handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), handle_response_publish(), handle_response_subscribe(), retrans_pkt(), sip_indicate(), and sip_sipredirect().
03214 { 03215 ast_debug(3, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid); 03216 dialog->alreadygone = 1; 03217 }
| static int sip_answer | ( | struct ast_channel * | ast | ) | [static] |
sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface
Definition at line 6729 of file chan_sip.c.
References ast_channel::_state, ast_debug, ast_rtp_instance_update_source(), ast_set_flag, ast_setstate(), AST_STATE_UP, ast_test_flag, FALSE, sip_pvt_lock, sip_pvt_unlock, start_session_timer(), ast_channel::tech_pvt, transmit_response_with_sdp(), TRUE, and try_suggested_sip_codec().
06730 { 06731 int res = 0; 06732 struct sip_pvt *p = ast->tech_pvt; 06733 int oldsdp = FALSE; 06734 06735 if (!p) { 06736 ast_debug(1, "Asked to answer channel %s without tech pvt; ignoring\n", 06737 ast->name); 06738 return res; 06739 } 06740 sip_pvt_lock(p); 06741 if (ast->_state != AST_STATE_UP) { 06742 try_suggested_sip_codec(p); 06743 06744 if (ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT)) { 06745 oldsdp = TRUE; 06746 } 06747 06748 ast_setstate(ast, AST_STATE_UP); 06749 ast_debug(1, "SIP answering channel: %s\n", ast->name); 06750 ast_rtp_instance_update_source(p->rtp); 06751 res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL, oldsdp, TRUE); 06752 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 06753 /* RFC says the session timer starts counting on 200, 06754 * not on INVITE. */ 06755 if (p->stimer->st_active == TRUE) { 06756 start_session_timer(p); 06757 } 06758 } 06759 sip_pvt_unlock(p); 06760 return res; 06761 }
| static int sip_call | ( | struct ast_channel * | ast, | |
| char * | dest, | |||
| int | timeout | |||
| ) | [static] |
Initiate SIP call from PBX used from the dial() application.
Definition at line 5759 of file chan_sip.c.
References ast_channel::_state, ao2_t_ref, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_USER_BUSY, ast_cc_get_monitor_by_recall_core_id(), ast_cc_is_recall(), ast_channel_get_device_name(), AST_CHANNEL_NAME, ast_channel_queue_connected_line_update(), ast_clear_flag, AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER, ast_copy_string(), ast_debug, AST_FORMAT_AUDIO_MASK, AST_LIST_TRAVERSE, ast_log(), ast_party_connected_line_init(), ast_party_id_presentation(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, ast_rtp_instance_available_formats(), AST_SCHED_REPLACE_UNREF, ast_set_flag, AST_STATE_DOWN, AST_STATE_RESERVED, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_var_name(), ast_var_value(), auto_congest(), ast_channel::caller, cid_name, connected, ast_channel::hangupcause, ast_party_connected_line::id, ast_set_party_connected_line::id, ast_party_caller::id, LOG_WARNING, ast_party_id::name, ast_set_party_id::name, ast_party_id::number, ast_set_party_id::number, ast_party_name::presentation, ast_party_number::presentation, ast_cc_monitor::private_data, setup_srtp(), sip_pvt_lock, sip_pvt_unlock, ast_party_connected_line::source, ast_party_name::str, ast_party_number::str, ast_party_id::tag, ast_channel::tech_pvt, transmit_invite(), update_call_counter(), ast_party_name::valid, ast_party_number::valid, and ast_channel::varshead.
05760 { 05761 int res; 05762 struct sip_pvt *p = ast->tech_pvt; /* chan is locked, so the reference cannot go away */ 05763 struct varshead *headp; 05764 struct ast_var_t *current; 05765 const char *referer = NULL; /* SIP referrer */ 05766 int cc_core_id; 05767 char uri[SIPBUFSIZE] = ""; 05768 05769 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 05770 ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name); 05771 return -1; 05772 } 05773 05774 if (ast_cc_is_recall(ast, &cc_core_id, "SIP")) { 05775 char device_name[AST_CHANNEL_NAME]; 05776 struct ast_cc_monitor *recall_monitor; 05777 struct sip_monitor_instance *monitor_instance; 05778 ast_channel_get_device_name(ast, device_name, sizeof(device_name)); 05779 if ((recall_monitor = ast_cc_get_monitor_by_recall_core_id(cc_core_id, device_name))) { 05780 monitor_instance = recall_monitor->private_data; 05781 ast_copy_string(uri, monitor_instance->notify_uri, sizeof(uri)); 05782 ao2_t_ref(recall_monitor, -1, "Got the URI we need so unreffing monitor"); 05783 } 05784 } 05785 05786 /* Check whether there is vxml_url, distinctive ring variables */ 05787 headp=&ast->varshead; 05788 AST_LIST_TRAVERSE(headp, current, entries) { 05789 /* Check whether there is a VXML_URL variable */ 05790 if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) { 05791 p->options->vxml_url = ast_var_value(current); 05792 } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) { 05793 p->options->uri_options = ast_var_value(current); 05794 } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 05795 /* Check whether there is a variable with a name starting with SIPADDHEADER */ 05796 p->options->addsipheaders = 1; 05797 } else if (!strcasecmp(ast_var_name(current), "SIPFROMDOMAIN")) { 05798 ast_string_field_set(p, fromdomain, ast_var_value(current)); 05799 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) { 05800 /* This is a transferred call */ 05801 p->options->transfer = 1; 05802 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) { 05803 /* This is the referrer */ 05804 referer = ast_var_value(current); 05805 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) { 05806 /* We're replacing a call. */ 05807 p->options->replaces = ast_var_value(current); 05808 } else if (!strcasecmp(ast_var_name(current), "SIP_MAX_FORWARDS")) { 05809 if (sscanf(ast_var_value(current), "%d", &(p->maxforwards)) != 1) { 05810 ast_log(LOG_WARNING, "The SIP_MAX_FORWARDS channel variable is not a valid integer.\n"); 05811 } 05812 } 05813 } 05814 05815 /* Check to see if we should try to force encryption */ 05816 if (p->req_secure_signaling && p->socket.type != SIP_TRANSPORT_TLS) { 05817 ast_log(LOG_WARNING, "Encrypted signaling is required\n"); 05818 ast->hangupcause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 05819 return -1; 05820 } 05821 05822 if (ast_test_flag(&p->flags[1], SIP_PAGE2_USE_SRTP)) { 05823 if (ast_test_flag(&p->flags[0], SIP_REINVITE)) { 05824 ast_debug(1, "Direct media not possible when using SRTP, ignoring canreinvite setting\n"); 05825 ast_clear_flag(&p->flags[0], SIP_REINVITE); 05826 } 05827 05828 if (p->rtp && !p->srtp && setup_srtp(&p->srtp) < 0) { 05829 ast_log(LOG_WARNING, "SRTP audio setup failed\n"); 05830 return -1; 05831 } 05832 05833 if (p->vrtp && !p->vsrtp && setup_srtp(&p->vsrtp) < 0) { 05834 ast_log(LOG_WARNING, "SRTP video setup failed\n"); 05835 return -1; 05836 } 05837 05838 if (p->trtp && !p->tsrtp && setup_srtp(&p->tsrtp) < 0) { 05839 ast_log(LOG_WARNING, "SRTP text setup failed\n"); 05840 return -1; 05841 } 05842 } 05843 05844 res = 0; 05845 ast_set_flag(&p->flags[0], SIP_OUTGOING); 05846 05847 /* T.38 re-INVITE FAX detection should never be done for outgoing calls, 05848 * so ensure it is disabled. 05849 */ 05850 ast_clear_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_T38); 05851 05852 if (p->options->transfer) { 05853 char buf[SIPBUFSIZE/2]; 05854 05855 if (referer) { 05856 if (sipdebug) 05857 ast_debug(3, "Call for %s transferred by %s\n", p->username, referer); 05858 snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer); 05859 } else 05860 snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name); 05861 ast_string_field_set(p, cid_name, buf); 05862 } 05863 ast_debug(1, "Outgoing Call for %s\n", p->username); 05864 05865 res = update_call_counter(p, INC_CALL_RINGING); 05866 05867 if (res == -1) { 05868 ast->hangupcause = AST_CAUSE_USER_BUSY; 05869 return res; 05870 } 05871 p->callingpres = ast_party_id_presentation(&ast->caller.id); 05872 p->jointcapability = ast_rtp_instance_available_formats(p->rtp, p->capability, p->prefcodec); 05873 p->jointnoncodeccapability = p->noncodeccapability; 05874 05875 /* If there are no audio formats left to offer, punt */ 05876 if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 05877 ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username); 05878 res = -1; 05879 } else { 05880 int xmitres; 05881 struct ast_party_connected_line connected; 05882 struct ast_set_party_connected_line update_connected; 05883 05884 sip_pvt_lock(p); 05885 05886 /* Supply initial connected line information if available. */ 05887 memset(&update_connected, 0, sizeof(update_connected)); 05888 ast_party_connected_line_init(&connected); 05889 if (!ast_strlen_zero(p->cid_num) 05890 || (p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) { 05891 update_connected.id.number = 1; 05892 connected.id.number.valid = 1; 05893 connected.id.number.str = (char *) p->cid_num; 05894 connected.id.number.presentation = p->callingpres; 05895 } 05896 if (!ast_strlen_zero(p->cid_name) 05897 || (p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) { 05898 update_connected.id.name = 1; 05899 connected.id.name.valid = 1; 05900 connected.id.name.str = (char *) p->cid_name; 05901 connected.id.name.presentation = p->callingpres; 05902 } 05903 if (update_connected.id.number || update_connected.id.name) { 05904 connected.id.tag = (char *) p->cid_tag; 05905 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; 05906 ast_channel_queue_connected_line_update(ast, &connected, &update_connected); 05907 } 05908 05909 xmitres = transmit_invite(p, SIP_INVITE, 1, 2, uri); 05910 if (xmitres == XMIT_ERROR) { 05911 sip_pvt_unlock(p); 05912 return -1; 05913 } 05914 p->invitestate = INV_CALLING; 05915 05916 /* Initialize auto-congest time */ 05917 AST_SCHED_REPLACE_UNREF(p->initid, sched, p->timer_b, auto_congest, p, 05918 dialog_unref(_data, "dialog ptr dec when SCHED_REPLACE del op succeeded"), 05919 dialog_unref(p, "dialog ptr dec when SCHED_REPLACE add failed"), 05920 dialog_ref(p, "dialog ptr inc when SCHED_REPLACE add succeeded") ); 05921 sip_pvt_unlock(p); 05922 } 05923 return res; 05924 }
| int sip_cancel_destroy | ( | struct sip_pvt * | p | ) |
Cancel destruction of SIP dialog. Be careful as this also absorbs the reference - if you call it from within the scheduler, this might be the last reference.
Definition at line 4139 of file chan_sip.c.
References append_history, and AST_SCHED_DEL_UNREF.
Referenced by handle_request_invite(), handle_request_subscribe(), handle_response(), handle_response_invite(), register_verify(), sip_hangup(), and sip_scheddestroy().
04140 { 04141 if (p->final_destruction_scheduled) { 04142 return 0; 04143 } 04144 04145 if (p->autokillid > -1) { 04146 append_history(p, "CancelDestroy", ""); 04147 AST_SCHED_DEL_UNREF(sched, p->autokillid, dialog_unref(p, "remove ref for autokillid")); 04148 } 04149 return 0; 04150 }
| static void sip_cc_agent_destructor | ( | struct ast_cc_agent * | agent | ) | [static] |
Definition at line 1812 of file chan_sip.c.
References ast_free, ast_test_flag, ast_cc_agent::private_data, sip_cc_agent_stop_offer_timer(), sip_pvt_lock, sip_pvt_unlock, and transmit_response().
01813 { 01814 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01815 01816 if (!agent_pvt) { 01817 /* The agent constructor probably failed. */ 01818 return; 01819 } 01820 01821 sip_cc_agent_stop_offer_timer(agent); 01822 if (agent_pvt->subscribe_pvt) { 01823 sip_pvt_lock(agent_pvt->subscribe_pvt); 01824 if (!ast_test_flag(&agent_pvt->subscribe_pvt->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) { 01825 /* If we haven't sent a 200 OK for the SUBSCRIBE dialog yet, then we need to send a response letting 01826 * the subscriber know something went wrong 01827 */ 01828 transmit_response(agent_pvt->subscribe_pvt, "500 Internal Server Error", &agent_pvt->subscribe_pvt->initreq); 01829 } 01830 sip_pvt_unlock(agent_pvt->subscribe_pvt); 01831 agent_pvt->subscribe_pvt = dialog_unref(agent_pvt->subscribe_pvt, "SIP CC agent destructor: Remove ref to subscription"); 01832 } 01833 ast_free(agent_pvt); 01834 }
| static int sip_cc_agent_init | ( | struct ast_cc_agent * | agent, | |
| struct ast_channel * | chan | |||
| ) | [static] |
Definition at line 1699 of file chan_sip.c.
References ast_assert, ast_calloc, ast_copy_string(), ast_set_flag, ast_cc_agent::private_data, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech, ast_channel::tech_pvt, and ast_channel_tech::type.
01700 { 01701 struct sip_cc_agent_pvt *agent_pvt = ast_calloc(1, sizeof(*agent_pvt)); 01702 struct sip_pvt *call_pvt = chan->tech_pvt; 01703 01704 if (!agent_pvt) { 01705 return -1; 01706 } 01707 01708 ast_assert(!strcmp(chan->tech->type, "SIP")); 01709 01710 ast_copy_string(agent_pvt->original_callid, call_pvt->callid, sizeof(agent_pvt->original_callid)); 01711 ast_copy_string(agent_pvt->original_exten, call_pvt->exten, sizeof(agent_pvt->original_exten)); 01712 agent_pvt->offer_timer_id = -1; 01713 agent->private_data = agent_pvt; 01714 sip_pvt_lock(call_pvt); 01715 ast_set_flag(&call_pvt->flags[0], SIP_OFFER_CC); 01716 sip_pvt_unlock(call_pvt); 01717 return 0; 01718 }
| static int sip_cc_agent_recall | ( | struct ast_cc_agent * | agent | ) | [static] |
Definition at line 1792 of file chan_sip.c.
References ast_cc_agent_caller_busy(), ast_cc_agent::core_id, ast_cc_agent::device_name, ast_cc_agent::private_data, sip_pvt_lock, sip_pvt_unlock, and transmit_cc_notify().
01793 { 01794 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01795 /* If we have received a PUBLISH beforehand stating that the caller in question 01796 * is not available, we can save ourself a bit of effort here and just report 01797 * the caller as busy 01798 */ 01799 if (!agent_pvt->is_available) { 01800 return ast_cc_agent_caller_busy(agent->core_id, "Caller %s is busy, reporting to the core", 01801 agent->device_name); 01802 } 01803 /* Otherwise, we transmit a NOTIFY to the caller and await either 01804 * a PUBLISH or an INVITE 01805 */ 01806 sip_pvt_lock(agent_pvt->subscribe_pvt); 01807 transmit_cc_notify(agent, agent_pvt->subscribe_pvt, CC_READY); 01808 sip_pvt_unlock(agent_pvt->subscribe_pvt); 01809 return 0; 01810 }
| static void sip_cc_agent_respond | ( | struct ast_cc_agent * | agent, | |
| enum ast_cc_agent_response_reason | reason | |||
| ) | [static] |
Definition at line 1748 of file chan_sip.c.
References AST_CC_AGENT_RESPONSE_SUCCESS, ast_set_flag, ast_strlen_zero(), ast_cc_agent::private_data, sip_pvt_lock, sip_pvt_unlock, transmit_cc_notify(), transmit_response(), and TRUE.
01749 { 01750 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01751 01752 sip_pvt_lock(agent_pvt->subscribe_pvt); 01753 ast_set_flag(&agent_pvt->subscribe_pvt->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 01754 if (reason == AST_CC_AGENT_RESPONSE_SUCCESS || !ast_strlen_zero(agent_pvt->notify_uri)) { 01755 /* The second half of this if statement may be a bit hard to grasp, 01756 * so here's an explanation. When a subscription comes into 01757 * chan_sip, as long as it is not malformed, it will be passed 01758 * to the CC core. If the core senses an out-of-order state transition, 01759 * then the core will call this callback with the "reason" set to a 01760 * failure condition. 01761 * However, an out-of-order state transition will occur during a resubscription 01762 * for CC. In such a case, we can see that we have already generated a notify_uri 01763 * and so we can detect that this isn't a *real* failure. Rather, it is just 01764 * something the core doesn't recognize as a legitimate SIP state transition. 01765 * Thus we respond with happiness and flowers. 01766 */ 01767 transmit_response(agent_pvt->subscribe_pvt, "200 OK", &agent_pvt->subscribe_pvt->initreq); 01768 transmit_cc_notify(agent, agent_pvt->subscribe_pvt, CC_QUEUED); 01769 } else { 01770 transmit_response(agent_pvt->subscribe_pvt, "500 Internal Error", &agent_pvt->subscribe_pvt->initreq); 01771 } 01772 sip_pvt_unlock(agent_pvt->subscribe_pvt); 01773 agent_pvt->is_available = TRUE; 01774 }
| static int sip_cc_agent_start_monitoring | ( | struct ast_cc_agent * | agent | ) | [static] |
Definition at line 1783 of file chan_sip.c.
| static int sip_cc_agent_start_offer_timer | ( | struct ast_cc_agent * | agent | ) | [static] |
Definition at line 1730 of file chan_sip.c.
References ast_get_cc_offer_timer(), ast_sched_add(), ast_cc_agent::cc_params, ast_cc_agent::private_data, and sip_offer_timer_expire().
01731 { 01732 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01733 int when; 01734 01735 when = ast_get_cc_offer_timer(agent->cc_params) * 1000; 01736 agent_pvt->offer_timer_id = ast_sched_add(sched, when, sip_offer_timer_expire, agent); 01737 return 0; 01738 }
| static int sip_cc_agent_status_request | ( | struct ast_cc_agent * | agent | ) | [static] |
Definition at line 1776 of file chan_sip.c.
References ast_cc_agent_status_response(), AST_DEVICE_INUSE, AST_DEVICE_NOT_INUSE, ast_cc_agent::core_id, and ast_cc_agent::private_data.
01777 { 01778 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01779 enum ast_device_state state = agent_pvt->is_available ? AST_DEVICE_NOT_INUSE : AST_DEVICE_INUSE; 01780 return ast_cc_agent_status_response(agent->core_id, state); 01781 }
| static int sip_cc_agent_stop_offer_timer | ( | struct ast_cc_agent * | agent | ) | [static] |
Definition at line 1740 of file chan_sip.c.
References AST_SCHED_DEL, and ast_cc_agent::private_data.
Referenced by sip_cc_agent_destructor().
01741 { 01742 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01743 01744 AST_SCHED_DEL(sched, agent_pvt->offer_timer_id); 01745 return 0; 01746 }
| static int sip_cc_monitor_cancel_available_timer | ( | struct ast_cc_monitor * | monitor, | |
| int * | sched_id | |||
| ) | [static] |
Definition at line 2051 of file chan_sip.c.
References ao2_t_ref, and AST_SCHED_DEL.
02052 { 02053 if (*sched_id != -1) { 02054 AST_SCHED_DEL(sched, *sched_id); 02055 ao2_t_ref(monitor, -1, "Removing scheduler's reference to the monitor"); 02056 } 02057 return 0; 02058 }
| static void sip_cc_monitor_destructor | ( | void * | private_data | ) | [static] |
Definition at line 2060 of file chan_sip.c.
References ao2_unlink, and ast_module_unref().
02061 { 02062 struct sip_monitor_instance *monitor_instance = private_data; 02063 ao2_unlink(sip_monitor_instances, monitor_instance); 02064 ast_module_unref(ast_module_info->self); 02065 }
| static int sip_cc_monitor_request_cc | ( | struct ast_cc_monitor * | monitor, | |
| int * | available_timer_id | |||
| ) | [static] |
Definition at line 1918 of file chan_sip.c.
References ao2_t_ref, ast_cc_available_timer_expire(), AST_CC_CCBS, ast_get_ccbs_available_timer(), ast_get_ccnr_available_timer(), ast_sched_add(), ast_set_flag, ast_sip_ouraddrfor(), ast_cc_interface::config_params, create_addr(), FALSE, ast_cc_monitor::interface, ast_cc_monitor::private_data, service, ast_cc_monitor::service_offered, sip_alloc(), sip_pvt_lock, sip_pvt_unlock, and transmit_invite().
01919 { 01920 struct sip_monitor_instance *monitor_instance = monitor->private_data; 01921 enum ast_cc_service_type service = monitor->service_offered; 01922 int when; 01923 01924 if (!monitor_instance) { 01925 return -1; 01926 } 01927 01928 if (!(monitor_instance->subscription_pvt = sip_alloc(NULL, NULL, 0, SIP_SUBSCRIBE, NULL))) { 01929 return -1; 01930 } 01931 01932 when = service == AST_CC_CCBS ? ast_get_ccbs_available_timer(monitor->interface->config_params) : 01933 ast_get_ccnr_available_timer(monitor->interface->config_params); 01934 01935 sip_pvt_lock(monitor_instance->subscription_pvt); 01936 ast_set_flag(&monitor_instance->subscription_pvt->flags[0], SIP_OUTGOING); 01937 create_addr(monitor_instance->subscription_pvt, monitor_instance->peername, 0, 1); 01938 ast_sip_ouraddrfor(&monitor_instance->subscription_pvt->sa, &monitor_instance->subscription_pvt->ourip, monitor_instance->subscription_pvt); 01939 monitor_instance->subscription_pvt->subscribed = CALL_COMPLETION; 01940 monitor_instance->subscription_pvt->expiry = when; 01941 01942 transmit_invite(monitor_instance->subscription_pvt, SIP_SUBSCRIBE, FALSE, 2, monitor_instance->subscribe_uri); 01943 sip_pvt_unlock(monitor_instance->subscription_pvt); 01944 01945 ao2_t_ref(monitor, +1, "Adding a ref to the monitor for the scheduler"); 01946 *available_timer_id = ast_sched_add(sched, when * 1000, ast_cc_available_timer_expire, monitor); 01947 return 0; 01948 }
| static int sip_cc_monitor_suspend | ( | struct ast_cc_monitor * | monitor | ) | [static] |
Definition at line 1976 of file chan_sip.c.
References ao2_ref, ast_calloc, ast_log(), ast_strlen_zero(), construct_pidf_body(), ast_cc_monitor::core_id, create_epa_entry(), LOG_WARNING, ast_cc_monitor::private_data, and transmit_publish().
01977 { 01978 struct sip_monitor_instance *monitor_instance = monitor->private_data; 01979 enum sip_publish_type publish_type; 01980 struct cc_epa_entry *cc_entry; 01981 01982 if (!monitor_instance) { 01983 return -1; 01984 } 01985 01986 if (!monitor_instance->suspension_entry) { 01987 /* We haven't yet allocated the suspension entry, so let's give it a shot */ 01988 if (!(monitor_instance->suspension_entry = create_epa_entry("call-completion", monitor_instance->peername))) { 01989 ast_log(LOG_WARNING, "Unable to allocate sip EPA entry for call-completion\n"); 01990 ao2_ref(monitor_instance, -1); 01991 return -1; 01992 } 01993 if (!(cc_entry = ast_calloc(1, sizeof(*cc_entry)))) { 01994 ast_log(LOG_WARNING, "Unable to allocate space for instance data of EPA entry for call-completion\n"); 01995 ao2_ref(monitor_instance, -1); 01996 return -1; 01997 } 01998 cc_entry->core_id = monitor->core_id; 01999 monitor_instance->suspension_entry->instance_data = cc_entry; 02000 publish_type = SIP_PUBLISH_INITIAL; 02001 } else { 02002 publish_type = SIP_PUBLISH_MODIFY; 02003 cc_entry = monitor_instance->suspension_entry->instance_data; 02004 } 02005 02006 cc_entry->current_state = CC_CLOSED; 02007 02008 if (ast_strlen_zero(monitor_instance->notify_uri)) { 02009 /* If we have no set notify_uri, then what this means is that we have 02010 * not received a NOTIFY from this destination stating that he is 02011 * currently available. 02012 * 02013 * This situation can arise when the core calls the suspend callbacks 02014 * of multiple destinations. If one of the other destinations aside 02015 * from this one notified Asterisk that he is available, then there 02016 * is no reason to take any suspension action on this device. Rather, 02017 * we should return now and if we receive a NOTIFY while monitoring 02018 * is still "suspended" then we can immediately respond with the 02019 * proper PUBLISH to let this endpoint know what is going on. 02020 */ 02021 return 0; 02022 } 02023 construct_pidf_body(CC_CLOSED, monitor_instance->suspension_entry->body, sizeof(monitor_instance->suspension_entry->body), monitor_instance->peername); 02024 return transmit_publish(monitor_instance->suspension_entry, publish_type, monitor_instance->notify_uri); 02025 }
| static int sip_cc_monitor_unsuspend | ( | struct ast_cc_monitor * | monitor | ) | [static] |
Definition at line 2027 of file chan_sip.c.
References ast_assert, ast_strlen_zero(), construct_pidf_body(), ast_cc_monitor::private_data, and transmit_publish().
02028 { 02029 struct sip_monitor_instance *monitor_instance = monitor->private_data; 02030 struct cc_epa_entry *cc_entry; 02031 02032 if (!monitor_instance) { 02033 return -1; 02034 } 02035 02036 ast_assert(monitor_instance->suspension_entry != NULL); 02037 02038 cc_entry = monitor_instance->suspension_entry->instance_data; 02039 cc_entry->current_state = CC_OPEN; 02040 if (ast_strlen_zero(monitor_instance->notify_uri)) { 02041 /* This means we are being asked to unsuspend a call leg we never 02042 * sent a PUBLISH on. As such, there is no reason to send another 02043 * PUBLISH at this point either. We can just return instead. 02044 */ 02045 return 0; 02046 } 02047 construct_pidf_body(CC_OPEN, monitor_instance->suspension_entry->body, sizeof(monitor_instance->suspension_entry->body), monitor_instance->peername); 02048 return transmit_publish(monitor_instance->suspension_entry, SIP_PUBLISH_MODIFY, monitor_instance->notify_uri); 02049 }
| static int sip_check_authtimeout | ( | time_t | start | ) | [static] |
Check if the authtimeout has expired.
| start | the time when the session started |
| 0 | the timeout has expired | |
| -1 | error |
Definition at line 2483 of file chan_sip.c.
References ast_log(), errno, and LOG_ERROR.
Referenced by _sip_tcp_helper_thread(), and sip_tcptls_read().
02484 { 02485 int timeout; 02486 time_t now; 02487 if(time(&now) == -1) { 02488 ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno)); 02489 return -1; 02490 } 02491 02492 timeout = (authtimeout - (now - start)) * 1000; 02493 if (timeout < 0) { 02494 /* we have timed out */ 02495 return 0; 02496 } 02497 02498 return timeout; 02499 }
| static char * sip_cli_notify | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Cli command to send SIP notify to peer.
Definition at line 19681 of file chan_sip.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_copy_string(), ast_log(), ast_set_flag, ast_sip_ouraddrfor(), ast_str_append(), ast_str_strlen(), ast_unescape_semicolon(), ast_variable_browse(), ast_variable_new(), build_via(), change_callid_pvt(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sipnotify(), create_addr(), dialog_unlink_all(), ast_cli_args::fd, ast_cli_args::line, LOG_WARNING, ast_cli_args::n, ast_variable::name, ast_variable::next, ast_cli_args::pos, sip_alloc(), sip_notify_allocate(), sip_scheddestroy(), transmit_invite(), ast_cli_entry::usage, ast_variable::value, var, and ast_cli_args::word.
19682 { 19683 struct ast_variable *varlist; 19684 int i; 19685 19686 switch (cmd) { 19687 case CLI_INIT: 19688 e->command = "sip notify"; 19689 e->usage = 19690 "Usage: sip notify <type> <peer> [<peer>...]\n" 19691 " Send a NOTIFY message to a SIP peer or peers\n" 19692 " Message types are defined in sip_notify.conf\n"; 19693 return NULL; 19694 case CLI_GENERATE: 19695 return complete_sipnotify(a->line, a->word, a->pos, a->n); 19696 } 19697 19698 if (a->argc < 4) 19699 return CLI_SHOWUSAGE; 19700 19701 if (!notify_types) { 19702 ast_cli(a->fd, "No %s file found, or no types listed there\n", notify_config); 19703 return CLI_FAILURE; 19704 } 19705 19706 varlist = ast_variable_browse(notify_types, a->argv[2]); 19707 19708 if (!varlist) { 19709 ast_cli(a->fd, "Unable to find notify type '%s'\n", a->argv[2]); 19710 return CLI_FAILURE; 19711 } 19712 19713 for (i = 3; i < a->argc; i++) { 19714 struct sip_pvt *p; 19715 char buf[512]; 19716 struct ast_variable *header, *var; 19717 19718 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) { 19719 ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n"); 19720 return CLI_FAILURE; 19721 } 19722 19723 if (create_addr(p, a->argv[i], NULL, 1)) { 19724 /* Maybe they're not registered, etc. */ 19725 dialog_unlink_all(p); 19726 dialog_unref(p, "unref dialog inside for loop" ); 19727 /* sip_destroy(p); */ 19728 ast_cli(a->fd, "Could not create address for '%s'\n", a->argv[i]); 19729 continue; 19730 } 19731 19732 /* Notify is outgoing call */ 19733 ast_set_flag(&p->flags[0], SIP_OUTGOING); 19734 sip_notify_allocate(p); 19735 p->notify->headers = header = ast_variable_new("Subscription-State", "terminated", ""); 19736 19737 for (var = varlist; var; var = var->next) { 19738 ast_copy_string(buf, var->value, sizeof(buf)); 19739 ast_unescape_semicolon(buf); 19740 19741 if (!strcasecmp(var->name, "Content")) { 19742 if (ast_str_strlen(p->notify->content)) 19743 ast_str_append(&p->notify->content, 0, "\r\n"); 19744 ast_str_append(&p->notify->content, 0, "%s", buf); 19745 } else if (!strcasecmp(var->name, "Content-Length")) { 19746 ast_log(LOG_WARNING, "it is not necessary to specify Content-Length in sip_notify.conf, ignoring\n"); 19747 } else { 19748 header->next = ast_variable_new(var->name, buf, ""); 19749 header = header->next; 19750 } 19751 } 19752 19753 /* Now that we have the peer's address, set our ip and change callid */ 19754 ast_sip_ouraddrfor(&p->sa, &p->ourip, p); 19755 build_via(p); 19756 19757 change_callid_pvt(p, NULL); 19758 19759 ast_cli(a->fd, "Sending NOTIFY of type '%s' to '%s'\n", a->argv[2], a->argv[i]); 19760 sip_scheddestroy(p, SIP_TRANS_TIMEOUT); 19761 transmit_invite(p, SIP_NOTIFY, 0, 2, NULL); 19762 dialog_unref(p, "bump down the count of p since we're done with it."); 19763 } 19764 19765 return CLI_SUCCESS; 19766 }
| static int sip_debug_test_addr | ( | const struct ast_sockaddr * | addr | ) | [inline, static] |
See if we pass debug IP filter.
Definition at line 3363 of file chan_sip.c.
References ast_sockaddr_cmp(), ast_sockaddr_cmp_addr(), ast_sockaddr_isnull(), ast_sockaddr_port, and debugaddr.
Referenced by check_peer_ok(), handle_request_do(), and sip_debug_test_pvt().
03364 { 03365 /* Can't debug if sipdebug is not enabled */ 03366 if (!sipdebug) { 03367 return 0; 03368 } 03369 03370 /* A null debug_addr means we'll debug any address */ 03371 if (ast_sockaddr_isnull(&debugaddr)) { 03372 return 1; 03373 } 03374 03375 /* If no port was specified for a debug address, just compare the 03376 * addresses, otherwise compare the address and port 03377 */ 03378 if (ast_sockaddr_port(&debugaddr)) { 03379 return !ast_sockaddr_cmp(&debugaddr, addr); 03380 } else { 03381 return !ast_sockaddr_cmp_addr(&debugaddr, addr); 03382 } 03383 }
| static int sip_debug_test_pvt | ( | struct sip_pvt * | p | ) | [inline, static] |
Test PVT for debugging output.
Definition at line 3402 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().
03403 { 03404 if (!sipdebug) { 03405 return 0; 03406 } 03407 return sip_debug_test_addr(sip_real_dst(p)); 03408 }
| struct sip_pvt* sip_destroy | ( | struct sip_pvt * | p | ) | [read] |
Destroy SIP call structure. Make it return NULL so the caller can do things like foo = sip_destroy(foo); and reduce the chance of bugs due to dangling pointers.
Definition at line 6296 of file chan_sip.c.
References __sip_destroy(), ast_debug, and TRUE.
Referenced by sip_destroy_fn().
06297 { 06298 ast_debug(3, "Destroying SIP dialog %s\n", p->callid); 06299 __sip_destroy(p, TRUE, TRUE); 06300 return NULL; 06301 }
| static void sip_destroy_fn | ( | void * | p | ) | [static] |
Definition at line 6286 of file chan_sip.c.
References sip_destroy().
Referenced by sip_alloc().
06287 { 06288 sip_destroy(p); 06289 }
| static void sip_destroy_peer | ( | struct sip_peer * | peer | ) | [static] |
Destroy peer object from memory.
Definition at line 4824 of file chan_sip.c.
References ao2_ref, ao2_t_ref, ast_atomic_fetchadd_int(), ast_cc_config_params_destroy(), ast_debug, ast_free_ha(), ast_string_field_free_memory, ast_test_flag, ast_variables_destroy(), clear_peer_mailboxes(), dialog_unlink_all(), FALSE, and register_peer_exten().
Referenced by sip_destroy_peer_fn().
04825 { 04826 ast_debug(3, "Destroying SIP peer %s\n", peer->name); 04827 04828 /* 04829 * Remove any mailbox event subscriptions for this peer before 04830 * we destroy anything. An event subscription callback may be 04831 * happening right now. 04832 */ 04833 clear_peer_mailboxes(peer); 04834 04835 if (peer->outboundproxy) { 04836 ao2_ref(peer->outboundproxy, -1); 04837 peer->outboundproxy = NULL; 04838 } 04839 04840 /* Delete it, it needs to disappear */ 04841 if (peer->call) { 04842 dialog_unlink_all(peer->call); 04843 peer->call = dialog_unref(peer->call, "peer->call is being unset"); 04844 } 04845 04846 if (peer->mwipvt) { /* We have an active subscription, delete it */ 04847 dialog_unlink_all(peer->mwipvt); 04848 peer->mwipvt = dialog_unref(peer->mwipvt, "unreffing peer->mwipvt"); 04849 } 04850 04851 if (peer->chanvars) { 04852 ast_variables_destroy(peer->chanvars); 04853 peer->chanvars = NULL; 04854 } 04855 04856 register_peer_exten(peer, FALSE); 04857 ast_free_ha(peer->ha); 04858 ast_free_ha(peer->directmediaha); 04859 if (peer->selfdestruct) 04860 ast_atomic_fetchadd_int(&apeerobjs, -1); 04861 else if (!ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && peer->is_realtime) { 04862 ast_atomic_fetchadd_int(&rpeerobjs, -1); 04863 ast_debug(3, "-REALTIME- peer Destroyed. Name: %s. Realtime Peer objects: %d\n", peer->name, rpeerobjs); 04864 } else 04865 ast_atomic_fetchadd_int(&speerobjs, -1); 04866 if (peer->auth) { 04867 ao2_t_ref(peer->auth, -1, "Removing peer authentication"); 04868 peer->auth = NULL; 04869 } 04870 04871 if (peer->socket.tcptls_session) { 04872 ao2_ref(peer->socket.tcptls_session, -1); 04873 peer->socket.tcptls_session = NULL; 04874 } 04875 04876 ast_cc_config_params_destroy(peer->cc_params); 04877 04878 ast_string_field_free_memory(peer); 04879 }
| static void sip_destroy_peer_fn | ( | void * | peer | ) | [static] |
Definition at line 4818 of file chan_sip.c.
References sip_destroy_peer().
Referenced by build_peer(), and temp_peer().
04819 { 04820 sip_destroy_peer(peer); 04821 }
| static int sip_devicestate | ( | void * | data | ) | [static] |
Part of PBX channel interface.
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 27237 of file chan_sip.c.
References ast_debug, AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, AST_DEVICE_ONHOLD, AST_DEVICE_RINGING, AST_DEVICE_RINGINUSE, AST_DEVICE_UNAVAILABLE, ast_sockaddr_isnull(), ast_strdupa, FALSE, find_peer(), TRUE, and unref_peer().
27238 { 27239 char *host; 27240 char *tmp; 27241 struct sip_peer *p; 27242 27243 int res = AST_DEVICE_INVALID; 27244 27245 /* make sure data is not null. Maybe unnecessary, but better be safe */ 27246 host = ast_strdupa(data ? data : ""); 27247 if ((tmp = strchr(host, '@'))) 27248 host = tmp + 1; 27249 27250 ast_debug(3, "Checking device state for peer %s\n", host); 27251 27252 /* If find_peer asks for a realtime peer, then this breaks rtautoclear. This 27253 * is because when a peer tries to autoexpire, the last thing it does is to 27254 * queue up an event telling the system that the devicestate has changed 27255 * (presumably to unavailable). If we ask for a realtime peer here, this would 27256 * load it BACK into memory, thus defeating the point of trying to clear dead 27257 * hosts out of memory. 27258 */ 27259 if ((p = find_peer(host, NULL, FALSE, FINDALLDEVICES, TRUE, 0))) { 27260 if (!(ast_sockaddr_isnull(&p->addr) && ast_sockaddr_isnull(&p->defaddr))) { 27261 /* we have an address for the peer */ 27262 27263 /* Check status in this order 27264 - Hold 27265 - Ringing 27266 - Busy (enforced only by call limit) 27267 - Inuse (we have a call) 27268 - Unreachable (qualify) 27269 If we don't find any of these state, report AST_DEVICE_NOT_INUSE 27270 for registered devices */ 27271 27272 if (p->onHold) 27273 /* First check for hold or ring states */ 27274 res = AST_DEVICE_ONHOLD; 27275 else if (p->inRinging) { 27276 if (p->inRinging == p->inUse) 27277 res = AST_DEVICE_RINGING; 27278 else 27279 res = AST_DEVICE_RINGINUSE; 27280 } else if (p->call_limit && (p->inUse == p->call_limit)) 27281 /* check call limit */ 27282 res = AST_DEVICE_BUSY; 27283 else if (p->call_limit && p->busy_level && p->inUse >= p->busy_level) 27284 /* We're forcing busy before we've reached the call limit */ 27285 res = AST_DEVICE_BUSY; 27286 else if (p->call_limit && p->inUse) 27287 /* Not busy, but we do have a call */ 27288 res = AST_DEVICE_INUSE; 27289 else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0))) 27290 /* We don't have a call. Are we reachable at all? Requires qualify= */ 27291 res = AST_DEVICE_UNAVAILABLE; 27292 else /* Default reply if we're registered and have no other data */ 27293 res = AST_DEVICE_NOT_INUSE; 27294 } else { 27295 /* there is no address, it's unavailable */ 27296 res = AST_DEVICE_UNAVAILABLE; 27297 } 27298 unref_peer(p, "unref_peer, from sip_devicestate, release ref from find_peer"); 27299 } 27300 27301 return res; 27302 }
| static char * sip_do_debug | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Turn on SIP debugging (CLI command).
Definition at line 19638 of file chan_sip.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sip_peer(), debugaddr, ast_cli_args::fd, ast_cli_args::n, ast_cli_args::pos, sip_do_debug_ip(), sip_do_debug_peer(), ast_cli_entry::usage, and ast_cli_args::word.
19639 { 19640 int oldsipdebug = sipdebug & sip_debug_console; 19641 const char *what; 19642 19643 if (cmd == CLI_INIT) { 19644 e->command = "sip set debug {on|off|ip|peer}"; 19645 e->usage = 19646 "Usage: sip set debug {off|on|ip addr[:port]|peer peername}\n" 19647 " Globally disables dumping of SIP packets,\n" 19648 " or enables it either globally or for a (single)\n" 19649 " IP address or registered peer.\n"; 19650 return NULL; 19651 } else if (cmd == CLI_GENERATE) { 19652 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer")) 19653 return complete_sip_peer(a->word, a->n, 0); 19654 return NULL; 19655 } 19656 19657 what = a->argv[e->args-1]; /* guaranteed to exist */ 19658 if (a->argc == e->args) { /* on/off */ 19659 if (!strcasecmp(what, "on")) { 19660 sipdebug |= sip_debug_console; 19661 sipdebug_text = 1; /*! \note this can be a special debug command - "sip debug text" or something */ 19662 memset(&debugaddr, 0, sizeof(debugaddr)); 19663 ast_cli(a->fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 19664 return CLI_SUCCESS; 19665 } else if (!strcasecmp(what, "off")) { 19666 sipdebug &= ~sip_debug_console; 19667 sipdebug_text = 0; 19668 ast_cli(a->fd, "SIP Debugging Disabled\n"); 19669 return CLI_SUCCESS; 19670 } 19671 } else if (a->argc == e->args +1) {/* ip/peer */ 19672 if (!strcasecmp(what, "ip")) 19673 return sip_do_debug_ip(a->fd, a->argv[e->args]); 19674 else if (!strcasecmp(what, "peer")) 19675 return sip_do_debug_peer(a->fd, a->argv[e->args]); 19676 } 19677 return CLI_SHOWUSAGE; /* default, failure */ 19678 }
| static char * sip_do_debug_ip | ( | int | fd, | |
| const char * | arg | |||
| ) | [static] |
Enable SIP Debugging for a single IP.
Definition at line 19607 of file chan_sip.c.
References ast_cli(), ast_sockaddr_resolve_first_af(), ast_sockaddr_stringify_addr(), CLI_SHOWUSAGE, CLI_SUCCESS, and debugaddr.
Referenced by sip_do_debug().
19608 { 19609 if (ast_sockaddr_resolve_first_af(&debugaddr, arg, 0, 0)) { 19610 return CLI_SHOWUSAGE; 19611 } 19612 19613 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_sockaddr_stringify_addr(&debugaddr)); 19614 sipdebug |= sip_debug_console; 19615 19616 return CLI_SUCCESS; 19617 }
| static char * sip_do_debug_peer | ( | int | fd, | |
| const char * | arg | |||
| ) | [static] |
Turn on SIP debugging for a given peer.
Definition at line 19620 of file chan_sip.c.
References ast_cli(), ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_stringify_addr(), CLI_SUCCESS, debugaddr, FALSE, find_peer(), TRUE, and unref_peer().
Referenced by sip_do_debug().
19621 { 19622 struct sip_peer *peer = find_peer(arg, NULL, TRUE, FINDPEERS, FALSE, 0); 19623 if (!peer) 19624 ast_cli(fd, "No such peer '%s'\n", arg); 19625 else if (ast_sockaddr_isnull(&peer->addr)) 19626 ast_cli(fd, "Unable to get IP address of peer '%s'\n", arg); 19627 else { 19628 ast_sockaddr_copy(&debugaddr, &peer->addr); 19629 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_sockaddr_stringify_addr(&debugaddr)); 19630 sipdebug |= sip_debug_console; 19631 } 19632 if (peer) 19633 unref_peer(peer, "sip_do_debug_peer: unref_peer, from find_peer call"); 19634 return CLI_SUCCESS; 19635 }
| static int sip_do_reload | ( | enum channelreloadreason | reason | ) | [static] |
Reload module.
Definition at line 30600 of file chan_sip.c.
References ast_debug, ast_sched_dump(), reload_config(), sip_poke_all_peers(), sip_send_all_mwi_subscriptions(), sip_send_all_registers(), and unlink_marked_peers_from_tables().
Referenced by do_monitor().
30601 { 30602 time_t start_poke, end_poke; 30603 30604 reload_config(reason); 30605 ast_sched_dump(sched); 30606 30607 start_poke = time(0); 30608 /* Prune peers who still are supposed to be deleted */ 30609 unlink_marked_peers_from_tables(); 30610 30611 ast_debug(4, "--------------- Done destroying pruned peers\n"); 30612 30613 /* Send qualify (OPTIONS) to all peers */ 30614 sip_poke_all_peers(); 30615 30616 /* Register with all services */ 30617 sip_send_all_registers(); 30618 30619 sip_send_all_mwi_subscriptions(); 30620 30621 end_poke = time(0); 30622 30623 ast_debug(4, "do_reload finished. peer poke/prune reg contact time = %d sec.\n", (int)(end_poke-start_poke)); 30624 30625 ast_debug(4, "--------------- SIP reload done\n"); 30626 30627 return 0; 30628 }
| static int sip_dtmfmode | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Set the DTMFmode for an outbound SIP call (application).
Definition at line 30283 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_log(), AST_RTP_DTMF, ast_rtp_instance_set_prop(), AST_RTP_PROPERTY_DTMF, ast_set_flag, ast_test_flag, disable_dsp_detect(), enable_dsp_detect(), LOG_WARNING, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech, and ast_channel::tech_pvt.
Referenced by load_module().
30284 { 30285 struct sip_pvt *p; 30286 const char *mode = data; 30287 30288 if (!data) { 30289 ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n"); 30290 return 0; 30291 } 30292 ast_channel_lock(chan); 30293 if (!IS_SIP_TECH(chan->tech)) { 30294 ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n"); 30295 ast_channel_unlock(chan); 30296 return 0; 30297 } 30298 p = chan->tech_pvt; 30299 if (!p) { 30300 ast_channel_unlock(chan); 30301 return 0; 30302 } 30303 sip_pvt_lock(p); 30304 if (!strcasecmp(mode, "info")) { 30305 ast_clear_flag(&p->flags[0], SIP_DTMF); 30306 ast_set_flag(&p->flags[0], SIP_DTMF_INFO); 30307 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 30308 } else if (!strcasecmp(mode, "shortinfo")) { 30309 ast_clear_flag(&p->flags[0], SIP_DTMF); 30310 ast_set_flag(&p->flags[0], SIP_DTMF_SHORTINFO); 30311 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 30312 } else if (!strcasecmp(mode, "rfc2833")) { 30313 ast_clear_flag(&p->flags[0], SIP_DTMF); 30314 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 30315 p->jointnoncodeccapability |= AST_RTP_DTMF; 30316 } else if (!strcasecmp(mode, "inband")) { 30317 ast_clear_flag(&p->flags[0], SIP_DTMF); 30318 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 30319 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 30320 } else { 30321 ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n", mode); 30322 } 30323 if (p->rtp) 30324 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 30325 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || 30326 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) { 30327 enable_dsp_detect(p); 30328 } else { 30329 disable_dsp_detect(p); 30330 } 30331 sip_pvt_unlock(p); 30332 ast_channel_unlock(chan); 30333 return 0; 30334 }
| static void sip_dump_history | ( | struct sip_pvt * | dialog | ) | [static] |
Dump SIP history to debug log file at end of lifespan for SIP dialog.
Definition at line 19407 of file chan_sip.c.
References ast_debug, AST_LIST_TRAVERSE, ast_log(), LOG_NOTICE, and option_debug.
Referenced by __sip_destroy().
19408 { 19409 int x = 0; 19410 struct sip_history *hist; 19411 static int errmsg = 0; 19412 19413 if (!dialog) 19414 return; 19415 19416 if (!option_debug && !sipdebug) { 19417 if (!errmsg) { 19418 ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n"); 19419 errmsg = 1; 19420 } 19421 return; 19422 } 19423 19424 ast_debug(1, "\n---------- SIP HISTORY for '%s' \n", dialog->callid); 19425 if (dialog->subscribed) 19426 ast_debug(1, " * Subscription\n"); 19427 else 19428 ast_debug(1, " * SIP Call\n"); 19429 if (dialog->history) 19430 AST_LIST_TRAVERSE(dialog->history, hist, list) 19431 ast_debug(1, " %-3.3d. %s\n", ++x, hist->event); 19432 if (!x) 19433 ast_debug(1, "Call '%s' has no history\n", dialog->callid); 19434 ast_debug(1, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid); 19435 }
| static int sip_epa_register | ( | const struct epa_static_data * | static_data | ) | [static] |
Definition at line 851 of file chan_sip.c.
References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, and AST_LIST_UNLOCK.
Referenced by load_module().
00852 { 00853 struct epa_backend *backend = ast_calloc(1, sizeof(*backend)); 00854 00855 if (!backend) { 00856 return -1; 00857 } 00858 00859 backend->static_data = static_data; 00860 00861 AST_LIST_LOCK(&epa_static_data_list); 00862 AST_LIST_INSERT_TAIL(&epa_static_data_list, backend, next); 00863 AST_LIST_UNLOCK(&epa_static_data_list); 00864 return 0; 00865 }
| static void sip_epa_unregister_all | ( | void | ) | [static] |
Definition at line 867 of file chan_sip.c.
References ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, and AST_LIST_UNLOCK.
Referenced by unload_module().
00868 { 00869 struct epa_backend *backend; 00870 00871 AST_LIST_LOCK(&epa_static_data_list); 00872 while ((backend = AST_LIST_REMOVE_HEAD(&epa_static_data_list, next))) { 00873 ast_free(backend); 00874 } 00875 AST_LIST_UNLOCK(&epa_static_data_list); 00876 }
| static int sip_fixup | ( | struct ast_channel * | oldchan, | |
| struct ast_channel * | newchan | |||
| ) | [static] |
sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links
Definition at line 6872 of file chan_sip.c.
References append_history, ast_debug, AST_FLAG_ZOMBIE, ast_log(), ast_test_flag, LOG_WARNING, sip_pvt_lock, sip_pvt_unlock, sip_set_rtp_peer(), and ast_channel::tech_pvt.
06873 { 06874 int ret = -1; 06875 struct sip_pvt *p; 06876 06877 if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE)) 06878 ast_debug(1, "New channel is zombie\n"); 06879 if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE)) 06880 ast_debug(1, "Old channel is zombie\n"); 06881 06882 if (!newchan || !newchan->tech_pvt) { 06883 if (!newchan) 06884 ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name); 06885 else 06886 ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name); 06887 return -1; 06888 } 06889 p = newchan->tech_pvt; 06890 06891 sip_pvt_lock(p); 06892 append_history(p, "Masq", "Old channel: %s\n", oldchan->name); 06893 append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name); 06894 if (p->owner != oldchan) 06895 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner); 06896 else { 06897 p->owner = newchan; 06898 /* Re-invite RTP back to Asterisk. Needed if channel is masqueraded out of a native 06899 RTP bridge (i.e., RTP not going through Asterisk): RTP bridge code might not be 06900 able to do this if the masquerade happens before the bridge breaks (e.g., AMI 06901 redirect of both channels). Note that a channel can not be masqueraded *into* 06902 a native bridge. So there is no danger that this breaks a native bridge that 06903 should stay up. */ 06904 sip_set_rtp_peer(newchan, NULL, NULL, 0, 0, 0); 06905 ret = 0; 06906 } 06907 ast_debug(3, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name); 06908 06909 sip_pvt_unlock(p); 06910 return ret; 06911 }
| static const char * sip_get_callid | ( | struct ast_channel * | chan | ) | [static] |
Deliver SIP call ID for the call.
Definition at line 4672 of file chan_sip.c.
References ast_channel::tech_pvt.
| static int sip_get_cc_information | ( | struct sip_request * | req, | |
| char * | subscribe_uri, | |||
| size_t | size, | |||
| enum ast_cc_service_type * | service | |||
| ) | [static] |
Definition at line 2067 of file chan_sip.c.
References AST_CC_NONE, ast_copy_string(), ast_strdupa, ast_strlen_zero(), get_header(), get_in_brackets(), and service_string_to_service_type().
Referenced by sip_handle_cc().
02068 { 02069 char *call_info = ast_strdupa(get_header(req, "Call-Info")); 02070 char *uri; 02071 char *purpose; 02072 char *service_str; 02073 static const char cc_purpose[] = "purpose=call-completion"; 02074 static const int cc_purpose_len = sizeof(cc_purpose) - 1; 02075 02076 if (ast_strlen_zero(call_info)) { 02077 /* No Call-Info present. Definitely no CC offer */ 02078 return -1; 02079 } 02080 02081 uri = strsep(&call_info, ";"); 02082 02083 while ((purpose = strsep(&call_info, ";"))) { 02084 if (!strncmp(purpose, cc_purpose, cc_purpose_len)) { 02085 break; 02086 } 02087 } 02088 if (!purpose) { 02089 /* We didn't find the appropriate purpose= parameter. Oh well */ 02090 return -1; 02091 } 02092 02093 /* Okay, call-completion has been offered. Let's figure out what type of service this is */ 02094 while ((service_str = strsep(&call_info, ";"))) { 02095 if (!strncmp(service_str, "m=", 2)) { 02096 break; 02097 } 02098 } 02099 if (!service_str) { 02100 /* So they didn't offer a particular service, We'll just go with CCBS since it really 02101 * doesn't matter anyway 02102 */ 02103 service_str = "BS"; 02104 } else { 02105 /* We already determined that there is an "m=" so no need to check 02106 * the result of this strsep 02107 */ 02108 strsep(&service_str, "="); 02109 } 02110 02111 if ((*service = service_string_to_service_type(service_str)) == AST_CC_NONE) { 02112 /* Invalid service offered */ 02113 return -1; 02114 } 02115 02116 ast_copy_string(subscribe_uri, get_in_brackets(uri), size); 02117 02118 return 0; 02119 }
| static format_t sip_get_codec | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 30263 of file chan_sip.c.
References ast_channel::tech_pvt.
30264 { 30265 struct sip_pvt *p = chan->tech_pvt; 30266 return p->peercapability ? p->peercapability : p->capability; 30267 }
| static enum ast_rtp_glue_result sip_get_rtp_peer | ( | struct ast_channel * | chan, | |
| struct ast_rtp_instance ** | instance | |||
| ) | [static] |
Definition at line 29974 of file chan_sip.c.
References ao2_ref, apply_directmedia_ha(), ast_bridged_channel(), AST_JB_FORCED, AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_LOCAL, AST_RTP_GLUE_RESULT_REMOTE, ast_test_flag, global_jbconf, sip_pvt_lock, sip_pvt_trylock, sip_pvt_unlock, sip_tech_info, ast_channel::tech, and ast_channel::tech_pvt.
29975 { 29976 struct sip_pvt *p = NULL; 29977 struct ast_channel *opp_chan; 29978 struct sip_pvt *opp = NULL; 29979 enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_LOCAL; 29980 29981 if (!(p = chan->tech_pvt)) { 29982 return AST_RTP_GLUE_RESULT_FORBID; 29983 } 29984 29985 if ((opp_chan = ast_bridged_channel(chan)) && (((opp_chan->tech != &sip_tech) && (opp_chan->tech != &sip_tech_info)) || 29986 (!(opp = opp_chan->tech_pvt)))) { 29987 return AST_RTP_GLUE_RESULT_FORBID; 29988 } 29989 29990 sip_pvt_lock(p); 29991 while (opp && sip_pvt_trylock(opp)) { 29992 sip_pvt_unlock(p); 29993 usleep(1); 29994 sip_pvt_lock(p); 29995 } 29996 29997 if (!(p->rtp)) { 29998 if (opp) { 29999 sip_pvt_unlock(opp); 30000 } 30001 sip_pvt_unlock(p); 30002 return AST_RTP_GLUE_RESULT_FORBID; 30003 } 30004 30005 ao2_ref(p->rtp, +1); 30006 *instance = p->rtp; 30007 30008 if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) { 30009 res = AST_RTP_GLUE_RESULT_REMOTE; 30010 if (opp && !apply_directmedia_ha(p, opp, "audio")) { 30011 res = AST_RTP_GLUE_RESULT_FORBID; 30012 } 30013 } else if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA_NAT)) { 30014 res = AST_RTP_GLUE_RESULT_REMOTE; 30015 } else if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) { 30016 res = AST_RTP_GLUE_RESULT_FORBID; 30017 } 30018 30019 if (opp) { 30020 sip_pvt_unlock(opp); 30021 } 30022 30023 if (p->srtp) { 30024 res = AST_RTP_GLUE_RESULT_FORBID; 30025 } 30026 30027 sip_pvt_unlock(p); 30028 30029 return res; 30030 }
| static enum ast_rtp_glue_result sip_get_trtp_peer | ( | struct ast_channel * | chan, | |
| struct ast_rtp_instance ** | instance | |||
| ) | [static] |
Definition at line 30081 of file chan_sip.c.
References ao2_ref, apply_directmedia_ha(), ast_bridged_channel(), AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_REMOTE, ast_test_flag, sip_pvt_lock, sip_pvt_trylock, sip_pvt_unlock, sip_tech_info, ast_channel::tech, and ast_channel::tech_pvt.
30082 { 30083 struct sip_pvt *p = NULL; 30084 struct ast_channel *opp_chan; 30085 struct sip_pvt *opp = NULL; 30086 enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_FORBID; 30087 30088 if (!(p = chan->tech_pvt)) { 30089 return AST_RTP_GLUE_RESULT_FORBID; 30090 } 30091 30092 if ((opp_chan = ast_bridged_channel(chan)) && (((opp_chan->tech != &sip_tech) && (opp_chan->tech != &sip_tech_info)) || 30093 (!(opp = opp_chan->tech_pvt)))) { 30094 return AST_RTP_GLUE_RESULT_FORBID; 30095 } 30096 30097 sip_pvt_lock(p); 30098 while (opp && sip_pvt_trylock(opp)) { 30099 sip_pvt_unlock(p); 30100 usleep(1); 30101 sip_pvt_lock(p); 30102 } 30103 30104 if (!(p->trtp)) { 30105 if (opp) { 30106 sip_pvt_unlock(opp); 30107 } 30108 sip_pvt_unlock(p); 30109 return AST_RTP_GLUE_RESULT_FORBID; 30110 } 30111 30112 ao2_ref(p->trtp, +1); 30113 *instance = p->trtp; 30114 30115 if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) { 30116 res = AST_RTP_GLUE_RESULT_REMOTE; 30117 if (opp && !apply_directmedia_ha(p, opp, "text")) { 30118 res = AST_RTP_GLUE_RESULT_FORBID; 30119 } 30120 } 30121 30122 if (opp) { 30123 sip_pvt_unlock(opp); 30124 } 30125 sip_pvt_unlock(p); 30126 30127 return res; 30128 }
| static struct ast_udptl * sip_get_udptl_peer | ( | struct ast_channel * | chan | ) | [static, read] |
Definition at line 29894 of file chan_sip.c.
References apply_directmedia_ha(), ast_bridged_channel(), ast_test_flag, sip_pvt_lock, sip_pvt_trylock, sip_pvt_unlock, sip_tech_info, ast_channel::tech, and ast_channel::tech_pvt.
29895 { 29896 struct sip_pvt *p; 29897 struct ast_channel *opp_chan; 29898 struct sip_pvt *opp; 29899 struct ast_udptl *udptl = NULL; 29900 29901 p = chan->tech_pvt; 29902 if (!p) { 29903 return NULL; 29904 } 29905 29906 if (!(opp_chan = ast_bridged_channel(chan))) { 29907 return NULL; 29908 } else if (((opp_chan->tech != &sip_tech) && (opp_chan->tech != &sip_tech_info)) || 29909 (!(opp = opp_chan->tech_pvt))) { 29910 return NULL; 29911 } 29912 29913 sip_pvt_lock(p); 29914 while (sip_pvt_trylock(opp)) { 29915 sip_pvt_unlock(p); 29916 usleep(1); 29917 sip_pvt_lock(p); 29918 } 29919 29920 if (p->udptl && ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) { 29921 if (apply_directmedia_ha(p, opp, "UDPTL T.38 data")) { 29922 udptl = p->udptl; 29923 } 29924 } 29925 29926 sip_pvt_unlock(opp); 29927 sip_pvt_unlock(p); 29928 return udptl; 29929 }
| static enum ast_rtp_glue_result sip_get_vrtp_peer | ( | struct ast_channel * | chan, | |
| struct ast_rtp_instance ** | instance | |||
| ) | [static] |
Definition at line 30032 of file chan_sip.c.
References ao2_ref, apply_directmedia_ha(), ast_bridged_channel(), AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_REMOTE, ast_test_flag, sip_pvt_lock, sip_pvt_trylock, sip_pvt_unlock, sip_tech_info, ast_channel::tech, and ast_channel::tech_pvt.
30033 { 30034 struct sip_pvt *p = NULL; 30035 struct ast_channel *opp_chan; 30036 struct sip_pvt *opp = NULL; 30037 enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_FORBID; 30038 30039 if (!(p = chan->tech_pvt)) { 30040 return AST_RTP_GLUE_RESULT_FORBID; 30041 } 30042 30043 if ((opp_chan = ast_bridged_channel(chan)) && (((opp_chan->tech != &sip_tech) && (opp_chan->tech != &sip_tech_info)) || 30044 (!(opp = opp_chan->tech_pvt)))) { 30045 return AST_RTP_GLUE_RESULT_FORBID; 30046 } 30047 30048 sip_pvt_lock(p); 30049 while (opp && sip_pvt_trylock(opp)) { 30050 sip_pvt_unlock(p); 30051 usleep(1); 30052 sip_pvt_lock(p); 30053 } 30054 30055 if (!(p->vrtp)) { 30056 if (opp) { 30057 sip_pvt_unlock(opp); 30058 } 30059 sip_pvt_unlock(p); 30060 return AST_RTP_GLUE_RESULT_FORBID; 30061 } 30062 30063 ao2_ref(p->vrtp, +1); 30064 *instance = p->vrtp; 30065 30066 if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) { 30067 res = AST_RTP_GLUE_RESULT_REMOTE; 30068 if (opp && !apply_directmedia_ha(p, opp, "video")) { 30069 res = AST_RTP_GLUE_RESULT_FORBID; 30070 } 30071 } 30072 30073 if (opp) { 30074 sip_pvt_unlock(opp); 30075 } 30076 sip_pvt_unlock(p); 30077 30078 return res; 30079 }
| static void sip_handle_cc | ( | struct sip_pvt * | pvt, | |
| struct sip_request * | req, | |||
| enum ast_cc_service_type | service | |||
| ) | [static] |
Definition at line 2138 of file chan_sip.c.
References ao2_ref, AST_CC_GENERIC_MONITOR_TYPE, ast_cc_get_current_core_id(), AST_CC_MONITOR_ALWAYS, AST_CC_MONITOR_GENERIC, AST_CC_MONITOR_NATIVE, AST_CC_MONITOR_NEVER, ast_channel_get_device_name(), AST_CHANNEL_NAME, ast_get_cc_monitor_policy(), ast_module_ref(), ast_queue_cc_frame(), sip_get_cc_information(), and sip_monitor_instance_init().
Referenced by handle_response(), and handle_response_invite().
02139 { 02140 enum ast_cc_monitor_policies monitor_policy = ast_get_cc_monitor_policy(pvt->cc_params); 02141 int core_id; 02142 char interface_name[AST_CHANNEL_NAME]; 02143 02144 if (monitor_policy == AST_CC_MONITOR_NEVER) { 02145 /* Don't bother, just return */ 02146 return; 02147 } 02148 02149 if ((core_id = ast_cc_get_current_core_id(pvt->owner)) == -1) { 02150 /* For some reason, CC is invalid, so don't try it! */ 02151 return; 02152 } 02153 02154 ast_channel_get_device_name(pvt->owner, interface_name, sizeof(interface_name)); 02155 02156 if (monitor_policy == AST_CC_MONITOR_ALWAYS || monitor_policy == AST_CC_MONITOR_NATIVE) { 02157 char subscribe_uri[SIPBUFSIZE]; 02158 char device_name[AST_CHANNEL_NAME]; 02159 enum ast_cc_service_type offered_service; 02160 struct sip_monitor_instance *monitor_instance; 02161 if (sip_get_cc_information(req, subscribe_uri, sizeof(subscribe_uri), &offered_service)) { 02162 /* If CC isn't being offered to us, or for some reason the CC offer is 02163 * not formatted correctly, then it may still be possible to use generic 02164 * call completion since the monitor policy may be "always" 02165 */ 02166 goto generic; 02167 } 02168 ast_channel_get_device_name(pvt->owner, device_name, sizeof(device_name)); 02169 if (!(monitor_instance = sip_monitor_instance_init(core_id, subscribe_uri, pvt->peername, device_name))) { 02170 /* Same deal. We can try using generic still */ 02171 goto generic; 02172 } 02173 /* We bump the refcount of chan_sip because once we queue this frame, the CC core 02174 * will have a reference to callbacks in this module. We decrement the module 02175 * refcount once the monitor destructor is called 02176 */ 02177 ast_module_ref(ast_module_info->self); 02178 ast_queue_cc_frame(pvt->owner, "SIP", pvt->dialstring, offered_service, monitor_instance); 02179 ao2_ref(monitor_instance, -1); 02180 return; 02181 } 02182 02183 generic: 02184 if (monitor_policy == AST_CC_MONITOR_GENERIC || monitor_policy == AST_CC_MONITOR_ALWAYS) { 02185 ast_queue_cc_frame(pvt->owner, AST_CC_GENERIC_MONITOR_TYPE, interface_name, service, NULL); 02186 } 02187 }
| static int sip_hangup | ( | struct ast_channel * | ast | ) | [static] |
sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup
Definition at line 6490 of file chan_sip.c.
References __sip_semi_ack(), ast_channel::_state, append_history, ast_bridged_channel(), ast_cause2str(), AST_CAUSE_ANSWERED_ELSEWHERE, ast_channel_trylock, ast_channel_unlock, ast_clear_flag, ast_debug, AST_FLAG_ANSWERED_ELSEWHERE, ast_log(), AST_MAX_USER_FIELD, ast_module_unref(), ast_rtp_instance_get_quality(), ast_rtp_instance_set_stats_vars(), AST_RTP_INSTANCE_STAT_FIELD_QUALITY, ast_sched_add(), AST_SCHED_DEL_UNREF, ast_set_flag, ast_state2str(), AST_STATE_UP, ast_str_buffer(), ast_str_strlen(), ast_test_flag, CHANNEL_DEADLOCK_AVOIDANCE, disable_dsp_detect(), FALSE, find_sip_method(), hangup_cause2sip(), ast_channel::hangupcause, LOG_WARNING, pbx_builtin_setvar_helper(), pvt_set_needdestroy(), quality, reinvite_timeout(), sip_cancel_destroy(), sip_pvt_lock, sip_pvt_trylock, sip_pvt_unlock, sip_scheddestroy(), stop_media_flows(), stop_session_timer(), ast_channel::tech, ast_channel::tech_pvt, transmit_request(), transmit_request_with_auth(), transmit_response_reliable(), TRUE, and update_call_counter().
06491 { 06492 struct sip_pvt *p = ast->tech_pvt; 06493 int needcancel = FALSE; 06494 int needdestroy = 0; 06495 struct ast_channel *oldowner = ast; 06496 06497 if (!p) { 06498 ast_debug(1, "Asked to hangup channel that was not connected\n"); 06499 return 0; 06500 } 06501 if (ast_test_flag(ast, AST_FLAG_ANSWERED_ELSEWHERE) || ast->hangupcause == AST_CAUSE_ANSWERED_ELSEWHERE) { 06502 ast_debug(1, "This call was answered elsewhere\n"); 06503 if (ast->hangupcause == AST_CAUSE_ANSWERED_ELSEWHERE) { 06504 ast_debug(1, "####### It's the cause code, buddy. The cause code!!!\n"); 06505 } 06506 append_history(p, "Cancel", "Call answered elsewhere"); 06507 p->answered_elsewhere = TRUE; 06508 } 06509 06510 /* Store hangupcause locally in PVT so we still have it before disconnect */ 06511 if (p->owner) 06512 p->hangupcause = p->owner->hangupcause; 06513 06514 if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 06515 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 06516 if (sipdebug) 06517 ast_debug(1, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 06518 update_call_counter(p, DEC_CALL_LIMIT); 06519 } 06520 ast_debug(4, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid); 06521 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 06522 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */ 06523 p->needdestroy = 0; 06524 if (p->owner) { 06525 p->owner->tech_pvt = dialog_unref(p->owner->tech_pvt, "unref p->owner->tech_pvt"); 06526 sip_pvt_lock(p); 06527 p->owner = NULL; /* Owner will be gone after we return, so take it away */ 06528 sip_pvt_unlock(p); 06529 } 06530 ast_module_unref(ast_module_info->self); 06531 return 0; 06532 } 06533 06534 ast_debug(1, "Hangup call %s, SIP callid %s\n", ast->name, p->callid); 06535 06536 sip_pvt_lock(p); 06537 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 06538 if (sipdebug) 06539 ast_debug(1, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 06540 update_call_counter(p, DEC_CALL_LIMIT); 06541 } 06542 06543 /* Determine how to disconnect */ 06544 if (p->owner != ast) { 06545 ast_log(LOG_WARNING, "Huh? We aren't the owner? Can't hangup call.\n"); 06546 sip_pvt_unlock(p); 06547 return 0; 06548 } 06549 /* If the call is not UP, we need to send CANCEL instead of BYE */ 06550 /* In case of re-invites, the call might be UP even though we have an incomplete invite transaction */ 06551 if (p->invitestate < INV_COMPLETED && p->owner->_state != AST_STATE_UP) { 06552 needcancel = TRUE; 06553 ast_debug(4, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state)); 06554 } 06555 06556 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 06557 06558 append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", ast_cause2str(p->hangupcause)); 06559 06560 /* Disconnect */ 06561 disable_dsp_detect(p); 06562 06563 p->owner = NULL; 06564 ast->tech_pvt = dialog_unref(ast->tech_pvt, "unref ast->tech_pvt"); 06565 06566 ast_module_unref(ast_module_info->self); 06567 /* Do not destroy this pvt until we have timeout or 06568 get an answer to the BYE or INVITE/CANCEL 06569 If we get no answer during retransmit period, drop the call anyway. 06570 (Sorry, mother-in-law, you can't deny a hangup by sending 06571 603 declined to BYE...) 06572 */ 06573 if (p->alreadygone) 06574 needdestroy = 1; /* Set destroy flag at end of this function */ 06575 else if (p->invitestate != INV_CALLING) 06576 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 06577 06578 /* Start the process if it's not already started */ 06579 if (!p->alreadygone && p->initreq.data && ast_str_strlen(p->initreq.data)) { 06580 if (needcancel) { /* Outgoing call, not up */ 06581 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06582 /* if we can't send right now, mark it pending */ 06583 if (p->invitestate == INV_CALLING) { 06584 /* We can't send anything in CALLING state */ 06585 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 06586 /* Do we need a timer here if we don't hear from them at all? Yes we do or else we will get hung dialogs and those are no fun. */ 06587 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 06588 append_history(p, "DELAY", "Not sending cancel, waiting for timeout"); 06589 } else { 06590 struct sip_pkt *cur; 06591 06592 for (cur = p->packets; cur; cur = cur->next) { 06593 __sip_semi_ack(p, cur->seqno, cur->is_resp, cur->method ? cur->method : find_sip_method(ast_str_buffer(cur->data))); 06594 } 06595 p->invitestate = INV_CANCELLED; 06596 /* Send a new request: CANCEL */ 06597 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 06598 /* Actually don't destroy us yet, wait for the 487 on our original 06599 INVITE, but do set an autodestruct just in case we never get it. */ 06600 needdestroy = 0; 06601 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 06602 } 06603 } else { /* Incoming call, not up */ 06604 const char *res; 06605 AST_SCHED_DEL_UNREF(sched, p->provisional_keepalive_sched_id, dialog_unref(p, "when you delete the provisional_keepalive_sched_id, you should dec the refcount for the stored dialog ptr")); 06606 if (p->hangupcause && (res = hangup_cause2sip(p->hangupcause))) 06607 transmit_response_reliable(p, res, &p->initreq); 06608 else 06609 transmit_response_reliable(p, "603 Declined", &p->initreq); 06610 p->invitestate = INV_TERMINATED; 06611 } 06612 } else { /* Call is in UP state, send BYE */ 06613 if (p->stimer->st_active == TRUE) { 06614 stop_session_timer(p); 06615 } 06616 06617 if (!p->pendinginvite) { 06618 struct ast_channel *bridge = ast_bridged_channel(oldowner); 06619 char quality_buf[AST_MAX_USER_FIELD], *quality; 06620 06621 /* We need to get the lock on bridge because ast_rtp_instance_set_stats_vars will attempt 06622 * to lock the bridge. This may get hairy... 06623 */ 06624 while (bridge && ast_channel_trylock(bridge)) { 06625 sip_pvt_unlock(p); 06626 do { 06627 CHANNEL_DEADLOCK_AVOIDANCE(oldowner); 06628 } while (sip_pvt_trylock(p)); 06629 bridge = ast_bridged_channel(oldowner); 06630 } 06631 06632 if (p->rtp) { 06633 ast_rtp_instance_set_stats_vars(oldowner, p->rtp); 06634 } 06635 06636 if (bridge) { 06637 struct sip_pvt *q = bridge->tech_pvt; 06638 06639 if (IS_SIP_TECH(bridge->tech) && q && q->rtp) { 06640 ast_rtp_instance_set_stats_vars(bridge, q->rtp); 06641 } 06642 ast_channel_unlock(bridge); 06643 } 06644 06645 /* 06646 * The channel variables are set below just to get the AMI 06647 * VarSet event because the channel is being hungup. 06648 */ 06649 if (p->rtp && (quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) { 06650 if (p->do_history) { 06651 append_history(p, "RTCPaudio", "Quality:%s", quality); 06652 } 06653 pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", quality); 06654 } 06655 if (p->vrtp && (quality = ast_rtp_instance_get_quality(p->vrtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) { 06656 if (p->do_history) { 06657 append_history(p, "RTCPvideo", "Quality:%s", quality); 06658 } 06659 pbx_builtin_setvar_helper(oldowner, "RTPVIDEOQOS", quality); 06660 } 06661 if (p->trtp && (quality = ast_rtp_instance_get_quality(p->trtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) { 06662 if (p->do_history) { 06663 append_history(p, "RTCPtext", "Quality:%s", quality); 06664 } 06665 pbx_builtin_setvar_helper(oldowner, "RTPTEXTQOS", quality); 06666 } 06667 06668 /* Send a hangup */ 06669 if (oldowner->_state == AST_STATE_UP) { 06670 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 06671 } 06672 06673 } else { 06674 /* Note we will need a BYE when this all settles out 06675 but we can't send one while we have "INVITE" outstanding. */ 06676 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 06677 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 06678 AST_SCHED_DEL_UNREF(sched, p->waitid, dialog_unref(p, "when you delete the waitid sched, you should dec the refcount for the stored dialog ptr")); 06679 if (sip_cancel_destroy(p)) { 06680 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 06681 } 06682 /* If we have an ongoing reinvite, there is a chance that we have gotten a provisional 06683 * response, but something weird has happened and we will never receive a final response. 06684 * So, just in case, check for pending actions after a bit of time to trigger the pending 06685 * bye that we are setting above */ 06686 if (p->ongoing_reinvite && p->reinviteid < 0) { 06687 p->reinviteid = ast_sched_add(sched, 32 * p->timer_t1, reinvite_timeout, dialog_ref(p, "ref for reinvite_timeout")); 06688 } 06689 } 06690 } 06691 } 06692 if (needdestroy) { 06693 pvt_set_needdestroy(p, "hangup"); 06694 } 06695 sip_pvt_unlock(p); 06696 return 0; 06697 }
| static int sip_indicate | ( | struct ast_channel * | ast, | |
| int | condition, | |||
| const void * | data, | |||
| size_t | datalen | |||
| ) | [static] |
Play indication to user With SIP a lot of indications is sent as messages, letting the device play the indication - busy signal, congestion etc.
Definition at line 7130 of file chan_sip.c.
References ast_channel::_state, AST_AOC_D, ast_aoc_decode(), ast_aoc_destroy_decoded(), AST_AOC_E, ast_aoc_get_msg_type(), ast_aoc_get_termination_request(), AST_AOC_REQUEST, AST_AOC_S, AST_CONTROL_AOC, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_FLASH, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, AST_CONTROL_VIDUPDATE, ast_debug, ast_log(), ast_moh_start(), ast_moh_stop(), ast_rtp_instance_change_source(), ast_rtp_instance_update_source(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_UP, ast_test_flag, initialize_udptl(), interpret_t38_parameters(), LOG_ERROR, LOG_WARNING, sip_alreadygone(), sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, transmit_info_with_aoc(), transmit_info_with_vidupdate(), transmit_provisional_response(), transmit_response(), transmit_response_reliable(), TRUE, update_connectedline(), and update_redirecting().
07131 { 07132 struct sip_pvt *p = ast->tech_pvt; 07133 int res = 0; 07134 07135 if (!p) { 07136 ast_debug(1, "Asked to indicate condition on channel %s with no pvt; ignoring\n", 07137 ast->name); 07138 return res; 07139 } 07140 07141 sip_pvt_lock(p); 07142 switch(condition) { 07143 case AST_CONTROL_RINGING: 07144 if (ast->_state == AST_STATE_RING) { 07145 p->invitestate = INV_EARLY_MEDIA; 07146 if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) || 07147 (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) { 07148 /* Send 180 ringing if out-of-band seems reasonable */ 07149 transmit_provisional_response(p, "180 Ringing", &p->initreq, 0); 07150 ast_set_flag(&p->flags[0], SIP_RINGING); 07151 if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES) 07152 break; 07153 } else { 07154 /* Well, if it's not reasonable, just send in-band */ 07155 } 07156 } 07157 res = -1; 07158 break; 07159 case AST_CONTROL_BUSY: 07160 if (ast->_state != AST_STATE_UP) { 07161 transmit_response_reliable(p, "486 Busy Here", &p->initreq); 07162 p->invitestate = INV_COMPLETED; 07163 sip_alreadygone(p); 07164 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 07165 break; 07166 } 07167 res = -1; 07168 break; 07169 case AST_CONTROL_CONGESTION: 07170 if (ast->_state != AST_STATE_UP) { 07171 transmit_response_reliable(p, "503 Service Unavailable", &p->initreq); 07172 p->invitestate = INV_COMPLETED; 07173 sip_alreadygone(p); 07174 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 07175 break; 07176 } 07177 res = -1; 07178 break; 07179 case AST_CONTROL_INCOMPLETE: 07180 if (ast->_state != AST_STATE_UP) { 07181 switch (ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) { 07182 case SIP_PAGE2_ALLOWOVERLAP_YES: 07183 transmit_response_reliable(p, "484 Address Incomplete", &p->initreq); 07184 p->invitestate = INV_COMPLETED; 07185 sip_alreadygone(p); 07186 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 07187 break; 07188 case SIP_PAGE2_ALLOWOVERLAP_DTMF: 07189 /* Just wait for inband DTMF digits */ 07190 break; 07191 default: 07192 /* it actually means no support for overlap */ 07193 transmit_response_reliable(p, "404 Not Found", &p->initreq); 07194 p->invitestate = INV_COMPLETED; 07195 sip_alreadygone(p); 07196 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 07197 break; 07198 } 07199 } 07200 break; 07201 case AST_CONTROL_PROCEEDING: 07202 if ((ast->_state != AST_STATE_UP) && 07203 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 07204 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 07205 transmit_response(p, "100 Trying", &p->initreq); 07206 p->invitestate = INV_PROCEEDING; 07207 break; 07208 } 07209 res = -1; 07210 break; 07211 case AST_CONTROL_PROGRESS: 07212 if ((ast->_state != AST_STATE_UP) && 07213 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 07214 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 07215 p->invitestate = INV_EARLY_MEDIA; 07216 transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE); 07217 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 07218 break; 07219 } 07220 res = -1; 07221 break; 07222 case AST_CONTROL_HOLD: 07223 ast_rtp_instance_update_source(p->rtp); 07224 ast_moh_start(ast, data, p->mohinterpret); 07225 break; 07226 case AST_CONTROL_UNHOLD: 07227 ast_rtp_instance_update_source(p->rtp); 07228 ast_moh_stop(ast); 07229 break; 07230 case AST_CONTROL_VIDUPDATE: /* Request a video frame update */ 07231 if (p->vrtp && !p->novideo) { 07232 transmit_info_with_vidupdate(p); 07233 /* ast_rtcp_send_h261fur(p->vrtp); */ 07234 } else 07235 res = -1; 07236 break; 07237 case AST_CONTROL_T38_PARAMETERS: 07238 res = -1; 07239 if (datalen != sizeof(struct ast_control_t38_parameters)) { 07240 ast_log(LOG_ERROR, "Invalid datalen for AST_CONTROL_T38_PARAMETERS. Expected %d, got %d\n", (int) sizeof(struct ast_control_t38_parameters), (int) datalen); 07241 } else { 07242 const struct ast_control_t38_parameters *parameters = data; 07243 if (!initialize_udptl(p)) { 07244 res = interpret_t38_parameters(p, parameters); 07245 } 07246 } 07247 break; 07248 case AST_CONTROL_SRCUPDATE: 07249 ast_rtp_instance_update_source(p->rtp); 07250 break; 07251 case AST_CONTROL_SRCCHANGE: 07252 ast_rtp_instance_change_source(p->rtp); 07253 break; 07254 case AST_CONTROL_CONNECTED_LINE: 07255 update_connectedline(p, data, datalen); 07256 break; 07257 case AST_CONTROL_REDIRECTING: 07258 update_redirecting(p, data, datalen); 07259 break; 07260 case AST_CONTROL_AOC: 07261 { 07262 struct ast_aoc_decoded *decoded = ast_aoc_decode((struct ast_aoc_encoded *) data, datalen, ast); 07263 if (!decoded) { 07264 ast_log(LOG_ERROR, "Error decoding indicated AOC data\n"); 07265 res = -1; 07266 break; 07267 } 07268 switch (ast_aoc_get_msg_type(decoded)) { 07269 case AST_AOC_REQUEST: 07270 if (ast_aoc_get_termination_request(decoded)) { 07271 /* TODO, once there is a way to get AOC-E on hangup, attempt that here 07272 * before hanging up the channel.*/ 07273 07274 /* The other side has already initiated the hangup. This frame 07275 * just says they are waiting to get AOC-E before completely tearing 07276 * the call down. Since SIP does not support this at the moment go 07277 * ahead and terminate the call here to avoid an unnecessary timeout. */ 07278 ast_debug(1, "AOC-E termination request received on %s. This is not yet supported on sip. Continue with hangup \n", p->owner->name); 07279 ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV); 07280 } 07281 break; 07282 case AST_AOC_D: 07283 case AST_AOC_E: 07284 if (ast_test_flag(&p->flags[2], SIP_PAGE3_SNOM_AOC)) { 07285 transmit_info_with_aoc(p, decoded); 07286 } 07287 break; 07288 case AST_AOC_S: /* S not supported yet */ 07289 default: 07290 break; 07291 } 07292 ast_aoc_destroy_decoded(decoded); 07293 } 07294 break; 07295 case AST_CONTROL_UPDATE_RTP_PEER: /* Absorb this since it is handled by the bridge */ 07296 break; 07297 case AST_CONTROL_FLASH: /* We don't currently handle AST_CONTROL_FLASH here, but it is expected, so we don't need to warn either. */ 07298 res = -1; 07299 break; 07300 case -1: 07301 res = -1; 07302 break; 07303 default: 07304 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition); 07305 res = -1; 07306 break; 07307 } 07308 sip_pvt_unlock(p); 07309 return res; 07310 }
| static int sip_is_xml_parsable | ( | void | ) | [static] |
Definition at line 30468 of file chan_sip.c.
Referenced by load_module().
| static int sip_monitor_instance_cmp_fn | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1844 of file chan_sip.c.
References CMP_MATCH, and CMP_STOP.
Referenced by load_module().
| static void sip_monitor_instance_destructor | ( | void * | data | ) | [static] |
Definition at line 1852 of file chan_sip.c.
References ao2_t_ref, ast_string_field_free_memory, FALSE, sip_pvt_lock, sip_pvt_unlock, transmit_invite(), and transmit_publish().
Referenced by sip_monitor_instance_init().
01853 { 01854 struct sip_monitor_instance *monitor_instance = data; 01855 if (monitor_instance->subscription_pvt) { 01856 sip_pvt_lock(monitor_instance->subscription_pvt); 01857 monitor_instance->subscription_pvt->expiry = 0; 01858 transmit_invite(monitor_instance->subscription_pvt, SIP_SUBSCRIBE, FALSE, 0, monitor_instance->subscribe_uri); 01859 sip_pvt_unlock(monitor_instance->subscription_pvt); 01860 dialog_unref(monitor_instance->subscription_pvt, "Unref monitor instance ref of subscription pvt"); 01861 } 01862 if (monitor_instance->suspension_entry) { 01863 monitor_instance->suspension_entry->body[0] = '\0'; 01864 transmit_publish(monitor_instance->suspension_entry, SIP_PUBLISH_REMOVE ,monitor_instance->notify_uri); 01865 ao2_t_ref(monitor_instance->suspension_entry, -1, "Decrementing suspension entry refcount in sip_monitor_instance_destructor"); 01866 } 01867 ast_string_field_free_memory(monitor_instance); 01868 }
| static int sip_monitor_instance_hash_fn | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 1838 of file chan_sip.c.
Referenced by load_module().
| static struct sip_monitor_instance* sip_monitor_instance_init | ( | int | core_id, | |
| const char *const | subscribe_uri, | |||
| const char *const | peername, | |||
| const char *const | device_name | |||
| ) | [static, read] |
Definition at line 1870 of file chan_sip.c.
References ao2_alloc, ao2_link, ao2_ref, ast_string_field_init, ast_string_field_set, and sip_monitor_instance_destructor().
Referenced by sip_handle_cc().
01871 { 01872 struct sip_monitor_instance *monitor_instance = ao2_alloc(sizeof(*monitor_instance), sip_monitor_instance_destructor); 01873 01874 if (!monitor_instance) { 01875 return NULL; 01876 } 01877 01878 if (ast_string_field_init(monitor_instance, 256)) { 01879 ao2_ref(monitor_instance, -1); 01880 return NULL; 01881 } 01882 01883 ast_string_field_set(monitor_instance, subscribe_uri, subscribe_uri); 01884 ast_string_field_set(monitor_instance, peername, peername); 01885 ast_string_field_set(monitor_instance, device_name, device_name); 01886 monitor_instance->core_id = core_id; 01887 ao2_link(sip_monitor_instances, monitor_instance); 01888 return monitor_instance; 01889 }
| static const char * sip_nat_mode | ( | const struct sip_pvt * | p | ) | [static] |
Display SIP nat mode.
Definition at line 3396 of file chan_sip.c.
References ast_test_flag.
Referenced by check_via(), retrans_pkt(), and send_response().
03397 { 03398 return ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT) ? "NAT" : "no NAT"; 03399 }
| static struct ast_channel* sip_new | ( | struct sip_pvt * | i, | |
| int | state, | |||
| const char * | title, | |||
| const char * | linkedid | |||
| ) | [static, read] |
Initiate a call in the SIP channel.
Definition at line 7323 of file chan_sip.c.
References accountcode, ast_channel::adsicpe, ast_channel::amaflags, ast_party_caller::ani, append_history, AST_ADSI_UNAVAILABLE, ast_atomic_fetchadd_int(), ast_best_codec(), ast_channel_alloc, ast_channel_cc_params_init(), ast_channel_lock, ast_channel_set_fd(), ast_channel_unlock, ast_codec_choose(), ast_copy_string(), ast_debug, ast_exists_extension(), AST_FLAG_DISABLE_DEVSTATE_CACHE, AST_FORMAT_TEXT_MASK, AST_FORMAT_VIDEO_MASK, ast_get_encoded_str(), ast_getformatname_multiple(), ast_jb_configure(), ast_log(), ast_module_ref(), AST_RTP_DTMF_MODE_INBAND, AST_RTP_DTMF_MODE_RFC2833, ast_rtp_instance_dtmf_mode_set(), ast_rtp_instance_fd(), ast_rtp_instance_set_read_format(), ast_rtp_instance_set_write_format(), AST_STATE_RING, ast_strdup, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_fd(), ast_uri_decode(), ast_channel::caller, ast_channel::callgroup, ast_channel::context, ast_channel::dialed, enable_dsp_detect(), EVENT_FLAG_SYSTEM, ast_channel::exten, exten, ast_channel::flags, ast_party_redirecting::from, global_jbconf, ast_party_caller::id, language, LOG_WARNING, manager_event, ast_variable::name, ast_party_id::name, ast_channel::nativeformats, ast_variable::next, ast_party_dialed::number, ast_party_id::number, parkinglot, pbx_builtin_setvar_helper(), ast_channel::pickupgroup, ast_party_number::presentation, ast_party_name::presentation, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::redirecting, ast_channel::rings, sip_cfg, sip_pvt_lock, sip_pvt_unlock, sip_tech_info, ast_party_dialed::str, ast_party_number::str, ast_party_id::tag, ast_channel::tech, ast_channel::tech_pvt, text, ast_party_number::valid, ast_variable::value, and ast_channel::writeformat.
Referenced by handle_request_invite(), and sip_request_call().
07324 { 07325 struct ast_channel *tmp; 07326 struct ast_variable *v = NULL; 07327 format_t fmt; 07328 format_t what; 07329 format_t video; 07330 format_t text; 07331 format_t needvideo = 0; 07332 int needtext = 0; 07333 char buf[SIPBUFSIZE]; 07334 char *exten; 07335 07336 { 07337 const char *my_name; /* pick a good name */ 07338 07339 if (title) { 07340 my_name = title; 07341 } else { 07342 my_name = ast_strdupa(i->fromdomain); 07343 } 07344 07345 sip_pvt_unlock(i); 07346 /* Don't hold a sip pvt lock while we allocate a channel */ 07347 tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, linkedid, i->amaflags, "SIP/%s-%08x", my_name, (unsigned)ast_atomic_fetchadd_int((int *)&chan_idx, +1)); 07348 } 07349 if (!tmp) { 07350 ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n"); 07351 sip_pvt_lock(i); 07352 return NULL; 07353 } 07354 ast_channel_lock(tmp); 07355 sip_pvt_lock(i); 07356 ast_channel_cc_params_init(tmp, i->cc_params); 07357 tmp->caller.id.tag = ast_strdup(i->cid_tag); 07358 07359 tmp->tech = ( ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO || ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_SHORTINFO) ? &sip_tech_info : &sip_tech; 07360 07361 /* Select our native format based on codec preference until we receive 07362 something from another device to the contrary. */ 07363 if (i->jointcapability) { /* The joint capabilities of us and peer */ 07364 what = i->jointcapability; 07365 video = i->jointcapability & AST_FORMAT_VIDEO_MASK; 07366 text = i->jointcapability & AST_FORMAT_TEXT_MASK; 07367 } else if (i->capability) { /* Our configured capability for this peer */ 07368 what = i->capability; 07369 video = i->capability & AST_FORMAT_VIDEO_MASK; 07370 text = i->capability & AST_FORMAT_TEXT_MASK; 07371 } else { 07372 what = sip_cfg.capability; /* Global codec support */ 07373 video = sip_cfg.capability & AST_FORMAT_VIDEO_MASK; 07374 text = sip_cfg.capability & AST_FORMAT_TEXT_MASK; 07375 } 07376 07377 /* Set the native formats for audio and merge in video */ 07378 tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | video | text; 07379 ast_debug(3, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, tmp->nativeformats)); 07380 ast_debug(3, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->jointcapability)); 07381 ast_debug(3, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->capability)); 07382 ast_debug(3, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, ast_codec_choose(&i->prefs, what, 1))); 07383 if (i->prefcodec) 07384 ast_debug(3, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->prefcodec)); 07385 07386 /* XXX Why are we choosing a codec from the native formats?? */ 07387 fmt = ast_best_codec(tmp->nativeformats); 07388 07389 /* If we have a prefcodec setting, we have an inbound channel that set a 07390 preferred format for this call. Otherwise, we check the jointcapability 07391 We also check for vrtp. If it's not there, we are not allowed do any video anyway. 07392 */ 07393 if (i->vrtp) { 07394 if (ast_test_flag(&i->flags[1], SIP_PAGE2_VIDEOSUPPORT)) 07395 needvideo = AST_FORMAT_VIDEO_MASK; 07396 else if (i->prefcodec) 07397 needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK; /* Outbound call */ 07398 else 07399 needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK; /* Inbound call */ 07400 } 07401 07402 if (i->trtp) { 07403 if (i->prefcodec) 07404 needtext = i->prefcodec & AST_FORMAT_TEXT_MASK; /* Outbound call */ 07405 else 07406 needtext = i->jointcapability & AST_FORMAT_TEXT_MASK; /* Inbound call */ 07407 } 07408 07409 if (needvideo) 07410 ast_debug(3, "This channel can handle video! HOLLYWOOD next!\n"); 07411 else 07412 ast_debug(3, "This channel will not be able to handle video.\n"); 07413 07414 enable_dsp_detect(i); 07415 07416 if ((ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || 07417 (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) { 07418 if (i->rtp) { 07419 ast_rtp_instance_dtmf_mode_set(i->rtp, AST_RTP_DTMF_MODE_INBAND); 07420 } 07421 } else if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) { 07422 if (i->rtp) { 07423 ast_rtp_instance_dtmf_mode_set(i->rtp, AST_RTP_DTMF_MODE_RFC2833); 07424 } 07425 } 07426 07427 /* Set file descriptors for audio, video, and realtime text. Since 07428 * UDPTL is created as needed in the lifetime of a dialog, its file 07429 * descriptor is set in initialize_udptl */ 07430 if (i->rtp) { 07431 ast_channel_set_fd(tmp, 0, ast_rtp_instance_fd(i->rtp, 0)); 07432 ast_channel_set_fd(tmp, 1, ast_rtp_instance_fd(i->rtp, 1)); 07433 ast_rtp_instance_set_write_format(i->rtp, fmt); 07434 ast_rtp_instance_set_read_format(i->rtp, fmt); 07435 } 07436 if (needvideo && i->vrtp) { 07437 ast_channel_set_fd(tmp, 2, ast_rtp_instance_fd(i->vrtp, 0)); 07438 ast_channel_set_fd(tmp, 3, ast_rtp_instance_fd(i->vrtp, 1)); 07439 } 07440 if (needtext && i->trtp) { 07441 ast_channel_set_fd(tmp, 4, ast_rtp_instance_fd(i->trtp, 0)); 07442 } 07443 if (i->udptl) { 07444 ast_channel_set_fd(tmp, 5, ast_udptl_fd(i->udptl)); 07445 } 07446 07447 if (state == AST_STATE_RING) 07448 tmp->rings = 1; 07449 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 07450 07451 tmp->writeformat = fmt; 07452 tmp->rawwriteformat = fmt; 07453 07454 tmp->readformat = fmt; 07455 tmp->rawreadformat = fmt; 07456 07457 tmp->tech_pvt = dialog_ref(i, "sip_new: set chan->tech_pvt to i"); 07458 07459 tmp->callgroup = i->callgroup; 07460 tmp->pickupgroup = i->pickupgroup; 07461 tmp->caller.id.name.presentation = i->callingpres; 07462 tmp->caller.id.number.presentation = i->callingpres; 07463 if (!ast_strlen_zero(i->parkinglot)) 07464 ast_string_field_set(tmp, parkinglot, i->parkinglot); 07465 if (!ast_strlen_zero(i->accountcode)) 07466 ast_string_field_set(tmp, accountcode, i->accountcode); 07467 if (i->amaflags) 07468 tmp->amaflags = i->amaflags; 07469 if (!ast_strlen_zero(i->language)) 07470 ast_string_field_set(tmp, language, i->language); 07471 i->owner = tmp; 07472 ast_module_ref(ast_module_info->self); 07473 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 07474 /*Since it is valid to have extensions in the dialplan that have unescaped characters in them 07475 * we should decode the uri before storing it in the channel, but leave it encoded in the sip_pvt 07476 * structure so that there aren't issues when forming URI's 07477 */ 07478 exten = ast_strdupa(i->exten); 07479 sip_pvt_unlock(i); 07480 ast_channel_unlock(tmp); 07481 if (!ast_exists_extension(NULL, i->context, i->exten, 1, i->cid_num)) { 07482 ast_uri_decode(exten); 07483 } 07484 ast_channel_lock(tmp); 07485 sip_pvt_lock(i); 07486 ast_copy_string(tmp->exten, exten, sizeof(tmp->exten)); 07487 07488 /* Don't use ast_set_callerid() here because it will 07489 * generate an unnecessary NewCallerID event */ 07490 if (!ast_strlen_zero(i->cid_num)) { 07491 tmp->caller.ani.number.valid = 1; 07492 tmp->caller.ani.number.str = ast_strdup(i->cid_num); 07493 } 07494 if (!ast_strlen_zero(i->rdnis)) { 07495 tmp->redirecting.from.number.valid = 1; 07496 tmp->redirecting.from.number.str = ast_strdup(i->rdnis); 07497 } 07498 07499 if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) { 07500 tmp->dialed.number.str = ast_strdup(i->exten); 07501 } 07502 07503 tmp->priority = 1; 07504 if (!ast_strlen_zero(i->uri)) 07505 pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri); 07506 if (!ast_strlen_zero(i->domain)) 07507 pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain); 07508 if (!ast_strlen_zero(i->callid)) 07509 pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid); 07510 if (i->rtp) 07511 ast_jb_configure(tmp, &global_jbconf); 07512 07513 if (!i->relatedpeer) { 07514 tmp->flags |= AST_FLAG_DISABLE_DEVSTATE_CACHE; 07515 } 07516 /* Set channel variables for this call from configuration */ 07517 for (v = i->chanvars ; v ; v = v->next) { 07518 char valuebuf[1024]; 07519 pbx_builtin_setvar_helper(tmp, v->name, ast_get_encoded_str(v->value, valuebuf, sizeof(valuebuf))); 07520 } 07521 07522 if (i->do_history) 07523 append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid); 07524 07525 /* Inform manager user about new channel and their SIP call ID */ 07526 if (sip_cfg.callevents) 07527 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", 07528 "Channel: %s\r\nUniqueid: %s\r\nChanneltype: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\n", 07529 tmp->name, tmp->uniqueid, "SIP", i->callid, i->fullcontact); 07530 07531 return tmp; 07532 }
| static int sip_notify_allocate | ( | struct sip_pvt * | p | ) | [static] |
Allocate SIP refer structure.
Definition at line 13961 of file chan_sip.c.
References ast_calloc, and ast_str_create().
Referenced by manager_sipnotify(), and sip_cli_notify().
13962 { 13963 p->notify = ast_calloc(1, sizeof(struct sip_notify)); 13964 if (p->notify) { 13965 p->notify->content = ast_str_create(128); 13966 } 13967 return p->notify ? 1 : 0; 13968 }
| static int sip_offer_timer_expire | ( | const void * | data | ) | [static] |
Definition at line 1720 of file chan_sip.c.
References ast_cc_failed(), ast_cc_agent::core_id, ast_cc_agent::device_name, and ast_cc_agent::private_data.
Referenced by sip_cc_agent_start_offer_timer().
01721 { 01722 struct ast_cc_agent *agent = (struct ast_cc_agent *) data; 01723 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01724 01725 agent_pvt->offer_timer_id = -1; 01726 01727 return ast_cc_failed(agent->core_id, "SIP agent %s's offer timer expired", agent->device_name); 01728 }
| static int sip_park | ( | struct ast_channel * | chan1, | |
| struct ast_channel * | chan2, | |||
| struct sip_request * | req, | |||
| uint32_t | seqno, | |||
| const char * | park_exten, | |||
| const char * | park_context | |||
| ) | [static] |
DO NOT hold any locks while calling sip_park
Definition at line 22215 of file chan_sip.c.
References ast_channel::amaflags, ast_calloc, ast_channel_alloc, ast_channel_masquerade(), ast_copy_string(), ast_do_masquerade(), ast_free, ast_hangup(), ast_pthread_create_detached_background, AST_STATE_DOWN, ast_strdup, ast_string_field_set, ast_channel::context, copy_request(), deinit_req(), ast_channel::exten, parkinglot, ast_channel::priority, ast_channel::readformat, sip_park_thread(), and ast_channel::writeformat.
Referenced by handle_request_refer().
22216 { 22217 struct sip_dual *d; 22218 struct ast_channel *transferee, *transferer; 22219 pthread_t th; 22220 22221 transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->linkedid, chan1->amaflags, "Parking/%s", chan1->name); 22222 transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->linkedid, chan2->amaflags, "SIPPeer/%s", chan2->name); 22223 d = ast_calloc(1, sizeof(*d)); 22224 if (!transferee || !transferer || !d) { 22225 if (transferee) { 22226 ast_hangup(transferee); 22227 } 22228 if (transferer) { 22229 ast_hangup(transferer); 22230 } 22231 ast_free(d); 22232 return -1; 22233 } 22234 d->park_exten = ast_strdup(park_exten); 22235 d->park_context = ast_strdup(park_context); 22236 if (!d->park_exten || !d->park_context) { 22237 ast_hangup(transferee); 22238 ast_hangup(transferer); 22239 ast_free(d->park_exten); 22240 ast_free(d->park_context); 22241 ast_free(d); 22242 return -1; 22243 } 22244 22245 /* Make formats okay */ 22246 transferee->readformat = chan1->readformat; 22247 transferee->writeformat = chan1->writeformat; 22248 22249 /* Prepare for taking over the channel */ 22250 if (ast_channel_masquerade(transferee, chan1)) { 22251 ast_hangup(transferee); 22252 ast_hangup(transferer); 22253 ast_free(d->park_exten); 22254 ast_free(d->park_context); 22255 ast_free(d); 22256 return -1; 22257 } 22258 22259 /* Setup the extensions and such */ 22260 ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context)); 22261 ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten)); 22262 transferee->priority = chan1->priority; 22263 22264 ast_do_masquerade(transferee); 22265 22266 /* We make a clone of the peer channel too, so we can play 22267 back the announcement */ 22268 22269 /* Make formats okay */ 22270 transferer->readformat = chan2->readformat; 22271 transferer->writeformat = chan2->writeformat; 22272 ast_string_field_set(transferer, parkinglot, chan2->parkinglot); 22273 22274 /* Prepare for taking over the channel */ 22275 if (ast_channel_masquerade(transferer, chan2)) { 22276 ast_hangup(transferee); 22277 ast_hangup(transferer); 22278 ast_free(d->park_exten); 22279 ast_free(d->park_context); 22280 ast_free(d); 22281 return -1; 22282 } 22283 22284 /* Setup the extensions and such */ 22285 ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context)); 22286 ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten)); 22287 transferer->priority = chan2->priority; 22288 22289 ast_do_masquerade(transferer); 22290 22291 /* Save original request for followup */ 22292 copy_request(&d->req, req); 22293 d->chan1 = transferee; /* Transferee */ 22294 d->chan2 = transferer; /* Transferer */ 22295 d->seqno = seqno; 22296 if (ast_pthread_create_detached_background(&th, NULL, sip_park_thread, d) < 0) { 22297 /* Could not start thread */ 22298 ast_hangup(transferer); 22299 ast_hangup(transferee); 22300 deinit_req(&d->req); 22301 ast_free(d->park_exten); 22302 ast_free(d->park_context); 22303 ast_free(d); /* We don't need it anymore. If thread is created, d will be free'd 22304 by sip_park_thread() */ 22305 return -1; 22306 } 22307 return 0; 22308 }
| static void * sip_park_thread | ( | void * | stuff | ) | [static] |
Park SIP call support function Starts in a new thread, then parks the call XXX Should we add a wait period after streaming audio and before hangup?? Sometimes the audio can't be heard before hangup.
Definition at line 22164 of file chan_sip.c.
References append_history, AST_CAUSE_NORMAL_CLEARING, ast_debug, ast_free, ast_hangup(), ast_log(), AST_LOG_NOTICE, ast_park_call_exten(), ast_set_flag, deinit_req(), ext, ast_channel::hangupcause, ast_channel::tech_pvt, transmit_message_with_text(), transmit_notify_with_sipfrag(), and TRUE.
Referenced by sip_park().
22165 { 22166 struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */ 22167 struct sip_pvt *transferer_pvt; 22168 struct sip_dual *d; 22169 int ext; 22170 int res; 22171 22172 d = stuff; 22173 transferee = d->chan1; 22174 transferer = d->chan2; 22175 transferer_pvt = transferer->tech_pvt; 22176 22177 ast_debug(4, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name); 22178 22179 res = ast_park_call_exten(transferee, transferer, d->park_exten, d->park_context, 0, &ext); 22180 22181 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE 22182 if (res) { 22183 transmit_message_with_text(transferer_pvt, "Unable to park call.\n"); 22184 } else { 22185 /* Then tell the transferer what happened */ 22186 sprintf(buf, "Call parked on extension '%d'", ext); 22187 transmit_message_with_text(transferer_pvt, buf); 22188 } 22189 #endif 22190 22191 /* Any way back to the current call??? */ 22192 /* Transmit response to the REFER request */ 22193 ast_set_flag(&transferer_pvt->flags[0], SIP_DEFER_BYE_ON_TRANSFER); 22194 if (!res) { 22195 /* Transfer succeeded */ 22196 append_history(transferer_pvt, "SIPpark", "Parked call on %d", ext); 22197 transmit_notify_with_sipfrag(transferer_pvt, d->seqno, "200 OK", TRUE); 22198 transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING; 22199 ast_debug(1, "SIP Call parked on extension '%d'\n", ext); 22200 } else { 22201 transmit_notify_with_sipfrag(transferer_pvt, d->seqno, "503 Service Unavailable", TRUE); 22202 append_history(transferer_pvt, "SIPpark", "Parking failed\n"); 22203 ast_log(AST_LOG_NOTICE, "SIP Call parked failed for %s\n", transferee->name); 22204 ast_hangup(transferee); 22205 } 22206 ast_hangup(transferer); 22207 deinit_req(&d->req); 22208 ast_free(d->park_exten); 22209 ast_free(d->park_context); 22210 ast_free(d); 22211 return NULL; 22212 }
| static void sip_peer_hold | ( | struct sip_pvt * | p, | |
| int | hold | |||
| ) | [static] |
Change onhold state of a peer using a pvt structure.
Definition at line 15032 of file chan_sip.c.
References ast_atomic_fetchadd_int(), AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), AST_DEVSTATE_NOT_CACHABLE, and AST_FLAG_DISABLE_DEVSTATE_CACHE.
Referenced by change_hold_state(), and update_call_counter().
15033 { 15034 if (!p->relatedpeer) { 15035 return; 15036 } 15037 15038 /* If they put someone on hold, increment the value... otherwise decrement it */ 15039 ast_atomic_fetchadd_int(&p->relatedpeer->onHold, (hold ? +1 : -1)); 15040 15041 /* Request device state update */ 15042 ast_devstate_changed(AST_DEVICE_UNKNOWN, (p->owner->flags & AST_FLAG_DISABLE_DEVSTATE_CACHE ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE), 15043 "SIP/%s", p->relatedpeer->name); 15044 15045 return; 15046 }
| static int sip_pickup | ( | struct ast_channel * | chan | ) | [static] |
Pickup a call using the subsystem in features.c This is executed in a separate thread.
Definition at line 22333 of file chan_sip.c.
References ast_channel_ref, ast_channel_unref, ast_debug, ast_pthread_create_detached_background, and sip_pickup_thread().
Referenced by handle_request_invite().
22334 { 22335 pthread_t threadid; 22336 22337 ast_channel_ref(chan); 22338 22339 if (ast_pthread_create_detached_background(&threadid, NULL, sip_pickup_thread, chan)) { 22340 ast_debug(1, "Unable to start Group pickup thread on channel %s\n", chan->name); 22341 ast_channel_unref(chan); 22342 return -1; 22343 } 22344 ast_debug(1, "Started Group pickup thread on channel %s\n", chan->name); 22345 return 0; 22346 }
| static void * sip_pickup_thread | ( | void * | stuff | ) | [static] |
SIP pickup support function Starts in a new thread, then pickup the call.
Definition at line 22314 of file chan_sip.c.
References AST_CAUSE_CALL_REJECTED, AST_CAUSE_NORMAL_CLEARING, ast_channel_unref, ast_hangup(), ast_pickup_call(), and ast_channel::hangupcause.
Referenced by sip_pickup().
22315 { 22316 struct ast_channel *chan; 22317 chan = stuff; 22318 22319 if (ast_pickup_call(chan)) { 22320 chan->hangupcause = AST_CAUSE_CALL_REJECTED; 22321 } else { 22322 chan->hangupcause = AST_CAUSE_NORMAL_CLEARING; 22323 } 22324 ast_hangup(chan); 22325 ast_channel_unref(chan); 22326 chan = NULL; 22327 return NULL; 22328 }
| static void sip_poke_all_peers | ( | void | ) | [static] |
Send a poke to all known peers.
Definition at line 30478 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_iterator_next, ao2_unlock, AST_SCHED_REPLACE_UNREF, ref_peer(), sip_poke_peer_s(), and unref_peer().
Referenced by load_module(), and sip_do_reload().
30479 { 30480 int ms = 0, num = 0; 30481 struct ao2_iterator i; 30482 struct sip_peer *peer; 30483 30484 if (!speerobjs) { /* No peers, just give up */ 30485 return; 30486 } 30487 30488 i = ao2_iterator_init(peers, 0); 30489 while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) { 30490 ao2_lock(peer); 30491 /* Don't schedule poking on a peer without qualify */ 30492 if (peer->maxms) { 30493 if (num == global_qualify_peers) { 30494 ms += global_qualify_gap; 30495 num = 0; 30496 } else { 30497 num++; 30498 } 30499 AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, ms, sip_poke_peer_s, peer, 30500 unref_peer(_data, "removing poke peer ref"), 30501 unref_peer(peer, "removing poke peer ref"), 30502 ref_peer(peer, "adding poke peer ref")); 30503 } 30504 ao2_unlock(peer); 30505 unref_peer(peer, "toss iterator peer ptr"); 30506 } 30507 ao2_iterator_destroy(&i); 30508 }
| static int sip_poke_noanswer | ( | const void * | data | ) | [static] |
React to lack of answer to Qualify poke.
Definition at line 27065 of file chan_sip.c.
References ast_check_realtime(), AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_log(), AST_SCHED_REPLACE_UNREF, ast_update_realtime(), DEFAULT_FREQ_NOTOK, dialog_unlink_all(), EVENT_FLAG_SYSTEM, FALSE, LOG_NOTICE, manager_event, ref_peer(), register_peer_exten(), SENTINEL, sip_cfg, sip_poke_peer_s(), and unref_peer().
Referenced by sip_poke_peer(), and sip_show_sched().
27066 { 27067 struct sip_peer *peer = (struct sip_peer *)data; 27068 27069 peer->pokeexpire = -1; 27070 27071 if (peer->lastms > -1) { 27072 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms); 27073 if (sip_cfg.peer_rtupdate) { 27074 ast_update_realtime(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", "name", peer->name, "lastms", "-1", SENTINEL); 27075 } 27076 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1); 27077 if (sip_cfg.regextenonqualify) { 27078 register_peer_exten(peer, FALSE); 27079 } 27080 } 27081 27082 if (peer->call) { 27083 dialog_unlink_all(peer->call); 27084 peer->call = dialog_unref(peer->call, "unref dialog peer->call"); 27085 /* peer->call = sip_destroy(peer->call);*/ 27086 } 27087 27088 /* Don't send a devstate change if nothing changed. */ 27089 if (peer->lastms > -1) { 27090 peer->lastms = -1; 27091 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", peer->name); 27092 } 27093 27094 /* Try again quickly */ 27095 AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, 27096 DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer, 27097 unref_peer(_data, "removing poke peer ref"), 27098 unref_peer(peer, "removing poke peer ref"), 27099 ref_peer(peer, "adding poke peer ref")); 27100 27101 /* Release the ref held by the running scheduler entry */ 27102 unref_peer(peer, "release peer poke noanswer ref"); 27103 27104 return 0; 27105 }
| static int sip_poke_peer | ( | struct sip_peer * | peer, | |
| int | force | |||
| ) | [static] |
Check availability of peer, also keep NAT open.
Definition at line 27115 of file chan_sip.c.
References ast_copy_flags, ast_copy_string(), ast_log(), AST_SCHED_DEL_UNREF, AST_SCHED_REPLACE_UNREF, ast_set_flag, ast_sip_ouraddrfor(), ast_sockaddr_isnull(), ast_sockaddr_stringify_host_remote(), ast_string_field_set, ast_strlen_zero(), ast_tvnow(), build_via(), change_callid_pvt(), copy_socket_data(), dialog_unlink_all(), LOG_NOTICE, obproxy_get(), ref_peer(), ref_proxy(), sip_alloc(), sip_poke_noanswer(), transmit_invite(), and unref_peer().
Referenced by _sip_qualify_peer(), build_peer(), parse_register_contact(), and sip_poke_peer_s().
27116 { 27117 struct sip_pvt *p; 27118 int xmitres = 0; 27119 27120 if ((!peer->maxms && !force) || ast_sockaddr_isnull(&peer->addr)) { 27121 /* IF we have no IP, or this isn't to be monitored, return 27122 immediately after clearing things out */ 27123 AST_SCHED_DEL_UNREF(sched, peer->pokeexpire, 27124 unref_peer(peer, "removing poke peer ref")); 27125 27126 peer->lastms = 0; 27127 if (peer->call) { 27128 peer->call = dialog_unref(peer->call, "unref dialog peer->call"); 27129 } 27130 return 0; 27131 } 27132 if (peer->call) { 27133 if (sipdebug) { 27134 ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n"); 27135 } 27136 dialog_unlink_all(peer->call); 27137 peer->call = dialog_unref(peer->call, "unref dialog peer->call"); 27138 /* peer->call = sip_destroy(peer->call); */ 27139 } 27140 if (!(p = sip_alloc(NULL, NULL, 0, SIP_OPTIONS, NULL))) { 27141 return -1; 27142 } 27143 peer->call = dialog_ref(p, "copy sip alloc from p to peer->call"); 27144 27145 p->sa = peer->addr; 27146 p->recv = peer->addr; 27147 copy_socket_data(&p->socket, &peer->socket); 27148 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 27149 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 27150 ast_copy_flags(&p->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY); 27151 27152 /* Get the outbound proxy information */ 27153 ref_proxy(p, obproxy_get(p, peer)); 27154 27155 /* Send OPTIONs to peer's fullcontact */ 27156 if (!ast_strlen_zero(peer->fullcontact)) { 27157 ast_string_field_set(p, fullcontact, peer->fullcontact); 27158 } 27159 27160 if (!ast_strlen_zero(peer->fromuser)) { 27161 ast_string_field_set(p, fromuser, peer->fromuser); 27162 } 27163 27164 if (!ast_strlen_zero(peer->tohost)) { 27165 ast_string_field_set(p, tohost, peer->tohost); 27166 } else { 27167 ast_string_field_set(p, tohost, ast_sockaddr_stringify_host_remote(&peer->addr)); 27168 } 27169 27170 /* Recalculate our side, and recalculate Call ID */ 27171 ast_sip_ouraddrfor(&p->sa, &p->ourip, p); 27172 build_via(p); 27173 27174 /* Change the dialog callid. */ 27175 change_callid_pvt(p, NULL); 27176 27177 AST_SCHED_DEL_UNREF(sched, peer->pokeexpire, 27178 unref_peer(peer, "removing poke peer ref")); 27179 27180 if (p->relatedpeer) 27181 p->relatedpeer = unref_peer(p->relatedpeer,"unsetting the relatedpeer field in the dialog, before it is set to something else."); 27182 p->relatedpeer = ref_peer(peer, "setting the relatedpeer field in the dialog"); 27183 ast_set_flag(&p->flags[0], SIP_OUTGOING); 27184 #ifdef VOCAL_DATA_HACK 27185 ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username)); 27186 xmitres = transmit_invite(p, SIP_INVITE, 0, 2, NULL); /* sinks the p refcount */ 27187 #else 27188 xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2, NULL); /* sinks the p refcount */ 27189 #endif 27190 peer->ps = ast_tvnow(); 27191 if (xmitres == XMIT_ERROR) { 27192 /* Immediately unreachable, network problems */ 27193 sip_poke_noanswer(ref_peer(peer, "add ref for peerexpire (fake, for sip_poke_noanswer to remove)")); 27194 } else if (!force) { 27195 AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, peer->maxms * 2, sip_poke_noanswer, peer, 27196 unref_peer(_data, "removing poke peer ref"), 27197 unref_peer(peer, "removing poke peer ref"), 27198 ref_peer(peer, "adding poke peer ref")); 27199 } 27200 dialog_unref(p, "unref dialog at end of sip_poke_peer, obtained from sip_alloc, just before it goes out of scope"); 27201 return 0; 27202 }
| static int sip_poke_peer_s | ( | const void * | data | ) | [static] |
Poke peer (send qualify to check if peer is alive and well).
Definition at line 14267 of file chan_sip.c.
References ao2_find, OBJ_POINTER, sip_poke_peer(), and unref_peer().
Referenced by handle_response_peerpoke(), reg_source_db(), sip_poke_all_peers(), sip_poke_noanswer(), and sip_show_sched().
14268 { 14269 struct sip_peer *peer = (struct sip_peer *)data; 14270 struct sip_peer *foundpeer; 14271 14272 peer->pokeexpire = -1; 14273 14274 foundpeer = ao2_find(peers, peer, OBJ_POINTER); 14275 if (!foundpeer) { 14276 unref_peer(peer, "removing poke peer ref"); 14277 return 0; 14278 } else if (foundpeer->name != peer->name) { 14279 unref_peer(foundpeer, "removing above peer ref"); 14280 unref_peer(peer, "removing poke peer ref"); 14281 return 0; 14282 } 14283 14284 unref_peer(foundpeer, "removing above peer ref"); 14285 sip_poke_peer(peer, 0); 14286 unref_peer(peer, "removing poke peer ref"); 14287 14288 return 0; 14289 }
| static int sip_prepare_socket | ( | struct sip_pvt * | p | ) | [static] |
Definition at line 26308 of file chan_sip.c.
References ast_tcptls_session_args::accept_fd, ao2_alloc, ao2_ref, ao2_t_ref, ao2_t_unlink, ast_calloc, ast_copy_string(), ast_debug, ast_pthread_create_detached_background, ast_sockaddr_copy(), ast_strdup, ast_strlen_zero(), ast_tcptls_client_create(), ast_tcptls_close_session_file(), ast_tls_config::cafile, ast_tls_config::capath, ast_tls_config::certfile, ast_tls_config::cipher, ast_tcptls_session_instance::fd, ast_tcptls_session_args::hostname, ast_tcptls_session_args::name, name, ast_tls_config::pvtfile, ast_tcptls_session_args::remote_address, sip_real_dst(), sip_tcp_locate(), sip_tcp_worker_fn(), sip_tcptls_client_args_destructor(), sip_threadinfo_create(), and ast_tcptls_session_args::tls_cfg.
Referenced by __sip_xmit().
26309 { 26310 struct sip_socket *s = &p->socket; 26311 static const char name[] = "SIP socket"; 26312 struct sip_threadinfo *th = NULL; 26313 struct ast_tcptls_session_instance *tcptls_session; 26314 struct ast_tcptls_session_args *ca; 26315 struct ast_sockaddr sa_tmp; 26316 pthread_t launched; 26317 26318 /* check to see if a socket is already active */ 26319 if ((s->fd != -1) && (s->type == SIP_TRANSPORT_UDP)) { 26320 return s->fd; 26321 } 26322 if ((s->type & (SIP_TRANSPORT_TCP | SIP_TRANSPORT_TLS)) && 26323 (s->tcptls_session) && 26324 (s->tcptls_session->fd != -1)) { 26325 return s->tcptls_session->fd; 26326 } 26327 26328 /*! \todo Check this... This might be wrong, depending on the proxy configuration 26329 If proxy is in "force" mode its correct. 26330 */ 26331 if (p->outboundproxy && p->outboundproxy->transport) { 26332 s->type = p->outboundproxy->transport; 26333 } 26334 26335 if (s->type == SIP_TRANSPORT_UDP) { 26336 s->fd = sipsock; 26337 return s->fd; 26338 } 26339 26340 /* At this point we are dealing with a TCP/TLS connection 26341 * 1. We need to check to see if a connection thread exists 26342 * for this address, if so use that. 26343 * 2. If a thread does not exist for this address, but the tcptls_session 26344 * exists on the socket, the connection was closed. 26345 * 3. If no tcptls_session thread exists for the address, and no tcptls_session 26346 * already exists on the socket, create a new one and launch a new thread. 26347 */ 26348 26349 /* 1. check for existing threads */ 26350 ast_sockaddr_copy(&sa_tmp, sip_real_dst(p)); 26351 if ((tcptls_session = sip_tcp_locate(&sa_tmp))) { 26352 s->fd = tcptls_session->fd; 26353 if (s->tcptls_session) { 26354 ao2_ref(s->tcptls_session, -1); 26355 s->tcptls_session = NULL; 26356 } 26357 s->tcptls_session = tcptls_session; 26358 return s->fd; 26359 /* 2. Thread not found, if tcptls_session already exists, it once had a thread and is now terminated */ 26360 } else if (s->tcptls_session) { 26361 return s->fd; /* XXX whether reconnection is ever necessary here needs to be investigated further */ 26362 } 26363 26364 /* 3. Create a new TCP/TLS client connection */ 26365 /* create new session arguments for the client connection */ 26366 if (!(ca = ao2_alloc(sizeof(*ca), sip_tcptls_client_args_destructor)) || 26367 !(ca->name = ast_strdup(name))) { 26368 goto create_tcptls_session_fail; 26369 } 26370 ca->accept_fd = -1; 26371 ast_sockaddr_copy(&ca->remote_address,sip_real_dst(p)); 26372 /* if type is TLS, we need to create a tls cfg for this session arg */ 26373 if (s->type == SIP_TRANSPORT_TLS) { 26374 if (!(ca->tls_cfg = ast_calloc(1, sizeof(*ca->tls_cfg)))) { 26375 goto create_tcptls_session_fail; 26376 } 26377 memcpy(ca->tls_cfg, &default_tls_cfg, sizeof(*ca->tls_cfg)); 26378 26379 if (!(ca->tls_cfg->certfile = ast_strdup(default_tls_cfg.certfile)) || 26380 !(ca->tls_cfg->pvtfile = ast_strdup(default_tls_cfg.pvtfile)) || 26381 !(ca->tls_cfg->cipher = ast_strdup(default_tls_cfg.cipher)) || 26382 !(ca->tls_cfg->cafile = ast_strdup(default_tls_cfg.cafile)) || 26383 !(ca->tls_cfg->capath = ast_strdup(default_tls_cfg.capath))) { 26384 26385 goto create_tcptls_session_fail; 26386 } 26387 26388 /* this host is used as the common name in ssl/tls */ 26389 if (!ast_strlen_zero(p->tohost)) { 26390 ast_copy_string(ca->hostname, p->tohost, sizeof(ca->hostname)); 26391 } 26392 } 26393 26394 /* Create a client connection for address, this does not start the connection, just sets it up. */ 26395 if (!(s->tcptls_session = ast_tcptls_client_create(ca))) { 26396 goto create_tcptls_session_fail; 26397 } 26398 26399 s->fd = s->tcptls_session->fd; 26400 26401 /* client connections need to have the sip_threadinfo object created before 26402 * the thread is detached. This ensures the alert_pipe is up before it will 26403 * be used. Note that this function links the new threadinfo object into the 26404 * threadt container. */ 26405 if (!(th = sip_threadinfo_create(s->tcptls_session, s->type))) { 26406 goto create_tcptls_session_fail; 26407 } 26408 26409 /* Give the new thread a reference to the tcptls_session */ 26410 ao2_ref(s->tcptls_session, +1); 26411 26412 if (ast_pthread_create_detached_background(&launched, NULL, sip_tcp_worker_fn, s->tcptls_session)) { 26413 ast_debug(1, "Unable to launch '%s'.", ca->name); 26414 ao2_ref(s->tcptls_session, -1); /* take away the thread ref we just gave it */ 26415 goto create_tcptls_session_fail; 26416 } 26417 26418 return s->fd; 26419 26420 create_tcptls_session_fail: 26421 if (ca) { 26422 ao2_t_ref(ca, -1, "failed to create client, getting rid of client tcptls_session arguments"); 26423 } 26424 if (s->tcptls_session) { 26425 ast_tcptls_close_session_file(s->tcptls_session); 26426 s->fd = -1; 26427 ao2_ref(s->tcptls_session, -1); 26428 s->tcptls_session = NULL; 26429 } 26430 if (th) { 26431 ao2_t_unlink(threadt, th, "Removing tcptls thread info object, thread failed to open"); 26432 } 26433 26434 return -1; 26435 }
| static char * sip_prune_realtime | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Remove temporary realtime objects from memory (CLI).
Definition at line 17733 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_find, ao2_t_iterator_next, ao2_t_link, ao2_t_unlink, ao2_unlock, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_cli_complete(), ast_copy_string(), ast_sockaddr_isnull(), ast_test_flag, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sip_peer(), FALSE, ast_cli_args::fd, ast_cli_args::n, name, OBJ_POINTER, OBJ_UNLINK, ast_cli_args::pos, TRUE, unlink_marked_peers_from_tables(), unref_peer(), ast_cli_entry::usage, and ast_cli_args::word.
17734 { 17735 struct sip_peer *peer, *pi; 17736 int prunepeer = FALSE; 17737 int multi = FALSE; 17738 const char *name = NULL; 17739 regex_t regexbuf; 17740 int havepattern = 0; 17741 struct ao2_iterator i; 17742 static const char * const choices[] = { "all", "like", NULL }; 17743 char *cmplt; 17744 17745 if (cmd == CLI_INIT) { 17746 e->command = "sip prune realtime [peer|all]"; 17747 e->usage = 17748 "Usage: sip prune realtime [peer [<name>|all|like <pattern>]|all]\n" 17749 " Prunes object(s) from the cache.\n" 17750 " Optional regular expression pattern is used to filter the objects.\n"; 17751 return NULL; 17752 } else if (cmd == CLI_GENERATE) { 17753 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer")) { 17754 cmplt = ast_cli_complete(a->word, choices, a->n); 17755 if (!cmplt) 17756 cmplt = complete_sip_peer(a->word, a->n - sizeof(choices), SIP_PAGE2_RTCACHEFRIENDS); 17757 return cmplt; 17758 } 17759 if (a->pos == 5 && !strcasecmp(a->argv[4], "like")) 17760 return complete_sip_peer(a->word, a->n, SIP_PAGE2_RTCACHEFRIENDS); 17761 return NULL; 17762 } 17763 switch (a->argc) { 17764 case 4: 17765 name = a->argv[3]; 17766 /* we accept a name in position 3, but keywords are not good. */ 17767 if (!strcasecmp(name, "peer") || !strcasecmp(name, "like")) 17768 return CLI_SHOWUSAGE; 17769 prunepeer = TRUE; 17770 if (!strcasecmp(name, "all")) { 17771 multi = TRUE; 17772 name = NULL; 17773 } 17774 /* else a single name, already set */ 17775 break; 17776 case 5: 17777 /* sip prune realtime {peer|like} name */ 17778 name = a->argv[4]; 17779 if (!strcasecmp(a->argv[3], "peer")) 17780 prunepeer = TRUE; 17781 else if (!strcasecmp(a->argv[3], "like")) { 17782 prunepeer = TRUE; 17783 multi = TRUE; 17784 } else 17785 return CLI_SHOWUSAGE; 17786 if (!strcasecmp(name, "like")) 17787 return CLI_SHOWUSAGE; 17788 if (!multi && !strcasecmp(name, "all")) { 17789 multi = TRUE; 17790 name = NULL; 17791 } 17792 break; 17793 case 6: 17794 name = a->argv[5]; 17795 multi = TRUE; 17796 /* sip prune realtime {peer} like name */ 17797 if (strcasecmp(a->argv[4], "like")) 17798 return CLI_SHOWUSAGE; 17799 if (!strcasecmp(a->argv[3], "peer")) { 17800 prunepeer = TRUE; 17801 } else 17802 return CLI_SHOWUSAGE; 17803 break; 17804 default: 17805 return CLI_SHOWUSAGE; 17806 } 17807 17808 if (multi && name) { 17809 if (regcomp(®exbuf, name, REG_EXTENDED | REG_NOSUB)) { 17810 return CLI_SHOWUSAGE; 17811 } 17812 havepattern = 1; 17813 } 17814 17815 if (multi) { 17816 if (prunepeer) { 17817 int pruned = 0; 17818 17819 i = ao2_iterator_init(peers, 0); 17820 while ((pi = ao2_t_iterator_next(&i, "iterate thru peers table"))) { 17821 ao2_lock(pi); 17822 if (name && regexec(®exbuf, pi->name, 0, NULL, 0)) { 17823 ao2_unlock(pi); 17824 unref_peer(pi, "toss iterator peer ptr before continue"); 17825 continue; 17826 }; 17827 if (ast_test_flag(&pi->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 17828 pi->the_mark = 1; 17829 pruned++; 17830 } 17831 ao2_unlock(pi); 17832 unref_peer(pi, "toss iterator peer ptr"); 17833 } 17834 ao2_iterator_destroy(&i); 17835 if (pruned) { 17836 unlink_marked_peers_from_tables(); 17837 ast_cli(a->fd, "%d peers pruned.\n", pruned); 17838 } else 17839 ast_cli(a->fd, "No peers found to prune.\n"); 17840 } 17841 } else { 17842 if (prunepeer) { 17843 struct sip_peer tmp; 17844 ast_copy_string(tmp.name, name, sizeof(tmp.name)); 17845 if ((peer = ao2_t_find(peers, &tmp, OBJ_POINTER | OBJ_UNLINK, "finding to unlink from peers"))) { 17846 if (!ast_sockaddr_isnull(&peer->addr)) { 17847 ao2_t_unlink(peers_by_ip, peer, "unlinking peer from peers_by_ip also"); 17848 } 17849 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 17850 ast_cli(a->fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name); 17851 /* put it back! */ 17852 ao2_t_link(peers, peer, "link peer into peer table"); 17853 if (!ast_sockaddr_isnull(&peer->addr)) { 17854 ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table"); 17855 } 17856 } else 17857 ast_cli(a->fd, "Peer '%s' pruned.\n", name); 17858 unref_peer(peer, "sip_prune_realtime: unref_peer: tossing temp peer ptr"); 17859 } else 17860 ast_cli(a->fd, "Peer '%s' not found.\n", name); 17861 } 17862 } 17863 17864 if (havepattern) { 17865 regfree(®exbuf); 17866 } 17867 17868 return CLI_SUCCESS; 17869 }
| static struct ast_channel * sip_pvt_lock_full | ( | struct sip_pvt * | pvt | ) | [static, read] |
Definition at line 8328 of file chan_sip.c.
References ast_channel_lock, ast_channel_ref, ast_channel_unlock, ast_channel_unref, sip_pvt_lock, and sip_pvt_unlock.
Referenced by __sip_autodestruct(), dialog_unlink_all(), handle_request_do(), reinvite_timeout(), send_provisional_keepalive_full(), and sip_queue_hangup_cause().
08329 { 08330 struct ast_channel *chan; 08331 08332 /* Locking is simple when it is done right. If you see a deadlock resulting 08333 * in this function, it is not this function's fault, Your problem exists elsewhere. 08334 * This function is perfect... seriously. */ 08335 for (;;) { 08336 /* First, get the channel and grab a reference to it */ 08337 sip_pvt_lock(pvt); 08338 chan = pvt->owner; 08339 if (chan) { 08340 /* The channel can not go away while we hold the pvt lock. 08341 * Give the channel a ref so it will not go away after we let 08342 * the pvt lock go. */ 08343 ast_channel_ref(chan); 08344 } else { 08345 /* no channel, return pvt locked */ 08346 return NULL; 08347 } 08348 08349 /* We had to hold the pvt lock while getting a ref to the owner channel 08350 * but now we have to let this lock go in order to preserve proper 08351 * locking order when grabbing the channel lock */ 08352 sip_pvt_unlock(pvt); 08353 08354 /* Look, no deadlock avoidance, hooray! */ 08355 ast_channel_lock(chan); 08356 sip_pvt_lock(pvt); 08357 08358 if (pvt->owner == chan) { 08359 /* done */ 08360 break; 08361 } 08362 08363 /* If the owner changed while everything was unlocked, no problem, 08364 * just start over and everthing will work. This is rare, do not be 08365 * confused by this loop and think this it is an expensive operation. 08366 * The majority of the calls to this function will never involve multiple 08367 * executions of this loop. */ 08368 ast_channel_unlock(chan); 08369 ast_channel_unref(chan); 08370 sip_pvt_unlock(pvt); 08371 } 08372 08373 /* If owner exists, it is locked and reffed */ 08374 return pvt->owner; 08375 }
| static char * sip_qualify_peer | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Send an OPTIONS packet to a SIP peer.
Definition at line 18018 of file chan_sip.c.
References _sip_qualify_peer(), ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, complete_sip_show_peer(), ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.
18019 { 18020 switch (cmd) { 18021 case CLI_INIT: 18022 e->command = "sip qualify peer"; 18023 e->usage = 18024 "Usage: sip qualify peer <name> [load]\n" 18025 " Requests a response from one SIP peer and the current status.\n" 18026 " Option \"load\" forces lookup of peer in realtime storage.\n"; 18027 return NULL; 18028 case CLI_GENERATE: 18029 return complete_sip_show_peer(a->line, a->word, a->pos, a->n); 18030 } 18031 return _sip_qualify_peer(0, a->fd, NULL, NULL, a->argc, (const char **) a->argv); 18032 }
| static int sip_queryoption | ( | struct ast_channel * | chan, | |
| int | option, | |||
| void * | data, | |||
| int * | datalen | |||
| ) | [static] |
Query an option on a SIP dialog.
Definition at line 4554 of file chan_sip.c.
References ast_copy_string(), ast_debug, ast_log(), AST_OPTION_DEVICE_NAME, AST_OPTION_DIGIT_DETECT, AST_OPTION_SECURE_MEDIA, AST_OPTION_SECURE_SIGNALING, AST_OPTION_T38_STATE, ast_test_flag, LOG_ERROR, sip_pvt_lock, sip_pvt_unlock, T38_STATE_NEGOTIATED, T38_STATE_NEGOTIATING, T38_STATE_UNAVAILABLE, T38_STATE_UNKNOWN, and ast_channel::tech_pvt.
04555 { 04556 int res = -1; 04557 enum ast_t38_state state = T38_STATE_UNAVAILABLE; 04558 struct sip_pvt *p = (struct sip_pvt *) chan->tech_pvt; 04559 char *cp; 04560 04561 sip_pvt_lock(p); 04562 04563 switch (option) { 04564 case AST_OPTION_T38_STATE: 04565 /* Make sure we got an ast_t38_state enum passed in */ 04566 if (*datalen != sizeof(enum ast_t38_state)) { 04567 ast_log(LOG_ERROR, "Invalid datalen for AST_OPTION_T38_STATE option. Expected %d, got %d\n", (int)sizeof(enum ast_t38_state), *datalen); 04568 break; 04569 } 04570 04571 /* Now if T38 support is enabled we need to look and see what the current state is to get what we want to report back */ 04572 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) { 04573 switch (p->t38.state) { 04574 case T38_LOCAL_REINVITE: 04575 case T38_PEER_REINVITE: 04576 state = T38_STATE_NEGOTIATING; 04577 break; 04578 case T38_ENABLED: 04579 state = T38_STATE_NEGOTIATED; 04580 break; 04581 default: 04582 state = T38_STATE_UNKNOWN; 04583 } 04584 } 04585 04586 *((enum ast_t38_state *) data) = state; 04587 res = 0; 04588 04589 break; 04590 case AST_OPTION_DIGIT_DETECT: 04591 cp = (char *) data; 04592 *cp = p->dsp ? 1 : 0; 04593 ast_debug(1, "Reporting digit detection %sabled on %s\n", *cp ? "en" : "dis", chan->name); 04594 break; 04595 case AST_OPTION_SECURE_SIGNALING: 04596 *((unsigned int *) data) = p->req_secure_signaling; 04597 res = 0; 04598 break; 04599 case AST_OPTION_SECURE_MEDIA: 04600 *((unsigned int *) data) = ast_test_flag(&p->flags[1], SIP_PAGE2_USE_SRTP) ? 1 : 0; 04601 res = 0; 04602 break; 04603 case AST_OPTION_DEVICE_NAME: 04604 if (p && p->outgoing_call) { 04605 cp = (char *) data; 04606 ast_copy_string(cp, p->dialstring, *datalen); 04607 res = 0; 04608 } 04609 /* We purposely break with a return of -1 in the 04610 * implied else case here 04611 */ 04612 break; 04613 default: 04614 break; 04615 } 04616 04617 sip_pvt_unlock(p); 04618 04619 return res; 04620 }
| static void sip_queue_hangup_cause | ( | struct sip_pvt * | p, | |
| int | cause | |||
| ) | [static] |
Definition at line 20667 of file chan_sip.c.
References ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_queue_hangup(), ast_queue_hangup_with_cause(), ast_set_hangupsource(), ast_strdupa, name, sip_pvt_lock_full(), and sip_pvt_unlock.
Referenced by handle_request_bye(), handle_request_cancel(), and handle_response_invite().
20668 { 20669 struct ast_channel *owner = p->owner; 20670 const char *name = ast_strdupa(owner->name); 20671 20672 /* Cannot hold any channel/private locks when calling. */ 20673 ast_channel_ref(owner); 20674 ast_channel_unlock(owner); 20675 sip_pvt_unlock(p); 20676 ast_set_hangupsource(owner, name, 0); 20677 if (cause) { 20678 ast_queue_hangup_with_cause(owner, cause); 20679 } else { 20680 ast_queue_hangup(owner); 20681 } 20682 ast_channel_unref(owner); 20683 20684 /* Relock things. */ 20685 owner = sip_pvt_lock_full(p); 20686 if (owner) { 20687 ast_channel_unref(owner); 20688 } 20689 }
| static struct ast_frame * sip_read | ( | struct ast_channel * | ast | ) | [static, read] |
Read SIP RTP from channel.
Definition at line 7782 of file chan_sip.c.
References ast_channel::_state, ast_async_goto(), ast_channel_lock, ast_channel_unlock, ast_exists_extension(), AST_FRAME_VOICE, ast_frfree, ast_log(), ast_null_frame, AST_STATE_UP, ast_test_flag, ast_verbose, ast_channel::caller, ast_channel::context, ast_channel::exten, FALSE, ast_frame::frametype, ast_party_caller::id, LOG_NOTICE, ast_channel::macrocontext, ast_party_id::number, pbx_builtin_setvar_helper(), S_COR, S_OR, sip_pvt_lock, sip_pvt_unlock, sip_rtp_read(), ast_party_number::str, ast_channel::tech_pvt, ast_party_number::valid, and VERBOSE_PREFIX_2.
07783 { 07784 struct ast_frame *fr; 07785 struct sip_pvt *p = ast->tech_pvt; 07786 int faxdetected = FALSE; 07787 07788 sip_pvt_lock(p); 07789 fr = sip_rtp_read(ast, p, &faxdetected); 07790 p->lastrtprx = time(NULL); 07791 07792 /* If we detect a CNG tone and fax detection is enabled then send us off to the fax extension */ 07793 if (faxdetected && ast_test_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_CNG)) { 07794 if (strcmp(ast->exten, "fax")) { 07795 const char *target_context = S_OR(ast->macrocontext, ast->context); 07796 /* We need to unlock 'ast' here because 07797 * ast_exists_extension has the potential to start and 07798 * stop an autoservice on the channel. Such action is 07799 * prone to deadlock if the channel is locked. 07800 */ 07801 sip_pvt_unlock(p); 07802 ast_channel_unlock(ast); 07803 if (ast_exists_extension(ast, target_context, "fax", 1, 07804 S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, NULL))) { 07805 ast_channel_lock(ast); 07806 sip_pvt_lock(p); 07807 ast_verbose(VERBOSE_PREFIX_2 "Redirecting '%s' to fax extension due to CNG detection\n", ast->name); 07808 pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten); 07809 if (ast_async_goto(ast, target_context, "fax", 1)) { 07810 ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context); 07811 } 07812 ast_frfree(fr); 07813 fr = &ast_null_frame; 07814 } else { 07815 ast_channel_lock(ast); 07816 sip_pvt_lock(p); 07817 ast_log(LOG_NOTICE, "FAX CNG detected but no fax extension\n"); 07818 } 07819 } 07820 } 07821 07822 /* Only allow audio through if they sent progress with SDP, or if the channel is actually answered */ 07823 if (fr && fr->frametype == AST_FRAME_VOICE && p->invitestate != INV_EARLY_MEDIA && ast->_state != AST_STATE_UP) { 07824 ast_frfree(fr); 07825 fr = &ast_null_frame; 07826 } 07827 07828 sip_pvt_unlock(p); 07829 07830 return fr; 07831 }
| static struct ast_sockaddr * sip_real_dst | ( | const struct sip_pvt * | p | ) | [static, read] |
The real destination address for a write.
Definition at line 3386 of file chan_sip.c.
References ast_test_flag.
Referenced by __sip_xmit(), check_via(), retrans_pkt(), send_response(), show_channels_cb(), sip_debug_test_pvt(), and sip_prepare_socket().
03387 { 03388 if (p->outboundproxy) { 03389 return &p->outboundproxy->ip; 03390 } 03391 03392 return ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT) || ast_test_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT) ? &p->recv : &p->sa; 03393 }
| static const char* sip_reason_code_to_str | ( | enum AST_REDIRECTING_REASON | code | ) | [static] |
Definition at line 2286 of file chan_sip.c.
References ARRAY_LEN, sip_reason_table, and sip_reasons::text.
Referenced by add_diversion_header().
02287 { 02288 if (code >= 0 && code < ARRAY_LEN(sip_reason_table)) { 02289 return sip_reason_table[code].text; 02290 } 02291 02292 return "unknown"; 02293 }
| static enum AST_REDIRECTING_REASON sip_reason_str_to_code | ( | const char * | text | ) | [static] |
Definition at line 2271 of file chan_sip.c.
References ARRAY_LEN, AST_REDIRECTING_REASON_UNKNOWN, sip_reasons::code, and sip_reason_table.
Referenced by get_rdnis().
02272 { 02273 enum AST_REDIRECTING_REASON ast = AST_REDIRECTING_REASON_UNKNOWN; 02274 int i; 02275 02276 for (i = 0; i < ARRAY_LEN(sip_reason_table); ++i) { 02277 if (!strcasecmp(text, sip_reason_table[i].text)) { 02278 ast = sip_reason_table[i].code; 02279 break; 02280 } 02281 } 02282 02283 return ast; 02284 }
| static int sip_refer_allocate | ( | struct sip_pvt * | p | ) | [static] |
Allocate SIP refer structure.
Definition at line 13954 of file chan_sip.c.
References ast_calloc.
Referenced by get_also_info(), handle_request_invite(), handle_request_refer(), and transmit_refer().
13955 { 13956 p->refer = ast_calloc(1, sizeof(struct sip_refer)); 13957 return p->refer ? 1 : 0; 13958 }
| static int sip_reg_timeout | ( | const void * | data | ) | [static] |
Registration timeout, register again Registered as a timeout handler during transmit_register(), to retransmit the packet if a reply does not come back. This is called by the scheduler so the event is not pending anymore when we are called.
Definition at line 13612 of file chan_sip.c.
References __sip_pretend_ack(), ast_dnsmgr_refresh(), ast_log(), EVENT_FLAG_SYSTEM, LOG_NOTICE, manager_event, pvt_set_needdestroy(), REG_STATE_UNREGISTERED, registry_unref(), regstate2str(), sip_pvt_lock, sip_pvt_unlock, and transmit_register().
Referenced by sip_show_sched(), and transmit_register().
13613 { 13614 13615 /* if we are here, our registration timed out, so we'll just do it over */ 13616 struct sip_registry *r = (struct sip_registry *)data; /* the ref count should have been bumped when the sched item was added */ 13617 struct sip_pvt *p; 13618 13619 /* if we couldn't get a reference to the registry object, punt */ 13620 if (!r) { 13621 return 0; 13622 } 13623 13624 if (r->dnsmgr) { 13625 /* If the registration has timed out, maybe the IP changed. Force a refresh. */ 13626 ast_dnsmgr_refresh(r->dnsmgr); 13627 } 13628 13629 /* If the initial tranmission failed, we may not have an existing dialog, 13630 * so it is possible that r->call == NULL. 13631 * Otherwise destroy it, as we have a timeout so we don't want it. 13632 */ 13633 if (r->call) { 13634 /* Unlink us, destroy old call. Locking is not relevant here because all this happens 13635 in the single SIP manager thread. */ 13636 p = r->call; 13637 sip_pvt_lock(p); 13638 pvt_set_needdestroy(p, "registration timeout"); 13639 /* Pretend to ACK anything just in case */ 13640 __sip_pretend_ack(p); 13641 sip_pvt_unlock(p); 13642 13643 /* decouple the two objects */ 13644 /* p->registry == r, so r has 2 refs, and the unref won't take the object away */ 13645 if (p->registry) { 13646 p->registry = registry_unref(p->registry, "p->registry unreffed"); 13647 } 13648 r->call = dialog_unref(r->call, "unrefing r->call"); 13649 } 13650 /* If we have a limit, stop registration and give up */ 13651 r->timeout = -1; 13652 if (global_regattempts_max && r->regattempts >= global_regattempts_max) { 13653 /* Ok, enough is enough. Don't try any more */ 13654 /* We could add an external notification here... 13655 steal it from app_voicemail :-) */ 13656 ast_log(LOG_NOTICE, " -- Last Registration Attempt #%d failed, Giving up forever trying to register '%s@%s'\n", r->regattempts, r->username, r->hostname); 13657 r->regstate = REG_STATE_FAILED; 13658 } else { 13659 r->regstate = REG_STATE_UNREGISTERED; 13660 transmit_register(r, SIP_REGISTER, NULL, NULL); 13661 ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 13662 } 13663 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: SIP\r\nUsername: %s\r\nDomain: %s\r\nStatus: %s\r\n", r->username, r->hostname, regstate2str(r->regstate)); 13664 registry_unref(r, "unreffing registry_unref r"); 13665 return 0; 13666 }
| static int sip_register | ( | const char * | value, | |
| int | lineno | |||
| ) | [static] |
create sip_registry object from register=> line in sip.conf and link into reg container
Definition at line 8545 of file chan_sip.c.
References ast_atomic_fetchadd_int(), ast_calloc_with_stringfields, ast_log(), ASTOBJ_CONTAINER_LINK, ASTOBJ_INIT, LOG_ERROR, registry_unref(), regl, and sip_parse_register_line().
Referenced by build_peer(), and reload_config().
08546 { 08547 struct sip_registry *reg; 08548 08549 if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) { 08550 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n"); 08551 return -1; 08552 } 08553 08554 ast_atomic_fetchadd_int(®objs, 1); 08555 ASTOBJ_INIT(reg); 08556 08557 if (sip_parse_register_line(reg, default_expiry, value, lineno)) { 08558 registry_unref(reg, "failure to parse, unref the reg pointer"); 08559 return -1; 08560 } 08561 08562 /* set default expiry if necessary */ 08563 if (reg->refresh && !reg->expiry && !reg->configured_expiry) { 08564 reg->refresh = reg->expiry = reg->configured_expiry = default_expiry; 08565 } 08566 08567 /* Add the new registry entry to the list */ 08568 ASTOBJ_CONTAINER_LINK(®l, reg); 08569 08570 /* release the reference given by ASTOBJ_INIT. The container has another reference */ 08571 registry_unref(reg, "unref the reg pointer"); 08572 08573 return 0; 08574 }
| static void sip_register_tests | ( | void | ) | [static] |
SIP test registration.
Definition at line 30882 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().
30883 { 30884 sip_config_parser_register_tests(); 30885 sip_request_parser_register_tests(); 30886 sip_dialplan_function_register_tests(); 30887 }
| static void sip_registry_destroy | ( | struct sip_registry * | reg | ) | [static] |
Destroy registry object Objects created with the register= statement in static configuration.
Definition at line 5928 of file chan_sip.c.
References ast_atomic_fetchadd_int(), ast_debug, ast_free, AST_SCHED_DEL, ast_string_field_free_memory, dialog_unlink_all(), and registry_unref().
Referenced by registry_unref(), reload_config(), and unload_module().
05929 { 05930 /* Really delete */ 05931 ast_debug(3, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname); 05932 05933 if (reg->call) { 05934 /* Clear registry before destroying to ensure 05935 we don't get reentered trying to grab the registry lock */ 05936 reg->call->registry = registry_unref(reg->call->registry, "destroy reg->call->registry"); 05937 ast_debug(3, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname); 05938 dialog_unlink_all(reg->call); 05939 reg->call = dialog_unref(reg->call, "unref reg->call"); 05940 /* reg->call = sip_destroy(reg->call); */ 05941 } 05942 AST_SCHED_DEL(sched, reg->expire); 05943 AST_SCHED_DEL(sched, reg->timeout); 05944 05945 ast_string_field_free_memory(reg); 05946 ast_atomic_fetchadd_int(®objs, -1); 05947 ast_free(reg); 05948 }
| static int sip_reinvite_retry | ( | const void * | data | ) | [static] |
Reset the NEEDREINVITE flag after waiting when we get 491 on a Re-invite to avoid race conditions between asterisk servers. Called from the scheduler.
Definition at line 20519 of file chan_sip.c.
References ast_channel_trylock, ast_channel_unlock, ast_set_flag, check_pendings(), sip_pvt_lock, and sip_pvt_unlock.
Referenced by handle_response_invite(), and sip_show_sched().
20520 { 20521 struct sip_pvt *p = (struct sip_pvt *) data; 20522 struct ast_channel *owner; 20523 20524 sip_pvt_lock(p); /* called from schedule thread which requires a lock */ 20525 while ((owner = p->owner) && ast_channel_trylock(owner)) { 20526 sip_pvt_unlock(p); 20527 usleep(1); 20528 sip_pvt_lock(p); 20529 } 20530 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 20531 p->waitid = -1; 20532 check_pendings(p); 20533 sip_pvt_unlock(p); 20534 if (owner) { 20535 ast_channel_unlock(owner); 20536 } 20537 dialog_unref(p, "unref the dialog ptr from sip_reinvite_retry, because it held a dialog ptr"); 20538 return 0; 20539 }
| static char * sip_reload | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Force reload of module from cli.
Definition at line 30631 of file chan_sip.c.
References ao2_t_ref, ast_clear_flag, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_string_field_set, ast_verbose, BOGUS_PEER_MD5SECRET, CHANNEL_CLI_RELOAD, CHANNEL_MODULE_RELOAD, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, LOG_ERROR, restart_monitor(), temp_peer(), TRUE, and ast_cli_entry::usage.
Referenced by reload().
30632 { 30633 static struct sip_peer *tmp_peer, *new_peer; 30634 30635 switch (cmd) { 30636 case CLI_INIT: 30637 e->command = "sip reload"; 30638 e->usage = 30639 "Usage: sip reload\n" 30640 " Reloads SIP configuration from sip.conf\n"; 30641 return NULL; 30642 case CLI_GENERATE: 30643 return NULL; 30644 } 30645 30646 ast_mutex_lock(&sip_reload_lock); 30647 if (sip_reloading) { 30648 ast_verbose("Previous SIP reload not yet done\n"); 30649 } else { 30650 sip_reloading = TRUE; 30651 sip_reloadreason = (a && a->fd) ? CHANNEL_CLI_RELOAD : CHANNEL_MODULE_RELOAD; 30652 } 30653 ast_mutex_unlock(&sip_reload_lock); 30654 restart_monitor(); 30655 30656 tmp_peer = bogus_peer; 30657 /* Create new bogus peer possibly with new global settings. */ 30658 if ((new_peer = temp_peer("(bogus_peer)"))) { 30659 ast_string_field_set(new_peer, md5secret, BOGUS_PEER_MD5SECRET); 30660 ast_clear_flag(&new_peer->flags[0], SIP_INSECURE); 30661 bogus_peer = new_peer; 30662 ao2_t_ref(tmp_peer, -1, "unref the old bogus_peer during reload"); 30663 } else { 30664 ast_log(LOG_ERROR, "Could not update the fake authentication peer.\n"); 30665 /* You probably have bigger (memory?) issues to worry about though.. */ 30666 } 30667 30668 return CLI_SUCCESS; 30669 }
| static int sip_removeheader | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Remove SIP headers added previously with SipAddHeader application.
Definition at line 30377 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_debug, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_strlen_zero(), ast_var_delete(), ast_var_name(), ast_var_value(), inbuf(), and ast_channel::varshead.
Referenced by load_module().
30378 { 30379 struct ast_var_t *newvariable; 30380 struct varshead *headp; 30381 int removeall = 0; 30382 char *inbuf = (char *) data; 30383 30384 if (ast_strlen_zero(inbuf)) { 30385 removeall = 1; 30386 } 30387 ast_channel_lock(chan); 30388 30389 headp=&chan->varshead; 30390 AST_LIST_TRAVERSE_SAFE_BEGIN (headp, newvariable, entries) { 30391 if (strncasecmp(ast_var_name(newvariable), "SIPADDHEADER", strlen("SIPADDHEADER")) == 0) { 30392 if (removeall || (!strncasecmp(ast_var_value(newvariable),inbuf,strlen(inbuf)))) { 30393 if (sipdebug) 30394 ast_debug(1,"removing SIP Header \"%s\" as %s\n", 30395 ast_var_value(newvariable), 30396 ast_var_name(newvariable)); 30397 AST_LIST_REMOVE_CURRENT(entries); 30398 ast_var_delete(newvariable); 30399 } 30400 } 30401 } 30402 AST_LIST_TRAVERSE_SAFE_END; 30403 30404 ast_channel_unlock(chan); 30405 return 0; 30406 }
| static struct ast_channel * sip_request_call | ( | const char * | type, | |
| format_t | format, | |||
| const struct ast_channel * | requestor, | |||
| void * | data, | |||
| int * | cause | |||
| ) | [static, read] |
PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here.
* SIP Dial string syntax: * SIP/devicename * or SIP/username@domain (SIP uri) * or SIP/username[:password[:md5secret[:authname[:transport]]]]@host[:port] * or SIP/devicename/extension * or SIP/devicename/extension/IPorHost * or SIP/username@domain//IPorHost * and there is an optional [!dnid] argument you can append to alter the * To: header. *
Definition at line 27319 of file chan_sip.c.
References args, AST_APP_ARG, ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_CHANNEL_UNACCEPTABLE, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNREGISTERED, ast_channel_unlock, ast_copy_string(), ast_debug, AST_DECLARE_APP_ARGS, AST_FORMAT_AUDIO_MASK, ast_getformatname(), ast_getformatname_multiple(), ast_log(), AST_NONSTANDARD_APP_ARGS, ast_sip_ouraddrfor(), AST_STATE_DOWN, ast_string_field_set, ast_strlen_zero(), ast_update_use_count(), build_via(), change_callid_pvt(), create_addr(), dialog_unlink_all(), EVENT_FLAG_SYSTEM, ext, exten, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event, proxy_from_config(), restart_monitor(), secret, set_socket_transport(), sip_alloc(), sip_cfg, sip_new(), sip_pvt_lock, sip_pvt_unlock, and TRUE.
27320 { 27321 struct sip_pvt *p; 27322 struct ast_channel *tmpc = NULL; 27323 char *ext = NULL, *host; 27324 char tmp[256]; 27325 char *dest = data; 27326 char *dnid; 27327 char *secret = NULL; 27328 char *md5secret = NULL; 27329 char *authname = NULL; 27330 char *trans = NULL; 27331 char dialstring[256]; 27332 char *remote_address; 27333 enum sip_transport transport = 0; 27334 format_t oldformat = format; 27335 AST_DECLARE_APP_ARGS(args, 27336 AST_APP_ARG(peerorhost); 27337 AST_APP_ARG(exten); 27338 AST_APP_ARG(remote_address); 27339 ); 27340 27341 /* mask request with some set of allowed formats. 27342 * XXX this needs to be fixed. 27343 * The original code uses AST_FORMAT_AUDIO_MASK, but it is 27344 * unclear what to use here. We have global_capabilities, which is 27345 * configured from sip.conf, and sip_tech.capabilities, which is 27346 * hardwired to all audio formats. 27347 */ 27348 format &= AST_FORMAT_AUDIO_MASK; 27349 if (!format) { 27350 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format %s while capability is %s\n", ast_getformatname(oldformat), ast_getformatname(sip_cfg.capability)); 27351 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; /* Can't find codec to connect to host */ 27352 return NULL; 27353 } 27354 ast_debug(1, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat)); 27355 27356 if (ast_strlen_zero(dest)) { 27357 ast_log(LOG_ERROR, "Unable to create channel with empty destination.\n"); 27358 *cause = AST_CAUSE_CHANNEL_UNACCEPTABLE; 27359 return NULL; 27360 } 27361 27362 if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE, NULL))) { 27363 ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", dest); 27364 *cause = AST_CAUSE_SWITCH_CONGESTION; 27365 return NULL; 27366 } 27367 27368 p->outgoing_call = TRUE; 27369 27370 snprintf(dialstring, sizeof(dialstring), "%s/%s", type, dest); 27371 ast_string_field_set(p, dialstring, dialstring); 27372 27373 if (!(p->options = ast_calloc(1, sizeof(*p->options)))) { 27374 dialog_unlink_all(p); 27375 dialog_unref(p, "unref dialog p from mem fail"); 27376 /* sip_destroy(p); */ 27377 ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n"); 27378 *cause = AST_CAUSE_SWITCH_CONGESTION; 27379 return NULL; 27380 } 27381 27382 /* Save the destination, the SIP dial string */ 27383 ast_copy_string(tmp, dest, sizeof(tmp)); 27384 27385 /* Find DNID and take it away */ 27386 dnid = strchr(tmp, '!'); 27387 if (dnid != NULL) { 27388 *dnid++ = '\0'; 27389 ast_string_field_set(p, todnid, dnid); 27390 } 27391 27392 /* Divvy up the items separated by slashes */ 27393 AST_NONSTANDARD_APP_ARGS(args, tmp, '/'); 27394 27395 /* Find at sign - @ */ 27396 host = strchr(args.peerorhost, '@'); 27397 if (host) { 27398 *host++ = '\0'; 27399 ext = args.peerorhost; 27400 secret = strchr(ext, ':'); 27401 } 27402 if (secret) { 27403 *secret++ = '\0'; 27404 md5secret = strchr(secret, ':'); 27405 } 27406 if (md5secret) { 27407 *md5secret++ = '\0'; 27408 authname = strchr(md5secret, ':'); 27409 } 27410 if (authname) { 27411 *authname++ = '\0'; 27412 trans = strchr(authname, ':'); 27413 } 27414 if (trans) { 27415 *trans++ = '\0'; 27416 if (!strcasecmp(trans, "tcp")) 27417 transport = SIP_TRANSPORT_TCP; 27418 else if (!strcasecmp(trans, "tls")) 27419 transport = SIP_TRANSPORT_TLS; 27420 else { 27421 if (strcasecmp(trans, "udp")) 27422 ast_log(LOG_WARNING, "'%s' is not a valid transport option to Dial() for SIP calls, using udp by default.\n", trans); 27423 transport = SIP_TRANSPORT_UDP; 27424 } 27425 } else { /* use default */ 27426 transport = SIP_TRANSPORT_UDP; 27427 } 27428 27429 if (!host) { 27430 ext = args.exten; 27431 host = args.peerorhost; 27432 remote_address = args.remote_address; 27433 } else { 27434 remote_address = args.remote_address; 27435 if (!ast_strlen_zero(args.exten)) { 27436 ast_log(LOG_NOTICE, "Conflicting extension values given. Using '%s' and not '%s'\n", ext, args.exten); 27437 } 27438 } 27439 27440 if (!ast_strlen_zero(remote_address)) { 27441 p->options->outboundproxy = proxy_from_config(remote_address, 0, NULL); 27442 if (!p->options->outboundproxy) { 27443 ast_log(LOG_WARNING, "Unable to parse outboundproxy %s. We will not use this remote IP address\n", remote_address); 27444 } 27445 } 27446 27447 set_socket_transport(&p->socket, transport); 27448 27449 /* We now have 27450 host = peer name, DNS host name or DNS domain (for SRV) 27451 ext = extension (user part of URI) 27452 dnid = destination of the call (applies to the To: header) 27453 */ 27454 if (create_addr(p, host, NULL, 1)) { 27455 *cause = AST_CAUSE_UNREGISTERED; 27456 ast_debug(3, "Cant create SIP call - target device not registered\n"); 27457 dialog_unlink_all(p); 27458 dialog_unref(p, "unref dialog p UNREGISTERED"); 27459 /* sip_destroy(p); */ 27460 return NULL; 27461 } 27462 if (ast_strlen_zero(p->peername) && ext) 27463 ast_string_field_set(p, peername, ext); 27464 /* Recalculate our side, and recalculate Call ID */ 27465 ast_sip_ouraddrfor(&p->sa, &p->ourip, p); 27466 build_via(p); 27467 27468 /* Change the dialog callid. */ 27469 change_callid_pvt(p, NULL); 27470 27471 /* We have an extension to call, don't use the full contact here */ 27472 /* This to enable dialing registered peers with extension dialling, 27473 like SIP/peername/extension 27474 SIP/peername will still use the full contact 27475 */ 27476 if (ext) { 27477 ast_string_field_set(p, username, ext); 27478 ast_string_field_set(p, fullcontact, NULL); 27479 } 27480 if (secret && !ast_strlen_zero(secret)) 27481 ast_string_field_set(p, peersecret, secret); 27482 27483 if (md5secret && !ast_strlen_zero(md5secret)) 27484 ast_string_field_set(p, peermd5secret, md5secret); 27485 27486 if (authname && !ast_strlen_zero(authname)) 27487 ast_string_field_set(p, authname, authname); 27488 #if 0 27489 printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host); 27490 #endif 27491 p->prefcodec = oldformat; /* Format for this call */ 27492 p->jointcapability = oldformat & p->capability; 27493 sip_pvt_lock(p); 27494 tmpc = sip_new(p, AST_STATE_DOWN, host, requestor ? requestor->linkedid : NULL); /* Place the call */ 27495 if (sip_cfg.callevents) 27496 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", 27497 "Channel: %s\r\nChanneltype: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\nPeername: %s\r\n", 27498 p->owner ? p->owner->name : "", "SIP", p->callid, p->fullcontact, p->peername); 27499 sip_pvt_unlock(p); 27500 if (!tmpc) { 27501 dialog_unlink_all(p); 27502 /* sip_destroy(p); */ 27503 } else { 27504 ast_channel_unlock(tmpc); 27505 } 27506 dialog_unref(p, "toss pvt ptr at end of sip_request_call"); 27507 ast_update_use_count(); 27508 restart_monitor(); 27509 return tmpc; 27510 }
| static int sip_reregister | ( | const void * | data | ) | [static] |
Update registration with SIP Proxy. Called from the scheduler when the previous registration expires, so we don't have to cancel the pending event. We assume the reference so the sip_registry is valid, since it is stored in the scheduled event anyways.
Definition at line 13569 of file chan_sip.c.
References __sip_do_register(), append_history, ast_log(), LOG_NOTICE, and registry_unref().
Referenced by handle_response_register(), sip_send_all_registers(), and sip_show_sched().
13570 { 13571 /* if we are here, we know that we need to reregister. */ 13572 struct sip_registry *r = (struct sip_registry *) data; 13573 13574 /* if we couldn't get a reference to the registry object, punt */ 13575 if (!r) { 13576 return 0; 13577 } 13578 13579 if (r->call && r->call->do_history) { 13580 append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname); 13581 } 13582 /* Since registry's are only added/removed by the the monitor thread, this 13583 may be overkill to reference/dereference at all here */ 13584 if (sipdebug) { 13585 ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname); 13586 } 13587 13588 r->expire = -1; 13589 r->expiry = r->configured_expiry; 13590 __sip_do_register(r); 13591 registry_unref(r, "unref the re-register scheduled event"); 13592 return 0; 13593 }
| static struct ast_frame* sip_rtp_read | ( | struct ast_channel * | ast, | |
| struct sip_pvt * | p, | |||
| int * | faxdetect | |||
| ) | [static, read] |
Read RTP from network.
Definition at line 7691 of file chan_sip.c.
References ast_debug, ast_dsp_free(), ast_dsp_process(), ast_dsp_set_features(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_TEXT_MASK, AST_FORMAT_VIDEO_MASK, AST_FRAME_DTMF, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_VOICE, ast_frfree, ast_getformatname(), ast_null_frame, ast_rtp_instance_read(), ast_set_read_format(), ast_set_write_format(), ast_test_flag, ast_udptl_read(), ast_verbose, ast_frame_subclass::codec, ast_frame::data, ast_frame::datalen, DSP_FEATURE_DIGIT_DETECT, f, ast_channel::fdno, ast_frame::frametype, ast_frame_subclass::integer, ast_frame::ptr, and ast_frame::subclass.
Referenced by sip_read().
07692 { 07693 /* Retrieve audio/etc from channel. Assumes p->lock is already held. */ 07694 struct ast_frame *f; 07695 07696 if (!p->rtp) { 07697 /* We have no RTP allocated for this channel */ 07698 return &ast_null_frame; 07699 } 07700 07701 switch(ast->fdno) { 07702 case 0: 07703 f = ast_rtp_instance_read(p->rtp, 0); /* RTP Audio */ 07704 break; 07705 case 1: 07706 f = ast_rtp_instance_read(p->rtp, 1); /* RTCP Control Channel */ 07707 break; 07708 case 2: 07709 f = ast_rtp_instance_read(p->vrtp, 0); /* RTP Video */ 07710 break; 07711 case 3: 07712 f = ast_rtp_instance_read(p->vrtp, 1); /* RTCP Control Channel for video */ 07713 break; 07714 case 4: 07715 f = ast_rtp_instance_read(p->trtp, 0); /* RTP Text */ 07716 if (sipdebug_text) { 07717 int i; 07718 unsigned char* arr = f->data.ptr; 07719 for (i=0; i < f->datalen; i++) 07720 ast_verbose("%c", (arr[i] > ' ' && arr[i] < '}') ? arr[i] : '.'); 07721 ast_verbose(" -> "); 07722 for (i=0; i < f->datalen; i++) 07723 ast_verbose("%02X ", (unsigned)arr[i]); 07724 ast_verbose("\n"); 07725 } 07726 break; 07727 case 5: 07728 f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */ 07729 break; 07730 default: 07731 f = &ast_null_frame; 07732 } 07733 /* Don't forward RFC2833 if we're not supposed to */ 07734 if (f && (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END) && 07735 (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833)) { 07736 ast_debug(1, "Ignoring DTMF (%c) RTP frame because dtmfmode is not RFC2833\n", f->subclass.integer); 07737 ast_frfree(f); 07738 return &ast_null_frame; 07739 } 07740 07741 /* We already hold the channel lock */ 07742 if (!p->owner || (f && f->frametype != AST_FRAME_VOICE)) 07743 return f; 07744 07745 if (f && f->subclass.codec != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) { 07746 if (!(f->subclass.codec & p->jointcapability)) { 07747 ast_debug(1, "Bogus frame of format '%s' received from '%s'!\n", 07748 ast_getformatname(f->subclass.codec), p->owner->name); 07749 ast_frfree(f); 07750 return &ast_null_frame; 07751 } 07752 ast_debug(1, "Oooh, format changed to %s\n", 07753 ast_getformatname(f->subclass.codec)); 07754 p->owner->nativeformats = (p->owner->nativeformats & (AST_FORMAT_VIDEO_MASK | AST_FORMAT_TEXT_MASK)) | f->subclass.codec; 07755 ast_set_read_format(p->owner, p->owner->readformat); 07756 ast_set_write_format(p->owner, p->owner->writeformat); 07757 } 07758 07759 if (f && p->dsp) { 07760 f = ast_dsp_process(p->owner, p->dsp, f); 07761 if (f && f->frametype == AST_FRAME_DTMF) { 07762 if (f->subclass.integer == 'f') { 07763 ast_debug(1, "Fax CNG detected on %s\n", ast->name); 07764 *faxdetect = 1; 07765 /* If we only needed this DSP for fax detection purposes we can just drop it now */ 07766 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 07767 ast_dsp_set_features(p->dsp, DSP_FEATURE_DIGIT_DETECT); 07768 } else { 07769 ast_dsp_free(p->dsp); 07770 p->dsp = NULL; 07771 } 07772 } else { 07773 ast_debug(1, "* Detected inband DTMF '%c'\n", f->subclass.integer); 07774 } 07775 } 07776 } 07777 07778 return f; 07779 }
| static const char* sip_sanitized_host | ( | const char * | host | ) | [static] |
Definition at line 13668 of file chan_sip.c.
References ast_sockaddr_parse(), ast_sockaddr_stringify_host_remote(), and PARSE_PORT_FORBID.
Referenced by transmit_register().
13669 { 13670 struct ast_sockaddr addr = { { 0, 0, }, }; 13671 13672 /* peer/sip_pvt->tohost and sip_registry->hostname should never have a port 13673 * in them, so we use PARSE_PORT_FORBID here. If this lookup fails, we return 13674 * the original host which is most likely a host name and not an IP. */ 13675 if (!ast_sockaddr_parse(&addr, host, PARSE_PORT_FORBID)) { 13676 return host; 13677 } 13678 return ast_sockaddr_stringify_host_remote(&addr); 13679 }
| void sip_scheddestroy | ( | struct sip_pvt * | p, | |
| int | ms | |||
| ) |
Schedule destruction of SIP dialog.
Definition at line 4103 of file chan_sip.c.
References __sip_autodestruct(), append_history, ast_log(), ast_sched_add(), ast_verbose, LOG_WARNING, sip_cancel_destroy(), sip_debug_test_pvt(), sip_methods, stop_session_timer(), cfsip_methods::text, and TRUE.
Referenced by __sip_autodestruct(), auto_congest(), cb_extensionstate(), check_auth(), check_pendings(), handle_incoming(), handle_invite_replaces(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_options(), handle_request_publish(), handle_request_register(), handle_request_subscribe(), handle_response_invite(), manager_sipnotify(), receive_message(), sip_cli_notify(), sip_hangup(), sip_scheddestroy_final(), sip_send_mwi_to_peer(), sip_sipredirect(), transmit_fake_auth_response(), and transmit_publish().
04104 { 04105 if (p->final_destruction_scheduled) { 04106 return; /* already set final destruction */ 04107 } 04108 04109 if (ms < 0) { 04110 if (p->timer_t1 == 0) { 04111 p->timer_t1 = global_t1; /* Set timer T1 if not set (RFC 3261) */ 04112 } 04113 if (p->timer_b == 0) { 04114 p->timer_b = global_timer_b; /* Set timer B if not set (RFC 3261) */ 04115 } 04116 ms = p->timer_t1 * 64; 04117 } 04118 if (sip_debug_test_pvt(p)) { 04119 ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text); 04120 } 04121 if (sip_cancel_destroy(p)) { 04122 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 04123 } 04124 04125 if (p->do_history) { 04126 append_history(p, "SchedDestroy", "%d ms", ms); 04127 } 04128 p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, dialog_ref(p, "setting ref as passing into ast_sched_add for __sip_autodestruct")); 04129 04130 if (p->stimer && p->stimer->st_active == TRUE && p->stimer->st_schedid > 0) { 04131 stop_session_timer(p); 04132 } 04133 }
| void sip_scheddestroy_final | ( | struct sip_pvt * | p, | |
| int | ms | |||
| ) |
Schedule final destruction of SIP dialog. This can not be canceled. This function is used to keep a dialog around for a period of time in order to properly respond to any retransmits.
Definition at line 4090 of file chan_sip.c.
References sip_scheddestroy().
Referenced by handle_request_bye().
04091 { 04092 if (p->final_destruction_scheduled) { 04093 return; /* already set final destruction */ 04094 } 04095 04096 sip_scheddestroy(p, ms); 04097 if (p->autokillid != -1) { 04098 p->final_destruction_scheduled = 1; 04099 } 04100 }
| static void sip_send_all_mwi_subscriptions | ( | void | ) | [static] |
Send all MWI subscriptions.
Definition at line 30535 of file chan_sip.c.
References ast_sched_add(), AST_SCHED_DEL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_REF, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, sip_subscribe_mwi_destroy(), sip_subscribe_mwi_do(), and submwil.
Referenced by load_module(), network_change_event_sched_cb(), and sip_do_reload().
30536 { 30537 ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do { 30538 struct sip_subscription_mwi *saved; 30539 ASTOBJ_WRLOCK(iterator); 30540 AST_SCHED_DEL(sched, iterator->resub); 30541 saved = ASTOBJ_REF(iterator); 30542 if ((iterator->resub = ast_sched_add(sched, 1, sip_subscribe_mwi_do, saved)) < 0) { 30543 ASTOBJ_UNREF(saved, sip_subscribe_mwi_destroy); 30544 } 30545 ASTOBJ_UNLOCK(iterator); 30546 } while (0)); 30547 }
| static void sip_send_all_registers | ( | void | ) | [static] |
Send all known registrations.
Definition at line 30511 of file chan_sip.c.
References AST_SCHED_REPLACE_UNREF, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, registry_addref(), registry_unref(), regl, and sip_reregister().
Referenced by load_module(), network_change_event_sched_cb(), and sip_do_reload().
30512 { 30513 int ms; 30514 int regspacing; 30515 if (!regobjs) 30516 return; 30517 regspacing = default_expiry * 1000/regobjs; 30518 if (regspacing > 100) { 30519 regspacing = 100; 30520 } 30521 ms = regspacing; 30522 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 30523 ASTOBJ_WRLOCK(iterator); 30524 ms += regspacing; 30525 AST_SCHED_REPLACE_UNREF(iterator->expire, sched, ms, sip_reregister, iterator, 30526 registry_unref(_data, "REPLACE sched del decs the refcount"), 30527 registry_unref(iterator, "REPLACE sched add failure decs the refcount"), 30528 registry_addref(iterator, "REPLACE sched add incs the refcount")); 30529 ASTOBJ_UNLOCK(iterator); 30530 } while (0) 30531 ); 30532 }
| static int sip_send_mwi_to_peer | ( | struct sip_peer * | peer, | |
| int | cache_only | |||
| ) | [static] |
Send message waiting indication to alert peer that they've got voicemail.
Definition at line 26467 of file chan_sip.c.
References ao2_lock, ao2_unlock, ast_app_inboxcount(), ast_set_flag, ast_sip_ouraddrfor(), ast_sockaddr_isnull(), ast_str_alloca, ast_str_buffer(), ast_str_strlen(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, build_via(), change_callid_pvt(), create_addr_from_peer(), dialog_unlink_all(), get_cached_mwi(), peer_mailboxes_to_str(), set_socket_transport(), sip_alloc(), sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), transmit_notify_with_mwi(), and update_peer_lastmsgssent().
Referenced by build_peer(), handle_request_subscribe(), mwi_event_cb(), and register_verify().
26468 { 26469 /* Called with peer lock, but releases it */ 26470 struct sip_pvt *p; 26471 int newmsgs = 0, oldmsgs = 0; 26472 const char *vmexten = NULL; 26473 26474 ao2_lock(peer); 26475 26476 if (peer->vmexten) { 26477 vmexten = ast_strdupa(peer->vmexten); 26478 } 26479 26480 if (ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY) && !peer->mwipvt) { 26481 update_peer_lastmsgssent(peer, -1, 1); 26482 ao2_unlock(peer); 26483 return 0; 26484 } 26485 26486 /* Do we have an IP address? If not, skip this peer */ 26487 if (ast_sockaddr_isnull(&peer->addr) && ast_sockaddr_isnull(&peer->defaddr)) { 26488 update_peer_lastmsgssent(peer, -1, 1); 26489 ao2_unlock(peer); 26490 return 0; 26491 } 26492 26493 /* Attempt to use cached mwi to get message counts. */ 26494 if (!get_cached_mwi(peer, &newmsgs, &oldmsgs) && !cache_only) { 26495 /* Fall back to manually checking the mailbox if not cache_only and get_cached_mwi failed */ 26496 struct ast_str *mailbox_str = ast_str_alloca(512); 26497 peer_mailboxes_to_str(&mailbox_str, peer); 26498 ao2_unlock(peer); 26499 /* If there is no mailbox do nothing */ 26500 if (!ast_str_strlen(mailbox_str)) { 26501 update_peer_lastmsgssent(peer, -1, 0); 26502 return 0; 26503 } 26504 ast_app_inboxcount(ast_str_buffer(mailbox_str), &newmsgs, &oldmsgs); 26505 ao2_lock(peer); 26506 } 26507 26508 if (peer->mwipvt) { 26509 /* Base message on subscription */ 26510 p = dialog_ref(peer->mwipvt, "sip_send_mwi_to_peer: Setting dialog ptr p from peer->mwipvt"); 26511 ao2_unlock(peer); 26512 } else { 26513 ao2_unlock(peer); 26514 /* Build temporary dialog for this message */ 26515 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) { 26516 update_peer_lastmsgssent(peer, -1, 0); 26517 return -1; 26518 } 26519 26520 /* If we don't set the socket type to 0, then create_addr_from_peer will fail immediately if the peer 26521 * uses any transport other than UDP. We set the type to 0 here and then let create_addr_from_peer copy 26522 * the peer's socket information to the sip_pvt we just allocated 26523 */ 26524 set_socket_transport(&p->socket, 0); 26525 if (create_addr_from_peer(p, peer)) { 26526 /* Maybe they're not registered, etc. */ 26527 dialog_unlink_all(p); 26528 dialog_unref(p, "unref dialog p just created via sip_alloc"); 26529 update_peer_lastmsgssent(peer, -1, 0); 26530 return 0; 26531 } 26532 /* Recalculate our side, and recalculate Call ID */ 26533 ast_sip_ouraddrfor(&p->sa, &p->ourip, p); 26534 build_via(p); 26535 26536 ao2_lock(peer); 26537 if (!ast_strlen_zero(peer->mwi_from)) { 26538 ast_string_field_set(p, mwi_from, peer->mwi_from); 26539 } else if (!ast_strlen_zero(default_mwi_from)) { 26540 ast_string_field_set(p, mwi_from, default_mwi_from); 26541 } 26542 ao2_unlock(peer); 26543 26544 /* Change the dialog callid. */ 26545 change_callid_pvt(p, NULL); 26546 26547 /* Destroy this session after 32 secs */ 26548 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 26549 } 26550 26551 /* We have multiple threads (mwi events and monitor retransmits) working with this PVT and as we modify the sip history if that's turned on, 26552 we really need to have a lock on it */ 26553 sip_pvt_lock(p); 26554 26555 /* Send MWI */ 26556 ast_set_flag(&p->flags[0], SIP_OUTGOING); 26557 /* the following will decrement the refcount on p as it finishes */ 26558 transmit_notify_with_mwi(p, newmsgs, oldmsgs, vmexten); 26559 sip_pvt_unlock(p); 26560 dialog_unref(p, "unref dialog ptr p just before it goes out of scope at the end of sip_send_mwi_to_peer."); 26561 26562 update_peer_lastmsgssent(peer, ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)), 0); 26563 26564 return 0; 26565 }
| static int sip_senddigit_begin | ( | struct ast_channel * | ast, | |
| char | digit | |||
| ) | [static] |
Definition at line 6913 of file chan_sip.c.
References ast_debug, ast_rtp_instance_dtmf_begin(), ast_test_flag, sip_pvt_lock, sip_pvt_unlock, and ast_channel::tech_pvt.
06914 { 06915 struct sip_pvt *p = ast->tech_pvt; 06916 int res = 0; 06917 06918 if (!p) { 06919 ast_debug(1, "Asked to begin DTMF digit on channel %s with no pvt; ignoring\n", 06920 ast->name); 06921 return res; 06922 } 06923 06924 sip_pvt_lock(p); 06925 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 06926 case SIP_DTMF_INBAND: 06927 res = -1; /* Tell Asterisk to generate inband indications */ 06928 break; 06929 case SIP_DTMF_RFC2833: 06930 if (p->rtp) 06931 ast_rtp_instance_dtmf_begin(p->rtp, digit); 06932 break; 06933 default: 06934 break; 06935 } 06936 sip_pvt_unlock(p); 06937 06938 return res; 06939 }
| static int sip_senddigit_end | ( | struct ast_channel * | ast, | |
| char | digit, | |||
| unsigned int | duration | |||
| ) | [static] |
Send DTMF character on SIP channel within one call, we're able to transmit in many methods simultaneously.
Definition at line 6943 of file chan_sip.c.
References ast_debug, ast_rtp_instance_dtmf_end_with_duration(), ast_test_flag, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, and transmit_info_with_digit().
06944 { 06945 struct sip_pvt *p = ast->tech_pvt; 06946 int res = 0; 06947 06948 if (!p) { 06949 ast_debug(1, "Asked to end DTMF digit on channel %s with no pvt; ignoring\n", 06950 ast->name); 06951 return res; 06952 } 06953 06954 sip_pvt_lock(p); 06955 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 06956 case SIP_DTMF_INFO: 06957 case SIP_DTMF_SHORTINFO: 06958 transmit_info_with_digit(p, digit, duration); 06959 break; 06960 case SIP_DTMF_RFC2833: 06961 if (p->rtp) 06962 ast_rtp_instance_dtmf_end_with_duration(p->rtp, digit, duration); 06963 break; 06964 case SIP_DTMF_INBAND: 06965 res = -1; /* Tell Asterisk to stop inband indications */ 06966 break; 06967 } 06968 sip_pvt_unlock(p); 06969 06970 return res; 06971 }
| static int sip_sendhtml | ( | struct ast_channel * | chan, | |
| int | subclass, | |||
| const char * | data, | |||
| int | datalen | |||
| ) | [static] |
Send message with Access-URL header, if this is an HTML URL only!
Definition at line 4638 of file chan_sip.c.
References ast_channel::_state, ast_debug, AST_HTML_URL, ast_log(), ast_set_flag, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_string_field_build, ast_test_flag, FALSE, LOG_WARNING, sip_debug_test_pvt(), ast_channel::tech_pvt, transmit_reinvite_with_sdp(), transmit_response(), and url.
04639 { 04640 struct sip_pvt *p = chan->tech_pvt; 04641 04642 if (subclass != AST_HTML_URL) 04643 return -1; 04644 04645 ast_string_field_build(p, url, "<%s>;mode=active", data); 04646 04647 if (sip_debug_test_pvt(p)) 04648 ast_debug(1, "Send URL %s, state = %u!\n", data, chan->_state); 04649 04650 switch (chan->_state) { 04651 case AST_STATE_RING: 04652 transmit_response(p, "100 Trying", &p->initreq); 04653 break; 04654 case AST_STATE_RINGING: 04655 transmit_response(p, "180 Ringing", &p->initreq); 04656 break; 04657 case AST_STATE_UP: 04658 if (!p->pendinginvite) { /* We are up, and have no outstanding invite */ 04659 transmit_reinvite_with_sdp(p, FALSE, FALSE); 04660 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 04661 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 04662 } 04663 break; 04664 default: 04665 ast_log(LOG_WARNING, "Don't know how to send URI when state is %u!\n", chan->_state); 04666 } 04667 04668 return 0; 04669 }
| static int sip_sendtext | ( | struct ast_channel * | ast, | |
| const char * | text | |||
| ) | [static] |
Definition at line 4682 of file chan_sip.c.
References ast_debug, ast_verbose, is_method_allowed(), sip_debug_test_pvt(), ast_channel::tech_pvt, and transmit_message_with_text().
04683 { 04684 struct sip_pvt *dialog = ast->tech_pvt; 04685 int debug; 04686 04687 if (!dialog) { 04688 return -1; 04689 } 04690 /* NOT ast_strlen_zero, because a zero-length message is specifically 04691 * allowed by RFC 3428 (See section 10, Examples) */ 04692 if (!text) { 04693 return 0; 04694 } 04695 if(!is_method_allowed(&dialog->allowed_methods, SIP_MESSAGE)) { 04696 ast_debug(2, "Trying to send MESSAGE to device that does not support it.\n"); 04697 return(0); 04698 } 04699 04700 debug = sip_debug_test_pvt(dialog); 04701 if (debug) { 04702 ast_verbose("Sending text %s on %s\n", text, ast->name); 04703 } 04704 04705 transmit_message_with_text(dialog, text); 04706 return 0; 04707 }
| static char * sip_set_history | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Enable/Disable SIP History logging (CLI).
Definition at line 19769 of file chan_sip.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, FALSE, ast_cli_args::fd, TRUE, and ast_cli_entry::usage.
19770 { 19771 switch (cmd) { 19772 case CLI_INIT: 19773 e->command = "sip set history {on|off}"; 19774 e->usage = 19775 "Usage: sip set history {on|off}\n" 19776 " Enables/Disables recording of SIP dialog history for debugging purposes.\n" 19777 " Use 'sip show history' to view the history of a call number.\n"; 19778 return NULL; 19779 case CLI_GENERATE: 19780 return NULL; 19781 } 19782 19783 if (a->argc != e->args) 19784 return CLI_SHOWUSAGE; 19785 19786 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) { 19787 recordhistory = TRUE; 19788 ast_cli(a->fd, "SIP History Recording Enabled (use 'sip show history')\n"); 19789 } else if (!strncasecmp(a->argv[e->args - 1], "off", 3)) { 19790 recordhistory = FALSE; 19791 ast_cli(a->fd, "SIP History Recording Disabled\n"); 19792 } else { 19793 return CLI_SHOWUSAGE; 19794 } 19795 return CLI_SUCCESS; 19796 }
| static void sip_set_redirstr | ( | struct sip_pvt * | p, | |
| char * | reason | |||
| ) | [static] |
Translate referring cause.
Definition at line 15566 of file chan_sip.c.
References ast_string_field_set.
Referenced by get_rdnis().
15566 { 15567 15568 if (!strcmp(reason, "unknown")) { 15569 ast_string_field_set(p, redircause, "UNKNOWN"); 15570 } else if (!strcmp(reason, "user-busy")) { 15571 ast_string_field_set(p, redircause, "BUSY"); 15572 } else if (!strcmp(reason, "no-answer")) { 15573 ast_string_field_set(p, redircause, "NOANSWER"); 15574 } else if (!strcmp(reason, "unavailable")) { 15575 ast_string_field_set(p, redircause, "UNREACHABLE"); 15576 } else if (!strcmp(reason, "unconditional")) { 15577 ast_string_field_set(p, redircause, "UNCONDITIONAL"); 15578 } else if (!strcmp(reason, "time-of-day")) { 15579 ast_string_field_set(p, redircause, "UNKNOWN"); 15580 } else if (!strcmp(reason, "do-not-disturb")) { 15581 ast_string_field_set(p, redircause, "UNKNOWN"); 15582 } else if (!strcmp(reason, "deflection")) { 15583 ast_string_field_set(p, redircause, "UNKNOWN"); 15584 } else if (!strcmp(reason, "follow-me")) { 15585 ast_string_field_set(p, redircause, "UNKNOWN"); 15586 } else if (!strcmp(reason, "out-of-service")) { 15587 ast_string_field_set(p, redircause, "UNREACHABLE"); 15588 } else if (!strcmp(reason, "away")) { 15589 ast_string_field_set(p, redircause, "UNREACHABLE"); 15590 } else { 15591 ast_string_field_set(p, redircause, "UNKNOWN"); 15592 } 15593 }
| static int sip_set_rtp_peer | ( | struct ast_channel * | chan, | |
| struct ast_rtp_instance * | instance, | |||
| struct ast_rtp_instance * | vinstance, | |||
| struct ast_rtp_instance * | tinstance, | |||
| format_t | codecs, | |||
| int | nat_active | |||
| ) | [static] |
Definition at line 30130 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), ast_channel_lock, ast_channel_set_fd(), ast_channel_unlock, ast_clear_flag, ast_debug, ast_rtp_instance_fd(), ast_rtp_instance_get_and_cmp_remote_address(), ast_rtp_instance_set_prop(), AST_RTP_PROPERTY_RTCP, ast_set_flag, ast_sockaddr_isnull(), ast_sockaddr_stringify(), AST_STATE_UP, ast_test_flag, FALSE, sip_cfg, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, and transmit_reinvite_with_sdp().
Referenced by sip_fixup().
30131 { 30132 struct sip_pvt *p; 30133 int changed = 0; 30134 30135 /* Lock the channel and the private safely. */ 30136 ast_channel_lock(chan); 30137 p = chan->tech_pvt; 30138 if (!p) { 30139 ast_channel_unlock(chan); 30140 return -1; 30141 } 30142 sip_pvt_lock(p); 30143 if (p->owner != chan) { 30144 /* I suppose it could be argued that if this happens it is a bug. */ 30145 ast_debug(1, "The private is not owned by channel %s anymore.\n", chan->name); 30146 sip_pvt_unlock(p); 30147 ast_channel_unlock(chan); 30148 return 0; 30149 } 30150 30151 /* Disable early RTP bridge */ 30152 if ((instance || vinstance || tinstance) && 30153 !ast_bridged_channel(chan) && 30154 !sip_cfg.directrtpsetup) { 30155 sip_pvt_unlock(p); 30156 ast_channel_unlock(chan); 30157 return 0; 30158 } 30159 30160 if (p->alreadygone) { 30161 /* If we're destroyed, don't bother */ 30162 sip_pvt_unlock(p); 30163 ast_channel_unlock(chan); 30164 return 0; 30165 } 30166 30167 /* if this peer cannot handle reinvites of the media stream to devices 30168 that are known to be behind a NAT, then stop the process now 30169 */ 30170 if (nat_active && !ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA_NAT)) { 30171 sip_pvt_unlock(p); 30172 ast_channel_unlock(chan); 30173 return 0; 30174 } 30175 30176 if (instance) { 30177 changed |= ast_rtp_instance_get_and_cmp_remote_address(instance, &p->redirip); 30178 30179 if (p->rtp) { 30180 /* Prevent audio RTCP reads */ 30181 ast_channel_set_fd(chan, 1, -1); 30182 /* Silence RTCP while audio RTP is inactive */ 30183 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_RTCP, 0); 30184 } 30185 } else if (!ast_sockaddr_isnull(&p->redirip)) { 30186 memset(&p->redirip, 0, sizeof(p->redirip)); 30187 changed = 1; 30188 30189 if (p->rtp) { 30190 /* Enable RTCP since it will be inactive if we're coming back 30191 * from a reinvite */ 30192 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_RTCP, 1); 30193 /* Enable audio RTCP reads */ 30194 ast_channel_set_fd(chan, 1, ast_rtp_instance_fd(p->rtp, 1)); 30195 } 30196 } 30197 30198 if (vinstance) { 30199 changed |= ast_rtp_instance_get_and_cmp_remote_address(vinstance, &p->vredirip); 30200 30201 if (p->vrtp) { 30202 /* Prevent video RTCP reads */ 30203 ast_channel_set_fd(chan, 3, -1); 30204 /* Silence RTCP while video RTP is inactive */ 30205 ast_rtp_instance_set_prop(p->vrtp, AST_RTP_PROPERTY_RTCP, 0); 30206 } 30207 } else if (!ast_sockaddr_isnull(&p->vredirip)) { 30208 memset(&p->vredirip, 0, sizeof(p->vredirip)); 30209 changed = 1; 30210 30211 if (p->vrtp) { 30212 /* Enable RTCP since it will be inactive if we're coming back 30213 * from a reinvite */ 30214 ast_rtp_instance_set_prop(p->vrtp, AST_RTP_PROPERTY_RTCP, 1); 30215 /* Enable video RTCP reads */ 30216 ast_channel_set_fd(chan, 3, ast_rtp_instance_fd(p->vrtp, 1)); 30217 } 30218 } 30219 30220 if (tinstance) { 30221 changed |= ast_rtp_instance_get_and_cmp_remote_address(tinstance, &p->tredirip); 30222 } else if (!ast_sockaddr_isnull(&p->tredirip)) { 30223 memset(&p->tredirip, 0, sizeof(p->tredirip)); 30224 changed = 1; 30225 } 30226 if (codecs && (p->redircodecs != codecs)) { 30227 p->redircodecs = codecs; 30228 changed = 1; 30229 } 30230 30231 if (ast_test_flag(&p->flags[2], SIP_PAGE3_DIRECT_MEDIA_OUTGOING) && !p->outgoing_call) { 30232 /* We only wish to withhold sending the initial direct media reinvite on the incoming dialog. 30233 * Further direct media reinvites beyond the initial should be sent. In order to allow further 30234 * direct media reinvites to be sent, we clear this flag. 30235 */ 30236 ast_clear_flag(&p->flags[2], SIP_PAGE3_DIRECT_MEDIA_OUTGOING); 30237 sip_pvt_unlock(p); 30238 ast_channel_unlock(chan); 30239 return 0; 30240 } 30241 30242 if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 30243 if (chan->_state != AST_STATE_UP) { /* We are in early state */ 30244 if (p->do_history) 30245 append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal."); 30246 ast_debug(1, "Early remote bridge setting SIP '%s' - Sending media to %s\n", p->callid, ast_sockaddr_stringify(instance ? &p->redirip : &p->ourip)); 30247 } else if (!p->pendinginvite) { /* We are up, and have no outstanding invite */ 30248 ast_debug(3, "Sending reinvite on SIP '%s' - It's audio soon redirected to IP %s\n", p->callid, ast_sockaddr_stringify(instance ? &p->redirip : &p->ourip)); 30249 transmit_reinvite_with_sdp(p, FALSE, FALSE); 30250 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 30251 ast_debug(3, "Deferring reinvite on SIP '%s' - It's audio will be redirected to IP %s\n", p->callid, ast_sockaddr_stringify(instance ? &p->redirip : &p->ourip)); 30252 /* We have a pending Invite. Send re-invite when we're done with the invite */ 30253 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 30254 } 30255 } 30256 /* Reset lastrtprx timer */ 30257 p->lastrtprx = p->lastrtptx = time(NULL); 30258 sip_pvt_unlock(p); 30259 ast_channel_unlock(chan); 30260 return 0; 30261 }
| static int sip_set_udptl_peer | ( | struct ast_channel * | chan, | |
| struct ast_udptl * | udptl | |||
| ) | [static] |
Definition at line 29931 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_debug, ast_set_flag, ast_sockaddr_stringify(), ast_test_flag, ast_udptl_get_peer(), FALSE, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), and TRUE.
29932 { 29933 struct sip_pvt *p; 29934 29935 /* Lock the channel and the private safely. */ 29936 ast_channel_lock(chan); 29937 p = chan->tech_pvt; 29938 if (!p) { 29939 ast_channel_unlock(chan); 29940 return -1; 29941 } 29942 sip_pvt_lock(p); 29943 if (p->owner != chan) { 29944 /* I suppose it could be argued that if this happens it is a bug. */ 29945 ast_debug(1, "The private is not owned by channel %s anymore.\n", chan->name); 29946 sip_pvt_unlock(p); 29947 ast_channel_unlock(chan); 29948 return 0; 29949 } 29950 29951 if (udptl) { 29952 ast_udptl_get_peer(udptl, &p->udptlredirip); 29953 } else { 29954 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 29955 } 29956 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 29957 if (!p->pendinginvite) { 29958 ast_debug(3, "Sending reinvite on SIP '%s' - It's UDPTL soon redirected to IP %s\n", 29959 p->callid, ast_sockaddr_stringify(udptl ? &p->udptlredirip : &p->ourip)); 29960 transmit_reinvite_with_sdp(p, TRUE, FALSE); 29961 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 29962 ast_debug(3, "Deferring reinvite on SIP '%s' - It's UDPTL will be redirected to IP %s\n", 29963 p->callid, ast_sockaddr_stringify(udptl ? &p->udptlredirip : &p->ourip)); 29964 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 29965 } 29966 } 29967 /* Reset lastrtprx timer */ 29968 p->lastrtprx = p->lastrtptx = time(NULL); 29969 sip_pvt_unlock(p); 29970 ast_channel_unlock(chan); 29971 return 0; 29972 }
| static int sip_setoption | ( | struct ast_channel * | chan, | |
| int | option, | |||
| void * | data, | |||
| int | datalen | |||
| ) | [static] |
Set an option on a SIP dialog.
Definition at line 4494 of file chan_sip.c.
References ast_debug, ast_log(), AST_OPTION_DIGIT_DETECT, AST_OPTION_FORMAT_READ, AST_OPTION_FORMAT_WRITE, AST_OPTION_MAKE_COMPATIBLE, AST_OPTION_SECURE_MEDIA, AST_OPTION_SECURE_SIGNALING, ast_rtp_instance_make_compatible(), ast_rtp_instance_set_read_format(), ast_rtp_instance_set_write_format(), ast_set2_flag, ast_test_flag, disable_dsp_detect(), enable_dsp_detect(), LOG_ERROR, sip_pvt_lock, sip_pvt_unlock, and ast_channel::tech_pvt.
04495 { 04496 int res = -1; 04497 struct sip_pvt *p = chan->tech_pvt; 04498 04499 if (!p) { 04500 ast_log(LOG_ERROR, "Attempt to Ref a null pointer. sip private structure is gone!\n"); 04501 return -1; 04502 } 04503 04504 sip_pvt_lock(p); 04505 04506 switch (option) { 04507 case AST_OPTION_FORMAT_READ: 04508 if (p->rtp) { 04509 res = ast_rtp_instance_set_read_format(p->rtp, *(int *) data); 04510 } 04511 break; 04512 case AST_OPTION_FORMAT_WRITE: 04513 if (p->rtp) { 04514 res = ast_rtp_instance_set_write_format(p->rtp, *(int *) data); 04515 } 04516 break; 04517 case AST_OPTION_MAKE_COMPATIBLE: 04518 if (p->rtp) { 04519 res = ast_rtp_instance_make_compatible(chan, p->rtp, (struct ast_channel *) data); 04520 } 04521 break; 04522 case AST_OPTION_DIGIT_DETECT: 04523 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || 04524 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) { 04525 char *cp = (char *) data; 04526 04527 ast_debug(1, "%sabling digit detection on %s\n", *cp ? "En" : "Dis", chan->name); 04528 if (*cp) { 04529 enable_dsp_detect(p); 04530 } else { 04531 disable_dsp_detect(p); 04532 } 04533 res = 0; 04534 } 04535 break; 04536 case AST_OPTION_SECURE_SIGNALING: 04537 p->req_secure_signaling = *(unsigned int *) data; 04538 res = 0; 04539 break; 04540 case AST_OPTION_SECURE_MEDIA: 04541 ast_set2_flag(&p->flags[1], *(unsigned int *) data, SIP_PAGE2_USE_SRTP); 04542 res = 0; 04543 break; 04544 default: 04545 break; 04546 } 04547 04548 sip_pvt_unlock(p); 04549 04550 return res; 04551 }
| static char * sip_show_channel | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Show details of one active dialog.
Definition at line 19228 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ao2_t_ref, ast_cli_args::argc, ast_cli_args::argv, ARRAY_LEN, ast_cli(), AST_CLI_YESNO, ast_getformatname_multiple(), ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_strlen_zero(), ast_test_flag, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sipch(), dtmfmode2str(), ast_cli_args::fd, len(), ast_cli_args::line, ast_cli_args::n, NONE, ast_cli_args::pos, sip_pvt_lock, sip_pvt_unlock, stmode2str(), strefresher2str(), strefresherparam2str(), subscription_type2str(), transfermode2str(), transport2str(), TRUE, ast_cli_entry::usage, and ast_cli_args::word.
19229 { 19230 struct sip_pvt *cur; 19231 size_t len; 19232 int found = 0; 19233 struct ao2_iterator i; 19234 19235 switch (cmd) { 19236 case CLI_INIT: 19237 e->command = "sip show channel"; 19238 e->usage = 19239 "Usage: sip show channel <call-id>\n" 19240 " Provides detailed status on a given SIP dialog (identified by SIP call-id).\n"; 19241 return NULL; 19242 case CLI_GENERATE: 19243 return complete_sipch(a->line, a->word, a->pos, a->n); 19244 } 19245 19246 if (a->argc != 4) 19247 return CLI_SHOWUSAGE; 19248 len = strlen(a->argv[3]); 19249 19250 i = ao2_iterator_init(dialogs, 0); 19251 while ((cur = ao2_t_iterator_next(&i, "iterate thru dialogs"))) { 19252 sip_pvt_lock(cur); 19253 19254 if (!strncasecmp(cur->callid, a->argv[3], len)) { 19255 char formatbuf[SIPBUFSIZE/2]; 19256 ast_cli(a->fd, "\n"); 19257 if (cur->subscribed != NONE) 19258 ast_cli(a->fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); 19259 else 19260 ast_cli(a->fd, " * SIP Call\n"); 19261 ast_cli(a->fd, " Curr. trans. direction: %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming"); 19262 ast_cli(a->fd, " Call-ID: %s\n", cur->callid); 19263 ast_cli(a->fd, " Owner channel ID: %s\n", cur->owner ? cur->owner->name : "<none>"); 19264 ast_cli(a->fd, " Our Codec Capability: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->capability)); 19265 ast_cli(a->fd, " Non-Codec Capability (DTMF): %d\n", cur->noncodeccapability); 19266 ast_cli(a->fd, " Their Codec Capability: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->peercapability)); 19267 ast_cli(a->fd, " Joint Codec Capability: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->jointcapability)); 19268 ast_cli(a->fd, " Format: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) ); 19269 ast_cli(a->fd, " T.38 support %s\n", AST_CLI_YESNO(cur->udptl != NULL)); 19270 ast_cli(a->fd, " Video support %s\n", AST_CLI_YESNO(cur->vrtp != NULL)); 19271 ast_cli(a->fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate); 19272 ast_cli(a->fd, " Theoretical Address: %s\n", ast_sockaddr_stringify(&cur->sa)); 19273 ast_cli(a->fd, " Received Address: %s\n", ast_sockaddr_stringify(&cur->recv)); 19274 ast_cli(a->fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer)); 19275 ast_cli(a->fd, " Force rport: %s\n", AST_CLI_YESNO(ast_test_flag(&cur->flags[0], SIP_NAT_FORCE_RPORT))); 19276 if (ast_sockaddr_isnull(&cur->redirip)) { 19277 ast_cli(a->fd, 19278 " Audio IP: %s (local)\n", 19279 ast_sockaddr_stringify_addr(&cur->ourip)); 19280 } else { 19281 ast_cli(a->fd, 19282 " Audio IP: %s (Outside bridge)\n", 19283 ast_sockaddr_stringify_addr(&cur->redirip)); 19284 } 19285 ast_cli(a->fd, " Our Tag: %s\n", cur->tag); 19286 ast_cli(a->fd, " Their Tag: %s\n", cur->theirtag); 19287 ast_cli(a->fd, " SIP User agent: %s\n", cur->useragent); 19288 if (!ast_strlen_zero(cur->username)) 19289 ast_cli(a->fd, " Username: %s\n", cur->username); 19290 if (!ast_strlen_zero(cur->peername)) 19291 ast_cli(a->fd, " Peername: %s\n", cur->peername); 19292 if (!ast_strlen_zero(cur->uri)) 19293 ast_cli(a->fd, " Original uri: %s\n", cur->uri); 19294 if (!ast_strlen_zero(cur->cid_num)) 19295 ast_cli(a->fd, " Caller-ID: %s\n", cur->cid_num); 19296 ast_cli(a->fd, " Need Destroy: %s\n", AST_CLI_YESNO(cur->needdestroy)); 19297 ast_cli(a->fd, " Last Message: %s\n", cur->lastmsg); 19298 ast_cli(a->fd, " Promiscuous Redir: %s\n", AST_CLI_YESNO(ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR))); 19299 ast_cli(a->fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); 19300 ast_cli(a->fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF))); 19301 ast_cli(a->fd, " SIP Options: "); 19302 if (cur->sipoptions) { 19303 int x; 19304 for (x = 0 ; x < ARRAY_LEN(sip_options); x++) { 19305 if (cur->sipoptions & sip_options[x].id) 19306 ast_cli(a->fd, "%s ", sip_options[x].text); 19307 } 19308 ast_cli(a->fd, "\n"); 19309 } else 19310 ast_cli(a->fd, "(none)\n"); 19311 19312 if (!cur->stimer) 19313 ast_cli(a->fd, " Session-Timer: Uninitiallized\n"); 19314 else { 19315 ast_cli(a->fd, " Session-Timer: %s\n", cur->stimer->st_active ? "Active" : "Inactive"); 19316 if (cur->stimer->st_active == TRUE) { 19317 ast_cli(a->fd, " S-Timer Interval: %d\n", cur->stimer->st_interval); 19318 ast_cli(a->fd, " S-Timer Refresher: %s\n", strefresher2str(cur->stimer->st_ref)); 19319 ast_cli(a->fd, " S-Timer Sched Id: %d\n", cur->stimer->st_schedid); 19320 ast_cli(a->fd, " S-Timer Peer Sts: %s\n", cur->stimer->st_active_peer_ua ? "Active" : "Inactive"); 19321 ast_cli(a->fd, " S-Timer Cached Min-SE: %d\n", cur->stimer->st_cached_min_se); 19322 ast_cli(a->fd, " S-Timer Cached SE: %d\n", cur->stimer->st_cached_max_se); 19323 ast_cli(a->fd, " S-Timer Cached Ref: %s\n", strefresherparam2str(cur->stimer->st_cached_ref)); 19324 ast_cli(a->fd, " S-Timer Cached Mode: %s\n", stmode2str(cur->stimer->st_cached_mode)); 19325 } 19326 } 19327 19328 /* add transport and media types */ 19329 ast_cli(a->fd, " Transport: %s\n", transport2str(cur->socket.type)); 19330 ast_cli(a->fd, " Media: %s\n", cur->srtp ? "SRTP" : cur->rtp ? "RTP" : "None"); 19331 19332 ast_cli(a->fd, "\n\n"); 19333 19334 found++; 19335 } 19336 19337 sip_pvt_unlock(cur); 19338 19339 ao2_t_ref(cur, -1, "toss dialog ptr set by iterator_next"); 19340 } 19341 ao2_iterator_destroy(&i); 19342 19343 if (!found) 19344 ast_cli(a->fd, "No such SIP Call ID starting with '%s'\n", a->argv[3]); 19345 19346 return CLI_SUCCESS; 19347 }
| static char* sip_show_channels | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
CLI for show channels or subscriptions. This is a new-style CLI handler so a single function contains the prototype for the function, the 'generator' to produce multiple entries in case it is required, and the actual handler for the command.
Definition at line 19035 of file chan_sip.c.
References ao2_t_callback, ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ESS, ast_cli_args::fd, FORMAT2, FORMAT3, OBJ_NODATA, show_channels_cb(), and ast_cli_entry::usage.
19036 { 19037 struct __show_chan_arg arg = { .fd = a->fd, .numchans = 0 }; 19038 19039 19040 if (cmd == CLI_INIT) { 19041 e->command = "sip show {channels|subscriptions}"; 19042 e->usage = 19043 "Usage: sip show channels\n" 19044 " Lists all currently active SIP calls (dialogs).\n" 19045 "Usage: sip show subscriptions\n" 19046 " Lists active SIP subscriptions.\n"; 19047 return NULL; 19048 } else if (cmd == CLI_GENERATE) 19049 return NULL; 19050 19051 if (a->argc != e->args) 19052 return CLI_SHOWUSAGE; 19053 arg.subscriptions = !strcasecmp(a->argv[e->args - 1], "subscriptions"); 19054 if (!arg.subscriptions) 19055 ast_cli(arg.fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Format", "Hold", "Last Message", "Expiry", "Peer"); 19056 else 19057 ast_cli(arg.fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox", "Expiry"); 19058 19059 /* iterate on the container and invoke the callback on each item */ 19060 ao2_t_callback(dialogs, OBJ_NODATA, show_channels_cb, &arg, "callback to show channels"); 19061 19062 /* print summary information */ 19063 ast_cli(arg.fd, "%d active SIP %s%s\n", arg.numchans, 19064 (arg.subscriptions ? "subscription" : "dialog"), 19065 ESS(arg.numchans)); /* ESS(n) returns an "s" if n>1 */ 19066 return CLI_SUCCESS; 19067 #undef FORMAT 19068 #undef FORMAT2 19069 #undef FORMAT3 19070 }
| static char * sip_show_channelstats | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
SIP show channelstats CLI (main function).
Definition at line 18656 of file chan_sip.c.
References ao2_t_callback, ast_cli_args::argc, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, FORMAT2, OBJ_NODATA, show_chanstats_cb(), and ast_cli_entry::usage.
18657 { 18658 struct __show_chan_arg arg = { .fd = a->fd, .numchans = 0 }; 18659 18660 switch (cmd) { 18661 case CLI_INIT: 18662 e->command = "sip show channelstats"; 18663 e->usage = 18664 "Usage: sip show channelstats\n" 18665 " Lists all currently active SIP channel's RTCP statistics.\n" 18666 " Note that calls in the much optimized RTP P2P bridge mode will not show any packets here."; 18667 return NULL; 18668 case CLI_GENERATE: 18669 return NULL; 18670 } 18671 18672 if (a->argc != 3) 18673 return CLI_SHOWUSAGE; 18674 18675 ast_cli(a->fd, FORMAT2, "Peer", "Call ID", "Duration", "Recv: Pack", "Lost", "Jitter", "Send: Pack", "Lost", "Jitter"); 18676 /* iterate on the container and invoke the callback on each item */ 18677 ao2_t_callback(dialogs, OBJ_NODATA, show_chanstats_cb, &arg, "callback to sip show chanstats"); 18678 ast_cli(a->fd, "%d active SIP channel%s\n", arg.numchans, (arg.numchans != 1) ? "s" : ""); 18679 return CLI_SUCCESS; 18680 }
| static char * sip_show_domains | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
CLI command to list local domains.
Definition at line 17904 of file chan_sip.c.
References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, domain_mode_to_text(), ast_cli_args::fd, FORMAT, S_OR, and ast_cli_entry::usage.
17905 { 17906 struct domain *d; 17907 #define FORMAT "%-40.40s %-20.20s %-16.16s\n" 17908 17909 switch (cmd) { 17910 case CLI_INIT: 17911 e->command = "sip show domains"; 17912 e->usage = 17913 "Usage: sip show domains\n" 17914 " Lists all configured SIP local domains.\n" 17915 " Asterisk only responds to SIP messages to local domains.\n"; 17916 return NULL; 17917 case CLI_GENERATE: 17918 return NULL; 17919 } 17920 17921 if (AST_LIST_EMPTY(&domain_list)) { 17922 ast_cli(a->fd, "SIP Domain support not enabled.\n\n"); 17923 return CLI_SUCCESS; 17924 } else { 17925 ast_cli(a->fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); 17926 AST_LIST_LOCK(&domain_list); 17927 AST_LIST_TRAVERSE(&domain_list, d, list) 17928 ast_cli(a->fd, FORMAT, d->domain, S_OR(d->context, "(default)"), 17929 domain_mode_to_text(d->mode)); 17930 AST_LIST_UNLOCK(&domain_list); 17931 ast_cli(a->fd, "\n"); 17932 return CLI_SUCCESS; 17933 } 17934 }
| static char * sip_show_history | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Show history details of one dialog.
Definition at line 19350 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ao2_t_ref, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_LIST_TRAVERSE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sip_show_history(), ast_cli_args::fd, len(), ast_cli_args::line, ast_cli_args::n, NONE, ast_cli_args::pos, sip_pvt_lock, sip_pvt_unlock, ast_cli_entry::usage, and ast_cli_args::word.
19351 { 19352 struct sip_pvt *cur; 19353 size_t len; 19354 int found = 0; 19355 struct ao2_iterator i; 19356 19357 switch (cmd) { 19358 case CLI_INIT: 19359 e->command = "sip show history"; 19360 e->usage = 19361 "Usage: sip show history <call-id>\n" 19362 " Provides detailed dialog history on a given SIP call (specified by call-id).\n"; 19363 return NULL; 19364 case CLI_GENERATE: 19365 return complete_sip_show_history(a->line, a->word, a->pos, a->n); 19366 } 19367 19368 if (a->argc != 4) 19369 return CLI_SHOWUSAGE; 19370 19371 if (!recordhistory) 19372 ast_cli(a->fd, "\n***Note: History recording is currently DISABLED. Use 'sip set history on' to ENABLE.\n"); 19373 19374 len = strlen(a->argv[3]); 19375 19376 i = ao2_iterator_init(dialogs, 0); 19377 while ((cur = ao2_t_iterator_next(&i, "iterate thru dialogs"))) { 19378 sip_pvt_lock(cur); 19379 if (!strncasecmp(cur->callid, a->argv[3], len)) { 19380 struct sip_history *hist; 19381 int x = 0; 19382 19383 ast_cli(a->fd, "\n"); 19384 if (cur->subscribed != NONE) 19385 ast_cli(a->fd, " * Subscription\n"); 19386 else 19387 ast_cli(a->fd, " * SIP Call\n"); 19388 if (cur->history) 19389 AST_LIST_TRAVERSE(cur->history, hist, list) 19390 ast_cli(a->fd, "%d. %s\n", ++x, hist->event); 19391 if (x == 0) 19392 ast_cli(a->fd, "Call '%s' has no history\n", cur->callid); 19393 found++; 19394 } 19395 sip_pvt_unlock(cur); 19396 ao2_t_ref(cur, -1, "toss dialog ptr from iterator_next"); 19397 } 19398 ao2_iterator_destroy(&i); 19399 19400 if (!found) 19401 ast_cli(a->fd, "No such SIP Call ID starting with '%s'\n", a->argv[3]); 19402 19403 return CLI_SUCCESS; 19404 }
| static char * sip_show_inuse | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
CLI Command to show calls within limits set by call_limit.
Definition at line 16938 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_iterator_next, ao2_unlock, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_copy_string(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, FALSE, ast_cli_args::fd, FORMAT, FORMAT2, TRUE, unref_peer(), and ast_cli_entry::usage.
16939 { 16940 #define FORMAT "%-25.25s %-15.15s %-15.15s \n" 16941 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" 16942 char ilimits[40]; 16943 char iused[40]; 16944 int showall = FALSE; 16945 struct ao2_iterator i; 16946 struct sip_peer *peer; 16947 16948 switch (cmd) { 16949 case CLI_INIT: 16950 e->command = "sip show inuse"; 16951 e->usage = 16952 "Usage: sip show inuse [all]\n" 16953 " List all SIP devices usage counters and limits.\n" 16954 " Add option \"all\" to show all devices, not only those with a limit.\n"; 16955 return NULL; 16956 case CLI_GENERATE: 16957 return NULL; 16958 } 16959 16960 if (a->argc < 3) 16961 return CLI_SHOWUSAGE; 16962 16963 if (a->argc == 4 && !strcmp(a->argv[3], "all")) 16964 showall = TRUE; 16965 16966 ast_cli(a->fd, FORMAT, "* Peer name", "In use", "Limit"); 16967 16968 i = ao2_iterator_init(peers, 0); 16969 while ((peer = ao2_t_iterator_next(&i, "iterate thru peer table"))) { 16970 ao2_lock(peer); 16971 if (peer->call_limit) 16972 snprintf(ilimits, sizeof(ilimits), "%d", peer->call_limit); 16973 else 16974 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 16975 snprintf(iused, sizeof(iused), "%d/%d/%d", peer->inUse, peer->inRinging, peer->onHold); 16976 if (showall || peer->call_limit) 16977 ast_cli(a->fd, FORMAT2, peer->name, iused, ilimits); 16978 ao2_unlock(peer); 16979 unref_peer(peer, "toss iterator pointer"); 16980 } 16981 ao2_iterator_destroy(&i); 16982 16983 return CLI_SUCCESS; 16984 #undef FORMAT 16985 #undef FORMAT2 16986 }
| static char * sip_show_mwi | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 18914 of file chan_sip.c.
References ast_cli(), AST_CLI_YESNO, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, FORMAT, submwil, and ast_cli_entry::usage.
18915 { 18916 #define FORMAT "%-30.30s %-12.12s %-10.10s %-10.10s\n" 18917 char host[80]; 18918 18919 switch (cmd) { 18920 case CLI_INIT: 18921 e->command = "sip show mwi"; 18922 e->usage = 18923 "Usage: sip show mwi\n" 18924 " Provides a list of MWI subscriptions and status.\n"; 18925 return NULL; 18926 case CLI_GENERATE: 18927 return NULL; 18928 } 18929 18930 ast_cli(a->fd, FORMAT, "Host", "Username", "Mailbox", "Subscribed"); 18931 18932 ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do { 18933 ASTOBJ_RDLOCK(iterator); 18934 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); 18935 ast_cli(a->fd, FORMAT, host, iterator->username, iterator->mailbox, AST_CLI_YESNO(iterator->subscribed)); 18936 ASTOBJ_UNLOCK(iterator); 18937 } while(0)); 18938 18939 return CLI_SUCCESS; 18940 #undef FORMAT 18941 }
| static char * sip_show_objects | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
List all allocated SIP Objects (realtime or static).
Definition at line 17525 of file chan_sip.c.
References ao2_t_callback, ast_cli_args::argc, ast_cli(), ASTOBJ_CONTAINER_DUMP, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, dialog_dump_func(), ast_cli_args::fd, OBJ_NODATA, peer_dump_func(), regl, and ast_cli_entry::usage.
17526 { 17527 char tmp[256]; 17528 17529 switch (cmd) { 17530 case CLI_INIT: 17531 e->command = "sip show objects"; 17532 e->usage = 17533 "Usage: sip show objects\n" 17534 " Lists status of known SIP objects\n"; 17535 return NULL; 17536 case CLI_GENERATE: 17537 return NULL; 17538 } 17539 17540 if (a->argc != 3) 17541 return CLI_SHOWUSAGE; 17542 ast_cli(a->fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs); 17543 ao2_t_callback(peers, OBJ_NODATA, peer_dump_func, a, "initiate ao2_callback to dump peers"); 17544 ast_cli(a->fd, "-= Peer objects by IP =-\n\n"); 17545 ao2_t_callback(peers_by_ip, OBJ_NODATA, peer_dump_func, a, "initiate ao2_callback to dump peers_by_ip"); 17546 ast_cli(a->fd, "-= Registry objects: %d =-\n\n", regobjs); 17547 ASTOBJ_CONTAINER_DUMP(a->fd, tmp, sizeof(tmp), ®l); 17548 ast_cli(a->fd, "-= Dialog objects:\n\n"); 17549 ao2_t_callback(dialogs, OBJ_NODATA, dialog_dump_func, a, "initiate ao2_callback to dump dialogs"); 17550 return CLI_SUCCESS; 17551 }
| static char * sip_show_peer | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Show one peer in detail.
Definition at line 17959 of file chan_sip.c.
References _sip_show_peer(), ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, complete_sip_show_peer(), ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.
17960 { 17961 switch (cmd) { 17962 case CLI_INIT: 17963 e->command = "sip show peer"; 17964 e->usage = 17965 "Usage: sip show peer <name> [load]\n" 17966 " Shows all details on one SIP peer and the current status.\n" 17967 " Option \"load\" forces lookup of peer in realtime storage.\n"; 17968 return NULL; 17969 case CLI_GENERATE: 17970 return complete_sip_show_peer(a->line, a->word, a->pos, a->n); 17971 } 17972 return _sip_show_peer(0, a->fd, NULL, NULL, a->argc, (const char **) a->argv); 17973 }
| static char * sip_show_peers | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
CLI Show Peers command.
Definition at line 17261 of file chan_sip.c.
References _sip_show_peers(), ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.
17262 { 17263 switch (cmd) { 17264 case CLI_INIT: 17265 e->command = "sip show peers"; 17266 e->usage = 17267 "Usage: sip show peers [like <pattern>]\n" 17268 " Lists all known SIP peers.\n" 17269 " Optional regular expression pattern is used to filter the peer list.\n"; 17270 return NULL; 17271 case CLI_GENERATE: 17272 return NULL; 17273 } 17274 17275 return _sip_show_peers(a->fd, NULL, NULL, NULL, a->argc, (const char **) a->argv); 17276 }
| static char * sip_show_registry | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Show SIP Registry (registrations with other SIP proxies.
Definition at line 18494 of file chan_sip.c.
References ast_cli_args::argc, ast_cli(), ast_localtime(), ast_strftime(), ast_strlen_zero(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, FORMAT, FORMAT2, regl, regstate2str(), and ast_cli_entry::usage.
18495 { 18496 #define FORMAT2 "%-39.39s %-6.6s %-12.12s %8.8s %-20.20s %-25.25s\n" 18497 #define FORMAT "%-39.39s %-6.6s %-12.12s %8d %-20.20s %-25.25s\n" 18498 char host[80]; 18499 char user[80]; 18500 char tmpdat[256]; 18501 struct ast_tm tm; 18502 int counter = 0; 18503 18504 switch (cmd) { 18505 case CLI_INIT: 18506 e->command = "sip show registry"; 18507 e->usage = 18508 "Usage: sip show registry\n" 18509 " Lists all registration requests and status.\n"; 18510 return NULL; 18511 case CLI_GENERATE: 18512 return NULL; 18513 } 18514 18515 if (a->argc != 3) 18516 return CLI_SHOWUSAGE; 18517 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Refresh", "State", "Reg.Time"); 18518 18519 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 18520 ASTOBJ_RDLOCK(iterator); 18521 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); 18522 snprintf(user, sizeof(user), "%s", iterator->username); 18523 if (!ast_strlen_zero(iterator->regdomain)) { 18524 snprintf(tmpdat, sizeof(tmpdat), "%s", user); 18525 snprintf(user, sizeof(user), "%s@%s", tmpdat, iterator->regdomain);} 18526 if (iterator->regdomainport) { 18527 snprintf(tmpdat, sizeof(tmpdat), "%s", user); 18528 snprintf(user, sizeof(user), "%s:%d", tmpdat, iterator->regdomainport);} 18529 if (iterator->regtime.tv_sec) { 18530 ast_localtime(&iterator->regtime, &tm, NULL); 18531 ast_strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm); 18532 } else 18533 tmpdat[0] = '\0'; 18534 ast_cli(a->fd, FORMAT, host, (iterator->dnsmgr) ? "Y" : "N", user, iterator->refresh, regstate2str(iterator->regstate), tmpdat); 18535 ASTOBJ_UNLOCK(iterator); 18536 counter++; 18537 } while(0)); 18538 ast_cli(a->fd, "%d SIP registrations.\n", counter); 18539 return CLI_SUCCESS; 18540 #undef FORMAT 18541 #undef FORMAT2 18542 }
| static char * sip_show_sched | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 18451 of file chan_sip.c.
References __sip_autodestruct(), ast_cli(), ast_sched_report(), ast_str_alloca, ast_str_buffer(), auto_congest(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, expire_register(), ast_cli_args::fd, retrans_pkt(), sip_poke_noanswer(), sip_poke_peer_s(), sip_reg_timeout(), sip_reinvite_retry(), sip_reregister(), and ast_cli_entry::usage.
18452 { 18453 struct ast_str *cbuf; 18454 struct ast_cb_names cbnames = {9, { "retrans_pkt", 18455 "__sip_autodestruct", 18456 "expire_register", 18457 "auto_congest", 18458 "sip_reg_timeout", 18459 "sip_poke_peer_s", 18460 "sip_poke_noanswer", 18461 "sip_reregister", 18462 "sip_reinvite_retry"}, 18463 { retrans_pkt, 18464 __sip_autodestruct, 18465 expire_register, 18466 auto_congest, 18467 sip_reg_timeout, 18468 sip_poke_peer_s, 18469 sip_poke_noanswer, 18470 sip_reregister, 18471 sip_reinvite_retry}}; 18472 18473 switch (cmd) { 18474 case CLI_INIT: 18475 e->command = "sip show sched"; 18476 e->usage = 18477 "Usage: sip show sched\n" 18478 " Shows stats on what's in the sched queue at the moment\n"; 18479 return NULL; 18480 case CLI_GENERATE: 18481 return NULL; 18482 } 18483 18484 cbuf = ast_str_alloca(2048); 18485 18486 ast_cli(a->fd, "\n"); 18487 ast_sched_report(sched, &cbuf, &cbnames); 18488 ast_cli(a->fd, "%s", ast_str_buffer(cbuf)); 18489 18490 return CLI_SUCCESS; 18491 }
| static char * sip_show_settings | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
List global settings for the SIP channel.
Definition at line 18685 of file chan_sip.c.
References ast_ha::addr, allowoverlap2str(), ao2_t_ref, ast_cli_args::argc, ast_check_realtime(), ast_cli(), AST_CLI_ONOFF, AST_CLI_YESNO, ast_getformatname_multiple(), AST_JB_ENABLED, AST_JB_FORCED, AST_JB_LOG, AST_LIST_EMPTY, AST_LIST_TRAVERSE, ast_mutex_lock, ast_mutex_unlock, ast_sockaddr_is_any(), ast_sockaddr_is_ipv6(), ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_tos2str(), bindaddr, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, default_prefs, dtmfmode2str(), ast_tls_config::enabled, externaddr, FALSE, faxec2str(), ast_cli_args::fd, get_transport(), get_transport_list(), global_jbconf, ast_jb_conf::impl, ast_tcptls_session_args::local_address, ast_jb_conf::max_size, ast_ha::netmask, ast_ha::next, prefix, print_codec_to_cli(), ast_jb_conf::resync_threshold, S_OR, sip_cfg, stmode2str(), strefresherparam2str(), ast_jb_conf::target_extra, transfermode2str(), and ast_cli_entry::usage.
18686 { 18687 int realtimepeers; 18688 int realtimeregs; 18689 char codec_buf[SIPBUFSIZE]; 18690 const char *msg; /* temporary msg pointer */ 18691 struct sip_auth_container *credentials; 18692 18693 switch (cmd) { 18694 case CLI_INIT: 18695 e->command = "sip show settings"; 18696 e->usage = 18697 "Usage: sip show settings\n" 18698 " Provides detailed list of the configuration of the SIP channel.\n"; 18699 return NULL; 18700 case CLI_GENERATE: 18701 return NULL; 18702 } 18703 18704 if (a->argc != 3) 18705 return CLI_SHOWUSAGE; 18706 18707 realtimepeers = ast_check_realtime("sippeers"); 18708 realtimeregs = ast_check_realtime("sipregs"); 18709 18710 ast_mutex_lock(&authl_lock); 18711 credentials = authl; 18712 if (credentials) { 18713 ao2_t_ref(credentials, +1, "Ref global auth for show"); 18714 } 18715 ast_mutex_unlock(&authl_lock); 18716 18717 ast_cli(a->fd, "\n\nGlobal Settings:\n"); 18718 ast_cli(a->fd, "----------------\n"); 18719 ast_cli(a->fd, " UDP Bindaddress: %s\n", ast_sockaddr_stringify(&bindaddr)); 18720 if (ast_sockaddr_is_ipv6(&bindaddr) && ast_sockaddr_is_any(&bindaddr)) { 18721 ast_cli(a->fd, " ** Additional Info:\n"); 18722 ast_cli(a->fd, " [::] may include IPv4 in addition to IPv6, if such a feature is enabled in the OS.\n"); 18723 } 18724 ast_cli(a->fd, " TCP SIP Bindaddress: %s\n", 18725 sip_cfg.tcp_enabled != FALSE ? 18726 ast_sockaddr_stringify(&sip_tcp_desc.local_address) : 18727 "Disabled"); 18728 ast_cli(a->fd, " TLS SIP Bindaddress: %s\n", 18729 default_tls_cfg.enabled != FALSE ? 18730 ast_sockaddr_stringify(&sip_tls_desc.local_address) : 18731 "Disabled"); 18732 ast_cli(a->fd, " Videosupport: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT))); 18733 ast_cli(a->fd, " Textsupport: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_TEXTSUPPORT))); 18734 ast_cli(a->fd, " Ignore SDP sess. ver.: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_IGNORESDPVERSION))); 18735 ast_cli(a->fd, " AutoCreate Peer: %s\n", AST_CLI_YESNO(sip_cfg.autocreatepeer)); 18736 ast_cli(a->fd, " Match Auth Username: %s\n", AST_CLI_YESNO(global_match_auth_username)); 18737 ast_cli(a->fd, " Allow unknown access: %s\n", AST_CLI_YESNO(sip_cfg.allowguest)); 18738 ast_cli(a->fd, " Allow subscriptions: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))); 18739 ast_cli(a->fd, " Allow overlap dialing: %s\n", allowoverlap2str(ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP))); 18740 ast_cli(a->fd, " Allow promisc. redir: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_PROMISCREDIR))); 18741 ast_cli(a->fd, " Enable call counters: %s\n", AST_CLI_YESNO(global_callcounter)); 18742 ast_cli(a->fd, " SIP domain support: %s\n", AST_CLI_YESNO(!AST_LIST_EMPTY(&domain_list))); 18743 ast_cli(a->fd, " Realm. auth: %s\n", AST_CLI_YESNO(credentials != NULL)); 18744 if (credentials) { 18745 struct sip_auth *auth; 18746 18747 AST_LIST_TRAVERSE(&credentials->list, auth, node) { 18748 ast_cli(a->fd, " Realm. auth entry: Realm %-15.15s User %-10.20s %s\n", 18749 auth->realm, 18750 auth->username, 18751 !ast_strlen_zero(auth->secret) 18752 ? "<Secret set>" 18753 : (!ast_strlen_zero(auth->md5secret) 18754 ? "<MD5secret set>" : "<Not set>")); 18755 } 18756 ao2_t_ref(credentials, -1, "Unref global auth for show"); 18757 } 18758 ast_cli(a->fd, " Our auth realm %s\n", sip_cfg.realm); 18759 ast_cli(a->fd, " Use domains as realms: %s\n", AST_CLI_YESNO(sip_cfg.domainsasrealm)); 18760 ast_cli(a->fd, " Call to non-local dom.: %s\n", AST_CLI_YESNO(sip_cfg.allow_external_domains)); 18761 ast_cli(a->fd, " URI user is phone no: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_USEREQPHONE))); 18762 ast_cli(a->fd, " Always auth rejects: %s\n", AST_CLI_YESNO(sip_cfg.alwaysauthreject)); 18763 ast_cli(a->fd, " Direct RTP setup: %s\n", AST_CLI_YESNO(sip_cfg.directrtpsetup)); 18764 ast_cli(a->fd, " User Agent: %s\n", global_useragent); 18765 ast_cli(a->fd, " SDP Session Name: %s\n", ast_strlen_zero(global_sdpsession) ? "-" : global_sdpsession); 18766 ast_cli(a->fd, " SDP Owner Name: %s\n", ast_strlen_zero(global_sdpowner) ? "-" : global_sdpowner); 18767 ast_cli(a->fd, " Reg. context: %s\n", S_OR(sip_cfg.regcontext, "(not set)")); 18768 ast_cli(a->fd, " Regexten on Qualify: %s\n", AST_CLI_YESNO(sip_cfg.regextenonqualify)); 18769 ast_cli(a->fd, " Legacy userfield parse: %s\n", AST_CLI_YESNO(sip_cfg.legacy_useroption_parsing)); 18770 ast_cli(a->fd, " Caller ID: %s\n", default_callerid); 18771 if ((default_fromdomainport) && (default_fromdomainport != STANDARD_SIP_PORT)) { 18772 ast_cli(a->fd, " From: Domain: %s:%d\n", default_fromdomain, default_fromdomainport); 18773 } else { 18774 ast_cli(a->fd, " From: Domain: %s\n", default_fromdomain); 18775 } 18776 ast_cli(a->fd, " Record SIP history: %s\n", AST_CLI_ONOFF(recordhistory)); 18777 ast_cli(a->fd, " Call Events: %s\n", AST_CLI_ONOFF(sip_cfg.callevents)); 18778 ast_cli(a->fd, " Auth. Failure Events: %s\n", AST_CLI_ONOFF(global_authfailureevents)); 18779 18780 ast_cli(a->fd, " T.38 support: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT))); 18781 ast_cli(a->fd, " T.38 EC mode: %s\n", faxec2str(ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT))); 18782 ast_cli(a->fd, " T.38 MaxDtgrm: %u\n", global_t38_maxdatagram); 18783 if (!realtimepeers && !realtimeregs) 18784 ast_cli(a->fd, " SIP realtime: Disabled\n" ); 18785 else 18786 ast_cli(a->fd, " SIP realtime: Enabled\n" ); 18787 ast_cli(a->fd, " Qualify Freq : %d ms\n", global_qualifyfreq); 18788 ast_cli(a->fd, " Q.850 Reason header: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_Q850_REASON))); 18789 ast_cli(a->fd, " Store SIP_CAUSE: %s\n", AST_CLI_YESNO(global_store_sip_cause)); 18790 ast_cli(a->fd, "\nNetwork QoS Settings:\n"); 18791 ast_cli(a->fd, "---------------------------\n"); 18792 ast_cli(a->fd, " IP ToS SIP: %s\n", ast_tos2str(global_tos_sip)); 18793 ast_cli(a->fd, " IP ToS RTP audio: %s\n", ast_tos2str(global_tos_audio)); 18794 ast_cli(a->fd, " IP ToS RTP video: %s\n", ast_tos2str(global_tos_video)); 18795 ast_cli(a->fd, " IP ToS RTP text: %s\n", ast_tos2str(global_tos_text)); 18796 ast_cli(a->fd, " 802.1p CoS SIP: %u\n", global_cos_sip); 18797 ast_cli(a->fd, " 802.1p CoS RTP audio: %u\n", global_cos_audio); 18798 ast_cli(a->fd, " 802.1p CoS RTP video: %u\n", global_cos_video); 18799 ast_cli(a->fd, " 802.1p CoS RTP text: %u\n", global_cos_text); 18800 ast_cli(a->fd, " Jitterbuffer enabled: %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_ENABLED))); 18801 if (ast_test_flag(&global_jbconf, AST_JB_ENABLED)) { 18802 ast_cli(a->fd, " Jitterbuffer forced: %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_FORCED))); 18803 ast_cli(a->fd, " Jitterbuffer max size: %ld\n", global_jbconf.max_size); 18804 ast_cli(a->fd, " Jitterbuffer resync: %ld\n", global_jbconf.resync_threshold); 18805 ast_cli(a->fd, " Jitterbuffer impl: %s\n", global_jbconf.impl); 18806 if (!strcasecmp(global_jbconf.impl, "adaptive")) { 18807 ast_cli(a->fd, " Jitterbuffer tgt extra: %ld\n", global_jbconf.target_extra); 18808 } 18809 ast_cli(a->fd, " Jitterbuffer log: %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_LOG))); 18810 } 18811 18812 ast_cli(a->fd, "\nNetwork Settings:\n"); 18813 ast_cli(a->fd, "---------------------------\n"); 18814 /* determine if/how SIP address can be remapped */ 18815 if (localaddr == NULL) 18816 msg = "Disabled, no localnet list"; 18817 else if (ast_sockaddr_isnull(&externaddr)) 18818 msg = "Disabled"; 18819 else if (!ast_strlen_zero(externhost)) 18820 msg = "Enabled using externhost"; 18821 else 18822 msg = "Enabled using externaddr"; 18823 ast_cli(a->fd, " SIP address remapping: %s\n", msg); 18824 ast_cli(a->fd, " Externhost: %s\n", S_OR(externhost, "<none>")); 18825 ast_cli(a->fd, " Externaddr: %s\n", ast_sockaddr_stringify(&externaddr)); 18826 ast_cli(a->fd, " Externrefresh: %d\n", externrefresh); 18827 { 18828 struct ast_ha *d; 18829 const char *prefix = "Localnet:"; 18830 18831 for (d = localaddr; d ; prefix = "", d = d->next) { 18832 const char *addr = ast_strdupa(ast_sockaddr_stringify_addr(&d->addr)); 18833 const char *mask = ast_strdupa(ast_sockaddr_stringify_addr(&d->netmask)); 18834 ast_cli(a->fd, " %-24s%s/%s\n", prefix, addr, mask); 18835 } 18836 } 18837 ast_cli(a->fd, "\nGlobal Signalling Settings:\n"); 18838 ast_cli(a->fd, "---------------------------\n"); 18839 ast_cli(a->fd, " Codecs: "); 18840 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, sip_cfg.capability); 18841 ast_cli(a->fd, "%s\n", codec_buf); 18842 ast_cli(a->fd, " Codec Order: "); 18843 print_codec_to_cli(a->fd, &default_prefs); 18844 ast_cli(a->fd, "\n"); 18845 ast_cli(a->fd, " Relax DTMF: %s\n", AST_CLI_YESNO(global_relaxdtmf)); 18846 ast_cli(a->fd, " RFC2833 Compensation: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE))); 18847 ast_cli(a->fd, " Symmetric RTP: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_SYMMETRICRTP))); 18848 ast_cli(a->fd, " Compact SIP headers: %s\n", AST_CLI_YESNO(sip_cfg.compactheaders)); 18849 ast_cli(a->fd, " RTP Keepalive: %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" ); 18850 ast_cli(a->fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" ); 18851 ast_cli(a->fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)"); 18852 ast_cli(a->fd, " MWI NOTIFY mime type: %s\n", default_notifymime); 18853 ast_cli(a->fd, " DNS SRV lookup: %s\n", AST_CLI_YESNO(sip_cfg.srvlookup)); 18854 ast_cli(a->fd, " Pedantic SIP support: %s\n", AST_CLI_YESNO(sip_cfg.pedanticsipchecking)); 18855 ast_cli(a->fd, " Reg. min duration %d secs\n", min_expiry); 18856 ast_cli(a->fd, " Reg. max duration: %d secs\n", max_expiry); 18857 ast_cli(a->fd, " Reg. default duration: %d secs\n", default_expiry); 18858 ast_cli(a->fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout); 18859 ast_cli(a->fd, " Outbound reg. attempts: %d\n", global_regattempts_max); 18860 ast_cli(a->fd, " Outbound reg. retry 403:%d\n", global_reg_retry_403); 18861 ast_cli(a->fd, " Notify ringing state: %s\n", AST_CLI_YESNO(sip_cfg.notifyringing)); 18862 if (sip_cfg.notifyringing) { 18863 ast_cli(a->fd, " Include CID: %s%s\n", 18864 AST_CLI_YESNO(sip_cfg.notifycid), 18865 sip_cfg.notifycid == IGNORE_CONTEXT ? " (Ignoring context)" : ""); 18866 } 18867 ast_cli(a->fd, " Notify hold state: %s\n", AST_CLI_YESNO(sip_cfg.notifyhold)); 18868 ast_cli(a->fd, " SIP Transfer mode: %s\n", transfermode2str(sip_cfg.allowtransfer)); 18869 ast_cli(a->fd, " Max Call Bitrate: %d kbps\n", default_maxcallbitrate); 18870 ast_cli(a->fd, " Auto-Framing: %s\n", AST_CLI_YESNO(global_autoframing)); 18871 ast_cli(a->fd, " Outb. proxy: %s %s\n", ast_strlen_zero(sip_cfg.outboundproxy.name) ? "<not set>" : sip_cfg.outboundproxy.name, 18872 sip_cfg.outboundproxy.force ? "(forced)" : ""); 18873 ast_cli(a->fd, " Session Timers: %s\n", stmode2str(global_st_mode)); 18874 ast_cli(a->fd, " Session Refresher: %s\n", strefresherparam2str(global_st_refresher)); 18875 ast_cli(a->fd, " Session Expires: %d secs\n", global_max_se); 18876 ast_cli(a->fd, " Session Min-SE: %d secs\n", global_min_se); 18877 ast_cli(a->fd, " Timer T1: %d\n", global_t1); 18878 ast_cli(a->fd, " Timer T1 minimum: %d\n", global_t1min); 18879 ast_cli(a->fd, " Timer B: %d\n", global_timer_b); 18880 ast_cli(a->fd, " No premature media: %s\n", AST_CLI_YESNO(global_prematuremediafilter)); 18881 ast_cli(a->fd, " Max forwards: %d\n", sip_cfg.default_max_forwards); 18882 18883 ast_cli(a->fd, "\nDefault Settings:\n"); 18884 ast_cli(a->fd, "-----------------\n"); 18885 ast_cli(a->fd, " Allowed transports: %s\n", get_transport_list(default_transports)); 18886 ast_cli(a->fd, " Outbound transport: %s\n", get_transport(default_primary_transport)); 18887 ast_cli(a->fd, " Context: %s\n", sip_cfg.default_context); 18888 ast_cli(a->fd, " Force rport: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_NAT_FORCE_RPORT))); 18889 ast_cli(a->fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF))); 18890 ast_cli(a->fd, " Qualify: %d\n", default_qualify); 18891 ast_cli(a->fd, " Use ClientCode: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_USECLIENTCODE))); 18892 ast_cli(a->fd, " Progress inband: %s\n", (ast_test_flag(&global_flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER) ? "Never" : (AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_NO))); 18893 ast_cli(a->fd, " Language: %s\n", default_language); 18894 ast_cli(a->fd, " MOH Interpret: %s\n", default_mohinterpret); 18895 ast_cli(a->fd, " MOH Suggest: %s\n", default_mohsuggest); 18896 ast_cli(a->fd, " Voice Mail Extension: %s\n", default_vmexten); 18897 18898 18899 if (realtimepeers || realtimeregs) { 18900 ast_cli(a->fd, "\nRealtime SIP Settings:\n"); 18901 ast_cli(a->fd, "----------------------\n"); 18902 ast_cli(a->fd, " Realtime Peers: %s\n", AST_CLI_YESNO(realtimepeers)); 18903 ast_cli(a->fd, " Realtime Regs: %s\n", AST_CLI_YESNO(realtimeregs)); 18904 ast_cli(a->fd, " Cache Friends: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS))); 18905 ast_cli(a->fd, " Update: %s\n", AST_CLI_YESNO(sip_cfg.peer_rtupdate)); 18906 ast_cli(a->fd, " Ignore Reg. Expire: %s\n", AST_CLI_YESNO(sip_cfg.ignore_regexpire)); 18907 ast_cli(a->fd, " Save sys. name: %s\n", AST_CLI_YESNO(sip_cfg.rtsave_sysname)); 18908 ast_cli(a->fd, " Auto Clear: %d (%s)\n", sip_cfg.rtautoclear, ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR) ? "Enabled" : "Disabled"); 18909 } 18910 ast_cli(a->fd, "\n----\n"); 18911 return CLI_SUCCESS; 18912 }
| static char* sip_show_tcp | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Show active TCP connections.
Definition at line 17076 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ao2_t_ref, ast_cli_args::argc, ast_cli(), ast_sockaddr_stringify(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, FORMAT, FORMAT2, get_transport(), and ast_cli_entry::usage.
17077 { 17078 struct sip_threadinfo *th; 17079 struct ao2_iterator i; 17080 17081 #define FORMAT2 "%-47.47s %9.9s %6.6s\n" 17082 #define FORMAT "%-47.47s %-9.9s %-6.6s\n" 17083 17084 switch (cmd) { 17085 case CLI_INIT: 17086 e->command = "sip show tcp"; 17087 e->usage = 17088 "Usage: sip show tcp\n" 17089 " Lists all active TCP/TLS sessions.\n"; 17090 return NULL; 17091 case CLI_GENERATE: 17092 return NULL; 17093 } 17094 17095 if (a->argc != 3) 17096 return CLI_SHOWUSAGE; 17097 17098 ast_cli(a->fd, FORMAT2, "Address", "Transport", "Type"); 17099 17100 i = ao2_iterator_init(threadt, 0); 17101 while ((th = ao2_t_iterator_next(&i, "iterate through tcp threads for 'sip show tcp'"))) { 17102 ast_cli(a->fd, FORMAT, 17103 ast_sockaddr_stringify(&th->tcptls_session->remote_address), 17104 get_transport(th->type), 17105 (th->tcptls_session->client ? "Client" : "Server")); 17106 ao2_t_ref(th, -1, "decrement ref from iterator"); 17107 } 17108 ao2_iterator_destroy(&i); 17109 17110 return CLI_SUCCESS; 17111 #undef FORMAT 17112 #undef FORMAT2 17113 }
| static char* sip_show_user | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Show one user in detail.
Definition at line 18375 of file chan_sip.c.
References ao2_lock, ao2_unlock, ast_cli_args::argc, ast_cli_args::argv, ast_callerid_merge(), ast_cdr_flags2str(), ast_cli(), AST_CLI_YESNO, ast_describe_caller_presentation(), ast_strlen_zero(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sip_show_user(), FALSE, ast_cli_args::fd, find_peer(), ast_cli_args::line, ast_cli_args::n, ast_variable::name, ast_variable::next, ast_cli_args::pos, print_codec_to_cli(), print_group(), stmode2str(), strefresherparam2str(), transfermode2str(), TRUE, unref_peer(), ast_cli_entry::usage, ast_variable::value, and ast_cli_args::word.
18376 { 18377 char cbuf[256]; 18378 struct sip_peer *user; 18379 struct ast_variable *v; 18380 int load_realtime; 18381 18382 switch (cmd) { 18383 case CLI_INIT: 18384 e->command = "sip show user"; 18385 e->usage = 18386 "Usage: sip show user <name> [load]\n" 18387 " Shows all details on one SIP user and the current status.\n" 18388 " Option \"load\" forces lookup of peer in realtime storage.\n"; 18389 return NULL; 18390 case CLI_GENERATE: 18391 return complete_sip_show_user(a->line, a->word, a->pos, a->n); 18392 } 18393 18394 if (a->argc < 4) 18395 return CLI_SHOWUSAGE; 18396 18397 /* Load from realtime storage? */ 18398 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? TRUE : FALSE; 18399 18400 if ((user = find_peer(a->argv[3], NULL, load_realtime, FINDUSERS, FALSE, 0))) { 18401 ao2_lock(user); 18402 ast_cli(a->fd, "\n\n"); 18403 ast_cli(a->fd, " * Name : %s\n", user->name); 18404 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>"); 18405 ast_cli(a->fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>"); 18406 ast_cli(a->fd, " Context : %s\n", user->context); 18407 ast_cli(a->fd, " Language : %s\n", user->language); 18408 if (!ast_strlen_zero(user->accountcode)) 18409 ast_cli(a->fd, " Accountcode : %s\n", user->accountcode); 18410 ast_cli(a->fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); 18411 ast_cli(a->fd, " Transfer mode: %s\n", transfermode2str(user->allowtransfer)); 18412 ast_cli(a->fd, " MaxCallBR : %d kbps\n", user->maxcallbitrate); 18413 ast_cli(a->fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); 18414 ast_cli(a->fd, " Call limit : %d\n", user->call_limit); 18415 ast_cli(a->fd, " Callgroup : "); 18416 print_group(a->fd, user->callgroup, 0); 18417 ast_cli(a->fd, " Pickupgroup : "); 18418 print_group(a->fd, user->pickupgroup, 0); 18419 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>")); 18420 ast_cli(a->fd, " ACL : %s\n", AST_CLI_YESNO(user->ha != NULL)); 18421 ast_cli(a->fd, " Sess-Timers : %s\n", stmode2str(user->stimer.st_mode_oper)); 18422 ast_cli(a->fd, " Sess-Refresh : %s\n", strefresherparam2str(user->stimer.st_ref)); 18423 ast_cli(a->fd, " Sess-Expires : %d secs\n", user->stimer.st_max_se); 18424 ast_cli(a->fd, " Sess-Min-SE : %d secs\n", user->stimer.st_min_se); 18425 ast_cli(a->fd, " RTP Engine : %s\n", user->engine); 18426 18427 ast_cli(a->fd, " Codec Order : ("); 18428 print_codec_to_cli(a->fd, &user->prefs); 18429 ast_cli(a->fd, ")\n"); 18430 18431 ast_cli(a->fd, " Auto-Framing: %s \n", AST_CLI_YESNO(user->autoframing)); 18432 if (user->chanvars) { 18433 ast_cli(a->fd, " Variables :\n"); 18434 for (v = user->chanvars ; v ; v = v->next) 18435 ast_cli(a->fd, " %s = %s\n", v->name, v->value); 18436 } 18437 18438 ast_cli(a->fd, "\n"); 18439 18440 ao2_unlock(user); 18441 unref_peer(user, "sip show user"); 18442 } else { 18443 ast_cli(a->fd, "User %s not found.\n", a->argv[3]); 18444 ast_cli(a->fd, "\n"); 18445 } 18446 18447 return CLI_SUCCESS; 18448 }
| static char* sip_show_users | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
CLI Command 'SIP Show Users'.
Definition at line 17116 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_iterator_next, ao2_unlock, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_CLI_YESNO, ast_test_flag, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, FALSE, ast_cli_args::fd, FORMAT, TRUE, unref_peer(), and ast_cli_entry::usage.
17117 { 17118 regex_t regexbuf; 17119 int havepattern = FALSE; 17120 struct ao2_iterator user_iter; 17121 struct sip_peer *user; 17122 17123 #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" 17124 17125 switch (cmd) { 17126 case CLI_INIT: 17127 e->command = "sip show users"; 17128 e->usage = 17129 "Usage: sip show users [like <pattern>]\n" 17130 " Lists all known SIP users.\n" 17131 " Optional regular expression pattern is used to filter the user list.\n"; 17132 return NULL; 17133 case CLI_GENERATE: 17134 return NULL; 17135 } 17136 17137 switch (a->argc) { 17138 case 5: 17139 if (!strcasecmp(a->argv[3], "like")) { 17140 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB)) 17141 return CLI_SHOWUSAGE; 17142 havepattern = TRUE; 17143 } else 17144 return CLI_SHOWUSAGE; 17145 case 3: 17146 break; 17147 default: 17148 return CLI_SHOWUSAGE; 17149 } 17150 17151 ast_cli(a->fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "Forcerport"); 17152 17153 user_iter = ao2_iterator_init(peers, 0); 17154 while ((user = ao2_t_iterator_next(&user_iter, "iterate thru peers table"))) { 17155 ao2_lock(user); 17156 if (!(user->type & SIP_TYPE_USER)) { 17157 ao2_unlock(user); 17158 unref_peer(user, "sip show users"); 17159 continue; 17160 } 17161 17162 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) { 17163 ao2_unlock(user); 17164 unref_peer(user, "sip show users"); 17165 continue; 17166 } 17167 17168 ast_cli(a->fd, FORMAT, user->name, 17169 user->secret, 17170 user->accountcode, 17171 user->context, 17172 AST_CLI_YESNO(user->ha != NULL), 17173 AST_CLI_YESNO(ast_test_flag(&user->flags[0], SIP_NAT_FORCE_RPORT))); 17174 ao2_unlock(user); 17175 unref_peer(user, "sip show users"); 17176 } 17177 ao2_iterator_destroy(&user_iter); 17178 17179 if (havepattern) 17180 regfree(®exbuf); 17181 17182 return CLI_SUCCESS; 17183 #undef FORMAT 17184 }
| static int sip_sipredirect | ( | struct sip_pvt * | p, | |
| const char * | dest | |||
| ) | [static] |
Transfer call before connect with a 302 redirect.
Definition at line 30414 of file chan_sip.c.
References AST_CONTROL_TRANSFER, ast_copy_string(), ast_log(), ast_queue_control_data(), ast_strdupa, ast_string_field_build, ast_strlen_zero(), AST_TRANSFER_SUCCESS, get_header(), LOG_ERROR, sip_alreadygone(), sip_scheddestroy(), and transmit_response_reliable().
Referenced by sip_transfer().
30415 { 30416 char *cdest; 30417 char *extension, *domain; 30418 30419 cdest = ast_strdupa(dest); 30420 30421 extension = strsep(&cdest, "@"); 30422 domain = cdest; 30423 if (ast_strlen_zero(extension)) { 30424 ast_log(LOG_ERROR, "Missing mandatory argument: extension\n"); 30425 return 0; 30426 } 30427 30428 /* we'll issue the redirect message here */ 30429 if (!domain) { 30430 char *local_to_header; 30431 char to_header[256]; 30432 30433 ast_copy_string(to_header, get_header(&p->initreq, "To"), sizeof(to_header)); 30434 if (ast_strlen_zero(to_header)) { 30435 ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n"); 30436 return 0; 30437 } 30438 if (((local_to_header = strcasestr(to_header, "sip:")) || (local_to_header = strcasestr(to_header, "sips:"))) 30439 && (local_to_header = strchr(local_to_header, '@'))) { 30440 char ldomain[256]; 30441 30442 memset(ldomain, 0, sizeof(ldomain)); 30443 local_to_header++; 30444 /* This is okey because lhost and lport are as big as tmp */ 30445 sscanf(local_to_header, "%256[^<>; ]", ldomain); 30446 if (ast_strlen_zero(ldomain)) { 30447 ast_log(LOG_ERROR, "Can't find the host address\n"); 30448 return 0; 30449 } 30450 domain = ast_strdupa(ldomain); 30451 } 30452 } 30453 30454 ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s>", extension, domain); 30455 transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq); 30456 30457 sip_scheddestroy(p, SIP_TRANS_TIMEOUT); /* Make sure we stop send this reply. */ 30458 sip_alreadygone(p); 30459 30460 if (p->owner) { 30461 enum ast_control_transfer message = AST_TRANSFER_SUCCESS; 30462 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 30463 } 30464 /* hangup here */ 30465 return 0; 30466 }
| static struct sip_st_dlg * sip_st_alloc | ( | struct sip_pvt *const | p | ) | [static, read] |
Allocate Session-Timers struct w/in dialog.
Definition at line 7944 of file chan_sip.c.
References ast_calloc, ast_log(), and LOG_ERROR.
Referenced by handle_request_invite_st(), and st_get_mode().
07945 { 07946 struct sip_st_dlg *stp; 07947 07948 if (p->stimer) { 07949 ast_log(LOG_ERROR, "Session-Timer struct already allocated\n"); 07950 return p->stimer; 07951 } 07952 07953 if (!(stp = ast_calloc(1, sizeof(struct sip_st_dlg)))) 07954 return NULL; 07955 07956 p->stimer = stp; 07957 07958 stp->st_schedid = -1; /* Session-Timers ast_sched scheduler id */ 07959 07960 return p->stimer; 07961 }
| static int sip_standard_port | ( | enum sip_transport | type, | |
| int | port | |||
| ) | [static] |
Returns the port to use for this socket.
| type | The type of transport used | |
| port | Port we are checking to see if it's the standard port. |
Definition at line 26243 of file chan_sip.c.
Referenced by initreqprep(), and transmit_notify_with_mwi().
26244 { 26245 if (type & SIP_TRANSPORT_TLS) 26246 return port == STANDARD_TLS_PORT; 26247 else 26248 return port == STANDARD_SIP_PORT; 26249 }
| static int sip_subscribe_mwi | ( | const char * | value, | |
| int | lineno | |||
| ) | [static] |
Parse mwi=> line in sip.conf and add to list.
--- SIP MWI Subscription support
Definition at line 8577 of file chan_sip.c.
References ast_calloc_with_stringfields, ast_copy_string(), ast_log(), ast_string_field_set, ast_strlen_zero(), ASTOBJ_CONTAINER_LINK, ASTOBJ_INIT, ASTOBJ_UNREF, hostname, LOG_WARNING, mailbox, secret, sip_subscribe_mwi_destroy(), and submwil.
Referenced by reload_config().
08578 { 08579 struct sip_subscription_mwi *mwi; 08580 int portnum = 0; 08581 enum sip_transport transport = SIP_TRANSPORT_UDP; 08582 char buf[256] = ""; 08583 char *username = NULL, *hostname = NULL, *secret = NULL, *authuser = NULL, *porta = NULL, *mailbox = NULL; 08584 08585 if (!value) { 08586 return -1; 08587 } 08588 08589 ast_copy_string(buf, value, sizeof(buf)); 08590 08591 username = buf; 08592 08593 if ((hostname = strrchr(buf, '@'))) { 08594 *hostname++ = '\0'; 08595 } else { 08596 return -1; 08597 } 08598 08599 if ((secret = strchr(username, ':'))) { 08600 *secret++ = '\0'; 08601 if ((authuser = strchr(secret, ':'))) { 08602 *authuser++ = '\0'; 08603 } 08604 } 08605 08606 if ((mailbox = strchr(hostname, '/'))) { 08607 *mailbox++ = '\0'; 08608 } 08609 08610 if (ast_strlen_zero(username) || ast_strlen_zero(hostname) || ast_strlen_zero(mailbox)) { 08611 ast_log(LOG_WARNING, "Format for MWI subscription is user[:secret[:authuser]]@host[:port]/mailbox at line %d\n", lineno); 08612 return -1; 08613 } 08614 08615 if ((porta = strchr(hostname, ':'))) { 08616 *porta++ = '\0'; 08617 if (!(portnum = atoi(porta))) { 08618 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 08619 return -1; 08620 } 08621 } 08622 08623 if (!(mwi = ast_calloc_with_stringfields(1, struct sip_subscription_mwi, 256))) { 08624 return -1; 08625 } 08626 08627 ASTOBJ_INIT(mwi); 08628 ast_string_field_set(mwi, username, username); 08629 if (secret) { 08630 ast_string_field_set(mwi, secret, secret); 08631 } 08632 if (authuser) { 08633 ast_string_field_set(mwi, authuser, authuser); 08634 } 08635 ast_string_field_set(mwi, hostname, hostname); 08636 ast_string_field_set(mwi, mailbox, mailbox); 08637 mwi->resub = -1; 08638 mwi->portno = portnum; 08639 mwi->transport = transport; 08640 08641 ASTOBJ_CONTAINER_LINK(&submwil, mwi); 08642 ASTOBJ_UNREF(mwi, sip_subscribe_mwi_destroy); 08643 08644 return 0; 08645 }
| static void sip_subscribe_mwi_destroy | ( | struct sip_subscription_mwi * | mwi | ) | [static] |
Destroy MWI subscription object.
Definition at line 5951 of file chan_sip.c.
References ast_free, AST_SCHED_DEL, and ast_string_field_free_memory.
Referenced by __sip_subscribe_mwi_do(), handle_response_subscribe(), sip_send_all_mwi_subscriptions(), sip_subscribe_mwi(), sip_subscribe_mwi_do(), and unload_module().
05952 { 05953 if (mwi->call) { 05954 mwi->call->mwi = NULL; 05955 mwi->call = dialog_unref(mwi->call, "sip_subscription_mwi destruction"); 05956 } 05957 05958 AST_SCHED_DEL(sched, mwi->resub); 05959 ast_string_field_free_memory(mwi); 05960 ast_free(mwi); 05961 }
| static int sip_subscribe_mwi_do | ( | const void * | data | ) | [static] |
Send a subscription or resubscription for MWI.
Definition at line 12780 of file chan_sip.c.
References __sip_subscribe_mwi_do(), ASTOBJ_UNREF, and sip_subscribe_mwi_destroy().
Referenced by handle_response_subscribe(), and sip_send_all_mwi_subscriptions().
12781 { 12782 struct sip_subscription_mwi *mwi = (struct sip_subscription_mwi*)data; 12783 12784 if (!mwi) { 12785 return -1; 12786 } 12787 12788 mwi->resub = -1; 12789 __sip_subscribe_mwi_do(mwi); 12790 ASTOBJ_UNREF(mwi, sip_subscribe_mwi_destroy); 12791 12792 return 0; 12793 }
| static int sip_t38_abort | ( | const void * | data | ) | [static] |
Called to deny a T38 reinvite if the core does not respond to our request.
Definition at line 22923 of file chan_sip.c.
References change_t38_state(), sip_pvt_lock, sip_pvt_unlock, and transmit_response_reliable().
Referenced by handle_request_invite().
22924 { 22925 struct sip_pvt *p = (struct sip_pvt *) data; 22926 22927 sip_pvt_lock(p); 22928 /* an application may have taken ownership of the T.38 negotiation on this 22929 * channel while we were waiting to grab the lock... if it did, the scheduler 22930 * id will have been reset to -1, which is our indication that we do *not* 22931 * want to abort the negotiation process 22932 */ 22933 if (p->t38id != -1) { 22934 change_t38_state(p, T38_DISABLED); 22935 transmit_response_reliable(p, "488 Not acceptable here", &p->initreq); 22936 p->t38id = -1; 22937 dialog_unref(p, "unref the dialog ptr from sip_t38_abort, because it held a dialog ptr"); 22938 } 22939 sip_pvt_unlock(p); 22940 return 0; 22941 }
| static struct ast_tcptls_session_instance* sip_tcp_locate | ( | struct ast_sockaddr * | s | ) | [static, read] |
Find thread for TCP/TLS session (based on IP/Port.
Definition at line 26268 of file chan_sip.c.
References ao2_callback, ao2_ref, ao2_t_ref, and threadinfo_locate_cb().
Referenced by sip_prepare_socket().
26269 { 26270 struct sip_threadinfo *th; 26271 struct ast_tcptls_session_instance *tcptls_instance = NULL; 26272 26273 if ((th = ao2_callback(threadt, 0, threadinfo_locate_cb, s))) { 26274 tcptls_instance = (ao2_ref(th->tcptls_session, +1), th->tcptls_session); 26275 ao2_t_ref(th, -1, "decrement ref from callback"); 26276 } 26277 26278 return tcptls_instance; 26279 }
| static void * sip_tcp_worker_fn | ( | void * | data | ) | [static] |
SIP TCP connection handler.
Definition at line 2469 of file chan_sip.c.
References _sip_tcp_helper_thread().
Referenced by sip_prepare_socket().
02470 { 02471 struct ast_tcptls_session_instance *tcptls_session = data; 02472 02473 return _sip_tcp_helper_thread(tcptls_session); 02474 }
| static void sip_tcptls_client_args_destructor | ( | void * | obj | ) | [static] |
Definition at line 2349 of file chan_sip.c.
References args, ast_free, ast_ssl_teardown(), ast_tls_config::cafile, ast_tls_config::capath, ast_tls_config::certfile, ast_tls_config::cipher, ast_tcptls_session_args::name, ast_tls_config::pvtfile, and ast_tcptls_session_args::tls_cfg.
Referenced by sip_prepare_socket().
02350 { 02351 struct ast_tcptls_session_args *args = obj; 02352 if (args->tls_cfg) { 02353 ast_free(args->tls_cfg->certfile); 02354 ast_free(args->tls_cfg->pvtfile); 02355 ast_free(args->tls_cfg->cipher); 02356 ast_free(args->tls_cfg->cafile); 02357 ast_free(args->tls_cfg->capath); 02358 02359 ast_ssl_teardown(args->tls_cfg); 02360 } 02361 ast_free(args->tls_cfg); 02362 ast_free((char *) args->name); 02363 }
| static int sip_tcptls_read | ( | struct sip_request * | req, | |
| struct ast_tcptls_session_instance * | tcptls_session, | |||
| int | authenticated, | |||
| time_t | start | |||
| ) | [static] |
Read SIP request or response from a TCP/TLS connection.
| req | The request structure to be filled in | |
| tcptls_session | The TCP/TLS connection from which to read |
| -1 | Failed to read data | |
| 0 | Successfully read data |
Definition at line 2661 of file chan_sip.c.
References ast_debug, ast_log(), ast_sockaddr_stringify(), ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_strlen(), ast_tcptls_server_read(), ast_wait_for_input(), check_message_integrity(), ast_tcptls_session_instance::client, errno, ast_tcptls_session_instance::fd, LOG_WARNING, MESSAGE_FRAGMENT, ast_tcptls_session_instance::overflow_buf, ast_tcptls_session_instance::remote_address, and sip_check_authtimeout().
Referenced by _sip_tcp_helper_thread().
02663 { 02664 enum message_integrity message_integrity = MESSAGE_FRAGMENT; 02665 02666 while (message_integrity == MESSAGE_FRAGMENT) { 02667 size_t datalen; 02668 02669 if (ast_str_strlen(tcptls_session->overflow_buf) == 0) { 02670 char readbuf[4097]; 02671 int timeout; 02672 int res; 02673 if (!tcptls_session->client && !authenticated) { 02674 if ((timeout = sip_check_authtimeout(start)) < 0) { 02675 return -1; 02676 } 02677 02678 if (timeout == 0) { 02679 ast_debug(2, "SIP TCP/TLS server timed out\n"); 02680 return -1; 02681 } 02682 } else { 02683 timeout = -1; 02684 } 02685 res = ast_wait_for_input(tcptls_session->fd, timeout); 02686 if (res < 0) { 02687 ast_debug(2, "SIP TCP/TLS server :: ast_wait_for_input returned %d\n", res); 02688 return -1; 02689 } else if (res == 0) { 02690 ast_debug(2, "SIP TCP/TLS server timed out\n"); 02691 return -1; 02692 } 02693 02694 res = ast_tcptls_server_read(tcptls_session, readbuf, sizeof(readbuf) - 1); 02695 if (res < 0) { 02696 if (errno == EAGAIN || errno == EINTR) { 02697 continue; 02698 } 02699 ast_debug(2, "SIP TCP/TLS server error when receiving data\n"); 02700 return -1; 02701 } else if (res == 0) { 02702 ast_debug(2, "SIP TCP/TLS server has shut down\n"); 02703 return -1; 02704 } 02705 readbuf[res] = '\0'; 02706 ast_str_append(&req->data, 0, "%s", readbuf); 02707 } else { 02708 ast_str_append(&req->data, 0, "%s", ast_str_buffer(tcptls_session->overflow_buf)); 02709 ast_str_reset(tcptls_session->overflow_buf); 02710 } 02711 02712 datalen = ast_str_strlen(req->data); 02713 if (datalen > SIP_MAX_PACKET_SIZE) { 02714 ast_log(LOG_WARNING, "Rejecting TCP/TLS packet from '%s' because way too large: %zu\n", 02715 ast_sockaddr_stringify(&tcptls_session->remote_address), datalen); 02716 return -1; 02717 } 02718 02719 message_integrity = check_message_integrity(&req->data, &tcptls_session->overflow_buf); 02720 } 02721 02722 return 0; 02723 }
| static int sip_tcptls_write | ( | struct ast_tcptls_session_instance * | tcptls_session, | |
| const void * | buf, | |||
| size_t | len | |||
| ) | [static] |
used to indicate to a tcptls thread that data is ready to be written
Definition at line 2411 of file chan_sip.c.
References ao2_alloc, ao2_lock, ao2_t_find, ao2_t_ref, ao2_unlock, AST_LIST_INSERT_TAIL, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_str_create(), ast_str_set(), errno, ast_tcptls_session_instance::fd, ast_tcptls_session_instance::lock, LOG_ERROR, OBJ_POINTER, and tcptls_packet_destructor().
Referenced by __sip_xmit().
02412 { 02413 int res = len; 02414 struct sip_threadinfo *th = NULL; 02415 struct tcptls_packet *packet = NULL; 02416 struct sip_threadinfo tmp = { 02417 .tcptls_session = tcptls_session, 02418 }; 02419 enum sip_tcptls_alert alert = TCPTLS_ALERT_DATA; 02420 02421 if (!tcptls_session) { 02422 return XMIT_ERROR; 02423 } 02424 02425 ast_mutex_lock(&tcptls_session->lock); 02426 02427 if ((tcptls_session->fd == -1) || 02428 !(th = ao2_t_find(threadt, &tmp, OBJ_POINTER, "ao2_find, getting sip_threadinfo in tcp helper thread")) || 02429 !(packet = ao2_alloc(sizeof(*packet), tcptls_packet_destructor)) || 02430 !(packet->data = ast_str_create(len))) { 02431 goto tcptls_write_setup_error; 02432 } 02433 02434 /* goto tcptls_write_error should _NOT_ be used beyond this point */ 02435 ast_str_set(&packet->data, 0, "%s", (char *) buf); 02436 packet->len = len; 02437 02438 /* alert tcptls thread handler that there is a packet to be sent. 02439 * must lock the thread info object to guarantee control of the 02440 * packet queue */ 02441 ao2_lock(th); 02442 if (write(th->alert_pipe[1], &alert, sizeof(alert)) == -1) { 02443 ast_log(LOG_ERROR, "write() to alert pipe failed: %s\n", strerror(errno)); 02444 ao2_t_ref(packet, -1, "could not write to alert pipe, remove packet"); 02445 packet = NULL; 02446 res = XMIT_ERROR; 02447 } else { /* it is safe to queue the frame after issuing the alert when we hold the threadinfo lock */ 02448 AST_LIST_INSERT_TAIL(&th->packet_q, packet, entry); 02449 } 02450 ao2_unlock(th); 02451 02452 ast_mutex_unlock(&tcptls_session->lock); 02453 ao2_t_ref(th, -1, "In sip_tcptls_write, unref threadinfo object after finding it"); 02454 return res; 02455 02456 tcptls_write_setup_error: 02457 if (th) { 02458 ao2_t_ref(th, -1, "In sip_tcptls_write, unref threadinfo obj, could not create packet"); 02459 } 02460 if (packet) { 02461 ao2_t_ref(packet, -1, "could not allocate packet's data"); 02462 } 02463 ast_mutex_unlock(&tcptls_session->lock); 02464 02465 return XMIT_ERROR; 02466 }
| static struct sip_threadinfo* sip_threadinfo_create | ( | struct ast_tcptls_session_instance * | tcptls_session, | |
| int | transport | |||
| ) | [static, read] |
creates a sip_threadinfo object and links it into the threadt table.
Definition at line 2387 of file chan_sip.c.
References ao2_alloc, ao2_t_link, ao2_t_ref, ast_log(), errno, LOG_ERROR, sip_threadinfo_destructor(), and ast_tcptls_session_instance::ssl.
Referenced by _sip_tcp_helper_thread(), and sip_prepare_socket().
02388 { 02389 struct sip_threadinfo *th; 02390 02391 if (!tcptls_session || !(th = ao2_alloc(sizeof(*th), sip_threadinfo_destructor))) { 02392 return NULL; 02393 } 02394 02395 th->alert_pipe[0] = th->alert_pipe[1] = -1; 02396 02397 if (pipe(th->alert_pipe) == -1) { 02398 ao2_t_ref(th, -1, "Failed to open alert pipe on sip_threadinfo"); 02399 ast_log(LOG_ERROR, "Could not create sip alert pipe in tcptls thread, error %s\n", strerror(errno)); 02400 return NULL; 02401 } 02402 ao2_t_ref(tcptls_session, +1, "tcptls_session ref for sip_threadinfo object"); 02403 th->tcptls_session = tcptls_session; 02404 th->type = transport ? transport : (tcptls_session->ssl ? SIP_TRANSPORT_TLS: SIP_TRANSPORT_TCP); 02405 ao2_t_link(threadt, th, "Adding new tcptls helper thread"); 02406 ao2_t_ref(th, -1, "Decrementing threadinfo ref from alloc, only table ref remains"); 02407 return th; 02408 }
| static void sip_threadinfo_destructor | ( | void * | obj | ) | [static] |
Definition at line 2365 of file chan_sip.c.
References ao2_t_ref, and AST_LIST_REMOVE_HEAD.
Referenced by sip_threadinfo_create().
02366 { 02367 struct sip_threadinfo *th = obj; 02368 struct tcptls_packet *packet; 02369 if (th->alert_pipe[1] > -1) { 02370 close(th->alert_pipe[0]); 02371 } 02372 if (th->alert_pipe[1] > -1) { 02373 close(th->alert_pipe[1]); 02374 } 02375 th->alert_pipe[0] = th->alert_pipe[1] = -1; 02376 02377 while ((packet = AST_LIST_REMOVE_HEAD(&th->packet_q, entry))) { 02378 ao2_t_ref(packet, -1, "thread destruction, removing packet from frame queue"); 02379 } 02380 02381 if (th->tcptls_session) { 02382 ao2_t_ref(th->tcptls_session, -1, "remove tcptls_session for sip_threadinfo object"); 02383 } 02384 }
| static int sip_transfer | ( | struct ast_channel * | ast, | |
| const char * | dest | |||
| ) | [static] |
Transfer SIP call.
Definition at line 6974 of file chan_sip.c.
References ast_channel::_state, ast_debug, AST_STATE_RING, sip_pvt_lock, sip_pvt_unlock, sip_sipredirect(), ast_channel::tech_pvt, and transmit_refer().
06975 { 06976 struct sip_pvt *p = ast->tech_pvt; 06977 int res; 06978 06979 if (!p) { 06980 ast_debug(1, "Asked to transfer channel %s with no pvt; ignoring\n", 06981 ast->name); 06982 return -1; 06983 } 06984 06985 if (dest == NULL) /* functions below do not take a NULL */ 06986 dest = ""; 06987 sip_pvt_lock(p); 06988 if (ast->_state == AST_STATE_RING) 06989 res = sip_sipredirect(p, dest); 06990 else 06991 res = transmit_refer(p, dest); 06992 sip_pvt_unlock(p); 06993 return res; 06994 }
| static char * sip_unregister | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Unregister (force expiration) a SIP peer in the registry via CLI.
Definition at line 18548 of file chan_sip.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_SCHED_DEL_UNREF, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sip_unregister(), expire_register(), ast_cli_args::fd, find_peer(), ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ref_peer(), TRUE, unref_peer(), ast_cli_entry::usage, and ast_cli_args::word.
18549 { 18550 struct sip_peer *peer; 18551 int load_realtime = 0; 18552 18553 switch (cmd) { 18554 case CLI_INIT: 18555 e->command = "sip unregister"; 18556 e->usage = 18557 "Usage: sip unregister <peer>\n" 18558 " Unregister (force expiration) a SIP peer from the registry\n"; 18559 return NULL; 18560 case CLI_GENERATE: 18561 return complete_sip_unregister(a->line, a->word, a->pos, a->n); 18562 } 18563 18564 if (a->argc != 3) 18565 return CLI_SHOWUSAGE; 18566 18567 if ((peer = find_peer(a->argv[2], NULL, load_realtime, FINDPEERS, TRUE, 0))) { 18568 if (peer->expire > 0) { 18569 AST_SCHED_DEL_UNREF(sched, peer->expire, 18570 unref_peer(peer, "remove register expire ref")); 18571 expire_register(ref_peer(peer, "ref for expire_register")); 18572 ast_cli(a->fd, "Unregistered peer \'%s\'\n\n", a->argv[2]); 18573 } else { 18574 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]); 18575 } 18576 unref_peer(peer, "sip_unregister: unref_peer via sip_unregister: done with peer from find_peer call"); 18577 } else { 18578 ast_cli(a->fd, "Peer unknown: \'%s\'. Not unregistered.\n", a->argv[2]); 18579 } 18580 18581 return CLI_SUCCESS; 18582 }
| static void sip_unregister_tests | ( | void | ) | [static] |
SIP test registration.
Definition at line 30890 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().
30891 { 30892 sip_config_parser_unregister_tests(); 30893 sip_request_parser_unregister_tests(); 30894 sip_dialplan_function_unregister_tests(); 30895 }
| static int sip_write | ( | struct ast_channel * | ast, | |
| struct ast_frame * | frame | |||
| ) | [static] |
Send frame to media channel (rtp).
Definition at line 6764 of file chan_sip.c.
References ast_channel::_state, AST_FORMAT_AUDIO_MASK, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_rtp_instance_update_source(), ast_rtp_instance_write(), ast_rtp_red_buffer(), ast_set_flag, AST_STATE_UP, ast_test_flag, ast_udptl_write(), ast_frame_subclass::codec, ast_frame::frametype, LOG_WARNING, ast_channel::nativeformats, ast_channel::readformat, sip_pvt_lock, sip_pvt_unlock, ast_frame::subclass, ast_channel::tech_pvt, transmit_provisional_response(), TRUE, and ast_channel::writeformat.
06765 { 06766 struct sip_pvt *p = ast->tech_pvt; 06767 int res = 0; 06768 06769 switch (frame->frametype) { 06770 case AST_FRAME_VOICE: 06771 if (!(frame->subclass.codec & ast->nativeformats)) { 06772 char s1[512], s2[512], s3[512]; 06773 ast_log(LOG_WARNING, "Asked to transmit frame type %s, while native formats is %s read/write = %s/%s\n", 06774 ast_getformatname(frame->subclass.codec), 06775 ast_getformatname_multiple(s1, sizeof(s1), ast->nativeformats & AST_FORMAT_AUDIO_MASK), 06776 ast_getformatname_multiple(s2, sizeof(s2), ast->readformat), 06777 ast_getformatname_multiple(s3, sizeof(s3), ast->writeformat)); 06778 return 0; 06779 } 06780 if (p) { 06781 sip_pvt_lock(p); 06782 if (p->t38.state == T38_ENABLED) { 06783 /* drop frame, can't sent VOICE frames while in T.38 mode */ 06784 sip_pvt_unlock(p); 06785 break; 06786 } else if (p->rtp) { 06787 /* If channel is not up, activate early media session */ 06788 if ((ast->_state != AST_STATE_UP) && 06789 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 06790 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06791 ast_rtp_instance_update_source(p->rtp); 06792 if (!global_prematuremediafilter) { 06793 p->invitestate = INV_EARLY_MEDIA; 06794 transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE); 06795 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 06796 } 06797 } 06798 p->lastrtptx = time(NULL); 06799 res = ast_rtp_instance_write(p->rtp, frame); 06800 } 06801 sip_pvt_unlock(p); 06802 } 06803 break; 06804 case AST_FRAME_VIDEO: 06805 if (p) { 06806 sip_pvt_lock(p); 06807 if (p->vrtp) { 06808 /* Activate video early media */ 06809 if ((ast->_state != AST_STATE_UP) && 06810 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 06811 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06812 p->invitestate = INV_EARLY_MEDIA; 06813 transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE); 06814 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 06815 } 06816 p->lastrtptx = time(NULL); 06817 res = ast_rtp_instance_write(p->vrtp, frame); 06818 } 06819 sip_pvt_unlock(p); 06820 } 06821 break; 06822 case AST_FRAME_TEXT: 06823 if (p) { 06824 sip_pvt_lock(p); 06825 if (p->red) { 06826 ast_rtp_red_buffer(p->trtp, frame); 06827 } else { 06828 if (p->trtp) { 06829 /* Activate text early media */ 06830 if ((ast->_state != AST_STATE_UP) && 06831 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 06832 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06833 p->invitestate = INV_EARLY_MEDIA; 06834 transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE); 06835 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 06836 } 06837 p->lastrtptx = time(NULL); 06838 res = ast_rtp_instance_write(p->trtp, frame); 06839 } 06840 } 06841 sip_pvt_unlock(p); 06842 } 06843 break; 06844 case AST_FRAME_IMAGE: 06845 return 0; 06846 break; 06847 case AST_FRAME_MODEM: 06848 if (p) { 06849 sip_pvt_lock(p); 06850 /* UDPTL requires two-way communication, so early media is not needed here. 06851 we simply forget the frames if we get modem frames before the bridge is up. 06852 Fax will re-transmit. 06853 */ 06854 if ((ast->_state == AST_STATE_UP) && 06855 p->udptl && 06856 (p->t38.state == T38_ENABLED)) { 06857 res = ast_udptl_write(p->udptl, frame); 06858 } 06859 sip_pvt_unlock(p); 06860 } 06861 break; 06862 default: 06863 ast_log(LOG_WARNING, "Can't send %u type frames with SIP write\n", frame->frametype); 06864 return 0; 06865 } 06866 06867 return res; 06868 }
| static int sipsock_read | ( | int * | id, | |
| int | fd, | |||
| short | events, | |||
| void * | ignore | |||
| ) | [static] |
Read data from SIP UDP socket.
Definition at line 26113 of file chan_sip.c.
References AST_DYNSTR_BUILD_FAILED, ast_log(), ast_recvfrom(), ast_sockaddr_port, ast_str_create(), ast_str_set(), bindaddr, deinit_req(), errno, handle_request_do(), LOG_NOTICE, LOG_WARNING, and set_socket_transport().
Referenced by do_monitor().
26114 { 26115 struct sip_request req; 26116 struct ast_sockaddr addr; 26117 int res; 26118 static char readbuf[65535]; 26119 26120 memset(&req, 0, sizeof(req)); 26121 res = ast_recvfrom(fd, readbuf, sizeof(readbuf) - 1, 0, &addr); 26122 if (res < 0) { 26123 #if !defined(__FreeBSD__) 26124 if (errno == EAGAIN) 26125 ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n"); 26126 else 26127 #endif 26128 if (errno != ECONNREFUSED) 26129 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 26130 return 1; 26131 } 26132 26133 readbuf[res] = '\0'; 26134 26135 if (!(req.data = ast_str_create(SIP_MIN_PACKET))) { 26136 return 1; 26137 } 26138 26139 if (ast_str_set(&req.data, 0, "%s", readbuf) == AST_DYNSTR_BUILD_FAILED) { 26140 return -1; 26141 } 26142 26143 req.socket.fd = sipsock; 26144 set_socket_transport(&req.socket, SIP_TRANSPORT_UDP); 26145 req.socket.tcptls_session = NULL; 26146 req.socket.port = htons(ast_sockaddr_port(&bindaddr)); 26147 26148 handle_request_do(&req, &addr); 26149 deinit_req(&req); 26150 26151 return 1; 26152 }
| static int sockaddr_is_null_or_any | ( | const struct ast_sockaddr * | addr | ) | [static] |
Definition at line 9082 of file chan_sip.c.
References ast_sockaddr_is_any(), and ast_sockaddr_isnull().
Referenced by process_sdp().
09083 { 09084 return ast_sockaddr_isnull(addr) || ast_sockaddr_is_any(addr); 09085 }
| enum st_mode st_get_mode | ( | struct sip_pvt * | p, | |
| int | no_cached | |||
| ) | [static] |
Get the session-timer mode.
| p | pointer to the SIP dialog | |
| no_cached,set | this to true in order to force a peername lookup on the session timer mode. |
Definition at line 27042 of file chan_sip.c.
References sip_st_alloc().
Referenced by add_supported_header(), handle_request_invite_st(), handle_response_invite(), and transmit_invite().
27043 { 27044 if (!p->stimer) { 27045 sip_st_alloc(p); 27046 if (!p->stimer) { 27047 return SESSION_TIMER_MODE_INVALID; 27048 } 27049 } 27050 27051 if (!no_cached && p->stimer->st_cached_mode != SESSION_TIMER_MODE_INVALID) 27052 return p->stimer->st_cached_mode; 27053 27054 if (p->relatedpeer) { 27055 p->stimer->st_cached_mode = p->relatedpeer->stimer.st_mode_oper; 27056 return p->stimer->st_cached_mode; 27057 } 27058 27059 p->stimer->st_cached_mode = global_st_mode; 27060 return global_st_mode; 27061 }
| enum st_refresher st_get_refresher | ( | struct sip_pvt * | p | ) | [static] |
Get the entity (UAC or UAS) that's acting as the session-timer refresher.
| p | pointer to the SIP dialog |
Definition at line 27020 of file chan_sip.c.
Referenced by handle_request_invite_st().
27021 { 27022 if (p->stimer->st_cached_ref != SESSION_TIMER_REFRESHER_AUTO) { 27023 return p->stimer->st_cached_ref; 27024 } 27025 27026 if (p->relatedpeer) { 27027 p->stimer->st_cached_ref = (p->relatedpeer->stimer.st_ref == SESSION_TIMER_REFRESHER_PARAM_UAC) ? SESSION_TIMER_REFRESHER_THEM : SESSION_TIMER_REFRESHER_US; 27028 return p->stimer->st_cached_ref; 27029 } 27030 27031 p->stimer->st_cached_ref = (global_st_refresher == SESSION_TIMER_REFRESHER_PARAM_UAC) ? SESSION_TIMER_REFRESHER_THEM : SESSION_TIMER_REFRESHER_US; 27032 return p->stimer->st_cached_ref; 27033 }
| int st_get_se | ( | struct sip_pvt * | p, | |
| int | max | |||
| ) | [static] |
Get Max or Min SE (session timer expiry).
| p | pointer to the SIP dialog | |
| max | if true, get max se, otherwise min se |
Definition at line 26988 of file chan_sip.c.
References TRUE.
Referenced by handle_request_invite_st(), handle_response_invite(), reqprep(), and transmit_invite().
26989 { 26990 if (max == TRUE) { 26991 if (p->stimer->st_cached_max_se) { 26992 return p->stimer->st_cached_max_se; 26993 } 26994 if (p->relatedpeer) { 26995 p->stimer->st_cached_max_se = p->relatedpeer->stimer.st_max_se; 26996 return (p->stimer->st_cached_max_se); 26997 } 26998 p->stimer->st_cached_max_se = global_max_se; 26999 return (p->stimer->st_cached_max_se); 27000 } 27001 /* Find Min SE timer */ 27002 if (p->stimer->st_cached_min_se) { 27003 return p->stimer->st_cached_min_se; 27004 } 27005 if (p->relatedpeer) { 27006 p->stimer->st_cached_min_se = p->relatedpeer->stimer.st_min_se; 27007 return (p->stimer->st_cached_min_se); 27008 } 27009 p->stimer->st_cached_min_se = global_min_se; 27010 return (p->stimer->st_cached_min_se); 27011 }
| static void start_session_timer | ( | struct sip_pvt * | p | ) | [static] |
Session-Timers: Start session timer.
Definition at line 26770 of file chan_sip.c.
References ast_debug, ast_log(), ast_sched_add(), AST_SCHED_DEL_UNREF, LOG_ERROR, MIN, proc_session_timer(), and TRUE.
Referenced by handle_response_invite(), restart_session_timer(), and sip_answer().
26771 { 26772 unsigned int timeout_ms; 26773 26774 if (p->stimer->st_schedid > -1) { 26775 /* in the event a timer is already going, stop it */ 26776 ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid); 26777 AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid, 26778 dialog_unref(p, "unref stimer->st_schedid from dialog")); 26779 } 26780 26781 /* 26782 * RFC 4028 Section 10 26783 * If the side not performing refreshes does not receive a 26784 * session refresh request before the session expiration, it SHOULD send 26785 * a BYE to terminate the session, slightly before the session 26786 * expiration. The minimum of 32 seconds and one third of the session 26787 * interval is RECOMMENDED. 26788 */ 26789 26790 timeout_ms = (1000 * p->stimer->st_interval); 26791 if (p->stimer->st_ref == SESSION_TIMER_REFRESHER_US) { 26792 timeout_ms /= 2; 26793 } else { 26794 timeout_ms -= MIN(timeout_ms / 3, 32000); 26795 } 26796 26797 p->stimer->st_schedid = ast_sched_add(sched, timeout_ms, proc_session_timer, 26798 dialog_ref(p, "adding session timer ref")); 26799 26800 if (p->stimer->st_schedid < 0) { 26801 dialog_unref(p, "removing session timer ref"); 26802 ast_log(LOG_ERROR, "ast_sched_add failed - %s\n", p->callid); 26803 } else { 26804 p->stimer->st_active = TRUE; 26805 ast_debug(2, "Session timer started: %d - %s %ums\n", p->stimer->st_schedid, p->callid, timeout_ms); 26806 } 26807 }
| static void state_notify_build_xml | ( | int | state, | |
| int | full, | |||
| const char * | exten, | |||
| const char * | context, | |||
| struct ast_str ** | tmp, | |||
| struct sip_pvt * | p, | |||
| int | subscribed, | |||
| const char * | mfrom, | |||
| const char * | mto | |||
| ) | [static] |
Builds XML portion of NOTIFY messages for presence or dialog updates.
Definition at line 12966 of file chan_sip.c.
References ast_alloca, ast_channel_callback(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, AST_DEVICE_UNAVAILABLE, AST_EXTENSION_BUSY, AST_EXTENSION_INUSE, AST_EXTENSION_NOT_INUSE, AST_EXTENSION_ONHOLD, AST_EXTENSION_RINGING, AST_EXTENSION_UNAVAILABLE, ast_get_hint(), AST_MAX_EXTENSION, AST_PRES_RESTRICTED, AST_PRES_RESTRICTION, ast_str_append(), ast_strdupa, ast_xml_escape(), ast_channel::caller, cid_num, ast_channel::connected, find_calling_channel(), ast_party_connected_line::id, ast_party_caller::id, ast_party_id::name, NONE, ast_party_id::number, ast_party_name::presentation, ast_party_number::presentation, S_COR, sip_cfg, ast_party_name::str, ast_party_number::str, ast_party_name::valid, and ast_party_number::valid.
Referenced by transmit_state_notify().
12967 { 12968 enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN; 12969 const char *statestring = "terminated"; 12970 const char *pidfstate = "--"; 12971 const char *pidfnote= "Ready"; 12972 char hint[AST_MAX_EXTENSION]; 12973 12974 switch (state) { 12975 case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE): 12976 statestring = (sip_cfg.notifyringing) ? "early" : "confirmed"; 12977 local_state = NOTIFY_INUSE; 12978 pidfstate = "busy"; 12979 pidfnote = "Ringing"; 12980 break; 12981 case AST_EXTENSION_RINGING: 12982 statestring = "early"; 12983 local_state = NOTIFY_INUSE; 12984 pidfstate = "busy"; 12985 pidfnote = "Ringing"; 12986 break; 12987 case AST_EXTENSION_INUSE: 12988 statestring = "confirmed"; 12989 local_state = NOTIFY_INUSE; 12990 pidfstate = "busy"; 12991 pidfnote = "On the phone"; 12992 break; 12993 case AST_EXTENSION_BUSY: 12994 statestring = "confirmed"; 12995 local_state = NOTIFY_CLOSED; 12996 pidfstate = "busy"; 12997 pidfnote = "On the phone"; 12998 break; 12999 case AST_EXTENSION_UNAVAILABLE: 13000 statestring = "terminated"; 13001 local_state = NOTIFY_CLOSED; 13002 pidfstate = "away"; 13003 pidfnote = "Unavailable"; 13004 break; 13005 case AST_EXTENSION_ONHOLD: 13006 statestring = "confirmed"; 13007 local_state = NOTIFY_CLOSED; 13008 pidfstate = "busy"; 13009 pidfnote = "On hold"; 13010 break; 13011 case AST_EXTENSION_NOT_INUSE: 13012 default: 13013 /* Default setting */ 13014 break; 13015 } 13016 13017 /* Check which device/devices we are watching and if they are registered */ 13018 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten)) { 13019 char *hint2 = hint, *individual_hint = NULL; 13020 int hint_count = 0, unavailable_count = 0; 13021 13022 while ((individual_hint = strsep(&hint2, "&"))) { 13023 hint_count++; 13024 13025 if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE) 13026 unavailable_count++; 13027 } 13028 13029 /* If none of the hinted devices are registered, we will 13030 * override notification and show no availability. 13031 */ 13032 if (hint_count > 0 && hint_count == unavailable_count) { 13033 local_state = NOTIFY_CLOSED; 13034 pidfstate = "away"; 13035 pidfnote = "Not online"; 13036 } 13037 } 13038 13039 switch (subscribed) { 13040 case XPIDF_XML: 13041 case CPIM_PIDF_XML: 13042 ast_str_append(tmp, 0, 13043 "<?xml version=\"1.0\"?>\n" 13044 "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n" 13045 "<presence>\n"); 13046 ast_str_append(tmp, 0, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom); 13047 ast_str_append(tmp, 0, "<atom id=\"%s\">\n", exten); 13048 ast_str_append(tmp, 0, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto); 13049 ast_str_append(tmp, 0, "<status status=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed"); 13050 ast_str_append(tmp, 0, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline"); 13051 ast_str_append(tmp, 0, "</address>\n</atom>\n</presence>\n"); 13052 break; 13053 case PIDF_XML: /* Eyebeam supports this format */ 13054 ast_str_append(tmp, 0, 13055 "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n" 13056 "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \nxmlns:pp=\"urn:ietf:params:xml:ns:pidf:person\"\nxmlns:es=\"urn:ietf:params:xml:ns:pidf:rpid:status:rpid-status\"\nxmlns:ep=\"urn:ietf:params:xml:ns:pidf:rpid:rpid-person\"\nentity=\"%s\">\n", mfrom); 13057 ast_str_append(tmp, 0, "<pp:person><status>\n"); 13058 if (pidfstate[0] != '-') { 13059 ast_str_append(tmp, 0, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate); 13060 } 13061 ast_str_append(tmp, 0, "</status></pp:person>\n"); 13062 ast_str_append(tmp, 0, "<note>%s</note>\n", pidfnote); /* Note */ 13063 ast_str_append(tmp, 0, "<tuple id=\"%s\">\n", exten); /* Tuple start */ 13064 ast_str_append(tmp, 0, "<contact priority=\"1\">%s</contact>\n", mto); 13065 if (pidfstate[0] == 'b') /* Busy? Still open ... */ 13066 ast_str_append(tmp, 0, "<status><basic>open</basic></status>\n"); 13067 else 13068 ast_str_append(tmp, 0, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed"); 13069 ast_str_append(tmp, 0, "</tuple>\n</presence>\n"); 13070 break; 13071 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 13072 ast_str_append(tmp, 0, "<?xml version=\"1.0\"?>\n"); 13073 ast_str_append(tmp, 0, "<dialog-info xmlns=\"urn:ietf:params:xml:ns:dialog-info\" version=\"%u\" state=\"%s\" entity=\"%s\">\n", p->dialogver, full ? "full" : "partial", mto); 13074 13075 if ((state & AST_EXTENSION_RINGING) && sip_cfg.notifyringing) { 13076 /* Twice the extension length should be enough for XML encoding */ 13077 char local_display[AST_MAX_EXTENSION * 2]; 13078 char remote_display[AST_MAX_EXTENSION * 2]; 13079 char *local_target = ast_strdupa(mto); 13080 /* It may seem odd to base the remote_target on the To header here, 13081 * but testing by reporters on issue ASTERISK-16735 found that basing 13082 * on the From header would cause ringing state hints to not work 13083 * properly on certain SNOM devices. If you are using notifycid properly 13084 * (i.e. in the same extension and context as the dialed call) then this 13085 * should not be an issue since the data will be overwritten shortly 13086 * with channel caller ID 13087 */ 13088 char *remote_target = ast_strdupa(mto); 13089 13090 ast_xml_escape(exten, local_display, sizeof(local_display)); 13091 ast_xml_escape(exten, remote_display, sizeof(remote_display)); 13092 13093 /* There are some limitations to how this works. The primary one is that the 13094 callee must be dialing the same extension that is being monitored. Simply dialing 13095 the hint'd device is not sufficient. */ 13096 if (sip_cfg.notifycid) { 13097 struct ast_channel *caller; 13098 13099 if ((caller = ast_channel_callback(find_calling_channel, NULL, p, 0))) { 13100 static char *anonymous = "anonymous"; 13101 static char *invalid = "anonymous.invalid"; 13102 char *cid_num; 13103 char *connected_num; 13104 int need; 13105 int cid_num_restricted, connected_num_restricted; 13106 13107 ast_channel_lock(caller); 13108 13109 cid_num_restricted = (caller->caller.id.number.presentation & 13110 AST_PRES_RESTRICTION) == AST_PRES_RESTRICTED; 13111 cid_num = S_COR(caller->caller.id.number.valid, 13112 S_COR(cid_num_restricted, anonymous, 13113 caller->caller.id.number.str), ""); 13114 13115 need = strlen(cid_num) + (cid_num_restricted ? strlen(invalid) : 13116 strlen(p->fromdomain)) + sizeof("sip:@"); 13117 13118 remote_target = ast_alloca(need); 13119 snprintf(remote_target, need, "sip:%s@%s", cid_num, 13120 cid_num_restricted ? invalid : p->fromdomain); 13121 13122 ast_xml_escape(S_COR(caller->caller.id.name.valid, 13123 S_COR((caller->caller.id.name.presentation & 13124 AST_PRES_RESTRICTION) == AST_PRES_RESTRICTED, anonymous, 13125 caller->caller.id.name.str), ""), 13126 remote_display, sizeof(remote_display)); 13127 13128 connected_num_restricted = (caller->connected.id.number.presentation & 13129 AST_PRES_RESTRICTION) == AST_PRES_RESTRICTED; 13130 connected_num = S_COR(caller->connected.id.number.valid, 13131 S_COR(connected_num_restricted, anonymous, 13132 caller->connected.id.number.str), ""); 13133 13134 need = strlen(connected_num) + (connected_num_restricted ? strlen(invalid) : 13135 strlen(p->fromdomain)) + sizeof("sip:@"); 13136 local_target = ast_alloca(need); 13137 13138 snprintf(local_target, need, "sip:%s@%s", connected_num, 13139 connected_num_restricted ? invalid : p->fromdomain); 13140 13141 ast_xml_escape(S_COR(caller->connected.id.name.valid, 13142 S_COR((caller->connected.id.name.presentation & 13143 AST_PRES_RESTRICTION) == AST_PRES_RESTRICTED, anonymous, 13144 caller->connected.id.name.str), ""), 13145 local_display, sizeof(local_display)); 13146 13147 ast_channel_unlock(caller); 13148 caller = ast_channel_unref(caller); 13149 } 13150 13151 /* We create a fake call-id which the phone will send back in an INVITE 13152 Replaces header which we can grab and do some magic with. */ 13153 if (sip_cfg.pedanticsipchecking) { 13154 ast_str_append(tmp, 0, "<dialog id=\"%s\" call-id=\"pickup-%s\" local-tag=\"%s\" remote-tag=\"%s\" direction=\"recipient\">\n", 13155 exten, p->callid, p->theirtag, p->tag); 13156 } else { 13157 ast_str_append(tmp, 0, "<dialog id=\"%s\" call-id=\"pickup-%s\" direction=\"recipient\">\n", 13158 exten, p->callid); 13159 } 13160 ast_str_append(tmp, 0, 13161 "<remote>\n" 13162 /* See the limitations of this above. Luckily the phone seems to still be 13163 happy when these values are not correct. */ 13164 "<identity display=\"%s\">%s</identity>\n" 13165 "<target uri=\"%s\"/>\n" 13166 "</remote>\n" 13167 "<local>\n" 13168 "<identity display=\"%s\">%s</identity>\n" 13169 "<target uri=\"%s\"/>\n" 13170 "</local>\n", 13171 remote_display, remote_target, remote_target, local_display, local_target, local_target); 13172 } else { 13173 ast_str_append(tmp, 0, "<dialog id=\"%s\" direction=\"recipient\">\n", exten); 13174 } 13175 13176 } else { 13177 ast_str_append(tmp, 0, "<dialog id=\"%s\">\n", exten); 13178 } 13179 ast_str_append(tmp, 0, "<state>%s</state>\n", statestring); 13180 if (state == AST_EXTENSION_ONHOLD) { 13181 ast_str_append(tmp, 0, "<local>\n<target uri=\"%s\">\n" 13182 "<param pname=\"+sip.rendering\" pvalue=\"no\"/>\n" 13183 "</target>\n</local>\n", mto); 13184 } 13185 ast_str_append(tmp, 0, "</dialog>\n</dialog-info>\n"); 13186 break; 13187 case NONE: 13188 default: 13189 break; 13190 } 13191 }
| static const char* stmode2str | ( | enum st_mode | m | ) | [static] |
Definition at line 17012 of file chan_sip.c.
References map_x_s().
Referenced by _sip_show_peer(), sip_show_channel(), sip_show_settings(), and sip_show_user().
| static void stop_media_flows | ( | struct sip_pvt * | p | ) | [static] |
Immediately stop RTP, VRTP and UDPTL as applicable.
Definition at line 21702 of file chan_sip.c.
References ast_rtp_instance_stop(), and ast_udptl_stop().
Referenced by __sip_autodestruct(), handle_request_bye(), handle_request_cancel(), handle_response(), and sip_hangup().
21703 { 21704 /* Immediately stop RTP, VRTP and UDPTL as applicable */ 21705 if (p->rtp) 21706 ast_rtp_instance_stop(p->rtp); 21707 if (p->vrtp) 21708 ast_rtp_instance_stop(p->vrtp); 21709 if (p->trtp) 21710 ast_rtp_instance_stop(p->trtp); 21711 if (p->udptl) 21712 ast_udptl_stop(p->udptl); 21713 }
| static void stop_session_timer | ( | struct sip_pvt * | p | ) | [static] |
Session-Timers: Stop session timer.
Definition at line 26758 of file chan_sip.c.
References ast_debug, AST_SCHED_DEL_UNREF, FALSE, and TRUE.
Referenced by __sip_destroy(), dialog_unlink_all(), handle_request_bye(), proc_session_timer(), sip_hangup(), and sip_scheddestroy().
26759 { 26760 if (p->stimer->st_active == TRUE) { 26761 p->stimer->st_active = FALSE; 26762 ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid); 26763 AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid, 26764 dialog_unref(p, "removing session timer ref")); 26765 } 26766 }
| static int str2dtmfmode | ( | const char * | str | ) | [static] |
| static enum st_mode str2stmode | ( | const char * | s | ) | [static] |
Definition at line 17017 of file chan_sip.c.
References map_s_x().
Referenced by build_peer(), and reload_config().
| static enum st_refresher str2strefresherparam | ( | const char * | s | ) | [static] |
Definition at line 17042 of file chan_sip.c.
References map_s_x().
Referenced by build_peer(), and reload_config().
17043 { 17044 return map_s_x(strefresher_params, s, -1); 17045 }
| static const char* strefresher2str | ( | enum st_refresher | r | ) | [static] |
Definition at line 17047 of file chan_sip.c.
References map_x_s().
Referenced by sip_show_channel().
17048 { 17049 return map_x_s(strefreshers, r, "Unknown"); 17050 }
| static const char * strefresherparam2str | ( | enum st_refresher | r | ) | [static] |
Definition at line 17037 of file chan_sip.c.
References map_x_s().
Referenced by _sip_show_peer(), sip_show_channel(), sip_show_settings(), and sip_show_user().
17038 { 17039 return map_x_s(strefresher_params, r, "Unknown"); 17040 }
| static const char * subscription_type2str | ( | enum subscriptiontype | subtype | ) | [static] |
Show subscription type in string format.
Definition at line 18945 of file chan_sip.c.
References ARRAY_LEN, subscription_types, cfsubscription_types::text, and type.
Referenced by show_channels_cb(), and sip_show_channel().
18946 { 18947 int i; 18948 18949 for (i = 1; i < ARRAY_LEN(subscription_types); i++) { 18950 if (subscription_types[i].type == subtype) { 18951 return subscription_types[i].text; 18952 } 18953 } 18954 return subscription_types[0].text; 18955 }
| static unsigned int t38_get_rate | ( | enum ast_control_t38_rate | rate | ) | [static] |
Get Max T.38 Transmission rate from T38 capabilities.
Definition at line 11502 of file chan_sip.c.
References AST_T38_RATE_12000, AST_T38_RATE_14400, AST_T38_RATE_2400, AST_T38_RATE_4800, AST_T38_RATE_7200, and AST_T38_RATE_9600.
Referenced by add_sdp().
11503 { 11504 switch (rate) { 11505 case AST_T38_RATE_2400: 11506 return 2400; 11507 case AST_T38_RATE_4800: 11508 return 4800; 11509 case AST_T38_RATE_7200: 11510 return 7200; 11511 case AST_T38_RATE_9600: 11512 return 9600; 11513 case AST_T38_RATE_12000: 11514 return 12000; 11515 case AST_T38_RATE_14400: 11516 return 14400; 11517 default: 11518 return 0; 11519 } 11520 }
| static void tcptls_packet_destructor | ( | void * | obj | ) | [static] |
Definition at line 2342 of file chan_sip.c.
References ast_free.
Referenced by sip_tcptls_write().
02343 { 02344 struct tcptls_packet *packet = obj; 02345 02346 ast_free(packet->data); 02347 }
| static struct sip_peer * temp_peer | ( | const char * | name | ) | [static, read] |
Create temporary peer (used in autocreatepeer mode).
Definition at line 28011 of file chan_sip.c.
References ao2_t_alloc, ao2_t_ref, ast_atomic_fetchadd_int(), ast_cc_config_params_init, ast_copy_string(), ast_string_field_init, default_prefs, reg_source_db(), set_peer_defaults(), sip_destroy_peer_fn(), and TRUE.
Referenced by load_module(), register_verify(), and sip_reload().
28012 { 28013 struct sip_peer *peer; 28014 28015 if (!(peer = ao2_t_alloc(sizeof(*peer), sip_destroy_peer_fn, "allocate a peer struct"))) 28016 return NULL; 28017 28018 if (ast_string_field_init(peer, 512)) { 28019 ao2_t_ref(peer, -1, "failed to string_field_init, drop peer"); 28020 return NULL; 28021 } 28022 28023 if (!(peer->cc_params = ast_cc_config_params_init())) { 28024 ao2_t_ref(peer, -1, "failed to allocate cc_params for peer"); 28025 return NULL; 28026 } 28027 28028 ast_atomic_fetchadd_int(&apeerobjs, 1); 28029 set_peer_defaults(peer); 28030 28031 ast_copy_string(peer->name, name, sizeof(peer->name)); 28032 28033 peer->selfdestruct = TRUE; 28034 peer->host_dynamic = TRUE; 28035 peer->prefs = default_prefs; 28036 reg_source_db(peer); 28037 28038 return peer; 28039 }
| static void temp_pvt_cleanup | ( | void * | data | ) | [static] |
Definition at line 10923 of file chan_sip.c.
References ast_free, and ast_string_field_free_memory.
10924 { 10925 struct sip_pvt *p = data; 10926 10927 ast_string_field_free_memory(p); 10928 10929 ast_free(data); 10930 }
| static int temp_pvt_init | ( | void * | data | ) | [static] |
Definition at line 10915 of file chan_sip.c.
References ast_string_field_init.
10916 { 10917 struct sip_pvt *p = data; 10918 10919 p->do_history = 0; /* XXX do we need it ? isn't already all 0 ? */ 10920 return ast_string_field_init(p, 512); 10921 }
| static char* terminate_uri | ( | char * | uri | ) | [static] |
Terminate the uri at the first ';' or space. Technically we should ignore escaped space per RFC3261 (19.1.1 etc) but don't do it for the time being. Remember the uri format is: (User-parameters was added after RFC 3261)
* * sip:user:password;user-parameters@host:port;uri-parameters?headers * sips:user:password;user-parameters@host:port;uri-parameters?headers * *
Definition at line 15236 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 26251 of file chan_sip.c.
References ast_sockaddr_cmp(), CMP_MATCH, and CMP_STOP.
Referenced by sip_tcp_locate().
26252 { 26253 struct sip_threadinfo *th = obj; 26254 struct ast_sockaddr *s = arg; 26255 26256 if (!ast_sockaddr_cmp(s, &th->tcptls_session->remote_address)) { 26257 return CMP_MATCH | CMP_STOP; 26258 } 26259 26260 return 0; 26261 }
| static int threadt_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 30817 of file chan_sip.c.
References CMP_MATCH, and CMP_STOP.
Referenced by load_module().
| static int threadt_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 30810 of file chan_sip.c.
References ast_sockaddr_hash().
Referenced by load_module().
30811 { 30812 const struct sip_threadinfo *th = obj; 30813 30814 return ast_sockaddr_hash(&th->tcptls_session->remote_address); 30815 }
| static char * transfermode2str | ( | enum transfermodes | mode | ) | [static] |
Convert transfer mode to text string.
Definition at line 16990 of file chan_sip.c.
Referenced by _sip_show_peer(), peers_data_provider_get(), sip_show_channel(), sip_show_settings(), and sip_show_user().
| static int transmit_cc_notify | ( | struct ast_cc_agent * | agent, | |
| struct sip_pvt * | subscription, | |||
| enum sip_cc_notify_state | state | |||
| ) | [static] |
Definition at line 13193 of file chan_sip.c.
References add_content(), add_header(), ast_log(), generate_uri(), LOG_WARNING, ast_cc_agent::private_data, reqprep(), send_request(), sip_cc_notify_state_map, state_string, and TRUE.
Referenced by sip_cc_agent_recall(), and sip_cc_agent_respond().
13194 { 13195 struct sip_request req; 13196 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 13197 char uri[SIPBUFSIZE]; 13198 char state_str[64]; 13199 char subscription_state_hdr[64]; 13200 13201 if (state < CC_QUEUED || state > CC_READY) { 13202 ast_log(LOG_WARNING, "Invalid state provided for transmit_cc_notify (%u)\n", state); 13203 return -1; 13204 } 13205 13206 reqprep(&req, subscription, SIP_NOTIFY, 0, TRUE); 13207 snprintf(state_str, sizeof(state_str), "%s\r\n", sip_cc_notify_state_map[state].state_string); 13208 add_header(&req, "Event", "call-completion"); 13209 add_header(&req, "Content-Type", "application/call-completion"); 13210 snprintf(subscription_state_hdr, sizeof(subscription_state_hdr), "active;expires=%d", subscription->expiry); 13211 add_header(&req, "Subscription-State", subscription_state_hdr); 13212 if (state == CC_READY) { 13213 generate_uri(subscription, agent_pvt->notify_uri, sizeof(agent_pvt->notify_uri)); 13214 snprintf(uri, sizeof(uri) - 1, "cc-URI: %s\r\n", agent_pvt->notify_uri); 13215 } 13216 add_content(&req, state_str); 13217 if (state == CC_READY) { 13218 add_content(&req, uri); 13219 } 13220 return send_request(subscription, &req, XMIT_RELIABLE, subscription->ocseq); 13221 }
| static void transmit_fake_auth_response | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| enum xmittype | reliable | |||
| ) | [static] |
Send a fake 401 Unauthorized response when the administrator wants to hide the names of local devices from fishers.
Definition at line 15135 of file chan_sip.c.
References __transmit_response(), AST_DYNSTR_BUILD_FAILED, ast_skip_blanks(), ast_str_set(), ast_str_thread_get(), ast_strlen_zero(), CHECK_AUTH_BUF_INITLEN, FALSE, get_header(), set_nonce_randdata(), sip_scheddestroy(), and transmit_response_with_auth().
Referenced by register_verify().
15136 { 15137 /* We have to emulate EXACTLY what we'd get with a good peer 15138 * and a bad password, or else we leak information. */ 15139 const char *response = "401 Unauthorized"; 15140 const char *reqheader = "Authorization"; 15141 const char *respheader = "WWW-Authenticate"; 15142 const char *authtoken; 15143 struct ast_str *buf; 15144 char *c; 15145 15146 /* table of recognised keywords, and their value in the digest */ 15147 enum keys { K_NONCE, K_LAST }; 15148 struct x { 15149 const char *key; 15150 const char *s; 15151 } *i, keys[] = { 15152 [K_NONCE] = { "nonce=", "" }, 15153 [K_LAST] = { NULL, NULL} 15154 }; 15155 15156 authtoken = get_header(req, reqheader); 15157 if (req->ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 15158 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 15159 * information */ 15160 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 15161 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 15162 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15163 return; 15164 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 15165 /* We have no auth, so issue challenge and request authentication */ 15166 set_nonce_randdata(p, 1); 15167 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 15168 /* Schedule auto destroy in 32 seconds */ 15169 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15170 return; 15171 } 15172 15173 if (!(buf = ast_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) { 15174 __transmit_response(p, "403 Forbidden", &p->initreq, reliable); 15175 return; 15176 } 15177 15178 /* Make a copy of the response and parse it */ 15179 if (ast_str_set(&buf, 0, "%s", authtoken) == AST_DYNSTR_BUILD_FAILED) { 15180 __transmit_response(p, "403 Forbidden", &p->initreq, reliable); 15181 return; 15182 } 15183 15184 c = buf->str; 15185 15186 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 15187 for (i = keys; i->key != NULL; i++) { 15188 const char *separator = ","; /* default */ 15189 15190 if (strncasecmp(c, i->key, strlen(i->key)) != 0) { 15191 continue; 15192 } 15193 /* Found. Skip keyword, take text in quotes or up to the separator. */ 15194 c += strlen(i->key); 15195 if (*c == '"') { /* in quotes. Skip first and look for last */ 15196 c++; 15197 separator = "\""; 15198 } 15199 i->s = c; 15200 strsep(&c, separator); 15201 break; 15202 } 15203 if (i->key == NULL) { /* not found, jump after space or comma */ 15204 strsep(&c, " ,"); 15205 } 15206 } 15207 15208 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 15209 if (strcasecmp(p->randdata, keys[K_NONCE].s)) { 15210 if (!req->ignore) { 15211 set_nonce_randdata(p, 1); 15212 } 15213 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 15214 15215 /* Schedule auto destroy in 32 seconds */ 15216 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15217 } else { 15218 __transmit_response(p, "403 Forbidden", &p->initreq, reliable); 15219 } 15220 }
| static int transmit_info_with_aoc | ( | struct sip_pvt * | p, | |
| struct ast_aoc_decoded * | decoded | |||
| ) | [static] |
Send SIP INFO advice of charge message.
Definition at line 14048 of file chan_sip.c.
References add_header(), ast_aoc_unit_entry::amount, AST_AOC_CHARGE_CURRENCY, AST_AOC_CHARGE_FREE, AST_AOC_CHARGE_UNIT, AST_AOC_D, AST_AOC_E, ast_aoc_get_charge_type(), ast_aoc_get_currency_amount(), ast_aoc_get_currency_multiplier_decimal(), ast_aoc_get_currency_name(), ast_aoc_get_msg_type(), ast_aoc_get_unit_info(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_strlen_zero(), reqprep(), send_request(), and str.
Referenced by sip_indicate().
14049 { 14050 struct sip_request req; 14051 struct ast_str *str = ast_str_alloca(512); 14052 const struct ast_aoc_unit_entry *unit_entry = ast_aoc_get_unit_info(decoded, 0); 14053 enum ast_aoc_charge_type charging = ast_aoc_get_charge_type(decoded); 14054 14055 reqprep(&req, p, SIP_INFO, 0, 1); 14056 14057 if (ast_aoc_get_msg_type(decoded) == AST_AOC_D) { 14058 ast_str_append(&str, 0, "type=active;"); 14059 } else if (ast_aoc_get_msg_type(decoded) == AST_AOC_E) { 14060 ast_str_append(&str, 0, "type=terminated;"); 14061 } else { 14062 /* unsupported message type */ 14063 return -1; 14064 } 14065 14066 switch (charging) { 14067 case AST_AOC_CHARGE_FREE: 14068 ast_str_append(&str, 0, "free-of-charge;"); 14069 break; 14070 case AST_AOC_CHARGE_CURRENCY: 14071 ast_str_append(&str, 0, "charging;"); 14072 ast_str_append(&str, 0, "charging-info=currency;"); 14073 ast_str_append(&str, 0, "amount=%u;", ast_aoc_get_currency_amount(decoded)); 14074 ast_str_append(&str, 0, "multiplier=%s;", ast_aoc_get_currency_multiplier_decimal(decoded)); 14075 if (!ast_strlen_zero(ast_aoc_get_currency_name(decoded))) { 14076 ast_str_append(&str, 0, "currency=%s;", ast_aoc_get_currency_name(decoded)); 14077 } 14078 break; 14079 case AST_AOC_CHARGE_UNIT: 14080 ast_str_append(&str, 0, "charging;"); 14081 ast_str_append(&str, 0, "charging-info=pulse;"); 14082 if (unit_entry) { 14083 ast_str_append(&str, 0, "recorded-units=%u;", unit_entry->amount); 14084 } 14085 break; 14086 default: 14087 ast_str_append(&str, 0, "not-available;"); 14088 }; 14089 14090 add_header(&req, "AOC", ast_str_buffer(str)); 14091 14092 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 14093 }
| static int transmit_info_with_digit | ( | struct sip_pvt * | p, | |
| const char | digit, | |||
| unsigned int | duration | |||
| ) | [static] |
Send SIP INFO dtmf message, see Cisco documentation on cisco.com.
Definition at line 14096 of file chan_sip.c.
References add_digit(), ast_test_flag, reqprep(), and send_request().
Referenced by sip_senddigit_end().
14097 { 14098 struct sip_request req; 14099 14100 reqprep(&req, p, SIP_INFO, 0, 1); 14101 add_digit(&req, digit, duration, (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_SHORTINFO)); 14102 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 14103 }
| static int transmit_info_with_vidupdate | ( | struct sip_pvt * | p | ) | [static] |
Send SIP INFO with video update request.
Definition at line 14106 of file chan_sip.c.
References add_vidupdate(), reqprep(), and send_request().
Referenced by sip_indicate().
14107 { 14108 struct sip_request req; 14109 14110 reqprep(&req, p, SIP_INFO, 0, 1); 14111 add_vidupdate(&req); 14112 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 14113 }
| static int transmit_invite | ( | struct sip_pvt * | p, | |
| int | sipmethod, | |||
| int | sdp, | |||
| int | init, | |||
| const char *const | explicit_uri | |||
| ) | [static] |
Build REFER/INVITE/OPTIONS/SUBSCRIBE message and transmit it.
| p | sip_pvt structure | |
| sipmethod | ||
| sdp | unknown | |
| init | 0 = Prepare request within dialog, 1= prepare request, new branch, 2= prepare new request and new dialog. do_proxy_auth calls this with init!=2 | |
| explicit_uri |
Definition at line 12610 of file chan_sip.c.
References add_content(), add_diversion_header(), add_header(), add_rpid(), add_sdp(), add_supported_header(), append_date(), ast_channel_lock, ast_channel_unlock, ast_debug, AST_LIST_TRAVERSE, ast_log(), ast_random(), ast_skip_blanks(), ast_str_buffer(), ast_str_strlen(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_var_name(), ast_var_value(), build_via(), FALSE, initialize_initreq(), initreqprep(), LOG_WARNING, ast_variable::name, ast_variable::next, reqprep(), send_request(), st_get_mode(), st_get_se(), TRUE, try_suggested_sip_codec(), ast_variable::value, var, and ast_channel::varshead.
Referenced by __sip_subscribe_mwi_do(), cc_handle_publish_error(), do_proxy_auth(), manager_sipnotify(), proc_422_rsp(), sip_call(), sip_cc_monitor_request_cc(), sip_cli_notify(), sip_monitor_instance_destructor(), sip_poke_peer(), and transmit_publish().
12611 { 12612 struct sip_request req; 12613 struct ast_variable *var; 12614 12615 if (init) {/* Bump branch even on initial requests */ 12616 p->branch ^= ast_random(); 12617 p->invite_branch = p->branch; 12618 build_via(p); 12619 } 12620 if (init > 1) { 12621 initreqprep(&req, p, sipmethod, explicit_uri); 12622 } else { 12623 /* If init=1, we should not generate a new branch. If it's 0, we need a new branch. */ 12624 reqprep(&req, p, sipmethod, 0, init ? 0 : 1); 12625 } 12626 12627 if (p->options && p->options->auth) { 12628 add_header(&req, p->options->authheader, p->options->auth); 12629 } 12630 append_date(&req); 12631 if (sipmethod == SIP_REFER) { /* Call transfer */ 12632 if (p->refer) { 12633 char buf[SIPBUFSIZE]; 12634 if (!ast_strlen_zero(p->refer->refer_to)) { 12635 add_header(&req, "Refer-To", p->refer->refer_to); 12636 } 12637 if (!ast_strlen_zero(p->refer->referred_by)) { 12638 snprintf(buf, sizeof(buf), "%s <%s>", p->refer->referred_by_name, p->refer->referred_by); 12639 add_header(&req, "Referred-By", buf); 12640 } 12641 } 12642 } else if (sipmethod == SIP_SUBSCRIBE) { 12643 char buf[SIPBUFSIZE]; 12644 if (p->subscribed == MWI_NOTIFICATION) { 12645 add_header(&req, "Event", "message-summary"); 12646 add_header(&req, "Accept", "application/simple-message-summary"); 12647 } else if (p->subscribed == CALL_COMPLETION) { 12648 add_header(&req, "Event", "call-completion"); 12649 add_header(&req, "Accept", "application/call-completion"); 12650 } 12651 snprintf(buf, sizeof(buf), "%d", p->expiry); 12652 add_header(&req, "Expires", buf); 12653 } 12654 12655 /* This new INVITE is part of an attended transfer. Make sure that the 12656 other end knows and replace the current call with this new call */ 12657 if (p->options && !ast_strlen_zero(p->options->replaces)) { 12658 add_header(&req, "Replaces", p->options->replaces); 12659 add_header(&req, "Require", "replaces"); 12660 } 12661 12662 /* Add Session-Timers related headers */ 12663 if (st_get_mode(p, 0) == SESSION_TIMER_MODE_ORIGINATE 12664 || (st_get_mode(p, 0) == SESSION_TIMER_MODE_ACCEPT 12665 && st_get_se(p, FALSE) != DEFAULT_MIN_SE)) { 12666 char i2astr[10]; 12667 12668 if (!p->stimer->st_interval) { 12669 p->stimer->st_interval = st_get_se(p, TRUE); 12670 } 12671 12672 p->stimer->st_active = TRUE; 12673 if (st_get_mode(p, 0) == SESSION_TIMER_MODE_ORIGINATE) { 12674 snprintf(i2astr, sizeof(i2astr), "%d", p->stimer->st_interval); 12675 add_header(&req, "Session-Expires", i2astr); 12676 } 12677 12678 snprintf(i2astr, sizeof(i2astr), "%d", st_get_se(p, FALSE)); 12679 add_header(&req, "Min-SE", i2astr); 12680 } 12681 12682 add_header(&req, "Allow", ALLOWED_METHODS); 12683 add_supported_header(p, &req); 12684 12685 if (p->options && p->options->addsipheaders && p->owner) { 12686 struct ast_channel *chan = p->owner; /* The owner channel */ 12687 struct varshead *headp; 12688 12689 ast_channel_lock(chan); 12690 12691 headp = &chan->varshead; 12692 12693 if (!headp) { 12694 ast_log(LOG_WARNING, "No Headp for the channel...ooops!\n"); 12695 } else { 12696 const struct ast_var_t *current; 12697 AST_LIST_TRAVERSE(headp, current, entries) { 12698 /* SIPADDHEADER: Add SIP header to outgoing call */ 12699 if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 12700 char *content, *end; 12701 const char *header = ast_var_value(current); 12702 char *headdup = ast_strdupa(header); 12703 12704 /* Strip of the starting " (if it's there) */ 12705 if (*headdup == '"') { 12706 headdup++; 12707 } 12708 if ((content = strchr(headdup, ':'))) { 12709 *content++ = '\0'; 12710 content = ast_skip_blanks(content); /* Skip white space */ 12711 /* Strip the ending " (if it's there) */ 12712 end = content + strlen(content) -1; 12713 if (*end == '"') { 12714 *end = '\0'; 12715 } 12716 12717 add_header(&req, headdup, content); 12718 if (sipdebug) { 12719 ast_debug(1, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content); 12720 } 12721 } 12722 } 12723 } 12724 } 12725 12726 ast_channel_unlock(chan); 12727 } 12728 if ((sipmethod == SIP_INVITE || sipmethod == SIP_UPDATE) && ast_test_flag(&p->flags[0], SIP_SENDRPID)) 12729 add_rpid(&req, p); 12730 if (sipmethod == SIP_INVITE) { 12731 add_diversion_header(&req, p); 12732 } 12733 if (sdp) { 12734 memset(p->offered_media, 0, sizeof(p->offered_media)); 12735 if (p->udptl && p->t38.state == T38_LOCAL_REINVITE) { 12736 ast_debug(1, "T38 is in state %u on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12737 add_sdp(&req, p, FALSE, FALSE, TRUE); 12738 } else if (p->rtp) { 12739 try_suggested_sip_codec(p); 12740 add_sdp(&req, p, FALSE, TRUE, FALSE); 12741 } 12742 } else if (p->notify) { 12743 for (var = p->notify->headers; var; var = var->next) { 12744 add_header(&req, var->name, var->value); 12745 } 12746 if (ast_str_strlen(p->notify->content)) { 12747 add_content(&req, ast_str_buffer(p->notify->content)); 12748 } 12749 } else if (sipmethod == SIP_PUBLISH) { 12750 char expires[SIPBUFSIZE]; 12751 12752 switch (p->epa_entry->static_data->event) { 12753 case CALL_COMPLETION: 12754 snprintf(expires, sizeof(expires), "%d", p->expiry); 12755 add_header(&req, "Event", "call-completion"); 12756 add_header(&req, "Expires", expires); 12757 if (p->epa_entry->publish_type != SIP_PUBLISH_INITIAL) { 12758 add_header(&req, "SIP-If-Match", p->epa_entry->entity_tag); 12759 } 12760 12761 if (!ast_strlen_zero(p->epa_entry->body)) { 12762 add_header(&req, "Content-Type", "application/pidf+xml"); 12763 add_content(&req, p->epa_entry->body); 12764 } 12765 default: 12766 break; 12767 } 12768 } 12769 12770 if (!p->initreq.headers || init > 2) { 12771 initialize_initreq(p, &req); 12772 } 12773 if (sipmethod == SIP_INVITE || sipmethod == SIP_SUBSCRIBE) { 12774 p->lastinvite = p->ocseq; 12775 } 12776 return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq); 12777 }
| static int transmit_message_with_text | ( | struct sip_pvt * | p, | |
| const char * | text | |||
| ) | [static] |
Transmit text with SIP MESSAGE method.
Definition at line 13944 of file chan_sip.c.
References add_text(), reqprep(), and send_request().
Referenced by sip_park_thread(), and sip_sendtext().
13945 { 13946 struct sip_request req; 13947 13948 reqprep(&req, p, SIP_MESSAGE, 0, 1); 13949 add_text(&req, text); 13950 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 13951 }
| static int transmit_notify_with_mwi | ( | struct sip_pvt * | p, | |
| int | newmsgs, | |||
| int | oldmsgs, | |||
| const char * | vmexten | |||
| ) | [static] |
Notify user of messages waiting in voicemail (RFC3842).
Definition at line 13331 of file chan_sip.c.
References add_content(), add_header(), ast_sockaddr_port, ast_sockaddr_stringify_host_remote(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_test_flag, exten, get_transport(), initialize_initreq(), initreqprep(), ourport, S_OR, send_request(), and sip_standard_port().
Referenced by sip_send_mwi_to_peer().
13332 { 13333 struct sip_request req; 13334 struct ast_str *out = ast_str_alloca(500); 13335 int ourport = (p->fromdomainport && (p->fromdomainport != STANDARD_SIP_PORT)) ? p->fromdomainport : ast_sockaddr_port(&p->ourip); 13336 const char *domain; 13337 const char *exten = S_OR(vmexten, default_vmexten); 13338 13339 initreqprep(&req, p, SIP_NOTIFY, NULL); 13340 add_header(&req, "Event", "message-summary"); 13341 add_header(&req, "Content-Type", default_notifymime); 13342 ast_str_append(&out, 0, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no"); 13343 13344 /* domain initialization occurs here because initreqprep changes ast_sockaddr_stringify string. */ 13345 domain = S_OR(p->fromdomain, ast_sockaddr_stringify_host_remote(&p->ourip)); 13346 13347 if (!sip_standard_port(p->socket.type, ourport)) { 13348 if (p->socket.type == SIP_TRANSPORT_UDP) { 13349 ast_str_append(&out, 0, "Message-Account: sip:%s@%s:%d\r\n", exten, domain, ourport); 13350 } else { 13351 ast_str_append(&out, 0, "Message-Account: sip:%s@%s:%d;transport=%s\r\n", exten, domain, ourport, get_transport(p->socket.type)); 13352 } 13353 } else { 13354 if (p->socket.type == SIP_TRANSPORT_UDP) { 13355 ast_str_append(&out, 0, "Message-Account: sip:%s@%s\r\n", exten, domain); 13356 } else { 13357 ast_str_append(&out, 0, "Message-Account: sip:%s@%s;transport=%s\r\n", exten, domain, get_transport(p->socket.type)); 13358 } 13359 } 13360 /* Cisco has a bug in the SIP stack where it can't accept the 13361 (0/0) notification. This can temporarily be disabled in 13362 sip.conf with the "buggymwi" option */ 13363 ast_str_append(&out, 0, "Voice-Message: %d/%d%s\r\n", 13364 newmsgs, oldmsgs, (ast_test_flag(&p->flags[1], SIP_PAGE2_BUGGY_MWI) ? "" : " (0/0)")); 13365 13366 if (p->subscribed) { 13367 if (p->expiry) { 13368 add_header(&req, "Subscription-State", "active"); 13369 } else { /* Expired */ 13370 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 13371 } 13372 } 13373 13374 add_content(&req, ast_str_buffer(out)); 13375 13376 if (!p->initreq.headers) { 13377 initialize_initreq(p, &req); 13378 } 13379 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 13380 }
| static int transmit_notify_with_sipfrag | ( | struct sip_pvt * | p, | |
| int | cseq, | |||
| char * | message, | |||
| int | terminate | |||
| ) | [static] |
Notify a transferring party of the status of transfer (RFC3515).
Definition at line 13383 of file chan_sip.c.
References add_content(), add_header(), add_supported_header(), initialize_initreq(), reqprep(), and send_request().
Referenced by handle_request_refer(), local_attended_transfer(), and sip_park_thread().
13384 { 13385 struct sip_request req; 13386 char tmp[SIPBUFSIZE/2]; 13387 13388 reqprep(&req, p, SIP_NOTIFY, 0, 1); 13389 snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq); 13390 add_header(&req, "Event", tmp); 13391 add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active"); 13392 add_header(&req, "Content-Type", "message/sipfrag;version=2.0"); 13393 add_header(&req, "Allow", ALLOWED_METHODS); 13394 add_supported_header(p, &req); 13395 13396 snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message); 13397 add_content(&req, tmp); 13398 13399 if (!p->initreq.headers) { 13400 initialize_initreq(p, &req); 13401 } 13402 13403 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 13404 }
| static int transmit_provisional_response | ( | struct sip_pvt * | p, | |
| const char * | msg, | |||
| const struct sip_request * | req, | |||
| int | with_sdp | |||
| ) | [static] |
Definition at line 11189 of file chan_sip.c.
References FALSE, transmit_response(), transmit_response_with_sdp(), and update_provisional_keepalive().
Referenced by handle_request_invite(), sip_indicate(), and sip_write().
11190 { 11191 int res; 11192 11193 if (!(res = with_sdp ? transmit_response_with_sdp(p, msg, req, XMIT_UNRELIABLE, FALSE, FALSE) : transmit_response(p, msg, req))) { 11194 p->last_provisional = msg; 11195 update_provisional_keepalive(p, with_sdp); 11196 } 11197 11198 return res; 11199 }
| static int transmit_publish | ( | struct sip_epa_entry * | epa_entry, | |
| enum sip_publish_type | publish_type, | |||
| const char *const | explicit_uri | |||
| ) | [static] |
Definition at line 12566 of file chan_sip.c.
References ao2_ref, ast_set_flag, ast_sip_ouraddrfor(), create_addr(), dialog_unlink_all(), FALSE, sip_alloc(), sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), transmit_invite(), and TRUE.
Referenced by handle_cc_notify(), sip_cc_monitor_suspend(), sip_cc_monitor_unsuspend(), and sip_monitor_instance_destructor().
12567 { 12568 struct sip_pvt *pvt; 12569 int expires; 12570 12571 epa_entry->publish_type = publish_type; 12572 12573 if (!(pvt = sip_alloc(NULL, NULL, 0, SIP_PUBLISH, NULL))) { 12574 return -1; 12575 } 12576 12577 sip_pvt_lock(pvt); 12578 12579 if (create_addr(pvt, epa_entry->destination, NULL, TRUE)) { 12580 sip_pvt_unlock(pvt); 12581 dialog_unlink_all(pvt); 12582 dialog_unref(pvt, "create_addr failed in transmit_publish. Unref dialog"); 12583 return -1; 12584 } 12585 ast_sip_ouraddrfor(&pvt->sa, &pvt->ourip, pvt); 12586 ast_set_flag(&pvt->flags[0], SIP_OUTGOING); 12587 expires = (publish_type == SIP_PUBLISH_REMOVE) ? 0 : DEFAULT_PUBLISH_EXPIRES; 12588 pvt->expiry = expires; 12589 12590 /* Bump refcount for sip_pvt's reference */ 12591 ao2_ref(epa_entry, +1); 12592 pvt->epa_entry = epa_entry; 12593 12594 transmit_invite(pvt, SIP_PUBLISH, FALSE, 2, explicit_uri); 12595 sip_pvt_unlock(pvt); 12596 sip_scheddestroy(pvt, DEFAULT_TRANS_TIMEOUT); 12597 dialog_unref(pvt, "Done with the sip_pvt allocated for transmitting PUBLISH"); 12598 return 0; 12599 }
| static int transmit_refer | ( | struct sip_pvt * | p, | |
| const char * | dest | |||
| ) | [static] |
Transmit SIP REFER message (initiated by the transfer() dialplan application.
Definition at line 13975 of file chan_sip.c.
References add_header(), add_supported_header(), ast_copy_string(), ast_debug, ast_log(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, FALSE, get_header(), get_in_brackets(), LOG_NOTICE, reqprep(), send_request(), sip_refer_allocate(), and TRUE.
Referenced by sip_transfer().
13976 { 13977 struct sip_request req = { 13978 .headers = 0, 13979 }; 13980 char from[256]; 13981 const char *of; 13982 char *c; 13983 char referto[256]; 13984 int use_tls=FALSE; 13985 13986 if (sipdebug) { 13987 ast_debug(1, "SIP transfer of %s to %s\n", p->callid, dest); 13988 } 13989 13990 /* Are we transfering an inbound or outbound call ? */ 13991 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 13992 of = get_header(&p->initreq, "To"); 13993 } else { 13994 of = get_header(&p->initreq, "From"); 13995 } 13996 13997 ast_copy_string(from, of, sizeof(from)); 13998 of = get_in_brackets(from); 13999 ast_string_field_set(p, from, of); 14000 if (!strncasecmp(of, "sip:", 4)) { 14001 of += 4; 14002 } else if (!strncasecmp(of, "sips:", 5)) { 14003 of += 5; 14004 use_tls = TRUE; 14005 } else { 14006 ast_log(LOG_NOTICE, "From address missing 'sip(s):', assuming sip:\n"); 14007 } 14008 /* Get just the username part */ 14009 if (strchr(dest, '@')) { 14010 c = NULL; 14011 } else if ((c = strchr(of, '@'))) { 14012 *c++ = '\0'; 14013 } 14014 if (c) { 14015 snprintf(referto, sizeof(referto), "<sip%s:%s@%s>", use_tls ? "s" : "", dest, c); 14016 } else { 14017 snprintf(referto, sizeof(referto), "<sip%s:%s>", use_tls ? "s" : "", dest); 14018 } 14019 14020 /* save in case we get 407 challenge */ 14021 sip_refer_allocate(p); 14022 ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to)); 14023 ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by)); 14024 p->refer->status = REFER_SENT; /* Set refer status */ 14025 14026 reqprep(&req, p, SIP_REFER, 0, 1); 14027 14028 add_header(&req, "Refer-To", referto); 14029 add_header(&req, "Allow", ALLOWED_METHODS); 14030 add_supported_header(p, &req); 14031 if (!ast_strlen_zero(p->our_contact)) { 14032 add_header(&req, "Referred-By", p->our_contact); 14033 } 14034 14035 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 14036 14037 /* We should propably wait for a NOTIFY here until we ack the transfer */ 14038 /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */ 14039 14040 /*! \todo In theory, we should hang around and wait for a reply, before 14041 returning to the dial plan here. Don't know really how that would 14042 affect the transfer() app or the pbx, but, well, to make this 14043 useful we should have a STATUS code on transfer(). 14044 */ 14045 }
| static int transmit_register | ( | struct sip_registry * | r, | |
| int | sipmethod, | |||
| const char * | auth, | |||
| const char * | authheader | |||
| ) | [static] |
Transmit register to SIP proxy or UA auth = NULL on the initial registration (from sip_reregister()).
Definition at line 13684 of file chan_sip.c.
References add_header(), add_header_max_forwards(), append_history, ast_debug, ast_dnsmgr_lookup_cb(), ast_log(), ast_random(), ast_sched_add(), AST_SCHED_REPLACE_UNREF, ast_set_flag, ast_sip_ouraddrfor(), ast_sockaddr_cmp(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_set_port, ast_string_field_set, ast_strlen_zero(), ast_verbose, build_callid_registry(), build_contact(), build_localtag_registry(), build_reply_digest(), build_via(), create_addr(), dialog_unlink_all(), exten, FALSE, find_peer(), get_address_family_filter(), get_srv_protocol(), get_srv_service(), init_req(), initialize_initreq(), internip, ast_tcptls_session_args::local_address, LOG_NOTICE, LOG_WARNING, MAXHOSTNAMELEN, obproxy_get(), on_dns_update_peer(), on_dns_update_registry(), REG_STATE_AUTHSENT, REG_STATE_REGSENT, registry_addref(), registry_unref(), S_OR, send_request(), set_socket_transport(), sip_alloc(), sip_cfg, sip_debug_test_pvt(), sip_methods, sip_reg_timeout(), sip_sanitized_host(), cfsip_methods::text, TRUE, and unref_peer().
Referenced by __sip_do_register(), do_register_auth(), handle_response_register(), and sip_reg_timeout().
13685 { 13686 struct sip_request req; 13687 char from[256]; 13688 char to[256]; 13689 char tmp[80]; 13690 char addr[80]; 13691 struct sip_pvt *p; 13692 struct sip_peer *peer = NULL; 13693 int res; 13694 int portno = 0; 13695 13696 /* exit if we are already in process with this registrar ?*/ 13697 if (r == NULL || ((auth == NULL) && (r->regstate == REG_STATE_REGSENT || r->regstate == REG_STATE_AUTHSENT))) { 13698 if (r) { 13699 ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname); 13700 } 13701 return 0; 13702 } 13703 13704 if (r->dnsmgr == NULL) { 13705 char transport[MAXHOSTNAMELEN]; 13706 peer = find_peer(r->hostname, NULL, TRUE, FINDPEERS, FALSE, 0); 13707 snprintf(transport, sizeof(transport), "_%s._%s",get_srv_service(r->transport), get_srv_protocol(r->transport)); /* have to use static get_transport function */ 13708 r->us.ss.ss_family = get_address_family_filter(r->transport); /* Filter address family */ 13709 13710 /* No point in doing a DNS lookup of the register hostname if we're just going to 13711 * end up using an outbound proxy. obproxy_get is safe to call with either of r->call 13712 * or peer NULL. Since we're only concerned with its existence, we're not going to 13713 * bother getting a ref to the proxy*/ 13714 if (!obproxy_get(r->call, peer)) { 13715 registry_addref(r, "add reg ref for dnsmgr"); 13716 ast_dnsmgr_lookup_cb(peer ? peer->tohost : r->hostname, &r->us, &r->dnsmgr, sip_cfg.srvlookup ? transport : NULL, on_dns_update_registry, r); 13717 if (!r->dnsmgr) { 13718 /*dnsmgr refresh disabled, no reference added! */ 13719 registry_unref(r, "remove reg ref, dnsmgr disabled"); 13720 } 13721 } 13722 if (peer) { 13723 peer = unref_peer(peer, "removing peer ref for dnsmgr_lookup"); 13724 } 13725 } 13726 13727 if (r->call) { /* We have a registration */ 13728 if (!auth) { 13729 ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname); 13730 return 0; 13731 } else { 13732 p = dialog_ref(r->call, "getting a copy of the r->call dialog in transmit_register"); 13733 ast_string_field_set(p, theirtag, NULL); /* forget their old tag, so we don't match tags when getting response */ 13734 } 13735 } else { 13736 /* Build callid for registration if we haven't registered before */ 13737 if (!r->callid_valid) { 13738 build_callid_registry(r, &internip, default_fromdomain); 13739 build_localtag_registry(r); 13740 r->callid_valid = TRUE; 13741 } 13742 /* Allocate SIP dialog for registration */ 13743 if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER, NULL))) { 13744 ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n"); 13745 return 0; 13746 } 13747 13748 /* reset tag to consistent value from registry */ 13749 ast_string_field_set(p, tag, r->localtag); 13750 13751 if (p->do_history) { 13752 append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname); 13753 } 13754 13755 p->socket.type = r->transport; 13756 13757 /* Use port number specified if no SRV record was found */ 13758 if (!ast_sockaddr_isnull(&r->us)) { 13759 if (!ast_sockaddr_port(&r->us) && r->portno) { 13760 ast_sockaddr_set_port(&r->us, r->portno); 13761 } 13762 13763 /* It is possible that DNS was unavailable at the time the peer was created. 13764 * Here, if we've updated the address in the registry via manually calling 13765 * ast_dnsmgr_lookup_cb() above, then we call the same function that dnsmgr would 13766 * call if it was updating a peer's address */ 13767 if ((peer = find_peer(S_OR(r->peername, r->hostname), NULL, TRUE, FINDPEERS, FALSE, 0))) { 13768 if (ast_sockaddr_cmp(&peer->addr, &r->us)) { 13769 on_dns_update_peer(&peer->addr, &r->us, peer); 13770 } 13771 peer = unref_peer(peer, "unref after find_peer"); 13772 } 13773 } 13774 13775 /* Find address to hostname */ 13776 if (create_addr(p, S_OR(r->peername, r->hostname), &r->us, 0)) { 13777 /* we have what we hope is a temporary network error, 13778 * probably DNS. We need to reschedule a registration try */ 13779 dialog_unlink_all(p); 13780 p = dialog_unref(p, "unref dialog after unlink_all"); 13781 if (r->timeout > -1) { 13782 AST_SCHED_REPLACE_UNREF(r->timeout, sched, global_reg_timeout * 1000, sip_reg_timeout, r, 13783 registry_unref(_data, "del for REPLACE of registry ptr"), 13784 registry_unref(r, "object ptr dec when SCHED_REPLACE add failed"), 13785 registry_addref(r,"add for REPLACE registry ptr")); 13786 ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout); 13787 } else { 13788 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, registry_addref(r, "add for REPLACE registry ptr")); 13789 ast_log(LOG_WARNING, "Probably a DNS error for registration to %s@%s, trying REGISTER again (after %d seconds)\n", r->username, r->hostname, global_reg_timeout); 13790 } 13791 r->regattempts++; 13792 return 0; 13793 } 13794 13795 /* Copy back Call-ID in case create_addr changed it */ 13796 ast_string_field_set(r, callid, p->callid); 13797 13798 if (!r->dnsmgr && r->portno) { 13799 ast_sockaddr_set_port(&p->sa, r->portno); 13800 ast_sockaddr_set_port(&p->recv, r->portno); 13801 } 13802 if (!ast_strlen_zero(p->fromdomain)) { 13803 portno = (p->fromdomainport) ? p->fromdomainport : STANDARD_SIP_PORT; 13804 } else if (!ast_strlen_zero(r->regdomain)) { 13805 portno = (r->regdomainport) ? r->regdomainport : STANDARD_SIP_PORT; 13806 } else { 13807 portno = ast_sockaddr_port(&p->sa); 13808 } 13809 13810 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */ 13811 r->call = dialog_ref(p, "copying dialog into registry r->call"); /* Save pointer to SIP dialog */ 13812 p->registry = registry_addref(r, "transmit_register: addref to p->registry in transmit_register"); /* Add pointer to registry in packet */ 13813 if (!ast_strlen_zero(r->secret)) { /* Secret (password) */ 13814 ast_string_field_set(p, peersecret, r->secret); 13815 } 13816 if (!ast_strlen_zero(r->md5secret)) 13817 ast_string_field_set(p, peermd5secret, r->md5secret); 13818 /* User name in this realm 13819 - if authuser is set, use that, otherwise use username */ 13820 if (!ast_strlen_zero(r->authuser)) { 13821 ast_string_field_set(p, peername, r->authuser); 13822 ast_string_field_set(p, authname, r->authuser); 13823 } else if (!ast_strlen_zero(r->username)) { 13824 ast_string_field_set(p, peername, r->username); 13825 ast_string_field_set(p, authname, r->username); 13826 ast_string_field_set(p, fromuser, r->username); 13827 } 13828 if (!ast_strlen_zero(r->username)) { 13829 ast_string_field_set(p, username, r->username); 13830 } 13831 /* Save extension in packet */ 13832 if (!ast_strlen_zero(r->callback)) { 13833 ast_string_field_set(p, exten, r->callback); 13834 } 13835 13836 /* Set transport and port so the correct contact is built */ 13837 set_socket_transport(&p->socket, r->transport); 13838 if (r->transport == SIP_TRANSPORT_TLS || r->transport == SIP_TRANSPORT_TCP) { 13839 p->socket.port = 13840 htons(ast_sockaddr_port(&sip_tcp_desc.local_address)); 13841 } 13842 13843 /* 13844 check which address we should use in our contact header 13845 based on whether the remote host is on the external or 13846 internal network so we can register through nat 13847 */ 13848 ast_sip_ouraddrfor(&p->sa, &p->ourip, p); 13849 build_contact(p); 13850 } 13851 13852 /* set up a timeout */ 13853 if (auth == NULL) { 13854 if (r->timeout > -1) { 13855 ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout); 13856 } 13857 AST_SCHED_REPLACE_UNREF(r->timeout, sched, global_reg_timeout * 1000, sip_reg_timeout, r, 13858 registry_unref(_data,"reg ptr unrefed from del in SCHED_REPLACE"), 13859 registry_unref(r,"reg ptr unrefed from add failure in SCHED_REPLACE"), 13860 registry_addref(r,"reg ptr reffed from add in SCHED_REPLACE")); 13861 ast_debug(1, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); 13862 } 13863 13864 snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, S_OR(r->regdomain, sip_sanitized_host(p->tohost)), p->tag); 13865 if (!ast_strlen_zero(p->theirtag)) { 13866 snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, S_OR(r->regdomain, sip_sanitized_host(p->tohost)), p->theirtag); 13867 } else { 13868 snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, S_OR(r->regdomain, sip_sanitized_host(p->tohost))); 13869 } 13870 13871 /* Fromdomain is what we are registering to, regardless of actual 13872 host name from SRV */ 13873 if (portno && portno != STANDARD_SIP_PORT) { 13874 snprintf(addr, sizeof(addr), "sip:%s:%d", S_OR(p->fromdomain,S_OR(r->regdomain, sip_sanitized_host(r->hostname))), portno); 13875 } else { 13876 snprintf(addr, sizeof(addr), "sip:%s", S_OR(p->fromdomain,S_OR(r->regdomain, sip_sanitized_host(r->hostname)))); 13877 } 13878 13879 ast_string_field_set(p, uri, addr); 13880 13881 p->branch ^= ast_random(); 13882 13883 init_req(&req, sipmethod, addr); 13884 13885 /* Add to CSEQ */ 13886 snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text); 13887 p->ocseq = r->ocseq; 13888 13889 build_via(p); 13890 add_header(&req, "Via", p->via); 13891 add_header_max_forwards(p, &req); 13892 add_header(&req, "From", from); 13893 add_header(&req, "To", to); 13894 add_header(&req, "Call-ID", p->callid); 13895 add_header(&req, "CSeq", tmp); 13896 if (!ast_strlen_zero(global_useragent)) 13897 add_header(&req, "User-Agent", global_useragent); 13898 13899 if (auth) { /* Add auth header */ 13900 add_header(&req, authheader, auth); 13901 } else if (!ast_strlen_zero(r->nonce)) { 13902 char digest[1024]; 13903 13904 /* We have auth data to reuse, build a digest header. 13905 * Note, this is not always useful because some parties do not 13906 * like nonces to be reused (for good reasons!) so they will 13907 * challenge us anyways. 13908 */ 13909 if (sipdebug) { 13910 ast_debug(1, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname); 13911 } 13912 ast_string_field_set(p, realm, r->realm); 13913 ast_string_field_set(p, nonce, r->nonce); 13914 ast_string_field_set(p, domain, r->authdomain); 13915 ast_string_field_set(p, opaque, r->opaque); 13916 ast_string_field_set(p, qop, r->qop); 13917 p->noncecount = ++r->noncecount; 13918 13919 memset(digest, 0, sizeof(digest)); 13920 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 13921 add_header(&req, "Authorization", digest); 13922 } else { 13923 ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname); 13924 } 13925 } 13926 13927 snprintf(tmp, sizeof(tmp), "%d", r->expiry); 13928 add_header(&req, "Expires", tmp); 13929 add_header(&req, "Contact", p->our_contact); 13930 13931 initialize_initreq(p, &req); 13932 if (sip_debug_test_pvt(p)) { 13933 ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 13934 } 13935 r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT; 13936 r->regattempts++; /* Another attempt */ 13937 ast_debug(4, "REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname); 13938 res = send_request(p, &req, XMIT_CRITICAL, p->ocseq); 13939 dialog_unref(p, "p is finished here at the end of transmit_register"); 13940 return res; 13941 }
| static int transmit_reinvite_with_sdp | ( | struct sip_pvt * | p, | |
| int | t38version, | |||
| int | oldsdp | |||
| ) | [static] |
Transmit reinvite with SDP.
If t38version is TRUE, we send T38 SDP for re-invite from audio/video to T38 UDPTL transmission on the channel
If oldsdp is TRUE then the SDP version number is not incremented. This is needed for Session-Timers so we can send a re-invite to refresh the SIP session without modifying the media session.
Definition at line 12260 of file chan_sip.c.
References add_header(), add_rpid(), add_sdp(), add_supported_header(), append_history, ast_set_flag, ast_test_flag, FALSE, initialize_initreq(), reqprep(), send_request(), TRUE, and try_suggested_sip_codec().
Referenced by check_pendings(), handle_response_invite(), interpret_t38_parameters(), proc_session_timer(), sip_sendhtml(), sip_set_rtp_peer(), and sip_set_udptl_peer().
12261 { 12262 struct sip_request req; 12263 12264 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 12265 12266 add_header(&req, "Allow", ALLOWED_METHODS); 12267 add_supported_header(p, &req); 12268 if (sipdebug) { 12269 if (oldsdp == TRUE) 12270 add_header(&req, "X-asterisk-Info", "SIP re-invite (Session-Timers)"); 12271 else 12272 add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)"); 12273 } 12274 12275 if (ast_test_flag(&p->flags[0], SIP_SENDRPID)) 12276 add_rpid(&req, p); 12277 12278 if (p->do_history) { 12279 append_history(p, "ReInv", "Re-invite sent"); 12280 } 12281 memset(p->offered_media, 0, sizeof(p->offered_media)); 12282 12283 try_suggested_sip_codec(p); 12284 if (t38version) { 12285 add_sdp(&req, p, oldsdp, FALSE, TRUE); 12286 } else { 12287 add_sdp(&req, p, oldsdp, TRUE, FALSE); 12288 } 12289 12290 /* Use this as the basis */ 12291 initialize_initreq(p, &req); 12292 p->lastinvite = p->ocseq; 12293 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 12294 p->ongoing_reinvite = 1; 12295 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 12296 }
| static int transmit_request | ( | struct sip_pvt * | p, | |
| int | sipmethod, | |||
| uint32_t | seqno, | |||
| enum xmittype | reliable, | |||
| int | newbranch | |||
| ) | [static] |
Transmit generic SIP request returns XMIT_ERROR if transmit failed with a critical error (don't retry).
Definition at line 14118 of file chan_sip.c.
References add_header(), reqprep(), and send_request().
Referenced by check_pendings(), handle_response(), handle_response_invite(), and sip_hangup().
14119 { 14120 struct sip_request resp; 14121 14122 reqprep(&resp, p, sipmethod, seqno, newbranch); 14123 if (sipmethod == SIP_CANCEL && p->answered_elsewhere) { 14124 add_header(&resp, "Reason", "SIP;cause=200;text=\"Call completed elsewhere\""); 14125 } 14126 14127 if (sipmethod == SIP_ACK) { 14128 p->invitestate = INV_CONFIRMED; 14129 } 14130 14131 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 14132 }
| static int transmit_request_with_auth | ( | struct sip_pvt * | p, | |
| int | sipmethod, | |||
| uint32_t | seqno, | |||
| enum xmittype | reliable, | |||
| int | newbranch | |||
| ) | [static] |
Transmit SIP request, auth added.
Definition at line 14150 of file chan_sip.c.
References add_header(), ast_cause2str(), ast_log(), ast_strlen_zero(), ast_test_flag, auth_headers(), build_reply_digest(), dummy(), LOG_WARNING, reqprep(), and send_request().
Referenced by __sip_autodestruct(), check_pendings(), and sip_hangup().
14151 { 14152 struct sip_request resp; 14153 14154 reqprep(&resp, p, sipmethod, seqno, newbranch); 14155 if (!ast_strlen_zero(p->realm)) { 14156 char digest[1024]; 14157 14158 memset(digest, 0, sizeof(digest)); 14159 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 14160 char *dummy, *response; 14161 enum sip_auth_type code = p->options ? p->options->auth_type : PROXY_AUTH; /* XXX force 407 if unknown */ 14162 auth_headers(code, &dummy, &response); 14163 add_header(&resp, response, digest); 14164 } else { 14165 ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid); 14166 } 14167 } 14168 /* If we are hanging up and know a cause for that, send it in clear text to make 14169 debugging easier. */ 14170 if (sipmethod == SIP_BYE) { 14171 char buf[20]; 14172 14173 if (ast_test_flag(&p->flags[1], SIP_PAGE2_Q850_REASON) && p->hangupcause) { 14174 sprintf(buf, "Q.850;cause=%i", p->hangupcause & 0x7f); 14175 add_header(&resp, "Reason", buf); 14176 } 14177 14178 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->hangupcause)); 14179 snprintf(buf, sizeof(buf), "%d", p->hangupcause); 14180 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 14181 } 14182 14183 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 14184 }
| static int transmit_response | ( | struct sip_pvt * | p, | |
| const char * | msg, | |||
| const struct sip_request * | req | |||
| ) | [static] |
Transmit response, no retransmits.
Definition at line 10986 of file chan_sip.c.
References __transmit_response().
Referenced by handle_cc_notify(), handle_cc_subscribe(), handle_incoming(), handle_invite_replaces(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_message(), handle_request_notify(), handle_request_options(), handle_request_publish(), handle_request_refer(), handle_request_subscribe(), handle_request_update(), handle_sip_publish_initial(), handle_sip_publish_modify(), handle_sip_publish_refresh(), handle_sip_publish_remove(), receive_message(), register_verify(), send_provisional_keepalive_full(), sip_cc_agent_destructor(), sip_cc_agent_respond(), sip_indicate(), sip_sendhtml(), and transmit_provisional_response().
10987 { 10988 return __transmit_response(p, msg, req, XMIT_UNRELIABLE); 10989 }
| static int transmit_response_reliable | ( | struct sip_pvt * | p, | |
| const char * | msg, | |||
| const struct sip_request * | req | |||
| ) | [static] |
Transmit response, Make sure you get an ACK This is only used for responses to INVITEs, where we need to make sure we get an ACK.
Definition at line 11019 of file chan_sip.c.
References __transmit_response().
Referenced by handle_incoming(), handle_invite_replaces(), handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_invite_st(), interpret_t38_parameters(), sip_hangup(), sip_indicate(), sip_sipredirect(), and sip_t38_abort().
11020 { 11021 return __transmit_response(p, msg, req, req->ignore ? XMIT_UNRELIABLE : XMIT_CRITICAL); 11022 }
| static int transmit_response_using_temp | ( | ast_string_field | callid, | |
| struct ast_sockaddr * | addr, | |||
| int | useglobal_nat, | |||
| const int | intended_method, | |||
| const struct sip_request * | req, | |||
| const char * | msg | |||
| ) | [static] |
Transmit response, no retransmits, using a temporary pvt structure.
Definition at line 10933 of file chan_sip.c.
References __transmit_response(), ast_copy_flags, ast_log(), ast_random(), ast_sip_ouraddrfor(), ast_sockaddr_copy(), ast_string_field_init, ast_string_field_set, ast_threadstorage_get(), build_via(), copy_socket_data(), do_setnat(), internip, LOG_ERROR, and make_our_tag().
Referenced by find_call().
10934 { 10935 struct sip_pvt *p = NULL; 10936 10937 if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) { 10938 ast_log(LOG_ERROR, "Failed to get temporary pvt\n"); 10939 return -1; 10940 } 10941 10942 /* XXX the structure may be dirty from previous usage. 10943 * Here we should state clearly how we should reinitialize it 10944 * before using it. 10945 * E.g. certainly the threadstorage should be left alone, 10946 * but other thihngs such as flags etc. maybe need cleanup ? 10947 */ 10948 10949 /* Initialize the bare minimum */ 10950 p->method = intended_method; 10951 10952 if (!addr) { 10953 ast_sockaddr_copy(&p->ourip, &internip); 10954 } else { 10955 ast_sockaddr_copy(&p->sa, addr); 10956 ast_sip_ouraddrfor(&p->sa, &p->ourip, p); 10957 } 10958 10959 p->branch = ast_random(); 10960 make_our_tag(p); 10961 p->ocseq = INITIAL_CSEQ; 10962 10963 if (useglobal_nat && addr) { 10964 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT_FORCE_RPORT); 10965 ast_sockaddr_copy(&p->recv, addr); 10966 do_setnat(p); 10967 } 10968 10969 ast_string_field_set(p, fromdomain, default_fromdomain); 10970 p->fromdomainport = default_fromdomainport; 10971 build_via(p); 10972 ast_string_field_set(p, callid, callid); 10973 10974 copy_socket_data(&p->socket, &req->socket); 10975 10976 /* Use this temporary pvt structure to send the message */ 10977 __transmit_response(p, msg, req, XMIT_UNRELIABLE); 10978 10979 /* Free the string fields, but not the pool space */ 10980 ast_string_field_init(p, 0); 10981 10982 return 0; 10983 }
| static int transmit_response_with_allow | ( | struct sip_pvt * | p, | |
| const char * | msg, | |||
| const struct sip_request * | req, | |||
| enum xmittype | reliable | |||
| ) | [static] |
Append Accept header, content length before transmitting response.
Definition at line 11055 of file chan_sip.c.
References add_header(), respprep(), and send_response().
Referenced by handle_incoming(), and handle_request_options().
11056 { 11057 struct sip_request resp; 11058 respprep(&resp, p, msg, req); 11059 add_header(&resp, "Accept", "application/sdp"); 11060 return send_response(p, &resp, reliable, 0); 11061 }
| static int transmit_response_with_auth | ( | struct sip_pvt * | p, | |
| const char * | msg, | |||
| const struct sip_request * | req, | |||
| const char * | rand, | |||
| enum xmittype | reliable, | |||
| const char * | header, | |||
| int | stale | |||
| ) | [static] |
Respond with authorization request.
Definition at line 11076 of file chan_sip.c.
References add_header(), append_history, ast_log(), get_header(), get_realm(), LOG_WARNING, respprep(), and send_response().
Referenced by check_auth(), and transmit_fake_auth_response().
11077 { 11078 struct sip_request resp; 11079 char tmp[512]; 11080 uint32_t seqno = 0; 11081 11082 if (reliable && (sscanf(get_header(req, "CSeq"), "%30u ", &seqno) != 1)) { 11083 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 11084 return -1; 11085 } 11086 /* Choose Realm */ 11087 get_realm(p, req); 11088 11089 /* Stale means that they sent us correct authentication, but 11090 based it on an old challenge (nonce) */ 11091 snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", p->realm, randdata, stale ? ", stale=true" : ""); 11092 respprep(&resp, p, msg, req); 11093 add_header(&resp, header, tmp); 11094 append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount); 11095 return send_response(p, &resp, reliable, seqno); 11096 }
| static int transmit_response_with_date | ( | struct sip_pvt * | p, | |
| const char * | msg, | |||
| const struct sip_request * | req | |||
| ) | [static] |
Append date and content length before transmitting response.
Definition at line 11046 of file chan_sip.c.
References append_date(), respprep(), and send_response().
Referenced by handle_response_subscribe(), and register_verify().
11047 { 11048 struct sip_request resp; 11049 respprep(&resp, p, msg, req); 11050 append_date(&resp); 11051 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 11052 }
| static int transmit_response_with_minexpires | ( | struct sip_pvt * | p, | |
| const char * | msg, | |||
| const struct sip_request * | req | |||
| ) | [static] |
Append Min-Expires header, content length before transmitting response.
Definition at line 11064 of file chan_sip.c.
References add_header(), respprep(), and send_response().
Referenced by handle_request_publish(), and handle_request_subscribe().
11065 { 11066 struct sip_request resp; 11067 char tmp[32]; 11068 11069 snprintf(tmp, sizeof(tmp), "%d", min_expiry); 11070 respprep(&resp, p, msg, req); 11071 add_header(&resp, "Min-Expires", tmp); 11072 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 11073 }
| static int transmit_response_with_minse | ( | struct sip_pvt * | p, | |
| const char * | msg, | |||
| const struct sip_request * | req, | |||
| int | minse_int | |||
| ) | [static] |
Transmit 422 response with Min-SE header (Session-Timers).
Definition at line 11002 of file chan_sip.c.
References add_header(), append_date(), respprep(), and send_response().
Referenced by handle_request_invite_st().
11003 { 11004 struct sip_request resp; 11005 char minse_str[20]; 11006 11007 respprep(&resp, p, msg, req); 11008 append_date(&resp); 11009 11010 snprintf(minse_str, sizeof(minse_str), "%d", minse_int); 11011 add_header(&resp, "Min-SE", minse_str); 11012 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 11013 }
| static int transmit_response_with_retry_after | ( | struct sip_pvt * | p, | |
| const char * | msg, | |||
| const struct sip_request * | req, | |||
| const char * | seconds | |||
| ) | [static] |
Append Retry-After header field when transmitting response.
Definition at line 11037 of file chan_sip.c.
References add_header(), respprep(), and send_response().
Referenced by handle_incoming().
11038 { 11039 struct sip_request resp; 11040 respprep(&resp, p, msg, req); 11041 add_header(&resp, "Retry-After", seconds); 11042 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 11043 }
| static int transmit_response_with_sdp | ( | struct sip_pvt * | p, | |
| const char * | msg, | |||
| const struct sip_request * | req, | |||
| enum xmittype | reliable, | |||
| int | oldsdp, | |||
| int | rpid | |||
| ) | [static] |
Used for 200 OK and 183 early media.
Definition at line 12169 of file chan_sip.c.
References add_cc_call_info_to_response(), add_required_respheader(), add_rpid(), add_sdp(), ast_debug, ast_log(), ast_rtp_codecs_packetization_set(), ast_rtp_instance_activate(), ast_rtp_instance_get_codecs(), ast_test_flag, FALSE, get_header(), LOG_ERROR, LOG_WARNING, respprep(), send_response(), TRUE, and try_suggested_sip_codec().
Referenced by handle_invite_replaces(), handle_request_invite(), send_provisional_keepalive_full(), sip_answer(), and transmit_provisional_response().
12170 { 12171 struct sip_request resp; 12172 uint32_t seqno; 12173 if (sscanf(get_header(req, "CSeq"), "%30u ", &seqno) != 1) { 12174 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 12175 return -1; 12176 } 12177 respprep(&resp, p, msg, req); 12178 if (rpid == TRUE) { 12179 add_rpid(&resp, p); 12180 } 12181 if (ast_test_flag(&p->flags[0], SIP_OFFER_CC)) { 12182 add_cc_call_info_to_response(p, &resp); 12183 } 12184 if (p->rtp) { 12185 if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 12186 ast_debug(1, "Setting framing from config on incoming call\n"); 12187 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &p->prefs); 12188 } 12189 ast_rtp_instance_activate(p->rtp); 12190 try_suggested_sip_codec(p); 12191 if (p->t38.state == T38_ENABLED) { 12192 add_sdp(&resp, p, oldsdp, TRUE, TRUE); 12193 } else { 12194 add_sdp(&resp, p, oldsdp, TRUE, FALSE); 12195 } 12196 } else 12197 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid); 12198 if (reliable && !p->pendinginvite) 12199 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 12200 add_required_respheader(&resp); 12201 return send_response(p, &resp, reliable, seqno); 12202 }
| static int transmit_response_with_sip_etag | ( | struct sip_pvt * | p, | |
| const char * | msg, | |||
| const struct sip_request * | req, | |||
| struct sip_esc_entry * | esc_entry, | |||
| int | need_new_etag | |||
| ) | [static] |
Definition at line 10902 of file chan_sip.c.
References add_header(), create_new_sip_etag(), respprep(), and send_response().
Referenced by handle_sip_publish_initial(), handle_sip_publish_modify(), handle_sip_publish_refresh(), and handle_sip_publish_remove().
10903 { 10904 struct sip_request resp; 10905 10906 if (need_new_etag) { 10907 create_new_sip_etag(esc_entry, 1); 10908 } 10909 respprep(&resp, p, msg, req); 10910 add_header(&resp, "SIP-ETag", esc_entry->entity_tag); 10911 10912 return send_response(p, &resp, 0, 0); 10913 }
| static int transmit_response_with_t38_sdp | ( | struct sip_pvt * | p, | |
| char * | msg, | |||
| struct sip_request * | req, | |||
| int | retrans | |||
| ) | [static] |
Used for 200 OK and 183 early media.
Definition at line 12085 of file chan_sip.c.
References add_sdp(), ast_log(), get_header(), LOG_ERROR, LOG_WARNING, respprep(), and send_response().
Referenced by handle_request_invite(), and interpret_t38_parameters().
12086 { 12087 struct sip_request resp; 12088 uint32_t seqno; 12089 12090 if (sscanf(get_header(req, "CSeq"), "%30u ", &seqno) != 1) { 12091 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 12092 return -1; 12093 } 12094 respprep(&resp, p, msg, req); 12095 if (p->udptl) { 12096 add_sdp(&resp, p, 0, 0, 1); 12097 } else 12098 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid); 12099 if (retrans && !p->pendinginvite) 12100 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 12101 return send_response(p, &resp, retrans, seqno); 12102 }
| static int transmit_response_with_unsupported | ( | struct sip_pvt * | p, | |
| const char * | msg, | |||
| const struct sip_request * | req, | |||
| const char * | unsupported | |||
| ) | [static] |
Transmit response, no retransmits.
Definition at line 10992 of file chan_sip.c.
References add_header(), append_date(), respprep(), and send_response().
Referenced by handle_request_bye(), handle_request_invite(), and handle_request_invite_st().
10993 { 10994 struct sip_request resp; 10995 respprep(&resp, p, msg, req); 10996 append_date(&resp); 10997 add_header(&resp, "Unsupported", unsupported); 10998 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 10999 }
| static int transmit_state_notify | ( | struct sip_pvt * | p, | |
| int | state, | |||
| int | full, | |||
| int | timeout | |||
| ) | [static] |
Used in the SUBSCRIBE notification subsystem (RFC3265).
Definition at line 13224 of file chan_sip.c.
References add_content(), add_header(), ast_copy_string(), AST_EXTENSION_DEACTIVATED, AST_EXTENSION_REMOVED, ast_log(), ast_str_alloca, ast_str_buffer(), ast_test_flag, cfsubscription_types::event, find_subscription_type(), get_header(), get_in_brackets(), LOG_WARNING, cfsubscription_types::mediatype, NONE, remove_uri_parameters(), reqprep(), send_request(), and state_notify_build_xml().
Referenced by __sip_autodestruct(), cb_extensionstate(), and handle_request_subscribe().
13225 { 13226 struct ast_str *tmp = ast_str_alloca(4000); 13227 char from[256], to[256]; 13228 char *c, *mfrom, *mto; 13229 struct sip_request req; 13230 const struct cfsubscription_types *subscriptiontype; 13231 13232 /* If the subscription has not yet been accepted do not send a NOTIFY */ 13233 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) { 13234 return 0; 13235 } 13236 13237 memset(from, 0, sizeof(from)); 13238 memset(to, 0, sizeof(to)); 13239 13240 subscriptiontype = find_subscription_type(p->subscribed); 13241 13242 ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from)); 13243 c = get_in_brackets(from); 13244 if (strncasecmp(c, "sip:", 4) && strncasecmp(c, "sips:", 5)) { 13245 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 13246 return -1; 13247 } 13248 13249 mfrom = remove_uri_parameters(c); 13250 13251 ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to)); 13252 c = get_in_brackets(to); 13253 if (strncasecmp(c, "sip:", 4) && strncasecmp(c, "sips:", 5)) { 13254 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 13255 return -1; 13256 } 13257 mto = remove_uri_parameters(c); 13258 13259 reqprep(&req, p, SIP_NOTIFY, 0, 1); 13260 13261 switch(state) { 13262 case AST_EXTENSION_DEACTIVATED: 13263 if (timeout) 13264 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 13265 else { 13266 add_header(&req, "Subscription-State", "terminated;reason=probation"); 13267 add_header(&req, "Retry-After", "60"); 13268 } 13269 break; 13270 case AST_EXTENSION_REMOVED: 13271 add_header(&req, "Subscription-State", "terminated;reason=noresource"); 13272 break; 13273 default: 13274 if (p->expiry) 13275 add_header(&req, "Subscription-State", "active"); 13276 else /* Expired */ 13277 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 13278 } 13279 13280 switch (p->subscribed) { 13281 case XPIDF_XML: 13282 case CPIM_PIDF_XML: 13283 add_header(&req, "Event", subscriptiontype->event); 13284 state_notify_build_xml(state, full, p->exten, p->context, &tmp, p, p->subscribed, mfrom, mto); 13285 add_header(&req, "Content-Type", subscriptiontype->mediatype); 13286 p->dialogver++; 13287 break; 13288 case PIDF_XML: /* Eyebeam supports this format */ 13289 add_header(&req, "Event", subscriptiontype->event); 13290 state_notify_build_xml(state, full, p->exten, p->context, &tmp, p, p->subscribed, mfrom, mto); 13291 add_header(&req, "Content-Type", subscriptiontype->mediatype); 13292 p->dialogver++; 13293 break; 13294 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 13295 add_header(&req, "Event", subscriptiontype->event); 13296 state_notify_build_xml(state, full, p->exten, p->context, &tmp, p, p->subscribed, mfrom, mto); 13297 add_header(&req, "Content-Type", subscriptiontype->mediatype); 13298 p->dialogver++; 13299 break; 13300 case NONE: 13301 default: 13302 break; 13303 } 13304 13305 add_content(&req, ast_str_buffer(tmp)); 13306 13307 p->pendinginvite = p->ocseq; /* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */ 13308 13309 /* Send as XMIT_CRITICAL as we may never receive a 200 OK Response which clears p->pendinginvite. 13310 * 13311 * extensionstate_update() uses p->pendinginvite for queuing control. 13312 * Updates stall if pendinginvite <> 0. 13313 * 13314 * The most appropriate solution is to remove the subscription when the NOTIFY transaction fails. 13315 * The client will re-subscribe after restarting or maxexpiry timeout. 13316 */ 13317 13318 /* RFC6665 4.2.2. Sending State Information to Subscribers 13319 * If the NOTIFY request fails due to expiration of SIP Timer F (transaction timeout), 13320 * the notifier SHOULD remove the subscription. 13321 */ 13322 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 13323 }
| static const char* transport2str | ( | enum sip_transport | transport | ) | [static] |
Definition at line 19213 of file chan_sip.c.
Referenced by sip_show_channel().
| static const char* trust_id_outbound2str | ( | int | mode | ) | [static] |
Definition at line 17615 of file chan_sip.c.
References map_x_s().
Referenced by _sip_show_peer().
17616 { 17617 return map_x_s(trust_id_outboundstr, mode, "<error>"); 17618 }
| static void try_suggested_sip_codec | ( | struct sip_pvt * | p | ) | [static] |
Try setting codec suggested by the SIP_CODEC channel variable.
Definition at line 6700 of file chan_sip.c.
References ast_getformatbyname(), ast_log(), LOG_NOTICE, and pbx_builtin_getvar_helper().
Referenced by sip_answer(), transmit_invite(), transmit_reinvite_with_sdp(), and transmit_response_with_sdp().
06701 { 06702 format_t fmt; 06703 const char *codec; 06704 06705 if (p->outgoing_call) { 06706 codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC_OUTBOUND"); 06707 } else if (!(codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC_INBOUND"))) { 06708 codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC"); 06709 } 06710 06711 if (!codec) 06712 return; 06713 06714 fmt = ast_getformatbyname(codec); 06715 if (fmt) { 06716 ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec); 06717 if (p->jointcapability & fmt) { 06718 p->jointcapability &= fmt; 06719 p->capability &= fmt; 06720 } else 06721 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n"); 06722 } else 06723 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec); 06724 return; 06725 }
| static void unlink_all_peers_from_tables | ( | void | ) | [static] |
Definition at line 3042 of file chan_sip.c.
References SIP_PEERS_ALL, and unlink_peers_from_tables().
Referenced by unload_module().
03043 { 03044 unlink_peers_from_tables(SIP_PEERS_ALL); 03045 }
| static void unlink_marked_peers_from_tables | ( | void | ) | [static] |
Definition at line 3037 of file chan_sip.c.
References SIP_PEERS_MARKED, and unlink_peers_from_tables().
Referenced by sip_do_reload(), and sip_prune_realtime().
03038 { 03039 unlink_peers_from_tables(SIP_PEERS_MARKED); 03040 }
| static void unlink_peers_from_tables | ( | peer_unlink_flag_t | flag | ) | [static] |
Definition at line 3028 of file chan_sip.c.
References ao2_t_callback, match_and_cleanup_peer_sched(), OBJ_MULTIPLE, OBJ_NODATA, and OBJ_UNLINK.
Referenced by unlink_all_peers_from_tables(), and unlink_marked_peers_from_tables().
03029 { 03030 ao2_t_callback(peers, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, 03031 match_and_cleanup_peer_sched, &flag, "initiating callback to remove marked peers"); 03032 ao2_t_callback(peers_by_ip, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, 03033 match_and_cleanup_peer_sched, &flag, "initiating callback to remove marked peers"); 03034 }
| static int unload_module | ( | void | ) | [static] |
PBX unload module API.
Definition at line 31966 of file chan_sip.c.
References ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ao2_t_ref, ARRAY_LEN, ast_cc_agent_unregister(), ast_cc_monitor_unregister(), ast_channel_unregister(), ast_cli_unregister_multiple(), ast_config_destroy(), ast_context_destroy(), ast_context_find(), ast_custom_function_unregister(), ast_data_unregister, ast_debug, ast_dnsmgr_release(), ast_free, ast_free_ha(), ast_io_remove(), ast_manager_unregister(), ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_rtp_glue_unregister(), ast_sched_dump(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_ssl_teardown(), ast_tcptls_server_stop(), AST_TEST_UNREGISTER, ast_udptl_proto_unregister(), ast_unload_realtime(), ast_unregister_application(), ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, ast_tls_config::cafile, ast_tls_config::capath, ast_tls_config::certfile, ast_tls_config::cipher, cleanup_all_regs(), clear_sip_domains(), destroy_escs(), dialog_unlink_all(), io_context_destroy(), ast_tcptls_session_args::master, network_change_event_unsubscribe(), ast_tls_config::pvtfile, regl, sched_context_destroy(), sip_cfg, sip_epa_unregister_all(), sip_registry_destroy(), sip_reqresp_parser_exit(), sip_subscribe_mwi_destroy(), sip_unregister_tests(), submwil, thread, ast_tcptls_session_args::tls_cfg, and unlink_all_peers_from_tables().
31967 { 31968 struct sip_pvt *p; 31969 struct sip_threadinfo *th; 31970 struct ast_context *con; 31971 struct ao2_iterator i; 31972 int wait_count; 31973 31974 network_change_event_unsubscribe(); 31975 31976 ast_sched_dump(sched); 31977 31978 /* First, take us out of the channel type list */ 31979 ast_channel_unregister(&sip_tech); 31980 31981 /* Unregister dial plan functions */ 31982 ast_custom_function_unregister(&sipchaninfo_function); 31983 ast_custom_function_unregister(&sippeer_function); 31984 ast_custom_function_unregister(&sip_header_function); 31985 ast_custom_function_unregister(&checksipdomain_function); 31986 31987 /* Unregister dial plan applications */ 31988 ast_unregister_application(app_dtmfmode); 31989 ast_unregister_application(app_sipaddheader); 31990 ast_unregister_application(app_sipremoveheader); 31991 31992 #ifdef TEST_FRAMEWORK 31993 AST_TEST_UNREGISTER(test_sip_peers_get); 31994 AST_TEST_UNREGISTER(test_sip_mwi_subscribe_parse); 31995 AST_TEST_UNREGISTER(test_tcp_message_fragmentation); 31996 AST_TEST_UNREGISTER(get_in_brackets_const_test); 31997 #endif 31998 /* Unregister all the AstData providers */ 31999 ast_data_unregister(NULL); 32000 32001 /* Unregister CLI commands */ 32002 ast_cli_unregister_multiple(cli_sip, ARRAY_LEN(cli_sip)); 32003 32004 /* Disconnect from UDPTL */ 32005 ast_udptl_proto_unregister(&sip_udptl); 32006 32007 /* Disconnect from RTP engine */ 32008 ast_rtp_glue_unregister(&sip_rtp_glue); 32009 32010 /* Unregister AMI actions */ 32011 ast_manager_unregister("SIPpeers"); 32012 ast_manager_unregister("SIPshowpeer"); 32013 ast_manager_unregister("SIPqualifypeer"); 32014 ast_manager_unregister("SIPshowregistry"); 32015 ast_manager_unregister("SIPnotify"); 32016 32017 /* Kill TCP/TLS server threads */ 32018 if (sip_tcp_desc.master) { 32019 ast_tcptls_server_stop(&sip_tcp_desc); 32020 } 32021 if (sip_tls_desc.master) { 32022 ast_tcptls_server_stop(&sip_tls_desc); 32023 } 32024 ast_ssl_teardown(sip_tls_desc.tls_cfg); 32025 32026 /* Kill all existing TCP/TLS threads */ 32027 i = ao2_iterator_init(threadt, 0); 32028 while ((th = ao2_t_iterator_next(&i, "iterate through tcp threads for 'sip show tcp'"))) { 32029 pthread_t thread = th->threadid; 32030 th->stop = 1; 32031 pthread_kill(thread, SIGURG); 32032 ao2_t_ref(th, -1, "decrement ref from iterator"); 32033 } 32034 ao2_iterator_destroy(&i); 32035 32036 /* Hangup all dialogs if they have an owner */ 32037 i = ao2_iterator_init(dialogs, 0); 32038 while ((p = ao2_t_iterator_next(&i, "iterate thru dialogs"))) { 32039 if (p->owner) 32040 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 32041 ao2_t_ref(p, -1, "toss dialog ptr from iterator_next"); 32042 } 32043 ao2_iterator_destroy(&i); 32044 32045 unlink_all_peers_from_tables(); 32046 32047 ast_mutex_lock(&monlock); 32048 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 32049 pthread_t th = monitor_thread; 32050 monitor_thread = AST_PTHREADT_STOP; 32051 pthread_cancel(th); 32052 pthread_kill(th, SIGURG); 32053 ast_mutex_unlock(&monlock); 32054 pthread_join(th, NULL); 32055 } else { 32056 monitor_thread = AST_PTHREADT_STOP; 32057 ast_mutex_unlock(&monlock); 32058 } 32059 32060 /* Destroy all the dialogs and free their memory */ 32061 i = ao2_iterator_init(dialogs, 0); 32062 while ((p = ao2_t_iterator_next(&i, "iterate thru dialogs"))) { 32063 dialog_unlink_all(p); 32064 ao2_t_ref(p, -1, "throw away iterator result"); 32065 } 32066 ao2_iterator_destroy(&i); 32067 32068 /* Free memory for local network address mask */ 32069 ast_free_ha(localaddr); 32070 32071 ast_mutex_lock(&authl_lock); 32072 if (authl) { 32073 ao2_t_ref(authl, -1, "Removing global authentication"); 32074 authl = NULL; 32075 } 32076 ast_mutex_unlock(&authl_lock); 32077 32078 sip_epa_unregister_all(); 32079 destroy_escs(); 32080 32081 ast_free(default_tls_cfg.certfile); 32082 ast_free(default_tls_cfg.pvtfile); 32083 ast_free(default_tls_cfg.cipher); 32084 ast_free(default_tls_cfg.cafile); 32085 ast_free(default_tls_cfg.capath); 32086 32087 cleanup_all_regs(); 32088 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 32089 ASTOBJ_CONTAINER_DESTROY(®l); 32090 32091 ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do { 32092 ASTOBJ_WRLOCK(iterator); 32093 if (iterator->dnsmgr) { 32094 ast_dnsmgr_release(iterator->dnsmgr); 32095 iterator->dnsmgr = NULL; 32096 ASTOBJ_UNREF(iterator, sip_subscribe_mwi_destroy); 32097 } 32098 ASTOBJ_UNLOCK(iterator); 32099 } while(0)); 32100 ASTOBJ_CONTAINER_DESTROYALL(&submwil, sip_subscribe_mwi_destroy); 32101 ASTOBJ_CONTAINER_DESTROY(&submwil); 32102 32103 /* 32104 * Wait awhile for the TCP/TLS thread container to become empty. 32105 * 32106 * XXX This is a hack, but the worker threads cannot be created 32107 * joinable. They can die on their own and remove themselves 32108 * from the container thus resulting in a huge memory leak. 32109 */ 32110 wait_count = 1000; 32111 while (ao2_container_count(threadt) && --wait_count) { 32112 sched_yield(); 32113 } 32114 if (!wait_count) { 32115 ast_debug(2, "TCP/TLS thread container did not become empty :(\n"); 32116 } 32117 32118 ao2_t_ref(bogus_peer, -1, "unref the bogus_peer"); 32119 32120 ao2_t_ref(peers, -1, "unref the peers table"); 32121 ao2_t_ref(peers_by_ip, -1, "unref the peers_by_ip table"); 32122 ao2_t_ref(dialogs, -1, "unref the dialogs table"); 32123 ao2_t_ref(dialogs_to_destroy, -1, "unref dialogs_to_destroy"); 32124 ao2_t_ref(threadt, -1, "unref the thread table"); 32125 ao2_t_ref(sip_monitor_instances, -1, "unref the sip_monitor_instances table"); 32126 32127 clear_sip_domains(); 32128 ast_free_ha(sip_cfg.contact_ha); 32129 if (sipsock_read_id) { 32130 ast_io_remove(io, sipsock_read_id); 32131 sipsock_read_id = NULL; 32132 } 32133 close(sipsock); 32134 io_context_destroy(io); 32135 sched_context_destroy(sched); 32136 con = ast_context_find(used_context); 32137 if (con) { 32138 ast_context_destroy(con, "SIP"); 32139 } 32140 ast_unload_realtime("sipregs"); 32141 ast_unload_realtime("sippeers"); 32142 ast_cc_monitor_unregister(&sip_cc_monitor_callbacks); 32143 ast_cc_agent_unregister(&sip_cc_agent_callbacks); 32144 32145 sip_reqresp_parser_exit(); 32146 sip_unregister_tests(); 32147 32148 if (notify_types) { 32149 ast_config_destroy(notify_types); 32150 notify_types = NULL; 32151 } 32152 32153 return 0; 32154 }
| static void* unref_peer | ( | struct sip_peer * | peer, | |
| char * | tag | |||
| ) | [static] |
helper functions to unreference various types of objects. By handling them this way, we don't have to declare the destructor on each call, which removes the chance of errors.
Definition at line 2979 of file chan_sip.c.
References ao2_t_ref.
Referenced by __sip_destroy(), _sip_qualify_peer(), _sip_show_peer(), _sip_show_peers(), _sip_show_peers_one(), build_peer(), check_peer_ok(), complete_sip_peer(), complete_sip_registered_peer(), complete_sip_user(), create_addr(), expire_register(), find_peer(), function_sippeer(), handle_request_invite(), handle_request_notify(), handle_request_subscribe(), handle_response_peerpoke(), match_and_cleanup_peer_sched(), parse_register_contact(), peer_sched_cleanup(), realtime_peer(), reg_source_db(), register_verify(), reload_config(), sip_devicestate(), sip_do_debug_peer(), sip_poke_all_peers(), sip_poke_noanswer(), sip_poke_peer(), sip_poke_peer_s(), sip_prune_realtime(), sip_show_inuse(), sip_show_user(), sip_show_users(), sip_unregister(), transmit_register(), and update_call_counter().
02980 { 02981 ao2_t_ref(peer, -1, tag); 02982 return NULL; 02983 }
| static int update_call_counter | ( | struct sip_pvt * | fup, | |
| int | event | |||
| ) | [static] |
update_call_counter: Handle call_limit for SIP devices Setting a call-limit will cause calls above the limit not to be accepted.
Remember that for a type=friend, there's one limit for the user and another for the peer, not a combined call limit. This will cause unexpected behaviour in subscriptions, since a "friend" is *two* devices in Asterisk, not one.
Thought: For realtime, we should probably update storage with inuse counter...
Definition at line 6143 of file chan_sip.c.
References ao2_lock, ao2_unlock, ast_clear_flag, ast_copy_string(), ast_debug, AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_log(), ast_set_flag, ast_test_flag, FALSE, LOG_ERROR, LOG_NOTICE, name, ref_peer(), sip_cfg, sip_peer_hold(), sip_pvt_lock, sip_pvt_unlock, and unref_peer().
Referenced by __sip_destroy(), handle_request_cancel(), handle_request_invite(), handle_response_invite(), sip_call(), and sip_hangup().
06144 { 06145 char name[256]; 06146 int *inuse = NULL, *call_limit = NULL, *inringing = NULL; 06147 int outgoing = fup->outgoing_call; 06148 struct sip_peer *p = NULL; 06149 06150 ast_debug(3, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming"); 06151 06152 06153 /* Test if we need to check call limits, in order to avoid 06154 realtime lookups if we do not need it */ 06155 if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT) && !ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD)) 06156 return 0; 06157 06158 ast_copy_string(name, fup->username, sizeof(name)); 06159 06160 /* Check the list of devices */ 06161 if (fup->relatedpeer) { 06162 p = ref_peer(fup->relatedpeer, "ref related peer for update_call_counter"); 06163 inuse = &p->inUse; 06164 call_limit = &p->call_limit; 06165 inringing = &p->inRinging; 06166 ast_copy_string(name, fup->peername, sizeof(name)); 06167 } 06168 if (!p) { 06169 ast_debug(2, "%s is not a local device, no call limit\n", name); 06170 return 0; 06171 } 06172 06173 switch(event) { 06174 /* incoming and outgoing affects the inUse counter */ 06175 case DEC_CALL_LIMIT: 06176 /* Decrement inuse count if applicable */ 06177 if (inuse) { 06178 sip_pvt_lock(fup); 06179 ao2_lock(p); 06180 if (*inuse > 0) { 06181 if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) { 06182 (*inuse)--; 06183 ast_clear_flag(&fup->flags[0], SIP_INC_COUNT); 06184 } 06185 } else { 06186 *inuse = 0; 06187 } 06188 ao2_unlock(p); 06189 sip_pvt_unlock(fup); 06190 } 06191 06192 /* Decrement ringing count if applicable */ 06193 if (inringing) { 06194 sip_pvt_lock(fup); 06195 ao2_lock(p); 06196 if (*inringing > 0) { 06197 if (ast_test_flag(&fup->flags[0], SIP_INC_RINGING)) { 06198 (*inringing)--; 06199 ast_clear_flag(&fup->flags[0], SIP_INC_RINGING); 06200 } 06201 } else { 06202 *inringing = 0; 06203 } 06204 ao2_unlock(p); 06205 sip_pvt_unlock(fup); 06206 } 06207 06208 /* Decrement onhold count if applicable */ 06209 sip_pvt_lock(fup); 06210 ao2_lock(p); 06211 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && sip_cfg.notifyhold) { 06212 ast_clear_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD); 06213 ao2_unlock(p); 06214 sip_pvt_unlock(fup); 06215 sip_peer_hold(fup, FALSE); 06216 } else { 06217 ao2_unlock(p); 06218 sip_pvt_unlock(fup); 06219 } 06220 if (sipdebug) 06221 ast_debug(2, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", "peer", name, *call_limit); 06222 break; 06223 06224 case INC_CALL_RINGING: 06225 case INC_CALL_LIMIT: 06226 /* If call limit is active and we have reached the limit, reject the call */ 06227 if (*call_limit > 0 ) { 06228 if (*inuse >= *call_limit) { 06229 ast_log(LOG_NOTICE, "Call %s %s '%s' rejected due to usage limit of %d\n", outgoing ? "to" : "from", "peer", name, *call_limit); 06230 unref_peer(p, "update_call_counter: unref peer p, call limit exceeded"); 06231 return -1; 06232 } 06233 } 06234 if (inringing && (event == INC_CALL_RINGING)) { 06235 sip_pvt_lock(fup); 06236 ao2_lock(p); 06237 if (!ast_test_flag(&fup->flags[0], SIP_INC_RINGING)) { 06238 (*inringing)++; 06239 ast_set_flag(&fup->flags[0], SIP_INC_RINGING); 06240 } 06241 ao2_unlock(p); 06242 sip_pvt_unlock(fup); 06243 } 06244 if (inuse) { 06245 sip_pvt_lock(fup); 06246 ao2_lock(p); 06247 if (!ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) { 06248 (*inuse)++; 06249 ast_set_flag(&fup->flags[0], SIP_INC_COUNT); 06250 } 06251 ao2_unlock(p); 06252 sip_pvt_unlock(fup); 06253 } 06254 if (sipdebug) { 06255 ast_debug(2, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", "peer", name, *inuse, *call_limit); 06256 } 06257 break; 06258 06259 case DEC_CALL_RINGING: 06260 if (inringing) { 06261 sip_pvt_lock(fup); 06262 ao2_lock(p); 06263 if (ast_test_flag(&fup->flags[0], SIP_INC_RINGING)) { 06264 if (*inringing > 0) { 06265 (*inringing)--; 06266 } 06267 ast_clear_flag(&fup->flags[0], SIP_INC_RINGING); 06268 } 06269 ao2_unlock(p); 06270 sip_pvt_unlock(fup); 06271 } 06272 break; 06273 06274 default: 06275 ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event); 06276 } 06277 06278 if (p) { 06279 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", p->name); 06280 unref_peer(p, "update_call_counter: unref_peer from call counter"); 06281 } 06282 return 0; 06283 }
| static void update_connectedline | ( | struct sip_pvt * | p, | |
| const void * | data, | |||
| size_t | datalen | |||
| ) | [static] |
Notify peer that the connected line has changed.
Definition at line 13480 of file chan_sip.c.
References add_header(), add_rpid(), add_sdp(), add_supported_header(), append_history, ast_clear_flag, ast_debug, ast_set_flag, ast_state2str(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, FALSE, initialize_initreq(), is_method_allowed(), reqprep(), respprep(), S_COR, send_request(), send_response(), and TRUE.
Referenced by sip_indicate().
13481 { 13482 13483 if (!ast_test_flag(&p->flags[0], SIP_SENDRPID)) { 13484 return; 13485 } 13486 if (!p->owner->connected.id.number.valid 13487 || ast_strlen_zero(p->owner->connected.id.number.str)) { 13488 return; 13489 } 13490 13491 append_history(p, "ConnectedLine", "%s party is now %s <%s>", 13492 ast_test_flag(&p->flags[0], SIP_OUTGOING) ? "Calling" : "Called", 13493 S_COR(p->owner->connected.id.name.valid, p->owner->connected.id.name.str, ""), 13494 S_COR(p->owner->connected.id.number.valid, p->owner->connected.id.number.str, "")); 13495 13496 if (p->owner->_state == AST_STATE_UP || ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 13497 struct sip_request req; 13498 13499 if (!p->pendinginvite && (p->invitestate == INV_CONFIRMED || p->invitestate == INV_TERMINATED)) { 13500 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 13501 13502 add_header(&req, "Allow", ALLOWED_METHODS); 13503 add_supported_header(p, &req); 13504 add_rpid(&req, p); 13505 add_sdp(&req, p, FALSE, TRUE, FALSE); 13506 13507 initialize_initreq(p, &req); 13508 p->lastinvite = p->ocseq; 13509 ast_set_flag(&p->flags[0], SIP_OUTGOING); 13510 p->invitestate = INV_CALLING; 13511 send_request(p, &req, XMIT_CRITICAL, p->ocseq); 13512 } else if ((is_method_allowed(&p->allowed_methods, SIP_UPDATE)) && (!ast_strlen_zero(p->okcontacturi))) { 13513 reqprep(&req, p, SIP_UPDATE, 0, 1); 13514 add_rpid(&req, p); 13515 add_header(&req, "X-Asterisk-rpid-update", "Yes"); 13516 send_request(p, &req, XMIT_CRITICAL, p->ocseq); 13517 } else { 13518 /* We cannot send the update yet, so we have to wait until we can */ 13519 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 13520 } 13521 } else { 13522 ast_set_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND); 13523 if (ast_test_flag(&p->flags[1], SIP_PAGE2_RPID_IMMEDIATE)) { 13524 struct sip_request resp; 13525 13526 if ((p->owner->_state == AST_STATE_RING) && !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT)) { 13527 ast_clear_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND); 13528 respprep(&resp, p, "180 Ringing", &p->initreq); 13529 add_rpid(&resp, p); 13530 send_response(p, &resp, XMIT_UNRELIABLE, 0); 13531 ast_set_flag(&p->flags[0], SIP_RINGING); 13532 } else if (p->owner->_state == AST_STATE_RINGING) { 13533 ast_clear_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND); 13534 respprep(&resp, p, "183 Session Progress", &p->initreq); 13535 add_rpid(&resp, p); 13536 send_response(p, &resp, XMIT_UNRELIABLE, 0); 13537 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 13538 } else { 13539 ast_debug(1, "Unable able to send update to '%s' in state '%s'\n", p->owner->name, ast_state2str(p->owner->_state)); 13540 } 13541 } 13542 } 13543 }
| static void update_peer | ( | struct sip_peer * | p, | |
| int | expire | |||
| ) | [static] |
Update peer data in database (if used).
Definition at line 4882 of file chan_sip.c.
References ast_test_flag, realtime_update_peer(), and sip_cfg.
Referenced by register_verify().
04883 { 04884 int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 04885 if (sip_cfg.peer_rtupdate && 04886 (p->is_realtime || rtcachefriends)) { 04887 realtime_update_peer(p->name, &p->addr, p->username, p->fullcontact, p->useragent, expire, p->deprecated_username, p->lastms); 04888 } 04889 }
| static void update_peer_lastmsgssent | ( | struct sip_peer * | peer, | |
| int | value, | |||
| int | locked | |||
| ) | [static] |
Definition at line 15260 of file chan_sip.c.
References ao2_lock, and ao2_unlock.
Referenced by register_verify(), and sip_send_mwi_to_peer().
15261 { 15262 if (!locked) { 15263 ao2_lock(peer); 15264 } 15265 peer->lastmsgssent = value; 15266 if (!locked) { 15267 ao2_unlock(peer); 15268 } 15269 }
| static void update_provisional_keepalive | ( | struct sip_pvt * | pvt, | |
| int | with_sdp | |||
| ) | [static] |
Definition at line 4339 of file chan_sip.c.
References ast_sched_add(), AST_SCHED_DEL_UNREF, send_provisional_keepalive(), and send_provisional_keepalive_with_sdp().
Referenced by transmit_provisional_response().
04340 { 04341 AST_SCHED_DEL_UNREF(sched, pvt->provisional_keepalive_sched_id, dialog_unref(pvt, "when you delete the provisional_keepalive_sched_id, you should dec the refcount for the stored dialog ptr")); 04342 04343 pvt->provisional_keepalive_sched_id = ast_sched_add(sched, PROVIS_KEEPALIVE_TIMEOUT, 04344 with_sdp ? send_provisional_keepalive_with_sdp : send_provisional_keepalive, dialog_ref(pvt, "Increment refcount to pass dialog pointer to sched callback")); 04345 }
| static void update_redirecting | ( | struct sip_pvt * | p, | |
| const void * | data, | |||
| size_t | datalen | |||
| ) | [static] |
Send a provisional response indicating that a call was redirected.
Definition at line 13466 of file chan_sip.c.
References add_diversion_header(), AST_STATE_UP, ast_test_flag, respprep(), and send_response().
Referenced by handle_request_invite(), handle_response(), handle_response_invite(), and sip_indicate().
13467 { 13468 struct sip_request resp; 13469 13470 if (p->owner->_state == AST_STATE_UP || ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 13471 return; 13472 } 13473 13474 respprep(&resp, p, "181 Call is being forwarded", &p->initreq); 13475 add_diversion_header(&resp, p); 13476 send_response(p, &resp, XMIT_UNRELIABLE, 0); 13477 }
struct _map_x_s allowoverlapstr[] [static] |
Definition at line 17595 of file chan_sip.c.
int apeerobjs = 0 [static] |
Autocreated peer objects
Definition at line 755 of file chan_sip.c.
char* app_dtmfmode = "SIPDtmfMode" [static] |
Definition at line 30278 of file chan_sip.c.
char* app_sipaddheader = "SIPAddHeader" [static] |
Definition at line 30279 of file chan_sip.c.
char* app_sipremoveheader = "SIPRemoveHeader" [static] |
Definition at line 30280 of file chan_sip.c.
struct sip_auth_container* authl = NULL [static] |
Authentication container for realm authentication.
Definition at line 1124 of file chan_sip.c.
int authlimit = DEFAULT_AUTHLIMIT [static] |
Definition at line 552 of file chan_sip.c.
int authtimeout = DEFAULT_AUTHTIMEOUT [static] |
Definition at line 553 of file chan_sip.c.
| struct ast_sockaddr bindaddr |
UDP: The address we bind to
Definition at line 1146 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), create_addr(), dialog_initialize_rtp(), get_address_family_filter(), initialize_udptl(), reload_config(), sip_show_settings(), and sipsock_read().
struct sip_peer* bogus_peer [static] |
A bogus peer, to be used when authentication should fail.
Definition at line 1103 of file chan_sip.c.
int can_parse_xml [static] |
We use libxml2 in order to parse XML that may appear in the body of a SIP message. Currently, the only usage is for parsing PIDF bodies of incoming PUBLISH requests in the call-completion event package. This variable is set at module load time and may be checked at runtime to determine if XML parsing support was found.
Definition at line 748 of file chan_sip.c.
struct epa_static_data cc_epa_static_data [static] |
Definition at line 887 of file chan_sip.c.
unsigned int chan_idx [static] |
used in naming sip channel
Definition at line 695 of file chan_sip.c.
struct ast_custom_function checksipdomain_function [static] |
{
.name = "CHECKSIPDOMAIN",
.read = func_check_sipdomain,
}
Definition at line 20107 of file chan_sip.c.
struct ast_cli_entry cli_sip[] [static] |
SIP Cli commands definition.
Definition at line 30855 of file chan_sip.c.
const char config[] = "sip.conf" [static] |
Main configuration file
Definition at line 567 of file chan_sip.c.
struct ast_sockaddr debugaddr [static] |
Definition at line 1190 of file chan_sip.c.
Referenced by sip_debug_test_addr(), sip_do_debug(), sip_do_debug_ip(), and sip_do_debug_peer().
char default_callerid[AST_MAX_EXTENSION] [static] |
Default caller ID for sip messages
Definition at line 668 of file chan_sip.c.
char default_engine[256] [static] |
Default RTP engine
Definition at line 679 of file chan_sip.c.
int default_expiry = DEFAULT_DEFAULT_EXPIRY [static] |
Definition at line 548 of file chan_sip.c.
Referenced by AST_TEST_DEFINE().
char default_fromdomain[AST_MAX_EXTENSION] [static] |
Default domain on outound messages
Definition at line 670 of file chan_sip.c.
int default_fromdomainport [static] |
Default domain port on outbound messages
Definition at line 671 of file chan_sip.c.
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled.
Definition at line 557 of file chan_sip.c.
char default_language[MAX_LANGUAGE] [static] |
Default language setting for new channels
Definition at line 667 of file chan_sip.c.
int default_maxcallbitrate [static] |
Maximum bitrate for call
Definition at line 680 of file chan_sip.c.
char default_mohinterpret[MAX_MUSICCLASS] [static] |
Global setting for moh class to use when put on hold
Definition at line 675 of file chan_sip.c.
char default_mohsuggest[MAX_MUSICCLASS] [static] |
Global setting for moh class to suggest when putting a bridged channel on hold
Definition at line 676 of file chan_sip.c.
char default_mwi_from[80] [static] |
Default caller ID for MWI updates
Definition at line 669 of file chan_sip.c.
char default_notifymime[AST_MAX_EXTENSION] [static] |
Default MIME media type for MWI notify messages
Definition at line 672 of file chan_sip.c.
char default_parkinglot[AST_MAX_CONTEXT] [static] |
Parkinglot
Definition at line 678 of file chan_sip.c.
struct ast_codec_pref default_prefs [static] |
Default codec prefs
Definition at line 681 of file chan_sip.c.
Referenced by reload_config(), set_peer_defaults(), sip_alloc(), sip_show_settings(), and temp_peer().
unsigned int default_primary_transport [static] |
Default primary Transport (enum sip_transport) for outbound connections to devices
Definition at line 683 of file chan_sip.c.
const int DEFAULT_PUBLISH_EXPIRES = 3600 [static] |
Definition at line 930 of file chan_sip.c.
int default_qualify [static] |
Default Qualify= setting
Definition at line 674 of file chan_sip.c.
struct ast_tls_config default_tls_cfg [static] |
Default TLS connection configuration.
Definition at line 2193 of file chan_sip.c.
unsigned int default_transports [static] |
Default Transports (enum sip_transport) that are acceptable
Definition at line 682 of file chan_sip.c.
char default_vmexten[AST_MAX_EXTENSION] [static] |
Default From Username on MWI updates
Definition at line 673 of file chan_sip.c.
struct ao2_container* dialogs [static] |
Here we implement the container for dialogs (sip_pvt), defining generic wrapper functions to ease the transition from the current implementation (a single linked list) to a different container. In addition to a reference to the container, we need functions to lock/unlock the container and individual items, and functions to add/remove references to the individual items.
Definition at line 1090 of file chan_sip.c.
| struct ao2_container* dialogs_to_destroy |
This container holds the dialogs that will be destroyed immediately.
Definition at line 1080 of file chan_sip.c.
struct _map_x_s dtmfstr[] [static] |
mapping between dtmf flags and strings
Definition at line 17560 of file chan_sip.c.
Referenced by conf_run(), and send_dtmf().
unsigned int dumphistory [static] |
Dump history to verbose before destroying SIP dialog
Definition at line 719 of file chan_sip.c.
int esc_etag_counter [static] |
Used to create new entity IDs by ESCs.
Definition at line 929 of file chan_sip.c.
const int ESC_MAX_BUCKETS = 37 [static] |
Definition at line 964 of file chan_sip.c.
struct event_state_compositor event_state_compositors[] [static] |
The Event State Compositors.
An Event State Compositor is an entity which accepts PUBLISH requests and acts appropriately based on these requests.
The actual event_state_compositor structure is simply an ao2_container of sip_esc_entrys. When an incoming PUBLISH is received, we can match the appropriate sip_esc_entry using the entity ID of the incoming PUBLISH.
Referenced by destroy_escs(), get_esc(), and initialize_escs().
struct ast_sockaddr externaddr [static] |
our external IP address/port for SIP sessions. externaddr.sin_addr is only set when we know we might be behind a NAT, and this is done using a variety of (mutually exclusive) ways from the config file:
+ with "externaddr = host[:port]" we specify the address/port explicitly. The address is looked up only once when (re)loading the config file;
+ with "externhost = host[:port]" we do a similar thing, but the hostname is stored in externhost, and the hostname->IP mapping is refreshed every 'externrefresh' seconds;
Other variables (externhost, externexpire, externrefresh) are used to support the above functions. External IP address if we are behind NAT
Definition at line 1171 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), reload_config(), and sip_show_settings().
time_t externexpire [static] |
Expiration counter for re-resolving external host name in dynamic DNS
Definition at line 1175 of file chan_sip.c.
char externhost[MAXHOSTNAMELEN] [static] |
External host name
Definition at line 1174 of file chan_sip.c.
int externrefresh = 10 [static] |
Refresh timer for DNS-based external address (dyndns)
Definition at line 1176 of file chan_sip.c.
uint16_t externtcpport [static] |
external tcp port
Definition at line 1177 of file chan_sip.c.
uint16_t externtlsport [static] |
external tls port
Definition at line 1178 of file chan_sip.c.
struct _map_x_s faxecmodes[] [static] |
Definition at line 18048 of file chan_sip.c.
int global_authfailureevents [static] |
Whether we send authentication failure manager events or not. Default no.
Definition at line 723 of file chan_sip.c.
unsigned int global_autoframing [static] |
Turn autoframing on or off.
Definition at line 727 of file chan_sip.c.
int global_callcounter [static] |
Enable call counters for all devices. This is currently enabled by setting the peer call-limit to INT_MAX. When we remove the call-limit from the code, we can make it with just a boolean flag in the device structure
Definition at line 707 of file chan_sip.c.
unsigned int global_cos_audio [static] |
802.1p class of service for audio RTP packets
Definition at line 715 of file chan_sip.c.
unsigned int global_cos_sip [static] |
802.1p class of service for SIP packets
Definition at line 714 of file chan_sip.c.
unsigned int global_cos_text [static] |
802.1p class of service for text RTP packets
Definition at line 717 of file chan_sip.c.
unsigned int global_cos_video [static] |
802.1p class of service for video RTP packets
Definition at line 716 of file chan_sip.c.
int global_dynamic_exclude_static = 0 [static] |
Exclude static peers from contact registrations
Definition at line 739 of file chan_sip.c.
struct ast_flags global_flags[3] = {{0}} [static] |
global SIP_ flags
Definition at line 759 of file chan_sip.c.
struct ast_jb_conf global_jbconf [static] |
Global jitterbuffer configuration
Definition at line 565 of file chan_sip.c.
Referenced by reload_config(), sip_get_rtp_peer(), sip_new(), and sip_show_settings().
int global_match_auth_username [static] |
Match auth username if available instead of From: Default off.
Definition at line 696 of file chan_sip.c.
int global_max_se [static] |
Highest threshold for session refresh interval
Definition at line 735 of file chan_sip.c.
int global_min_se [static] |
Lowest threshold for session refresh interval
Definition at line 734 of file chan_sip.c.
int global_prematuremediafilter [static] |
Enable/disable premature frames in a call (causing 183 early media)
Definition at line 699 of file chan_sip.c.
int global_qualify_gap [static] |
Time between our group of peer pokes
Definition at line 729 of file chan_sip.c.
int global_qualify_peers [static] |
Number of peers to poke at a given time
Definition at line 730 of file chan_sip.c.
int global_qualifyfreq [static] |
Qualify frequency
Definition at line 728 of file chan_sip.c.
int global_reg_retry_403 [static] |
Treat 403 responses to registrations as 401 responses
Definition at line 705 of file chan_sip.c.
int global_reg_timeout [static] |
Global time between attempts for outbound registrations
Definition at line 703 of file chan_sip.c.
int global_regattempts_max [static] |
Registration attempts before giving up
Definition at line 704 of file chan_sip.c.
int global_relaxdtmf [static] |
Relax DTMF
Definition at line 698 of file chan_sip.c.
int global_rtpholdtimeout [static] |
Time out call if no RTP during hold
Definition at line 701 of file chan_sip.c.
int global_rtpkeepalive [static] |
Send RTP keepalives
Definition at line 702 of file chan_sip.c.
int global_rtptimeout [static] |
Time out call if no RTP
Definition at line 700 of file chan_sip.c.
char global_sdpowner[AST_MAX_EXTENSION] [static] |
SDP owner name for the SIP channel
Definition at line 722 of file chan_sip.c.
char global_sdpsession[AST_MAX_EXTENSION] [static] |
SDP session name for the SIP channel
Definition at line 721 of file chan_sip.c.
int global_shrinkcallerid [static] |
enable or disable shrinking of caller id
Definition at line 706 of file chan_sip.c.
enum st_mode global_st_mode [static] |
Mode of operation for Session-Timers
Definition at line 732 of file chan_sip.c.
enum st_refresher_param global_st_refresher [static] |
Session-Timer refresher
Definition at line 733 of file chan_sip.c.
int global_store_sip_cause [static] |
Whether the MASTER_CHANNEL(HASH(SIP_CAUSE,[chan_name])) var should be set
Definition at line 737 of file chan_sip.c.
int global_t1 [static] |
T1 time
Definition at line 724 of file chan_sip.c.
int global_t1min [static] |
T1 roundtrip time minimum
Definition at line 725 of file chan_sip.c.
unsigned int global_t38_maxdatagram [static] |
global T.38 FaxMaxDatagram override
Definition at line 760 of file chan_sip.c.
int global_timer_b [static] |
Timer B - RFC 3261 Section 17.1.1.2
Definition at line 726 of file chan_sip.c.
unsigned int global_tos_audio [static] |
IP type of service for audio RTP packets
Definition at line 711 of file chan_sip.c.
unsigned int global_tos_sip [static] |
IP type of service for SIP packets
Definition at line 710 of file chan_sip.c.
unsigned int global_tos_text [static] |
IP type of service for text RTP packets
Definition at line 713 of file chan_sip.c.
unsigned int global_tos_video [static] |
IP type of service for video RTP packets
Definition at line 712 of file chan_sip.c.
char global_useragent[AST_MAX_EXTENSION] [static] |
Useragent for the SIP channel
Definition at line 720 of file chan_sip.c.
const int HASH_DIALOG_SIZE = 563 [static] |
Definition at line 817 of file chan_sip.c.
const int HASH_PEER_SIZE = 563 [static] |
Size of peer hash table, prime number preferred!
Definition at line 816 of file chan_sip.c.
struct _map_x_s insecurestr[] [static] |
Definition at line 17581 of file chan_sip.c.
struct ast_sockaddr internip [static] |
our (internal) default address/port to put in SIP/SDP messages internip is initialized picking a suitable address from one of the interfaces, and the same port number we bind to. It is used as the default address/port in SIP messages, and as the default address (but not port) in SDP messages.
Definition at line 1154 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), reload_config(), sip_alloc(), transmit_register(), and transmit_response_using_temp().
struct invstate2stringtable invitestate2string[] [static] |
Readable descriptions of device states.
Referenced by show_chanstats_cb().
struct io_context* io [static] |
The IO context
Definition at line 783 of file chan_sip.c.
List of local networks We store "localnet" addresses from the config file into an access list, marked as 'DENY', so the call to ast_apply_ha() will return AST_SENSE_DENY for 'local' addresses, and AST_SENSE_ALLOW for 'non local' (i.e. presumably public) addresses.
List of local networks, on the same side of NAT as this Asterisk
Definition at line 1186 of file chan_sip.c.
int max_expiry = DEFAULT_MAX_EXPIRY [static] |
Maximum accepted registration time
Definition at line 547 of file chan_sip.c.
struct ast_sockaddr media_address [static] |
External RTP IP address if we are behind NAT
Definition at line 1172 of file chan_sip.c.
Referenced by get_our_media_address(), and reload_config().
int min_expiry = DEFAULT_MIN_EXPIRY [static] |
Minimum accepted registration time
Definition at line 546 of file chan_sip.c.
pthread_t monitor_thread = AST_PTHREADT_NULL [static] |
This is the thread for the monitor which checks for input on the channels which are not currently in use.
Definition at line 777 of file chan_sip.c.
int mwi_expiry = DEFAULT_MWI_EXPIRY [static] |
Definition at line 549 of file chan_sip.c.
int network_change_event_sched_id = -1 [static] |
Definition at line 763 of file chan_sip.c.
struct ast_event_sub* network_change_event_subscription [static] |
subscription id for network change events
Definition at line 762 of file chan_sip.c.
const char notify_config[] = "sip_notify.conf" [static] |
Configuration file for sending Notify with CLI commands to reconfigure or reboot phones
Definition at line 568 of file chan_sip.c.
struct ast_config* notify_types = NULL [static] |
The list of manual NOTIFY types we know how to send
Definition at line 1192 of file chan_sip.c.
int ourport_tcp [static] |
The port used for TCP connections
Definition at line 1188 of file chan_sip.c.
int ourport_tls [static] |
The port used for TCP/TLS connections
Definition at line 1189 of file chan_sip.c.
struct ao2_container* peers [static] |
The peer list: Users, Peers and Friends.
Definition at line 1099 of file chan_sip.c.
struct ao2_container* peers_by_ip [static] |
Definition at line 1100 of file chan_sip.c.
struct ast_data_handler peers_data_provider [static] |
{
.version = AST_DATA_HANDLER_VERSION,
.get = peers_data_provider_get
}
Definition at line 31804 of file chan_sip.c.
unsigned int recordhistory [static] |
Record SIP history. Off by default
Definition at line 718 of file chan_sip.c.
struct _map_x_s referstatusstrings[] [static] |
Definition at line 798 of file chan_sip.c.
struct ast_register_list regl [static] |
The register list: Other SIP proxies we register with and receive calls from.
Referenced by cleanup_all_regs(), load_module(), manager_show_registry(), reload_config(), sip_register(), sip_send_all_registers(), sip_show_objects(), sip_show_registry(), and unload_module().
int regobjs = 0 [static] |
Registry objects
Definition at line 756 of file chan_sip.c.
struct _map_x_s regstatestrings[] [static] |
Definition at line 13545 of file chan_sip.c.
int rpeerobjs = 0 [static] |
Realtime peers
Definition at line 754 of file chan_sip.c.
| struct sched_context* sched |
The scheduling context
Definition at line 782 of file chan_sip.c.
Definition at line 821 of file chan_sip.c.
Referenced by cc_generic_monitor_request_cc(), create_addr(), launch_ha_netscript(), service_string_to_service_type(), and sip_cc_monitor_request_cc().
| const char* service_string |
Definition at line 822 of file chan_sip.c.
struct ast_cc_agent_callbacks sip_cc_agent_callbacks [static] |
Definition at line 1642 of file chan_sip.c.
struct ast_cc_monitor_callbacks sip_cc_monitor_callbacks [static] |
Definition at line 1909 of file chan_sip.c.
struct { ... } sip_cc_notify_state_map[] [static] |
Referenced by transmit_cc_notify().
struct { ... } sip_cc_service_map[] [static] |
Referenced by service_string_to_service_type().
struct sip_settings sip_cfg [static] |
SIP configuration data.
Definition at line 686 of file chan_sip.c.
Referenced by __get_header(), __sip_subscribe_mwi_do(), _sip_show_peer(), add_header(), ast_sip_ouraddrfor(), build_peer(), change_hold_state(), check_peer_ok(), check_user_full(), create_addr(), destroy_association(), do_magic_pickup(), find_call(), find_calling_channel(), get_also_info(), get_destination(), get_realm(), get_refer_info(), get_sip_pvt_byid_locked(), handle_incoming(), handle_request_bye(), handle_request_do(), handle_request_invite(), handle_request_options(), handle_request_refer(), handle_request_subscribe(), handle_response_invite(), handle_response_peerpoke(), initreqprep(), obproxy_get(), parse_register_contact(), parse_uri_legacy_check(), proxy_update(), read_raw_content_length(), realtime_peer(), realtime_update_peer(), ref_proxy(), reg_source_db(), register_peer_exten(), register_verify(), reload_config(), set_peer_defaults(), sip_alloc(), sip_new(), sip_poke_noanswer(), sip_request_call(), sip_set_rtp_peer(), sip_show_settings(), state_notify_build_xml(), transmit_register(), unload_module(), update_call_counter(), and update_peer().
struct ast_data_entry sip_data_providers[] [static] |
{
AST_DATA_ENTRY("asterisk/channel/sip/peers", &peers_data_provider),
}
Definition at line 31809 of file chan_sip.c.
struct ast_custom_function sip_header_function [static] |
{
.name = "SIP_HEADER",
.read = func_header_read,
}
Definition at line 20088 of file chan_sip.c.
struct cfsip_methods sip_methods[] [static] |
The core structure to setup dialogs. We parse incoming messages by using structure and then route the messages according to the type.
Referenced by __sip_autodestruct(), __sip_destroy(), __sip_pretend_ack(), __sip_semi_ack(), build_reply_digest(), check_auth(), dialog_initialize_rtp(), dialog_needdestroy(), do_proxy_auth(), find_call(), find_sip_method(), get_destination(), handle_incoming(), handle_request_bye(), handle_request_invite(), handle_request_register(), handle_request_subscribe(), handle_response(), handle_response_info(), handle_response_message(), init_req(), initialize_initreq(), initreqprep(), method_match(), reqprep(), retrans_pkt(), send_request(), send_response(), sip_alloc(), sip_scheddestroy(), and transmit_register().
| struct ao2_container* sip_monitor_instances |
Definition at line 1836 of file chan_sip.c.
struct sip_reasons sip_reason_table[] [static] |
Diversion header reasons.
The core defines a bunch of constants used to define redirecting reasons. This provides a translation table between those and the strings which may be present in a SIP Diversion header
Referenced by sip_reason_code_to_str(), and sip_reason_str_to_code().
int sip_reloading = FALSE [static] |
Flag for avoiding multiple reloads at the same time
Definition at line 779 of file chan_sip.c.
enum channelreloadreason sip_reloadreason [static] |
Reason for last reload/load of configuration
Definition at line 780 of file chan_sip.c.
struct ast_rtp_glue sip_rtp_glue [static] |
Definition at line 30269 of file chan_sip.c.
struct ast_tcptls_session_args sip_tcp_desc [static] |
The TCP server definition.
Definition at line 2196 of file chan_sip.c.
| struct ast_channel_tech sip_tech |
Definition of this channel for PBX channel registration.
Definition at line 1596 of file chan_sip.c.
| struct ast_channel_tech sip_tech_info |
This version of the sip channel tech has no send_digit_begin callback so that the core knows that the channel does not want DTMF BEGIN frames. The struct is initialized just before registering the channel driver, and is for use with channels using SIP INFO DTMF.
Definition at line 1631 of file chan_sip.c.
Referenced by load_module(), sip_get_rtp_peer(), sip_get_trtp_peer(), sip_get_udptl_peer(), sip_get_vrtp_peer(), and sip_new().
struct ast_tls_config sip_tls_cfg [static] |
Working TLS connection configuration.
Definition at line 2190 of file chan_sip.c.
struct ast_tcptls_session_args sip_tls_desc [static] |
The TCP/TLS server definition.
Definition at line 2207 of file chan_sip.c.
struct ast_udptl_protocol sip_udptl [static] |
{
.type = "SIP",
.get_udptl_info = sip_get_udptl_peer,
.set_udptl_peer = sip_set_udptl_peer,
}
Interface structure with callbacks used to connect to UDPTL module.
Definition at line 3169 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 20277 of file chan_sip.c.
enum sip_debug_e sipdebug [static] |
Definition at line 790 of file chan_sip.c.
int sipdebug_text [static] |
extra debugging for 'text' related events. At the moment this is set together with sip_debug_console.
Definition at line 796 of file chan_sip.c.
struct ast_custom_function sippeer_function [static] |
{
.name = "SIPPEER",
.read = function_sippeer,
}
Structure to declare a dialplan function: SIPPEER.
Definition at line 20206 of file chan_sip.c.
int sipsock = -1 [static] |
Main socket for UDP SIP communication.
sipsock is shared between the SIP manager thread (which handles reload requests), the udp io handler (sipsock_read()) and the user routines that issue udp writes (using __sip_xmit()). The socket is -1 only when opening fails (this is a permanent condition), or when we are handling a reload() that changes its address (this is a transient situation during which we might have a harmless race, see below). Because the conditions for the race to be possible are extremely rare, we don't want to pay the cost of locking on every I/O. Rather, we remember that when the race may occur, communication is bound to fail anyways, so we just live with this event and let the protocol handle this above us.
Definition at line 1144 of file chan_sip.c.
int* sipsock_read_id [static] |
ID of IO entry for sipsock FD
Definition at line 784 of file chan_sip.c.
int speerobjs = 0 [static] |
Static peers
Definition at line 753 of file chan_sip.c.
| enum sip_cc_notify_state state |
Definition at line 842 of file chan_sip.c.
| const char* state_string |
Definition at line 843 of file chan_sip.c.
Referenced by transmit_cc_notify().
struct _map_x_s stmodes[] [static] |
Report Peer status in character string.
Definition at line 17005 of file chan_sip.c.
struct _map_x_s strefresher_params[] [static] |
Definition at line 17023 of file chan_sip.c.
struct _map_x_s strefreshers[] [static] |
Definition at line 17030 of file chan_sip.c.
struct ast_subscription_mwi_list submwil [static] |
The MWI subscription list.
Referenced by load_module(), sip_send_all_mwi_subscriptions(), sip_show_mwi(), sip_subscribe_mwi(), and unload_module().
struct cfsubscription_types subscription_types[] [static] |
Subscription types that we support. We support
Referenced by find_subscription_type(), and subscription_type2str().
struct ao2_container* threadt [static] |
The table of TCP threads.
Definition at line 1096 of file chan_sip.c.
struct _map_x_s trust_id_outboundstr[] [static] |
Definition at line 17608 of file chan_sip.c.
int unauth_sessions = 0 [static] |
Definition at line 551 of file chan_sip.c.
char used_context[AST_MAX_CONTEXT] [static] |
name of automatically created context for unloading
Definition at line 765 of file chan_sip.c.
1.6.1