Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Enumerations | Functions | Variables
chan_sip.c File Reference

Implementation of Session Initiation Protocol. More...

#include "asterisk.h"
#include <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/pickup.h"
#include "asterisk/parking.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/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/aoc.h"
#include "asterisk/message.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 "asterisk/sdp_srtp.h"
#include "asterisk/ccss.h"
#include "asterisk/xml.h"
#include "sip/include/dialog.h"
#include "sip/include/dialplan_functions.h"
#include "sip/include/security_events.h"
#include "sip/include/route.h"
#include "asterisk/sip_api.h"
#include "asterisk/mwi.h"
#include "asterisk/bridge.h"
#include "asterisk/stasis.h"
#include "asterisk/stasis_endpoints.h"
#include "asterisk/stasis_system.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/features_config.h"
#include "asterisk/http_websocket.h"
#include "asterisk/format_cache.h"
#include "asterisk/linkedlists.h"

Go to the source code of this file.

Data Structures

struct  blind_transfer_cb_data
 
struct  cfalias
 Structure for conversion between compressed SIP and "normal" SIP headers. 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. More...
 
struct  domain_list
 
struct  epa_static_data_list
 
struct  event_state_compositor
 The Event State Compositors. More...
 
struct  invstate2stringtable
 Readable descriptions of device states. More...
 
struct  match_req_args
 
struct  mwi_subscription_data
 
struct  reregister_data
 
struct  show_peers_context
 Used in the sip_show_peers functions to pass parameters. More...
 
struct  sip_history_head
 
struct  sip_reasons
 Diversion header reasons. More...
 
struct  sip_scheddestroy_data
 
struct  state_notify_data
 

Macros

#define append_history(p, event, fmt, args...)   append_history_full(p, "%-15s " fmt, event, ## args)
 Append to SIP dialog history. More...
 
#define BOGUS_PEER_MD5SECRET   "intentionally_invalid_md5_string"
 We can recognize the bogus peer by this invalid MD5 hash. More...
 
#define check_request_transport(peer, tmpl)
 generic function for determining if a correct transport is being used to contact a peer More...
 
#define CHECK_RESULTS(in, expected_res, expected_start, expected_len)
 
#define CONTAINER_UNLINK(container, obj, tag)
 Unlink the given object from the container and return TRUE if it was in the container. More...
 
#define find_call(req, addr, intended_method)   __find_call(req, addr, intended_method, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
#define FORMAT   "%-25.25s %-15.15s %-15.15s \n"
 
#define FORMAT   "%-47.47s %-9.9s %-6.6s\n"
 
#define FORMAT   "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n"
 
#define FORMAT   "%-40.40s %-20.20s %-16.16s\n"
 
#define FORMAT   "%-39.39s %-6.6s %-12.12s %8d %-20.20s %-25.25s\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   "%-30.30s %-12.12s %-10.10s %-10.10s\n"
 
#define FORMAT   "%-15.15s %-15.15s %-15.15s %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s %-10.10s\n"
 
#define FORMAT2   "%-25.25s %-15.15s %-15.15s \n"
 
#define FORMAT2   "%-47.47s %9.9s %6.6s\n"
 
#define FORMAT2   "%-39.39s %-6.6s %-12.12s %8.8s %-20.20s %-25.25s\n"
 
#define FORMAT2   "%-15.15s %-11.11s %-8.8s %-10.10s %-10.10s ( %%) %-6.6s %-10.10s %-10.10s ( %%) %-6.6s\n"
 
#define FORMAT2   "%-15.15s %-15.15s %-15.15s %-15.15s %-7.7s %-15.15s %-10.10s %-10.10s\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 peer_in_destruction(peer)   (ao2_ref(peer, 0) == 0)
 
#define PEERS_FORMAT2   "%-25.25s %-39.39s %-3.3s %-10.10s %-10.10s %-3.3s %-8s %-11s %-32.32s %s\n"
 
#define REMOVE_MAILBOX_WITH_LOCKED_PEER(__peer)
 
#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 SIP_TRANSPORT_STR_BUFSIZE   128
 Size of the SIP transport buffer. More...
 
#define SIPHEADER   256
 
#define UNLINK(element, head, prev)
 

Enumerations

enum  match_req_res { SIP_REQ_MATCH, SIP_REQ_NOT_MATCH, SIP_REQ_LOOP_DETECTED, SIP_REQ_FORKED }
 
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 }
 
enum  sip_media_fds {
  SIP_AUDIO_RTP_FD, SIP_AUDIO_RTCP_FD, SIP_VIDEO_RTP_FD, SIP_VIDEO_RTCP_FD,
  SIP_TEXT_RTP_FD, SIP_UDPTL_FD
}
 

Functions

static int __cleanup_registration (const void *data)
 
static int __dialog_unlink_sched_items (const void *data)
 
static struct sip_pvt__find_call (struct sip_request *req, struct ast_sockaddr *addr, const int intended_method, const char *file, int line, const char *func)
 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 More...
 
static const char * __get_header (const struct sip_request *req, const char *name, int *start)
 
static void __init_sip_content_buf (void)
 
static void __init_sip_transport_str_buf (void)
 A per-thread buffer for transport to string conversion. More...
 
static void __init_ts_temp_pvt (void)
 A per-thread temporary pvt structure. More...
 
static void __reg_module (void)
 
static int __sched_check_pendings (const void *data)
 
static int __set_address_from_contact (const char *fullcontact, struct ast_sockaddr *addr, int tcp)
 
static int __shutdown_mwi_subscription (const void *data)
 
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. More...
 
struct sip_pvt__sip_alloc (ast_string_field callid, struct ast_sockaddr *addr, int useglobal_nat, const int intended_method, struct sip_request *req, ast_callid logger_callid, const char *file, int line, const char *func)
 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. More...
 
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(). More...
 
static int __sip_cancel_destroy (const void *data)
 
static int __sip_do_register (struct sip_registry *r)
 Register with SIP proxy. More...
 
void __sip_pretend_ack (struct sip_pvt *p)
 Pretend to ack all packets called with p locked. More...
 
static int __sip_reliable_xmit (struct sip_pvt *p, uint32_t seqno, int resp, struct ast_str *data, int fatal, int sipmethod)
 
static int __sip_scheddestroy (const void *data)
 
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) More...
 
static int __sip_subscribe_mwi_do (struct sip_subscription_mwi *mwi)
 Actually setup an MWI subscription or resubscribe. More...
 
static int __sip_xmit (struct sip_pvt *p, struct ast_str *data)
 
static int __start_mwi_subscription (const void *data)
 
static int __start_register_timeout (const void *data)
 
static int __start_reregister_timeout (const void *data)
 
static int __start_session_timer (const void *data)
 
static int __start_t38_abort_timer (const void *data)
 
static int __stop_provisional_keepalive (const void *data)
 
static int __stop_register_timeout (const void *data)
 
static int __stop_reinvite_retry (const void *data)
 
static int __stop_reinviteid (const void *data)
 
static int __stop_retrans_pkt (const void *data)
 
static int __stop_session_timer (const void *data)
 
static int __stop_t38_abort_timer (const void *data)
 
static int __transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable)
 Base transmit response function. More...
 
static void __unreg_module (void)
 
static int __update_provisional_keepalive (const void *data)
 
static int __update_provisional_keepalive_full (struct sip_pvt *pvt, int with_sdp)
 
static int __update_provisional_keepalive_with_sdp (const void *data)
 
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. More...
 
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) More...
 
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. More...
 
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. More...
 
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. More...
 
static void acl_change_event_stasis_unsubscribe (void)
 
static void acl_change_stasis_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void acl_change_stasis_subscribe (void)
 
static void add_blank (struct sip_request *req)
 add a blank line if no body More...
 
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, struct ast_format *format, struct ast_str **m_buf, struct ast_str **a_buf, int debug, int *min_packet_size, int *max_packet_size)
 Add codec offer to SDP offer/answer body in INVITE or 200 OK. More...
 
static int add_content (struct sip_request *req, const char *line)
 Add content (not header) to SIP message. More...
 
static void add_date (struct sip_request *req)
 Add date header to SIP message. More...
 
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. More...
 
static void add_diversion (struct sip_request *req, struct sip_pvt *pvt)
 Add "Diversion" header to outgoing message. More...
 
static void add_dtls_to_sdp (struct ast_rtp_instance *instance, struct ast_str **a_buf)
 Add DTLS attributes to SDP. More...
 
static void add_expires (struct sip_request *req, int expires)
 Add Expires header to SIP message. More...
 
static int add_header (struct sip_request *req, const char *var, const char *value)
 Add header to SIP message. More...
 
static void add_ice_to_sdp (struct ast_rtp_instance *instance, struct ast_str **a_buf)
 Add ICE attributes to SDP. More...
 
static int add_max_forwards (struct sip_pvt *dialog, struct sip_request *req)
 Add 'Max-Forwards' header to SIP message. More...
 
static void add_msg_header (struct sip_pvt *pvt, const char *hdr_name, const char *hdr_value)
 
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. More...
 
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, int skip)
 Add route header into request per learned route. More...
 
static int add_rpid (struct sip_request *req, struct sip_pvt *p)
 Add Remote-Party-ID header to SIP message. More...
 
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. More...
 
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. More...
 
static int add_supported (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. More...
 
static void add_tcodec_to_sdp (const struct sip_pvt *p, struct ast_format *format, 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. More...
 
static int add_text (struct sip_request *req, struct sip_pvt *p)
 Add text body to SIP message. More...
 
static struct ast_variableadd_var (const char *buf, struct ast_variable *list)
 implement the setvar config line More...
 
static void add_vcodec_to_sdp (const struct sip_pvt *p, struct ast_format *format, 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. More...
 
static int add_vidupdate (struct sip_request *req)
 add XML encoded media control with update More...
 
static int allow_notify_user_presence (struct sip_pvt *p)
 
static const char * allowoverlap2str (int mode)
 Convert AllowOverlap setting to printable string. More...
 
static AO2_GLOBAL_OBJ_STATIC (g_bogus_peer)
 A bogus peer, to be used when authentication should fail. More...
 
static void append_history_full (struct sip_pvt *p, const char *fmt,...)
 Append to SIP dialog history with arg list. More...
 
static void append_history_va (struct sip_pvt *p, const char *fmt, va_list ap)
 Append to SIP dialog history with arg list. More...
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
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? More...
 
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. More...
 
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. More...
 
 AST_TEST_DEFINE (test_sip_mwi_subscribe_parse)
 
 AST_TEST_DEFINE (test_tcp_message_fragmentation)
 
 AST_TEST_DEFINE (get_in_brackets_const_test)
 
static int auto_congest (const void *arg)
 Scheduled congestion on a call. Only called by the scheduler, must return the reference when done. More...
 
static const char * autocreatepeer2str (enum autocreatepeer_mode r)
 
static void blind_transfer_cb (struct ast_channel *chan, struct transfer_channel_data *user_data_wrapper, enum ast_transfer_type transfer_type)
 
static int block_msg_header (const char *header_name)
 
static void build_callid_pvt (struct sip_pvt *pvt)
 Build SIP Call-ID value for a non-REGISTER transaction. More...
 
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. More...
 
static void build_contact (struct sip_pvt *p, struct sip_request *req, int incoming)
 Build contact header. More...
 
static void build_localtag_registry (struct sip_registry *reg)
 Build SIP From tag value for REGISTER. More...
 
static void build_nonce (struct sip_pvt *p, int forceupdate)
 builds the sip_pvt's nonce field which is used for the authentication 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. More...
 
static int build_path (struct sip_pvt *p, struct sip_peer *peer, struct sip_request *req, const char *pathbuf)
 Build route list from Path header RFC 3327 requires that the Path header contains SIP URIs with lr paramter. Thus, we do not care about strict routing SIP routers. More...
 
static struct sip_peerbuild_peer (const char *name, struct ast_variable *v_head, struct ast_variable *alt, int realtime, int devstate_only)
 Build peer from configuration (file or realtime static/dynamic) More...
 
static int build_reply_digest (struct sip_pvt *p, int method, char *digest, int digest_len)
 Build reply digest. More...
 
static void build_route (struct sip_pvt *p, struct sip_request *req, int backwards, int resp)
 Build route list from Record-Route header. More...
 
static void build_via (struct sip_pvt *p)
 Build a Via header for a request. More...
 
static int cb_extensionstate (const char *context, const char *exten, struct ast_state_cb_info *info, void *data)
 Callback for the devicestate notification (SUBSCRIBE) support subsystem. More...
 
static void cb_extensionstate_destroy (int id, void *data)
 
static void cc_epa_destructor (void *data)
 
static int cc_esc_publish_handler (struct sip_pvt *pvt, struct sip_request *req, struct event_state_compositor *esc, struct sip_esc_entry *esc_entry)
 
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. More...
 
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 More...
 
static void change_t38_state (struct sip_pvt *p, int state)
 Change the T38 state on a SIP dialog. More...
 
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)
 Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set) More...
 
static void check_for_nat (const struct ast_sockaddr *addr, struct sip_pvt *p)
 Check and see if the requesting UA is likely to be behind a NAT. More...
 
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. More...
 
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. More...
 
static void check_pendings (struct sip_pvt *p)
 Check pending actions on SIP call. More...
 
static int 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 More...
 
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 More...
 
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, that needs to be unreferenced. More...
 
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. More...
 
static void check_via (struct sip_pvt *p, const struct sip_request *req)
 check Via: header for hostname, port and rport request/answer More...
 
static void cleanup_all_regs (void)
 
static int cleanup_registration (void *obj, void *arg, int flags)
 
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. More...
 
static void clear_peer_mailboxes (struct sip_peer *peer)
 
static void clear_sip_domains (void)
 Clear our domain list (at reload) More...
 
static char * complete_sip_notify (const char *line, const char *word, int pos, int state)
 Support routine for 'sip notify' CLI. More...
 
static char * complete_sip_peer (const char *word, int state, int flags2)
 Do completion on peer name. More...
 
static char * complete_sip_registered_peer (const char *word, int state, int flags2)
 Do completion on registered peer name. More...
 
static char * complete_sip_show_history (const char *line, const char *word, int pos, int state)
 Support routine for 'sip show history' CLI. More...
 
static char * complete_sip_show_peer (const char *line, const char *word, int pos, int state)
 Support routine for 'sip show peer' CLI. More...
 
static char * complete_sip_show_user (const char *line, const char *word, int pos, int state)
 Support routine for 'sip show user' CLI. More...
 
static char * complete_sip_unregister (const char *line, const char *word, int pos, int state)
 Support routine for 'sip unregister' CLI. More...
 
static char * complete_sip_user (const char *word, int state)
 Do completion on user name. More...
 
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. More...
 
static void configure_rtcp (struct sip_pvt *p, struct ast_rtp_instance *instance, int which, int remote_rtcp_mux)
 
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. More...
 
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. More...
 
static void copy_request (struct sip_request *dst, const struct sip_request *src)
 copy SIP request (mostly used to save request for responses) More...
 
static void copy_socket_data (struct sip_socket *to_sock, const struct sip_socket *from_sock)
 
static struct ast_variablecopy_vars (struct ast_variable *src)
 duplicate a list of channel variables, More...
 
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. More...
 
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 More...
 
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. More...
 
static struct sip_epa_entrycreate_epa_entry (const char *const event_package, const char *const destination)
 
static struct sip_esc_entrycreate_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 char * crypto_get_attrib (struct ast_sdp_srtp *srtp, int dtls_enabled, int default_taglen_32)
 
static int default_sip_port (enum ast_transport type)
 The default sip port for the given transport. More...
 
static void deinit_req (struct sip_request *req)
 Deinitialize SIP response/request. More...
 
static void deprecation_notice (void)
 
static void destroy_association (struct sip_peer *peer)
 Remove registration data from realtime database or AST/DB when registration expires. More...
 
static void destroy_escs (void)
 
static void destroy_mailbox (struct sip_mailbox *mailbox)
 
static void destroy_msg_headers (struct sip_pvt *pvt)
 
static void destroy_realm_authentication (void *obj)
 
static int determine_firstline_parts (struct sip_request *req)
 Parse first line of incoming SIP request. More...
 
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_checkrtp_cb (void *dialogobj, void *arg, int flags)
 Check RTP Timeout on dialogs. More...
 
static void dialog_clean_rtp (struct sip_pvt *p)
 
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_dtls_srtp (const struct sip_pvt *dialog, struct ast_rtp_instance *rtp, struct ast_sdp_srtp **srtp)
 Initialize DTLS-SRTP support on an RTP instance. More...
 
static int dialog_initialize_rtp (struct sip_pvt *dialog)
 Initialize RTP portion of a dialog. More...
 
static int dialog_needdestroy (void *dialogobj, void *arg, int flags)
 Match dialogs that need to be destroyed. More...
 
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. More...
 
static void disable_dsp_detect (struct sip_pvt *p)
 
static void display_nat_warning (const char *cat, int reason, struct ast_flags *flags)
 
static void do_cancel_destroy (struct sip_pvt *pvt)
 
static void do_dialog_unlink_sched_items (struct sip_pvt *dialog)
 
static int do_magic_pickup (struct ast_channel *channel, const char *extension, const char *context)
 
static int do_message_auth (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno)
 
static void * do_monitor (void *data)
 The SIP monitoring thread. More...
 
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. More...
 
static int do_register_auth (struct sip_pvt *p, struct sip_request *req, enum sip_auth_type code)
 Authenticate for outbound registration. More...
 
static void do_setnat (struct sip_pvt *p)
 Set nat mode on the various data sockets. More...
 
static void do_stop_session_timer (struct sip_pvt *pvt)
 
static const char * domain_mode_to_text (const enum domain_mode mode)
 Print domain mode to cli. More...
 
static const char * dtmfmode2str (int mode)
 Convert DTMF mode to printable string. More...
 
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. More...
 
static int extensionstate_update (const char *context, const char *exten, struct state_notify_data *data, struct sip_pvt *p, int force)
 Callback for the devicestate notification (SUBSCRIBE) support subsystem. More...
 
static void extract_host_from_hostport (char **hostport)
 Terminate a host:port at the ':'. More...
 
static void extract_transferrer_headers (const char *prefix, struct ast_channel *peer, const struct sip_request *req)
 
static void extract_uri (struct sip_pvt *p, struct sip_request *req)
 Check Contact: URI of SIP message. More...
 
static const char * faxec2str (int faxec)
 
static int finalize_content (struct sip_request *req)
 Add 'Content-Length' header and content to SIP message. More...
 
static const char * find_alias (const char *name, const char *_default)
 Find compressed SIP alias. More...
 
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)
 
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. More...
 
static const char * find_full_alias (const char *name, const char *_default)
 Find full SIP alias. More...
 
static struct sip_authfind_realm_authentication (struct sip_auth_container *credentials, const char *realm)
 
static struct ast_channelfind_ringing_channel (struct ao2_container *device_state_info, struct sip_pvt *p)
 
static int find_sdp (struct sip_request *req)
 Determine whether a SIP message contains an SDP in its body. More...
 
static struct ast_cc_agentfind_sip_cc_agent_by_notify_uri (const char *const uri)
 
static struct ast_cc_agentfind_sip_cc_agent_by_original_callid (struct sip_pvt *pvt)
 
static struct ast_cc_agentfind_sip_cc_agent_by_subscribe_uri (const char *const uri)
 
static int find_sip_method (const char *msg)
 find_sip_method: Find SIP method from header More...
 
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 const struct epa_static_datafind_static_data (const char *const event_package)
 
static const struct cfsubscription_typesfind_subscription_type (enum subscriptiontype subtype)
 Find subscription type in array. More...
 
static void forked_invite_init (struct sip_request *req, const char *new_theirtag, struct sip_pvt *original, struct ast_sockaddr *addr)
 This function creates a dialog to handle a forked request. This dialog exists only to properly terminiate the forked request immediately. More...
 
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. More...
 
static int func_header_read (struct ast_channel *chan, const char *function, char *data, char *buf, size_t len)
 Read SIP header (dialplan function) More...
 
static int func_headers_read2 (struct ast_channel *chan, const char *function, char *data, struct ast_str **buf, ssize_t maxlen)
 Read unique list of SIP headers (dialplan function) More...
 
static int function_sippeer (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 ${SIPPEER()} Dialplan function - reads peer data More...
 
static char * generate_random_string (char *buf, size_t size)
 Generate 32 byte random string for callid's etc. More...
 
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. More...
 
static int get_also_info (struct sip_pvt *p, struct sip_request *oreq)
 Call transfer support (old way, deprecated by the IETF) More...
 
static int get_cached_mwi (struct sip_peer *peer, int *new, int *old)
 Get cached MWI info. More...
 
static char * get_content (struct sip_request *req)
 Get message body content. More...
 
static char * get_content_line (struct sip_request *req, char *name, char delimiter)
 Get a specific line from the message content. More...
 
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. More...
 
static int get_domain (const char *str, char *domain, int len)
 Extract domain from SIP To/From header. More...
 
static struct event_state_compositorget_esc (const char *const event_package)
 
static struct sip_esc_entryget_esc_entry (const char *entity_tag, struct event_state_compositor *esc)
 
static struct ast_variableget_insecure_variable_from_config (struct ast_config *config)
 
static struct ast_variableget_insecure_variable_from_sippeers (const char *column, const char *value)
 
static struct ast_variableget_insecure_variable_from_sipregs (const char *column, const char *value, struct ast_variable **var)
 
static 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. More...
 
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. More...
 
static int get_rdnis (struct sip_pvt *p, struct sip_request *oreq, char **name, char **number, int *reason_code, char **reason_str)
 Get referring dnis. More...
 
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=... More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
static int get_sip_pvt_from_replaces (const char *callid, const char *totag, const char *fromtag, struct sip_pvt **out_pvt, struct ast_channel **out_chan)
 Find a companion dialog based on Replaces information. More...
 
static const char * get_srv_protocol (enum ast_transport t)
 Return protocol string for srv dns query. More...
 
static const char * get_srv_service (enum ast_transport t)
 Return service string for srv dns query. More...
 
static const char * get_transport_list (unsigned int transports)
 Return configuration of transports for a device. More...
 
static const char * get_transport_pvt (struct sip_pvt *p)
 Return transport of dialog. More...
 
static int get_transport_str2enum (const char *transport)
 Return int representing a bit field of transport types found in const char *transport. More...
 
static const char * gettag (const struct sip_request *req, const char *header, char *tagbuf, int tagbufsize)
 Get tag from packet. More...
 
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. More...
 
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) More...
 
static int handle_invite_replaces (struct sip_pvt *p, struct sip_request *req, int *nounlock, struct sip_pvt *replaces_pvt, struct ast_channel *replaces_chan)
 Handle the transfer part of INVITE with a replaces: header,. More...
 
static int handle_request_bye (struct sip_pvt *p, struct sip_request *req)
 Handle incoming BYE request. More...
 
static int handle_request_cancel (struct sip_pvt *p, struct sip_request *req)
 Handle incoming CANCEL request. More...
 
static int handle_request_do (struct sip_request *req, struct ast_sockaddr *addr)
 Handle incoming SIP message - request or response. More...
 
static void handle_request_info (struct sip_pvt *p, struct sip_request *req)
 Receive SIP INFO Message. More...
 
static int handle_request_invite (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, uint32_t seqno, int *recount, const char *e, int *nounlock)
 Handle incoming INVITE request. More...
 
static int handle_request_invite_st (struct sip_pvt *p, struct sip_request *req, int reinvite)
 
static int handle_request_message (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, const char *e)
 Handle incoming MESSAGE request. More...
 
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. More...
 
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. More...
 
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, 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. More...
 
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. More...
 
static int handle_request_update (struct sip_pvt *p, struct sip_request *req)
 bare-bones support for SIP UPDATE More...
 
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. More...
 
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. More...
 
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) More...
 
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. More...
 
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. More...
 
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. More...
 
const char * hangup_cause2sip (int cause)
 Convert Asterisk hangup causes to SIP codes. More...
 
int hangup_sip2cause (int cause)
 Convert SIP hangup causes to Asterisk hangup causes. More...
 
static int has_media_level_attribute (int start, struct sip_request *req, const char *attr)
 
static int has_media_stream (struct sip_pvt *p, enum media_type m)
 Check the media stream list to see if the given type already exists. More...
 
static int init_req (struct sip_request *req, int sipmethod, const char *recip)
 Initialize SIP request. More...
 
static int init_resp (struct sip_request *resp, const char *msg)
 Initialize SIP response, based on SIP request. More...
 
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. More...
 
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. More...
 
static const char * insecure2str (int mode)
 Convert Insecure setting to printable string. More...
 
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. More...
 
static int is_method_allowed (unsigned int *allowed_methods, enum sipmethod method)
 Check if method is allowed for a device or a dialog. More...
 
static int load_module (void)
 Load the module. More...
 
static int local_attended_transfer (struct sip_pvt *transferer, struct ast_channel *transferer_chan, uint32_t seqno, int *nounlock)
 Find all call legs and bridge transferee with target called from handle_request_refer. More...
 
static void lws2sws (struct ast_str *data)
 Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled. More...
 
static void make_our_tag (struct sip_pvt *pvt)
 Make our SIP dialog tag. More...
 
static int manager_show_registry (struct mansession *s, const struct message *m)
 Show SIP registrations in the manager API. More...
 
static int manager_sip_peer_status (struct mansession *s, const struct message *m)
 Show SIP peers in the manager API. More...
 
static int manager_sip_qualify_peer (struct mansession *s, const struct message *m)
 Qualify SIP peers in the manager API. More...
 
static int manager_sip_show_peer (struct mansession *s, const struct message *m)
 Show SIP peers in the manager API. More...
 
static int manager_sip_show_peers (struct mansession *s, const struct message *m)
 Show SIP peers in the manager API. More...
 
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. More...
 
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 More...
 
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 More...
 
static int mock_tcp_loop (char *fragments[], size_t num_fragments, struct ast_str **overflow, char **messages, int *num_messages, struct ast_test *test)
 Imitation TCP reception loop. More...
 
static void mwi_event_cb (void *userdata, struct stasis_subscription *sub, struct stasis_message *msg)
 Receive MWI events that we have subscribed to. More...
 
static int network_change_sched_cb (const void *data)
 
static void network_change_stasis_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void network_change_stasis_subscribe (void)
 
static void network_change_stasis_unsubscribe (void)
 
static struct sip_proxyobproxy_get (struct sip_pvt *dialog, struct sip_peer *peer)
 Get default outbound proxy or global proxy. More...
 
static void offered_media_list_destroy (struct sip_pvt *p)
 Destroy SDP media offer list. More...
 
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. More...
 
static void parse_copy (struct sip_request *dst, const struct sip_request *src)
 Copy SIP request, parse it. More...
 
static int parse_minse (const char *p_hdrval, int *const p_interval)
 Session-Timers: Function for parsing Min-SE header. More...
 
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. More...
 
static int parse_ok_contact (struct sip_pvt *pvt, struct sip_request *req)
 Save contact header for 200 OK on INVITE. More...
 
static void parse_oli (struct sip_request *req, struct ast_channel *chan)
 Check for the presence of OLI tag(s) in the From header and set on the channel. More...
 
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) More...
 
static int parse_request (struct sip_request *req)
 Parse a SIP message. More...
 
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. More...
 
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 More...
 
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_full (void *obj, void *arg, void *data, 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 More...
 
static int peer_markall_autopeers_func (void *device, void *arg, int flags)
 
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 pidf_validate_presence (struct ast_xml_doc *doc)
 
static int pidf_validate_tuple (struct ast_xml_node *tuple_node)
 
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. More...
 
static void print_group (int fd, ast_group_t group, int crlf)
 Print call group and pickup group. More...
 
static void print_named_groups (int fd, struct ast_namedgroups *group, int crlf)
 Print named call groups and pickup groups. More...
 
static void proc_422_rsp (struct sip_pvt *p, struct sip_request *rsp)
 Handle 422 response to INVITE with session-timer requested. More...
 
static int proc_session_timer (const void *vp)
 Session-Timers: Process session refresh timeout event. More...
 
static int process_crypto (struct sip_pvt *p, struct ast_rtp_instance *rtp, struct ast_sdp_srtp **srtp, const char *a)
 
static int process_sdp (struct sip_pvt *p, struct sip_request *req, int t38action, int is_offer)
 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(). More...
 
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_dtls (const char *a, struct sip_pvt *p, struct ast_rtp_instance *instance)
 
static int process_sdp_a_ice (const char *a, struct sip_pvt *p, struct ast_rtp_instance *instance, int rtcp_mux)
 
static int process_sdp_a_image (const char *a, struct sip_pvt *p)
 
static int process_sdp_a_rtcp_mux (const char *a, struct sip_pvt *p, int *requested)
 
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. More...
 
static struct sip_proxyproxy_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. More...
 
static int proxy_update (struct sip_proxy *proxy)
 
static int publish_expire (const void *data)
 
static void publish_qualify_peer_done (const char *id, const char *peer)
 
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. More...
 
static struct sip_peerrealtime_peer (const char *newpeername, struct ast_sockaddr *addr, char *callbackexten, 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. More...
 
static int realtime_peer_by_addr (const char **name, struct ast_sockaddr *addr, const char *ipaddr, const char *callbackexten, struct ast_variable **var, struct ast_variable **varregs)
 
static int realtime_peer_by_name (const char *const *name, struct ast_sockaddr *addr, const char *ipaddr, struct ast_variable **var, struct ast_variable **varregs)
 
static struct ast_variablerealtime_peer_get_sippeer_helper (const char **name, struct ast_variable **varregs)
 
static void realtime_update_peer (const char *peername, struct ast_sockaddr *addr, const char *defaultuser, const char *fullcontact, const char *useragent, int expirey, unsigned short deprecated_username, int lastms, const char *path)
 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. More...
 
static void receive_message (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, const char *e)
 Receive SIP MESSAGE method messages. More...
 
static void ref_proxy (struct sip_pvt *pvt, struct sip_proxy *proxy)
 maintain proper refcounts for a sip_pvt's outboundproxy More...
 
static const char * referstatus2str (enum referstatus rstatus)
 Convert transfer status to string. More...
 
static void reg_source_db (struct sip_peer *peer)
 Get registration details from Asterisk DB. More...
 
static void register_peer_exten (struct sip_peer *peer, int onoff)
 Automatically add peer extension to dial plan. More...
 
static int register_realtime_peers_with_callbackextens (void)
 
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. More...
 
static int registry_cmp_cb (void *obj, void *arg, int flags)
 
static int registry_hash_cb (const void *obj, const int flags)
 
static const char * regstate2str (enum sipregistrystate regstate)
 Convert registration state status to string. More...
 
static int reinvite_timeout (const void *data)
 
static int reload (void)
 Part of Asterisk module interface. More...
 
static int reload_config (enum channelreloadreason reason)
 Re-read SIP.conf config file. More...
 
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 More...
 
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) More...
 
static int resp_needs_contact (const char *msg, enum sipmethod method)
 Test if this response needs a contact header. More...
 
static int respprep (struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Prepare SIP response packet. More...
 
static int restart_monitor (void)
 Start the channel monitor thread. More...
 
static void restart_session_timer (struct sip_pvt *p)
 Session-Timers: Restart session timer. More...
 
static int retrans_pkt (const void *data)
 Retransmit SIP message if no answer. More...
 
static void sched_check_pendings (struct sip_pvt *pvt)
 
static void send_check_user_failure_response (struct sip_pvt *p, struct sip_request *req, int res, enum xmittype reliable)
 
static void send_manager_peer_status (struct mansession *s, struct sip_peer *peer, const char *idText)
 
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. More...
 
static void send_session_timeout (struct ast_channel *chan, const char *source)
 Sends a session timeout channel blob used to produce SessionTimeout AMI messages. More...
 
static enum ast_cc_service_type service_string_to_service_type (const char *const service_string)
 
static struct ast_manager_event_blobsession_timeout_to_ami (struct stasis_message *msg)
 
static int set_address_from_contact (struct sip_pvt *pvt)
 Change the other partys IP address based on given contact. More...
 
static void set_destination (struct sip_pvt *p, const char *uri)
 Set destination from SIP URI. More...
 
static void set_ice_components (struct sip_pvt *p, struct ast_rtp_instance *instance, int remote_rtcp_mux)
 
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. More...
 
static int set_message_vars_from_req (struct ast_msg *msg, struct sip_request *req)
 
static void set_peer_defaults (struct sip_peer *peer)
 Set peer defaults before configuring specific configurations. More...
 
static void set_peer_nat (const struct sip_pvt *p, struct sip_peer *peer)
 Set the peers nat flags if they are using auto_* settings. More...
 
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. More...
 
static int show_channels_cb (struct sip_pvt *cur, struct __show_chan_arg *arg)
 callback for show channel|subscription More...
 
static int show_chanstats_cb (struct sip_pvt *cur, struct __show_chan_arg *arg)
 Callback for show_chanstats. More...
 
static void shutdown_mwi_subscription (struct sip_subscription_mwi *mwi)
 
static int sip_addheader (struct ast_channel *chan, const char *data)
 Add a SIP header to an outbound INVITE. More...
 
static int sip_allow_anyrtp_remote (struct ast_channel *chan1, struct ast_rtp_instance *instance, const char *rtptype)
 
static int sip_allow_rtp_remote (struct ast_channel *chan1, struct ast_rtp_instance *instance)
 
static int sip_allow_vrtp_remote (struct ast_channel *chan1, struct ast_rtp_instance *instance)
 
static void sip_alreadygone (struct sip_pvt *dialog)
 Encapsulate setting of SIP_ALREADYGONE to be able to trace it with debugging. More...
 
static int sip_answer (struct ast_channel *ast)
 sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface More...
 
void sip_auth_headers (enum sip_auth_type code, char **header, char **respheader)
 return the request and response header for a 401 or 407 code More...
 
static int sip_call (struct ast_channel *ast, const char *dest, int timeout)
 Initiate SIP call from PBX used from the dial() application. More...
 
void sip_cancel_destroy (struct sip_pvt *pvt)
 Cancel destruction of SIP dialog. More...
 
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. More...
 
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. More...
 
static int sip_debug_test_addr (const struct ast_sockaddr *addr)
 See if we pass debug IP filter. More...
 
static int sip_debug_test_pvt (struct sip_pvt *p)
 Test PVT for debugging output. More...
 
static void sip_destroy_peer (struct sip_peer *peer)
 Destroy peer object from memory. More...
 
static void sip_destroy_peer_fn (void *peer)
 
static int sip_devicestate (const char *data)
 Part of PBX channel interface. More...
 
void sip_digest_parser (char *c, struct digestkeys *keys)
 Takes the digest response and parses it. More...
 
static char * sip_do_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Turn on SIP debugging (CLI command) More...
 
static char * sip_do_debug_ip (int fd, const char *arg)
 Enable SIP Debugging for a single IP. More...
 
static char * sip_do_debug_peer (int fd, const char *arg)
 Turn on SIP debugging for a given peer. More...
 
static int sip_do_reload (enum channelreloadreason reason)
 Reload module. More...
 
static int sip_dtmfmode (struct ast_channel *chan, const char *data)
 Set the DTMFmode for an outbound SIP call (application) More...
 
static void sip_dump_history (struct sip_pvt *dialog)
 Dump SIP history to debug log file at end of lifespan for SIP dialog. More...
 
static int sip_epa_register (const struct epa_static_data *static_data)
 
static void sip_epa_unregister_all (void)
 
struct sip_peersip_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. More...
 
static struct sip_peersip_find_peer_by_ip_and_exten (struct ast_sockaddr *addr, char *callbackexten, int transport)
 
static struct sip_peersip_find_peer_full (const char *peer, struct ast_sockaddr *addr, char *callbackexten, int realtime, int which_objects, int devstate_only, int transport)
 
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 More...
 
static const char * sip_get_callid (struct ast_channel *chan)
 Deliver SIP call ID for the call. More...
 
static int sip_get_cc_information (struct sip_request *req, char *subscribe_uri, size_t size, enum ast_cc_service_type *service)
 
static void sip_get_codec (struct ast_channel *chan, struct ast_format_cap *result)
 
const char * sip_get_header (const struct sip_request *req, const char *name)
 Get header from SIP request. More...
 
static enum ast_rtp_glue_result sip_get_rtp_peer (struct ast_channel *chan, struct ast_rtp_instance **instance)
 
const char * sip_get_transport (enum ast_transport t)
 Return transport as string. More...
 
static enum ast_rtp_glue_result sip_get_trtp_peer (struct ast_channel *chan, struct ast_rtp_instance **instance)
 
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 More...
 
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. More...
 
static int sip_is_token (const char *str)
 
static int sip_is_xml_parsable (void)
 
static void sip_keepalive_all_peers (void)
 Send a keepalive to all known peers. More...
 
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_instancesip_monitor_instance_init (int core_id, const char *const subscribe_uri, const char *const peername, const char *const device_name)
 
static int sip_msg_send (const struct ast_msg *msg, const char *to, const char *from)
 
static const char * sip_nat_mode (const struct sip_pvt *p)
 Display SIP nat mode. More...
 
static struct ast_channelsip_new (struct sip_pvt *i, int state, const char *title, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, ast_callid callid)
 Initiate a call in the SIP channel. More...
 
static int sip_notify_alloc (struct sip_pvt *p)
 Allocate SIP refer structure. More...
 
static int sip_offer_timer_expire (const void *data)
 
static void sip_peer_hold (struct sip_pvt *p, int hold)
 Change onhold state of a peer using a pvt structure. More...
 
static int sip_pickup (struct ast_channel *chan)
 Pickup a call using the subsystem in features.c This is executed in a separate thread. More...
 
static void * sip_pickup_thread (void *stuff)
 SIP pickup support function Starts in a new thread, then pickup the call. More...
 
static int sip_pidf_validate (struct sip_request *req, struct ast_xml_doc **pidf_doc)
 Makes sure that body is properly formatted PIDF. More...
 
static void sip_pkt_dtor (void *vdoomed)
 
static void sip_poke_all_peers (void)
 Send a poke to all known peers. More...
 
static int sip_poke_noanswer (const void *data)
 React to lack of answer to Qualify poke. More...
 
static int sip_poke_peer (struct sip_peer *peer, int force)
 Check availability of peer, also keep NAT open. More...
 
static int sip_poke_peer_now (const void *data)
 
static int sip_poke_peer_s (const void *data)
 Poke peer (send qualify to check if peer is alive and well) More...
 
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) More...
 
static void sip_publish_registry (const char *username, const char *domain, const char *status)
 
static void sip_pvt_callid_set (struct sip_pvt *pvt, ast_callid callid)
 
static void sip_pvt_dtor (void *vdoomed)
 ao2 destructor for SIP dialog structure More...
 
static struct ast_channelsip_pvt_lock_full (struct sip_pvt *pvt)
 
static char * sip_qualify_peer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Send an OPTIONS packet to a SIP peer. More...
 
static int sip_queryoption (struct ast_channel *chan, int option, void *data, int *datalen)
 Query an option on a SIP dialog. More...
 
static void sip_queue_hangup_cause (struct sip_pvt *p, int cause)
 
static struct ast_framesip_read (struct ast_channel *ast)
 Read SIP RTP from channel. More...
 
static const struct ast_sockaddrsip_real_dst (const struct sip_pvt *p)
 The real destination address for a write. More...
 
static const char * sip_reason_code_to_str (struct ast_party_redirecting_reason *reason)
 
static int sip_refer_alloc (struct sip_pvt *p)
 Allocate SIP refer structure. More...
 
static void sip_refer_destroy (struct sip_pvt *p)
 Destroy SIP refer structure. More...
 
static int sip_reg_timeout (const void *data)
 Registration request timeout, register again. More...
 
static int sip_register (const char *value, int lineno)
 create sip_registry object from register=> line in sip.conf and link into reg container More...
 
static void sip_register_tests (void)
 SIP test registration. More...
 
static void sip_registry_destroy (void *obj)
 Destroy registry object Objects created with the register= statement in static configuration. More...
 
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. More...
 
static char * sip_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Force reload of module from cli. More...
 
static int sip_removeheader (struct ast_channel *chan, const char *data)
 Remove SIP headers added previously with SipAddHeader application. More...
 
static struct ast_channelsip_request_call (const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *dest, int *cause)
 PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here. More...
 
static int sip_reregister (const void *data)
 Update registration with SIP Proxy. More...
 
static struct ast_framesip_rtp_read (struct ast_channel *ast, struct sip_pvt *p, int *faxdetect)
 Read RTP from network. More...
 
static const char * sip_sanitized_host (const char *host)
 
void sip_scheddestroy (struct sip_pvt *p, int ms)
 Schedule destruction of SIP dialog. More...
 
void sip_scheddestroy_final (struct sip_pvt *p, int ms)
 Schedule final destruction of SIP dialog. More...
 
static int sip_scheddestroy_full (struct sip_pvt *p, int ms)
 
static void sip_send_all_mwi_subscriptions (void)
 Send all MWI subscriptions. More...
 
static void sip_send_all_registers (void)
 Send all known registrations. More...
 
static int sip_send_keepalive (const void *data)
 Send keep alive packet to peer. More...
 
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. More...
 
static int sip_sendcustominfo (struct ast_channel *chan, const char *data)
 Send a custom INFO message via AST_CONTROL_CUSTOM indication. More...
 
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. More...
 
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! More...
 
static int sip_sendtext (struct ast_channel *ast, const char *text)
 
static void sip_set_default_format_capabilities (struct ast_format_cap *cap)
 
static char * sip_set_history (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Enable/Disable SIP History logging (CLI) More...
 
static void sip_set_owner (struct sip_pvt *p, struct ast_channel *chan)
 Set the owning channel on the sip_pvt object. More...
 
static void sip_set_redirstr (struct sip_pvt *p, char *reason)
 Translate referring cause. More...
 
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, const struct ast_format_cap *cap, int nat_active)
 
static int sip_setoption (struct ast_channel *chan, int option, void *data, int datalen)
 Set an option on a SIP dialog. More...
 
static char * sip_show_channel (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show details of one active dialog. More...
 
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. More...
 
static char * sip_show_channelstats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 SIP show channelstats CLI (main function) More...
 
static char * sip_show_domains (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command to list local domains. More...
 
static char * sip_show_history (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show history details of one dialog. More...
 
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. More...
 
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) More...
 
static char * sip_show_peer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show one peer in detail. More...
 
static char * sip_show_peers (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI Show Peers command. More...
 
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. More...
 
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. More...
 
static char * sip_show_tcp (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show active TCP connections. More...
 
static char * sip_show_user (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show one user in detail. More...
 
static char * sip_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI Command 'SIP Show Users'. More...
 
static int sip_sipredirect (struct sip_pvt *p, const char *dest)
 Transfer call before connect with a 302 redirect. More...
 
static struct sip_st_dlgsip_st_alloc (struct sip_pvt *const p)
 Allocate Session-Timers struct w/in dialog. More...
 
static int sip_standard_port (enum ast_transport type, int port)
 Returns the port to use for this socket. More...
 
static int sip_subscribe_mwi (const char *value, int lineno)
 Parse mwi=> line in sip.conf and add to list. More...
 
static void sip_subscribe_mwi_destroy (void *data)
 Destroy MWI subscription object. More...
 
static int sip_subscribe_mwi_do (const void *data)
 Send a subscription or resubscription for MWI. More...
 
static int sip_t38_abort (const void *data)
 Called to deny a T38 reinvite if the core does not respond to our request. More...
 
static struct ast_tcptls_session_instancesip_tcp_locate (struct ast_sockaddr *s)
 Find thread for TCP/TLS session (based on IP/Port. More...
 
static void * sip_tcp_worker_fn (void *data)
 SIP TCP connection handler. More...
 
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. More...
 
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 More...
 
static struct sip_threadinfosip_threadinfo_create (struct ast_tcptls_session_instance *tcptls_session, int transport)
 creates a sip_threadinfo object and links it into the threadt table. More...
 
static void sip_threadinfo_destructor (void *obj)
 
static int sip_transfer (struct ast_channel *ast, const char *dest)
 Transfer SIP call. More...
 
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. More...
 
static void sip_unregister_tests (void)
 SIP test registration. More...
 
static void sip_websocket_callback (struct ast_websocket *session, struct ast_variable *parameters, struct ast_variable *headers)
 SIP WebSocket connection handler. More...
 
static int sip_write (struct ast_channel *ast, struct ast_frame *frame)
 Send frame to media channel (rtp) More...
 
static int sipinfo_send (struct ast_channel *chan, struct ast_variable *headers, const char *content_type, const char *content, const char *useragent_filter)
 
static int sipsock_read (int *id, int fd, short events, void *ignore)
 Read data from SIP UDP socket. More...
 
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. More...
 
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. More...
 
static int st_get_se (struct sip_pvt *p, int max)
 Get Max or Min SE (session timer expiry) More...
 
static void start_ice (struct ast_rtp_instance *instance, int offer)
 Start ICE negotiation on an RTP instance. More...
 
static void start_mwi_subscription (struct sip_subscription_mwi *mwi, int ms)
 
static void start_register_timeout (struct sip_registry *reg)
 
static void start_reregister_timeout (struct sip_registry *reg, int ms)
 
static void start_session_timer (struct sip_pvt *pvt)
 Session-Timers: Start session timer. More...
 
static void start_t38_abort_timer (struct sip_pvt *pvt)
 
static void startup_event_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 Event callback which indicates we're fully booted. More...
 
 STASIS_MESSAGE_TYPE_DEFN_LOCAL (session_timeout_type,.to_ami=session_timeout_to_ami,)
 
static void state_notify_build_xml (struct state_notify_data *data, 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. More...
 
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. More...
 
static void stop_provisional_keepalive (struct sip_pvt *pvt)
 
static void stop_register_timeout (struct sip_registry *reg)
 
static void stop_reinvite_retry (struct sip_pvt *pvt)
 
static void stop_reinviteid (struct sip_pvt *pvt)
 
static void stop_retrans_pkt (struct sip_pkt *pkt)
 
static void stop_session_timer (struct sip_pvt *pvt)
 Session-Timers: Stop session timer. More...
 
static void stop_t38_abort_timer (struct sip_pvt *pvt)
 
static int str2dtmfmode (const char *str)
 maps a string to dtmfmode, returns -1 on error More...
 
static enum st_mode str2stmode (const char *s)
 
static enum st_refresher_param str2strefresherparam (const char *s)
 
static const char * strefresher2str (enum st_refresher r)
 
static const char * strefresherparam2str (enum st_refresher_param r)
 
static const char * subscription_type2str (enum subscriptiontype subtype)
 Show subscription type in string format. More...
 
static unsigned int t38_get_rate (enum ast_control_t38_rate rate)
 Get Max T.38 Transmission rate from T38 capabilities. More...
 
static void tcptls_packet_destructor (void *obj)
 
static struct sip_peertemp_peer (const char *name)
 Create temporary peer (used in autocreatepeer mode) More...
 
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. More...
 
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. More...
 
static int transmit_info_with_aoc (struct sip_pvt *p, struct ast_aoc_decoded *decoded)
 Send SIP INFO advice of charge message. More...
 
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. More...
 
static int transmit_info_with_vidupdate (struct sip_pvt *p)
 Send SIP INFO with video update request. More...
 
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. More...
 
static int transmit_message (struct sip_pvt *p, int init, int auth)
 Transmit with SIP MESSAGE method. More...
 
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) More...
 
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) More...
 
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. More...
 
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()) More...
 
static int transmit_reinvite_with_sdp (struct sip_pvt *p, int t38version, int oldsdp)
 Transmit reinvite with SDP. More...
 
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) More...
 
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. More...
 
static int transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Transmit response, no retransmits. More...
 
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. More...
 
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. More...
 
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. More...
 
static int transmit_response_with_auth (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *nonce, enum xmittype reliable, const char *header, int stale)
 Respond with authorization request. More...
 
static int transmit_response_with_date (struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Add date before transmitting response. More...
 
static int transmit_response_with_minexpires (struct sip_pvt *p, const char *msg, const struct sip_request *req, int minexpires)
 Append Min-Expires header, content length before transmitting response. More...
 
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) More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
static int transmit_state_notify (struct sip_pvt *p, struct state_notify_data *data, int full, int timeout)
 Used in the SUBSCRIBE notification subsystem (RFC3265) More...
 
static const char * trust_id_outbound2str (int mode)
 
static void try_suggested_sip_codec (struct sip_pvt *p)
 Try setting the codecs suggested by the SIP_CODEC channel variable. More...
 
static int uac_sips_contact (struct sip_request *req)
 Determine if, as a UAC, we need to use a SIPS Contact. More...
 
static int uas_sips_contact (struct sip_request *req)
 Determine if, as a UAS, we need to use a SIPS Contact. More...
 
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. More...
 
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. More...
 
static void update_connectedline (struct sip_pvt *p, const void *data, size_t datalen)
 Notify peer that the connected line has changed. More...
 
static void update_peer (struct sip_peer *p, int expire)
 Update peer data in database (if used) More...
 
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. More...
 
static int use_reason_header (struct sip_pvt *pvt, struct sip_request *req)
 Parses SIP reason header according to RFC3326 and sets channel's hangupcause if configured so and header present. More...
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Session Initiation Protocol (SIP)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_DEPRECATED, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .requires = "ccss,dnsmgr,udptl", .optional_modules = "res_crypto,res_http_websocket", }
 
static struct stasis_subscriptionacl_change_sub
 
static const struct cfalias aliases []
 
static const struct _map_x_s allowoverlapstr []
 
static char * app_dtmfmode = "SIPDtmfMode"
 
static char * app_sipaddheader = "SIPAddHeader"
 
static char * app_sipremoveheader = "SIPRemoveHeader"
 
static char * app_sipsendcustominfo = "SIPSendCustomINFO"
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct sip_auth_containerauthl = NULL
 Authentication container for realm authentication. More...
 
static ast_mutex_t authl_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 Global authentication container protection while adjusting the references. More...
 
static int authlimit = DEFAULT_AUTHLIMIT
 
static int authtimeout = DEFAULT_AUTHTIMEOUT
 
static struct _map_x_s autopeermodes []
 
struct ast_sockaddr bindaddr
 
static int can_parse_xml
 
static const struct epa_static_data cc_epa_static_data
 
static const struct sip_esc_publish_callbacks cc_esc_publish_callbacks
 
static const struct ast_sip_api_tech chan_sip_api_provider
 
static struct ast_custom_function checksipdomain_function
 
static struct ast_cli_entry cli_sip []
 SIP Cli commands definition. More...
 
static const char config [] = "sip.conf"
 
static struct ast_sockaddr debugaddr
 
static struct ast_rtp_dtls_cfg default_dtls_cfg
 Default DTLS connection configuration. More...
 
static int default_expiry = DEFAULT_DEFAULT_EXPIRY
 
static struct ast_jb_conf default_jbconf
 Global jitterbuffer configuration - by default, jb is disabled. More...
 
static const int DEFAULT_PUBLISH_EXPIRES = 3600
 
static struct ast_tls_config default_tls_cfg
 Default TLS connection configuration. More...
 
static struct ao2_containerdialogs
 
struct ao2_containerdialogs_needdestroy
 
struct ao2_containerdialogs_rtpcheck
 
static struct domain_list domain_list = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
 
static const struct _map_x_s dtmfstr []
 mapping between dtmf flags and strings More...
 
struct epa_static_data_list epa_static_data_list = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
 
static int esc_etag_counter
 
static const int ESC_MAX_BUCKETS = 37
 
static struct event_state_compositor 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: More...
 
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 struct ast_jb_conf global_jbconf
 
static unsigned int global_t38_maxdatagram
 
static const int HASH_DIALOG_SIZE = 563
 
static const int HASH_PEER_SIZE = 563
 
static const int HASH_REGISTRY_SIZE = 563
 
static const 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. More...
 
static const struct invstate2stringtable invitestate2string []
 
static struct io_contextio
 
static struct ast_halocaladdr
 List of local networks We store "localnet" addresses from the config file into an access list, marked as 'DENY', so the call to ast_apply_ha() will return AST_SENSE_DENY for 'local' addresses, and AST_SENSE_ALLOW for 'non local' (i.e. presumably public) addresses. More...
 
static int log_level = -1
 
static int max_expiry = DEFAULT_MAX_EXPIRY
 
static int max_subexpiry = DEFAULT_MAX_EXPIRY
 
static struct ast_sockaddr media_address
 
static int min_expiry = DEFAULT_MIN_EXPIRY
 
static int min_subexpiry = DEFAULT_MIN_EXPIRY
 
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. More...
 
static ast_mutex_t monlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical. More...
 
static int mwi_expiry = DEFAULT_MWI_EXPIRY
 
static ast_mutex_t netlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 
static int network_change_sched_id = -1
 
static struct stasis_subscriptionnetwork_change_sub
 
static const char notify_config [] = "sip_notify.conf"
 
static struct ast_confignotify_types = NULL
 
static int ourport_tcp
 
static int ourport_tls
 
static struct ao2_containerpeers
 The peer list: Users, Peers and Friends. More...
 
static struct ao2_containerpeers_by_ip
 
static const struct _map_x_s referstatusstrings []
 
static struct ao2_containerregistry_list
 The register list: Other SIP proxies we register with and receive calls from. More...
 
static const struct _map_x_s regstatestrings []
 
static struct ast_sockaddr rtpbindaddr
 
struct ast_sched_contextsched
 
static struct ast_cc_agent_callbacks sip_cc_agent_callbacks
 
static struct ast_cc_monitor_callbacks sip_cc_monitor_callbacks
 
struct {
   enum sip_cc_notify_state   state
 
   const char *   state_string
 
sip_cc_notify_state_map []
 
struct {
   enum ast_cc_service_type   service
 
   const char *   service_string
 
sip_cc_service_map []
 
static struct ast_threadstorage sip_content_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_sip_content_buf , .custom_init = NULL , }
 
static struct ast_custom_function sip_header_function
 
static struct ast_custom_function sip_headers_function
 
static const struct cfsip_methods sip_methods []
 
struct ao2_containersip_monitor_instances
 
static const struct ast_msg_tech sip_msg_tech
 
static const struct sip_reasons sip_reason_table []
 
static ast_mutex_t sip_reload_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 
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. More...
 
struct ast_channel_tech sip_tech
 Definition of this channel for PBX channel registration. More...
 
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. More...
 
static struct ast_tls_config sip_tls_cfg
 Working TLS connection configuration. More...
 
static struct ast_tcptls_session_args sip_tls_desc
 The TCP/TLS server definition. More...
 
static struct ast_threadstorage sip_transport_str_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_sip_transport_str_buf , .custom_init = NULL , }
 
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. More...
 
static struct ast_custom_function sippeer_function
 Structure to declare a dialplan function: SIPPEER. More...
 
static int sipsock = -1
 Main socket for UDP SIP communication. More...
 
static int * sipsock_read_id
 
static const struct _map_x_s stmodes []
 Report Peer status in character string. More...
 
static const struct _map_x_s strefresher_params []
 
static const struct _map_x_s strefreshers []
 
static struct ao2_containersubscription_mwi_list
 The MWI subscription list. More...
 
static const struct cfsubscription_types subscription_types []
 
static struct ao2_containerthreadt
 The table of TCP threads. More...
 
static const struct _map_x_s trust_id_outboundstr []
 
static struct ast_threadstorage ts_temp_pvt = { .once = PTHREAD_ONCE_INIT , .key_init = __init_ts_temp_pvt , .custom_init = temp_pvt_init , }
 
static int unauth_sessions = 0
 
static char used_context [AST_MAX_CONTEXT]
 
Object counters @{
Bug:
These counters are not handled in a thread-safe way ast_atomic_fetchadd_int() should be used to modify these values.
static int speerobjs = 0
 
static int rpeerobjs = 0
 
static int apeerobjs = 0
 

DefaultSettings

Default setttings are used as a channel setting and as a default when configuring devices

#define SIP_PEDANTIC_DECODE(str)
 
static char default_language [MAX_LANGUAGE]
 
static char default_callerid [AST_MAX_EXTENSION]
 
static char default_mwi_from [80]
 
static char default_fromdomain [AST_MAX_EXTENSION]
 
static int default_fromdomainport
 
static char default_notifymime [AST_MAX_EXTENSION]
 
static char default_vmexten [AST_MAX_EXTENSION]
 
static int default_qualify
 
static int default_keepalive
 
static char default_mohinterpret [MAX_MUSICCLASS]
 
static char default_mohsuggest [MAX_MUSICCLASS]
 
static char default_parkinglot [AST_MAX_CONTEXT]
 
static char default_engine [256]
 
static int default_maxcallbitrate
 
static char default_zone [MAX_TONEZONE_COUNTRY]
 
static unsigned int default_transports
 
static unsigned int default_primary_transport
 
static struct sip_settings sip_cfg
 
static unsigned int chan_idx
 
static int global_match_auth_username
 
static int global_relaxdtmf
 
static int global_prematuremediafilter
 
static int global_rtptimeout
 
static int global_rtpholdtimeout
 
static int global_rtpkeepalive
 
static int global_reg_timeout
 
static int global_regattempts_max
 
static int global_reg_retry_403
 
static int global_shrinkcallerid
 
static int global_callcounter
 
static unsigned int global_tos_sip
 
static unsigned int global_tos_audio
 
static unsigned int global_tos_video
 
static unsigned int global_tos_text
 
static unsigned int global_cos_sip
 
static unsigned int global_cos_audio
 
static unsigned int global_cos_video
 
static unsigned int global_cos_text
 
static unsigned int recordhistory
 
static unsigned int dumphistory
 
static char global_useragent [AST_MAX_EXTENSION]
 
static char global_sdpsession [AST_MAX_EXTENSION]
 
static char global_sdpowner [AST_MAX_EXTENSION]
 
static int global_authfailureevents
 
static int global_t1
 
static int global_t1min
 
static int global_timer_b
 
static unsigned int global_autoframing
 
static int global_qualifyfreq
 
static int global_qualify_gap
 
static int global_qualify_peers
 
static enum st_mode global_st_mode
 
static enum st_refresher_param global_st_refresher
 
static int global_min_se
 
static int global_max_se
 
static int global_store_sip_cause
 
static int global_dynamic_exclude_static = 0
 
static unsigned char global_refer_addheaders
 

Detailed Description

Implementation of Session Initiation Protocol.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m

See Also:

Implementation of RFC 3261 - without S/MIME, and experimental TCP and TLS support Configuration file sip.conf

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

Note
TCP/TLS support is EXPERIMENTAL and WILL CHANGE. This applies to configuration settings, dialplan commands and dialplans apps/functions See SIP TCP and TLS support

******** General TODO:s

Todo:

Better support of forking

VIA branch tag transaction checking

Transaction support

******** Wishlist: Improvements

Overview of the handling of SIP sessions
The SIP channel handles several types of SIP sessions, or dialogs, not all of them being "telephone calls".
  • Incoming calls that will be sent to the PBX core
  • Outgoing calls, generated by the PBX
  • SIP subscriptions and notifications of states and voicemail messages
  • SIP registrations, both inbound and outbound
  • SIP peer management (peerpoke, OPTIONS)
  • SIP text messages

In the SIP channel, there's a list of active SIP dialogs, which includes all of these when they are active. "sip show channels" in the CLI will show most of these, excluding subscriptions which are shown by "sip show subscriptions"

incoming packets
Incoming packets are received in the monitoring thread, then handled by sipsock_read() for udp only. In tcp, packets are read by the tcp_helper thread. sipsock_read() function parses the packet and matches an existing dialog or starts a new SIP dialog.

sipsock_read sends the packet to handle_incoming(), that parses a bit more. If it is a response to an outbound request, the packet is sent to handle_response(). If it is a request, handle_incoming() sends it to one of a list of functions depending on the request type - INVITE, OPTIONS, REFER, BYE, CANCEL etc sipsock_read locks the ast_channel if it exists (an active call) and unlocks it after we have processed the SIP message.

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

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

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

Definition in file chan_sip.c.

Macro Definition Documentation

◆ append_history

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

◆ BOGUS_PEER_MD5SECRET

#define BOGUS_PEER_MD5SECRET   "intentionally_invalid_md5_string"

We can recognize the bogus peer by this invalid MD5 hash.

Definition at line 1058 of file chan_sip.c.

Referenced by check_auth(), load_module(), and sip_reload().

◆ check_request_transport

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

Referenced by create_addr_from_peer(), and register_verify().

◆ CHECK_RESULTS

#define CHECK_RESULTS (   in,
  expected_res,
  expected_start,
  expected_len 
)

Referenced by AST_TEST_DEFINE().

◆ CONTAINER_UNLINK

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

Referenced by change_callid_pvt().

◆ find_call

#define find_call (   req,
  addr,
  intended_method 
)    __find_call(req, addr, intended_method, __FILE__, __LINE__, __PRETTY_FUNCTION__)

Definition at line 1240 of file chan_sip.c.

Referenced by handle_request_do().

◆ FORMAT [1/8]

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

◆ FORMAT [2/8]

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

Definition at line 22152 of file chan_sip.c.

◆ FORMAT [3/8]

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

Definition at line 22152 of file chan_sip.c.

◆ FORMAT [4/8]

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

Definition at line 22152 of file chan_sip.c.

◆ FORMAT [5/8]

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

Definition at line 22152 of file chan_sip.c.

◆ FORMAT [6/8]

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

◆ FORMAT [7/8]

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

Definition at line 22152 of file chan_sip.c.

◆ FORMAT [8/8]

#define FORMAT   "%-15.15s %-15.15s %-15.15s %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s %-10.10s\n"

Definition at line 22152 of file chan_sip.c.

◆ FORMAT2 [1/5]

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

◆ FORMAT2 [2/5]

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

Definition at line 22151 of file chan_sip.c.

◆ FORMAT2 [3/5]

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

Definition at line 22151 of file chan_sip.c.

◆ FORMAT2 [4/5]

#define FORMAT2   "%-15.15s %-11.11s %-8.8s %-10.10s %-10.10s ( %%) %-6.6s %-10.10s %-10.10s ( %%) %-6.6s\n"

Definition at line 22151 of file chan_sip.c.

◆ FORMAT2 [5/5]

#define FORMAT2   "%-15.15s %-15.15s %-15.15s %-15.15s %-7.7s %-15.15s %-10.10s %-10.10s\n"

Definition at line 22151 of file chan_sip.c.

◆ FORMAT3

#define FORMAT3   "%-15.15s %-15.15s %-15.15s %-15.15s %-13.13s %-15.15s %-10.10s %-6.6s\n"

Definition at line 22150 of file chan_sip.c.

Referenced by sip_show_channels().

◆ FORMAT4

#define FORMAT4   "%-15.15s %-15.15s %-15.15s %-15.15s %-13.13s %-15.15s %-10.10s %-6.6d\n"

Definition at line 22149 of file chan_sip.c.

Referenced by show_channels_cb().

◆ peer_in_destruction

#define peer_in_destruction (   peer)    (ao2_ref(peer, 0) == 0)

Definition at line 1337 of file chan_sip.c.

Referenced by mwi_event_cb().

◆ PEERS_FORMAT2

#define PEERS_FORMAT2   "%-25.25s %-39.39s %-3.3s %-10.10s %-10.10s %-3.3s %-8s %-11s %-32.32s %s\n"

Definition at line 20280 of file chan_sip.c.

Referenced by _sip_show_peers(), and _sip_show_peers_one().

◆ REMOVE_MAILBOX_WITH_LOCKED_PEER

#define REMOVE_MAILBOX_WITH_LOCKED_PEER (   __peer)

Definition at line 5283 of file chan_sip.c.

Referenced by clear_peer_mailboxes().

◆ SIP_PEDANTIC_DECODE

#define SIP_PEDANTIC_DECODE (   str)
Value:
ast_uri_decode(str, ast_uri_sip_user); \
} \
const char * str
Definition: app_jack.c:147
#define ast_strlen_zero(foo)
Definition: strings.h:52
int pedanticsipchecking
Definition: sip.h:756
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
const struct ast_flags ast_uri_sip_user
Definition: main/utils.c:575

Definition at line 813 of file chan_sip.c.

Referenced by check_user_full(), get_also_info(), get_destination(), get_refer_info(), register_verify(), and sip_msg_send().

◆ sip_pvt_lock

#define sip_pvt_lock (   x)    ao2_lock(x)

◆ sip_pvt_trylock

#define sip_pvt_trylock (   x)    ao2_trylock(x)

Definition at line 1045 of file chan_sip.c.

Referenced by dialog_checkrtp_cb(), dialog_needdestroy(), and forked_invite_init().

◆ sip_pvt_unlock

#define sip_pvt_unlock (   x)    ao2_unlock(x)

Definition at line 1046 of file chan_sip.c.

Referenced by __find_call(), __sched_check_pendings(), __sip_autodestruct(), __sip_cancel_destroy(), __sip_scheddestroy(), __update_provisional_keepalive_full(), auto_congest(), complete_sipch(), dialog_checkrtp_cb(), dialog_needdestroy(), dialog_unlink_all(), do_dialog_unlink_sched_items(), extensionstate_update(), forked_invite_init(), get_refer_info(), get_sip_pvt_from_replaces(), 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(), reinvite_timeout(), retrans_pkt(), send_provisional_keepalive_full(), show_channels_cb(), show_chanstats_cb(), sip_allow_anyrtp_remote(), 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_vrtp_peer(), sip_hangup(), sip_indicate(), sip_monitor_instance_destructor(), sip_msg_send(), 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_sendtext(), sip_set_rtp_peer(), sip_setoption(), sip_show_channel(), sip_show_history(), sip_t38_abort(), sip_transfer(), sip_write(), sipinfo_send(), transmit_publish(), and update_call_counter().

◆ SIP_TRANSPORT_STR_BUFSIZE

#define SIP_TRANSPORT_STR_BUFSIZE   128

Size of the SIP transport buffer.

Definition at line 1076 of file chan_sip.c.

Referenced by get_transport_list().

◆ SIPHEADER

#define SIPHEADER   256

Referenced by initreqprep().

◆ UNLINK

#define UNLINK (   element,
  head,
  prev 
)

some list management macros.

Definition at line 1157 of file chan_sip.c.

Referenced by __sip_ack(), handle_request_cancel(), and retrans_pkt().

Enumeration Type Documentation

◆ match_req_res

Enumerator
SIP_REQ_MATCH 
SIP_REQ_NOT_MATCH 
SIP_REQ_LOOP_DETECTED 
SIP_REQ_FORKED 

Definition at line 9165 of file chan_sip.c.

9165  {
9166  SIP_REQ_MATCH,
9168  SIP_REQ_LOOP_DETECTED, /* multiple incoming requests with same call-id but different branch parameters have been detected */
9169  SIP_REQ_FORKED, /* An outgoing request has been forked as result of receiving two differing 200ok responses. */
9170 };

◆ message_integrity

Indication of a TCP message's integrity.

Enumerator
MESSAGE_INVALID 

The message has an error in it with regards to its Content-Length header

MESSAGE_FRAGMENT 

The message is incomplete

MESSAGE_FRAGMENT_COMPLETE 

The data contains a complete message plus a fragment of another.

MESSAGE_COMPLETE 

The message is complete

Definition at line 2761 of file chan_sip.c.

2761  {
2762  /*!
2763  * The message has an error in it with
2764  * regards to its Content-Length header
2765  */
2767  /*!
2768  * The message is incomplete
2769  */
2771  /*!
2772  * The data contains a complete message
2773  * plus a fragment of another.
2774  */
2776  /*!
2777  * The message is complete
2778  */
2780 };

◆ peer_unlink_flag_t

Enumerator
SIP_PEERS_MARKED 
SIP_PEERS_ALL 

Definition at line 3225 of file chan_sip.c.

3225  {
3227  SIP_PEERS_ALL,
peer_unlink_flag_t
Definition: chan_sip.c:3225

◆ sip_media_fds

Enumerator
SIP_AUDIO_RTP_FD 
SIP_AUDIO_RTCP_FD 
SIP_VIDEO_RTP_FD 
SIP_VIDEO_RTCP_FD 
SIP_TEXT_RTP_FD 
SIP_UDPTL_FD 

Definition at line 7841 of file chan_sip.c.

Function Documentation

◆ __cleanup_registration()

static int __cleanup_registration ( const void *  data)
static

Definition at line 32459 of file chan_sip.c.

References ao2_lock, ao2_t_ref, ao2_unlock, ast_debug, ast_dnsmgr_release(), AST_SCHED_DEL_UNREF, sip_registry::call, dialog_unlink_all(), dialog_unref, sip_registry::dnsmgr, sip_registry::expire, sip_registry::hostname, NULL, sip_registry::timeout, and sip_registry::username.

Referenced by cleanup_registration().

32460 {
32461  struct sip_registry *reg = (struct sip_registry *) data;
32462 
32463  ao2_lock(reg);
32464 
32465  if (reg->call) {
32466  ast_debug(3, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname);
32467  /* This will also remove references to the registry */
32468  dialog_unlink_all(reg->call);
32469  reg->call = dialog_unref(reg->call, "remove iterator->call from registry traversal");
32470  }
32471 
32473  ao2_t_ref(reg, -1, "Stop scheduled reregister timeout"));
32475  ao2_t_ref(reg, -1, "Stop scheduled register timeout"));
32476 
32477  if (reg->dnsmgr) {
32478  ast_dnsmgr_release(reg->dnsmgr);
32479  reg->dnsmgr = NULL;
32480  ao2_t_ref(reg, -1, "reg ptr unref from dnsmgr");
32481  }
32482 
32483  ao2_unlock(reg);
32484 
32485  ao2_t_ref(reg, -1, "cleanup_registration action");
32486  return 0;
32487 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
const ast_string_field hostname
Definition: sip.h:1414
int expire
Definition: sip.h:1418
const ast_string_field username
Definition: sip.h:1414
struct sip_pvt * call
Definition: sip.h:1424
Definition: sched.c:76
Registrations with other SIP proxies.
Definition: sip.h:1396
#define AST_SCHED_DEL_UNREF(sched, id, refcall)
schedule task to get deleted and call unref function
Definition: sched.h:80
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
struct ast_dnsmgr_entry * dnsmgr
Definition: sip.h:1429
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 stor...
Definition: chan_sip.c:3367
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
void ast_dnsmgr_release(struct ast_dnsmgr_entry *entry)
Free a DNS manager entry.
Definition: dnsmgr.c:136
#define ao2_lock(a)
Definition: astobj2.h:718
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
int timeout
Definition: sip.h:1422

◆ __dialog_unlink_sched_items()

static int __dialog_unlink_sched_items ( const void *  data)
static

Definition at line 3351 of file chan_sip.c.

References dialog_unref, and do_dialog_unlink_sched_items().

Referenced by dialog_unlink_all().

3352 {
3353  struct sip_pvt *dialog = (void *) data;
3354 
3356  dialog_unref(dialog, "Stop scheduled items for unlink action");
3357  return 0;
3358 }
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
static void do_dialog_unlink_sched_items(struct sip_pvt *dialog)
Definition: chan_sip.c:3308

◆ __find_call()

static struct sip_pvt * __find_call ( struct sip_request req,
struct ast_sockaddr addr,
const int  intended_method,
const char *  file,
int  line,
const char *  func 
)
static

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

References __ao2_callback(), __ao2_find(), __ao2_ref(), ao2_iterator_destroy(), ao2_iterator_next, args, ast_create_callid(), ast_debug, ast_skip_blanks(), ast_string_field_set, ast_strlen_zero, match_req_args::authentication_present, sip_via::branch, sip_pvt::callid, match_req_args::callid, CAN_CREATE_DIALOG, CAN_CREATE_DIALOG_UNSUPPORTED_METHOD, dialog_find_multiple(), dialog_ref, dialog_unref, forked_invite_init(), free_via(), match_req_args::fromtag, gettag(), sip_request::has_to_tag, match_req_to_dialog(), sip_request::method, sip_pvt::method, match_req_args::method, NULL, OBJ_MULTIPLE, OBJ_POINTER, parse_via(), sip_settings::pedanticsipchecking, REQ_OFFSET_TO_STR, match_req_args::respid, match_req_args::ruri, sip_via::sent_by, match_req_args::seqno, SIP_ACK, sip_alloc, SIP_BYE, sip_cfg, sip_get_header(), SIP_INFO, SIP_INVITE, sip_methods, sip_pvt_lock, sip_pvt_unlock, SIP_REGISTER, SIP_REQ_FORKED, SIP_REQ_LOOP_DETECTED, SIP_REQ_MATCH, SIP_REQ_NOT_MATCH, SIP_RESPONSE, cfsip_methods::text, sip_pvt::theirtag, match_req_args::totag, transmit_response_using_temp(), match_req_args::viabranch, and match_req_args::viasentby.

9471 {
9472  char totag[128];
9473  char fromtag[128];
9474  const char *callid = sip_get_header(req, "Call-ID");
9475  const char *from = sip_get_header(req, "From");
9476  const char *to = sip_get_header(req, "To");
9477  const char *cseq = sip_get_header(req, "Cseq");
9478  struct sip_pvt *sip_pvt_ptr;
9479  uint32_t seqno;
9480  /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */
9481  /* sip_get_header always returns non-NULL so we must use ast_strlen_zero() */
9482  if (ast_strlen_zero(callid) || ast_strlen_zero(to) ||
9483  ast_strlen_zero(from) || ast_strlen_zero(cseq) ||
9484  (sscanf(cseq, "%30u", &seqno) != 1)) {
9485 
9486  /* RFC 3261 section 24.4.1. Send a 400 Bad Request if the request is malformed. */
9487  if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) {
9488  transmit_response_using_temp(callid, addr, 1, intended_method,
9489  req, "400 Bad Request");
9490  }
9491  return NULL; /* Invalid packet */
9492  }
9493 
9495  /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy
9496  we need more to identify a branch - so we have to check branch, from
9497  and to tags to identify a call leg.
9498  For Asterisk to behave correctly, you need to turn on pedanticsipchecking
9499  in sip.conf
9500  */
9501  if (gettag(req, "To", totag, sizeof(totag)))
9502  req->has_to_tag = 1; /* Used in handle_request/response */
9503  gettag(req, "From", fromtag, sizeof(fromtag));
9504 
9505  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);
9506 
9507  /* All messages must always have From: tag */
9508  if (ast_strlen_zero(fromtag)) {
9509  ast_debug(5, "%s request has no from tag, dropping callid: %s from: %s\n", sip_methods[req->method].text , callid, from );
9510  return NULL;
9511  }
9512  /* reject requests that must always have a To: tag */
9513  if (ast_strlen_zero(totag) && (req->method == SIP_ACK || req->method == SIP_BYE || req->method == SIP_INFO )) {
9514  if (req->method != SIP_ACK) {
9515  transmit_response_using_temp(callid, addr, 1, intended_method, req, "481 Call leg/transaction does not exist");
9516  }
9517  ast_debug(5, "%s must have a to tag. dropping callid: %s from: %s\n", sip_methods[req->method].text , callid, from );
9518  return NULL;
9519  }
9520  }
9521 
9522  /* match on callid only for REGISTERs */
9523  if (!sip_cfg.pedanticsipchecking || req->method == SIP_REGISTER) {
9524  struct sip_pvt tmp_dialog = {
9525  .callid = callid,
9526  };
9527  sip_pvt_ptr = __ao2_find(dialogs, &tmp_dialog, OBJ_POINTER,
9528  "find_call in dialogs", file, line, func);
9529  if (sip_pvt_ptr) { /* well, if we don't find it-- what IS in there? */
9530  /* Found the call */
9531  return sip_pvt_ptr;
9532  }
9533  } else { /* in pedantic mode! -- do the fancy search */
9534  struct sip_pvt tmp_dialog = {
9535  .callid = callid,
9536  };
9537  /* if a Outbound forked Request is detected, this pvt will point
9538  * to the dialog the Request is forking off of. */
9539  struct sip_pvt *fork_pvt = NULL;
9540  struct match_req_args args = { 0, };
9541  int found;
9542  struct ao2_iterator *iterator = __ao2_callback(dialogs,
9545  &tmp_dialog,
9546  "pedantic ao2_find in dialogs",
9547  file, line, func);
9548  struct sip_via *via = NULL;
9549 
9550  args.method = req->method;
9551  args.callid = NULL; /* we already matched this. */
9552  args.totag = totag;
9553  args.fromtag = fromtag;
9554  args.seqno = seqno;
9555  /* get via header information. */
9556  args.ruri = REQ_OFFSET_TO_STR(req, rlpart2);
9557  via = parse_via(sip_get_header(req, "Via"));
9558  if (via) {
9559  args.viasentby = via->sent_by;
9560  args.viabranch = via->branch;
9561  }
9562  /* determine if this is a Request with authentication credentials. */
9563  if (!ast_strlen_zero(sip_get_header(req, "Authorization")) ||
9564  !ast_strlen_zero(sip_get_header(req, "Proxy-Authorization"))) {
9565  args.authentication_present = 1;
9566  }
9567  /* if it is a response, get the response code */
9568  if (req->method == SIP_RESPONSE) {
9569  const char* e = ast_skip_blanks(REQ_OFFSET_TO_STR(req, rlpart2));
9570  int respid;
9571  if (!ast_strlen_zero(e) && (sscanf(e, "%30d", &respid) == 1)) {
9572  args.respid = respid;
9573  }
9574  }
9575 
9576  /* Iterate a list of dialogs already matched by Call-id */
9577  while (iterator && (sip_pvt_ptr = ao2_iterator_next(iterator))) {
9578  sip_pvt_lock(sip_pvt_ptr);
9579  found = match_req_to_dialog(sip_pvt_ptr, &args);
9580  sip_pvt_unlock(sip_pvt_ptr);
9581 
9582  switch (found) {
9583  case SIP_REQ_MATCH:
9584  sip_pvt_lock(sip_pvt_ptr);
9585  if (args.method != SIP_RESPONSE && args.authentication_present
9586  && strcmp(args.fromtag, sip_pvt_ptr->theirtag)) {
9587  /* If we have a request that uses athentication and the fromtag is
9588  * different from that in the original call dialog, update the
9589  * fromtag in the saved call dialog */
9590  ast_string_field_set(sip_pvt_ptr, theirtag, args.fromtag);
9591  }
9592  sip_pvt_unlock(sip_pvt_ptr);
9593  ao2_iterator_destroy(iterator);
9594  dialog_unref(fork_pvt, "unref fork_pvt");
9595  free_via(via);
9596  return sip_pvt_ptr; /* return pvt with ref */
9597  case SIP_REQ_LOOP_DETECTED:
9598  /* This is likely a forked Request that somehow resulted in us receiving multiple parts of the fork.
9599  * RFC 3261 section 8.2.2.2, Indicate that we want to merge requests by sending a 482 response. */
9600  transmit_response_using_temp(callid, addr, 1, intended_method, req, "482 (Loop Detected)");
9601  __ao2_ref(sip_pvt_ptr, -1, "pvt did not match incoming SIP msg, unref from search.",
9602  file, line, func);
9603  ao2_iterator_destroy(iterator);
9604  dialog_unref(fork_pvt, "unref fork_pvt");
9605  free_via(via);
9606  return NULL;
9607  case SIP_REQ_FORKED:
9608  dialog_unref(fork_pvt, "throwing way pvt to fork off of.");
9609  fork_pvt = dialog_ref(sip_pvt_ptr, "this pvt has a forked request, save this off to copy information into new dialog\n");
9610  /* fall through */
9611  case SIP_REQ_NOT_MATCH:
9612  default:
9613  __ao2_ref(sip_pvt_ptr, -1, "pvt did not match incoming SIP msg, unref from search",
9614  file, line, func);
9615  break;
9616  }
9617  }
9618  if (iterator) {
9619  ao2_iterator_destroy(iterator);
9620  }
9621 
9622  /* Handle any possible forked requests. This must be done only after transaction matching is complete. */
9623  if (fork_pvt) {
9624  /* XXX right now we only support handling forked INVITE Requests. Any other
9625  * forked request type must be added here. */
9626  if (fork_pvt->method == SIP_INVITE) {
9627  forked_invite_init(req, args.totag, fork_pvt, addr);
9628  dialog_unref(fork_pvt, "throwing way old forked pvt");
9629  free_via(via);
9630  return NULL;
9631  }
9632  fork_pvt = dialog_unref(fork_pvt, "throwing way pvt to fork off of");
9633  }
9634 
9635  free_via(via);
9636  } /* end of pedantic mode Request/Reponse to Dialog matching */
9637 
9638  /* See if the method is capable of creating a dialog */
9639  if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) {
9640  struct sip_pvt *p = NULL;
9642 
9643  if (intended_method == SIP_INVITE) {
9644  logger_callid = ast_create_callid();
9645  }
9646 
9647  /* Ok, time to create a new SIP dialog object, a pvt */
9648  if (!(p = sip_alloc(callid, addr, 1, intended_method, req, logger_callid))) {
9649  /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not
9650  getting a dialog from sip_alloc.
9651 
9652  Without a dialog we can't retransmit and handle ACKs and all that, but at least
9653  send an error message.
9654 
9655  Sorry, we apologize for the inconvienience
9656  */
9657  transmit_response_using_temp(callid, addr, 1, intended_method, req, "500 Server internal error");
9658  ast_debug(4, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n");
9659  }
9660  return p; /* can be NULL */
9661  } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) {
9662  /* A method we do not support, let's take it on the volley */
9663  transmit_response_using_temp(callid, addr, 1, intended_method, req, "501 Method Not Implemented");
9664  ast_debug(2, "Got a request with unsupported SIP method.\n");
9665  } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) {
9666  /* This is a request outside of a dialog that we don't know about */
9667  transmit_response_using_temp(callid, addr, 1, intended_method, req, "481 Call leg/transaction does not exist");
9668  ast_debug(2, "That's odd... Got a request in unknown dialog. Callid %s\n", callid ? callid : "<unknown>");
9669  }
9670  /* We do not respond to responses for dialogs that we don't know about, we just drop
9671  the session quickly */
9672  if (intended_method == SIP_RESPONSE)
9673  ast_debug(2, "That's odd... Got a response on a call we don't know about. Callid %s\n", callid ? callid : "<unknown>");
9674 
9675  return NULL;
9676 }
static struct ao2_container * dialogs
Definition: chan_sip.c:1043
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
Definition: sip.h:626
ast_callid logger_callid
Definition: sip.h:1008
void free_via(struct sip_via *v)
const char * viabranch
Definition: chan_sip.c:9158
const char * ruri
Definition: chan_sip.c:9157
void * __ao2_find(struct ao2_container *c, const void *arg, enum search_flags flags, const char *tag, const char *file, int line, const char *func)
Definition: sip.h:619
static const struct cfsip_methods sip_methods[]
const char * viasentby
Definition: chan_sip.c:9159
#define OBJ_POINTER
Definition: astobj2.h:1154
static const char * gettag(const struct sip_request *req, const char *header, char *tagbuf, int tagbufsize)
Get tag from packet.
Definition: chan_sip.c:25654
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
const ast_string_field from
Definition: sip.h:1063
unsigned int ast_callid
Definition: logger.h:87
static int dialog_find_multiple(void *obj, void *arg, int flags)
Definition: chan_sip.c:34633
void * __ao2_callback(struct ao2_container *c, enum search_flags flags, ao2_callback_fn *cb_fn, void *arg, const char *tag, const char *file, int line, const char *func)
const char * args
Definition: sip.h:621
#define NULL
Definition: resample.c:96
const char * fromtag
Definition: chan_sip.c:9150
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
Structure to store Via information.
Definition: sip.h:874
int __ao2_ref(void *o, int delta, const char *tag, const char *file, int line, const char *func)
Definition: astobj2.c:498
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
int authentication_present
Definition: chan_sip.c:9162
const char * branch
Definition: sip.h:878
const char * totag
Definition: chan_sip.c:9149
#define sip_alloc(callid, addr, useglobal_nat, intended_method, req, logger_callid)
Definition: dialog.h:39
const ast_string_field theirtag
Definition: sip.h:1063
char * via
Definition: sip.h:875
int pedanticsipchecking
Definition: sip.h:756
static enum match_req_res match_req_to_dialog(struct sip_pvt *sip_pvt_ptr, struct match_req_args *arg)
Definition: chan_sip.c:9177
const ast_string_field callid
Definition: sip.h:1063
ast_callid ast_create_callid(void)
factory function to create a new uniquely identifying callid.
Definition: logger.c:1957
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
int method
Definition: sip.h:1009
int method
Definition: sip.h:833
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
#define dialog_ref(dialog, tag)
when we create or delete references, make sure to use these functions so we keep track of the refcoun...
Definition: dialog.h:32
#define REQ_OFFSET_TO_STR(req, offset)
Definition: sip.h:858
char *const text
Definition: chan_sip.c:737
const char * sent_by
Definition: sip.h:877
uint32_t seqno
Definition: chan_sip.c:9151
const char * callid
Definition: chan_sip.c:9148
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
struct sip_via * parse_via(const char *header)
Parse a Via header.
char has_to_tag
Definition: sip.h:838
static void forked_invite_init(struct sip_request *req, const char *new_theirtag, struct sip_pvt *original, struct ast_sockaddr *addr)
This function creates a dialog to handle a forked request. This dialog exists only to properly termin...
Definition: chan_sip.c:9333
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.
Definition: chan_sip.c:12601
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ __get_header()

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

Definition at line 8562 of file chan_sip.c.

References ast_skip_blanks(), find_alias(), sip_request::headers, len(), match(), NULL, and REQ_OFFSET_TO_STR.

Referenced by build_path(), build_route(), copy_all_header(), copy_via_headers(), func_header_read(), handle_incoming(), handle_request_invite(), handle_request_subscribe(), handle_response_register(), parse_register_contact(), reply_digest(), and sip_get_header().

8563 {
8564  /*
8565  * Technically you can place arbitrary whitespace both before and after the ':' in
8566  * a header, although RFC3261 clearly says you shouldn't before, and place just
8567  * one afterwards. If you shouldn't do it, what absolute idiot decided it was
8568  * a good idea to say you can do it, and if you can do it, why in the hell would.
8569  * you say you shouldn't.
8570  */
8571  const char *sname = find_alias(name, NULL);
8572  int x, len = strlen(name), slen = (sname ? 1 : 0);
8573  for (x = *start; x < req->headers; x++) {
8574  const char *header = REQ_OFFSET_TO_STR(req, header[x]);
8575  int smatch = 0, match = !strncasecmp(header, name, len);
8576  if (slen) {
8577  smatch = !strncasecmp(header, sname, slen);
8578  }
8579  if (match || smatch) {
8580  /* skip name */
8581  const char *r = header + (match ? len : slen );
8582  /* HCOLON has optional SP/HTAB; skip past those */
8583  while (*r == ' ' || *r == '\t') {
8584  ++r;
8585  }
8586  if (*r == ':') {
8587  *start = x+1;
8588  return ast_skip_blanks(r+1);
8589  }
8590  }
8591  }
8592 
8593  /* Don't return NULL, so sip_get_header is always a valid pointer */
8594  return "";
8595 }
static const char * find_alias(const char *name, const char *_default)
Find compressed SIP alias.
Definition: chan_sip.c:8534
static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Definition: chan_iax2.c:2315
#define NULL
Definition: resample.c:96
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
int headers
Definition: sip.h:832
static const char name[]
Definition: cdr_mysql.c:74
#define REQ_OFFSET_TO_STR(req, offset)
Definition: sip.h:858

◆ __init_sip_content_buf()

static void __init_sip_content_buf ( void  )
static

Definition at line 8607 of file chan_sip.c.

8611 {

◆ __init_sip_transport_str_buf()

static void __init_sip_transport_str_buf ( void  )
static

A per-thread buffer for transport to string conversion.

Definition at line 1073 of file chan_sip.c.

1157 { \

◆ __init_ts_temp_pvt()

static void __init_ts_temp_pvt ( void  )
static

A per-thread temporary pvt structure.

Definition at line 1070 of file chan_sip.c.

1157 { \

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 35928 of file chan_sip.c.

◆ __sched_check_pendings()

static int __sched_check_pendings ( const void *  data)
static

Definition at line 23785 of file chan_sip.c.

References ast_channel_unlock, ast_channel_unref, check_pendings(), dialog_unref, sip_pvt_lock_full(), and sip_pvt_unlock.

Referenced by sched_check_pendings().

23786 {
23787  struct sip_pvt *pvt = (void *) data;
23788  struct ast_channel *owner;
23789 
23790  owner = sip_pvt_lock_full(pvt);
23791  check_pendings(pvt);
23792  if (owner) {
23793  ast_channel_unlock(owner);
23794  ast_channel_unref(owner);
23795  }
23796  sip_pvt_unlock(pvt);
23797 
23798  dialog_unref(pvt, "Check pending actions action");
23799  return 0;
23800 }
Main Channel structure associated with a channel.
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
static struct ast_channel * sip_pvt_lock_full(struct sip_pvt *pvt)
Definition: chan_sip.c:9400
#define ast_channel_unlock(chan)
Definition: channel.h:2946
static void check_pendings(struct sip_pvt *p)
Check pending actions on SIP call.
Definition: chan_sip.c:23735

◆ __set_address_from_contact()

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

Definition at line 16892 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, AST_TRANSPORT_TLS, get_transport_str2enum(), LOG_WARNING, NULL, parse_uri_legacy_check(), STANDARD_SIP_PORT, and STANDARD_TLS_PORT.

Referenced by build_peer(), create_addr_from_peer(), dialog_initialize_rtp(), set_address_from_contact(), sip_poke_peer(), and sip_request_call().

16893 {
16894  char *hostport, *transport;
16895  char contact_buf[256];
16896  char *contact;
16897 
16898  /* Work on a copy */
16899  ast_copy_string(contact_buf, fullcontact, sizeof(contact_buf));
16900  contact = contact_buf;
16901 
16902  /*
16903  * We have only the part in <brackets> here so we just need to parse a SIP URI.
16904  *
16905  * Note: The outbound proxy could be using UDP between the proxy and Asterisk.
16906  * We still need to be able to send to the remote agent through the proxy.
16907  */
16908 
16909  if (parse_uri_legacy_check(contact, "sip:,sips:", &contact, NULL, &hostport,
16910  &transport)) {
16911  ast_log(LOG_WARNING, "Invalid contact uri %s (missing sip: or sips:), attempting to use anyway\n", fullcontact);
16912  }
16913 
16914  /* XXX This could block for a long time XXX */
16915  /* We should only do this if it's a name, not an IP */
16916  /* \todo - if there's no PORT number in contact - we are required to check NAPTR/SRV records
16917  to find transport, port address and hostname. If there's a port number, we have to
16918  assume that the hostport part is a host name and only look for an A/AAAA record in DNS.
16919  */
16920 
16921  /* If we took in an invalid URI, hostport may not have been initialized */
16922  /* ast_sockaddr_resolve requires an initialized hostport string. */
16923  if (ast_strlen_zero(hostport)) {
16924  ast_log(LOG_WARNING, "Invalid URI: parse_uri failed to acquire hostport\n");
16925  return -1;
16926  }
16927 
16928  if (ast_sockaddr_resolve_first_transport(addr, hostport, 0, get_transport_str2enum(transport))) {
16929  ast_log(LOG_WARNING, "Invalid host name in Contact: (can't "
16930  "resolve in DNS) : '%s'\n", hostport);
16931  return -1;
16932  }
16933 
16934  /* set port */
16935  if (!ast_sockaddr_port(addr)) {
16936  ast_sockaddr_set_port(addr,
16937  (get_transport_str2enum(transport) ==
16939  !strncasecmp(fullcontact, "sips", 4)) ?
16941  }
16942 
16943  return 0;
16944 }
#define LOG_WARNING
Definition: logger.h:274
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:521
#define ast_log
Definition: astobj2.c:42
#define STANDARD_TLS_PORT
Standard SIP TLS port from RFC 3261. DO NOT CHANGE THIS.
Definition: sip.h:178
#define STANDARD_SIP_PORT
Standard SIP unsecure port for UDP and TCP from RFC 3261. DO NOT CHANGE THIS.
Definition: sip.h:176
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:537
static int get_transport_str2enum(const char *transport)
Return int representing a bit field of transport types found in const char *transport.
Definition: chan_sip.c:3658
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
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. ...
Definition: chan_sip.c:34479
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
Definition: chan_sip.c:16880

◆ __shutdown_mwi_subscription()

static int __shutdown_mwi_subscription ( const void *  data)
static

Definition at line 14935 of file chan_sip.c.

References ao2_t_ref, ast_dnsmgr_release(), AST_SCHED_DEL_UNREF, sip_subscription_mwi::dnsmgr, NULL, and sip_subscription_mwi::resub.

Referenced by shutdown_mwi_subscription().

14936 {
14937  struct sip_subscription_mwi *mwi = (void *) data;
14938 
14940  ao2_t_ref(mwi, -1, "Stop scheduled mwi resub"));
14941 
14942  if (mwi->dnsmgr) {
14943  ast_dnsmgr_release(mwi->dnsmgr);
14944  mwi->dnsmgr = NULL;
14945  ao2_t_ref(mwi, -1, "dnsmgr release");
14946  }
14947 
14948  ao2_t_ref(mwi, -1, "Shutdown MWI subscription action");
14949  return 0;
14950 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
Definition: sched.c:76
#define AST_SCHED_DEL_UNREF(sched, id, refcall)
schedule task to get deleted and call unref function
Definition: sched.h:80
#define NULL
Definition: resample.c:96
void ast_dnsmgr_release(struct ast_dnsmgr_entry *entry)
Free a DNS manager entry.
Definition: dnsmgr.c:136
Definition of an MWI subscription to another server.
Definition: sip.h:1454
struct ast_dnsmgr_entry * dnsmgr
Definition: sip.h:1467

◆ __sip_ack()

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

References ao2_t_ref, ast_debug, sip_pvt::callid, FALSE, sip_proxy::force, sip_pkt::is_resp, sip_pkt::method, sip_pkt::next, NULL, sip_pvt::outboundproxy, sip_pvt::packets, sip_pvt::pendinginvite, ref_proxy(), sip_pkt::retransid, sip_pkt::seqno, sipdebug, stop_retrans_pkt(), TRUE, and UNLINK.

Referenced by __sip_pretend_ack(), handle_incoming(), handle_request_invite(), handle_request_publish(), and handle_response().

4571 {
4572  struct sip_pkt *cur, *prev = NULL;
4573  const char *msg = "Not Found"; /* used only for debugging */
4574  int res = FALSE;
4575 
4576  /* If we have an outbound proxy for this dialog, then delete it now since
4577  the rest of the requests in this dialog needs to follow the routing.
4578  If obforcing is set, we will keep the outbound proxy during the whole
4579  dialog, regardless of what the SIP rfc says
4580  */
4581  if (p->outboundproxy && !p->outboundproxy->force) {
4582  ref_proxy(p, NULL);
4583  }
4584 
4585  for (cur = p->packets; cur; prev = cur, cur = cur->next) {
4586  if (cur->seqno != seqno || cur->is_resp != resp) {
4587  continue;
4588  }
4589  if (cur->is_resp || cur->method == sipmethod) {
4590  res = TRUE;
4591  msg = "Found";
4592  if (!resp && (seqno == p->pendinginvite)) {
4593  ast_debug(1, "Acked pending invite %u\n", p->pendinginvite);
4594  p->pendinginvite = 0;
4595  }
4596  if (cur->retransid > -1) {
4597  if (sipdebug)
4598  ast_debug(4, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid);
4599  }
4600 
4601  /* Unlink and destroy the packet object. */
4602  UNLINK(cur, p->packets, prev);
4603  stop_retrans_pkt(cur);
4604  ao2_t_ref(cur, -1, "Packet retransmission list");
4605  break;
4606  }
4607  }
4608  ast_debug(1, "Stopping retransmission on '%s' of %s %u: Match %s\n",
4609  p->callid, resp ? "Response" : "Request", seqno, msg);
4610  return res;
4611 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
sip packet - raw format for outbound packets that are sent or scheduled for transmission Packets are ...
Definition: sip.h:1231
int force
Definition: sip.h:727
#define FALSE
Definition: app_minivm.c:521
int method
Definition: sip.h:1234
static void stop_retrans_pkt(struct sip_pkt *pkt)
Definition: chan_sip.c:4251
uint32_t pendinginvite
Definition: sip.h:1147
uint32_t seqno
Definition: sip.h:1235
int retransid
Definition: sip.h:1240
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
sipmethod
SIP Request methods known by Asterisk.
Definition: sip.h:612
const ast_string_field callid
Definition: sip.h:1063
char is_resp
Definition: sip.h:1236
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
struct sip_pkt * next
Definition: sip.h:1232
struct sip_pkt * packets
Definition: sip.h:1177
static void ref_proxy(struct sip_pvt *pvt, struct sip_proxy *proxy)
maintain proper refcounts for a sip_pvt&#39;s outboundproxy
Definition: chan_sip.c:3293
#define UNLINK(element, head, prev)
Definition: chan_sip.c:1157
#define TRUE
Definition: app_minivm.c:518
struct sip_proxy * outboundproxy
Definition: sip.h:1112

◆ __sip_alloc()

struct sip_pvt* __sip_alloc ( ast_string_field  callid,
struct ast_sockaddr addr,
int  useglobal_nat,
const int  intended_method,
struct sip_request req,
ast_callid  logger_callid,
const char *  file,
int  line,
const char *  func 
)

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

References __ao2_alloc(), sip_pvt::allowed_methods, sip_settings::allowtransfer, sip_pvt::allowtransfer, AO2_ALLOC_OPT_LOCK_MUTEX, ao2_cleanup, ao2_t_link, ao2_t_ref, ast_cc_config_params_init, ast_copy_flags, ast_copy_string(), ast_debug, ast_format_cap_alloc, ast_format_cap_append_from_cap(), AST_FORMAT_CAP_FLAG_DEFAULT, AST_LIST_HEAD_INIT_NOLOCK, AST_MEDIA_TYPE_UNKNOWN, 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, AST_TRANSPORT_UDP, sip_pvt::autoframing, sip_pvt::autokillid, sip_via::branch, sip_pvt::branch, build_callid_pvt(), build_via(), sip_pvt::callid, sip_settings::caps, sip_pvt::caps, sip_pvt::cc_params, check_via(), context, sip_settings::default_context, default_engine, default_fromdomain, default_fromdomainport, sip_settings::default_max_forwards, default_maxcallbitrate, default_mohinterpret, default_mohsuggest, default_parkinglot, default_zone, sip_pvt::do_history, do_setnat(), sip_socket::fd, sip_pvt::flags, free_via(), sip_pvt::fromdomainport, global_autoframing, global_t1, global_timer_b, sip_pvt::init_icseq, INITIAL_CSEQ, sip_pvt::initid, internip, sip_pvt::jointcaps, make_our_tag(), sip_pvt::maxcallbitrate, sip_pvt::maxforwards, sip_pvt::method, mohinterpret, mohsuggest, sip_pvt::noncodeccapability, NONE, NULL, sip_pvt::ocseq, sip_pvt::offered_media, sip_pvt::ourip, parkinglot, parse_via(), sip_pvt::peercaps, sip_pvt::prefcaps, sip_pvt::provisional_keepalive_sched_id, recordhistory, sip_pvt::recv, sip_pvt::redircaps, sip_pvt::reinviteid, sip_pvt::request_queue, sip_pvt::request_queue_sched_id, sip_pvt::rtp, sip_pvt::sa, sip_via::sent_by, sip_pvt::session_modify, sip_pvt::sessionversion_remote, set_socket_transport(), sip_cfg, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, sip_get_header(), sip_methods, SIP_OPTIONS, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE3_FLAGS_TO_COPY, sip_pvt_callid_set(), sip_pvt_dtor(), SIP_REGISTER, sip_request::socket, sip_pvt::socket, sip_pvt::stateid, sip_pvt::stimer, sip_pvt::subscribed, sip_pvt::t38id, cfsip_methods::text, sip_pvt::timer_b, sip_pvt::timer_t1, TRUE, sip_socket::type, sip_pvt::waitid, and sip_pvt::zone.

8945 {
8946  struct sip_pvt *p;
8947 
8948  p = __ao2_alloc(sizeof(*p), sip_pvt_dtor,
8949  AO2_ALLOC_OPT_LOCK_MUTEX, "allocate a dialog(pvt) struct",
8950  file, line, func);
8951  if (!p) {
8952  return NULL;
8953  }
8954 
8955  if (ast_string_field_init(p, 512)) {
8956  ao2_t_ref(p, -1, "failed to string_field_init, drop p");
8957  return NULL;
8958  }
8959 
8960  if (!(p->cc_params = ast_cc_config_params_init())) {
8961  ao2_t_ref(p, -1, "Yuck, couldn't allocate cc_params struct. Get rid o' p");
8962  return NULL;
8963  }
8964 
8965  if (logger_callid) {
8967  }
8968 
8974 
8975  if (!p->caps|| !p->jointcaps || !p->peercaps || !p->redircaps || !p->prefcaps) {
8976  ao2_cleanup(p->caps);
8977  ao2_cleanup(p->jointcaps);
8978  ao2_cleanup(p->peercaps);
8979  ao2_cleanup(p->redircaps);
8980  ao2_cleanup(p->prefcaps);
8981  ao2_t_ref(p, -1, "Yuck, couldn't allocate format capabilities. Get rid o' p");
8982  return NULL;
8983  }
8984 
8985 
8986  /* If this dialog is created as a result of a request or response, lets store
8987  * some information about it in the dialog. */
8988  if (req) {
8989  struct sip_via *via;
8990  const char *cseq = sip_get_header(req, "Cseq");
8991  uint32_t seqno;
8992 
8993  /* get branch parameter from initial Request that started this dialog */
8994  via = parse_via(sip_get_header(req, "Via"));
8995  if (via) {
8996  /* only store the branch if it begins with the magic prefix "z9hG4bK", otherwise
8997  * it is not useful to us to have it */
8998  if (!ast_strlen_zero(via->branch) && !strncasecmp(via->branch, "z9hG4bK", 7)) {
8999  ast_string_field_set(p, initviabranch, via->branch);
9000  ast_string_field_set(p, initviasentby, via->sent_by);
9001  }
9002  free_via(via);
9003  }
9004 
9005  /* Store initial incoming cseq. An error in sscanf here is ignored. There is no approperiate
9006  * except not storing the number. CSeq validation must take place before dialog creation in find_call */
9007  if (!ast_strlen_zero(cseq) && (sscanf(cseq, "%30u", &seqno) == 1)) {
9008  p->init_icseq = seqno;
9009  }
9010  /* Later in ast_sip_ouraddrfor we need this to choose the right ip and port for the specific transport */
9012  } else {
9014  }
9015 
9016  p->socket.fd = -1;
9017  p->method = intended_method;
9018  p->initid = -1;
9019  p->waitid = -1;
9020  p->reinviteid = -1;
9021  p->autokillid = -1;
9022  p->request_queue_sched_id = -1;
9024  p->t38id = -1;
9025  p->subscribed = NONE;
9026  p->stateid = -1;
9027  p->sessionversion_remote = -1;
9028  p->session_modify = TRUE;
9029  p->stimer = NULL;
9030  ast_copy_string(p->zone, default_zone, sizeof(p->zone));
9032 
9033  if (intended_method != SIP_OPTIONS) { /* Peerpoke has it's own system */
9034  p->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */
9035  p->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */
9036  }
9037 
9038  if (!addr) {
9039  p->ourip = internip;
9040  } else {
9041  ast_sockaddr_copy(&p->sa, addr);
9042  ast_sip_ouraddrfor(&p->sa, &p->ourip, p);
9043  }
9044 
9045  /* Copy global flags to this PVT at setup. */
9049 
9051 
9052  p->branch = ast_random();
9053  make_our_tag(p);
9054  p->ocseq = INITIAL_CSEQ;
9055  p->allowed_methods = UINT_MAX;
9056 
9057  if (sip_methods[intended_method].need_rtp) {
9060  }
9061 
9062  if (useglobal_nat && addr) {
9063  /* Setup NAT structure according to global settings if we have an address */
9064  ast_sockaddr_copy(&p->recv, addr);
9065  check_via(p, req);
9066  do_setnat(p);
9067  }
9068 
9069  if (p->method != SIP_REGISTER) {
9070  ast_string_field_set(p, fromdomain, default_fromdomain);
9072  }
9073  build_via(p);
9074  if (!callid)
9075  build_callid_pvt(p);
9076  else
9077  ast_string_field_set(p, callid, callid);
9078  /* Assign default music on hold class */
9083  if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
9084  (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) {
9086  }
9090 
9093 
9094  /* Add to active dialog list */
9095 
9096  ao2_t_link(dialogs, p, "link pvt into dialogs table");
9097 
9098  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");
9099  return p;
9100 }
static struct ao2_container * dialogs
Definition: chan_sip.c:1043
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
ast_callid logger_callid
Definition: sip.h:1008
struct ast_format_cap * peercaps
Definition: sip.h:1101
struct ast_cc_config_params * cc_params
Definition: sip.h:1218
static char mohinterpret[MAX_MUSICCLASS]
Definition: chan_alsa.c:119
uint32_t init_icseq
Definition: sip.h:1069
struct ast_format_cap * prefcaps
Definition: sip.h:1103
enum subscriptiontype subscribed
Definition: sip.h:1161
int fromdomainport
Definition: sip.h:1220
unsigned int allowed_methods
Definition: sip.h:1196
void free_via(struct sip_via *v)
static char parkinglot[AST_MAX_CONTEXT]
Definition: chan_mgcp.c:163
int64_t sessionversion_remote
Definition: sip.h:1123
static void build_via(struct sip_pvt *p)
Build a Via header for a request.
Definition: chan_sip.c:3847
int maxcallbitrate
Definition: sip.h:1106
#define ast_test_flag(p, flag)
Definition: utils.h:63
static const struct cfsip_methods sip_methods[]
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:171
#define NONE
Definition: misdn_config.c:45
int autokillid
Definition: sip.h:1158
int reinviteid
Definition: sip.h:1157
static void check_via(struct sip_pvt *p, const struct sip_request *req)
check Via: header for hostname, port and rport request/answer
Definition: chan_sip.c:19164
struct ast_sockaddr recv
Definition: sip.h:1135
int initid
Definition: sip.h:1155
struct sip_socket socket
Definition: sip.h:1066
#define SIP_DTMF_RFC2833
Definition: sip.h:276
void * __ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options, const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result
Definition: astobj2.c:765
struct ast_sockaddr ourip
Definition: sip.h:1136
#define ao2_t_link(container, obj, tag)
Add an object to a container.
Definition: astobj2.h:1547
static struct ast_sockaddr internip
our (internal) default address/port to put in SIP/SDP messages internip is initialized picking a suit...
Definition: chan_sip.c:1114
struct ast_format_cap * jointcaps
Definition: sip.h:1100
static char default_fromdomain[AST_MAX_EXTENSION]
Definition: chan_sip.c:793
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?
Definition: chan_sip.c:3866
struct ast_flags flags[3]
Definition: sip.h:1075
#define ast_copy_flags(dest, src, flagz)
Definition: utils.h:84
#define NULL
Definition: resample.c:96
int provisional_keepalive_sched_id
Definition: sip.h:1109
static int default_maxcallbitrate
Definition: chan_sip.c:804
#define ast_cc_config_params_init()
Allocate and initialize an ast_cc_config_params structure.
Definition: ccss.h:135
int fd
Definition: sip.h:799
int request_queue_sched_id
Definition: sip.h:1108
static void make_our_tag(struct sip_pvt *pvt)
Make our SIP dialog tag.
Definition: chan_sip.c:8908
enum transfermodes allowtransfer
Definition: sip.h:776
#define ast_strlen_zero(foo)
Definition: strings.h:52
Structure to store Via information.
Definition: sip.h:874
char zone[MAX_TONEZONE_COUNTRY]
Definition: sip.h:1116
struct ast_sockaddr sa
Definition: sip.h:1125
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static void sip_pvt_callid_set(struct sip_pvt *pvt, ast_callid callid)
Definition: chan_sip.c:8933
int noncodeccapability
Definition: sip.h:1104
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:353
struct ast_format_cap * caps
Definition: sip.h:1099
static char default_zone[MAX_TONEZONE_COUNTRY]
Definition: chan_sip.c:805
static char mohsuggest[MAX_MUSICCLASS]
Definition: chan_iax2.c:430
long branch
Definition: sip.h:1121
const char * branch
Definition: sip.h:878
long int ast_random(void)
Definition: main/utils.c:2064
#define SIP_PAGE3_FLAGS_TO_COPY
Definition: sip.h:396
unsigned short autoframing
Definition: sip.h:1089
int maxforwards
Definition: sip.h:1065
char * via
Definition: sip.h:875
int default_max_forwards
Definition: sip.h:789
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
#define SIP_PAGE2_FLAGS_TO_COPY
Definition: sip.h:375
int waitid
Definition: sip.h:1156
const ast_string_field callid
Definition: sip.h:1063
static unsigned int recordhistory
Definition: chan_sip.c:841
struct ast_format_cap * redircaps
Definition: sip.h:1102
struct sip_st_dlg * stimer
Definition: sip.h:1184
static char default_parkinglot[AST_MAX_CONTEXT]
Definition: chan_sip.c:802
int method
Definition: sip.h:1009
static struct ast_flags global_flags[3]
Definition: chan_sip.c:884
int timer_b
Definition: sip.h:1096
uint32_t ocseq
Definition: sip.h:1067
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
static char default_mohsuggest[MAX_MUSICCLASS]
Definition: chan_sip.c:800
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
static int global_timer_b
Definition: chan_sip.c:849
int stateid
Definition: sip.h:1162
#define SIP_FLAGS_TO_COPY
Flags to copy from peer/user to dialog.
Definition: sip.h:313
unsigned short do_history
Definition: sip.h:1078
int timer_t1
Definition: sip.h:1095
static unsigned int global_autoframing
Definition: chan_sip.c:850
#define INITIAL_CSEQ
Definition: sip.h:117
struct ast_rtp_instance * rtp
Definition: sip.h:1174
static char default_engine[256]
Definition: chan_sip.c:803
struct ast_format_cap * caps
Global list of addresses dynamic peers are not allowed to use.
Definition: sip.h:787
static void build_callid_pvt(struct sip_pvt *pvt)
Build SIP Call-ID value for a non-REGISTER transaction.
Definition: chan_sip.c:8829
static void do_setnat(struct sip_pvt *p)
Set nat mode on the various data sockets.
Definition: chan_sip.c:5862
char *const text
Definition: chan_sip.c:737
const char * sent_by
Definition: sip.h:877
struct sip_pvt::request_queue request_queue
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:680
enum transfermodes allowtransfer
Definition: sip.h:1137
#define SIP_DTMF
Definition: sip.h:275
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
enum ast_transport type
Definition: sip.h:798
static char default_mohinterpret[MAX_MUSICCLASS]
Definition: chan_sip.c:799
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static int default_fromdomainport
Definition: chan_sip.c:794
#define TRUE
Definition: app_minivm.c:518
static int global_t1
Definition: chan_sip.c:847
unsigned short session_modify
Definition: sip.h:1087
struct sip_via * parse_via(const char *header)
Parse a Via header.
struct sip_socket socket
Definition: sip.h:846
int ast_format_cap_append_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type)
Append the formats of provided type in src to dst.
Definition: format_cap.c:269
static void set_socket_transport(struct sip_socket *socket, int transport)
Definition: chan_sip.c:16629
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
struct sip_pvt::@174 offered_media
#define AST_RTP_DTMF
Definition: rtp_engine.h:266
char default_context[AST_MAX_CONTEXT]
Definition: sip.h:782
static void sip_pvt_dtor(void *vdoomed)
ao2 destructor for SIP dialog structure
Definition: chan_sip.c:6673
#define SIP_DTMF_AUTO
Definition: sip.h:279
int t38id
Definition: sip.h:1159
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ __sip_autodestruct()

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

References __sip_pretend_ack(), sip_pvt::alreadygone, append_history, AST_CAUSE_PROTOCOL_ERROR, ast_channel_name(), ast_channel_unlock, ast_channel_unref, ast_debug, AST_EXTENSION_DEACTIVATED, ast_log, ast_queue_hangup_with_cause(), sip_pvt::autokillid, CALL_COMPLETION, sip_pvt::callid, DEFAULT_TRANS_TIMEOUT, dialog_unlink_all(), dialog_unref, sip_pvt::lastmsg, LOG_WARNING, sip_pvt::method, method_match(), MWI_NOTIFICATION, sip_pvt::needdestroy, NONE, sip_pvt::ongoing_reinvite, sip_pvt::packets, pvt_set_needdestroy(), sip_pvt::refer, SIP_BYE, SIP_CANCEL, sip_methods, sip_pvt_lock_full(), sip_pvt_unlock, sip_scheddestroy(), state_notify_data::state, stop_media_flows(), sip_pvt::subscribed, cfsip_methods::text, transmit_request_with_auth(), transmit_state_notify(), TRUE, and XMIT_RELIABLE.

Referenced by __sip_scheddestroy(), and sip_show_sched().

4370 {
4371  struct sip_pvt *p = (struct sip_pvt *)data;
4372  struct ast_channel *owner;
4373 
4374  /* If this is a subscription, tell the phone that we got a timeout */
4376  struct state_notify_data data = { 0, };
4377 
4379 
4380  transmit_state_notify(p, &data, 1, TRUE); /* Send last notification */
4381  p->subscribed = NONE;
4382  append_history(p, "Subscribestatus", "timeout");
4383  ast_debug(3, "Re-scheduled destruction of SIP subscription %s\n", p->callid ? p->callid : "<unknown>");
4384  return 10000; /* Reschedule this destruction so that we know that it's gone */
4385  }
4386 
4387  /* If there are packets still waiting for delivery, delay the destruction */
4388  if (p->packets) {
4389  if (!p->needdestroy) {
4390  char method_str[31];
4391 
4392  ast_debug(3, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>");
4393  append_history(p, "ReliableXmit", "timeout");
4394  if (sscanf(p->lastmsg, "Tx: %30s", method_str) == 1 || sscanf(p->lastmsg, "Rx: %30s", method_str) == 1) {
4395  if (p->ongoing_reinvite || method_match(SIP_CANCEL, method_str) || method_match(SIP_BYE, method_str)) {
4396  pvt_set_needdestroy(p, "autodestruct");
4397  }
4398  }
4399  return 10000;
4400  } else {
4401  /* They've had their chance to respond. Time to bail */
4402  __sip_pretend_ack(p);
4403  }
4404  }
4405 
4406  /*
4407  * Lock both the pvt and the channel safely so that we can queue up a frame.
4408  */
4409  owner = sip_pvt_lock_full(p);
4410  if (owner) {
4412  "Autodestruct on dialog '%s' with owner %s in place (Method: %s). Rescheduling destruction for 10000 ms\n",
4413  p->callid, ast_channel_name(owner), sip_methods[p->method].text);
4415  ast_channel_unlock(owner);
4416  ast_channel_unref(owner);
4417  sip_pvt_unlock(p);
4418  return 10000;
4419  }
4420 
4421  /* Reset schedule ID */
4422  p->autokillid = -1;
4423 
4424  if (p->refer && !p->alreadygone) {
4425  ast_debug(3, "Finally hanging up channel after transfer: %s\n", p->callid);
4426  stop_media_flows(p);
4428  append_history(p, "ReferBYE", "Sending BYE on transferer call leg %s", p->callid);
4430  sip_pvt_unlock(p);
4431  } else {
4432  append_history(p, "AutoDestroy", "%s", p->callid);
4433  ast_debug(3, "Auto destroying SIP dialog '%s'\n", p->callid);
4434  sip_pvt_unlock(p);
4435  dialog_unlink_all(p); /* once it's unlinked and unrefd everywhere, it'll be freed automagically */
4436  }
4437 
4438  dialog_unref(p, "autokillid complete");
4439 
4440  return 0;
4441 }
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.
Definition: chan_sip.c:16564
#define AST_CAUSE_PROTOCOL_ERROR
Definition: causes.h:144
Main Channel structure associated with a channel.
enum subscriptiontype subscribed
Definition: sip.h:1161
void __sip_pretend_ack(struct sip_pvt *p)
Pretend to ack all packets called with p locked.
Definition: chan_sip.c:4615
char lastmsg[256]
Definition: sip.h:1145
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
static const struct cfsip_methods sip_methods[]
#define NONE
Definition: misdn_config.c:45
int autokillid
Definition: sip.h:1158
#define LOG_WARNING
Definition: logger.h:274
#define DEFAULT_TRANS_TIMEOUT
Definition: sip.h:107
unsigned short needdestroy
Definition: sip.h:1080
static int method_match(enum sipmethod id, const char *name)
returns true if &#39;name&#39; (with optional trailing whitespace) matches the sip method &#39;id&#39;...
Definition: chan_sip.c:3584
unsigned int ongoing_reinvite
Definition: sip.h:1144
Definition: sip.h:621
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
Queue a hangup frame with hangupcause set.
Definition: channel.c:1166
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 stor...
Definition: chan_sip.c:3367
unsigned short alreadygone
Definition: sip.h:1079
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
const ast_string_field callid
Definition: sip.h:1063
static void pvt_set_needdestroy(struct sip_pvt *pvt, const char *reason)
Definition: chan_sip.c:3429
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
int method
Definition: sip.h:1009
static void stop_media_flows(struct sip_pvt *p)
Immediately stop RTP, VRTP and UDPTL as applicable.
Definition: chan_sip.c:25156
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
static struct ast_channel * sip_pvt_lock_full(struct sip_pvt *pvt)
Definition: chan_sip.c:9400
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct sip_pkt * packets
Definition: sip.h:1177
char *const text
Definition: chan_sip.c:737
struct sip_refer * refer
Definition: sip.h:1160
static int transmit_state_notify(struct sip_pvt *p, struct state_notify_data *data, int full, int timeout)
Used in the SUBSCRIBE notification subsystem (RFC3265)
Definition: chan_sip.c:15477
const char * ast_channel_name(const struct ast_channel *chan)
#define TRUE
Definition: app_minivm.c:518
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406
void sip_scheddestroy(struct sip_pvt *p, int ms)
Schedule destruction of SIP dialog.
Definition: chan_sip.c:4549

◆ __sip_cancel_destroy()

static int __sip_cancel_destroy ( const void *  data)
static

Definition at line 4453 of file chan_sip.c.

References dialog_unref, do_cancel_destroy(), sip_pvt_lock, and sip_pvt_unlock.

Referenced by sip_cancel_destroy().

4454 {
4455  struct sip_pvt *pvt = (void *) data;
4456 
4457  sip_pvt_lock(pvt);
4458  do_cancel_destroy(pvt);
4459  sip_pvt_unlock(pvt);
4460  dialog_unref(pvt, "Cancel destroy action");
4461  return 0;
4462 }
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
static void do_cancel_destroy(struct sip_pvt *pvt)
Definition: chan_sip.c:4443
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005

◆ __sip_do_register()

static int __sip_do_register ( struct sip_registry r)
static

Register with SIP proxy.

Returns
see __sip_xmit

Definition at line 15909 of file chan_sip.c.

References NULL, SIP_REGISTER, and transmit_register().

Referenced by sip_reregister().

15910 {
15911  int res;
15912 
15914  return res;
15915 }
#define NULL
Definition: resample.c:96
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()) ...
Definition: chan_sip.c:16106

◆ __sip_pretend_ack()

void __sip_pretend_ack ( struct sip_pvt p)

Pretend to ack all packets called with p locked.

Definition at line 4615 of file chan_sip.c.

References __sip_ack(), ast_log, ast_str_buffer(), sip_pkt::data, find_sip_method(), sip_pkt::is_resp, LOG_WARNING, sip_pkt::method, method, NULL, sip_pvt::packets, sip_pkt::seqno, sip_methods, and cfsip_methods::text.

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

4616 {
4617  struct sip_pkt *cur = NULL;
4618 
4619  while (p->packets) {
4620  int method;
4621  if (cur == p->packets) {
4622  ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text);
4623  return;
4624  }
4625  cur = p->packets;
4626  method = (cur->method) ? cur->method : find_sip_method(ast_str_buffer(cur->data));
4627  __sip_ack(p, cur->seqno, cur->is_resp, method);
4628  }
4629 }
sip packet - raw format for outbound packets that are sent or scheduled for transmission Packets are ...
Definition: sip.h:1231
int method
Definition: sip.h:1234
static const struct cfsip_methods sip_methods[]
#define LOG_WARNING
Definition: logger.h:274
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
uint32_t seqno
Definition: sip.h:1235
#define NULL
Definition: resample.c:96
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: chan_sip.c:4570
#define ast_log
Definition: astobj2.c:42
const char * method
Definition: res_pjsip.c:4335
struct ast_str * data
Definition: sip.h:1246
char is_resp
Definition: sip.h:1236
struct sip_pkt * packets
Definition: sip.h:1177
static int find_sip_method(const char *msg)
find_sip_method: Find SIP method from header
Definition: chan_sip.c:3594
char *const text
Definition: chan_sip.c:737

◆ __sip_reliable_xmit()

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

References __sip_xmit(), AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_t_ref, append_history, ast_debug, AST_FAILURE, ast_log, AST_PTHREADT_NULL, ast_sched_add_variable(), ast_str_buffer(), ast_str_create, ast_str_set(), ast_str_strlen(), AST_SUCCESS, AST_TRANSPORT_UDP, ast_tvnow(), sip_pkt::data, DEFAULT_RETRANS, DEFAULT_TIMER_T1, dialog_ref, sip_pkt::is_fatal, sip_pkt::is_resp, LOG_ERROR, sip_pkt::method, monitor_thread, sip_pkt::next, NULL, sip_pkt::owner, sip_pvt::packets, sip_pvt::pendinginvite, sip_pkt::response_code, retrans_pkt(), sip_pkt::retrans_stop, sip_pkt::retrans_stop_time, sip_pkt::retransid, sip_pkt::seqno, SIP_INVITE, sip_pkt_dtor(), sipdebug, sip_pvt::socket, stop_retrans_pkt(), sip_pkt::time_sent, sip_pvt::timer_t1, sip_pkt::timer_t1, sip_socket::type, and XMIT_ERROR.

Referenced by send_request(), and send_response().

4276 {
4277  struct sip_pkt *pkt = NULL;
4278  int siptimer_a = DEFAULT_RETRANS;
4279  int xmitres = 0;
4280  unsigned respid;
4281 
4282  if (sipmethod == SIP_INVITE) {
4283  /* Note this is a pending invite */
4284  p->pendinginvite = seqno;
4285  }
4286 
4288  if (!pkt) {
4289  return AST_FAILURE;
4290  }
4291  /* copy data, add a terminator and save length */
4292  pkt->data = ast_str_create(ast_str_strlen(data));
4293  if (!pkt->data) {
4294  ao2_t_ref(pkt, -1, "Failed to initialize");
4295  return AST_FAILURE;
4296  }
4297  ast_str_set(&pkt->data, 0, "%s%s", ast_str_buffer(data), "\0");
4298  /* copy other parameters from the caller */
4299  pkt->method = sipmethod;
4300  pkt->seqno = seqno;
4301  pkt->is_resp = resp;
4302  pkt->is_fatal = fatal;
4303  pkt->owner = dialog_ref(p, "__sip_reliable_xmit: setting pkt->owner");
4304 
4305  /* The retransmission list owns a pkt ref */
4306  pkt->next = p->packets;
4307  p->packets = pkt; /* Add it to the queue */
4308 
4309  if (resp) {
4310  /* Parse out the response code */
4311  if (sscanf(ast_str_buffer(pkt->data), "SIP/2.0 %30u", &respid) == 1) {
4312  pkt->response_code = respid;
4313  }
4314  }
4315  pkt->timer_t1 = p->timer_t1; /* Set SIP timer T1 */
4316  if (pkt->timer_t1) {
4317  siptimer_a = pkt->timer_t1;
4318  }
4319 
4320  pkt->time_sent = ast_tvnow(); /* time packet was sent */
4321  pkt->retrans_stop_time = 64 * (pkt->timer_t1 ? pkt->timer_t1 : DEFAULT_TIMER_T1); /* time in ms after pkt->time_sent to stop retransmission */
4322 
4323  if (!(p->socket.type & AST_TRANSPORT_UDP)) {
4324  /* TCP does not need retransmits as that's built in, but with
4325  * retrans_stop set, we must give it the full timer_H treatment */
4326  pkt->retrans_stop = 1;
4327  siptimer_a = pkt->retrans_stop_time;
4328  }
4329 
4330  /* Schedule retransmission */
4331  ao2_t_ref(pkt, +1, "Schedule packet retransmission");
4332  pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1);
4333  if (pkt->retransid < 0) {
4334  ao2_t_ref(pkt, -1, "Failed to schedule packet retransmission");
4335  }
4336 
4337  if (sipdebug) {
4338  ast_debug(4, "*** SIP TIMER: Initializing retransmit timer on packet: Id #%d\n", pkt->retransid);
4339  }
4340 
4341  xmitres = __sip_xmit(pkt->owner, pkt->data); /* Send packet */
4342 
4343  if (xmitres == XMIT_ERROR) { /* Serious network trouble, no need to try again */
4344  append_history(pkt->owner, "XmitErr", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)");
4345  ast_log(LOG_ERROR, "Serious Network Trouble; __sip_xmit returns error for pkt data\n");
4346 
4347  /* Unlink and destroy the packet object. */
4348  p->packets = pkt->next;
4349  stop_retrans_pkt(pkt);
4350  ao2_t_ref(pkt, -1, "Packet retransmission list");
4351  return AST_FAILURE;
4352  } else {
4353  /* This is odd, but since the retrans timer starts at 500ms and the do_monitor thread
4354  * only wakes up every 1000ms by default, we have to poke the thread here to make
4355  * sure it successfully detects this must be retransmitted in less time than
4356  * it usually sleeps for. Otherwise it might not retransmit this packet for 1000ms. */
4358  pthread_kill(monitor_thread, SIGURG);
4359  }
4360  return AST_SUCCESS;
4361  }
4362 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
sip packet - raw format for outbound packets that are sent or scheduled for transmission Packets are ...
Definition: sip.h:1231
struct sip_pvt * owner
Definition: sip.h:1239
int method
Definition: sip.h:1234
static void stop_retrans_pkt(struct sip_pkt *pkt)
Definition: chan_sip.c:4251
int response_code
Definition: sip.h:1238
uint32_t pendinginvite
Definition: sip.h:1147
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
struct sip_socket socket
Definition: sip.h:1066
uint32_t seqno
Definition: sip.h:1235
int retransid
Definition: sip.h:1240
Definition: sched.c:76
int ast_sched_add_variable(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data, int variable) attribute_warn_unused_result
Adds a scheduled event with rescheduling support.
Definition: sched.c:524
int timer_t1
Definition: sip.h:1242
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:406
#define NULL
Definition: resample.c:96
static int retrans_pkt(const void *data)
Retransmit SIP message if no answer.
Definition: chan_sip.c:4041
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define AST_PTHREADT_NULL
Definition: lock.h:66
static int __sip_xmit(struct sip_pvt *p, struct ast_str *data)
Definition: chan_sip.c:3801
sipmethod
SIP Request methods known by Asterisk.
Definition: sip.h:612
static void sip_pkt_dtor(void *vdoomed)
Definition: chan_sip.c:4260
struct ast_str * data
Definition: sip.h:1246
int64_t retrans_stop_time
Definition: sip.h:1244
#define XMIT_ERROR
Definition: sip.h:58
#define LOG_ERROR
Definition: logger.h:285
#define DEFAULT_RETRANS
Definition: chan_mgcp.c:126
char is_resp
Definition: sip.h:1236
int retrans_stop
Definition: sip.h:1245
struct timeval time_sent
Definition: sip.h:1243
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
struct sip_pkt * next
Definition: sip.h:1232
int timer_t1
Definition: sip.h:1095
#define dialog_ref(dialog, tag)
when we create or delete references, make sure to use these functions so we keep track of the refcoun...
Definition: dialog.h:32
struct sip_pkt * packets
Definition: sip.h:1177
#define DEFAULT_TIMER_T1
Definition: sip.h:101
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
enum ast_transport type
Definition: sip.h:798
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406
char is_fatal
Definition: sip.h:1237
static pthread_t monitor_thread
This is the thread for the monitor which checks for input on the channels which are not currently in ...
Definition: chan_sip.c:903
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ __sip_scheddestroy()

static int __sip_scheddestroy ( const void *  data)
static

Definition at line 4484 of file chan_sip.c.

References __sip_autodestruct(), append_history, ast_free, ast_sched_add(), sip_pvt::autokillid, dialog_ref, dialog_unref, do_cancel_destroy(), sip_pvt::do_history, sip_scheddestroy_data::ms, sip_scheddestroy_data::pvt, sip_pvt_lock, sip_pvt_unlock, sip_pvt::stimer, and stop_session_timer().

Referenced by sip_scheddestroy_full().

4485 {
4486  struct sip_scheddestroy_data *sched_data = (void *) data;
4487  struct sip_pvt *pvt = sched_data->pvt;
4488  int ms = sched_data->ms;
4489 
4490  ast_free(sched_data);
4491 
4492  sip_pvt_lock(pvt);
4493  do_cancel_destroy(pvt);
4494 
4495  if (pvt->do_history) {
4496  append_history(pvt, "SchedDestroy", "%d ms", ms);
4497  }
4498 
4499  dialog_ref(pvt, "Schedule autokillid");
4501  if (pvt->autokillid < 0) {
4502  /* Uh Oh. Expect bad behavior. */
4503  dialog_unref(pvt, "Failed to schedule autokillid");
4504  }
4505 
4506  if (pvt->stimer) {
4507  stop_session_timer(pvt);
4508  }
4509  sip_pvt_unlock(pvt);
4510  dialog_unref(pvt, "Destroy action");
4511  return 0;
4512 }
int autokillid
Definition: sip.h:1158
Definition: sched.c:76
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
static void stop_session_timer(struct sip_pvt *p)
Session-Timers: Stop session timer.
Definition: chan_sip.c:30213
static void do_cancel_destroy(struct sip_pvt *pvt)
Definition: chan_sip.c:4443
struct sip_st_dlg * stimer
Definition: sip.h:1184
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
#define ast_free(a)
Definition: astmm.h:182
unsigned short do_history
Definition: sip.h:1078
#define dialog_ref(dialog, tag)
when we create or delete references, make sure to use these functions so we keep track of the refcoun...
Definition: dialog.h:32
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406
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-...
Definition: chan_sip.c:4369
struct sip_pvt * pvt
Definition: chan_sip.c:4479

◆ __sip_semi_ack()

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

References ast_debug, ast_str_buffer(), sip_pvt::callid, sip_pkt::data, FALSE, sip_pkt::is_resp, method_match(), sip_pkt::next, sip_pvt::packets, sip_pkt::retransid, sip_pkt::seqno, sip_methods, sipdebug, stop_retrans_pkt(), cfsip_methods::text, and TRUE.

Referenced by handle_response(), and sip_hangup().

4633 {
4634  struct sip_pkt *cur;
4635  int res = FALSE;
4636 
4637  for (cur = p->packets; cur; cur = cur->next) {
4638  if (cur->seqno == seqno && cur->is_resp == resp &&
4639  (cur->is_resp || method_match(sipmethod, ast_str_buffer(cur->data)))) {
4640  /* this is our baby */
4641  if (cur->retransid > -1) {
4642  if (sipdebug)
4643  ast_debug(4, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text);
4644  }
4645  stop_retrans_pkt(cur);
4646  res = TRUE;
4647  break;
4648  }
4649  }
4650  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");
4651  return res;
4652 }
sip packet - raw format for outbound packets that are sent or scheduled for transmission Packets are ...
Definition: sip.h:1231
#define FALSE
Definition: app_minivm.c:521
static void stop_retrans_pkt(struct sip_pkt *pkt)
Definition: chan_sip.c:4251
static const struct cfsip_methods sip_methods[]
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
uint32_t seqno
Definition: sip.h:1235
static int method_match(enum sipmethod id, const char *name)
returns true if &#39;name&#39; (with optional trailing whitespace) matches the sip method &#39;id&#39;...
Definition: chan_sip.c:3584
int retransid
Definition: sip.h:1240
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
sipmethod
SIP Request methods known by Asterisk.
Definition: sip.h:612
struct ast_str * data
Definition: sip.h:1246
const ast_string_field callid
Definition: sip.h:1063
char is_resp
Definition: sip.h:1236
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
struct sip_pkt * next
Definition: sip.h:1232
struct sip_pkt * packets
Definition: sip.h:1177
char *const text
Definition: chan_sip.c:737
#define TRUE
Definition: app_minivm.c:518

◆ __sip_subscribe_mwi_do()

static int __sip_subscribe_mwi_do ( struct sip_subscription_mwi mwi)
static

Actually setup an MWI subscription or resubscribe.

Definition at line 15075 of file chan_sip.c.

References ao2_t_bump, ao2_t_ref, ast_dnsmgr_lookup_cb(), ast_set_flag, ast_sip_ouraddrfor(), ast_sockaddr_port, ast_sockaddr_set_port, ast_string_field_set, ast_strlen_zero, sip_subscription_mwi::authuser, build_via(), sip_subscription_mwi::call, change_callid_pvt(), create_addr(), dialog_unlink_all(), dialog_unref, sip_subscription_mwi::dnsmgr, sip_pvt::expiry, sip_pvt::flags, get_address_family_filter(), get_srv_protocol(), get_srv_service(), sip_subscription_mwi::hostname, MAXHOSTNAMELEN, sip_pvt::mwi, mwi_expiry, MWI_NOTIFICATION, NULL, obproxy_get(), on_dns_update_mwi(), sip_pvt::ourip, sip_monitor_instance::peername, sip_subscription_mwi::portno, sip_pvt::recv, ref_proxy(), sip_pvt::sa, sip_subscription_mwi::secret, set_socket_transport(), sip_alloc, sip_cfg, SIP_OUTGOING, SIP_SUBSCRIBE, sip_pvt::socket, sip_settings::srvlookup, ast_sockaddr::ss, sip_pvt::subscribed, transmit_invite(), sip_subscription_mwi::transport, sip_subscription_mwi::us, and sip_subscription_mwi::username.

Referenced by sip_subscribe_mwi_do().

15076 {
15077  /* If we have no DNS manager let's do a lookup */
15078  if (!mwi->dnsmgr) {
15079  char transport[MAXHOSTNAMELEN];
15080  snprintf(transport, sizeof(transport), "_%s._%s", get_srv_service(mwi->transport), get_srv_protocol(mwi->transport));
15081 
15082  mwi->us.ss.ss_family = get_address_family_filter(mwi->transport); /* Filter address family */
15083  ao2_t_ref(mwi, +1, "dnsmgr reference to mwi");
15084  ast_dnsmgr_lookup_cb(mwi->hostname, &mwi->us, &mwi->dnsmgr, sip_cfg.srvlookup ? transport : NULL, on_dns_update_mwi, mwi);
15085  if (!mwi->dnsmgr) {
15086  ao2_t_ref(mwi, -1, "dnsmgr disabled, remove reference");
15087  }
15088  }
15089 
15090  /* If we already have a subscription up simply send a resubscription */
15091  if (mwi->call) {
15092  transmit_invite(mwi->call, SIP_SUBSCRIBE, 0, 0, NULL);
15093  return 0;
15094  }
15095 
15096  /* Create a dialog that we will use for the subscription */
15097  if (!(mwi->call = sip_alloc(NULL, NULL, 0, SIP_SUBSCRIBE, NULL, 0))) {
15098  return -1;
15099  }
15100 
15101  ref_proxy(mwi->call, obproxy_get(mwi->call, NULL));
15102 
15103  if (!ast_sockaddr_port(&mwi->us) && mwi->portno) {
15104  ast_sockaddr_set_port(&mwi->us, mwi->portno);
15105  }
15106 
15107  /* Setup the destination of our subscription */
15108  if (create_addr(mwi->call, mwi->hostname, &mwi->us, 0)) {
15109  dialog_unlink_all(mwi->call);
15110  mwi->call = dialog_unref(mwi->call, "unref dialog after unlink_all");
15111  return 0;
15112  }
15113 
15114  mwi->call->expiry = mwi_expiry;
15115 
15116  if (!mwi->dnsmgr && mwi->portno) {
15117  ast_sockaddr_set_port(&mwi->call->sa, mwi->portno);
15118  ast_sockaddr_set_port(&mwi->call->recv, mwi->portno);
15119  } else {
15120  mwi->portno = ast_sockaddr_port(&mwi->call->sa);
15121  }
15122 
15123  /* Set various other information */
15124  if (!ast_strlen_zero(mwi->authuser)) {
15125  ast_string_field_set(mwi->call, peername, mwi->authuser);
15126  ast_string_field_set(mwi->call, authname, mwi->authuser);
15127  ast_string_field_set(mwi->call, fromuser, mwi->authuser);
15128  } else {
15129  ast_string_field_set(mwi->call, peername, mwi->username);
15130  ast_string_field_set(mwi->call, authname, mwi->username);
15131  ast_string_field_set(mwi->call, fromuser, mwi->username);
15132  }
15133  ast_string_field_set(mwi->call, username, mwi->username);
15134  if (!ast_strlen_zero(mwi->secret)) {
15135  ast_string_field_set(mwi->call, peersecret, mwi->secret);
15136  }
15137  set_socket_transport(&mwi->call->socket, mwi->transport);
15138  ast_sip_ouraddrfor(&mwi->call->sa, &mwi->call->ourip, mwi->call);
15139  build_via(mwi->call);
15140 
15141  /* Change the dialog callid. */
15142  change_callid_pvt(mwi->call, NULL);
15143 
15144  ast_set_flag(&mwi->call->flags[0], SIP_OUTGOING);
15145 
15146  /* Associate the call with us */
15147  mwi->call->mwi = ao2_t_bump(mwi, "Reference mwi from it's call");
15148 
15150 
15151  /* Actually send the packet */
15152  transmit_invite(mwi->call, SIP_SUBSCRIBE, 0, 2, NULL);
15153 
15154  return 0;
15155 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
struct sockaddr_storage ss
Definition: netsock2.h:98
enum subscriptiontype subscribed
Definition: sip.h:1161
static void build_via(struct sip_pvt *p)
Build a Via header for a request.
Definition: chan_sip.c:3847
static int get_address_family_filter(unsigned int transport)
Helper for dns resolution to filter by address family.
Definition: chan_sip.c:29558
#define ast_set_flag(p, flag)
Definition: utils.h:70
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.
Definition: chan_sip.c:14755
struct ast_sockaddr recv
Definition: sip.h:1135
struct sip_socket socket
Definition: sip.h:1066
const ast_string_field hostname
Definition: sip.h:1461
struct ast_sockaddr ourip
Definition: sip.h:1136
static const char * get_srv_protocol(enum ast_transport t)
Return protocol string for srv dns query.
Definition: chan_sip.c:3743
int srvlookup
Definition: sip.h:758
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?
Definition: chan_sip.c:3866
struct ast_flags flags[3]
Definition: sip.h:1075
#define MAXHOSTNAMELEN
Definition: network.h:69
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:521
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 stor...
Definition: chan_sip.c:3367
const ast_string_field username
Definition: sip.h:1461
struct ast_sockaddr sa
Definition: sip.h:1125
struct sip_subscription_mwi * mwi
Definition: sip.h:1192
static struct sip_proxy * obproxy_get(struct sip_pvt *dialog, struct sip_peer *peer)
Get default outbound proxy or global proxy.
Definition: chan_sip.c:3549
enum ast_transport transport
Definition: sip.h:1462
#define sip_alloc(callid, addr, useglobal_nat, intended_method, req, logger_callid)
Definition: dialog.h:39
int expiry
Definition: sip.h:1118
const ast_string_field authuser
Definition: sip.h:1461
struct sip_pvt * call
Definition: sip.h:1466
struct ast_sockaddr us
Definition: sip.h:1468
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:537
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
static void change_callid_pvt(struct sip_pvt *pvt, const char *callid)
Definition: chan_sip.c:8860
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
static void ref_proxy(struct sip_pvt *pvt, struct sip_proxy *proxy)
maintain proper refcounts for a sip_pvt&#39;s outboundproxy
Definition: chan_sip.c:3293
#define ao2_t_bump(obj, tag)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:483
const ast_string_field secret
Definition: sip.h:1461
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 TR...
Definition: chan_sip.c:6317
static const char * get_srv_service(enum ast_transport t)
Return service string for srv dns query.
Definition: chan_sip.c:3761
#define SIP_OUTGOING
Definition: sip.h:257
static void set_socket_transport(struct sip_socket *socket, int transport)
Definition: chan_sip.c:16629
struct ast_dnsmgr_entry * dnsmgr
Definition: sip.h:1467
static void on_dns_update_mwi(struct ast_sockaddr *old, struct ast_sockaddr *new, void *data)
Definition: chan_sip.c:15058
static int mwi_expiry
Definition: chan_sip.c:672
int ast_dnsmgr_lookup_cb(const char *name, struct ast_sockaddr *result, struct ast_dnsmgr_entry **dnsmgr, const char *service, dns_update_func func, void *data)
Allocate and initialize a DNS manager entry, with update callback.
Definition: dnsmgr.c:196
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ __sip_xmit()

static int __sip_xmit ( struct sip_pvt p,
struct ast_str data 
)
static

Definition at line 3801 of file chan_sip.c.

References ast_debug, ast_log, ast_sendto(), ast_sockaddr_stringify(), ast_str_buffer(), ast_str_strlen(), AST_TRANSPORT_UDP, ast_websocket_write_string(), errno, sip_socket::fd, get_transport_pvt(), LOG_WARNING, sip_prepare_socket(), sip_real_dst(), sip_tcptls_write(), sip_pvt::socket, sip_socket::tcptls_session, sip_socket::type, sip_socket::ws_session, and XMIT_ERROR.

Referenced by __sip_reliable_xmit(), retrans_pkt(), send_request(), and send_response().

3802 {
3803  int res = 0;
3804  const struct ast_sockaddr *dst = sip_real_dst(p);
3805 
3806  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));
3807 
3808  if (sip_prepare_socket(p) < 0) {
3809  return XMIT_ERROR;
3810  }
3811 
3812  if (p->socket.type == AST_TRANSPORT_UDP) {
3813  res = ast_sendto(p->socket.fd, ast_str_buffer(data), ast_str_strlen(data), 0, dst);
3814  } else if (p->socket.tcptls_session) {
3816  if (res < -1) {
3817  return res;
3818  }
3819  } else if (p->socket.ws_session) {
3820  if (!(res = ast_websocket_write_string(p->socket.ws_session, ast_str_buffer(data)))) {
3821  /* The WebSocket API just returns 0 on success and -1 on failure, while this code expects the payload length to be returned */
3822  res = ast_str_strlen(data);
3823  }
3824  } else {
3825  ast_debug(2, "Socket type is TCP but no tcptls_session is present to write to\n");
3826  return XMIT_ERROR;
3827  }
3828 
3829  if (res == -1) {
3830  switch (errno) {
3831  case EBADF: /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */
3832  case EHOSTUNREACH: /* Host can't be reached */
3833  case ENETDOWN: /* Interface down */
3834  case ENETUNREACH: /* Network failure */
3835  case ECONNREFUSED: /* ICMP port unreachable */
3836  res = XMIT_ERROR; /* Don't bother with trying to transmit again */
3837  }
3838  }
3839  if (res != ast_str_strlen(data)) {
3840  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));
3841  }
3842 
3843  return res;
3844 }
ssize_t ast_sendto(int sockfd, const void *buf, size_t len, int flags, const struct ast_sockaddr *dest_addr)
Wrapper around sendto(2) that uses ast_sockaddr.
Definition: netsock2.c:614
#define LOG_WARNING
Definition: logger.h:274
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
struct sip_socket socket
Definition: sip.h:1066
int AST_OPTIONAL_API_NAME() ast_websocket_write_string(struct ast_websocket *ws, const char *buf)
int fd
Definition: sip.h:799
Socket address structure.
Definition: netsock2.h:97
static const char * get_transport_pvt(struct sip_pvt *p)
Return transport of dialog.
Definition: chan_sip.c:3781
struct ast_websocket * ws_session
Definition: sip.h:802
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static const struct ast_sockaddr * sip_real_dst(const struct sip_pvt *p)
The real destination address for a write.
Definition: chan_sip.c:3633
struct ast_tcptls_session_instance * tcptls_session
Definition: sip.h:801
#define XMIT_ERROR
Definition: sip.h:58
int errno
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
static int sip_prepare_socket(struct sip_pvt *p)
Definition: chan_sip.c:29578
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
enum ast_transport type
Definition: sip.h:798
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
Definition: chan_sip.c:2608

◆ __start_mwi_subscription()

static int __start_mwi_subscription ( const void *  data)
static

Definition at line 14967 of file chan_sip.c.

References ao2_t_ref, ast_free, ast_sched_add(), AST_SCHED_DEL_UNREF, mwi_subscription_data::ms, mwi_subscription_data::mwi, sip_subscription_mwi::resub, and sip_subscribe_mwi_do().

Referenced by start_mwi_subscription().

14968 {
14969  struct mwi_subscription_data *sched_data = (void *) data;
14970  struct sip_subscription_mwi *mwi = sched_data->mwi;
14971  int ms = sched_data->ms;
14972 
14973  ast_free(sched_data);
14974 
14976  ao2_t_ref(mwi, -1, "Stop scheduled mwi resub"));
14977 
14978  ao2_t_ref(mwi, +1, "Schedule mwi resub");
14979  mwi->resub = ast_sched_add(sched, ms, sip_subscribe_mwi_do, mwi);
14980  if (mwi->resub < 0) {
14981  /* Uh Oh. Expect bad behavior. */
14982  ao2_t_ref(mwi, -1, "Failed to schedule mwi resub");
14983  }
14984 
14985  ao2_t_ref(mwi, -1, "Start MWI subscription action");
14986  return 0;
14987 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
Definition: sched.c:76
#define AST_SCHED_DEL_UNREF(sched, id, refcall)
schedule task to get deleted and call unref function
Definition: sched.h:80
static int sip_subscribe_mwi_do(const void *data)
Send a subscription or resubscription for MWI.
Definition: chan_sip.c:14923
#define ast_free(a)
Definition: astmm.h:182
struct sip_subscription_mwi * mwi
Definition: chan_sip.c:14962
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565
Definition of an MWI subscription to another server.
Definition: sip.h:1454

◆ __start_register_timeout()

static int __start_register_timeout ( const void *  data)
static

Definition at line 16060 of file chan_sip.c.

References ao2_t_ref, ast_debug, ast_sched_add(), AST_SCHED_DEL_UNREF, global_reg_timeout, sip_registry::hostname, sip_reg_timeout(), and sip_registry::timeout.

Referenced by start_register_timeout().

16061 {
16062  struct sip_registry *reg = (struct sip_registry *) data;
16063 
16065  ao2_t_ref(reg, -1, "Stop scheduled register timeout"));
16066 
16067  ao2_t_ref(reg, +1, "Schedule register timeout");
16069  if (reg->timeout < 0) {
16070  /* Uh Oh. Expect bad behavior. */
16071  ao2_t_ref(reg, -1, "Failed to schedule register timeout");
16072  }
16073  ast_debug(1, "Scheduled a registration timeout for %s id #%d \n",
16074  reg->hostname, reg->timeout);
16075 
16076  ao2_t_ref(reg, -1, "Start register timeout action");
16077  return 0;
16078 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
const ast_string_field hostname
Definition: sip.h:1414
Definition: sched.c:76
Registrations with other SIP proxies.
Definition: sip.h:1396
#define AST_SCHED_DEL_UNREF(sched, id, refcall)
schedule task to get deleted and call unref function
Definition: sched.h:80
static int sip_reg_timeout(const void *data)
Registration request timeout, register again.
Definition: chan_sip.c:15976
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static int global_reg_timeout
Definition: chan_sip.c:826
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565
int timeout
Definition: sip.h:1422

◆ __start_reregister_timeout()

static int __start_reregister_timeout ( const void *  data)
static

Definition at line 15923 of file chan_sip.c.

References ao2_t_ref, ast_free, ast_sched_add(), AST_SCHED_DEL_UNREF, sip_registry::expire, reregister_data::ms, reregister_data::reg, and sip_reregister().

Referenced by start_reregister_timeout().

15924 {
15925  struct reregister_data *sched_data = (void *) data;
15926  struct sip_registry *reg = sched_data->reg;
15927  int ms = sched_data->ms;
15928 
15929  ast_free(sched_data);
15930 
15932  ao2_t_ref(reg, -1, "Stop scheduled reregister timeout"));
15933 
15934  ao2_t_ref(reg, +1, "Schedule reregister timeout");
15935  reg->expire = ast_sched_add(sched, ms, sip_reregister, reg);
15936  if (reg->expire < 0) {
15937  /* Uh Oh. Expect bad behavior. */
15938  ao2_t_ref(reg, -1, "Failed to schedule reregister timeout");
15939  }
15940 
15941  ao2_t_ref(reg, -1, "Start reregister timeout action");
15942  return 0;
15943 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
struct sip_registry * reg
Definition: chan_sip.c:15918
int expire
Definition: sip.h:1418
Definition: sched.c:76
Registrations with other SIP proxies.
Definition: sip.h:1396
#define AST_SCHED_DEL_UNREF(sched, id, refcall)
schedule task to get deleted and call unref function
Definition: sched.h:80
#define ast_free(a)
Definition: astmm.h:182
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565
static int sip_reregister(const void *data)
Update registration with SIP Proxy.
Definition: chan_sip.c:15868

◆ __start_session_timer()

static int __start_session_timer ( const void *  data)
static

Definition at line 30226 of file chan_sip.c.

References ast_debug, ast_sched_add(), sip_pvt::callid, dialog_ref, dialog_unref, do_stop_session_timer(), MIN, proc_session_timer(), SESSION_TIMER_REFRESHER_US, sip_st_dlg::st_interval, sip_st_dlg::st_ref, sip_st_dlg::st_schedid, and sip_pvt::stimer.

Referenced by start_session_timer().

30227 {
30228  struct sip_pvt *pvt = (void *) data;
30229  struct sip_st_dlg *stimer = pvt->stimer;
30230  unsigned int timeout_ms;
30231 
30232  /*
30233  * RFC 4028 Section 10
30234  * If the side not performing refreshes does not receive a
30235  * session refresh request before the session expiration, it SHOULD send
30236  * a BYE to terminate the session, slightly before the session
30237  * expiration. The minimum of 32 seconds and one third of the session
30238  * interval is RECOMMENDED.
30239  */
30240 
30241  timeout_ms = (1000 * stimer->st_interval);
30242  if (stimer->st_ref == SESSION_TIMER_REFRESHER_US) {
30243  timeout_ms /= 2;
30244  } else {
30245  timeout_ms -= MIN(timeout_ms / 3, 32000);
30246  }
30247 
30248  /* in the event a timer is already going, stop it */
30249  do_stop_session_timer(pvt);
30250 
30251  dialog_ref(pvt, "Schedule session timer st_schedid");
30252  stimer->st_schedid = ast_sched_add(sched, timeout_ms, proc_session_timer, pvt);
30253  if (stimer->st_schedid < 0) {
30254  dialog_unref(pvt, "Failed to schedule session timer st_schedid");
30255  } else {
30256  ast_debug(2, "Session timer started: %d - %s %ums\n",
30257  stimer->st_schedid, pvt->callid, timeout_ms);
30258  }
30259 
30260  dialog_unref(pvt, "Start session timer action");
30261  return 0;
30262 }
enum st_refresher st_ref
Definition: sip.h:962
int st_schedid
Definition: sip.h:963
Definition: sched.c:76
int st_interval
Definition: sip.h:961
#define MIN(a, b)
Definition: utils.h:226
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static int proc_session_timer(const void *vp)
Session-Timers: Process session refresh timeout event.
Definition: chan_sip.c:30132
const ast_string_field callid
Definition: sip.h:1063
struct sip_st_dlg * stimer
Definition: sip.h:1184
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
static void do_stop_session_timer(struct sip_pvt *pvt)
Definition: chan_sip.c:30190
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
#define dialog_ref(dialog, tag)
when we create or delete references, make sure to use these functions so we keep track of the refcoun...
Definition: dialog.h:32
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565
Structure that encapsulates all attributes related to running SIP Session-Timers feature on a per dia...
Definition: sip.h:959

◆ __start_t38_abort_timer()

static int __start_t38_abort_timer ( const void *  data)
static

Definition at line 26126 of file chan_sip.c.

References ast_sched_add(), AST_SCHED_DEL_UNREF, dialog_ref, dialog_unref, sip_t38_abort(), and sip_pvt::t38id.

Referenced by start_t38_abort_timer().

26127 {
26128  struct sip_pvt *pvt = (void *) data;
26129 
26131  dialog_unref(pvt, "Stop scheduled t38id"));
26132 
26133  dialog_ref(pvt, "Schedule t38id");
26134  pvt->t38id = ast_sched_add(sched, 5000, sip_t38_abort, pvt);
26135  if (pvt->t38id < 0) {
26136  /* Uh Oh. Expect bad behavior. */
26137  dialog_unref(pvt, "Failed to schedule t38id");
26138  }
26139 
26140  dialog_unref(pvt, "Start t38id action");
26141  return 0;
26142 }
Definition: sched.c:76
#define AST_SCHED_DEL_UNREF(sched, id, refcall)
schedule task to get deleted and call unref function
Definition: sched.h:80
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
static int sip_t38_abort(const void *data)
Called to deny a T38 reinvite if the core does not respond to our request.
Definition: chan_sip.c:26075
#define dialog_ref(dialog, tag)
when we create or delete references, make sure to use these functions so we keep track of the refcoun...
Definition: dialog.h:32
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565
int t38id
Definition: sip.h:1159

◆ __stop_provisional_keepalive()

static int __stop_provisional_keepalive ( const void *  data)
static

Definition at line 4773 of file chan_sip.c.

References AST_SCHED_DEL_UNREF, dialog_unref, and sip_pvt::provisional_keepalive_sched_id.

Referenced by stop_provisional_keepalive().

4774 {
4775  struct sip_pvt *pvt = (void *) data;
4776 
4778  dialog_unref(pvt, "Stop scheduled provisional keepalive"));
4779  dialog_unref(pvt, "Stop provisional keepalive action");
4780  return 0;
4781 }
Definition: sched.c:76
#define AST_SCHED_DEL_UNREF(sched, id, refcall)
schedule task to get deleted and call unref function
Definition: sched.h:80
int provisional_keepalive_sched_id
Definition: sip.h:1109
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005

◆ __stop_register_timeout()

static int __stop_register_timeout ( const void *  data)
static

Definition at line 16040 of file chan_sip.c.

References ao2_t_ref, AST_SCHED_DEL_UNREF, and sip_registry::timeout.

Referenced by stop_register_timeout().

16041 {
16042  struct sip_registry *reg = (struct sip_registry *) data;
16043 
16045  ao2_t_ref(reg, -1, "Stop scheduled register timeout"));
16046  ao2_t_ref(reg, -1, "Stop register timeout action");
16047  return 0;
16048 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
Definition: sched.c:76
Registrations with other SIP proxies.
Definition: sip.h:1396
#define AST_SCHED_DEL_UNREF(sched, id, refcall)
schedule task to get deleted and call unref function
Definition: sched.h:80
int timeout
Definition: sip.h:1422

◆ __stop_reinvite_retry()

static int __stop_reinvite_retry ( const void *  data)
static

Definition at line 23836 of file chan_sip.c.

References AST_SCHED_DEL_UNREF, dialog_unref, and sip_pvt::waitid.

Referenced by stop_reinvite_retry().

23837 {
23838  struct sip_pvt *pvt = (void *) data;
23839 
23841  dialog_unref(pvt, "Stop scheduled waitid"));
23842  dialog_unref(pvt, "Stop reinvite retry action");
23843  return 0;
23844 }
Definition: sched.c:76
#define AST_SCHED_DEL_UNREF(sched, id, refcall)
schedule task to get deleted and call unref function
Definition: sched.h:80
int waitid
Definition: sip.h:1156
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005

◆ __stop_reinviteid()

static int __stop_reinviteid ( const void *  data)
static

Definition at line 7176 of file chan_sip.c.

References AST_SCHED_DEL_UNREF, dialog_unref, and sip_pvt::reinviteid.

Referenced by stop_reinviteid().

7177 {
7178  struct sip_pvt *pvt = (void *) data;
7179 
7181  dialog_unref(pvt, "Stop scheduled reinviteid"));
7182  dialog_unref(pvt, "Stop reinviteid action");
7183  return 0;
7184 }
int reinviteid
Definition: sip.h:1157
Definition: sched.c:76
#define AST_SCHED_DEL_UNREF(sched, id, refcall)
schedule task to get deleted and call unref function
Definition: sched.h:80
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005

◆ __stop_retrans_pkt()

static int __stop_retrans_pkt ( const void *  data)
static

Definition at line 4241 of file chan_sip.c.

References ao2_t_ref, AST_SCHED_DEL_UNREF, and sip_pkt::retransid.

Referenced by stop_retrans_pkt().

4242 {
4243  struct sip_pkt *pkt = (void *) data;
4244 
4246  ao2_t_ref(pkt, -1, "Stop scheduled packet retransmission"));
4247  ao2_t_ref(pkt, -1, "Stop packet retransmission action");
4248  return 0;
4249 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
sip packet - raw format for outbound packets that are sent or scheduled for transmission Packets are ...
Definition: sip.h:1231
int retransid
Definition: sip.h:1240
Definition: sched.c:76
#define AST_SCHED_DEL_UNREF(sched, id, refcall)
schedule task to get deleted and call unref function
Definition: sched.h:80
struct ast_str * data
Definition: sip.h:1246

◆ __stop_session_timer()

static int __stop_session_timer ( const void *  data)
static

Definition at line 30203 of file chan_sip.c.

References dialog_unref, and do_stop_session_timer().

Referenced by stop_session_timer().

30204 {
30205  struct sip_pvt *pvt = (void *) data;
30206 
30207  do_stop_session_timer(pvt);
30208  dialog_unref(pvt, "Stop session timer action");
30209  return 0;
30210 }
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
static void do_stop_session_timer(struct sip_pvt *pvt)
Definition: chan_sip.c:30190
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005

◆ __stop_t38_abort_timer()

static int __stop_t38_abort_timer ( const void *  data)
static

Definition at line 26106 of file chan_sip.c.

References AST_SCHED_DEL_UNREF, dialog_unref, and sip_pvt::t38id.

Referenced by stop_t38_abort_timer().

26107 {
26108  struct sip_pvt *pvt = (void *) data;
26109 
26111  dialog_unref(pvt, "Stop scheduled t38id"));
26112  dialog_unref(pvt, "Stop t38id action");
26113  return 0;
26114 }
Definition: sched.c:76
#define AST_SCHED_DEL_UNREF(sched, id, refcall)
schedule task to get deleted and call unref function
Definition: sched.h:80
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
int t38id
Definition: sip.h:1159

◆ __transmit_response()

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

References add_cc_call_info_to_response(), add_diversion(), add_header(), add_rpid(), ast_cause2str(), ast_channel_hangupcause(), ast_clear_flag, ast_log, ast_test_flag, buf, sip_pvt::flags, hangup_sip2cause(), sip_pvt::hangupcause, LOG_WARNING, sip_pvt::method, sip_pvt::owner, respprep(), send_response(), sip_get_header(), SIP_INVITE, SIP_OFFER_CC, SIP_PAGE2_CONNECTLINEUPDATE_PEND, SIP_PAGE2_Q850_REASON, and SIP_SENDRPID.

Referenced by transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), and transmit_response_using_temp().

12512 {
12513  struct sip_request resp;
12514  uint32_t seqno = 0;
12515 
12516  if (reliable && (sscanf(sip_get_header(req, "CSeq"), "%30u ", &seqno) != 1)) {
12517  ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", sip_get_header(req, "CSeq"));
12518  return -1;
12519  }
12520  respprep(&resp, p, msg, req);
12521 
12522  if (ast_test_flag(&p->flags[0], SIP_SENDRPID)
12524  && (!strncmp(msg, "180", 3) || !strncmp(msg, "183", 3))) {
12526  add_rpid(&resp, p);
12527  }
12528  if (ast_test_flag(&p->flags[0], SIP_OFFER_CC)) {
12529  add_cc_call_info_to_response(p, &resp);
12530  }
12531 
12532  /* If we are sending a 302 Redirect we can add a diversion header if the redirect information is set */
12533  if (!strncmp(msg, "302", 3)) {
12534  add_diversion(&resp, p);
12535  }
12536 
12537  /* If we are cancelling an incoming invite for some reason, add information
12538  about the reason why we are doing this in clear text */
12539  if (p->method == SIP_INVITE && msg[0] != '1') {
12540  char buf[20];
12541 
12542  if (ast_test_flag(&p->flags[1], SIP_PAGE2_Q850_REASON)) {
12543  int hangupcause = 0;
12544 
12545  if (p->owner && ast_channel_hangupcause(p->owner)) {
12546  hangupcause = ast_channel_hangupcause(p->owner);
12547  } else if (p->hangupcause) {
12548  hangupcause = p->hangupcause;
12549  } else {
12550  int respcode;
12551  if (sscanf(msg, "%30d ", &respcode))
12552  hangupcause = hangup_sip2cause(respcode);
12553  }
12554 
12555  if (hangupcause) {
12556  sprintf(buf, "Q.850;cause=%i", hangupcause & 0x7f);
12557  add_header(&resp, "Reason", buf);
12558  }
12559  }
12560 
12561  if (p->owner && ast_channel_hangupcause(p->owner)) {
12562  add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(ast_channel_hangupcause(p->owner)));
12563  snprintf(buf, sizeof(buf), "%d", ast_channel_hangupcause(p->owner));
12564  add_header(&resp, "X-Asterisk-HangupCauseCode", buf);
12565  }
12566  }
12567  return send_response(p, &resp, reliable, seqno);
12568 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
#define SIP_PAGE2_CONNECTLINEUPDATE_PEND
Definition: sip.h:329
int hangupcause
Definition: sip.h:1190
#define ast_test_flag(p, flag)
Definition: utils.h:63
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
struct ast_flags flags[3]
Definition: sip.h:1075
int hangup_sip2cause(int cause)
Convert SIP hangup causes to Asterisk hangup causes.
Definition: chan_sip.c:6986
#define ast_log
Definition: astobj2.c:42
#define SIP_PAGE2_Q850_REASON
Definition: sip.h:326
int method
Definition: sip.h:1009
const char * ast_cause2str(int state) attribute_pure
Gives the string form of a given cause code.
Definition: channel.c:612
struct ast_channel * owner
Definition: sip.h:1138
static int send_response(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno)
Transmit response on SIP request.
Definition: chan_sip.c:4821
static int add_rpid(struct sip_request *req, struct sip_pvt *p)
Add Remote-Party-ID header to SIP message.
Definition: chan_sip.c:12996
#define ast_clear_flag(p, flag)
Definition: utils.h:77
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
static void add_diversion(struct sip_request *req, struct sip_pvt *pvt)
Add "Diversion" header to outgoing message.
Definition: chan_sip.c:14653
int ast_channel_hangupcause(const struct ast_channel *chan)
static void add_cc_call_info_to_response(struct sip_pvt *p, struct sip_request *resp)
Definition: chan_sip.c:14090
static int respprep(struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req)
Prepare SIP response packet.
Definition: chan_sip.c:12269
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873
#define SIP_OFFER_CC
Definition: sip.h:258
#define SIP_SENDRPID
Definition: sip.h:306

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 35928 of file chan_sip.c.

◆ __update_provisional_keepalive()

static int __update_provisional_keepalive ( const void *  data)
static

Definition at line 4747 of file chan_sip.c.

References __update_provisional_keepalive_full().

Referenced by update_provisional_keepalive().

4748 {
4749  struct sip_pvt *pvt = (void *) data;
4750 
4751  return __update_provisional_keepalive_full(pvt, 0);
4752 }
static int __update_provisional_keepalive_full(struct sip_pvt *pvt, int with_sdp)
Definition: chan_sip.c:4724
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005

◆ __update_provisional_keepalive_full()

static int __update_provisional_keepalive_full ( struct sip_pvt pvt,
int  with_sdp 
)
static

Definition at line 4724 of file chan_sip.c.

References ast_sched_add(), AST_SCHED_DEL_UNREF, dialog_ref, dialog_unref, INV_COMPLETED, sip_pvt::invitestate, PROVIS_KEEPALIVE_TIMEOUT, sip_pvt::provisional_keepalive_sched_id, send_provisional_keepalive(), send_provisional_keepalive_with_sdp(), sip_pvt_lock, and sip_pvt_unlock.

Referenced by __update_provisional_keepalive(), and __update_provisional_keepalive_with_sdp().

4725 {
4727  dialog_unref(pvt, "Stop scheduled provisional keepalive for update"));
4728 
4729  sip_pvt_lock(pvt);
4730  if (pvt->invitestate < INV_COMPLETED) {
4731  /* Provisional keepalive is still needed. */
4732  dialog_ref(pvt, "Schedule provisional keepalive");
4735  pvt);
4736  if (pvt->provisional_keepalive_sched_id < 0) {
4737  dialog_unref(pvt, "Failed to schedule provisional keepalive");
4738  }
4739  }
4740  sip_pvt_unlock(pvt);
4741 
4742  dialog_unref(pvt, "Update provisional keepalive action");
4743  return 0;
4744 }
#define PROVIS_KEEPALIVE_TIMEOUT
Definition: sip.h:108
static int send_provisional_keepalive_with_sdp(const void *data)
Definition: chan_sip.c:4716
Definition: sched.c:76
#define AST_SCHED_DEL_UNREF(sched, id, refcall)
schedule task to get deleted and call unref function
Definition: sched.h:80
int provisional_keepalive_sched_id
Definition: sip.h:1109
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
#define dialog_ref(dialog, tag)
when we create or delete references, make sure to use these functions so we keep track of the refcoun...
Definition: dialog.h:32
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565
enum invitestates invitestate
Definition: sip.h:1007
static int send_provisional_keepalive(const void *data)
Definition: chan_sip.c:4708

◆ __update_provisional_keepalive_with_sdp()

static int __update_provisional_keepalive_with_sdp ( const void *  data)
static

Definition at line 4755 of file chan_sip.c.

References __update_provisional_keepalive_full().

Referenced by update_provisional_keepalive().

4756 {
4757  struct sip_pvt *pvt = (void *) data;
4758 
4759  return __update_provisional_keepalive_full(pvt, 1);
4760 }
static int __update_provisional_keepalive_full(struct sip_pvt *pvt, int with_sdp)
Definition: chan_sip.c:4724
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005

◆ _sip_qualify_peer()

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

References ast_cli(), astman_get_header(), astman_send_ack(), astman_send_error(), CLI_SHOWUSAGE, CLI_SUCCESS, FALSE, FINDPEERS, NULL, publish_qualify_peer_done(), sip_find_peer(), sip_poke_peer(), sip_unref_peer, and TRUE.

Referenced by manager_sip_qualify_peer(), and sip_qualify_peer().

21085 {
21086  struct sip_peer *peer;
21087  int load_realtime;
21088 
21089  if (argc < 4)
21090  return CLI_SHOWUSAGE;
21091 
21092  load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
21093  if ((peer = sip_find_peer(argv[3], NULL, load_realtime, FINDPEERS, FALSE, 0))) {
21094  const char *id = astman_get_header(m,"ActionID");
21095 
21096  if (type != 0) {
21097  astman_send_ack(s, m, "SIP peer found - will qualify");
21098  }
21099 
21100  sip_poke_peer(peer, 1);
21101 
21102  publish_qualify_peer_done(id, argv[3]);
21103 
21104  sip_unref_peer(peer, "qualify: done with peer");
21105  } else if (type == 0) {
21106  ast_cli(fd, "Peer '%s' not found\n", argv[3]);
21107  } else {
21108  astman_send_error(s, m, "Peer not found");
21109  }
21110 
21111  return CLI_SUCCESS;
21112 }
static const char type[]
Definition: chan_ooh323.c:109
#define FALSE
Definition: app_minivm.c:521
struct sip_peer * sip_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.
Definition: chan_sip.c:5851
static void publish_qualify_peer_done(const char *id, const char *peer)
Definition: chan_sip.c:21067
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3191
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
#define FINDPEERS
Definition: sip.h:53
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
#define CLI_SUCCESS
Definition: cli.h:44
#define TRUE
Definition: app_minivm.c:518
static int sip_poke_peer(struct sip_peer *peer, int force)
Check availability of peer, also keep NAT open.
Definition: chan_sip.c:30583
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159

◆ _sip_show_peer()

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

References sip_peer::accountcode, sip_peer::acl, sip_peer::addr, allowoverlap2str(), sip_peer::allowtransfer, sip_peer::amaflags, ao2_lock, ao2_t_ref, ao2_unlock, ARRAY_LEN, ast_acl_list_is_empty(), ast_callerid_merge(), ast_channel_amaflags2string(), ast_check_realtime(), ast_cli(), AST_CLI_YESNO, ast_describe_caller_presentation(), ast_format_cap_get_names(), AST_FORMAT_CAP_NAMES_LEN, ast_free, AST_LIST_TRAVERSE, ast_print_group(), ast_print_namedgroups(), ast_sched_when(), ast_sockaddr_port, ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_str_alloca, ast_str_buffer(), ast_str_reset(), ast_strlen_zero, ast_test_flag, astman_append(), astman_get_header(), astman_send_error(), sip_peer::auth, sip_peer::autoframing, sip_peer::busy_level, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::caps, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, CLI_SHOWUSAGE, CLI_SUCCESS, comedia_string(), sip_peer::contactacl, sip_peer::context, sip_peer::defaddr, sip_peer::description, sip_peer::directmediaacl, dtmfmode2str(), sip_peer::engine, sip_peer::expire, FALSE, faxec2str(), FINDPEERS, sip_peer::flags, sip_proxy::force, force_rport_string(), sip_peer::fromdomain, sip_peer::fromdomainport, sip_peer::fromuser, sip_peer::fullcontact, get_transport_list(), sip_peer::host_dynamic, cfsip_options::id, insecure2str(), sip_peer::is_realtime, sip_peer::keepalive, sip_peer::language, sip_peer::lastmsgssent, sip_auth_container::list, sip_peer::maxcallbitrate, sip_peer::maxforwards, sip_auth::md5secret, sip_peer::md5secret, sip_peer::mohsuggest, ast_variable::name, sip_proxy::name, sip_peer::name, sip_peer::named_callgroups, sip_peer::named_pickupgroups, ast_variable::next, NULL, sip_peer::outboundproxy, sip_peer::parkinglot, sip_peer::path, peer_mailboxes_to_str(), peer_status(), sip_peer::pickupgroup, print_group(), print_named_groups(), sip_peer::qualifyfreq, sip_auth::realm, sip_peer::record_off_feature, sip_peer::record_on_feature, sip_settings::regcontext, sip_peer::regexten, sip_peer::remotesecret, S_OR, sip_auth::secret, sip_peer::secret, sip_cfg, SIP_DIRECT_MEDIA, SIP_DTMF, sip_find_peer(), sip_get_transport(), SIP_INSECURE, SIP_NAT_FORCE_RPORT, sip_options, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_IGNORESDPVERSION, SIP_PAGE2_Q850_REASON, SIP_PAGE2_SYMMETRICRTP, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_TEXTSUPPORT, SIP_PAGE2_TRUST_ID_OUTBOUND, SIP_PAGE2_USE_SRTP, SIP_PAGE2_VIDEOSUPPORT, SIP_PAGE2_VIDEOSUPPORT_ALWAYS, SIP_PAGE3_NAT_AUTO_COMEDIA, SIP_PAGE3_NAT_AUTO_RPORT, SIP_PAGE3_RTCP_MUX, SIP_PROMISCREDIR, sip_route_list(), SIP_SENDRPID, SIP_TRUSTRPID, sip_unref_peer, SIP_USEPATH, SIP_USEREQPHONE, sip_peer::sipoptions, sip_peer::socket, sip_st_cfg::st_max_se, sip_st_cfg::st_min_se, sip_st_cfg::st_mode_oper, sip_st_cfg::st_ref, STANDARD_SIP_PORT, status, sip_peer::stimer, stmode2str(), strefresherparam2str(), sip_peer::subscribecontext, sip_peer::t38_maxdatagram, text, sip_peer::timer_b, sip_peer::timer_t1, sip_peer::tohost, transfermode2str(), sip_peer::transports, TRUE, trust_id_outbound2str(), sip_socket::type, sip_peer::useragent, sip_auth::username, sip_peer::username, ast_variable::value, sip_peer::vmexten, and sip_peer::zone.

Referenced by manager_sip_show_peer(), and sip_show_peer().

21182 {
21183  char status[30] = "";
21184  char cbuf[256];
21185  struct sip_peer *peer;
21186  struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
21187  struct ast_variable *v;
21188  int x = 0, load_realtime;
21189  int realtimepeers;
21190 
21191  realtimepeers = ast_check_realtime("sippeers");
21192 
21193  if (argc < 4)
21194  return CLI_SHOWUSAGE;
21195 
21196  load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
21197  peer = sip_find_peer(argv[3], NULL, load_realtime, FINDPEERS, FALSE, 0);
21198 
21199  if (s) { /* Manager */
21200  if (peer) {
21201  const char *id = astman_get_header(m, "ActionID");
21202 
21203  astman_append(s, "Response: Success\r\n");
21204  if (!ast_strlen_zero(id))
21205  astman_append(s, "ActionID: %s\r\n", id);
21206  } else {
21207  snprintf (cbuf, sizeof(cbuf), "Peer %s not found.", argv[3]);
21208  astman_send_error(s, m, cbuf);
21209  return CLI_SUCCESS;
21210  }
21211  }
21212  if (peer && type==0 ) { /* Normal listing */
21213  struct ast_str *mailbox_str = ast_str_alloca(512);
21214  struct ast_str *path;
21215  struct sip_auth_container *credentials;
21216 
21217  ao2_lock(peer);
21218  credentials = peer->auth;
21219  if (credentials) {
21220  ao2_t_ref(credentials, +1, "Ref peer auth for show");
21221  }
21222  ao2_unlock(peer);
21223 
21224  ast_cli(fd, "\n\n");
21225  ast_cli(fd, " * Name : %s\n", peer->name);
21226  ast_cli(fd, " Description : %s\n", peer->description);
21227  if (realtimepeers) { /* Realtime is enabled */
21228  ast_cli(fd, " Realtime peer: %s\n", peer->is_realtime ? "Yes, cached" : "No");
21229  }
21230  ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
21231  ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>");
21232  ast_cli(fd, " Remote Secret: %s\n", ast_strlen_zero(peer->remotesecret)?"<Not set>":"<Set>");
21233  if (credentials) {
21234  struct sip_auth *auth;
21235 
21236  AST_LIST_TRAVERSE(&credentials->list, auth, node) {
21237  ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s %s\n",
21238  auth->realm,
21239  auth->username,
21240  !ast_strlen_zero(auth->secret)
21241  ? "<Secret set>"
21242  : (!ast_strlen_zero(auth->md5secret)
21243  ? "<MD5secret set>" : "<Not set>"));
21244  }
21245  ao2_t_ref(credentials, -1, "Unref peer auth for show");
21246  }
21247  ast_cli(fd, " Context : %s\n", peer->context);
21248  ast_cli(fd, " Record On feature : %s\n", peer->record_on_feature);
21249  ast_cli(fd, " Record Off feature : %s\n", peer->record_off_feature);
21250  ast_cli(fd, " Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") );
21251  ast_cli(fd, " Language : %s\n", peer->language);
21252  ast_cli(fd, " Tonezone : %s\n", peer->zone[0] != '\0' ? peer->zone : "<Not set>");
21253  if (!ast_strlen_zero(peer->accountcode))
21254  ast_cli(fd, " Accountcode : %s\n", peer->accountcode);
21255  ast_cli(fd, " AMA flags : %s\n", ast_channel_amaflags2string(peer->amaflags));
21256  ast_cli(fd, " Transfer mode: %s\n", transfermode2str(peer->allowtransfer));
21257  ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres));
21258  if (!ast_strlen_zero(peer->fromuser))
21259  ast_cli(fd, " FromUser : %s\n", peer->fromuser);
21260  if (!ast_strlen_zero(peer->fromdomain))
21261  ast_cli(fd, " FromDomain : %s Port %d\n", peer->fromdomain, (peer->fromdomainport) ? peer->fromdomainport : STANDARD_SIP_PORT);
21262  ast_cli(fd, " Callgroup : ");
21263  print_group(fd, peer->callgroup, 0);
21264  ast_cli(fd, " Pickupgroup : ");
21265  print_group(fd, peer->pickupgroup, 0);
21266  ast_cli(fd, " Named Callgr : ");
21267  print_named_groups(fd, peer->named_callgroups, 0);
21268  ast_cli(fd, " Nam. Pickupgr: ");
21269  print_named_groups(fd, peer->named_pickupgroups, 0);
21270  peer_mailboxes_to_str(&mailbox_str, peer);
21271  ast_cli(fd, " MOH Suggest : %s\n", peer->mohsuggest);
21272  ast_cli(fd, " Mailbox : %s\n", ast_str_buffer(mailbox_str));
21273  ast_cli(fd, " VM Extension : %s\n", peer->vmexten);
21274  ast_cli(fd, " LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff);
21275  ast_cli(fd, " Call limit : %d\n", peer->call_limit);
21276  ast_cli(fd, " Max forwards : %d\n", peer->maxforwards);
21277  if (peer->busy_level)
21278  ast_cli(fd, " Busy level : %d\n", peer->busy_level);
21279  ast_cli(fd, " Dynamic : %s\n", AST_CLI_YESNO(peer->host_dynamic));
21280  ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
21281  ast_cli(fd, " MaxCallBR : %d kbps\n", peer->maxcallbitrate);
21282  ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, peer->expire));
21283  ast_cli(fd, " Insecure : %s\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE)));
21284  ast_cli(fd, " Force rport : %s\n", force_rport_string(peer->flags));
21285  ast_cli(fd, " Symmetric RTP: %s\n", comedia_string(peer->flags));
21286  ast_cli(fd, " ACL : %s\n", AST_CLI_YESNO(ast_acl_list_is_empty(peer->acl) == 0));
21287  ast_cli(fd, " ContactACL : %s\n", AST_CLI_YESNO(ast_acl_list_is_empty(peer->contactacl) == 0));
21288  ast_cli(fd, " DirectMedACL : %s\n", AST_CLI_YESNO(ast_acl_list_is_empty(peer->directmediaacl) == 0));
21289  ast_cli(fd, " T.38 support : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT)));
21290  ast_cli(fd, " T.38 EC mode : %s\n", faxec2str(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT)));
21291  ast_cli(fd, " T.38 MaxDtgrm: %u\n", peer->t38_maxdatagram);
21292  ast_cli(fd, " DirectMedia : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_DIRECT_MEDIA)));
21293  ast_cli(fd, " PromiscRedir : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)));
21294  ast_cli(fd, " User=Phone : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)));
21295  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)));
21296  ast_cli(fd, " Text Support : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT)));
21297  ast_cli(fd, " Ign SDP ver : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_IGNORESDPVERSION)));
21298  ast_cli(fd, " Trust RPID : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_TRUSTRPID)));
21299  ast_cli(fd, " Send RPID : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_SENDRPID)));
21300  ast_cli(fd, " Path support : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_USEPATH)));
21301  if ((path = sip_route_list(&peer->path, 1, 0))) {
21302  ast_cli(fd, " Path : %s\n", ast_str_buffer(path));
21303  ast_free(path);
21304  }
21305  ast_cli(fd, " TrustIDOutbnd: %s\n", trust_id_outbound2str(ast_test_flag(&peer->flags[1], SIP_PAGE2_TRUST_ID_OUTBOUND)));
21306  ast_cli(fd, " Subscriptions: %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)));
21307  ast_cli(fd, " Overlap dial : %s\n", allowoverlap2str(ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP)));
21308  if (peer->outboundproxy)
21309  ast_cli(fd, " Outb. proxy : %s %s\n", ast_strlen_zero(peer->outboundproxy->name) ? "<not set>" : peer->outboundproxy->name,
21310  peer->outboundproxy->force ? "(forced)" : "");
21311 
21312  /* - is enumerated */
21313  ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF)));
21314  ast_cli(fd, " Timer T1 : %d\n", peer->timer_t1);
21315  ast_cli(fd, " Timer B : %d\n", peer->timer_b);
21316  ast_cli(fd, " ToHost : %s\n", peer->tohost);
21317  ast_cli(fd, " Addr->IP : %s\n", ast_sockaddr_stringify(&peer->addr));
21318  ast_cli(fd, " Defaddr->IP : %s\n", ast_sockaddr_stringify(&peer->defaddr));
21319  ast_cli(fd, " Prim.Transp. : %s\n", sip_get_transport(peer->socket.type));
21320  ast_cli(fd, " Allowed.Trsp : %s\n", get_transport_list(peer->transports));
21322  ast_cli(fd, " Reg. exten : %s\n", peer->regexten);
21323  ast_cli(fd, " Def. Username: %s\n", peer->username);
21324  ast_cli(fd, " SIP Options : ");
21325  if (peer->sipoptions) {
21326  int lastoption = -1;
21327  for (x = 0 ; x < ARRAY_LEN(sip_options); x++) {
21328  if (sip_options[x].id != lastoption) {
21329  if (peer->sipoptions & sip_options[x].id)
21330  ast_cli(fd, "%s ", sip_options[x].text);
21331  lastoption = x;
21332  }
21333  }
21334  } else
21335  ast_cli(fd, "(none)");
21336 
21337  ast_cli(fd, "\n");
21338  ast_cli(fd, " Codecs : %s\n", ast_format_cap_get_names(peer->caps, &codec_buf));
21339 
21340  ast_cli(fd, " Auto-Framing : %s\n", AST_CLI_YESNO(peer->autoframing));
21341  ast_cli(fd, " Status : ");
21342  peer_status(peer, status, sizeof(status));
21343  ast_cli(fd, "%s\n", status);
21344  ast_cli(fd, " Useragent : %s\n", peer->useragent);
21345  ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact);
21346  ast_cli(fd, " Qualify Freq : %d ms\n", peer->qualifyfreq);
21347  ast_cli(fd, " Keepalive : %d ms\n", peer->keepalive * 1000);
21348  if (peer->chanvars) {
21349  ast_cli(fd, " Variables :\n");
21350  for (v = peer->chanvars ; v ; v = v->next)
21351  ast_cli(fd, " %s = %s\n", v->name, v->value);
21352  }
21353 
21354  ast_cli(fd, " Sess-Timers : %s\n", stmode2str(peer->stimer.st_mode_oper));
21355  ast_cli(fd, " Sess-Refresh : %s\n", strefresherparam2str(peer->stimer.st_ref));
21356  ast_cli(fd, " Sess-Expires : %d secs\n", peer->stimer.st_max_se);
21357  ast_cli(fd, " Min-Sess : %d secs\n", peer->stimer.st_min_se);
21358  ast_cli(fd, " RTP Engine : %s\n", peer->engine);
21359  ast_cli(fd, " Parkinglot : %s\n", peer->parkinglot);
21360  ast_cli(fd, " Use Reason : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_Q850_REASON)));
21361  ast_cli(fd, " Encryption : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_USE_SRTP)));
21362  ast_cli(fd, " RTCP Mux : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[2], SIP_PAGE3_RTCP_MUX)));
21363  ast_cli(fd, "\n");
21364  peer = sip_unref_peer(peer, "sip_show_peer: sip_unref_peer: done with peer ptr");
21365  } else if (peer && type == 1) { /* manager listing */
21366  char buffer[256];
21367  struct ast_str *tmp_str = ast_str_alloca(512);
21368  astman_append(s, "Channeltype: SIP\r\n");
21369  astman_append(s, "ObjectName: %s\r\n", peer->name);
21370  astman_append(s, "ChanObjectType: peer\r\n");
21371  astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y");
21372  astman_append(s, "RemoteSecretExist: %s\r\n", ast_strlen_zero(peer->remotesecret)?"N":"Y");
21373  astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y");
21374  astman_append(s, "Context: %s\r\n", peer->context);
21375  if (!ast_strlen_zero(peer->subscribecontext)) {
21376  astman_append(s, "SubscribeContext: %s\r\n", peer->subscribecontext);
21377  }
21378  astman_append(s, "Language: %s\r\n", peer->language);
21379  astman_append(s, "ToneZone: %s\r\n", peer->zone[0] != '\0' ? peer->zone : "<Not set>");
21380  if (!ast_strlen_zero(peer->accountcode))
21381  astman_append(s, "Accountcode: %s\r\n", peer->accountcode);
21382  astman_append(s, "AMAflags: %s\r\n", ast_channel_amaflags2string(peer->amaflags));
21383  astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres));
21384  if (!ast_strlen_zero(peer->fromuser))
21385  astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser);
21386  if (!ast_strlen_zero(peer->fromdomain))
21387  astman_append(s, "SIP-FromDomain: %s\r\nSip-FromDomain-Port: %d\r\n", peer->fromdomain, (peer->fromdomainport) ? peer->fromdomainport : STANDARD_SIP_PORT);
21388  astman_append(s, "Callgroup: ");
21389  astman_append(s, "%s\r\n", ast_print_group(buffer, sizeof(buffer), peer->callgroup));
21390  astman_append(s, "Pickupgroup: ");
21391  astman_append(s, "%s\r\n", ast_print_group(buffer, sizeof(buffer), peer->pickupgroup));
21392  astman_append(s, "Named Callgroup: ");
21393  astman_append(s, "%s\r\n", ast_print_namedgroups(&tmp_str, peer->named_callgroups));
21394  ast_str_reset(tmp_str);
21395  astman_append(s, "Named Pickupgroup: ");
21396  astman_append(s, "%s\r\n", ast_print_namedgroups(&tmp_str, peer->named_pickupgroups));
21397  ast_str_reset(tmp_str);
21398  astman_append(s, "MOHSuggest: %s\r\n", peer->mohsuggest);
21399  peer_mailboxes_to_str(&tmp_str, peer);
21400  astman_append(s, "VoiceMailbox: %s\r\n", ast_str_buffer(tmp_str));
21401  astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer));
21402  astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent);
21403  astman_append(s, "Maxforwards: %d\r\n", peer->maxforwards);
21404  astman_append(s, "Call-limit: %d\r\n", peer->call_limit);
21405  astman_append(s, "Busy-level: %d\r\n", peer->busy_level);
21406  astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate);
21407  astman_append(s, "Dynamic: %s\r\n", peer->host_dynamic?"Y":"N");
21408  astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, ""));
21409  astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched, peer->expire));
21410  astman_append(s, "SIP-AuthInsecure: %s\r\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE)));
21411  astman_append(s, "SIP-Forcerport: %s\r\n", ast_test_flag(&peer->flags[2], SIP_PAGE3_NAT_AUTO_RPORT) ?
21412  (ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? "A" : "a") :
21413  (ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? "Y" : "N"));
21414  astman_append(s, "SIP-Comedia: %s\r\n", ast_test_flag(&peer->flags[2], SIP_PAGE3_NAT_AUTO_COMEDIA) ?
21415  (ast_test_flag(&peer->flags[1], SIP_PAGE2_SYMMETRICRTP) ? "A" : "a") :
21416  (ast_test_flag(&peer->flags[1], SIP_PAGE2_SYMMETRICRTP) ? "Y" : "N"));
21417  astman_append(s, "ACL: %s\r\n", (ast_acl_list_is_empty(peer->acl) ? "N" : "Y"));
21418  astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_DIRECT_MEDIA)?"Y":"N"));
21419  astman_append(s, "SIP-DirectMedia: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_DIRECT_MEDIA)?"Y":"N"));
21420  astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N"));
21421  astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N"));
21422  astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N"));
21423  astman_append(s, "SIP-TextSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT)?"Y":"N"));
21424  astman_append(s, "SIP-T.38Support: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT)?"Y":"N"));
21425  astman_append(s, "SIP-T.38EC: %s\r\n", faxec2str(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT)));
21426  astman_append(s, "SIP-T.38MaxDtgrm: %u\r\n", peer->t38_maxdatagram);
21427  astman_append(s, "SIP-Sess-Timers: %s\r\n", stmode2str(peer->stimer.st_mode_oper));
21428  astman_append(s, "SIP-Sess-Refresh: %s\r\n", strefresherparam2str(peer->stimer.st_ref));
21429  astman_append(s, "SIP-Sess-Expires: %d\r\n", peer->stimer.st_max_se);
21430  astman_append(s, "SIP-Sess-Min: %d\r\n", peer->stimer.st_min_se);
21431  astman_append(s, "SIP-RTP-Engine: %s\r\n", peer->engine);
21432  astman_append(s, "SIP-Encryption: %s\r\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_USE_SRTP) ? "Y" : "N");
21433  astman_append(s, "SIP-RTCP-Mux: %s\r\n", ast_test_flag(&peer->flags[2], SIP_PAGE3_RTCP_MUX) ? "Y" : "N");
21434 
21435  /* - is enumerated */
21436  astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF)));
21437  astman_append(s, "ToHost: %s\r\n", peer->tohost);
21438  astman_append(s, "Address-IP: %s\r\nAddress-Port: %d\r\n", ast_sockaddr_stringify_addr(&peer->addr), ast_sockaddr_port(&peer->addr));
21439  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));
21440  astman_append(s, "Default-Username: %s\r\n", peer->username);
21442  astman_append(s, "RegExtension: %s\r\n", peer->regexten);
21443  astman_append(s, "Codecs: %s\r\n", ast_format_cap_get_names(peer->caps, &codec_buf));
21444  astman_append(s, "Status: ");
21445  peer_status(peer, status, sizeof(status));
21446  astman_append(s, "%s\r\n", status);
21447  astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent);
21448  astman_append(s, "Reg-Contact: %s\r\n", peer->fullcontact);
21449  astman_append(s, "QualifyFreq: %d ms\r\n", peer->qualifyfreq);
21450  astman_append(s, "Parkinglot: %s\r\n", peer->parkinglot);
21451  if (peer->chanvars) {
21452  for (v = peer->chanvars ; v ; v = v->next) {
21453  astman_append(s, "ChanVariable: %s=%s\r\n", v->name, v->value);
21454  }
21455  }
21456  astman_append(s, "SIP-Use-Reason-Header: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_Q850_REASON)) ? "Y" : "N");
21457  astman_append(s, "Description: %s\r\n", peer->description);
21458 
21459  peer = sip_unref_peer(peer, "sip_show_peer: sip_unref_peer: done with peer");
21460 
21461  } else {
21462  ast_cli(fd, "Peer %s not found.\n", argv[3]);
21463  ast_cli(fd, "\n");
21464  }
21465 
21466  return CLI_SUCCESS;
21467 }
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:290
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
static const char * trust_id_outbound2str(int mode)
Definition: chan_sip.c:20643
int st_min_se
Definition: sip.h:978
struct ast_variable * next
#define SIP_PAGE3_RTCP_MUX
Definition: sip.h:394
static const char type[]
Definition: chan_ooh323.c:109
#define SIP_DIRECT_MEDIA
Definition: sip.h:289
int keepalive
Definition: sip.h:1360
Definition: test_heap.c:38
struct ast_namedgroups * named_pickupgroups
Definition: sip.h:1349
int force
Definition: sip.h:727
#define SIP_PAGE2_ALLOWSUBSCRIBE
Definition: sip.h:335
struct ast_sockaddr addr
Definition: sip.h:1352
int timer_t1
Definition: sip.h:1369
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3080
#define FALSE
Definition: app_minivm.c:521
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
struct sip_peer * sip_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.
Definition: chan_sip.c:5851
const ast_string_field language
Definition: sip.h:1306
const ast_string_field parkinglot
Definition: sip.h:1306
const ast_string_field mohsuggest
Definition: sip.h:1306
#define SIP_USEPATH
Definition: sip.h:305
const char * ast_describe_caller_presentation(int data)
Convert caller ID pres value to explanatory string.
Definition: callerid.c:1164
#define ast_test_flag(p, flag)
Definition: utils.h:63
const ast_string_field accountcode
Definition: sip.h:1306
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:326
int ast_check_realtime(const char *family)
Check if realtime engine is configured for family.
Definition: main/config.c:3363
Structure for variables, used for configurations and for channel variables.
int lastmsgssent
Definition: sip.h:1333
#define SIP_TRUSTRPID
Definition: sip.h:270
const char * sip_get_transport(enum ast_transport t)
Return transport as string.
Definition: chan_sip.c:3725
int maxforwards
Definition: sip.h:1331
struct ast_sockaddr defaddr
Definition: sip.h:1362
Definition: sched.c:76
#define SIP_NAT_FORCE_RPORT
Definition: sip.h:283
const char * ast_channel_amaflags2string(enum ama_flags flags)
Convert the enum representation of an AMA flag to a string representation.
Definition: channel.c:4418
unsigned short host_dynamic
Definition: sip.h:1314
#define ao2_unlock(a)
Definition: astobj2.h:730
struct sip_route path
Definition: sip.h:1372
char * text
Definition: app_queue.c:1508
#define ast_str_alloca(init_len)
Definition: strings.h:800
#define SIP_PAGE2_TRUST_ID_OUTBOUND
Definition: sip.h:370
const ast_string_field subscribecontext
Definition: sip.h:1306
#define NULL
Definition: resample.c:96
const ast_string_field vmexten
Definition: sip.h:1306
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
int st_max_se
Definition: sip.h:979
static int peer_status(struct sip_peer *peer, char *status, int statuslen)
Definition: chan_sip.c:20043
unsigned short transports
Definition: sip.h:1311
struct sip_proxy * outboundproxy
Definition: sip.h:1350
char name[80]
Definition: sip.h:1274
static const char * stmode2str(enum st_mode m)
Definition: chan_sip.c:19990
static const char * allowoverlap2str(int mode) attribute_const
Convert AllowOverlap setting to printable string.
Definition: chan_sip.c:20631
struct ast_variable * chanvars
Definition: sip.h:1366
static char * transfermode2str(enum transfermodes mode) attribute_const
Convert transfer mode to text string.
Definition: chan_sip.c:19968
char * ast_print_group(char *buf, int buflen, ast_group_t group)
Print call and pickup groups into buffer.
Definition: channel.c:8133
const char * comedia_string(struct ast_flags *flags)
Return a string describing the comedia value for the given flags.
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
const ast_string_field tohost
Definition: sip.h:1306
#define SIP_PAGE2_USE_SRTP
Definition: sip.h:368
static const char * strefresherparam2str(enum st_refresher_param r)
Definition: chan_sip.c:20015
struct ast_str * sip_route_list(const struct sip_route *route, int formatcli, int skip)
Make the comma separated list of route hops.
Definition: route.c:155
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:521
enum transfermodes allowtransfer
Definition: sip.h:1332
#define SIP_PAGE2_SYMMETRICRTP
Definition: sip.h:327
struct ast_namedgroups * named_callgroups
Definition: sip.h:1348
static const char * insecure2str(int mode) attribute_const
Convert Insecure setting to printable string.
Definition: chan_sip.c:20618
struct ast_acl_list * acl
Definition: sip.h:1363
char * ast_callerid_merge(char *buf, int bufsiz, const char *name, const char *num, const char *unknown)
Definition: callerid.c:1073
#define STANDARD_SIP_PORT
Standard SIP unsecure port for UDP and TCP from RFC 3261. DO NOT CHANGE THIS.
Definition: sip.h:176
int amaflags
Definition: sip.h:1323
static void print_group(int fd, ast_group_t group, int crlf)
Print call group and pickup group.
Definition: chan_sip.c:20571
int call_limit
Definition: sip.h:1328
const ast_string_field remotesecret
Definition: sip.h:1306
#define ao2_lock(a)
Definition: astobj2.h:718
const ast_string_field username
Definition: sip.h:1306
int id
Definition: sip.h:1828
int maxcallbitrate
Definition: sip.h:1340
const ast_string_field md5secret
Definition: sip.h:1306
#define SIP_PAGE2_VIDEOSUPPORT_ALWAYS
Definition: sip.h:366
int timer_b
Definition: sip.h:1370
const ast_string_field useragent
Definition: sip.h:1306
unsigned int t38_maxdatagram
Definition: sip.h:1329
struct ast_acl_list * directmediaacl
Definition: sip.h:1365
#define SIP_PAGE2_IGNORESDPVERSION
Definition: sip.h:344
int ast_acl_list_is_empty(struct ast_acl_list *acl_list)
Determines if an ACL is empty or if it contains entries.
Definition: acl.c:541
struct sip_auth_container::@170 list
#define SIP_PAGE2_ALLOWOVERLAP
Definition: sip.h:337
int expire
Definition: sip.h:1341
#define SIP_INSECURE
Definition: sip.h:294
#define SIP_PAGE2_Q850_REASON
Definition: sip.h:326
char name[MAXHOSTNAMELEN]
Definition: sip.h:722
struct ast_format_cap * caps
Definition: sip.h:1342
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
const ast_string_field zone
Definition: sip.h:1306
const ast_string_field fromdomain
Definition: sip.h:1306
#define CLI_SHOWUSAGE
Definition: cli.h:45
const ast_string_field record_on_feature
Definition: sip.h:1306
const ast_string_field fullcontact
Definition: sip.h:1306
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
static void print_named_groups(int fd, struct ast_namedgroups *groups, int crlf)
Print named call groups and pickup groups.
Definition: chan_sip.c:20578
const ast_string_field regexten
Definition: sip.h:1306
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition: format_cap.c:736
long ast_sched_when(struct ast_sched_context *con, int id)
Returns the number of seconds before an event takes place.
Definition: sched.c:814
#define SIP_PAGE3_NAT_AUTO_RPORT
Definition: sip.h:386
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
const char * force_rport_string(struct ast_flags *flags)
Return a string describing the force_rport value for the given flags.
static const struct cfsip_options sip_options[]
#define ast_free(a)
Definition: astmm.h:182
unsigned short is_realtime
Definition: sip.h:1312
#define FINDPEERS
Definition: sip.h:53
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
struct ast_acl_list * contactacl
Definition: sip.h:1364
enum st_mode st_mode_oper
Definition: sip.h:976
unsigned short autoframing
Definition: sip.h:1317
char username[256]
Definition: sip.h:905
#define SIP_PAGE2_TEXTSUPPORT
Definition: sip.h:334
#define SIP_PAGE2_VIDEOSUPPORT
Definition: sip.h:333
ast_group_t callgroup
Definition: sip.h:1346
#define SIP_PAGE3_NAT_AUTO_COMEDIA
Definition: sip.h:387
const ast_string_field cid_name
Definition: sip.h:1306
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:653
#define CLI_SUCCESS
Definition: cli.h:44
#define SIP_PAGE2_T38SUPPORT
Definition: sip.h:346
struct sip_auth_container * auth
Definition: sip.h:1322
const ast_string_field record_off_feature
Definition: sip.h:1306
#define SIP_DTMF
Definition: sip.h:275
enum ast_transport type
Definition: sip.h:798
static const char * faxec2str(int faxec)
Definition: chan_sip.c:21175
char realm[AST_MAX_EXTENSION]
Definition: sip.h:904
char secret[256]
Definition: sip.h:906
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
struct ast_flags flags[3]
Definition: sip.h:1335
#define TRUE
Definition: app_minivm.c:518
static const char * get_transport_list(unsigned int transports)
Return configuration of transports for a device.
Definition: chan_sip.c:3686
const ast_string_field secret
Definition: sip.h:1306
sip_auth: Credentials for authentication to other SIP services
Definition: sip.h:902
const ast_string_field cid_num
Definition: sip.h:1306
const ast_string_field fromuser
Definition: sip.h:1306
int callingpres
Definition: sip.h:1324
char md5secret[256]
Definition: sip.h:907
#define SIP_PROMISCREDIR
Definition: sip.h:269
int qualifyfreq
Definition: sip.h:1358
#define AST_CLI_YESNO(x)
Return Yes or No depending on the argument.
Definition: cli.h:71
int busy_level
Definition: sip.h:1330
struct sip_st_cfg stimer
Definition: sip.h:1368
const ast_string_field description
Definition: sip.h:1306
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159
enum st_refresher_param st_ref
Definition: sip.h:977
unsigned int sipoptions
Definition: sip.h:1334
char * ast_print_namedgroups(struct ast_str **buf, struct ast_namedgroups *groups)
Print named call groups and named pickup groups.
Definition: channel.c:8158
struct sip_socket socket
Definition: sip.h:1307
const ast_string_field engine
Definition: sip.h:1306
char regcontext[AST_MAX_CONTEXT]
Definition: sip.h:770
Container of SIP authentication credentials.
Definition: sip.h:911
#define SIP_USEREQPHONE
Definition: sip.h:271
static const char * dtmfmode2str(int mode) attribute_const
Convert DTMF mode to printable string.
Definition: chan_sip.c:20598
jack_status_t status
Definition: app_jack.c:146
int fromdomainport
Definition: sip.h:1371
ast_group_t pickupgroup
Definition: sip.h:1347
#define SIP_SENDRPID
Definition: sip.h:306
const ast_string_field context
Definition: sip.h:1306
static void peer_mailboxes_to_str(struct ast_str **mailbox_str, struct sip_peer *peer)
list peer mailboxes to CLI
Definition: chan_sip.c:21157

◆ _sip_show_peers()

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 20295 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, sip_peer::name, NULL, OBJ_MULTIPLE, 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, SIP_TYPE_PEER, sip_unref_peer, TRUE, and sip_peer::type.

Referenced by manager_sip_show_peers(), and sip_show_peers().

20296 {
20297  struct show_peers_context cont = {
20298  .havepattern = FALSE,
20299  .idtext = "",
20300 
20301  .peers_mon_online = 0,
20302  .peers_mon_offline = 0,
20303  .peers_unmon_online = 0,
20304  .peers_unmon_offline = 0,
20305  };
20306 
20307  struct sip_peer *peer;
20308  struct ao2_iterator* it_peers;
20309 
20310  int total_peers = 0;
20311  const char *id;
20312  struct sip_peer **peerarray;
20313  int k;
20314 
20315  cont.realtimepeers = ast_check_realtime("sippeers");
20316 
20317  if (s) { /* Manager - get ActionID */
20318  id = astman_get_header(m, "ActionID");
20319  if (!ast_strlen_zero(id)) {
20320  snprintf(cont.idtext, sizeof(cont.idtext), "ActionID: %s\r\n", id);
20321  }
20322  }
20323 
20324  switch (argc) {
20325  case 5:
20326  if (!strcasecmp(argv[3], "like")) {
20327  if (regcomp(&cont.regexbuf, argv[4], REG_EXTENDED | REG_NOSUB)) {
20328  return CLI_SHOWUSAGE;
20329  }
20330  cont.havepattern = TRUE;
20331  } else {
20332  return CLI_SHOWUSAGE;
20333  }
20334  case 3:
20335  break;
20336  default:
20337  return CLI_SHOWUSAGE;
20338  }
20339 
20340  if (!s) {
20341  /* Normal list */
20342  ast_cli(fd, PEERS_FORMAT2, "Name/username", "Host", "Dyn", "Forcerport", "Comedia", "ACL", "Port", "Status", "Description", (cont.realtimepeers ? "Realtime" : ""));
20343  }
20344 
20345  ao2_lock(peers);
20346  if (!(it_peers = ao2_callback(peers, OBJ_MULTIPLE, NULL, NULL))) {
20347  ast_log(AST_LOG_ERROR, "Unable to create iterator for peers container for sip show peers\n");
20348  ao2_unlock(peers);
20349  return CLI_FAILURE;
20350  }
20351  if (!(peerarray = ast_calloc(sizeof(struct sip_peer *), ao2_container_count(peers)))) {
20352  ast_log(AST_LOG_ERROR, "Unable to allocate peer array for sip show peers\n");
20353  ao2_iterator_destroy(it_peers);
20354  ao2_unlock(peers);
20355  return CLI_FAILURE;
20356  }
20357  ao2_unlock(peers);
20358 
20359  while ((peer = ao2_t_iterator_next(it_peers, "iterate thru peers table"))) {
20360  ao2_lock(peer);
20361 
20362  if (!(peer->type & SIP_TYPE_PEER)) {
20363  ao2_unlock(peer);
20364  sip_unref_peer(peer, "unref peer because it's actually a user");
20365  continue;
20366  }
20367 
20368  if (cont.havepattern && regexec(&cont.regexbuf, peer->name, 0, NULL, 0)) {
20369  ao2_unlock(peer);
20370  sip_unref_peer(peer, "toss iterator peer ptr before continue");
20371  continue;
20372  }
20373 
20374  peerarray[total_peers++] = peer;
20375  ao2_unlock(peer);
20376  }
20377  ao2_iterator_destroy(it_peers);
20378 
20379  qsort(peerarray, total_peers, sizeof(struct sip_peer *), peercomparefunc);
20380 
20381  for(k = 0; k < total_peers; k++) {
20382  peerarray[k] = _sip_show_peers_one(fd, s, &cont, peerarray[k]);
20383  }
20384 
20385  if (!s) {
20386  ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n",
20387  total_peers, cont.peers_mon_online, cont.peers_mon_offline, cont.peers_unmon_online, cont.peers_unmon_offline);
20388  }
20389 
20390  if (cont.havepattern) {
20391  regfree(&cont.regexbuf);
20392  }
20393 
20394  if (total) {
20395  *total = total_peers;
20396  }
20397 
20398  ast_free(peerarray);
20399 
20400  return CLI_SUCCESS;
20401 }
#define FALSE
Definition: app_minivm.c:521
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
char idtext[256]
Definition: chan_iax2.c:6833
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.
Definition: chan_sip.c:20404
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
int ast_check_realtime(const char *family)
Check if realtime engine is configured for family.
Definition: main/config.c:3363
Used in the sip_show_peers functions to pass parameters.
Definition: chan_iax2.c:6830
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_unlock(a)
Definition: astobj2.h:730
enum sip_peer_type type
Definition: sip.h:1375
#define NULL
Definition: resample.c:96
#define PEERS_FORMAT2
Definition: chan_sip.c:20280
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
char name[80]
Definition: sip.h:1274
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#define AST_LOG_ERROR
Definition: logger.h:290
#define ao2_lock(a)
Definition: astobj2.h:718
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define ao2_t_iterator_next(iter, tag)
Definition: astobj2.h:1931
#define CLI_FAILURE
Definition: cli.h:46
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
int peercomparefunc(const void *a, const void *b)
Definition: chan_sip.c:20272
#define CLI_SUCCESS
Definition: cli.h:44
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
#define TRUE
Definition: app_minivm.c:518
static int total
Definition: res_adsi.c:968
enum queue_result id
Definition: app_queue.c:1507

◆ _sip_show_peers_one()

static struct sip_peer * _sip_show_peers_one ( int  fd,
struct mansession s,
struct show_peers_context cont,
struct sip_peer peer 
)
static

Emit informations for one peer during sip show peers command.

Definition at line 20404 of file chan_sip.c.

References sip_peer::accountcode, sip_peer::acl, sip_peer::addr, ao2_lock, ao2_unlock, ast_acl_list_is_empty(), 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(), comedia_string(), sip_peer::description, sip_peer::flags, force_rport_string(), show_peers_context::havepattern, sip_peer::host_dynamic, show_peers_context::idtext, sip_peer::is_realtime, name, sip_peer::name, NULL, 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, SIP_NAT_FORCE_RPORT, SIP_PAGE2_SYMMETRICRTP, SIP_PAGE2_TEXTSUPPORT, SIP_PAGE2_VIDEOSUPPORT, SIP_PAGE3_NAT_AUTO_COMEDIA, SIP_PAGE3_NAT_AUTO_RPORT, sip_unref_peer, status, and sip_peer::username.

Referenced by _sip_show_peers().

20405 {
20406  /* _sip_show_peers_one() is separated from _sip_show_peers() to properly free the ast_strdupa
20407  * (this is executed in a loop in _sip_show_peers() )
20408  */
20409 
20410  char name[256];
20411  char status[20] = "";
20412  char pstatus;
20413 
20414  /*
20415  * tmp_port and tmp_host store copies of ast_sockaddr_stringify strings since the
20416  * string pointers for that function aren't valid between subsequent calls to
20417  * ast_sockaddr_stringify functions
20418  */
20419  char *tmp_port;
20420  char *tmp_host;
20421 
20422  tmp_port = ast_sockaddr_isnull(&peer->addr) ?
20424 
20425  tmp_host = ast_sockaddr_isnull(&peer->addr) ?
20426  "(Unspecified)" : ast_strdupa(ast_sockaddr_stringify_addr(&peer->addr));
20427 
20428  ao2_lock(peer);
20429  if (cont->havepattern && regexec(&cont->regexbuf, peer->name, 0, NULL, 0)) {
20430  ao2_unlock(peer);
20431  return sip_unref_peer(peer, "toss iterator peer ptr no match");
20432  }
20433 
20434  if (!ast_strlen_zero(peer->username) && !s) {
20435  snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
20436  } else {
20437  ast_copy_string(name, peer->name, sizeof(name));
20438  }
20439 
20440  pstatus = peer_status(peer, status, sizeof(status));
20441  if (pstatus == 1) {
20442  cont->peers_mon_online++;
20443  } else if (pstatus == 0) {
20444  cont->peers_mon_offline++;
20445  } else {
20446  if (ast_sockaddr_isnull(&peer->addr) ||
20447  !ast_sockaddr_port(&peer->addr)) {
20448  cont->peers_unmon_offline++;
20449  } else {
20450  cont->peers_unmon_online++;
20451  }
20452  }
20453 
20454  if (!s) { /* Normal CLI list */
20455  ast_cli(fd, PEERS_FORMAT2, name,
20456  tmp_host,
20457  peer->host_dynamic ? " D " : " ", /* Dynamic or not? */
20458  force_rport_string(peer->flags),
20459  comedia_string(peer->flags),
20460  (!ast_acl_list_is_empty(peer->acl)) ? " A " : " ", /* permit/deny */
20461  tmp_port, status,
20462  peer->description ? peer->description : "",
20463  cont->realtimepeers ? (peer->is_realtime ? "Cached RT" : "") : "");
20464  } else { /* Manager format */
20465  /* The names here need to be the same as other channels */
20466  astman_append(s,
20467  "Event: PeerEntry\r\n%s"
20468  "Channeltype: SIP\r\n"
20469  "ObjectName: %s\r\n"
20470  "ChanObjectType: peer\r\n" /* "peer" or "user" */
20471  "IPaddress: %s\r\n"
20472  "IPport: %s\r\n"
20473  "Dynamic: %s\r\n"
20474  "AutoForcerport: %s\r\n"
20475  "Forcerport: %s\r\n"
20476  "AutoComedia: %s\r\n"
20477  "Comedia: %s\r\n"
20478  "VideoSupport: %s\r\n"
20479  "TextSupport: %s\r\n"
20480  "ACL: %s\r\n"
20481  "Status: %s\r\n"
20482  "RealtimeDevice: %s\r\n"
20483  "Description: %s\r\n"
20484  "Accountcode: %s\r\n"
20485  "\r\n",
20486  cont->idtext,
20487  peer->name,
20488  ast_sockaddr_isnull(&peer->addr) ? "-none-" : tmp_host,
20489  ast_sockaddr_isnull(&peer->addr) ? "0" : tmp_port,
20490  peer->host_dynamic ? "yes" : "no", /* Dynamic or not? */
20491  ast_test_flag(&peer->flags[2], SIP_PAGE3_NAT_AUTO_RPORT) ? "yes" : "no",
20492  ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? "yes" : "no",
20493  ast_test_flag(&peer->flags[2], SIP_PAGE3_NAT_AUTO_COMEDIA) ? "yes" : "no",
20494  ast_test_flag(&peer->flags[1], SIP_PAGE2_SYMMETRICRTP) ? "yes" : "no",
20495  ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */
20496  ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT) ? "yes" : "no", /* TEXTSUPPORT=yes? */
20497  ast_acl_list_is_empty(peer->acl) ? "no" : "yes", /* permit/deny/acl */
20498  status,
20499  cont->realtimepeers ? (peer->is_realtime ? "yes" : "no") : "no",
20500  peer->description,
20501  peer->accountcode);
20502  }
20503  ao2_unlock(peer);
20504 
20505  return sip_unref_peer(peer, "toss iterator peer ptr");
20506 }
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:290
struct ast_sockaddr addr
Definition: sip.h:1352
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3080
char idtext[256]
Definition: chan_iax2.c:6833
#define ast_test_flag(p, flag)
Definition: utils.h:63
const ast_string_field accountcode
Definition: sip.h:1306
#define SIP_NAT_FORCE_RPORT
Definition: sip.h:283
unsigned short host_dynamic
Definition: sip.h:1314
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
#define PEERS_FORMAT2
Definition: chan_sip.c:20280
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
static int peer_status(struct sip_peer *peer, char *status, int statuslen)
Definition: chan_sip.c:20043
char name[80]
Definition: sip.h:1274
const char * comedia_string(struct ast_flags *flags)
Return a string describing the comedia value for the given flags.
#define ast_strlen_zero(foo)
Definition: strings.h:52
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:521
#define SIP_PAGE2_SYMMETRICRTP
Definition: sip.h:327
static char * ast_sockaddr_stringify_port(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return a port only.
Definition: netsock2.h:362
struct ast_acl_list * acl
Definition: sip.h:1363
#define ao2_lock(a)
Definition: astobj2.h:718
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
const ast_string_field username
Definition: sip.h:1306
int ast_acl_list_is_empty(struct ast_acl_list *acl_list)
Determines if an ACL is empty or if it contains entries.
Definition: acl.c:541
#define SIP_PAGE3_NAT_AUTO_RPORT
Definition: sip.h:386
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
const char * force_rport_string(struct ast_flags *flags)
Return a string describing the force_rport value for the given flags.
static const char name[]
Definition: cdr_mysql.c:74
unsigned short is_realtime
Definition: sip.h:1312
#define SIP_PAGE2_TEXTSUPPORT
Definition: sip.h:334
#define SIP_PAGE2_VIDEOSUPPORT
Definition: sip.h:333
#define SIP_PAGE3_NAT_AUTO_COMEDIA
Definition: sip.h:387
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
struct ast_flags flags[3]
Definition: sip.h:1335
const ast_string_field description
Definition: sip.h:1306
jack_status_t status
Definition: app_jack.c:146

◆ _sip_tcp_helper_thread()

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

References sip_threadinfo::alert_pipe, ao2_lock, ao2_ref, ao2_t_find, ao2_t_ref, ao2_t_unlink, ao2_unlock, ast_atomic_fetchadd_int(), ast_debug, ast_iostream_get_fd(), ast_iostream_get_ssl(), ast_iostream_nonblock(), ast_iostream_set_exclusive_input(), ast_iostream_set_timeout_disable(), ast_iostream_set_timeout_sequence(), ast_iostream_write(), AST_LIST_REMOVE_HEAD, ast_log, ast_poll, ast_str_buffer(), ast_str_create, ast_str_reset(), ast_str_strlen(), ast_tcptls_client_start(), ast_tcptls_close_session_file(), AST_TRANSPORT_TCP, AST_TRANSPORT_TLS, ast_tvnow(), sip_request::authenticated, authlimit, authtimeout, buf, cleanup(), ast_tcptls_session_instance::client, sip_request::data, tcptls_packet::data, deinit_req(), errno, sip_socket::fd, handle_request_do(), tcptls_packet::len, LOG_ERROR, LOG_WARNING, NULL, OBJ_POINTER, ast_tcptls_session_instance::overflow_buf, sip_threadinfo::packet_q, ast_tcptls_session_instance::parent, ast_tcptls_session_instance::remote_address, set_socket_transport(), sip_check_authtimeout(), SIP_MIN_PACKET, sip_tcptls_read(), sip_threadinfo_create(), sip_request::socket, ast_tcptls_session_instance::stream, TCPTLS_ALERT_DATA, TCPTLS_ALERT_STOP, sip_socket::tcptls_session, sip_threadinfo::threadid, timeout, tmp(), unauth_sessions, and sip_socket::ws_session.

Referenced by sip_tcp_worker_fn().

2986 {
2987  int res, timeout = -1, authenticated = 0, flags;
2988  time_t start;
2989  struct sip_request req = { 0, } , reqcpy = { 0, };
2990  struct sip_threadinfo *me = NULL;
2991  char buf[1024] = "";
2992  struct pollfd fds[2] = { { 0 }, { 0 }, };
2993  struct ast_tcptls_session_args *ca = NULL;
2994 
2995  /* If this is a server session, then the connection has already been
2996  * setup. Check if the authlimit has been reached and if not create the
2997  * threadinfo object so we can access this thread for writing.
2998  *
2999  * if this is a client connection more work must be done.
3000  * 1. We own the parent session args for a client connection. This pointer needs
3001  * to be held on to so we can decrement it's ref count on thread destruction.
3002  * 2. The threadinfo object was created before this thread was launched, however
3003  * it must be found within the threadt table.
3004  * 3. Last, the tcptls_session must be started.
3005  */
3006  if (!tcptls_session->client) {
3008  /* unauth_sessions is decremented in the cleanup code */
3009  goto cleanup;
3010  }
3011 
3012  ast_iostream_nonblock(tcptls_session->stream);
3013  if (!(me = sip_threadinfo_create(tcptls_session, ast_iostream_get_ssl(tcptls_session->stream) ? AST_TRANSPORT_TLS : AST_TRANSPORT_TCP))) {
3014  goto cleanup;
3015  }
3016  me->threadid = pthread_self();
3017  ao2_t_ref(me, +1, "Adding threadinfo ref for tcp_helper_thread");
3018  } else {
3019  struct sip_threadinfo tmp = {
3020  .tcptls_session = tcptls_session,
3021  };
3022 
3023  if ((!(ca = tcptls_session->parent)) ||
3024  (!(me = ao2_t_find(threadt, &tmp, OBJ_POINTER, "ao2_find, getting sip_threadinfo in tcp helper thread")))) {
3025  goto cleanup;
3026  }
3027 
3028  me->threadid = pthread_self();
3029 
3030  if (!(tcptls_session = ast_tcptls_client_start(tcptls_session))) {
3031  goto cleanup;
3032  }
3033  }
3034 
3035  flags = 1;
3036  if (setsockopt(ast_iostream_get_fd(tcptls_session->stream), SOL_SOCKET, SO_KEEPALIVE, &flags, sizeof(flags))) {
3037  ast_log(LOG_ERROR, "error enabling TCP keep-alives on sip socket: %s\n", strerror(errno));
3038  goto cleanup;
3039  }
3040 
3041  ast_debug(2, "Starting thread for %s server\n", ast_iostream_get_ssl(tcptls_session->stream) ? "TLS" : "TCP");
3042 
3043  /* set up pollfd to watch for reads on both the socket and the alert_pipe */
3044  fds[0].fd = ast_iostream_get_fd(tcptls_session->stream);
3045  fds[1].fd = me->alert_pipe[0];
3046  fds[0].events = fds[1].events = POLLIN | POLLPRI;
3047 
3048  if (!(req.data = ast_str_create(SIP_MIN_PACKET))) {
3049  goto cleanup;
3050  }
3051  if (!(reqcpy.data = ast_str_create(SIP_MIN_PACKET))) {
3052  goto cleanup;
3053  }
3054 
3055  if(time(&start) == -1) {
3056  ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
3057  goto cleanup;
3058  }
3059 
3060  /*
3061  * We cannot let the stream exclusively wait for data to arrive.
3062  * We have to wake up the task to send outgoing messages.
3063  */
3064  ast_iostream_set_exclusive_input(tcptls_session->stream, 0);
3065 
3067  tcptls_session->client ? -1 : (authtimeout * 1000));
3068 
3069  for (;;) {
3070  struct ast_str *str_save;
3071 
3072  if (!tcptls_session->client && req.authenticated && !authenticated) {
3073  authenticated = 1;
3074  ast_iostream_set_timeout_disable(tcptls_session->stream);
3076  }
3077 
3078  /* calculate the timeout for unauthenticated server sessions */
3079  if (!tcptls_session->client && !authenticated ) {
3080  if ((timeout = sip_check_authtimeout(start)) < 0) {
3081  goto cleanup;
3082  }
3083 
3084  if (timeout == 0) {
3085  ast_debug(2, "SIP %s server timed out\n", ast_iostream_get_ssl(tcptls_session->stream) ? "TLS": "TCP");
3086  goto cleanup;
3087  }
3088  } else {
3089  timeout = -1;
3090  }
3091 
3092  if (ast_str_strlen(tcptls_session->overflow_buf) == 0) {
3093  res = ast_poll(fds, 2, timeout); /* polls for both socket and alert_pipe */
3094  if (res < 0) {
3095  ast_debug(2, "SIP %s server :: ast_wait_for_input returned %d\n", ast_iostream_get_ssl(tcptls_session->stream) ? "TLS": "TCP", res);
3096  goto cleanup;
3097  } else if (res == 0) {
3098  /* timeout */
3099  ast_debug(2, "SIP %s server timed out\n", ast_iostream_get_ssl(tcptls_session->stream) ? "TLS": "TCP");
3100  goto cleanup;
3101  }
3102  }
3103 
3104  /*
3105  * handle the socket event, check for both reads from the socket fd or TCP overflow buffer,
3106  * and writes from alert_pipe fd.
3107  */
3108  if (fds[0].revents || (ast_str_strlen(tcptls_session->overflow_buf) > 0)) { /* there is data on the socket to be read */
3109  fds[0].revents = 0;
3110 
3111  /* clear request structure */
3112  str_save = req.data;
3113  memset(&req, 0, sizeof(req));
3114  req.data = str_save;
3115  ast_str_reset(req.data);
3116 
3117  str_save = reqcpy.data;
3118  memset(&reqcpy, 0, sizeof(reqcpy));
3119  reqcpy.data = str_save;
3120  ast_str_reset(reqcpy.data);
3121 
3122  memset(buf, 0, sizeof(buf));
3123 
3124  if (ast_iostream_get_ssl(tcptls_session->stream)) {
3126  } else {
3128  }
3129  req.socket.fd = ast_iostream_get_fd(tcptls_session->stream);
3130 
3131  res = sip_tcptls_read(&req, tcptls_session, authenticated, start);
3132  if (res < 0) {
3133  goto cleanup;
3134  }
3135 
3136  req.socket.tcptls_session = tcptls_session;
3137  req.socket.ws_session = NULL;
3138  handle_request_do(&req, &tcptls_session->remote_address);
3139  }
3140 
3141  if (fds[1].revents) { /* alert_pipe indicates there is data in the send queue to be sent */
3142  enum sip_tcptls_alert alert;
3143  struct tcptls_packet *packet;
3144 
3145  fds[1].revents = 0;
3146 
3147  if (read(me->alert_pipe[0], &alert, sizeof(alert)) == -1) {
3148  ast_log(LOG_ERROR, "read() failed: %s\n", strerror(errno));
3149  goto cleanup;
3150  }
3151 
3152  switch (alert) {
3153  case TCPTLS_ALERT_STOP:
3154  goto cleanup;
3155  case TCPTLS_ALERT_DATA:
3156  ao2_lock(me);
3157  if (!(packet = AST_LIST_REMOVE_HEAD(&me->packet_q, entry))) {
3158  ast_log(LOG_WARNING, "TCPTLS thread alert_pipe indicated packet should be sent, but frame_q is empty\n");
3159  }
3160  ao2_unlock(me);
3161 
3162  if (packet) {
3163  if (ast_iostream_write(tcptls_session->stream, ast_str_buffer(packet->data), packet->len) == -1) {
3164  ast_log(LOG_WARNING, "Failure to write to tcp/tls socket\n");
3165  }
3166  ao2_t_ref(packet, -1, "tcptls packet sent, this is no longer needed");
3167  } else {
3168  goto cleanup;
3169  }
3170  break;
3171  default:
3172  ast_log(LOG_ERROR, "Unknown tcptls thread alert '%u'\n", alert);
3173  goto cleanup;
3174  }
3175  }
3176  }
3177 
3178  ast_debug(2, "Shutting down thread for %s server\n", ast_iostream_get_ssl(tcptls_session->stream) ? "TLS" : "TCP");
3179 
3180 cleanup:
3181  if (tcptls_session && !tcptls_session->client && !authenticated) {
3183  }
3184 
3185  if (me) {
3186  ao2_t_unlink(threadt, me, "Removing tcptls helper thread, thread is closing");
3187  ao2_t_ref(me, -1, "Removing tcp_helper_threads threadinfo ref");
3188  }
3189  deinit_req(&reqcpy);
3190  deinit_req(&req);
3191 
3192  /* if client, we own the parent session arguments and must decrement ref */
3193  if (ca) {
3194  ao2_t_ref(ca, -1, "closing tcptls thread, getting rid of client tcptls_session arguments");
3195  }
3196 
3197  if (tcptls_session) {
3198  ao2_lock(tcptls_session);
3199  ast_tcptls_close_session_file(tcptls_session);
3200  tcptls_session->parent = NULL;
3201  ao2_unlock(tcptls_session);
3202 
3203  ao2_ref(tcptls_session, -1);
3204  tcptls_session = NULL;
3205  }
3206  return NULL;
3207 }
void ast_iostream_set_exclusive_input(struct ast_iostream *stream, int exclusive_input)
Set the iostream if it can exclusively depend upon the set timeouts.
Definition: iostream.c:148
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
static struct ao2_container * threadt
The table of TCP threads.
Definition: chan_sip.c:1049
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.
Definition: chan_sip.c:2918
A request to stop the tcp_handler thread.
Definition: sip.h:699
struct ast_str * data
Definition: sip.h:1437
ssize_t ast_iostream_write(struct ast_iostream *stream, const void *buffer, size_t count)
Write data to an iostream.
Definition: iostream.c:374
There is new data to be sent out.
Definition: sip.h:698
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
struct ast_str * overflow_buf
Definition: tcptls.h:158
#define OBJ_POINTER
Definition: astobj2.h:1154
static int sip_check_authtimeout(time_t start)
Check if the authtimeout has expired.
Definition: chan_sip.c:2740
#define LOG_WARNING
Definition: logger.h:274
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
struct ast_tcptls_session_args * parent
Definition: tcptls.h:152
static int timeout
Definition: cdr_mysql.c:86
static int tmp()
Definition: bt_open.c:389
#define ao2_t_unlink(container, obj, tag)
Remove an object from a container.
Definition: astobj2.h:1596
int ast_iostream_get_fd(struct ast_iostream *stream)
Get an iostream&#39;s file descriptor.
Definition: iostream.c:84
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
arguments for the accepting thread
Definition: tcptls.h:129
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
pthread_t threadid
Definition: sip.h:1445
int fd
Definition: sip.h:799
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:755
static void deinit_req(struct sip_request *req)
Deinitialize SIP response/request.
Definition: chan_sip.c:12195
SSL * ast_iostream_get_ssl(struct ast_iostream *stream)
Get a pointer to an iostream&#39;s OpenSSL SSL structure.
Definition: iostream.c:108
struct ast_websocket * ws_session
Definition: sip.h:802
Definition of a thread that handles a socket.
Definition: sip.h:1441
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define ast_poll(a, b, c)
Definition: poll-compat.h:88
int alert_pipe[2]
Definition: sip.h:1444
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
static int authlimit
Definition: chan_sip.c:675
char authenticated
Definition: sip.h:840
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
struct ast_tcptls_session_instance * tcptls_session
Definition: sip.h:801
void ast_iostream_set_timeout_disable(struct ast_iostream *stream)
Disable the iostream timeout timer.
Definition: iostream.c:113
#define LOG_ERROR
Definition: logger.h:285
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
void ast_iostream_set_timeout_sequence(struct ast_iostream *stream, struct timeval start, int timeout)
Set the iostream I/O sequence timeout timer.
Definition: iostream.c:139
struct ast_str * data
Definition: sip.h:843
int errno
struct sip_threadinfo::@178 packet_q
static int unauth_sessions
Definition: chan_sip.c:674
static void * cleanup(void *unused)
Definition: pbx_realtime.c:124
struct ast_iostream * stream
Definition: tcptls.h:160
static int authtimeout
Definition: chan_sip.c:676
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:653
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
#define SIP_MIN_PACKET
Definition: sip.h:114
static int handle_request_do(struct sip_request *req, struct ast_sockaddr *addr)
Handle incoming SIP message - request or response.
Definition: chan_sip.c:29424
sip_tcptls_alert
Definition: sip.h:697
void ast_tcptls_close_session_file(struct ast_tcptls_session_instance *tcptls_session)
Closes a tcptls session instance&#39;s file and/or file descriptor. The tcptls_session will be set to NUL...
Definition: tcptls.c:839
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.
Definition: chan_sip.c:2584
struct ast_flags flags[3]
Definition: sip.h:1335
#define ao2_t_find(container, arg, flags, tag)
Definition: astobj2.h:1754
void ast_iostream_nonblock(struct ast_iostream *stream)
Make an iostream non-blocking.
Definition: iostream.c:103
size_t len
Definition: sip.h:1438
Definition: search.h:40
struct ast_tcptls_session_instance * ast_tcptls_client_start(struct ast_tcptls_session_instance *tcptls_session)
attempts to connect and start tcptls session, on error the tcptls_session&#39;s ref count is decremented...
Definition: tcptls.c:585
struct sip_socket socket
Definition: sip.h:846
static void set_socket_transport(struct sip_socket *socket, int transport)
Definition: chan_sip.c:16629
struct ast_tcptls_session_instance * tcptls_session
Definition: sip.h:1446
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620
struct ast_sockaddr remote_address
Definition: tcptls.h:151

◆ acl_change_event_stasis_unsubscribe()

static void acl_change_event_stasis_unsubscribe ( void  )
static

Definition at line 17573 of file chan_sip.c.

References stasis_unsubscribe_and_join().

Referenced by unload_module().

17574 {
17576 }
static struct stasis_subscription * acl_change_sub
Definition: chan_sip.c:888
struct stasis_subscription * stasis_unsubscribe_and_join(struct stasis_subscription *subscription)
Cancel a subscription, blocking until the last message is processed.
Definition: stasis.c:1136

◆ acl_change_stasis_cb()

static void acl_change_stasis_cb ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Definition at line 30104 of file chan_sip.c.

References ast_log, ast_mutex_lock, ast_mutex_unlock, ast_named_acl_change_type(), ast_verbose(), CHANNEL_ACL_RELOAD, LOG_NOTICE, restart_monitor(), sip_reload_lock, sip_reloading, sip_reloadreason, stasis_message_type(), and TRUE.

Referenced by acl_change_stasis_subscribe().

30106 {
30107  if (stasis_message_type(message) != ast_named_acl_change_type()) {
30108  return;
30109  }
30110 
30111  ast_log(LOG_NOTICE, "Reloading chan_sip in response to ACL change event.\n");
30112 
30114 
30115  if (sip_reloading) {
30116  ast_verbose("Previous SIP reload not yet done\n");
30117  } else {
30118  sip_reloading = TRUE;
30120  }
30121 
30123 
30124  restart_monitor();
30125 }
static int sip_reloading
Definition: chan_sip.c:905
static enum channelreloadreason sip_reloadreason
Definition: chan_sip.c:906
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
struct stasis_message_type * ast_named_acl_change_type(void)
a stasis_message_type for changes against a named ACL or the set of all named ACLs ...
#define ast_mutex_lock(a)
Definition: lock.h:187
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
#define ast_log
Definition: astobj2.c:42
static ast_mutex_t sip_reload_lock
Definition: chan_sip.c:899
#define LOG_NOTICE
Definition: logger.h:263
#define TRUE
Definition: app_minivm.c:518
static int restart_monitor(void)
Start the channel monitor thread.
Definition: chan_sip.c:30078
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ acl_change_stasis_subscribe()

static void acl_change_stasis_subscribe ( void  )
static

Definition at line 17562 of file chan_sip.c.

References acl_change_stasis_cb(), ast_named_acl_change_type(), ast_security_topic(), NULL, stasis_subscribe, stasis_subscription_accept_message_type(), STASIS_SUBSCRIPTION_FILTER_SELECTIVE, and stasis_subscription_set_filter().

Referenced by build_peer(), and reload_config().

17563 {
17564  if (!acl_change_sub) {
17569  }
17570 
17571 }
struct stasis_topic * ast_security_topic(void)
A stasis_topic which publishes messages for security related issues.
int stasis_subscription_set_filter(struct stasis_subscription *subscription, enum stasis_subscription_message_filter filter)
Set the message type filtering level on a subscription.
Definition: stasis.c:1079
struct stasis_message_type * ast_named_acl_change_type(void)
a stasis_message_type for changes against a named ACL or the set of all named ACLs ...
static void acl_change_stasis_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: chan_sip.c:30104
#define NULL
Definition: resample.c:96
#define stasis_subscribe(topic, callback, data)
Definition: stasis.h:652
static struct stasis_subscription * acl_change_sub
Definition: chan_sip.c:888
int stasis_subscription_accept_message_type(struct stasis_subscription *subscription, const struct stasis_message_type *type)
Indicate to a subscription that we are interested in a message type.
Definition: stasis.c:1025

◆ add_blank()

static void add_blank ( struct sip_request req)
static

add a blank line if no body

Definition at line 4663 of file chan_sip.c.

References ast_str_append(), sip_request::data, and sip_request::lines.

Referenced by send_request(), and send_response().

4664 {
4665  if (!req->lines) {
4666  /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */
4667  ast_str_append(&req->data, 0, "\r\n");
4668  }
4669 }
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
struct ast_str * data
Definition: sip.h:843
int lines
Definition: sip.h:834

◆ add_cc_call_info_to_response()

static void add_cc_call_info_to_response ( struct sip_pvt p,
struct sip_request resp 
)
static

Definition at line 14090 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, sip_pvt::callid, find_sip_cc_agent_by_original_callid(), generate_uri(), LOG_WARNING, ast_cc_agent::private_data, SIPBUFSIZE, and sip_cc_agent_pvt::subscribe_uri.

Referenced by __transmit_response(), and transmit_response_with_sdp().

14091 {
14092  char uri[SIPBUFSIZE];
14095  struct sip_cc_agent_pvt *agent_pvt;
14096 
14097  if (!agent) {
14098  /* Um, what? How could the SIP_OFFER_CC flag be set but there not be an
14099  * agent? Oh well, we'll just warn and return without adding the header.
14100  */
14101  ast_log(LOG_WARNING, "Can't find SIP CC agent for call '%s' even though OFFER_CC flag was set?\n", p->callid);
14102  return;
14103  }
14104 
14105  agent_pvt = agent->private_data;
14106 
14107  if (!ast_strlen_zero(agent_pvt->subscribe_uri)) {
14108  ast_copy_string(uri, agent_pvt->subscribe_uri, sizeof(uri));
14109  } else {
14110  generate_uri(p, uri, sizeof(uri));
14111  ast_copy_string(agent_pvt->subscribe_uri, uri, sizeof(agent_pvt->subscribe_uri));
14112  }
14113  /* XXX Hardcode "NR" as the m reason for now. This should perhaps be changed
14114  * to be more accurate. This parameter has no bearing on the actual operation
14115  * of the feature; it's just there for informational purposes.
14116  */
14117  ast_str_set(&header, 0, "<%s>;purpose=call-completion;m=%s", uri, "NR");
14118  add_header(resp, "Call-Info", ast_str_buffer(header));
14119  ao2_ref(agent, -1);
14120 }
void * private_data
Definition: ccss.h:871
#define LOG_WARNING
Definition: logger.h:274
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define ast_str_alloca(init_len)
Definition: strings.h:800
char subscribe_uri[SIPBUFSIZE]
Definition: sip.h:1809
#define ast_strlen_zero(foo)
Definition: strings.h:52
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static char * generate_uri(struct sip_pvt *pvt, char *buf, size_t size)
Definition: chan_sip.c:8809
const ast_string_field callid
Definition: sip.h:1063
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
Structure representing an agent.
#define SIPBUFSIZE
Definition: sip.h:56
static struct ast_cc_agent * find_sip_cc_agent_by_original_callid(struct sip_pvt *pvt)
Definition: chan_sip.c:1878
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873

◆ add_codec_to_sdp()

static void add_codec_to_sdp ( const struct sip_pvt p,
struct ast_format codec,
struct ast_str **  m_buf,
struct ast_str **  a_buf,
int  debug,
int *  min_packet_size,
int *  max_packet_size 
)
static

Add codec offer to SDP offer/answer body in INVITE or 200 OK.

Definition at line 13241 of file chan_sip.c.

References ast_format_cap_get_format_framing(), ast_format_cmp(), AST_FORMAT_CMP_EQUAL, ast_format_g719, ast_format_g723, ast_format_generate_sdp_fmtp(), ast_format_get_maximum_ms(), ast_format_get_name(), ast_format_opus, 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_RTP_PT_LAST_STATIC, ast_str_append(), ast_test_flag, ast_verbose(), sip_pvt::caps, sip_settings::compactheaders, sip_pvt::flags, sip_pvt::rtp, sip_cfg, and SIP_G726_NONSTANDARD.

Referenced by add_sdp().

13248 {
13249  int rtp_code;
13250  const char *mime;
13251  unsigned int rate, framing;
13252 
13253  if (debug)
13254  ast_verbose("Adding codec %s to SDP\n", ast_format_get_name(format));
13255 
13256  if (((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->rtp), 1, format, 0)) == -1) ||
13258  !(rate = ast_rtp_lookup_sample_rate2(1, format, 0))) {
13259  return;
13260  }
13261 
13262  ast_str_append(m_buf, 0, " %d", rtp_code);
13263  /* Opus mandates 2 channels in rtpmap */
13265  ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%u/2\r\n", rtp_code, mime, rate);
13266  } else if ((AST_RTP_PT_LAST_STATIC < rtp_code) || !(sip_cfg.compactheaders)) {
13267  ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%u\r\n", rtp_code, mime, rate);
13268  }
13269 
13270  ast_format_generate_sdp_fmtp(format, rtp_code, a_buf);
13271 
13273 
13275  /* Indicate that we don't support VAD (G.723.1 annex A) */
13276  ast_str_append(a_buf, 0, "a=fmtp:%d annexa=no\r\n", rtp_code);
13278  /* Indicate that we only expect 64Kbps */
13279  ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=64000\r\n", rtp_code);
13280  }
13281 
13282  if (max_packet_size && ast_format_get_maximum_ms(format) &&
13283  (ast_format_get_maximum_ms(format) < *max_packet_size)) {
13284  *max_packet_size = ast_format_get_maximum_ms(format);
13285  }
13286 
13287  if (framing && (framing < *min_packet_size)) {
13288  *min_packet_size = framing;
13289  }
13290 
13291  /* Our first codec packetization processed cannot be zero */
13292  if ((*min_packet_size) == 0 && framing) {
13293  *min_packet_size = framing;
13294  }
13295 
13296  if ((*max_packet_size) == 0 && ast_format_get_maximum_ms(format)) {
13297  *max_packet_size = ast_format_get_maximum_ms(format);
13298  }
13299 }
struct ast_format * ast_format_g723
Built-in cached g723.1 format.
Definition: format_cache.c:151
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_rtp_codecs * ast_rtp_instance_get_codecs(struct ast_rtp_instance *instance)
Get the codecs structure of an RTP instance.
Definition: rtp_engine.c:727
#define AST_RTP_PT_LAST_STATIC
Definition: rtp_engine.h:89
static int debug
Global debug status.
Definition: res_xmpp.c:435
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
struct ast_flags flags[3]
Definition: sip.h:1075
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
struct ast_format * ast_format_g719
Built-in cached g719 format.
Definition: format_cache.c:161
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
const char * ast_rtp_lookup_mime_subtype2(const int asterisk_format, const struct ast_format *format, int code, enum ast_rtp_options options)
Retrieve mime subtype information on a payload.
Definition: rtp_engine.c:1992
struct ast_format * ast_format_opus
Built-in cached opus format.
Definition: format_cache.c:226
int ast_rtp_codecs_payload_code(struct ast_rtp_codecs *codecs, int asterisk_format, struct ast_format *format, int code)
Retrieve a rx mapped payload type based on whether it is an Asterisk format and the code...
Definition: rtp_engine.c:1873
int compactheaders
Definition: sip.h:764
struct ast_format_cap * caps
Definition: sip.h:1099
unsigned int ast_format_cap_get_format_framing(const struct ast_format_cap *cap, const struct ast_format *format)
Get the framing for a format.
Definition: format_cap.c:443
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
unsigned int ast_rtp_lookup_sample_rate2(int asterisk_format, const struct ast_format *format, int code)
Get the sample rate associated with known RTP payload types.
Definition: rtp_engine.c:2022
struct ast_rtp_instance * rtp
Definition: sip.h:1174
unsigned int ast_format_get_maximum_ms(const struct ast_format *format)
Get the maximum amount of media carried in this format.
Definition: format.c:369
#define SIP_G726_NONSTANDARD
Definition: sip.h:310
void ast_format_generate_sdp_fmtp(const struct ast_format *format, unsigned int payload, struct ast_str **str)
This function is used to produce an fmtp SDP line for an Asterisk format. The attributes present on t...
Definition: format.c:305
static snd_pcm_format_t format
Definition: chan_alsa.c:102

◆ add_content()

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

Add content (not header) to SIP message.

Definition at line 11931 of file chan_sip.c.

References ast_log, ast_str_append(), sip_request::content, sip_request::lines, and LOG_WARNING.

Referenced by add_digit(), add_sdp(), add_text(), add_vidupdate(), sipinfo_send(), transmit_cc_notify(), transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), and transmit_state_notify().

11932 {
11933  if (req->lines) {
11934  ast_log(LOG_WARNING, "Can't add more content when the content has been finalized\n");
11935  return -1;
11936  }
11937 
11938  ast_str_append(&req->content, 0, "%s", line);
11939  return 0;
11940 }
#define LOG_WARNING
Definition: logger.h:274
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
#define ast_log
Definition: astobj2.c:42
struct ast_str * content
Definition: sip.h:844
int lines
Definition: sip.h:834

◆ add_date()

static void add_date ( struct sip_request req)
static

Add date header to SIP message.

Definition at line 12694 of file chan_sip.c.

References add_header(), NULL, and tmp().

Referenced by transmit_invite(), transmit_response_with_date(), transmit_response_with_minse(), and transmit_response_with_unsupported().

12695 {
12696  char tmp[256];
12697  struct tm tm;
12698  time_t t = time(NULL);
12699 
12700  gmtime_r(&t, &tm);
12701  strftime(tmp, sizeof(tmp), "%a, %d %b %Y %T GMT", &tm);
12702  add_header(req, "Date", tmp);
12703 }
static int tmp()
Definition: bt_open.c:389
#define NULL
Definition: resample.c:96
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873

◆ add_digit()

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

References add_content(), add_header(), and tmp().

Referenced by transmit_info_with_digit().

12961 {
12962  char tmp[256];
12963  int event;
12964  if (mode) {
12965  /* Application/dtmf short version used by some implementations */
12966  if ('0' <= digit && digit <= '9') {
12967  event = digit - '0';
12968  } else if (digit == '*') {
12969  event = 10;
12970  } else if (digit == '#') {
12971  event = 11;
12972  } else if ('A' <= digit && digit <= 'D') {
12973  event = 12 + digit - 'A';
12974  } else if ('a' <= digit && digit <= 'd') {
12975  event = 12 + digit - 'a';
12976  } else {
12977  /* Unknown digit */
12978  event = 0;
12979  }
12980  snprintf(tmp, sizeof(tmp), "%d\r\n", event);
12981  add_header(req, "Content-Type", "application/dtmf");
12982  add_content(req, tmp);
12983  } else {
12984  /* Application/dtmf-relay as documented by Cisco */
12985  snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration);
12986  add_header(req, "Content-Type", "application/dtmf-relay");
12987  add_content(req, tmp);
12988  }
12989  return 0;
12990 }
char digit
static int tmp()
Definition: bt_open.c:389
Definition: astman.c:222
static int add_content(struct sip_request *req, const char *line)
Add content (not header) to SIP message.
Definition: chan_sip.c:11931
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873

◆ add_diversion()

static void add_diversion ( struct sip_request req,
struct sip_pvt pvt 
)
static

Add "Diversion" header to outgoing message.

We need to add a Diversion header if the owner channel of this dialog has redirecting information associated with it.

Parameters
reqThe request/response to which we will add the header
pvtThe sip_pvt which represents the call-leg

Definition at line 14653 of file chan_sip.c.

References add_header(), ast_channel_redirecting(), ast_channel_redirecting_effective_from(), ast_copy_string(), ast_escape_quoted(), ast_sockaddr_stringify_host_remote(), ast_strlen_zero, ast_uri_encode(), ast_uri_sip_user, ast_party_id::name, ast_party_id::number, sip_pvt::ourip, sip_pvt::owner, sip_settings::pedanticsipchecking, ast_party_redirecting::reason, sip_settings::send_diversion, sip_cfg, sip_is_token(), sip_reason_code_to_str(), SIPBUFSIZE, ast_party_name::str, ast_party_number::str, ast_party_name::valid, and ast_party_number::valid.

Referenced by __transmit_response(), transmit_invite(), and update_redirecting().

14654 {
14655  struct ast_party_id diverting_from;
14656  const char *reason;
14657  const char *quote_str;
14658  char header_text[256];
14659  char encoded_number[SIPBUFSIZE/2];
14660 
14661  /* We skip this entirely if the configuration doesn't allow diversion headers */
14662  if (!sip_cfg.send_diversion) {
14663  return;
14664  }
14665 
14666  if (!pvt->owner) {
14667  return;
14668  }
14669 
14670  diverting_from = ast_channel_redirecting_effective_from(pvt->owner);
14671  if (!diverting_from.number.valid
14672  || ast_strlen_zero(diverting_from.number.str)) {
14673  return;
14674  }
14675 
14677  ast_uri_encode(diverting_from.number.str, encoded_number, sizeof(encoded_number), ast_uri_sip_user);
14678  } else {
14679  ast_copy_string(encoded_number, diverting_from.number.str, sizeof(encoded_number));
14680  }
14681 
14683 
14684  /* Reason is either already quoted or it is a token to not need quotes added. */
14685  quote_str = *reason == '\"' || sip_is_token(reason) ? "" : "\"";
14686 
14687  /* We at least have a number to place in the Diversion header, which is enough */
14688  if (!diverting_from.name.valid
14689  || ast_strlen_zero(diverting_from.name.str)) {
14690  snprintf(header_text, sizeof(header_text), "<sip:%s@%s>;reason=%s%s%s",
14691  encoded_number,
14693  quote_str, reason, quote_str);
14694  } else {
14695  char escaped_name[SIPBUFSIZE/2];
14697  ast_escape_quoted(diverting_from.name.str, escaped_name, sizeof(escaped_name));
14698  } else {
14699  ast_copy_string(escaped_name, diverting_from.name.str, sizeof(escaped_name));
14700  }
14701  snprintf(header_text, sizeof(header_text), "\"%s\" <sip:%s@%s>;reason=%s%s%s",
14702  escaped_name,
14703  encoded_number,
14705  quote_str, reason, quote_str);
14706  }
14707 
14708  add_header(req, "Diversion", header_text);
14709 }
Information needed to identify an endpoint in a call.
Definition: channel.h:339
static const char * sip_reason_code_to_str(struct ast_party_redirecting_reason *reason)
Definition: chan_sip.c:2471
struct ast_party_id ast_channel_redirecting_effective_from(struct ast_channel *chan)
char * ast_uri_encode(const char *string, char *outbuf, int buflen, struct ast_flags spec)
Turn text string to URI-encoded XX version.
Definition: main/utils.c:577
struct ast_sockaddr ourip
Definition: sip.h:1136
#define ast_strlen_zero(foo)
Definition: strings.h:52
static int sip_is_token(const char *str)
Definition: chan_sip.c:2449
int pedanticsipchecking
Definition: sip.h:756
#define SIPBUFSIZE
Definition: sip.h:56
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
static char * ast_sockaddr_stringify_host_remote(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only, suitable for a URL (with brack...
Definition: netsock2.h:349
char * ast_escape_quoted(const char *string, char *outbuf, int buflen)
Escape characters found in a quoted string.
Definition: main/utils.c:635
struct ast_channel * owner
Definition: sip.h:1138
struct ast_party_redirecting_reason reason
Reason for the redirection.
Definition: channel.h:543
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
const struct ast_flags ast_uri_sip_user
Definition: main/utils.c:575
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873
int send_diversion
Definition: sip.h:768

◆ add_dtls_to_sdp()

static void add_dtls_to_sdp ( struct ast_rtp_instance instance,
struct ast_str **  a_buf 
)
static

Add DTLS attributes to SDP.

Definition at line 13194 of file chan_sip.c.

References ast_rtp_engine_dtls::active, AST_RTP_DTLS_CONNECTION_EXISTING, AST_RTP_DTLS_CONNECTION_NEW, AST_RTP_DTLS_HASH_SHA1, AST_RTP_DTLS_HASH_SHA256, AST_RTP_DTLS_SETUP_ACTIVE, AST_RTP_DTLS_SETUP_ACTPASS, AST_RTP_DTLS_SETUP_HOLDCONN, AST_RTP_DTLS_SETUP_PASSIVE, ast_rtp_instance_get_dtls(), ast_str_append(), ast_rtp_engine_dtls::get_connection, ast_rtp_engine_dtls::get_fingerprint, ast_rtp_engine_dtls::get_fingerprint_hash, and ast_rtp_engine_dtls::get_setup.

Referenced by add_sdp().

13195 {
13196  struct ast_rtp_engine_dtls *dtls;
13197  enum ast_rtp_dtls_hash hash;
13198  const char *fingerprint;
13199 
13200  if (!instance || !(dtls = ast_rtp_instance_get_dtls(instance)) || !dtls->active(instance)) {
13201  return;
13202  }
13203 
13204  switch (dtls->get_connection(instance)) {
13206  ast_str_append(a_buf, 0, "a=connection:new\r\n");
13207  break;
13209  ast_str_append(a_buf, 0, "a=connection:existing\r\n");
13210  break;
13211  default:
13212  break;
13213  }
13214 
13215  switch (dtls->get_setup(instance)) {
13217  ast_str_append(a_buf, 0, "a=setup:active\r\n");
13218  break;
13220  ast_str_append(a_buf, 0, "a=setup:passive\r\n");
13221  break;
13223  ast_str_append(a_buf, 0, "a=setup:actpass\r\n");
13224  break;
13226  ast_str_append(a_buf, 0, "a=setup:holdconn\r\n");
13227  break;
13228  default:
13229  break;
13230  }
13231 
13232  hash = dtls->get_fingerprint_hash(instance);
13233  fingerprint = dtls->get_fingerprint(instance);
13234  if (fingerprint && (hash == AST_RTP_DTLS_HASH_SHA1 || hash == AST_RTP_DTLS_HASH_SHA256)) {
13235  ast_str_append(a_buf, 0, "a=fingerprint:%s %s\r\n", hash == AST_RTP_DTLS_HASH_SHA1 ? "SHA-1" : "SHA-256",
13236  fingerprint);
13237  }
13238 }
const char *(* get_fingerprint)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:590
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
enum ast_rtp_dtls_hash(* get_fingerprint_hash)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:588
enum ast_rtp_dtls_setup(* get_setup)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:582
enum ast_rtp_dtls_connection(* get_connection)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:580
Structure that represents the optional DTLS SRTP support within an RTP engine.
Definition: rtp_engine.h:570
struct ast_rtp_engine_dtls * ast_rtp_instance_get_dtls(struct ast_rtp_instance *instance)
Obtain a pointer to the DTLS support present on an RTP instance.
Definition: rtp_engine.c:3011
ast_rtp_dtls_hash
DTLS fingerprint hashes.
Definition: rtp_engine.h:527
int(* active)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:574

◆ add_expires()

static void add_expires ( struct sip_request req,
int  expires 
)
static

Add Expires header to SIP message.

Definition at line 12706 of file chan_sip.c.

References add_header(), and tmp().

Referenced by respprep(), transmit_invite(), and transmit_register().

12707 {
12708  char tmp[32];
12709 
12710  snprintf(tmp, sizeof(tmp), "%d", expires);
12711  add_header(req, "Expires", tmp);
12712 }
static int tmp()
Definition: bt_open.c:389
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873

◆ add_header()

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

Add header to SIP message.

Definition at line 11873 of file chan_sip.c.

References ast_log, ast_str_append(), ast_str_strlen(), sip_settings::compactheaders, sip_request::data, find_alias(), sip_request::header, sip_request::headers, sip_request::lines, LOG_WARNING, sip_cfg, and SIP_MAX_HEADERS.

Referenced by __transmit_response(), add_cc_call_info_to_response(), add_date(), add_digit(), add_diversion(), add_expires(), add_max_forwards(), add_required_respheader(), add_route(), add_rpid(), add_sdp(), add_supported(), add_text(), add_vidupdate(), copy_all_header(), copy_header(), copy_via_headers(), finalize_content(), initreqprep(), reqprep(), respprep(), sipinfo_send(), transmit_cc_notify(), transmit_info_with_aoc(), transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), 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().

11874 {
11875  if (req->headers == SIP_MAX_HEADERS) {
11876  ast_log(LOG_WARNING, "Out of SIP header space\n");
11877  return -1;
11878  }
11879 
11880  if (req->lines) {
11881  ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n");
11882  return -1;
11883  }
11884 
11885  if (sip_cfg.compactheaders) {
11886  var = find_alias(var, var);
11887  }
11888 
11889  ast_str_append(&req->data, 0, "%s: %s\r\n", var, value);
11890  req->header[req->headers] = ast_str_strlen(req->data);
11891 
11892  req->headers++;
11893 
11894  return 0;
11895 }
static const char * find_alias(const char *name, const char *_default)
Find compressed SIP alias.
Definition: chan_sip.c:8534
#define SIP_MAX_HEADERS
Definition: sip.h:111
#define LOG_WARNING
Definition: logger.h:274
#define var
Definition: ast_expr2f.c:614
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
ptrdiff_t header[SIP_MAX_HEADERS]
Definition: sip.h:841
int value
Definition: syslog.c:37
#define ast_log
Definition: astobj2.c:42
int compactheaders
Definition: sip.h:764
struct ast_str * data
Definition: sip.h:843
int headers
Definition: sip.h:832
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
int lines
Definition: sip.h:834

◆ add_ice_to_sdp()

static void add_ice_to_sdp ( struct ast_rtp_instance instance,
struct ast_str **  a_buf 
)
static

Add ICE attributes to SDP.

Definition at line 13129 of file chan_sip.c.

References ast_rtp_engine_ice_candidate::address, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, AST_RTP_ICE_CANDIDATE_TYPE_HOST, AST_RTP_ICE_CANDIDATE_TYPE_RELAYED, AST_RTP_ICE_CANDIDATE_TYPE_SRFLX, ast_rtp_instance_get_ice(), ast_sockaddr_isnull(), ast_sockaddr_stringify_addr_remote(), ast_sockaddr_stringify_port(), ast_str_append(), ast_rtp_engine_ice_candidate::foundation, ast_rtp_engine_ice::get_local_candidates, ast_rtp_engine_ice::get_password, ast_rtp_engine_ice::get_ufrag, ast_rtp_engine_ice_candidate::id, password, ast_rtp_engine_ice_candidate::priority, ast_rtp_engine_ice_candidate::relay_address, ast_rtp_engine_ice_candidate::transport, and ast_rtp_engine_ice_candidate::type.

Referenced by add_sdp().

13130 {
13131  struct ast_rtp_engine_ice *ice = ast_rtp_instance_get_ice(instance);
13132  const char *username, *password;
13133  struct ao2_container *candidates;
13134  struct ao2_iterator i;
13135  struct ast_rtp_engine_ice_candidate *candidate;
13136 
13137  /* If no ICE support is present we can't very well add the attributes */
13138  if (!ice || !(candidates = ice->get_local_candidates(instance))) {
13139  return;
13140  }
13141 
13142  if ((username = ice->get_ufrag(instance))) {
13143  ast_str_append(a_buf, 0, "a=ice-ufrag:%s\r\n", username);
13144  }
13145  if ((password = ice->get_password(instance))) {
13146  ast_str_append(a_buf, 0, "a=ice-pwd:%s\r\n", password);
13147  }
13148 
13149  i = ao2_iterator_init(candidates, 0);
13150 
13151  while ((candidate = ao2_iterator_next(&i))) {
13152  ast_str_append(a_buf, 0, "a=candidate:%s %u %s %d ", candidate->foundation, candidate->id, candidate->transport, candidate->priority);
13153  ast_str_append(a_buf, 0, "%s ", ast_sockaddr_stringify_addr_remote(&candidate->address));
13154 
13155  ast_str_append(a_buf, 0, "%s typ ", ast_sockaddr_stringify_port(&candidate->address));
13156 
13157  if (candidate->type == AST_RTP_ICE_CANDIDATE_TYPE_HOST) {
13158  ast_str_append(a_buf, 0, "host");
13159  } else if (candidate->type == AST_RTP_ICE_CANDIDATE_TYPE_SRFLX) {
13160  ast_str_append(a_buf, 0, "srflx");
13161  } else if (candidate->type == AST_RTP_ICE_CANDIDATE_TYPE_RELAYED) {
13162  ast_str_append(a_buf, 0, "relay");
13163  }
13164 
13165  if (!ast_sockaddr_isnull(&candidate->relay_address)) {
13166  ast_str_append(a_buf, 0, " raddr %s ", ast_sockaddr_stringify_addr_remote(&candidate->relay_address));
13167  ast_str_append(a_buf, 0, "rport %s", ast_sockaddr_stringify_port(&candidate->relay_address));
13168  }
13169 
13170  ast_str_append(a_buf, 0, "\r\n");
13171  ao2_ref(candidate, -1);
13172  }
13173 
13175 
13176  ao2_ref(candidates, -1);
13177 }
static char * ast_sockaddr_stringify_addr_remote(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:317
const char *(* get_password)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:497
struct ast_rtp_engine_ice * ast_rtp_instance_get_ice(struct ast_rtp_instance *instance)
Obtain a pointer to the ICE support present on an RTP instance.
Definition: rtp_engine.c:2891
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
Structure for an ICE candidate.
Definition: rtp_engine.h:474
static struct ast_str * password
Definition: cdr_mysql.c:77
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
enum ast_rtp_ice_candidate_type type
Definition: rtp_engine.h:481
static char * ast_sockaddr_stringify_port(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return a port only.
Definition: netsock2.h:362
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_sockaddr relay_address
Definition: rtp_engine.h:480
const char *(* get_ufrag)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:495
struct ao2_container *(* get_local_candidates)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:499
enum ast_rtp_ice_component_type id
Definition: rtp_engine.h:476
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
Structure that represents the optional ICE support within an RTP engine.
Definition: rtp_engine.h:485
struct ast_sockaddr address
Definition: rtp_engine.h:479
Generic container type.
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

◆ add_max_forwards()

static int add_max_forwards ( struct sip_pvt dialog,
struct sip_request req 
)
static

Add 'Max-Forwards' header to SIP message.

Precondition
dialog is assumed to be locked while calling this function

Definition at line 11901 of file chan_sip.c.

References add_header(), and sip_pvt::maxforwards.

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

11902 {
11903  char clen[10];
11904 
11905  snprintf(clen, sizeof(clen), "%d", dialog->maxforwards);
11906 
11907  return add_header(req, "Max-Forwards", clen);
11908 }
int maxforwards
Definition: sip.h:1065
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873

◆ add_msg_header()

static void add_msg_header ( struct sip_pvt pvt,
const char *  hdr_name,
const char *  hdr_value 
)
static

Definition at line 12906 of file chan_sip.c.

References ast_calloc, AST_LIST_INSERT_TAIL, sip_pvt::msg_headers, sip_msg_hdr::name, sip_msg_hdr::stuff, and sip_msg_hdr::value.

Referenced by sip_msg_send().

12907 {
12908  size_t hdr_len_name;
12909  size_t hdr_len_value;
12910  struct sip_msg_hdr *node;
12911  char *pos;
12912 
12913  hdr_len_name = strlen(hdr_name) + 1;
12914  hdr_len_value = strlen(hdr_value) + 1;
12915 
12916  node = ast_calloc(1, sizeof(*node) + hdr_len_name + hdr_len_value);
12917  if (!node) {
12918  return;
12919  }
12920  pos = node->stuff;
12921  node->name = pos;
12922  strcpy(pos, hdr_name);
12923  pos += hdr_len_name;
12924  node->value = pos;
12925  strcpy(pos, hdr_value);
12926 
12927  AST_LIST_INSERT_TAIL(&pvt->msg_headers, node, next);
12928 }
Definition: test_heap.c:38
const char * value
Definition: sip.h:996
const char * name
Definition: sip.h:994
struct sip_pvt::@173 msg_headers
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
char stuff[0]
Definition: sip.h:998
struct sip_msg_hdr * next
Definition: sip.h:992

◆ add_noncodec_to_sdp()

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 13388 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(), ast_verbose(), NULL, and sip_pvt::rtp.

Referenced by add_sdp().

13391 {
13392  int rtp_code;
13393 
13394  if (debug)
13395  ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", (unsigned)format, ast_rtp_lookup_mime_subtype2(0, NULL, format, 0));
13396  if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->rtp), 0, NULL, format)) == -1)
13397  return;
13398 
13399  ast_str_append(m_buf, 0, " %d", rtp_code);
13400  ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%u\r\n", rtp_code,
13401  ast_rtp_lookup_mime_subtype2(0, NULL, format, 0),
13402  ast_rtp_lookup_sample_rate2(0, NULL, format));
13403  if (format == AST_RTP_DTMF) /* Indicate we support DTMF and FLASH... */
13404  ast_str_append(a_buf, 0, "a=fmtp:%d 0-16\r\n", rtp_code);
13405 }
struct ast_rtp_codecs * ast_rtp_instance_get_codecs(struct ast_rtp_instance *instance)
Get the codecs structure of an RTP instance.
Definition: rtp_engine.c:727
static int debug
Global debug status.
Definition: res_xmpp.c:435
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
#define NULL
Definition: resample.c:96
const char * ast_rtp_lookup_mime_subtype2(const int asterisk_format, const struct ast_format *format, int code, enum ast_rtp_options options)
Retrieve mime subtype information on a payload.
Definition: rtp_engine.c:1992
int ast_rtp_codecs_payload_code(struct ast_rtp_codecs *codecs, int asterisk_format, struct ast_format *format, int code)
Retrieve a rx mapped payload type based on whether it is an Asterisk format and the code...
Definition: rtp_engine.c:1873
unsigned int ast_rtp_lookup_sample_rate2(int asterisk_format, const struct ast_format *format, int code)
Get the sample rate associated with known RTP payload types.
Definition: rtp_engine.c:2022
struct ast_rtp_instance * rtp
Definition: sip.h:1174
#define AST_RTP_DTMF
Definition: rtp_engine.h:266
static snd_pcm_format_t format
Definition: chan_alsa.c:102

◆ add_peer_mailboxes()

static void add_peer_mailboxes ( struct sip_peer peer,
const char *  value 
)
static
Todo:
document this function

Definition at line 31589 of file chan_sip.c.

References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_strdupa, ast_strip(), ast_strlen_zero, sip_mailbox::id, mailbox, sip_peer::mailboxes, mbox(), sip_mailbox::peer, SIP_MAILBOX_STATUS_EXISTING, SIP_MAILBOX_STATUS_NEW, sip_mailbox::status, and strsep().

Referenced by build_peer().

31590 {
31591  char *next;
31592  char *mbox;
31593 
31594  next = ast_strdupa(value);
31595 
31596  while ((mbox = strsep(&next, ","))) {
31597  struct sip_mailbox *mailbox;
31598  int duplicate = 0;
31599 
31600  /* remove leading/trailing whitespace from mailbox string */
31601  mbox = ast_strip(mbox);
31602  if (ast_strlen_zero(mbox)) {
31603  continue;
31604  }
31605 
31606  /* Check whether the mailbox is already in the list */
31607  AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
31608  if (!strcmp(mailbox->id, mbox)) {
31609  duplicate = 1;
31611  break;
31612  }
31613  }
31614  if (duplicate) {
31615  continue;
31616  }
31617 
31618  mailbox = ast_calloc(1, sizeof(*mailbox) + strlen(mbox));
31619  if (!mailbox) {
31620  continue;
31621  }
31622  strcpy(mailbox->id, mbox); /* SAFE */
31623  mailbox->status = SIP_MAILBOX_STATUS_NEW;
31624  mailbox->peer = peer;
31625 
31626  AST_LIST_INSERT_TAIL(&peer->mailboxes, mailbox, entry);
31627  }
31628 }
A peer&#39;s mailbox.
Definition: sip.h:1261
char id[1]
Definition: sip.h:1267
int value
Definition: syslog.c:37
#define ast_strlen_zero(foo)
Definition: strings.h:52
static const char * mbox(struct ast_vm_user *vmu, int id)
static char mailbox[AST_MAX_MAILBOX_UNIQUEID]
Definition: chan_mgcp.c:204
struct sip_peer * peer
Definition: sip.h:1265
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:219
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
struct sip_peer::@176 mailboxes
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
char * strsep(char **str, const char *delims)
Definition: search.h:40
struct sip_msg_hdr * next
Definition: sip.h:992
enum sip_mailbox_status status
Definition: sip.h:1266

◆ add_peer_mwi_subs()

static void add_peer_mwi_subs ( struct sip_peer peer)
static

Definition at line 28499 of file chan_sip.c.

References AST_LIST_TRAVERSE, ast_mwi_subscribe_pool(), ast_mwi_subscriber_subscription(), sip_mailbox::event_sub, sip_mailbox::id, mailbox, sip_peer::mailboxes, mwi_event_cb(), SIP_MAILBOX_STATUS_NEW, stasis_subscription_accept_message_type(), stasis_subscription_change_type(), and sip_mailbox::status.

Referenced by build_peer(), and handle_request_subscribe().

28500 {
28501  struct sip_mailbox *mailbox;
28502 
28503  AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
28504  if (mailbox->status != SIP_MAILBOX_STATUS_NEW) {
28505  continue;
28506  }
28507  mailbox->event_sub = ast_mwi_subscribe_pool(mailbox->id, mwi_event_cb, peer);
28508  if (mailbox->event_sub) {
28512  }
28513  }
28514 }
struct stasis_subscription * ast_mwi_subscriber_subscription(struct ast_mwi_subscriber *sub)
Retrieve the stasis MWI topic subscription if available.
Definition: mwi.c:272
A peer&#39;s mailbox.
Definition: sip.h:1261
char id[1]
Definition: sip.h:1267
struct ast_mwi_subscriber * event_sub
Definition: sip.h:1263
static char mailbox[AST_MAX_MAILBOX_UNIQUEID]
Definition: chan_mgcp.c:204
struct sip_peer::@176 mailboxes
static void mwi_event_cb(void *, struct stasis_subscription *, struct stasis_message *)
Receive MWI events that we have subscribed to.
Definition: chan_sip.c:17528
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
int stasis_subscription_accept_message_type(struct stasis_subscription *subscription, const struct stasis_message_type *type)
Indicate to a subscription that we are interested in a message type.
Definition: stasis.c:1025
Definition: search.h:40
struct stasis_message_type * stasis_subscription_change_type(void)
Gets the message type for subscription change notices.
struct ast_mwi_subscriber * ast_mwi_subscribe_pool(const char *mailbox, stasis_subscription_cb callback, void *data)
Add an MWI state subscriber, and stasis subscription to the mailbox.
Definition: mwi.c:230
enum sip_mailbox_status status
Definition: sip.h:1266

◆ add_realm_authentication()

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

Definition at line 31375 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, sip_auth::md5secret, NULL, sip_auth::realm, sip_auth::secret, and sip_auth::username.

Referenced by build_peer(), and reload_config().

31376 {
31377  char *authcopy;
31378  char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL;
31379  struct sip_auth *auth;
31380 
31381  if (ast_strlen_zero(configuration)) {
31382  /* Nothing to add */
31383  return;
31384  }
31385 
31386  ast_debug(1, "Auth config :: %s\n", configuration);
31387 
31388  authcopy = ast_strdupa(configuration);
31389  username = authcopy;
31390 
31391  /* split user[:secret] and relm */
31392  realm = strrchr(username, '@');
31393  if (realm)
31394  *realm++ = '\0';
31395  if (ast_strlen_zero(username) || ast_strlen_zero(realm)) {
31396  ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno);
31397  return;
31398  }
31399 
31400  /* parse username at ':' for secret, or '#" for md5secret */
31401  if ((secret = strchr(username, ':'))) {
31402  *secret++ = '\0';
31403  } else if ((md5secret = strchr(username, '#'))) {
31404  *md5secret++ = '\0';
31405  }
31406 
31407  /* Create the continer if needed. */
31408  if (!*credentials) {
31409  *credentials = ao2_t_alloc(sizeof(**credentials), destroy_realm_authentication,
31410  "Create realm auth container.");
31411  if (!*credentials) {
31412  /* Failed to create the credentials container. */
31413  return;
31414  }
31415  }
31416 
31417  /* Create the authentication credential entry. */
31418  auth = ast_calloc(1, sizeof(*auth));
31419  if (!auth) {
31420  return;
31421  }
31422  ast_copy_string(auth->realm, realm, sizeof(auth->realm));
31423  ast_copy_string(auth->username, username, sizeof(auth->username));
31424  if (secret)
31425  ast_copy_string(auth->secret, secret, sizeof(auth->secret));
31426  if (md5secret)
31427  ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret));
31428 
31429  /* Add credential to container list. */
31430  AST_LIST_INSERT_TAIL(&(*credentials)->list, auth, node);
31431 
31432  ast_verb(3, "Added authentication for realm %s\n", realm);
31433 }
Definition: test_heap.c:38
#define ao2_t_alloc(data_size, destructor_fn, debug_msg)
Definition: astobj2.h:409
#define LOG_WARNING
Definition: logger.h:274
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:463
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
static void destroy_realm_authentication(void *obj)
Definition: chan_sip.c:31355
char username[256]
Definition: sip.h:905
char realm[AST_MAX_EXTENSION]
Definition: sip.h:904
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
char secret[256]
Definition: sip.h:906
sip_auth: Credentials for authentication to other SIP services
Definition: sip.h:902
char md5secret[256]
Definition: sip.h:907

◆ add_required_respheader()

static void add_required_respheader ( struct sip_request req)
static

Definition at line 4792 of file chan_sip.c.

References add_header(), ARRAY_LEN, ast_free, ast_str_append(), ast_str_buffer(), ast_str_create, ast_str_strlen(), cfsip_options::id, sip_request::reqsipoptions, sip_options, str, and text.

Referenced by transmit_response_with_sdp().

4793 {
4794  struct ast_str *str;
4795  int i;
4796 
4797  if (!req->reqsipoptions) {
4798  return;
4799  }
4800 
4801  str = ast_str_create(32);
4802 
4803  for (i = 0; i < ARRAY_LEN(sip_options); ++i) {
4804  if (!(req->reqsipoptions & sip_options[i].id)) {
4805  continue;
4806  }
4807  if (ast_str_strlen(str) > 0) {
4808  ast_str_append(&str, 0, ", ");
4809  }
4810  ast_str_append(&str, 0, "%s", sip_options[i].text);
4811  }
4812 
4813  if (ast_str_strlen(str) > 0) {
4814  add_header(req, "Require", ast_str_buffer(str));
4815  }
4816 
4817  ast_free(str);
4818 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
unsigned int reqsipoptions
Definition: sip.h:848
char * text
Definition: app_queue.c:1508
const char * str
Definition: app_jack.c:147
int id
Definition: sip.h:1828
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
static const struct cfsip_options sip_options[]
#define ast_free(a)
Definition: astmm.h:182
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ add_route()

static void add_route ( struct sip_request req,
struct sip_route route,
int  skip 
)
static

Add route header into request per learned route.

Definition at line 12042 of file chan_sip.c.

References add_header(), ast_free, ast_str_buffer(), ast_str_strlen(), sip_route_empty, and sip_route_list().

Referenced by initreqprep(), and reqprep().

12043 {
12044  struct ast_str *r;
12045 
12046  if (sip_route_empty(route)) {
12047  return;
12048  }
12049 
12050  if ((r = sip_route_list(route, 0, skip))) {
12051  if (ast_str_strlen(r)) {
12052  add_header(req, "Route", ast_str_buffer(r));
12053  }
12054  ast_free(r);
12055  }
12056 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
struct ast_str * sip_route_list(const struct sip_route *route, int formatcli, int skip)
Make the comma separated list of route hops.
Definition: route.c:155
#define sip_route_empty(route)
Check if route has no URI&#39;s.
Definition: route.h:118
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
#define ast_free(a)
Definition: astmm.h:182
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873

◆ add_rpid()

static int add_rpid ( struct sip_request req,
struct sip_pvt p 
)
static

Add Remote-Party-ID header to SIP message.

Precondition
if p->owner exists, it must be locked

Definition at line 12996 of file chan_sip.c.

References add_header(), ast_channel_connected_effective_id(), 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(), ast_uri_sip_user, sip_pvt::flags, sip_pvt::fromdomain, ast_party_id::name, NULL, ast_party_id::number, sip_pvt::ourip, sip_pvt::outgoing_call, sip_pvt::owner, S_COR, SIP_PAGE2_TRUST_ID_OUTBOUND, SIP_PAGE2_TRUST_ID_OUTBOUND_LEGACY, SIP_PAGE2_TRUST_ID_OUTBOUND_NO, SIP_PAGE2_TRUST_ID_OUTBOUND_YES, SIP_SENDRPID, SIP_SENDRPID_PAI, ast_party_name::str, ast_party_number::str, tmp(), ast_party_name::valid, and ast_party_number::valid.

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

12997 {
12998  struct ast_str *tmp = ast_str_alloca(256);
12999  char tmp2[256];
13000  char lid_name_buf[128];
13001  char *lid_num;
13002  char *lid_name;
13003  int lid_pres;
13004  const char *fromdomain;
13005  const char *privacy = NULL;
13006  const char *screen = NULL;
13007  struct ast_party_id connected_id;
13008  const char *anonymous_string = "\"Anonymous\" <sip:[email protected]>";
13009 
13010  if (!ast_test_flag(&p->flags[0], SIP_SENDRPID)) {
13011  return 0;
13012  }
13013 
13014  if (!p->owner) {
13015  return 0;
13016  }
13017  connected_id = ast_channel_connected_effective_id(p->owner);
13018  lid_num = S_COR(connected_id.number.valid, connected_id.number.str, NULL);
13019  if (!lid_num) {
13020  return 0;
13021  }
13022  lid_name = S_COR(connected_id.name.valid, connected_id.name.str, NULL);
13023  if (!lid_name) {
13024  lid_name = lid_num;
13025  }
13026  ast_escape_quoted(lid_name, lid_name_buf, sizeof(lid_name_buf));
13027  lid_pres = ast_party_id_presentation(&connected_id);
13028 
13029  if (((lid_pres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) &&
13031  /* If pres is not allowed and we don't trust the peer, we don't apply an RPID header */
13032  return 0;
13033  }
13034 
13035  fromdomain = p->fromdomain;
13036  if (!fromdomain ||
13038  !strcmp("anonymous.invalid", fromdomain))) {
13039  /* If the fromdomain is NULL or if it was set to anonymous.invalid due to privacy settings and we trust the peer,
13040  * use the host IP address */
13041  fromdomain = ast_sockaddr_stringify_host_remote(&p->ourip);
13042  }
13043 
13044  lid_num = ast_uri_encode(lid_num, tmp2, sizeof(tmp2), ast_uri_sip_user);
13045 
13046  if (ast_test_flag(&p->flags[0], SIP_SENDRPID_PAI)) {
13048  /* trust_id_outbound = yes - Always give full information even if it's private, but append a privacy header
13049  * When private data is included */
13050  ast_str_set(&tmp, -1, "\"%s\" <sip:%s@%s>", lid_name_buf, lid_num, fromdomain);
13051  if ((lid_pres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) {
13052  add_header(req, "Privacy", "id");
13053  }
13054  } else {
13055  /* trust_id_outbound = legacy - behave in a non RFC-3325 compliant manner and send anonymized data when
13056  * when handling private data. */
13057  if ((lid_pres & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED) {
13058  ast_str_set(&tmp, -1, "\"%s\" <sip:%s@%s>", lid_name_buf, lid_num, fromdomain);
13059  } else {
13060  ast_str_set(&tmp, -1, "%s", anonymous_string);
13061  }
13062  }
13063  add_header(req, "P-Asserted-Identity", ast_str_buffer(tmp));
13064  } else {
13065  ast_str_set(&tmp, -1, "\"%s\" <sip:%s@%s>;party=%s", lid_name_buf, lid_num, fromdomain, p->outgoing_call ? "calling" : "called");
13066 
13067  switch (lid_pres) {
13070  privacy = "off";
13071  screen = "no";
13072  break;
13075  privacy = "off";
13076  screen = "yes";
13077  break;
13080  privacy = "full";
13081  screen = "no";
13082  break;
13085  privacy = "full";
13086  screen = "yes";
13087  break;
13089  break;
13090  default:
13091  if ((lid_pres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) {
13092  privacy = "full";
13093  }
13094  else
13095  privacy = "off";
13096  screen = "no";
13097  break;
13098  }
13099 
13100  if (!ast_strlen_zero(privacy) && !ast_strlen_zero(screen)) {
13101  ast_str_append(&tmp, -1, ";privacy=%s;screen=%s", privacy, screen);
13102  }
13103 
13104  add_header(req, "Remote-Party-ID", ast_str_buffer(tmp));
13105  }
13106  return 0;
13107 }
Information needed to identify an endpoint in a call.
Definition: channel.h:339
#define SIP_PAGE2_TRUST_ID_OUTBOUND_NO
Definition: sip.h:372
#define ast_test_flag(p, flag)
Definition: utils.h:63
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
int ast_party_id_presentation(const struct ast_party_id *id)
Determine the overall presentation value for the given party.
Definition: channel.c:1821
#define AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN
Definition: callerid.h:335
static int tmp()
Definition: bt_open.c:389
#define AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED
Definition: callerid.h:341
unsigned short outgoing_call
Definition: sip.h:1083
char * ast_uri_encode(const char *string, char *outbuf, int buflen, struct ast_flags spec)
Turn text string to URI-encoded XX version.
Definition: main/utils.c:577
struct ast_sockaddr ourip
Definition: sip.h:1136
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
struct ast_flags flags[3]
Definition: sip.h:1075
#define ast_str_alloca(init_len)
Definition: strings.h:800
#define SIP_PAGE2_TRUST_ID_OUTBOUND
Definition: sip.h:370
#define NULL
Definition: resample.c:96
#define SIP_PAGE2_TRUST_ID_OUTBOUND_YES
Definition: sip.h:373
#define AST_PRES_ALLOWED_NETWORK_NUMBER
Definition: callerid.h:338
#define AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED
Definition: callerid.h:329
#define SIP_SENDRPID_PAI
Definition: sip.h:308
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN
Definition: callerid.h:344
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
#define AST_PRES_PROHIB_NETWORK_NUMBER
Definition: callerid.h:350
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:85
const ast_string_field fromdomain
Definition: sip.h:1063
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
struct ast_party_id ast_channel_connected_effective_id(struct ast_channel *chan)
#define AST_PRES_NUMBER_NOT_AVAILABLE
Definition: callerid.h:353
static char * ast_sockaddr_stringify_host_remote(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only, suitable for a URL (with brack...
Definition: netsock2.h:349
#define AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN
Definition: callerid.h:347
char * ast_escape_quoted(const char *string, char *outbuf, int buflen)
Escape characters found in a quoted string.
Definition: main/utils.c:635
struct ast_channel * owner
Definition: sip.h:1138
#define AST_PRES_RESTRICTION
Definition: callerid.h:323
#define AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN
Definition: callerid.h:332
#define AST_PRES_ALLOWED
Definition: callerid.h:324
const struct ast_flags ast_uri_sip_user
Definition: main/utils.c:575
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873
#define SIP_PAGE2_TRUST_ID_OUTBOUND_LEGACY
Definition: sip.h:371
#define SIP_SENDRPID
Definition: sip.h:306

◆ add_sdp()

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

References add_codec_to_sdp(), add_content(), add_dtls_to_sdp(), add_header(), add_ice_to_sdp(), add_noncodec_to_sdp(), add_tcodec_to_sdp(), add_vcodec_to_sdp(), ao2_cleanup, ao2_lock, ao2_ref, ao2_t_link, ao2_t_unlink, ao2_unlock, ast_channel_timingfd(), ast_debug, AST_FAILURE, ast_format_cap_alloc, ast_format_cap_append, ast_format_cap_append_from_cap(), ast_format_cap_count(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_get_compatible(), ast_format_cap_get_format(), ast_format_cap_get_names(), ast_format_cap_has_type(), ast_format_cap_iscompatible_format(), AST_FORMAT_CAP_NAMES_LEN, AST_FORMAT_CMP_NOT_EQUAL, ast_format_get_type(), ast_free, AST_LIST_EMPTY, AST_LIST_TRAVERSE, ast_log, AST_MEDIA_TYPE_AUDIO, AST_MEDIA_TYPE_TEXT, AST_MEDIA_TYPE_UNKNOWN, AST_MEDIA_TYPE_VIDEO, ast_random(), ast_rtp_codecs_set_framing(), ast_rtp_instance_get_codecs(), AST_RTP_MAX, ast_sdp_get_rtp_profile(), ast_sockaddr_cmp_addr(), 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_create, ast_strlen_zero, AST_SUCCESS, 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(), crypto_get_attrib(), debug, offered_media::decline_m_line, sip_pvt::dtls_cfg, ast_rtp_dtls_cfg::enabled, FALSE, ast_control_t38_parameters::fill_bit_removal, sip_pvt::flags, get_our_media_address(), global_sdpowner, global_sdpsession, hold(), sip_pvt::jointcaps, sip_pvt::jointnoncodeccapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, LOG_WARNING, sip_pvt::maxcallbitrate, sip_request::method, sip_pvt::notext, sip_pvt::novideo, NULL, sip_pvt::offered_media, t38properties::our_parms, sip_pvt::ourip, sip_pvt::owner, sip_pvt::prefcaps, RAII_VAR, ast_control_t38_parameters::rate, ast_control_t38_parameters::rate_management, sip_pvt::redircaps, sip_pvt::redirip, sip_pvt::rtp, SDP_AUDIO, SDP_IMAGE, SDP_TEXT, SDP_UNKNOWN, SDP_VIDEO, sip_pvt::sessionid, sip_pvt::sessionversion, sip_debug_test_pvt(), SIP_OUTGOING, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_CALL_ONHOLD_INACTIVE, SIP_PAGE2_CALL_ONHOLD_ONEDIR, SIP_PAGE3_FORCE_AVP, SIP_PAGE3_ICE_SUPPORT, SIP_PAGE3_IGNORE_PREFCAPS, SIP_PAGE3_RTCP_MUX, SIP_PAGE3_SRTP_TAG_32, SIP_PAGE3_USE_AVPF, SIP_RESPONSE, sipdebug_text, sip_pvt::srtp, start_ice(), sip_pvt::t38, t38_get_rate(), ast_control_t38_parameters::transcoding_jbig, ast_control_t38_parameters::transcoding_mmr, sip_pvt::trtp, TRUE, sip_pvt::tsrtp, offered_media::type, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_REDUNDANCY, version, ast_control_t38_parameters::version, sip_pvt::vrtp, and sip_pvt::vsrtp.

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

13543 {
13546  int res = AST_SUCCESS;
13547  int doing_directmedia = FALSE;
13548  struct ast_sockaddr addr = { {0,} };
13549  struct ast_sockaddr vaddr = { {0,} };
13550  struct ast_sockaddr taddr = { {0,} };
13551  struct ast_sockaddr udptladdr = { {0,} };
13552  struct ast_sockaddr dest = { {0,} };
13553  struct ast_sockaddr vdest = { {0,} };
13554  struct ast_sockaddr tdest = { {0,} };
13555  struct ast_sockaddr udptldest = { {0,} };
13556 
13557  /* SDP fields */
13558  struct offered_media *offer;
13559  char *version = "v=0\r\n"; /* Protocol version */
13560  char subject[256]; /* Subject of the session */
13561  char owner[256]; /* Session owner/creator */
13562  char connection[256]; /* Connection data */
13563  char *session_time = "t=0 0\r\n"; /* Time the session is active */
13564  char bandwidth[256] = ""; /* Max bitrate */
13565  char *hold = "";
13566  struct ast_str *m_audio = ast_str_alloca(256); /* Media declaration line for audio */
13567  struct ast_str *m_video = ast_str_alloca(256); /* Media declaration line for video */
13568  struct ast_str *m_text = ast_str_alloca(256); /* Media declaration line for text */
13569  struct ast_str *m_modem = ast_str_alloca(256); /* Media declaration line for modem */
13570  struct ast_str *a_audio = ast_str_create(256); /* Attributes for audio */
13571  struct ast_str *a_video = ast_str_create(256); /* Attributes for video */
13572  struct ast_str *a_text = ast_str_create(256); /* Attributes for text */
13573  struct ast_str *a_modem = ast_str_alloca(1024); /* Attributes for modem */
13574  RAII_VAR(char *, a_crypto, NULL, ast_free);
13575  RAII_VAR(char *, v_a_crypto, NULL, ast_free);
13576  RAII_VAR(char *, t_a_crypto, NULL, ast_free);
13577 
13578  int x;
13579  struct ast_format *tmp_fmt;
13580  int needaudio = FALSE;
13581  int needvideo = FALSE;
13582  int needtext = FALSE;
13583  int debug = sip_debug_test_pvt(p);
13584  int min_audio_packet_size = 0;
13585  int max_audio_packet_size = 0;
13586  int min_video_packet_size = 0;
13587  int min_text_packet_size = 0;
13588 
13589  struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
13590 
13591  /* Set the SDP session name */
13592  snprintf(subject, sizeof(subject), "s=%s\r\n", ast_strlen_zero(global_sdpsession) ? "-" : global_sdpsession);
13593 
13594  if (!alreadysent || !tmpcap) {
13595  res = AST_FAILURE;
13596  goto add_sdp_cleanup;
13597  }
13598  if (!p->rtp) {
13599  ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n");
13600  res = AST_FAILURE;
13601  goto add_sdp_cleanup;
13602 
13603  }
13604  /* XXX We should not change properties in the SIP dialog until
13605  we have acceptance of the offer if this is a re-invite */
13606 
13607  /* Set RTP Session ID and version */
13608  if (!p->sessionid) {
13609  p->sessionid = (int)ast_random();
13610  p->sessionversion = p->sessionid;
13611  } else {
13612  if (oldsdp == FALSE)
13613  p->sessionversion++;
13614  }
13615 
13616  if (add_audio) {
13617  doing_directmedia = (!ast_sockaddr_isnull(&p->redirip) && (ast_format_cap_count(p->redircaps))) ? TRUE : FALSE;
13618 
13619  if (doing_directmedia) {
13621  ast_debug(1, "** Our native-bridge filtered capablity: %s\n", ast_format_cap_get_names(tmpcap, &codec_buf));
13622  } else {
13624  }
13625 
13626  /* Check if we need audio in this call */
13627  needaudio = ast_format_cap_has_type(tmpcap, AST_MEDIA_TYPE_AUDIO);
13628 
13629  /* Check if we need video in this call */
13630  if ((ast_format_cap_has_type(tmpcap, AST_MEDIA_TYPE_VIDEO)) && !p->novideo) {
13631  if (doing_directmedia && !ast_format_cap_has_type(tmpcap, AST_MEDIA_TYPE_VIDEO)) {
13632  ast_debug(2, "This call needs video offers, but caller probably did not offer it!\n");
13633  } else if (p->vrtp) {
13634  needvideo = TRUE;
13635  ast_debug(2, "This call needs video offers!\n");
13636  } else {
13637  ast_debug(2, "This call needs video offers, but there's no video support enabled!\n");
13638  }
13639  }
13640 
13641  /* Check if we need text in this call */
13643  if (sipdebug_text)
13644  ast_verbose("We think we can do text\n");
13645  if (p->trtp) {
13646  if (sipdebug_text) {
13647  ast_verbose("And we have a text rtp object\n");
13648  }
13649  needtext = TRUE;
13650  ast_debug(2, "This call needs text offers! \n");
13651  } else {
13652  ast_debug(2, "This call needs text offers, but there's no text support enabled ! \n");
13653  }
13654  }
13655 
13656  /* XXX note, Video and Text are negated - 'true' means 'no' */
13657  ast_debug(1, "** Our capability: %s Video flag: %s Text flag: %s\n",
13658  ast_format_cap_get_names(tmpcap, &codec_buf),
13659  p->novideo ? "True" : "False", p->notext ? "True" : "False");
13660  ast_debug(1, "** Our prefcodec: %s \n", ast_format_cap_get_names(p->prefcaps, &codec_buf));
13661  }
13662 
13663  get_our_media_address(p, needvideo, needtext, &addr, &vaddr, &taddr, &dest, &vdest, &tdest);
13664 
13665  /* We don't use dest here but p->ourip because address in o= field must not change in reINVITE */
13666  snprintf(owner, sizeof(owner), "o=%s %d %d IN %s %s\r\n",
13668  p->sessionid, p->sessionversion,
13670  "IP6" : "IP4",
13672 
13673  snprintf(connection, sizeof(connection), "c=IN %s %s\r\n",
13675  "IP6" : "IP4",
13677 
13678  if (add_audio) {
13680  hold = "a=recvonly\r\n";
13681  doing_directmedia = FALSE;
13683  hold = "a=inactive\r\n";
13684  doing_directmedia = FALSE;
13685  } else {
13686  hold = "a=sendrecv\r\n";
13687  }
13688 
13689  if (debug) {
13690  ast_verbose("Audio is at %s\n", ast_sockaddr_stringify_port(&addr));
13691  }
13692 
13693  /* Ok, we need video. Let's add what we need for video and set codecs.
13694  Video is handled differently than audio since we can not transcode. */
13695  if (needvideo) {
13696  v_a_crypto = crypto_get_attrib(p->vsrtp, p->dtls_cfg.enabled,
13698  ast_str_append(&m_video, 0, "m=video %d %s", ast_sockaddr_port(&vdest),
13699  ast_sdp_get_rtp_profile(v_a_crypto ? 1 : 0, p->vrtp,
13702 
13703  /* Build max bitrate string */
13704  if (p->maxcallbitrate)
13705  snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate);
13706  if (debug) {
13707  ast_verbose("Video is at %s\n", ast_sockaddr_stringify(&vdest));
13708  }
13709 
13710  if (!doing_directmedia) {
13711  if (ast_test_flag(&p->flags[2], SIP_PAGE3_ICE_SUPPORT)) {
13712  add_ice_to_sdp(p->vrtp, &a_video);
13713  }
13714 
13715  add_dtls_to_sdp(p->vrtp, &a_video);
13716  }
13717  }
13718 
13719  /* Ok, we need text. Let's add what we need for text and set codecs.
13720  Text is handled differently than audio since we can not transcode. */
13721  if (needtext) {
13722  if (sipdebug_text)
13723  ast_verbose("Lets set up the text sdp\n");
13724  t_a_crypto = crypto_get_attrib(p->tsrtp, p->dtls_cfg.enabled,
13726  ast_str_append(&m_text, 0, "m=text %d %s", ast_sockaddr_port(&tdest),
13727  ast_sdp_get_rtp_profile(t_a_crypto ? 1 : 0, p->trtp,
13730  if (debug) { /* XXX should I use tdest below ? */
13731  ast_verbose("Text is at %s\n", ast_sockaddr_stringify(&taddr));
13732  }
13733 
13734  if (!doing_directmedia) {
13735  if (ast_test_flag(&p->flags[2], SIP_PAGE3_ICE_SUPPORT)) {
13736  add_ice_to_sdp(p->trtp, &a_text);
13737  }
13738 
13739  add_dtls_to_sdp(p->trtp, &a_text);
13740  }
13741  }
13742 
13743  /* Start building generic SDP headers */
13744 
13745  /* We break with the "recommendation" and send our IP, in order that our
13746  peer doesn't have to ast_gethostbyname() us */
13747 
13748  a_crypto = crypto_get_attrib(p->srtp, p->dtls_cfg.enabled,
13750  ast_str_append(&m_audio, 0, "m=audio %d %s", ast_sockaddr_port(&dest),
13751  ast_sdp_get_rtp_profile(a_crypto ? 1 : 0, p->rtp,
13754 
13755  /* Now, start adding audio codecs. These are added in this order:
13756  - First what was requested by the calling channel
13757  - Then our mutually shared capabilities, determined previous in tmpcap
13758  */
13759 
13760 
13761  /* Unless otherwise configured, the prefcaps is added before the peer's
13762  * configured codecs.
13763  */
13765  for (x = 0; x < ast_format_cap_count(p->prefcaps); x++) {
13766  tmp_fmt = ast_format_cap_get_format(p->prefcaps, x);
13767 
13768  if ((ast_format_get_type(tmp_fmt) != AST_MEDIA_TYPE_AUDIO) ||
13770  ao2_ref(tmp_fmt, -1);
13771  continue;
13772  }
13773 
13774  add_codec_to_sdp(p, tmp_fmt, &m_audio, &a_audio, debug, &min_audio_packet_size, &max_audio_packet_size);
13775  ast_format_cap_append(alreadysent, tmp_fmt, 0);
13776  ao2_ref(tmp_fmt, -1);
13777  }
13778  }
13779 
13780  /* Now send any other common codecs */
13781  for (x = 0; x < ast_format_cap_count(tmpcap); x++) {
13782  tmp_fmt = ast_format_cap_get_format(tmpcap, x);
13783 
13784  if (ast_format_cap_iscompatible_format(alreadysent, tmp_fmt) != AST_FORMAT_CMP_NOT_EQUAL) {
13785  ao2_ref(tmp_fmt, -1);
13786  continue;
13787  }
13788 
13789  if (ast_format_get_type(tmp_fmt) == AST_MEDIA_TYPE_AUDIO) {
13790  add_codec_to_sdp(p, tmp_fmt, &m_audio, &a_audio, debug, &min_audio_packet_size, &max_audio_packet_size);
13791  } else if (needvideo && ast_format_get_type(tmp_fmt) == AST_MEDIA_TYPE_VIDEO) {
13792  add_vcodec_to_sdp(p, tmp_fmt, &m_video, &a_video, debug, &min_video_packet_size);
13793  } else if (needtext && ast_format_get_type(tmp_fmt) == AST_MEDIA_TYPE_TEXT) {
13794  add_tcodec_to_sdp(p, tmp_fmt, &m_text, &a_text, debug, &min_text_packet_size);
13795  }
13796 
13797  ast_format_cap_append(alreadysent, tmp_fmt, 0);
13798  ao2_ref(tmp_fmt, -1);
13799  }
13800 
13801  /* Now add DTMF RFC2833 telephony-event as a codec */
13802  for (x = 1LL; x <= AST_RTP_MAX; x <<= 1) {
13803  if (!(p->jointnoncodeccapability & x))
13804  continue;
13805 
13806  add_noncodec_to_sdp(p, x, &m_audio, &a_audio, debug);
13807  }
13808 
13809  ast_debug(3, "-- Done with adding codecs to SDP\n");
13810 
13811  if (!p->owner || ast_channel_timingfd(p->owner) == -1) {
13812  ast_str_append(&a_audio, 0, "a=silenceSupp:off - - - -\r\n");
13813  }
13814 
13815  if (min_audio_packet_size) {
13816  ast_str_append(&a_audio, 0, "a=ptime:%d\r\n", min_audio_packet_size);
13817  }
13818 
13819  /* XXX don't think you can have ptime for video */
13820  if (min_video_packet_size) {
13821  ast_str_append(&a_video, 0, "a=ptime:%d\r\n", min_video_packet_size);
13822  }
13823 
13824  /* XXX don't think you can have ptime for text */
13825  if (min_text_packet_size) {
13826  ast_str_append(&a_text, 0, "a=ptime:%d\r\n", min_text_packet_size);
13827  }
13828 
13829  if (max_audio_packet_size) {
13830  ast_str_append(&a_audio, 0, "a=maxptime:%d\r\n", max_audio_packet_size);
13831  }
13832 
13833  if (!ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
13834  ast_debug(1, "Setting framing on incoming call: %u\n", min_audio_packet_size);
13835  ast_rtp_codecs_set_framing(ast_rtp_instance_get_codecs(p->rtp), min_audio_packet_size);
13836  }
13837 
13838  if (!doing_directmedia) {
13839  if (ast_test_flag(&p->flags[2], SIP_PAGE3_ICE_SUPPORT)) {
13840  add_ice_to_sdp(p->rtp, &a_audio);
13841  /* Start ICE negotiation, and setting that we are controlled agent,
13842  as this is response to offer */
13843  if (resp->method == SIP_RESPONSE) {
13844  start_ice(p->rtp, 0);
13845  }
13846  }
13847 
13848  add_dtls_to_sdp(p->rtp, &a_audio);
13849  }
13850 
13851  /* If we've got rtcp-mux enabled, just unconditionally offer it in all SDPs */
13852  if (ast_test_flag(&p->flags[2], SIP_PAGE3_RTCP_MUX)) {
13853  ast_str_append(&a_audio, 0, "a=rtcp-mux\r\n");
13854  ast_str_append(&a_video, 0, "a=rtcp-mux\r\n");
13855  }
13856  }
13857 
13858  if (add_t38) {
13859  /* Our T.38 end is */
13860  ast_udptl_get_us(p->udptl, &udptladdr);
13861 
13862  /* We don't use directmedia for T.38, so keep the destination the same as our IP address. */
13863  ast_sockaddr_copy(&udptldest, &p->ourip);
13864  ast_sockaddr_set_port(&udptldest, ast_sockaddr_port(&udptladdr));
13865 
13866  if (debug) {
13867  ast_debug(1, "T.38 UDPTL is at %s port %d\n", ast_sockaddr_stringify_addr(&p->ourip), ast_sockaddr_port(&udptladdr));
13868  }
13869 
13870  /* We break with the "recommendation" and send our IP, in order that our
13871  peer doesn't have to ast_gethostbyname() us */
13872 
13873  ast_str_append(&m_modem, 0, "m=image %d udptl t38\r\n", ast_sockaddr_port(&udptldest));
13874 
13875  if (ast_sockaddr_cmp_addr(&udptldest, &dest)) {
13876  ast_str_append(&m_modem, 0, "c=IN %s %s\r\n",
13877  (ast_sockaddr_is_ipv6(&udptldest) && !ast_sockaddr_is_ipv4_mapped(&udptldest)) ?
13878  "IP6" : "IP4", ast_sockaddr_stringify_addr_remote(&udptldest));
13879  }
13880 
13881  ast_str_append(&a_modem, 0, "a=T38FaxVersion:%u\r\n", p->t38.our_parms.version);
13882  ast_str_append(&a_modem, 0, "a=T38MaxBitRate:%u\r\n", t38_get_rate(p->t38.our_parms.rate));
13883  if (p->t38.our_parms.fill_bit_removal) {
13884  ast_str_append(&a_modem, 0, "a=T38FaxFillBitRemoval\r\n");
13885  }
13886  if (p->t38.our_parms.transcoding_mmr) {
13887  ast_str_append(&a_modem, 0, "a=T38FaxTranscodingMMR\r\n");
13888  }
13889  if (p->t38.our_parms.transcoding_jbig) {
13890  ast_str_append(&a_modem, 0, "a=T38FaxTranscodingJBIG\r\n");
13891  }
13892  switch (p->t38.our_parms.rate_management) {
13894  ast_str_append(&a_modem, 0, "a=T38FaxRateManagement:transferredTCF\r\n");
13895  break;
13897  ast_str_append(&a_modem, 0, "a=T38FaxRateManagement:localTCF\r\n");
13898  break;
13899  }
13900  ast_str_append(&a_modem, 0, "a=T38FaxMaxDatagram:%u\r\n", ast_udptl_get_local_max_datagram(p->udptl));
13903  break;
13905  ast_str_append(&a_modem, 0, "a=T38FaxUdpEC:t38UDPFEC\r\n");
13906  break;
13908  ast_str_append(&a_modem, 0, "a=T38FaxUdpEC:t38UDPRedundancy\r\n");
13909  break;
13910  }
13911  }
13912 
13913  if (needaudio)
13914  ast_str_append(&m_audio, 0, "\r\n");
13915  if (needvideo)
13916  ast_str_append(&m_video, 0, "\r\n");
13917  if (needtext)
13918  ast_str_append(&m_text, 0, "\r\n");
13919 
13920  add_header(resp, "Content-Type", "application/sdp");
13921  add_content(resp, version);
13922  add_content(resp, owner);
13923  add_content(resp, subject);
13924  add_content(resp, connection);
13925  /* only if video response is appropriate */
13926  if (needvideo) {
13927  add_content(resp, bandwidth);
13928  }
13929  add_content(resp, session_time);
13930  /* if this is a response to an invite, order our offers properly */
13931  if (!AST_LIST_EMPTY(&p->offered_media)) {
13932  AST_LIST_TRAVERSE(&p->offered_media, offer, next) {
13933  switch (offer->type) {
13934  case SDP_AUDIO:
13935  if (needaudio) {
13936  add_content(resp, ast_str_buffer(m_audio));
13937  if (a_crypto) {
13938  add_content(resp, a_crypto);
13939  }
13940  add_content(resp, ast_str_buffer(a_audio));
13941  add_content(resp, hold);
13942  } else {
13943  add_content(resp, offer->decline_m_line);
13944  }
13945  break;
13946  case SDP_VIDEO:
13947  if (needvideo) { /* only if video response is appropriate */
13948  add_content(resp, ast_str_buffer(m_video));
13949  add_content(resp, ast_str_buffer(a_video));
13950  add_content(resp, hold); /* Repeat hold for the video stream */
13951  if (v_a_crypto) {
13952  add_content(resp, v_a_crypto);
13953  }
13954  } else {
13955  add_content(resp, offer->decline_m_line);
13956  }
13957  break;
13958  case SDP_TEXT:
13959  if (needtext) { /* only if text response is appropriate */
13960  add_content(resp, ast_str_buffer(m_text));
13961  add_content(resp, ast_str_buffer(a_text));
13962  add_content(resp, hold); /* Repeat hold for the text stream */
13963  if (t_a_crypto) {
13964  add_content(resp, t_a_crypto);
13965  }
13966  } else {
13967  add_content(resp, offer->decline_m_line);
13968  }
13969  break;
13970  case SDP_IMAGE:
13971  if (add_t38) {
13972  add_content(resp, ast_str_buffer(m_modem));
13973  add_content(resp, ast_str_buffer(a_modem));
13974  } else {
13975  add_content(resp, offer->decline_m_line);
13976  }
13977  break;
13978  case SDP_UNKNOWN:
13979  add_content(resp, offer->decline_m_line);
13980  break;
13981  }
13982  }
13983  } else {
13984  /* generate new SDP from scratch, no offers */
13985  if (needaudio) {
13986  add_content(resp, ast_str_buffer(m_audio));
13987  if (a_crypto) {
13988  add_content(resp, a_crypto);
13989  }
13990  add_content(resp, ast_str_buffer(a_audio));
13991  add_content(resp, hold);
13992  }
13993  if (needvideo) { /* only if video response is appropriate */
13994  add_content(resp, ast_str_buffer(m_video));
13995  add_content(resp, ast_str_buffer(a_video));
13996  add_content(resp, hold); /* Repeat hold for the video stream */
13997  if (v_a_crypto) {
13998  add_content(resp, v_a_crypto);
13999  }
14000  }
14001  if (needtext) { /* only if text response is appropriate */
14002  add_content(resp, ast_str_buffer(m_text));
14003  add_content(resp, ast_str_buffer(a_text));
14004  add_content(resp, hold); /* Repeat hold for the text stream */
14005  if (t_a_crypto) {
14006  add_content(resp, t_a_crypto);
14007  }
14008  }
14009  if (add_t38) {
14010  add_content(resp, ast_str_buffer(m_modem));
14011  add_content(resp, ast_str_buffer(a_modem));
14012  }
14013  }
14014 
14015  /* Update lastrtprx when we send our SDP */
14016  p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */
14017 
14018  /*
14019  * We unlink this dialog and link again into the
14020  * dialogs_rtpcheck container so its not in there twice.
14021  */
14023  ao2_t_unlink(dialogs_rtpcheck, p, "unlink pvt into dialogs_rtpcheck container");
14024  ao2_t_link(dialogs_rtpcheck, p, "link pvt into dialogs_rtpcheck container");
14026 
14027  ast_debug(3, "Done building SDP. Settling with this capability: %s\n",
14028  ast_format_cap_get_names(tmpcap, &codec_buf));
14029 
14030 add_sdp_cleanup:
14031  ast_free(a_text);
14032  ast_free(a_video);
14033  ast_free(a_audio);
14034  ao2_cleanup(alreadysent);
14035  ao2_cleanup(tmpcap);
14036 
14037  return res;
14038 }
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:290
#define SIP_PAGE3_ICE_SUPPORT
Definition: sip.h:390
#define SIP_PAGE3_RTCP_MUX
Definition: sip.h:394
static void add_dtls_to_sdp(struct ast_rtp_instance *instance, struct ast_str **a_buf)
Add DTLS attributes to SDP.
Definition: chan_sip.c:13194
int sessionversion
Definition: sip.h:1119
struct ast_format_cap * prefcaps
Definition: sip.h:1103
enum ast_media_type ast_format_get_type(const struct ast_format *format)
Get the media type of a format.
Definition: format.c:354
#define FALSE
Definition: app_minivm.c:521
static char * ast_sockaddr_stringify_addr_remote(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:317
int maxcallbitrate
Definition: sip.h:1106
time_t lastrtprx
Definition: sip.h:1129
struct ast_rtp_instance * trtp
Definition: sip.h:1176
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_control_t38_parameters our_parms
Definition: sip.h:918
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:171
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.
Definition: chan_sip.c:13410
#define SIP_PAGE2_CALL_ONHOLD_ONEDIR
Definition: sip.h:353
static void add_ice_to_sdp(struct ast_rtp_instance *instance, struct ast_str **a_buf)
Add ICE attributes to SDP.
Definition: chan_sip.c:13129
static void hold(struct ast_channel *chan)
Helper method to place a channel in a bridge on hold.
struct ast_rtp_codecs * ast_rtp_instance_get_codecs(struct ast_rtp_instance *instance)
Get the codecs structure of an RTP instance.
Definition: rtp_engine.c:727
#define LOG_WARNING
Definition: logger.h:274
struct ast_sdp_srtp * tsrtp
Definition: sip.h:1187
Definition: sip.h:493
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:326
static int debug
Global debug status.
Definition: res_xmpp.c:435
struct ast_sockaddr redirip
Definition: sip.h:1126
#define SIP_PAGE2_CALL_ONHOLD_INACTIVE
Definition: sip.h:354
unsigned int ast_udptl_get_local_max_datagram(struct ast_udptl *udptl)
retrieves local_max_datagram.
Definition: udptl.c:984
struct ast_sockaddr ourip
Definition: sip.h:1136
#define ao2_t_link(container, obj, tag)
Add an object to a container.
Definition: astobj2.h:1547
struct ast_format_cap * jointcaps
Definition: sip.h:1100
Definition of a media format.
Definition: format.c:43
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
#define ao2_t_unlink(container, obj, tag)
Remove an object from a container.
Definition: astobj2.h:1596
char * ast_sdp_get_rtp_profile(unsigned int sdes_active, struct ast_rtp_instance *instance, unsigned int using_avpf, unsigned int force_avp)
Get the RTP profile in use by a media session.
Definition: sdp_srtp.c:103
size_t ast_format_cap_count(const struct ast_format_cap *cap)
Get the number of formats present within the capabilities structure.
Definition: format_cap.c:395
#define SIP_PAGE2_CALL_ONHOLD
Definition: sip.h:351
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
#define ao2_unlock(a)
Definition: astobj2.h:730
struct ast_flags flags[3]
Definition: sip.h:1075
#define ast_str_alloca(init_len)
Definition: strings.h:800
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
void ast_rtp_codecs_set_framing(struct ast_rtp_codecs *codecs, unsigned int framing)
Set the framing used for a set of codecs.
Definition: rtp_engine.c:1558
unsigned short novideo
Definition: sip.h:1085
#define NULL
Definition: resample.c:96
Definition: sip.h:490
Socket address structure.
Definition: netsock2.h:97
int ast_sockaddr_cmp_addr(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares the addresses of two ast_sockaddr structures.
Definition: netsock2.c:413
int jointnoncodeccapability
Definition: sip.h:1105
struct t38properties t38
Definition: sip.h:1113
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.
Definition: chan_sip.c:13388
enum ast_t38_ec_modes ast_udptl_get_error_correction_scheme(const struct ast_udptl *udptl)
Definition: udptl.c:940
struct ast_sdp_srtp * vsrtp
Definition: sip.h:1186
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define SIP_PAGE3_FORCE_AVP
Definition: sip.h:393
enum ast_format_cmp_res ast_format_cap_iscompatible_format(const struct ast_format_cap *cap, const struct ast_format *format)
Find if ast_format is within the capabilities of the ast_format_cap object.
Definition: format_cap.c:583
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
void ast_udptl_get_us(const struct ast_udptl *udptl, struct ast_sockaddr *us)
Definition: udptl.c:1140
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:521
#define AST_RTP_MAX
Definition: rtp_engine.h:272
static char * ast_sockaddr_stringify_port(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return a port only.
Definition: netsock2.h:362
struct ast_rtp_dtls_cfg dtls_cfg
Definition: sip.h:1222
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static unsigned int t38_get_rate(enum ast_control_t38_rate rate)
Get Max T.38 Transmission rate from T38 capabilities.
Definition: chan_sip.c:13367
int sessionid
Definition: sip.h:1120
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define ao2_ref(o, delta)
Definition: astobj2.h:464
enum ast_control_t38_rate rate
long int ast_random(void)
Definition: main/utils.c:2064
#define ao2_lock(a)
Definition: astobj2.h:718
static void start_ice(struct ast_rtp_instance *instance, int offer)
Start ICE negotiation on an RTP instance.
Definition: chan_sip.c:13180
static char * crypto_get_attrib(struct ast_sdp_srtp *srtp, int dtls_enabled, int default_taglen_32)
Definition: chan_sip.c:13503
#define ast_format_cap_append(cap, format, framing)
Definition: format_cap.h:103
static void add_codec_to_sdp(const struct sip_pvt *p, struct ast_format *codec, struct ast_str **m_buf, struct ast_str **a_buf, int debug, int *min_packet_size, int *max_packet_size)
Add codec offer to SDP offer/answer body in INVITE or 200 OK.
Definition: chan_sip.c:13241
Definition: sip.h:492
struct ast_udptl * udptl
Definition: sip.h:1115
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
static char global_sdpowner[AST_MAX_EXTENSION]
Definition: chan_sip.c:845
enum media_type type
Definition: sip.h:985
Definition: sip.h:491
int ast_channel_timingfd(const struct ast_channel *chan)
Structure for remembering offered media in an INVITE, to make sure we reply to all media streams...
Definition: sip.h:984
unsigned int enabled
Definition: rtp_engine.h:555
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
struct ast_format_cap * redircaps
Definition: sip.h:1102
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
unsigned short notext
Definition: sip.h:1086
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:537
int method
Definition: sip.h:833
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
struct ast_rtp_instance * vrtp
Definition: sip.h:1175
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition: format_cap.c:736
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static char version[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:391
#define ast_free(a)
Definition: astmm.h:182
char * decline_m_line
Definition: sip.h:986
static char global_sdpsession[AST_MAX_EXTENSION]
Definition: chan_sip.c:844
struct ast_channel * owner
Definition: sip.h:1138
int ast_sockaddr_is_ipv4_mapped(const struct ast_sockaddr *addr)
Determine if this is an IPv4-mapped IPv6 address.
Definition: netsock2.c:507
struct ast_rtp_instance * rtp
Definition: sip.h:1174
static void add_vcodec_to_sdp(const struct sip_pvt *p, struct ast_format *format, 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.
Definition: chan_sip.c:13303
static int sip_debug_test_pvt(struct sip_pvt *p)
Test PVT for debugging output.
Definition: chan_sip.c:3649
static int sipdebug_text
extra debugging for &#39;text&#39; related events. At the moment this is set together with sip_debug_console...
Definition: chan_sip.c:922
time_t lastrtptx
Definition: sip.h:1130
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define TRUE
Definition: app_minivm.c:518
enum ast_control_t38_rate_management rate_management
#define SIP_PAGE3_SRTP_TAG_32
Definition: sip.h:385
static void add_tcodec_to_sdp(const struct sip_pvt *p, struct ast_format *format, 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.
Definition: chan_sip.c:13334
#define SIP_PAGE3_IGNORE_PREFCAPS
Definition: sip.h:391
#define SIP_OUTGOING
Definition: sip.h:257
int ast_format_cap_append_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type)
Append the formats of provided type in src to dst.
Definition: format_cap.c:269
struct ao2_container * dialogs_rtpcheck
Definition: chan_sip.c:1032
struct ast_format * ast_format_cap_get_format(const struct ast_format_cap *cap, int position)
Get the format at a specific index.
Definition: format_cap.c:400
struct sip_pvt::@174 offered_media
struct ast_sdp_srtp * srtp
Definition: sip.h:1185
static int add_content(struct sip_request *req, const char *line)
Add content (not header) to SIP message.
Definition: chan_sip.c:11931
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873
int ast_format_cap_get_compatible(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2, struct ast_format_cap *result)
Find the compatible formats between two capabilities structures.
Definition: format_cap.c:630
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
Definition: netsock2.c:524
int ast_format_cap_has_type(const struct ast_format_cap *cap, enum ast_media_type type)
Find out if the capabilities structure has any formats of a specific type.
Definition: format_cap.c:615
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620
#define SIP_PAGE3_USE_AVPF
Definition: sip.h:389

◆ add_sip_domain()

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 31284 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, domain::context, d, domain::domain, LOG_WARNING, domain::mode, and sipdebug.

Referenced by reload_config().

31285 {
31286  struct domain *d;
31287 
31288  if (ast_strlen_zero(domain)) {
31289  ast_log(LOG_WARNING, "Zero length domain.\n");
31290  return 1;
31291  }
31292 
31293  if (!(d = ast_calloc(1, sizeof(*d))))
31294  return 0;
31295 
31296  ast_copy_string(d->domain, domain, sizeof(d->domain));
31297 
31298  if (!ast_strlen_zero(context))
31299  ast_copy_string(d->context, context, sizeof(d->context));
31300 
31301  d->mode = mode;
31302 
31306 
31307  if (sipdebug)
31308  ast_debug(1, "Added local SIP domain '%s'\n", domain);
31309 
31310  return 1;
31311 }
struct domain::@167 list
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define LOG_WARNING
Definition: logger.h:274
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
static struct test_val d
Domain data structure.
Definition: sip.h:888
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
enum domain_mode mode
Definition: sip.h:891
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
char domain[MAXHOSTNAMELEN]
Definition: sip.h:889
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
char context[AST_MAX_EXTENSION]
Definition: sip.h:890

◆ add_supported()

static int add_supported ( 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 11859 of file chan_sip.c.

References add_header(), ast_test_flag, sip_pvt::flags, SESSION_TIMER_MODE_REFUSE, SIP_USEPATH, SIPBUFSIZE, and st_get_mode().

Referenced by respprep(), transmit_invite(), transmit_notify_with_sipfrag(), transmit_register(), transmit_reinvite_with_sdp(), and update_connectedline().

11860 {
11861  char supported_value[SIPBUFSIZE];
11862  int res;
11863 
11864  sprintf(supported_value, "replaces%s%s",
11865  (st_get_mode(pvt, 0) != SESSION_TIMER_MODE_REFUSE) ? ", timer" : "",
11866  ast_test_flag(&pvt->flags[0], SIP_USEPATH) ? ", path" : "");
11867  res = add_header(req, "Supported", supported_value);
11868 
11869  return res;
11870 }
#define SIP_USEPATH
Definition: sip.h:305
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_flags flags[3]
Definition: sip.h:1075
static enum st_mode st_get_mode(struct sip_pvt *, int no_cached)
Get the session-timer mode.
Definition: chan_sip.c:30447
#define SIPBUFSIZE
Definition: sip.h:56
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873

◆ add_tcodec_to_sdp()

static void add_tcodec_to_sdp ( const struct sip_pvt p,
struct ast_format format,
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 13334 of file chan_sip.c.

References ast_format_cmp(), AST_FORMAT_CMP_EQUAL, ast_format_get_name(), ast_format_t140, ast_format_t140_red, ast_rtp_codecs_payload_code(), ast_rtp_instance_get_codecs(), ast_rtp_lookup_mime_subtype2(), ast_rtp_lookup_sample_rate2(), ast_str_append(), ast_verbose(), and sip_pvt::trtp.

Referenced by add_sdp().

13337 {
13338  int rtp_code;
13339 
13340  if (!p->trtp)
13341  return;
13342 
13343  if (debug)
13344  ast_verbose("Adding text codec %s to SDP\n", ast_format_get_name(format));
13345 
13346  if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->trtp), 1, format, 0)) == -1)
13347  return;
13348 
13349  ast_str_append(m_buf, 0, " %d", rtp_code);
13350  ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%u\r\n", rtp_code,
13351  ast_rtp_lookup_mime_subtype2(1, format, 0, 0),
13352  ast_rtp_lookup_sample_rate2(1, format, 0));
13353  /* Add fmtp code here */
13354 
13357  ast_str_append(a_buf, 0, "a=fmtp:%d %d/%d/%d\r\n", rtp_code,
13358  t140code,
13359  t140code,
13360  t140code);
13361 
13362  }
13363 }
struct ast_format * ast_format_t140_red
Built-in cached t140 red format.
Definition: format_cache.c:241
struct ast_rtp_instance * trtp
Definition: sip.h:1176
struct ast_rtp_codecs * ast_rtp_instance_get_codecs(struct ast_rtp_instance *instance)
Get the codecs structure of an RTP instance.
Definition: rtp_engine.c:727
static int debug
Global debug status.
Definition: res_xmpp.c:435
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
const char * ast_rtp_lookup_mime_subtype2(const int asterisk_format, const struct ast_format *format, int code, enum ast_rtp_options options)
Retrieve mime subtype information on a payload.
Definition: rtp_engine.c:1992
int ast_rtp_codecs_payload_code(struct ast_rtp_codecs *codecs, int asterisk_format, struct ast_format *format, int code)
Retrieve a rx mapped payload type based on whether it is an Asterisk format and the code...
Definition: rtp_engine.c:1873
unsigned int ast_rtp_lookup_sample_rate2(int asterisk_format, const struct ast_format *format, int code)
Get the sample rate associated with known RTP payload types.
Definition: rtp_engine.c:2022
struct ast_format * ast_format_t140
Built-in cached t140 format.
Definition: format_cache.c:236

◆ add_text()

static int add_text ( struct sip_request req,
struct sip_pvt p 
)
static

Add text body to SIP message.

Definition at line 12931 of file chan_sip.c.

References add_content(), add_header(), AST_LIST_TRAVERSE, ast_strlen_zero, sip_pvt::msg_body, sip_pvt::msg_headers, sip_msg_hdr::name, NULL, and sip_msg_hdr::value.

Referenced by transmit_message(), and transmit_request_with_auth().

12932 {
12933  const char *content_type = NULL;
12934  struct sip_msg_hdr *node;
12935 
12936  /* Add any additional MESSAGE headers. */
12937  AST_LIST_TRAVERSE(&p->msg_headers, node, next) {
12938  if (!strcasecmp(node->name, "Content-Type")) {
12939  /* Save content type */
12940  content_type = node->value;
12941  } else {
12942  add_header(req, node->name, node->value);
12943  }
12944  }
12945  if (ast_strlen_zero(content_type)) {
12946  /* "Content-Type" not set - use default value */
12947  content_type = "text/plain;charset=UTF-8";
12948  }
12949  add_header(req, "Content-Type", content_type);
12950 
12951  /* XXX Convert \n's to \r\n's XXX */
12952  add_content(req, p->msg_body);
12953  return 0;
12954 }
Definition: test_heap.c:38
const char * value
Definition: sip.h:996
const char * name
Definition: sip.h:994
struct sip_pvt::@173 msg_headers
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
const ast_string_field msg_body
Definition: sip.h:1063
struct sip_msg_hdr * next
Definition: sip.h:992
static int add_content(struct sip_request *req, const char *line)
Add content (not header) to SIP message.
Definition: chan_sip.c:11931
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873

◆ add_var()

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

implement the setvar config line

Definition at line 31464 of file chan_sip.c.

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

Referenced by build_peer().

31465 {
31466  struct ast_variable *tmpvar = NULL;
31467  char *varname = ast_strdupa(buf), *varval = NULL;
31468 
31469  if ((varval = strchr(varname, '='))) {
31470  *varval++ = '\0';
31471  if ((tmpvar = ast_variable_new(varname, varval, ""))) {
31472  if (ast_variable_list_replace(&list, tmpvar)) {
31473  tmpvar->next = list;
31474  list = tmpvar;
31475  }
31476  }
31477  }
31478  return list;
31479 }
struct ast_variable * next
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96
int ast_variable_list_replace(struct ast_variable **head, struct ast_variable *replacement)
Replace a variable in the given list with a new value.
Definition: main/config.c:668
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define ast_variable_new(name, value, filename)

◆ add_vcodec_to_sdp()

static void add_vcodec_to_sdp ( const struct sip_pvt p,
struct ast_format format,
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 13303 of file chan_sip.c.

References ast_format_cmp(), AST_FORMAT_CMP_EQUAL, ast_format_generate_sdp_fmtp(), ast_format_get_name(), ast_format_vp8, ast_rtp_codecs_payload_code(), ast_rtp_instance_get_codecs(), ast_rtp_lookup_mime_subtype2(), ast_rtp_lookup_sample_rate2(), ast_str_append(), ast_verbose(), and sip_pvt::vrtp.

Referenced by add_sdp().

13306 {
13307  int rtp_code;
13308  const char *subtype;
13309  unsigned int rate;
13310 
13311  if (!p->vrtp)
13312  return;
13313 
13314  if (debug)
13315  ast_verbose("Adding video codec %s to SDP\n", ast_format_get_name(format));
13316 
13317  if (((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->vrtp), 1, format, 0)) == -1) ||
13318  !(subtype = ast_rtp_lookup_mime_subtype2(1, format, 0, 0)) ||
13319  !(rate = ast_rtp_lookup_sample_rate2(1, format, 0))) {
13320  return;
13321  }
13322 
13323  ast_str_append(m_buf, 0, " %d", rtp_code);
13324  ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%u\r\n", rtp_code, subtype, rate);
13325  /* VP8: add RTCP FIR support */
13327  ast_str_append(a_buf, 0, "a=rtcp-fb:* ccm fir\r\n");
13328  }
13329 
13330  ast_format_generate_sdp_fmtp(format, rtp_code, a_buf);
13331 }
struct ast_format * ast_format_vp8
Built-in cached vp8 format.
Definition: format_cache.c:196
struct ast_rtp_codecs * ast_rtp_instance_get_codecs(struct ast_rtp_instance *instance)
Get the codecs structure of an RTP instance.
Definition: rtp_engine.c:727
static int debug
Global debug status.
Definition: res_xmpp.c:435
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
const char * ast_rtp_lookup_mime_subtype2(const int asterisk_format, const struct ast_format *format, int code, enum ast_rtp_options options)
Retrieve mime subtype information on a payload.
Definition: rtp_engine.c:1992
int ast_rtp_codecs_payload_code(struct ast_rtp_codecs *codecs, int asterisk_format, struct ast_format *format, int code)
Retrieve a rx mapped payload type based on whether it is an Asterisk format and the code...
Definition: rtp_engine.c:1873
struct ast_rtp_instance * vrtp
Definition: sip.h:1175
unsigned int ast_rtp_lookup_sample_rate2(int asterisk_format, const struct ast_format *format, int code)
Get the sample rate associated with known RTP payload types.
Definition: rtp_engine.c:2022
void ast_format_generate_sdp_fmtp(const struct ast_format *format, unsigned int payload, struct ast_str **str)
This function is used to produce an fmtp SDP line for an Asterisk format. The attributes present on t...
Definition: format.c:305

◆ add_vidupdate()

static int add_vidupdate ( struct sip_request req)
static

add XML encoded media control with update

Note
XML: The only way to turn 0 bits of information into a few hundred. (markster)

Definition at line 13111 of file chan_sip.c.

References add_content(), and add_header().

Referenced by transmit_info_with_vidupdate().

13112 {
13113  const char *xml_is_a_huge_waste_of_space =
13114  "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n"
13115  " <media_control>\r\n"
13116  " <vc_primitive>\r\n"
13117  " <to_encoder>\r\n"
13118  " <picture_fast_update>\r\n"
13119  " </picture_fast_update>\r\n"
13120  " </to_encoder>\r\n"
13121  " </vc_primitive>\r\n"
13122  " </media_control>\r\n";
13123  add_header(req, "Content-Type", "application/media_control+xml");
13124  add_content(req, xml_is_a_huge_waste_of_space);
13125  return 0;
13126 }
static int add_content(struct sip_request *req, const char *line)
Add content (not header) to SIP message.
Definition: chan_sip.c:11931
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873

◆ allow_notify_user_presence()

static int allow_notify_user_presence ( struct sip_pvt p)
static

Definition at line 15187 of file chan_sip.c.

References sip_pvt::useragent.

Referenced by cb_extensionstate(), handle_request_subscribe(), and state_notify_build_xml().

15188 {
15189  return (strstr(p->useragent, "Digium")) ? 1 : 0;
15190 }
const ast_string_field useragent
Definition: sip.h:1063

◆ allowoverlap2str()

static const char * allowoverlap2str ( int  mode)
static

Convert AllowOverlap setting to printable string.

Definition at line 20631 of file chan_sip.c.

References map_x_s().

Referenced by _sip_show_peer(), and sip_show_settings().

20632 {
20633  return map_x_s(allowoverlapstr, mode, "<error>");
20634 }
static const struct _map_x_s allowoverlapstr[]
Definition: chan_sip.c:20623
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
Definition: chan_sip.c:2411

◆ AO2_GLOBAL_OBJ_STATIC()

static AO2_GLOBAL_OBJ_STATIC ( g_bogus_peer  )
static

A bogus peer, to be used when authentication should fail.

◆ append_history_full()

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

Append to SIP dialog history with arg list.

Definition at line 4017 of file chan_sip.c.

References append_history_va(), sip_pvt::do_history, dumphistory, and recordhistory.

Referenced by dialog_unlink_all().

4018 {
4019  va_list ap;
4020 
4021  if (!p) {
4022  return;
4023  }
4024 
4025  if (!p->do_history && !recordhistory && !dumphistory) {
4026  return;
4027  }
4028 
4029  va_start(ap, fmt);
4030  append_history_va(p, fmt, ap);
4031  va_end(ap);
4032 
4033  return;
4034 }
static unsigned int dumphistory
Definition: chan_sip.c:842
static unsigned int recordhistory
Definition: chan_sip.c:841
unsigned short do_history
Definition: sip.h:1078
static void append_history_va(struct sip_pvt *p, const char *fmt, va_list ap)
Append to SIP dialog history with arg list.
Definition: chan_sip.c:3986

◆ append_history_va()

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

References ast_calloc, ast_free, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, ast_log_dynamic_level, buf, c, sip_history::event, log_level, MAX_HISTORY_ENTRIES, and strsep().

Referenced by append_history_full().

3987 {
3988  char buf[80], *c = buf; /* max history length */
3989  struct sip_history *hist;
3990  int l;
3991 
3992  vsnprintf(buf, sizeof(buf), fmt, ap);
3993  strsep(&c, "\r\n"); /* Trim up everything after \r or \n */
3994  l = strlen(buf) + 1;
3995  if (!(hist = ast_calloc(1, sizeof(*hist) + l))) {
3996  return;
3997  }
3998  if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) {
3999  ast_free(hist);
4000  return;
4001  }
4002  memcpy(hist->event, buf, l);
4004  struct sip_history *oldest;
4005  oldest = AST_LIST_REMOVE_HEAD(p->history, list);
4006  p->history_entries--;
4007  ast_free(oldest);
4008  }
4009  AST_LIST_INSERT_TAIL(p->history, hist, list);
4010  p->history_entries++;
4011  if (log_level != -1) {
4012  ast_log_dynamic_level(log_level, "%s\n", buf);
4013  }
4014 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
size_t history_entries
Definition: sip.h:1179
#define ast_log_dynamic_level(level,...)
Send a log message to a dynamically registered log level.
Definition: logger.h:439
#define MAX_HISTORY_ENTRIES
Definition: sip.h:115
static struct test_val c
static int log_level
Definition: chan_sip.c:665
char event[0]
Definition: sip.h:898
struct sip_history_head * history
Definition: sip.h:1178
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
char * strsep(char **str, const char *delims)
struct sip_history::@168 list
sip_history: Structure for saving transactions within a SIP dialog
Definition: sip.h:896

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 35928 of file chan_sip.c.

◆ ast_sip_ouraddrfor()

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

References AST_AF_INET, ast_apply_ha(), ast_debug, ast_log, ast_ouraddrfor(), AST_SENSE_ALLOW, ast_sockaddr_copy(), ast_sockaddr_is_any(), ast_sockaddr_is_ipv4_mapped(), ast_sockaddr_is_ipv6(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_resolve_first_af(), ast_sockaddr_set_port, ast_sockaddr_stringify(), AST_TRANSPORT_TCP, AST_TRANSPORT_TLS, AST_TRANSPORT_UDP, bindaddr, externaddr, externexpire, externhost, externrefresh, externtcpport, externtlsport, internip, ast_tcptls_session_args::local_address, LOG_NOTICE, LOG_WARNING, sip_settings::matchexternaddrlocally, NULL, sip_cfg, sip_get_transport(), sip_pvt::socket, STANDARD_SIP_PORT, STANDARD_TLS_PORT, and sip_socket::type.

Referenced by __sip_alloc(), __sip_subscribe_mwi_do(), manager_sipnotify(), sip_cc_monitor_request_cc(), sip_cli_notify(), sip_msg_send(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_publish(), transmit_register(), and transmit_response_using_temp().

3867 {
3868  struct ast_sockaddr theirs;
3869 
3870  /* Set want_remap to non-zero if we want to remap 'us' to an externally
3871  * reachable IP address and port. This is done if:
3872  * 1. we have a localaddr list (containing 'internal' addresses marked
3873  * as 'deny', so ast_apply_ha() will return AST_SENSE_DENY on them,
3874  * and AST_SENSE_ALLOW on 'external' ones);
3875  * 2. externaddr is set, so we know what to use as the
3876  * externally visible address;
3877  * 3. the remote address, 'them', is external;
3878  * 4. the address returned by ast_ouraddrfor() is 'internal' (AST_SENSE_DENY
3879  * when passed to ast_apply_ha() so it does need to be remapped.
3880  * This fourth condition is checked later.
3881  */
3882  int want_remap = 0;
3883 
3884  ast_sockaddr_copy(us, &internip); /* starting guess for the internal address */
3885  /* now ask the system what would it use to talk to 'them' */
3886  ast_ouraddrfor(them, us);
3887  ast_sockaddr_copy(&theirs, them);
3888 
3889  if (ast_sockaddr_is_ipv6(&theirs) && !ast_sockaddr_is_ipv4_mapped(&theirs)) {
3891  ast_log(LOG_WARNING, "Address remapping activated in sip.conf "
3892  "but we're using IPv6, which doesn't need it. Please "
3893  "remove \"localnet\" and/or \"externaddr\" settings.\n");
3894  }
3895  } else {
3896  want_remap = localaddr &&
3898  ast_apply_ha(localaddr, &theirs) == AST_SENSE_ALLOW ;
3899  }
3900 
3901  if (want_remap &&
3903  /* if we used externhost, see if it is time to refresh the info */
3904  if (externexpire && time(NULL) >= externexpire) {
3906  ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost);
3907  }
3908  externexpire = time(NULL) + externrefresh;
3909  }
3912  switch (p->socket.type) {
3913  case AST_TRANSPORT_TCP:
3915  /* for consistency, default to the externaddr port */
3917  }
3918  if (!externtcpport) {
3920  }
3921  if (!externtcpport) {
3923  }
3925  break;
3926  case AST_TRANSPORT_TLS:
3927  if (!externtlsport) {
3929  }
3930  if (!externtlsport) {
3932  }
3934  break;
3935  case AST_TRANSPORT_UDP:
3936  if (!ast_sockaddr_port(&externaddr)) {
3938  }
3939  break;
3940  default:
3941  break;
3942  }
3943  }
3944  ast_debug(1, "Target address %s is not local, substituting externaddr\n",
3945  ast_sockaddr_stringify(them));
3946  } else {
3947  /* no remapping, but we bind to a specific address, so use it. */
3948  switch (p->socket.type) {
3949  case AST_TRANSPORT_TCP:
3952  ast_sockaddr_copy(us,
3954  } else {
3957  }
3958  break;
3959  } /* fall through on purpose */
3960  case AST_TRANSPORT_TLS:
3963  ast_sockaddr_copy(us,
3965  } else {
3968  }
3969  break;
3970  } /* fall through on purpose */
3971  case AST_TRANSPORT_UDP:
3972  /* fall through on purpose */
3973  default:
3974  if (!ast_sockaddr_is_any(&bindaddr)) {
3976  }
3977  if (!ast_sockaddr_port(us)) {
3979  }
3980  }
3981  }
3982  ast_debug(3, "Setting AST_TRANSPORT_%s with address %s\n", sip_get_transport(p->socket.type), ast_sockaddr_stringify(us));
3983 }
static struct ast_tcptls_session_args sip_tls_desc
The TCP/TLS server definition.
Definition: chan_sip.c:2394
static uint16_t externtcpport
Definition: chan_sip.c:1138
static struct ast_ha * localaddr
List of local networks We store "localnet" addresses from the config file into an access list...
Definition: chan_sip.c:1147
int matchexternaddrlocally
Definition: sip.h:769
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:171
#define LOG_WARNING
Definition: logger.h:274
struct sip_socket socket
Definition: sip.h:1066
const char * sip_get_transport(enum ast_transport t)
Return transport as string.
Definition: chan_sip.c:3725
enum ast_acl_sense ast_apply_ha(const struct ast_ha *ha, const struct ast_sockaddr *addr)
Apply a set of rules to a given IP address.
Definition: acl.c:808
static struct ast_tcptls_session_args sip_tcp_desc
The TCP server definition.
Definition: chan_sip.c:2383
static struct ast_sockaddr internip
our (internal) default address/port to put in SIP/SDP messages internip is initialized picking a suit...
Definition: chan_sip.c:1114
#define NULL
Definition: resample.c:96
Socket address structure.
Definition: netsock2.h:97
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:521
int ast_ouraddrfor(const struct ast_sockaddr *them, struct ast_sockaddr *us)
Get our local IP address when contacting a remote host.
Definition: acl.c:1005
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define STANDARD_TLS_PORT
Standard SIP TLS port from RFC 3261. DO NOT CHANGE THIS.
Definition: sip.h:178
int ast_sockaddr_is_any(const struct ast_sockaddr *addr)
Determine if the address type is unspecified, or "any" address.
Definition: netsock2.c:534
#define STANDARD_SIP_PORT
Standard SIP unsecure port for UDP and TCP from RFC 3261. DO NOT CHANGE THIS.
Definition: sip.h:176
static uint16_t externtlsport
Definition: chan_sip.c:1139
static char externhost[MAXHOSTNAMELEN]
Definition: chan_sip.c:1135
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.
Definition: netsock2.c:337
static struct ast_sockaddr externaddr
our external IP address/port for SIP sessions. externaddr.sin_addr is only set when we know we might ...
Definition: chan_sip.c:1131
static time_t externexpire
Definition: chan_sip.c:1136
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:537
struct ast_sockaddr bindaddr
Definition: chan_sip.c:1106
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
static int externrefresh
Definition: chan_sip.c:1137
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
#define LOG_NOTICE
Definition: logger.h:263
int ast_sockaddr_is_ipv4_mapped(const struct ast_sockaddr *addr)
Determine if this is an IPv4-mapped IPv6 address.
Definition: netsock2.c:507
enum ast_transport type
Definition: sip.h:798
struct ast_sockaddr local_address
Definition: tcptls.h:130
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
Definition: netsock2.c:524

◆ ast_sockaddr_resolve_first()

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.

Warning
Using this function probably means you have a faulty design.

Definition at line 34469 of file chan_sip.c.

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

Referenced by check_via().

34471 {
34473 }
static int get_address_family_filter(unsigned int transport)
Helper for dns resolution to filter by address family.
Definition: chan_sip.c:29558
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.
Definition: netsock2.c:337
long int flag
Definition: f2c.h:83
static const char name[]
Definition: cdr_mysql.c:74

◆ ast_sockaddr_resolve_first_transport()

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.

Warning
Using this function probably means you have a faulty design.

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

34481 {
34483 }
static int get_address_family_filter(unsigned int transport)
Helper for dns resolution to filter by address family.
Definition: chan_sip.c:29558
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.
Definition: netsock2.c:337
long int flag
Definition: f2c.h:83
static const char name[]
Definition: cdr_mysql.c:74

◆ AST_TEST_DEFINE() [1/3]

AST_TEST_DEFINE ( test_sip_mwi_subscribe_parse  )

Definition at line 34741 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_iterator_next, ao2_t_ref, ao2_unlock, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, sip_subscription_mwi::authuser, sip_subscription_mwi::hostname, sip_to_pjsip::info(), sip_subscription_mwi::mailbox, sip_subscription_mwi::portno, sip_subscription_mwi::secret, sip_subscribe_mwi(), TEST_EXECUTE, TEST_INIT, and sip_subscription_mwi::username.

34742 {
34743  struct ao2_iterator iter;
34744  struct sip_subscription_mwi *iterator;
34745  int found = 0;
34747  const char *mwi1 = "[email protected]/1234";
34748  const char *mwi2 = "1234:[email protected]/1234";
34749  const char *mwi3 = "1234:[email protected]:5061/1234";
34750  const char *mwi4 = "1234:password:[email protected]/1234";
34751  const char *mwi5 = "1234:password:[email protected]:5061/1234";
34752  const char *mwi6 = "1234:password";
34753 
34754  switch (cmd) {
34755  case TEST_INIT:
34756  info->name = "sip_mwi_subscribe_parse_test";
34757  info->category = "/channels/chan_sip/";
34758  info->summary = "SIP MWI subscribe line parse unit test";
34759  info->description =
34760  "Tests the parsing of mwi subscription lines (e.g., mwi => from sip.conf)";
34761  return AST_TEST_NOT_RUN;
34762  case TEST_EXECUTE:
34763  break;
34764  }
34765 
34766  if (sip_subscribe_mwi(mwi1, 1)) {
34767  res = AST_TEST_FAIL;
34768  } else {
34769  found = 0;
34770  res = AST_TEST_FAIL;
34771 
34773  while ((iterator = ao2_t_iterator_next(&iter, "test_sip_mwi_subscribe_parse mwi1"))) {
34774  ao2_lock(iterator);
34775  if (
34776  !strcmp(iterator->hostname, "mysipprovider.com") &&
34777  !strcmp(iterator->username, "1234") &&
34778  !strcmp(iterator->secret, "") &&
34779  !strcmp(iterator->authuser, "") &&
34780  !strcmp(iterator->mailbox, "1234") &&
34781  iterator->portno == 0) {
34782  found = 1;
34783  res = AST_TEST_PASS;
34784  }
34785  ao2_unlock(iterator);
34786  ao2_t_ref(iterator, -1, "test_sip_mwi_subscribe_parse mwi1");
34787  }
34788  ao2_iterator_destroy(&iter);
34789  if (!found) {
34790  ast_test_status_update(test, "sip_subscribe_mwi test 1 failed\n");
34791  }
34792  }
34793 
34794  if (sip_subscribe_mwi(mwi2, 1)) {
34795  res = AST_TEST_FAIL;
34796  } else {
34797  found = 0;
34798  res = AST_TEST_FAIL;
34799 
34801  while ((iterator = ao2_t_iterator_next(&iter, "test_sip_mwi_subscribe_parse mwi2"))) {
34802  ao2_lock(iterator);
34803  if (
34804  !strcmp(iterator->hostname, "mysipprovider.com") &&
34805  !strcmp(iterator->username, "1234") &&
34806  !strcmp(iterator->secret, "password") &&
34807  !strcmp(iterator->authuser, "") &&
34808  !strcmp(iterator->mailbox, "1234") &&
34809  iterator->portno == 0) {
34810  found = 1;
34811  res = AST_TEST_PASS;
34812  }
34813  ao2_unlock(iterator);
34814  ao2_t_ref(iterator, -1, "test_sip_mwi_subscribe_parse mwi2");
34815  }
34816  ao2_iterator_destroy(&iter);
34817  if (!found) {
34818  ast_test_status_update(test, "sip_subscribe_mwi test 2 failed\n");
34819  }
34820  }
34821 
34822  if (sip_subscribe_mwi(mwi3, 1)) {
34823  res = AST_TEST_FAIL;
34824  } else {
34825  found = 0;
34826  res = AST_TEST_FAIL;
34827 
34829  while ((iterator = ao2_t_iterator_next(&iter, "test_sip_mwi_subscribe_parse mwi3"))) {
34830  ao2_lock(iterator);
34831  if (
34832  !strcmp(iterator->hostname, "mysipprovider.com") &&
34833  !strcmp(iterator->username, "1234") &&
34834  !strcmp(iterator->secret, "password") &&
34835  !strcmp(iterator->authuser, "") &&
34836  !strcmp(iterator->mailbox, "1234") &&
34837  iterator->portno == 5061) {
34838  found = 1;
34839  res = AST_TEST_PASS;
34840  }
34841  ao2_unlock(iterator);
34842  ao2_t_ref(iterator, -1, "test_sip_mwi_subscribe_parse mwi3");
34843  }
34844  ao2_iterator_destroy(&iter);
34845  if (!found) {
34846  ast_test_status_update(test, "sip_subscribe_mwi test 3 failed\n");
34847  }
34848  }
34849 
34850  if (sip_subscribe_mwi(mwi4, 1)) {
34851  res = AST_TEST_FAIL;
34852  } else {
34853  found = 0;
34854  res = AST_TEST_FAIL;
34855 
34857  while ((iterator = ao2_t_iterator_next(&iter, "test_sip_mwi_subscribe_parse mwi4"))) {
34858  ao2_lock(iterator);
34859  if (
34860  !strcmp(iterator->hostname, "mysipprovider.com") &&
34861  !strcmp(iterator->username, "1234") &&
34862  !strcmp(iterator->secret, "password") &&
34863  !strcmp(iterator->authuser, "authuser") &&
34864  !strcmp(iterator->mailbox, "1234") &&
34865  iterator->portno == 0) {
34866  found = 1;
34867  res = AST_TEST_PASS;
34868  }
34869  ao2_unlock(iterator);
34870  ao2_t_ref(iterator, -1, "test_sip_mwi_subscribe_parse mwi4");
34871  }
34872  ao2_iterator_destroy(&iter);
34873  if (!found) {
34874  ast_test_status_update(test, "sip_subscribe_mwi test 4 failed\n");
34875  }
34876  }
34877 
34878  if (sip_subscribe_mwi(mwi5, 1)) {
34879  res = AST_TEST_FAIL;
34880  } else {
34881  found = 0;
34882  res = AST_TEST_FAIL;
34883 
34885  while ((iterator = ao2_t_iterator_next(&iter, "test_sip_mwi_subscribe_parse mwi4"))) {
34886  ao2_lock(iterator);
34887  if (
34888  !strcmp(iterator->hostname, "mysipprovider.com") &&
34889  !strcmp(iterator->username, "1234") &&
34890  !strcmp(iterator->secret, "password") &&
34891  !strcmp(iterator->authuser, "authuser") &&
34892  !strcmp(iterator->mailbox, "1234") &&
34893  iterator->portno == 5061) {
34894  found = 1;
34895  res = AST_TEST_PASS;
34896  }
34897  ao2_unlock(iterator);
34898  ao2_t_ref(iterator, -1, "test_sip_mwi_subscribe_parse mwi4");
34899  }
34900  ao2_iterator_destroy(&iter);
34901  if (!found) {
34902  ast_test_status_update(test, "sip_subscribe_mwi test 5 failed\n");
34903  }
34904  }
34905 
34906  if (sip_subscribe_mwi(mwi6, 1)) {
34907  res = AST_TEST_PASS;
34908  } else {
34909  res = AST_TEST_FAIL;
34910  }
34911  return res;
34912 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
const ast_string_field hostname
Definition: sip.h:1461
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_unlock(a)
Definition: astobj2.h:730
const ast_string_field mailbox
Definition: sip.h:1461
const ast_string_field username
Definition: sip.h:1461
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
#define ao2_lock(a)
Definition: astobj2.h:718
const ast_string_field authuser
Definition: sip.h:1461
#define ao2_t_iterator_next(iter, tag)
Definition: astobj2.h:1931
def info(msg)
Definition of an MWI subscription to another server.
Definition: sip.h:1454
static struct ao2_container * subscription_mwi_list
The MWI subscription list.
Definition: chan_sip.c:1064
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
const ast_string_field secret
Definition: sip.h:1461
static int sip_subscribe_mwi(const char *value, int lineno)
Parse mwi=> line in sip.conf and add to list.
Definition: chan_sip.c:9720
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
ast_test_result_state
Definition: test.h:200

◆ AST_TEST_DEFINE() [2/3]

AST_TEST_DEFINE ( test_tcp_message_fragmentation  )

Definition at line 34971 of file chan_sip.c.

References ARRAY_LEN, ast_free, ast_log, ast_str_create, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, sip_to_pjsip::info(), LOG_WARNING, mock_tcp_loop(), sip_settings::pedanticsipchecking, sip_cfg, TEST_EXECUTE, and TEST_INIT.

34972 {
34973  /* Normal single message in one fragment */
34974  char *normal[] = {
34975  "INVITE sip:[email protected] SIP/2.0\r\n"
34976  "Via: SIP/2.0/TCP 127.0.0.1:5060;branch=[branch]\r\n"
34977  "From: sipp <sip:127.0.0.1:5061>;tag=12345\r\n"
34978  "To: <sip:[email protected]:5060>\r\n"
34979  "Call-ID: 12345\r\n"
34980  "CSeq: 1 INVITE\r\n"
34981  "Contact: sip:127.0.0.1:5061\r\n"
34982  "Max-Forwards: 70\r\n"
34983  "Content-Type: application/sdp\r\n"
34984  "Content-Length: 130\r\n"
34985  "\r\n"
34986  "v=0\r\n"
34987  "o=user1 53655765 2353687637 IN IP4 127.0.0.1\r\n"
34988  "s=-\r\n"
34989  "c=IN IP4 127.0.0.1\r\n"
34990  "t=0 0\r\n"
34991  "m=audio 10000 RTP/AVP 0\r\n"
34992  "a=rtpmap:0 PCMU/8000\r\n"
34993  };
34994 
34995  /* Single message in two fragments.
34996  * Fragments combine to make "normal"
34997  */
34998  char *fragmented[] = {
34999  "INVITE sip:[email protected] SIP/2.0\r\n"
35000  "Via: SIP/2.0/TCP 127.0.0.1:5060;branch=[branch]\r\n"
35001  "From: sipp <sip:127.0.0.1:5061>;tag=12345\r\n"
35002  "To: <sip:[email protected]:5060>\r\n"
35003  "Call-ID: 12345\r\n"
35004  "CSeq: 1 INVITE\r\n"
35005  "Contact: sip:127.0.0.1:5061\r\n"
35006  "Max-Forwards: ",
35007 
35008  "70\r\n"
35009  "Content-Type: application/sdp\r\n"
35010  "Content-Length: 130\r\n"
35011  "\r\n"
35012  "v=0\r\n"
35013  "o=user1 53655765 2353687637 IN IP4 127.0.0.1\r\n"
35014  "s=-\r\n"
35015  "c=IN IP4 127.0.0.1\r\n"
35016  "t=0 0\r\n"
35017  "m=audio 10000 RTP/AVP 0\r\n"
35018  "a=rtpmap:0 PCMU/8000\r\n"
35019  };
35020  /* Single message in two fragments, divided precisely at the body
35021  * Fragments combine to make "normal"
35022  */
35023  char *fragmented_body[] = {
35024  "INVITE sip:[email protected] SIP/2.0\r\n"
35025  "Via: SIP/2.0/TCP 127.0.0.1:5060;branch=[branch]\r\n"
35026  "From: sipp <sip:127.0.0.1:5061>;tag=12345\r\n"
35027  "To: <sip:[email protected]:5060>\r\n"
35028  "Call-ID: 12345\r\n"
35029  "CSeq: 1 INVITE\r\n"
35030  "Contact: sip:127.0.0.1:5061\r\n"
35031  "Max-Forwards: 70\r\n"
35032  "Content-Type: application/sdp\r\n"
35033  "Content-Length: 130\r\n"
35034  "\r\n",
35035 
35036  "v=0\r\n"
35037  "o=user1 53655765 2353687637 IN IP4 127.0.0.1\r\n"
35038  "s=-\r\n"
35039  "c=IN IP4 127.0.0.1\r\n"
35040  "t=0 0\r\n"
35041  "m=audio 10000 RTP/AVP 0\r\n"
35042  "a=rtpmap:0 PCMU/8000\r\n"
35043  };
35044 
35045  /* Single message in three fragments
35046  * Fragments combine to make "normal"
35047  */
35048  char *multi_fragment[] = {
35049  "INVITE sip:[email protected] SIP/2.0\r\n"
35050  "Via: SIP/2.0/TCP 127.0.0.1:5060;branch=[branch]\r\n"
35051  "From: sipp <sip:127.0.0.1:5061>;tag=12345\r\n"
35052  "To: <sip:[email protected]:5060>\r\n"
35053  "Call-ID: 12345\r\n"
35054  "CSeq: 1 INVITE\r\n",
35055 
35056  "Contact: sip:127.0.0.1:5061\r\n"
35057  "Max-Forwards: 70\r\n"
35058  "Content-Type: application/sdp\r\n"
35059  "Content-Length: 130\r\n"
35060  "\r\n"
35061  "v=0\r\n"
35062  "o=user1 53655765 2353687637 IN IP4 127.0.0.1\r\n"
35063  "s=-\r\n"
35064  "c=IN IP4",
35065 
35066  " 127.0.0.1\r\n"
35067  "t=0 0\r\n"
35068  "m=audio 10000 RTP/AVP 0\r\n"
35069  "a=rtpmap:0 PCMU/8000\r\n"
35070  };
35071 
35072  /* Two messages in a single fragment
35073  * Fragments split into "multi_message_divided"
35074  */
35075  char *multi_message[] = {
35076  "SIP/2.0 100 Trying\r\n"
35077  "Via: SIP/2.0/TCP 127.0.0.1:5060;branch=[branch]\r\n"
35078  "From: sipp <sip:127.0.0.1:5061>;tag=12345\r\n"
35079  "To: <sip:[email protected]:5060>\r\n"
35080  "Call-ID: 12345\r\n"
35081  "CSeq: 1 INVITE\r\n"
35082  "Contact: <sip:[email protected]:5060>\r\n"
35083  "Content-Length: 0\r\n"
35084  "\r\n"
35085  "SIP/2.0 180 Ringing\r\n"
35086  "Via: SIP/2.0/TCP 127.0.0.1:5060;branch=[branch]\r\n"
35087  "From: sipp <sip:127.0.0.1:5061>;tag=12345\r\n"
35088  "To: <sip:[email protected]:5060>\r\n"
35089  "Call-ID: 12345\r\n"
35090  "CSeq: 1 INVITE\r\n"
35091  "Contact: <sip:[email protected]:5060>\r\n"
35092  "Content-Length: 0\r\n"
35093  "\r\n"
35094  };
35095  char *multi_message_divided[] = {
35096  "SIP/2.0 100 Trying\r\n"
35097  "Via: SIP/2.0/TCP 127.0.0.1:5060;branch=[branch]\r\n"
35098  "From: sipp <sip:127.0.0.1:5061>;tag=12345\r\n"
35099  "To: <sip:[email protected]:5060>\r\n"
35100  "Call-ID: 12345\r\n"
35101  "CSeq: 1 INVITE\r\n"
35102  "Contact: <sip:[email protected]:5060>\r\n"
35103  "Content-Length: 0\r\n"
35104  "\r\n",
35105 
35106  "SIP/2.0 180 Ringing\r\n"
35107  "Via: SIP/2.0/TCP 127.0.0.1:5060;branch=[branch]\r\n"
35108  "From: sipp <sip:127.0.0.1:5061>;tag=12345\r\n"
35109  "To: <sip:[email protected]:5060>\r\n"
35110  "Call-ID: 12345\r\n"
35111  "CSeq: 1 INVITE\r\n"
35112  "Contact: <sip:[email protected]:5060>\r\n"
35113  "Content-Length: 0\r\n"
35114  "\r\n"
35115  };
35116  /* Two messages with bodies combined into one fragment
35117  * Fragments split into "multi_message_body_divided"
35118  */
35119  char *multi_message_body[] = {
35120  "INVITE sip:[email protected] SIP/2.0\r\n"
35121  "Via: SIP/2.0/TCP 127.0.0.1:5060;branch=[branch]\r\n"
35122  "From: sipp <sip:127.0.0.1:5061>;tag=12345\r\n"
35123  "To: <sip:[email protected]:5060>\r\n"
35124  "Call-ID: 12345\r\n"
35125  "CSeq: 1 INVITE\r\n"
35126  "Contact: sip:127.0.0.1:5061\r\n"
35127  "Max-Forwards: 70\r\n"
35128  "Content-Type: application/sdp\r\n"
35129  "Content-Length: 130\r\n"
35130  "\r\n"
35131  "v=0\r\n"
35132  "o=user1 53655765 2353687637 IN IP4 127.0.0.1\r\n"
35133  "s=-\r\n"
35134  "c=IN IP4 127.0.0.1\r\n"
35135  "t=0 0\r\n"
35136  "m=audio 10000 RTP/AVP 0\r\n"
35137  "a=rtpmap:0 PCMU/8000\r\n"
35138  "INVITE sip:[email protected] SIP/2.0\r\n"
35139  "Via: SIP/2.0/TCP 127.0.0.1:5060;branch=[branch]\r\n"
35140  "From: sipp <sip:127.0.0.1:5061>;tag=12345\r\n"
35141  "To: <sip:[email protected]:5060>\r\n"
35142  "Call-ID: 12345\r\n"
35143  "CSeq: 2 INVITE\r\n"
35144  "Contact: sip:127.0.0.1:5061\r\n"
35145  "Max-Forwards: 70\r\n"
35146  "Content-Type: application/sdp\r\n"
35147  "Content-Length: 130\r\n"
35148  "\r\n"
35149  "v=0\r\n"
35150  "o=user1 53655765 2353687637 IN IP4 127.0.0.1\r\n"
35151  "s=-\r\n"
35152  "c=IN IP4 127.0.0.1\r\n"
35153  "t=0 0\r\n"
35154  "m=audio 10000 RTP/AVP 0\r\n"
35155  "a=rtpmap:0 PCMU/8000\r\n"
35156  };
35157  char *multi_message_body_divided[] = {
35158  "INVITE sip:[email protected] SIP/2.0\r\n"
35159  "Via: SIP/2.0/TCP 127.0.0.1:5060;branch=[branch]\r\n"
35160  "From: sipp <sip:127.0.0.1:5061>;tag=12345\r\n"
35161  "To: <sip:[email protected]:5060>\r\n"
35162  "Call-ID: 12345\r\n"
35163  "CSeq: 1 INVITE\r\n"
35164  "Contact: sip:127.0.0.1:5061\r\n"
35165  "Max-Forwards: 70\r\n"
35166  "Content-Type: application/sdp\r\n"
35167  "Content-Length: 130\r\n"
35168  "\r\n"
35169  "v=0\r\n"
35170  "o=user1 53655765 2353687637 IN IP4 127.0.0.1\r\n"
35171  "s=-\r\n"
35172  "c=IN IP4 127.0.0.1\r\n"
35173  "t=0 0\r\n"
35174  "m=audio 10000 RTP/AVP 0\r\n"
35175  "a=rtpmap:0 PCMU/8000\r\n",
35176 
35177  "INVITE sip:[email protected] SIP/2.0\r\n"
35178  "Via: SIP/2.0/TCP 127.0.0.1:5060;branch=[branch]\r\n"
35179  "From: sipp <sip:127.0.0.1:5061>;tag=12345\r\n"
35180  "To: <sip:[email protected]:5060>\r\n"
35181  "Call-ID: 12345\r\n"
35182  "CSeq: 2 INVITE\r\n"
35183  "Contact: sip:127.0.0.1:5061\r\n"
35184  "Max-Forwards: 70\r\n"
35185  "Content-Type: application/sdp\r\n"
35186  "Content-Length: 130\r\n"
35187  "\r\n"
35188  "v=0\r\n"
35189  "o=user1 53655765 2353687637 IN IP4 127.0.0.1\r\n"
35190  "s=-\r\n"
35191  "c=IN IP4 127.0.0.1\r\n"
35192  "t=0 0\r\n"
35193  "m=audio 10000 RTP/AVP 0\r\n"
35194  "a=rtpmap:0 PCMU/8000\r\n"
35195  };
35196 
35197  /* Two messages that appear in two fragments. Fragment
35198  * boundaries do not align with message boundaries.
35199  * Fragments combine to make "multi_message_divided"
35200  */
35201  char *multi_message_in_fragments[] = {
35202  "SIP/2.0 100 Trying\r\n"
35203  "Via: SIP/2.0/TCP 127.0.0.1:5060;branch=[branch]\r\n"
35204  "From: sipp <sip:127.0.0.1:5061>;tag=12345\r\n"
35205  "To: <sip:[email protected]:5060>\r\n"
35206  "Call-ID: 12345\r\n"
35207  "CSeq: 1 INVI",
35208 
35209  "TE\r\n"
35210  "Contact: <sip:[email protected]:5060>\r\n"
35211  "Content-Length: 0\r\n"
35212  "\r\n"
35213  "SIP/2.0 180 Ringing\r\n"
35214  "Via: SIP/2.0/TCP 127.0.0.1:5060;branch=[branch]\r\n"
35215  "From: sipp <sip:127.0.0.1:5061>;tag=12345\r\n"
35216  "To: <sip:[email protected]:5060>\r\n"
35217  "Call-ID: 12345\r\n"
35218  "CSeq: 1 INVITE\r\n"
35219  "Contact: <sip:[email protected]:5060>\r\n"
35220  "Content-Length: 0\r\n"
35221  "\r\n"
35222  };
35223 
35224  /* Message with compact content-length header
35225  * Same as "normal" but with compact content-length header
35226  */
35227  char *compact[] = {
35228  "INVITE sip:[email protected] SIP/2.0\r\n"
35229  "Via: SIP/2.0/TCP 127.0.0.1:5060;branch=[branch]\r\n"
35230  "From: sipp <sip:127.0.0.1:5061>;tag=12345\r\n"
35231  "To: <sip:[email protected]:5060>\r\n"
35232  "Call-ID: 12345\r\n"
35233  "CSeq: 1 INVITE\r\n"
35234  "Contact: sip:127.0.0.1:5061\r\n"
35235  "Max-Forwards: 70\r\n"
35236  "Content-Type: application/sdp\r\n"
35237  "l:130\r\n" /* intentionally no space */
35238  "\r\n"
35239  "v=0\r\n"
35240  "o=user1 53655765 2353687637 IN IP4 127.0.0.1\r\n"
35241  "s=-\r\n"
35242  "c=IN IP4 127.0.0.1\r\n"
35243  "t=0 0\r\n"
35244  "m=audio 10000 RTP/AVP 0\r\n"
35245  "a=rtpmap:0 PCMU/8000\r\n"
35246  };
35247 
35248  /* Message with faux content-length headers
35249  * Same as "normal" but with extra fake content-length headers
35250  */
35251  char *faux[] = {
35252  "INVITE sip:[email protected] SIP/2.0\r\n"
35253  "Via: SIP/2.0/TCP 127.0.0.1:5060;branch=[branch]\r\n"
35254  "From: sipp <sip:127.0.0.1:5061>;tag=12345\r\n"
35255  "To: <sip:[email protected]:5060>\r\n"
35256  "Call-ID: 12345\r\n"
35257  "CSeq: 1 INVITE\r\n"
35258  "Contact: sip:127.0.0.1:5061\r\n"
35259  "Max-Forwards: 70\r\n"
35260  "Content-Type: application/sdp\r\n"
35261  "DisContent-Length: 0\r\n"
35262  "MalContent-Length: 60\r\n"
35263  "Content-Length:130\r\n" /* intentionally no space */
35264  "\r\n"
35265  "v=0\r\n"
35266  "o=user1 53655765 2353687637 IN IP4 127.0.0.1\r\n"
35267  "s=-\r\n"
35268  "c=IN IP4 127.0.0.1\r\n"
35269  "t=0 0\r\n"
35270  "m=audio 10000 RTP/AVP 0\r\n"
35271  "a=rtpmap:0 PCMU/8000\r\n"
35272  };
35273 
35274  /* Message with folded Content-Length header
35275  * Message is "normal" with Content-Length spread across three lines
35276  *
35277  * This is the test that requires pedantic=yes in order to pass
35278  */
35279  char *folded[] = {
35280  "INVITE sip:[email protected] SIP/2.0\r\n"
35281  "Via: SIP/2.0/TCP 127.0.0.1:5060;branch=[branch]\r\n"
35282  "From: sipp <sip:127.0.0.1:5061>;tag=12345\r\n"
35283  "To: <sip:[email protected]:5060>\r\n"
35284  "Call-ID: 12345\r\n"
35285  "CSeq: 1 INVITE\r\n"
35286  "Contact: sip:127.0.0.1:5061\r\n"
35287  "Max-Forwards: 70\r\n"
35288  "Content-Type: application/sdp\r\n"
35289  "Content-Length: \t\r\n"
35290  "\t \r\n"
35291  " 130\t \r\n"
35292  "\r\n"
35293  "v=0\r\n"
35294  "o=user1 53655765 2353687637 IN IP4 127.0.0.1\r\n"
35295  "s=-\r\n"
35296  "c=IN IP4 127.0.0.1\r\n"
35297  "t=0 0\r\n"
35298  "m=audio 10000 RTP/AVP 0\r\n"
35299  "a=rtpmap:0 PCMU/8000\r\n"
35300  };
35301 
35302  /* Message with compact Content-length header in message and
35303  * full Content-Length header in the body. Ensure that the header
35304  * in the message is read and that the one in the body is ignored
35305  */
35306  char *cl_in_body[] = {
35307  "INVITE sip:[email protected] SIP/2.0\r\n"
35308  "Via: SIP/2.0/TCP 127.0.0.1:5060;branch=[branch]\r\n"
35309  "From: sipp <sip:127.0.0.1:5061>;tag=12345\r\n"
35310  "To: <sip:[email protected]:5060>\r\n"
35311  "Call-ID: 12345\r\n"
35312  "CSeq: 1 INVITE\r\n"
35313  "Contact: sip:127.0.0.1:5061\r\n"
35314  "Max-Forwards: 70\r\n"
35315  "Content-Type: application/sdp\r\n"
35316  "l: 149\r\n"
35317  "\r\n"
35318  "v=0\r\n"
35319  "Content-Length: 0\r\n"
35320  "o=user1 53655765 2353687637 IN IP4 127.0.0.1\r\n"
35321  "s=-\r\n"
35322  "c=IN IP4 127.0.0.1\r\n"
35323  "t=0 0\r\n"
35324  "m=audio 10000 RTP/AVP 0\r\n"
35325  "a=rtpmap:0 PCMU/8000\r\n"
35326  };
35327 
35328  struct ast_str *overflow;
35329  struct {
35330  char **fragments;
35331  size_t fragment_count;
35332  char **expected;
35333  int num_expected;
35334  const char *description;
35335  } tests[] = {
35336  { normal, ARRAY_LEN(normal), normal, 1, "normal" },
35337  { fragmented, ARRAY_LEN(fragmented), normal, 1, "fragmented" },
35338  { fragmented_body, ARRAY_LEN(fragmented_body), normal, 1, "fragmented_body" },
35339  { multi_fragment, ARRAY_LEN(multi_fragment), normal, 1, "multi_fragment" },
35340  { multi_message, ARRAY_LEN(multi_message), multi_message_divided, 2, "multi_message" },
35341  { multi_message_body, ARRAY_LEN(multi_message_body), multi_message_body_divided, 2, "multi_message_body" },
35342  { multi_message_in_fragments, ARRAY_LEN(multi_message_in_fragments), multi_message_divided, 2, "multi_message_in_fragments" },
35343  { compact, ARRAY_LEN(compact), compact, 1, "compact" },
35344  { faux, ARRAY_LEN(faux), faux, 1, "faux" },
35345  { folded, ARRAY_LEN(folded), folded, 1, "folded" },
35346  { cl_in_body, ARRAY_LEN(cl_in_body), cl_in_body, 1, "cl_in_body" },
35347  };
35348  int i;
35350 
35351  switch (cmd) {
35352  case TEST_INIT:
35353  info->name = "sip_tcp_message_fragmentation";
35354  info->category = "/main/sip/transport/";
35355  info->summary = "SIP TCP message fragmentation test";
35356  info->description =
35357  "Tests reception of different TCP messages that have been fragmented or"
35358  "run together. This test mimicks the code that TCP reception uses.";
35359  return AST_TEST_NOT_RUN;
35360  case TEST_EXECUTE:
35361  break;
35362  }
35364  ast_log(LOG_WARNING, "Not running test. Pedantic SIP checking is not enabled, so it is guaranteed to fail\n");
35365  return AST_TEST_NOT_RUN;
35366  }
35367 
35368  overflow = ast_str_create(128);
35369  if (!overflow) {
35370  return AST_TEST_FAIL;
35371  }
35372  for (i = 0; i < ARRAY_LEN(tests); ++i) {
35373  int num_messages = 0;
35374  if (mock_tcp_loop(tests[i].fragments, tests[i].fragment_count,
35375  &overflow, tests[i].expected, &num_messages, test)) {
35376  ast_test_status_update(test, "Failed to parse message '%s'\n", tests[i].description);
35377  res = AST_TEST_FAIL;
35378  break;
35379  }
35380  if (num_messages != tests[i].num_expected) {
35381  ast_test_status_update(test, "Did not receive the expected number of messages. "
35382  "Expected %d but received %d\n", tests[i].num_expected, num_messages);
35383  res = AST_TEST_FAIL;
35384  break;
35385  }
35386  }
35387  ast_free(overflow);
35388  return res;
35389 }
static int mock_tcp_loop(char *fragments[], size_t num_fragments, struct ast_str **overflow, char **messages, int *num_messages, struct ast_test *test)
Imitation TCP reception loop.
Definition: chan_sip.c:34932
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define LOG_WARNING
Definition: logger.h:274
#define ast_log
Definition: astobj2.c:42
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
int pedanticsipchecking
Definition: sip.h:756
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
def info(msg)
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
#define ast_free(a)
Definition: astmm.h:182
Definition: test.c:104
ast_test_result_state
Definition: test.h:200
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ AST_TEST_DEFINE() [3/3]

AST_TEST_DEFINE ( get_in_brackets_const_test  )

Definition at line 35391 of file chan_sip.c.

References AST_TEST_NOT_RUN, AST_TEST_PASS, CHECK_RESULTS, sip_to_pjsip::info(), input(), len(), NULL, TEST_EXECUTE, and TEST_INIT.

35392 {
35393  const char *input;
35394  const char *start = NULL;
35395  int len = 0;
35396  int res;
35397 
35398 #define CHECK_RESULTS(in, expected_res, expected_start, expected_len) do { \
35399  input = (in); \
35400  res = get_in_brackets_const(input, &start, &len); \
35401  if ((expected_res) != res) { \
35402  ast_test_status_update(test, "Unexpected result: %d != %d\n", expected_res, res); \
35403  return AST_TEST_FAIL; \
35404  } \
35405  if ((expected_start) != start) { \
35406  const char *e = expected_start ? expected_start : "(null)"; \
35407  const char *a = start ? start : "(null)"; \
35408  ast_test_status_update(test, "Unexpected start: %s != %s\n", e, a); \
35409  return AST_TEST_FAIL; \
35410  } \
35411  if ((expected_len) != len) { \
35412  ast_test_status_update(test, "Unexpected len: %d != %d\n", expected_len, len); \
35413  return AST_TEST_FAIL; \
35414  } \
35415  } while(0)
35416 
35417  switch (cmd) {
35418  case TEST_INIT:
35419  info->name = __func__;
35420  info->category = "/channels/chan_sip/";
35421  info->summary = "get_in_brackets_const test";
35422  info->description =
35423  "Tests the get_in_brackets_const function";
35424  return AST_TEST_NOT_RUN;
35425  case TEST_EXECUTE:
35426  break;
35427  }
35428 
35429  CHECK_RESULTS("", 1, NULL, -1);
35430  CHECK_RESULTS("normal <test>", 0, input + 8, 4);
35431  CHECK_RESULTS("\"normal\" <test>", 0, input + 10, 4);
35432  CHECK_RESULTS("not normal <test", -1, NULL, -1);
35433  CHECK_RESULTS("\"yes < really\" <test>", 0, input + 16, 4);
35434  CHECK_RESULTS("\"even > this\" <test>", 0, input + 15, 4);
35435  CHECK_RESULTS("<sip:[email protected];lr>", 0, input + 1, 22);
35436  CHECK_RESULTS("<sip:[email protected];lr>, <sip:[email protected];lr>", 0, input + 1, 22);
35437  CHECK_RESULTS("<sip:id1,[email protected];lr>", 0, input + 1, 26);
35438  CHECK_RESULTS("<sip:id1@10., <sip:[email protected];lr>", 0, input + 1, 36);
35439  CHECK_RESULTS("\"quoted text\" <sip:[email protected];lr>", 0, input + 15, 23);
35440 
35441  return AST_TEST_PASS;
35442 }
#define NULL
Definition: resample.c:96
#define CHECK_RESULTS(in, expected_res, expected_start, expected_len)
static int input(yyscan_t yyscanner)
Definition: ast_expr2f.c:1584
def info(msg)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)

◆ auto_congest()

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

References append_history, ast_channel_trylock, ast_channel_unlock, AST_CONTROL_CONGESTION, ast_queue_control(), DEFAULT_TRANS_TIMEOUT, dialog_unref, sip_pvt::initid, sip_pvt::owner, sip_pvt_lock, sip_pvt_unlock, and sip_scheddestroy().

Referenced by sip_call(), and sip_show_sched().

6421 {
6422  struct sip_pvt *p = (struct sip_pvt *)arg;
6423 
6424  sip_pvt_lock(p);
6425  p->initid = -1; /* event gone, will not be rescheduled */
6426  if (p->owner) {
6427  /* XXX fails on possible deadlock */
6428  if (!ast_channel_trylock(p->owner)) {
6429  append_history(p, "Cong", "Auto-congesting (timer)");
6432  }
6433 
6434  /* Give the channel a chance to act before we proceed with destruction */
6436  }
6437  sip_pvt_unlock(p);
6438  dialog_unref(p, "unreffing arg passed into auto_congest callback (p->initid)");
6439  return 0;
6440 }
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
Definition: channel.c:1231
int initid
Definition: sip.h:1155
#define DEFAULT_TRANS_TIMEOUT
Definition: sip.h:107
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_channel * owner
Definition: sip.h:1138
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406
#define ast_channel_trylock(chan)
Definition: channel.h:2947
void sip_scheddestroy(struct sip_pvt *p, int ms)
Schedule destruction of SIP dialog.
Definition: chan_sip.c:4549

◆ autocreatepeer2str()

static const char* autocreatepeer2str ( enum autocreatepeer_mode  r)
static

Definition at line 20038 of file chan_sip.c.

References map_x_s().

Referenced by sip_show_settings().

20039 {
20040  return map_x_s(autopeermodes, r, "Unknown");
20041 }
static struct _map_x_s autopeermodes[]
Definition: chan_sip.c:20026
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
Definition: chan_sip.c:2411

◆ blind_transfer_cb()

static void blind_transfer_cb ( struct ast_channel chan,
struct transfer_channel_data user_data_wrapper,
enum ast_transfer_type  transfer_type 
)
static

Definition at line 27249 of file chan_sip.c.

References ast_channel_update_redirecting(), transfer_channel_data::data, blind_transfer_cb_data::domain, pbx_builtin_setvar_helper(), blind_transfer_cb_data::redirecting, blind_transfer_cb_data::referred_by, blind_transfer_cb_data::replaces, and blind_transfer_cb_data::update_redirecting.

Referenced by handle_request_refer().

27251 {
27252  struct blind_transfer_cb_data *cb_data = user_data_wrapper->data;
27253 
27254  pbx_builtin_setvar_helper(chan, "SIPTRANSFER", "yes");
27255  pbx_builtin_setvar_helper(chan, "SIPTRANSFER_REFERER", cb_data->referred_by);
27256  pbx_builtin_setvar_helper(chan, "SIPTRANSFER_REPLACES", cb_data->replaces);
27257  pbx_builtin_setvar_helper(chan, "SIPDOMAIN", cb_data->domain);
27259 }
const char * domain
Definition: chan_sip.c:27228
struct ast_set_party_redirecting update_redirecting
Definition: chan_sip.c:27234
void ast_channel_update_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
Indicate that the redirecting id has changed.
Definition: channel.c:10379
const char * referred_by
Definition: chan_sip.c:27226
const char * replaces
Definition: chan_sip.c:27230
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
struct ast_party_redirecting redirecting
Definition: chan_sip.c:27232

◆ block_msg_header()

static int block_msg_header ( const char *  header_name)
static

Definition at line 27849 of file chan_sip.c.

References ARRAY_LEN.

Referenced by sip_msg_send().

27850 {
27851  int idx;
27852 
27853  /*
27854  * Don't block Content-Type or Max-Forwards headers because the
27855  * user can override them.
27856  */
27857  static const char *hdr[] = {
27858  "To",
27859  "From",
27860  "Via",
27861  "Route",
27862  "Contact",
27863  "Call-ID",
27864  "CSeq",
27865  "Allow",
27866  "Content-Length",
27867  "Request-URI",
27868  };
27869 
27870  for (idx = 0; idx < ARRAY_LEN(hdr); ++idx) {
27871  if (!strcasecmp(header_name, hdr[idx])) {
27872  /* Block addition of this header. */
27873  return 1;
27874  }
27875  }
27876  return 0;
27877 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42

◆ build_callid_pvt()

static void build_callid_pvt ( struct sip_pvt pvt)
static

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

Note
The passed in pvt must not be in a dialogs container since this function changes the hash key used by the container.

Definition at line 8829 of file chan_sip.c.

References ast_sockaddr_stringify_remote(), ast_string_field_build, buf, sip_pvt::fromdomain, generate_random_string(), host, sip_pvt::ourip, and S_OR.

Referenced by __sip_alloc(), and change_callid_pvt().

8830 {
8831  char buf[33];
8832  const char *host = S_OR(pvt->fromdomain, ast_sockaddr_stringify_remote(&pvt->ourip));
8833 
8834  ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
8835 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
struct ast_sockaddr ourip
Definition: sip.h:1136
static char * ast_sockaddr_stringify_remote(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:277
static char host[256]
Definition: muted.c:77
static char * generate_random_string(char *buf, size_t size)
Generate 32 byte random string for callid&#39;s etc.
Definition: chan_sip.c:8797
const ast_string_field fromdomain
Definition: sip.h:1063
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
Definition: stringfields.h:550
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79

◆ build_callid_registry()

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

References ast_sockaddr_stringify_host_remote(), ast_string_field_build, buf, generate_random_string(), host, and S_OR.

Referenced by transmit_register().

8893 {
8894  char buf[33];
8895 
8896  const char *host = S_OR(fromdomain, ast_sockaddr_stringify_host_remote(ourip));
8897 
8898  ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
8899 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static char host[256]
Definition: muted.c:77
static char * generate_random_string(char *buf, size_t size)
Generate 32 byte random string for callid&#39;s etc.
Definition: chan_sip.c:8797
static char * ast_sockaddr_stringify_host_remote(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only, suitable for a URL (with brack...
Definition: netsock2.h:349
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
Definition: stringfields.h:550
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79

◆ build_contact()

static void build_contact ( struct sip_pvt p,
struct sip_request req,
int  incoming 
)
static

Build contact header.

This is the Contact header that we send out in SIP requests and responses involving this sip_pvt.

The incoming parameter is used to tell if we are building the request parameter is an incoming SIP request that we are building the Contact header in response to, or if the req parameter is an outbound SIP request that we will later be adding the Contact header to.

Parameters
pThe sip_pvt where the built Contact will be saved.
reqThe request that triggered the creation of a Contact header.
incomingIndicates if the Contact header is being created for a response to an incoming request

Definition at line 14385 of file chan_sip.c.

References ast_sockaddr_stringify_remote(), ast_str_to_lower(), ast_strdupa, ast_string_field_build, ast_strlen_zero, AST_TRANSPORT_UDP, ast_uri_encode(), ast_uri_sip_user, sip_pvt::exten, sip_pvt::ourip, sip_get_transport(), SIPBUFSIZE, sip_pvt::socket, tmp(), sip_socket::type, uac_sips_contact(), and uas_sips_contact().

Referenced by check_user_full(), handle_request_invite(), handle_request_options(), handle_request_subscribe(), initreqprep(), register_verify(), and transmit_register().

14386 {
14387  char tmp[SIPBUFSIZE];
14388  char *user = ast_uri_encode(p->exten, tmp, sizeof(tmp), ast_uri_sip_user);
14389  int use_sips;
14390  char *transport = ast_strdupa(sip_get_transport(p->socket.type));
14391 
14392  if (incoming) {
14393  use_sips = uas_sips_contact(req);
14394  } else {
14395  use_sips = uac_sips_contact(req);
14396  }
14397 
14398  if (p->socket.type == AST_TRANSPORT_UDP) {
14399  ast_string_field_build(p, our_contact, "<%s:%s%s%s>", use_sips ? "sips" : "sip",
14400  user, ast_strlen_zero(user) ? "" : "@",
14402  } else {
14403  ast_string_field_build(p, our_contact, "<%s:%s%s%s;transport=%s>",
14404  use_sips ? "sips" : "sip", user, ast_strlen_zero(user) ? "" : "@",
14406  }
14407 }
static int uas_sips_contact(struct sip_request *req)
Determine if, as a UAS, we need to use a SIPS Contact.
Definition: chan_sip.c:14314
struct sip_socket socket
Definition: sip.h:1066
static int tmp()
Definition: bt_open.c:389
char * ast_uri_encode(const char *string, char *outbuf, int buflen, struct ast_flags spec)
Turn text string to URI-encoded XX version.
Definition: main/utils.c:577
const char * sip_get_transport(enum ast_transport t)
Return transport as string.
Definition: chan_sip.c:3725
struct ast_sockaddr ourip
Definition: sip.h:1136
static char * ast_sockaddr_stringify_remote(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:277
#define ast_strlen_zero(foo)
Definition: strings.h:52
const ast_string_field exten
Definition: sip.h:1063
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static force_inline char * ast_str_to_lower(char *str)
Convert a string to all lower-case.
Definition: strings.h:1268
#define SIPBUFSIZE
Definition: sip.h:56
structure to hold users read from users.conf
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
Definition: stringfields.h:550
static int uac_sips_contact(struct sip_request *req)
Determine if, as a UAC, we need to use a SIPS Contact.
Definition: chan_sip.c:14351
enum ast_transport type
Definition: sip.h:798
const struct ast_flags ast_uri_sip_user
Definition: main/utils.c:575

◆ build_localtag_registry()

static void build_localtag_registry ( struct sip_registry reg)
static

Build SIP From tag value for REGISTER.

Definition at line 8902 of file chan_sip.c.

References ast_random(), and ast_string_field_build.

Referenced by transmit_register().

8903 {
8904  ast_string_field_build(reg, localtag, "as%08lx", (unsigned long)ast_random());
8905 }
long int ast_random(void)
Definition: main/utils.c:2064
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
Definition: stringfields.h:550

◆ build_nonce()

static void build_nonce ( struct sip_pvt p,
int  forceupdate 
)
static

builds the sip_pvt's nonce field which is used for the authentication 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 17300 of file chan_sip.c.

References ast_random(), ast_string_field_build, ast_strlen_zero, sip_pvt::nonce, and sip_pvt::stalenonce.

Referenced by check_auth(), and transmit_fake_auth_response().

17301 {
17302  if (p->stalenonce || forceupdate || ast_strlen_zero(p->nonce)) {
17303  ast_string_field_build(p, nonce, "%08lx", (unsigned long)ast_random()); /* Create nonce for challenge */
17304  p->stalenonce = 0;
17305  }
17306 }
const ast_string_field nonce
Definition: sip.h:1063
#define ast_strlen_zero(foo)
Definition: strings.h:52
unsigned int stalenonce
Definition: sip.h:1143
long int ast_random(void)
Definition: main/utils.c:2064
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
Definition: stringfields.h:550

◆ build_path()

static int build_path ( struct sip_pvt p,
struct sip_peer peer,
struct sip_request req,
const char *  pathbuf 
)
static

Build route list from Path header RFC 3327 requires that the Path header contains SIP URIs with lr paramter. Thus, we do not care about strict routing SIP routers.

Definition at line 17260 of file chan_sip.c.

References __get_header(), ast_debug, ast_test_flag, sip_peer::flags, sip_peer::path, sip_debug_test_pvt(), sip_route_clear(), sip_route_dump(), sip_route_is_strict(), sip_route_process_header(), and SIP_USEPATH.

Referenced by parse_register_contact(), and reg_source_db().

17261 {
17262  sip_route_clear(&peer->path);
17263 
17264  if (!ast_test_flag(&peer->flags[0], SIP_USEPATH)) {
17265  ast_debug(2, "build_path: do not use Path headers\n");
17266  return -1;
17267  }
17268  ast_debug(2, "build_path: try to build pre-loaded route-set by parsing Path headers\n");
17269 
17270  if (req) {
17271  int start = 0;
17272  const char *header;
17273  for (;;) {
17274  header = __get_header(req, "Path", &start);
17275  if (*header == '\0') {
17276  break;
17277  }
17278  sip_route_process_header(&peer->path, header, 0);
17279  }
17280  } else if (pathbuf) {
17281  sip_route_process_header(&peer->path, pathbuf, 0);
17282  }
17283 
17284  /* Caches result for any dialog->route copied from peer->path */
17285  sip_route_is_strict(&peer->path);
17286 
17287  /* For debugging dump what we ended up with */
17288  if (p && sip_debug_test_pvt(p)) {
17289  sip_route_dump(&peer->path);
17290  }
17291  return 0;
17292 }
void sip_route_process_header(struct sip_route *route, const char *header, int inserthead)
Add routes from header.
Definition: route.c:79
#define SIP_USEPATH
Definition: sip.h:305
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct sip_route path
Definition: sip.h:1372
void sip_route_clear(struct sip_route *route)
Free all routes in the list.
Definition: route.c:132
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static const char * __get_header(const struct sip_request *req, const char *name, int *start)
Definition: chan_sip.c:8562
static int sip_debug_test_pvt(struct sip_pvt *p)
Test PVT for debugging output.
Definition: chan_sip.c:3649
int sip_route_is_strict(struct sip_route *route)
Check if the route is strict.
Definition: route.c:183
struct ast_flags flags[3]
Definition: sip.h:1335
void sip_route_dump(const struct sip_route *route)
Verbose dump of all hops for debugging.
Definition: route.c:143

◆ build_peer()

static struct sip_peer * build_peer ( const char *  name,
struct ast_variable v,
struct ast_variable alt,
int  realtime,
int  devstate_only 
)
static

Build peer from configuration (file or realtime static/dynamic)

< The first transport listed should be default outbound

Definition at line 31631 of file chan_sip.c.

References __set_address_from_contact(), accountcode, sip_peer::acl, acl_change_stasis_subscribe(), add_peer_mailboxes(), add_peer_mwi_subs(), add_realm_authentication(), add_var(), sip_peer::addr, sip_settings::allowsubscribe, sip_peer::allowtransfer, sip_peer::amaflags, ao2_lock, ao2_t_alloc, ao2_t_find, ao2_t_ref, ao2_t_unlink, ao2_unlock, AST_AES_CM_128_HMAC_SHA1_32, AST_AES_CM_128_HMAC_SHA1_80, AST_AF_UNSPEC, ast_append_acl(), 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_channel_string2amaflag(), ast_copy_flags, ast_copy_string(), ast_debug, ast_dnsmgr_lookup_cb(), ast_dnsmgr_refresh(), ast_endpoint_create(), ast_format_cap_alloc, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_remove_by_type(), ast_format_cap_update_by_allow_disallow(), ast_free, ast_free_acl_list(), ast_get_cc_agent_policy(), ast_get_group(), ast_get_indication_zone(), ast_get_ip(), ast_get_namedgroups(), 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_MAX_MAILBOX_UNIQUEID, AST_MEDIA_TYPE_UNKNOWN, ast_parse_caller_presentation(), ast_rtp_dtls_cfg_copy(), ast_rtp_dtls_cfg_free(), ast_rtp_dtls_cfg_parse(), ast_rtp_dtls_cfg_validate(), AST_SCHED_DEL_UNREF, AST_SCHED_REPLACE_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_tone_zone_unref(), AST_TRANSPORT_TCP, AST_TRANSPORT_TLS, AST_TRANSPORT_UDP, AST_TRANSPORT_WS, AST_TRANSPORT_WSS, ast_true(), ast_unref_namedgroups(), ast_variables_destroy(), sip_peer::auth, sip_peer::autoframing, sip_peer::busy_level, sip_peer::call_limit, sip_peer::callback, sip_peer::callgroup, sip_peer::callingpres, can_parse_xml, sip_peer::caps, sip_peer::cc_params, sip_peer::chanvars, cid_name, cid_num, config, sip_settings::contact_acl, sip_peer::contactacl, context, sip_peer::defaddr, DEFAULT_KEEPALIVE_INTERVAL, sip_settings::default_max_forwards, default_maxcallbitrate, DEFAULT_MAXMS, DEFAULT_MIN_SE, sip_peer::default_outbound_transport, default_primary_transport, default_qualify, default_transports, sip_peer::deprecated_username, destroy_association(), destroy_mailbox(), sip_peer::directmediaacl, sip_peer::disallowed_methods, sip_peer::dnsmgr, sip_peer::dtls_cfg, ast_tls_config::enabled, ast_rtp_dtls_cfg::enabled, sip_peer::endpoint, error(), sip_peer::expire, FALSE, ast_flags::flags, sip_peer::flags, format, sip_peer::fromdomain, sip_peer::fromdomainport, sip_peer::fromuser, get_address_family_filter(), get_srv_protocol(), get_srv_service(), global_dynamic_exclude_static, global_max_se, global_min_se, global_qualifyfreq, global_rtpholdtimeout, global_rtpkeepalive, global_rtptimeout, global_st_mode, global_st_refresher, global_t1min, global_timer_b, handle_common_options(), handle_t38_options(), sip_peer::host_dynamic, sip_settings::ignore_regexpire, sip_peer::is_realtime, sip_peer::keepalive, sip_peer::keepalivesend, language, sip_peer::lastms, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, mailbox, sip_peer::mailboxes, mark_parsed_methods(), sip_peer::maxcallbitrate, sip_peer::maxforwards, MAXHOSTNAMELEN, sip_peer::maxms, mohinterpret, mohsuggest, ast_variable::name, sip_peer::name, sip_peer::named_callgroups, sip_peer::named_pickupgroups, ast_variable::next, NULL, OBJ_POINTER, OBJ_UNLINK, on_dns_update_peer(), sip_peer::outboundproxy, parkinglot, PARSE_PORT_FORBID, sip_settings::peer_rtupdate, sip_peer::pickupgroup, sip_peer::pokeexpire, port_str2int(), sip_peer::portinuri, proxy_from_config(), sip_peer::qualifyfreq, reg_source_db(), sip_peer::remotesecret, rpeerobjs, sip_peer::rt_fromcontact, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_peer::rtptimeout, S_OR, sip_peer::secret, set_peer_defaults(), set_socket_transport(), sip_cfg, sip_destroy_peer_fn(), SIP_MAILBOX_STATUS_UNKNOWN, SIP_NAT_FORCE_RPORT, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_HAVEPEERCONTEXT, SIP_PAGE2_PREFERRED_CODEC, SIP_PAGE2_Q850_REASON, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_SUBSCRIBEMWIONLY, SIP_PAGE2_USE_SRTP, SIP_PAGE3_DISCARD_REMOTE_HOLD_RETRIEVAL, SIP_PAGE3_FORCE_AVP, SIP_PAGE3_ICE_SUPPORT, SIP_PAGE3_IGNORE_PREFCAPS, SIP_PAGE3_NAT_AUTO_RPORT, SIP_PAGE3_SNOM_AOC, SIP_PAGE3_SRTP_TAG_32, SIP_PAGE3_USE_AVPF, sip_poke_peer_now(), sip_ref_peer, sip_register(), sip_send_mwi_to_peer(), SIP_TYPE_PEER, SIP_TYPE_USER, sip_unref_peer, SIP_USEREQPHONE, sip_peer::socket, speerobjs, srvlookup, sip_settings::srvlookup, ast_sockaddr::ss, sip_st_cfg::st_max_se, sip_st_cfg::st_min_se, sip_st_cfg::st_mode_oper, sip_st_cfg::st_ref, STANDARD_SIP_PORT, STANDARD_TLS_PORT, sip_mailbox::status, sip_peer::stimer, str2stmode(), str2strefresherparam(), strsep(), ast_rtp_dtls_cfg::suite, sip_peer::t38_maxdatagram, sip_settings::tcp_enabled, sip_peer::the_mark, sip_peer::timer_b, sip_peer::timer_t1, tmp(), sip_peer::tohost, TRANSFER_CLOSED, TRANSFER_OPENFORALL, sip_peer::transports, TRUE, sip_socket::type, sip_peer::type, sip_peer::username, ast_variable::value, and vmexten.

Referenced by realtime_peer(), register_realtime_peers_with_callbackextens(), and reload_config().

31632 {
31633  /* We preserve the original value of v_head to make analyzing backtraces easier */
31634  struct ast_variable *v = v_head;
31635  struct sip_peer *peer = NULL;
31636  struct ast_acl_list *oldacl = NULL;
31637  struct ast_acl_list *oldcontactacl = NULL;
31638  struct ast_acl_list *olddirectmediaacl = NULL;
31639  int found = 0;
31640  int firstpass = 1;
31641  uint16_t port = 0;
31642  int format = 0; /* Ama flags */
31643  int timerb_set = 0, timert1_set = 0;
31644  time_t regseconds = 0;
31645  struct ast_flags peerflags[3] = {{(0)}};
31646  struct ast_flags mask[3] = {{(0)}};
31647  struct sip_peer tmp_peer;
31648  const char *srvlookup = NULL;
31649  static int deprecation_warning = 1;
31650  int alt_fullcontact = alt ? 1 : 0, headercount = 0;
31651  struct ast_str *fullcontact = ast_str_alloca(512);
31652  int acl_change_subscription_needed = 0;
31653 
31654  if (!realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
31655  /* Note we do NOT use sip_find_peer here, to avoid realtime recursion */
31656  /* We also use a case-sensitive comparison (unlike sip_find_peer) so
31657  that case changes made to the peer name will be properly handled
31658  during reload
31659  */
31660  ast_copy_string(tmp_peer.name, name, sizeof(tmp_peer.name));
31661  peer = ao2_t_find(peers, &tmp_peer, OBJ_POINTER | OBJ_UNLINK, "find and unlink peer from peers table");
31662  }
31663 
31664  if (peer) {
31665  /* Already in the list, remove it and it will be added back (or FREE'd) */
31666  found++;
31667  /* we've unlinked the peer from the peers container but not unlinked from the peers_by_ip container yet
31668  this leads to a wrong refcounter and the peer object is never destroyed */
31669  if (!ast_sockaddr_isnull(&peer->addr)) {
31670  ao2_t_unlink(peers_by_ip, peer, "ao2_unlink peer from peers_by_ip table");
31671  }
31672  if (!(peer->the_mark)) {
31673  firstpass = 0;
31674  } else {
31676  }
31677  } else {
31678  if (!(peer = ao2_t_alloc(sizeof(*peer), sip_destroy_peer_fn, "allocate a peer struct"))) {
31679  return NULL;
31680  }
31681  if (!(peer->endpoint = ast_endpoint_create("SIP", name))) {
31682  ao2_t_ref(peer, -1, "failed to allocate endpoint, drop peer");
31683  return NULL;
31684  }
31686  ao2_t_ref(peer, -1, "failed to allocate format capabilities, drop peer");
31687  return NULL;
31688  }
31689  if (ast_string_field_init(peer, 512)) {
31690  ao2_t_ref(peer, -1, "failed to string_field_init, drop peer");
31691  return NULL;
31692  }
31693 
31694  if (!(peer->cc_params = ast_cc_config_params_init())) {
31695  ao2_t_ref(peer, -1, "failed to allocate cc_params for peer");
31696  return NULL;
31697  }
31698 
31699 
31700  if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
31702  ast_debug(3, "-REALTIME- peer built. Name: %s. Peer objects: %d\n", name, rpeerobjs);
31703  } else
31705 
31706  peer->expire = -1;
31707  peer->pokeexpire = -1;
31708  peer->keepalivesend = -1;
31709  }
31710 
31711  /* Note that our peer HAS had its reference count increased */
31712  if (firstpass) {
31713  oldacl = peer->acl;
31714  peer->acl = NULL;
31715  oldcontactacl = peer->contactacl;
31716  peer->contactacl = NULL;
31717  olddirectmediaacl = peer->directmediaacl;
31718  peer->directmediaacl = NULL;
31719  set_peer_defaults(peer); /* Set peer defaults */
31720  peer->type = 0;
31721  }
31722 
31723  /* in case the case of the peer name has changed, update the name */
31724  ast_copy_string(peer->name, name, sizeof(peer->name));
31725 
31726  /* If we have channel variables, remove them (reload) */
31727  if (peer->chanvars) {
31729  peer->chanvars = NULL;
31730  /* XXX should unregister ? */
31731  }
31732 
31733  if (found)
31734  peer->portinuri = 0;
31735 
31736  /* If we have realm authentication information, remove them (reload) */
31737  ao2_lock(peer);
31738  if (peer->auth) {
31739  ao2_t_ref(peer->auth, -1, "Removing old peer authentication");
31740  peer->auth = NULL;
31741  }
31742  ao2_unlock(peer);
31743 
31744  /* clear the transport information. We will detect if a default value is required after parsing the config */
31745  peer->default_outbound_transport = 0;
31746  peer->transports = 0;
31747 
31748  if (!devstate_only) {
31749  struct sip_mailbox *mailbox;
31750  AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
31752  }
31753  }
31754 
31755  /* clear named callgroup and named pickup group container */
31758 
31759  /* Set the default DTLS settings from default_tls_cfg */
31762  peer->dtls_cfg.enabled = FALSE;
31763 
31764  for (; v || ((v = alt) && !(alt=NULL)); v = v->next) {
31765  if (!devstate_only) {
31766  if (handle_common_options(&peerflags[0], &mask[0], v)) {
31767  continue;
31768  }
31769  if (handle_t38_options(&peerflags[0], &mask[0], v, &peer->t38_maxdatagram)) {
31770  continue;
31771  }
31772  if (!strcasecmp(v->name, "transport")) {
31773  char *val = ast_strdupa(v->value);
31774  char *trans;
31775 
31776  peer->transports = peer->default_outbound_transport = 0;
31777  while ((trans = strsep(&val, ","))) {
31778  trans = ast_skip_blanks(trans);
31779 
31780  if (!strncasecmp(trans, "udp", 3)) {
31781  peer->transports |= AST_TRANSPORT_UDP;
31782  } else if (!strncasecmp(trans, "wss", 3)) {
31783  peer->transports |= AST_TRANSPORT_WSS;
31784  } else if (!strncasecmp(trans, "ws", 2)) {
31785  peer->transports |= AST_TRANSPORT_WS;
31786  } else if (sip_cfg.tcp_enabled && !strncasecmp(trans, "tcp", 3)) {
31787  peer->transports |= AST_TRANSPORT_TCP;
31788  } else if (default_tls_cfg.enabled && !strncasecmp(trans, "tls", 3)) {
31789  peer->transports |= AST_TRANSPORT_TLS;
31790  } else if (!strncasecmp(trans, "tcp", 3) || !strncasecmp(trans, "tls", 3)) {
31791  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);
31792  } else {
31793  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);
31794  }
31795 
31796  if (!peer->default_outbound_transport) { /*!< The first transport listed should be default outbound */
31797  peer->default_outbound_transport = peer->transports;
31798  }
31799  }
31800  } else if (realtime && !strcasecmp(v->name, "regseconds")) {
31801  ast_get_time_t(v->value, &regseconds, 0, NULL);
31802  } else if (realtime && !strcasecmp(v->name, "name")) {
31803  ast_copy_string(peer->name, v->value, sizeof(peer->name));
31804  } else if (realtime && !strcasecmp(v->name, "useragent")) {
31805  ast_string_field_set(peer, useragent, v->value);
31806  } else if (!strcasecmp(v->name, "type")) {
31807  if (!strcasecmp(v->value, "peer")) {
31808  peer->type |= SIP_TYPE_PEER;
31809  } else if (!strcasecmp(v->value, "user")) {
31810  peer->type |= SIP_TYPE_USER;
31811  } else if (!strcasecmp(v->value, "friend")) {
31812  peer->type = SIP_TYPE_USER | SIP_TYPE_PEER;
31813  }
31814  } else if (!strcasecmp(v->name, "remotesecret")) {
31815  ast_string_field_set(peer, remotesecret, v->value);
31816  } else if (!strcasecmp(v->name, "secret")) {
31817  ast_string_field_set(peer, secret, v->value);
31818  } else if (!strcasecmp(v->name, "description")) {
31819  ast_string_field_set(peer, description, v->value);
31820  } else if (!strcasecmp(v->name, "md5secret")) {
31821  ast_string_field_set(peer, md5secret, v->value);
31822  } else if (!strcasecmp(v->name, "auth")) {
31823  add_realm_authentication(&peer->auth, v->value, v->lineno);
31824  } else if (!strcasecmp(v->name, "callerid")) {
31825  char cid_name[80] = { '\0' }, cid_num[80] = { '\0' };
31826 
31827  ast_callerid_split(v->value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num));
31828  ast_string_field_set(peer, cid_name, cid_name);
31830  } else if (!strcasecmp(v->name, "mwi_from")) {
31831  ast_string_field_set(peer, mwi_from, v->value);
31832  } else if (!strcasecmp(v->name, "fullname")) {
31833  ast_string_field_set(peer, cid_name, v->value);
31834  } else if (!strcasecmp(v->name, "trunkname")) {
31835  /* This is actually for a trunk, so we don't want to override callerid */
31836  ast_string_field_set(peer, cid_name, "");
31837  } else if (!strcasecmp(v->name, "cid_number")) {
31838  ast_string_field_set(peer, cid_num, v->value);
31839  } else if (!strcasecmp(v->name, "cid_tag")) {
31840  ast_string_field_set(peer, cid_tag, v->value);
31841  } else if (!strcasecmp(v->name, "context")) {
31842  ast_string_field_set(peer, context, v->value);
31844  } else if (!strcasecmp(v->name, "recordonfeature")) {
31845  ast_string_field_set(peer, record_on_feature, v->value);
31846  } else if (!strcasecmp(v->name, "recordofffeature")) {
31847  ast_string_field_set(peer, record_off_feature, v->value);
31848  } else if (!strcasecmp(v->name, "outofcall_message_context")) {
31849  ast_string_field_set(peer, messagecontext, v->value);
31850  } else if (!strcasecmp(v->name, "subscribecontext")) {
31851  ast_string_field_set(peer, subscribecontext, v->value);
31852  } else if (!strcasecmp(v->name, "fromdomain")) {
31853  char *fromdomainport;
31854  ast_string_field_set(peer, fromdomain, v->value);
31855  if ((fromdomainport = strchr(peer->fromdomain, ':'))) {
31856  *fromdomainport++ = '\0';
31857  if (!(peer->fromdomainport = port_str2int(fromdomainport, 0))) {
31858  ast_log(LOG_NOTICE, "'%s' is not a valid port number for fromdomain.\n",fromdomainport);
31859  }
31860  } else {
31862  }
31863  } else if (!strcasecmp(v->name, "usereqphone")) {
31865  } else if (!strcasecmp(v->name, "fromuser")) {
31866  ast_string_field_set(peer, fromuser, v->value);
31867  } else if (!strcasecmp(v->name, "outboundproxy")) {
31868  struct sip_proxy *proxy;
31869  if (ast_strlen_zero(v->value)) {
31870  ast_log(LOG_WARNING, "no value given for outbound proxy on line %d of sip.conf\n", v->lineno);
31871  continue;
31872  }
31873  proxy = proxy_from_config(v->value, v->lineno, peer->outboundproxy);
31874  if (!proxy) {
31875  ast_log(LOG_WARNING, "failure parsing the outbound proxy on line %d of sip.conf.\n", v->lineno);
31876  continue;
31877  }
31878  peer->outboundproxy = proxy;
31879  } else if (!strcasecmp(v->name, "host")) {
31880  if (!strcasecmp(v->value, "dynamic")) {
31881  /* They'll register with us */
31882  if ((!found && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) || !peer->host_dynamic) {
31883  /* Initialize stuff if this is a new peer, or if it used to
31884  * not be dynamic before the reload. */
31885  ast_string_field_set(peer, tohost, NULL);
31886  ast_sockaddr_setnull(&peer->addr);
31887  }
31888  peer->host_dynamic = TRUE;
31889  } else {
31890  /* Non-dynamic. Make sure we become that way if we're not */
31892  sip_unref_peer(peer, "removing register expire ref"));
31893  peer->host_dynamic = FALSE;
31894  srvlookup = v->value;
31895  }
31896  } else if (!strcasecmp(v->name, "defaultip")) {
31897  peer->defaddr.ss.ss_family = AST_AF_UNSPEC;
31898  if (!ast_strlen_zero(v->value) && ast_get_ip(&peer->defaddr, v->value)) {
31899  sip_unref_peer(peer, "sip_unref_peer: from build_peer defaultip");
31900  return NULL;
31901  }
31902  } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny") || !strcasecmp(v->name, "acl")) {
31903  int ha_error = 0;
31904  if (!ast_strlen_zero(v->value)) {
31905  ast_append_acl(v->name, v->value, &peer->acl, &ha_error, &acl_change_subscription_needed);
31906  }
31907  if (ha_error) {
31908  ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s. Deleting peer\n", v->lineno, v->value);
31909  sip_unref_peer(peer, "Removing peer due to bad ACL configuration");
31910  return NULL;
31911  }
31912  } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny") || !strcasecmp(v->name, "contactacl")) {
31913  int ha_error = 0;
31914  if (!ast_strlen_zero(v->value)) {
31915  ast_append_acl(v->name + 7, v->value, &peer->contactacl, &ha_error, &acl_change_subscription_needed);
31916  }
31917  if (ha_error) {
31918  ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s. Deleting peer\n", v->lineno, v->value);
31919  sip_unref_peer(peer, "Removing peer due to bad contact ACL configuration");
31920  return NULL;
31921  }
31922  } else if (!strcasecmp(v->name, "directmediapermit") || !strcasecmp(v->name, "directmediadeny") || !strcasecmp(v->name, "directmediaacl")) {
31923  int ha_error = 0;
31924  ast_append_acl(v->name + 11, v->value, &peer->directmediaacl, &ha_error, &acl_change_subscription_needed);
31925  if (ha_error) {
31926  ast_log(LOG_ERROR, "Bad directmedia ACL entry in configuration line %d : %s. Deleting peer\n", v->lineno, v->value);
31927  sip_unref_peer(peer, "Removing peer due to bad direct media ACL configuration");
31928  return NULL;
31929  }
31930  } else if (!strcasecmp(v->name, "port")) {
31931  peer->portinuri = 1;
31932  if (!(port = port_str2int(v->value, 0))) {
31933  if (realtime) {
31934  /* If stored as integer, could be 0 for some DBs (notably MySQL) */
31935  peer->portinuri = 0;
31936  } else {
31937  ast_log(LOG_WARNING, "Invalid peer port configuration at line %d : %s\n", v->lineno, v->value);
31938  }
31939  }
31940  } else if (!strcasecmp(v->name, "callingpres")) {
31942  if (peer->callingpres == -1) {
31943  peer->callingpres = atoi(v->value);
31944  }
31945  } else if (!strcasecmp(v->name, "username") || !strcasecmp(v->name, "defaultuser")) { /* "username" is deprecated */
31946  ast_string_field_set(peer, username, v->value);
31947  if (!strcasecmp(v->name, "username")) {
31948  if (deprecation_warning) {
31949  ast_log(LOG_NOTICE, "The 'username' field for sip peers has been deprecated in favor of the term 'defaultuser'\n");
31950  deprecation_warning = 0;
31951  }
31952  peer->deprecated_username = 1;
31953  }
31954  } else if (!strcasecmp(v->name, "tonezone")) {
31955  struct ast_tone_zone *new_zone;
31956  if (!(new_zone = ast_get_indication_zone(v->value))) {
31957  ast_log(LOG_ERROR, "Unknown country code '%s' for tonezone in device [%s] at line %d. Check indications.conf for available country codes.\n", v->value, peer->name, v->lineno);
31958  } else {
31959  ast_tone_zone_unref(new_zone);
31960  ast_string_field_set(peer, zone, v->value);
31961  }
31962  } else if (!strcasecmp(v->name, "language")) {
31963  ast_string_field_set(peer, language, v->value);
31964  } else if (!strcasecmp(v->name, "regexten")) {
31965  ast_string_field_set(peer, regexten, v->value);
31966  } else if (!strcasecmp(v->name, "callbackextension")) {
31967  ast_string_field_set(peer, callback, v->value);
31968  } else if (!strcasecmp(v->name, "amaflags")) {
31969  format = ast_channel_string2amaflag(v->value);
31970  if (format < 0) {
31971  ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno);
31972  } else {
31973  peer->amaflags = format;
31974  }
31975  } else if (!strcasecmp(v->name, "maxforwards")) {
31976  if (sscanf(v->value, "%30d", &peer->maxforwards) != 1
31977  || peer->maxforwards < 1 || 255 < peer->maxforwards) {
31978  ast_log(LOG_WARNING, "'%s' is not a valid maxforwards value at line %d. Using default.\n", v->value, v->lineno);
31980  }
31981  } else if (!strcasecmp(v->name, "accountcode")) {
31983  } else if (!strcasecmp(v->name, "mohinterpret")) {
31985  } else if (!strcasecmp(v->name, "mohsuggest")) {
31987  } else if (!strcasecmp(v->name, "parkinglot")) {
31989  } else if (!strcasecmp(v->name, "rtp_engine")) {
31990  ast_string_field_set(peer, engine, v->value);
31991  } else if (!strcasecmp(v->name, "mailbox")) {
31992  add_peer_mailboxes(peer, v->value);
31993  } else if (!strcasecmp(v->name, "hasvoicemail")) {
31994  /* People expect that if 'hasvoicemail' is set, that the mailbox will
31995  * be also set, even if not explicitly specified. */
31996  if (ast_true(v->value) && AST_LIST_EMPTY(&peer->mailboxes)) {
31997  /*
31998  * hasvoicemail is a users.conf legacy voicemail enable method.
31999  * hasvoicemail is only going to work for app_voicemail mailboxes.
32000  */
32001  if (strchr(name, '@')) {
32002  add_peer_mailboxes(peer, name);
32003  } else {
32005 
32006  snprintf(mailbox, sizeof(mailbox), "%s@default", name);
32007  add_peer_mailboxes(peer, mailbox);
32008  }
32009  }
32010  } else if (!strcasecmp(v->name, "subscribemwi")) {
32012  } else if (!strcasecmp(v->name, "vmexten")) {
32013  ast_string_field_set(peer, vmexten, v->value);
32014  } else if (!strcasecmp(v->name, "callgroup")) {
32015  peer->callgroup = ast_get_group(v->value);
32016  } else if (!strcasecmp(v->name, "allowtransfer")) {
32018  } else if (!strcasecmp(v->name, "pickupgroup")) {
32019  peer->pickupgroup = ast_get_group(v->value);
32020  } else if (!strcasecmp(v->name, "namedcallgroup")) {
32022  } else if (!strcasecmp(v->name, "namedpickupgroup")) {
32024  } else if (!strcasecmp(v->name, "allow")) {
32026  if (error) {
32027  ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value);
32028  }
32029  } else if (!strcasecmp(v->name, "disallow")) {
32030  int error = ast_format_cap_update_by_allow_disallow(peer->caps, v->value, FALSE);
32031  if (error) {
32032  ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value);
32033  }
32034  } else if (!strcasecmp(v->name, "preferred_codec_only")) {
32036  } else if (!strcasecmp(v->name, "autoframing")) {
32037  peer->autoframing = ast_true(v->value);
32038  } else if (!strcasecmp(v->name, "rtptimeout")) {
32039  if ((sscanf(v->value, "%30d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) {
32040  ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno);
32041  peer->rtptimeout = global_rtptimeout;
32042  }
32043  } else if (!strcasecmp(v->name, "rtpholdtimeout")) {
32044  if ((sscanf(v->value, "%30d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) {
32045  ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno);
32047  }
32048  } else if (!strcasecmp(v->name, "rtpkeepalive")) {
32049  if ((sscanf(v->value, "%30d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) {
32050  ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno);
32052  }
32053  } else if (!strcasecmp(v->name, "timert1")) {
32054  if ((sscanf(v->value, "%30d", &peer->timer_t1) != 1) || (peer->timer_t1 < 200) || (peer->timer_t1 < global_t1min)) {
32055  ast_log(LOG_WARNING, "'%s' is not a valid T1 time at line %d. Using default.\n", v->value, v->lineno);
32056  peer->timer_t1 = global_t1min;
32057  }
32058  timert1_set = 1;
32059  } else if (!strcasecmp(v->name, "timerb")) {
32060  if ((sscanf(v->value, "%30d", &peer->timer_b) != 1) || (peer->timer_b < 200)) {
32061  ast_log(LOG_WARNING, "'%s' is not a valid Timer B time at line %d. Using default.\n", v->value, v->lineno);
32062  peer->timer_b = global_timer_b;
32063  }
32064  timerb_set = 1;
32065  } else if (!strcasecmp(v->name, "setvar")) {
32066  peer->chanvars = add_var(v->value, peer->chanvars);
32067  } else if (!strcasecmp(v->name, "header")) {
32068  char tmp[4096];
32069  snprintf(tmp, sizeof(tmp), "__SIPADDHEADERpre%2d=%s", ++headercount, v->value);
32070  peer->chanvars = add_var(tmp, peer->chanvars);
32071  } else if (!strcasecmp(v->name, "qualifyfreq")) {
32072  int i;
32073  if (sscanf(v->value, "%30d", &i) == 1) {
32074  peer->qualifyfreq = i * 1000;
32075  } else {
32076  ast_log(LOG_WARNING, "Invalid qualifyfreq number '%s' at line %d of %s\n", v->value, v->lineno, config);
32078  }
32079  } else if (!strcasecmp(v->name, "maxcallbitrate")) {
32080  peer->maxcallbitrate = atoi(v->value);
32081  if (peer->maxcallbitrate < 0) {
32083  }
32084  } else if (!strcasecmp(v->name, "session-timers")) {
32085  int i = (int) str2stmode(v->value);
32086  if (i < 0) {
32087  ast_log(LOG_WARNING, "Invalid session-timers '%s' at line %d of %s\n", v->value, v->lineno, config);
32089  } else {
32090  peer->stimer.st_mode_oper = i;
32091  }
32092  } else if (!strcasecmp(v->name, "session-expires")) {
32093  if (sscanf(v->value, "%30d", &peer->stimer.st_max_se) != 1) {
32094  ast_log(LOG_WARNING, "Invalid session-expires '%s' at line %d of %s\n", v->value, v->lineno, config);
32095  peer->stimer.st_max_se = global_max_se;
32096  }
32097  } else if (!strcasecmp(v->name, "session-minse")) {
32098  if (sscanf(v->value, "%30d", &peer->stimer.st_min_se) != 1) {
32099  ast_log(LOG_WARNING, "Invalid session-minse '%s' at line %d of %s\n", v->value, v->lineno, config);
32100  peer->stimer.st_min_se = global_min_se;
32101  }
32102  if (peer->stimer.st_min_se < DEFAULT_MIN_SE) {
32103  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);
32104  peer->stimer.st_min_se = global_min_se;
32105  }
32106  } else if (!strcasecmp(v->name, "session-refresher")) {
32107  int i = (int) str2strefresherparam(v->value);
32108  if (i < 0) {
32109  ast_log(LOG_WARNING, "Invalid session-refresher '%s' at line %d of %s\n", v->value, v->lineno, config);
32111  } else {
32112  peer->stimer.st_ref = i;
32113  }
32114  } else if (!strcasecmp(v->name, "disallowed_methods")) {
32115  char *disallow = ast_strdupa(v->value);
32116  mark_parsed_methods(&peer->disallowed_methods, disallow);
32117  } else if (!strcasecmp(v->name, "unsolicited_mailbox")) {
32118  ast_string_field_set(peer, unsolicited_mailbox, v->value);
32119  } else if (!strcasecmp(v->name, "use_q850_reason")) {
32121  } else if (!strcasecmp(v->name, "encryption")) {
32123  } else if (!strcasecmp(v->name, "encryption_taglen")) {
32124  ast_set2_flag(&peer->flags[2], !strcasecmp(v->value, "32"), SIP_PAGE3_SRTP_TAG_32);
32125  } else if (!strcasecmp(v->name, "snom_aoc_enabled")) {
32127  } else if (!strcasecmp(v->name, "avpf")) {
32129  } else if (!strcasecmp(v->name, "icesupport")) {
32131  } else if (!strcasecmp(v->name, "ignore_requested_pref")) {
32133  } else if (!strcasecmp(v->name, "discard_remote_hold_retrieval")) {
32135  } else if (!strcasecmp(v->name, "force_avp")) {
32137  } else {
32138  ast_rtp_dtls_cfg_parse(&peer->dtls_cfg, v->name, v->value);
32139  }
32140  }
32141 
32142  /* Validate DTLS configuration */
32143  if (ast_rtp_dtls_cfg_validate(&peer->dtls_cfg)) {
32144  sip_unref_peer(peer, "Removing peer due to bad DTLS configuration");
32145  return NULL;
32146  }
32147 
32148  /* SRB */
32149 
32150  /* Apply the encryption tag length to the DTLS configuration, in case DTLS is in use */
32152 
32153  /* These apply to devstate lookups */
32154  if (realtime && !strcasecmp(v->name, "lastms")) {
32155  sscanf(v->value, "%30d", &peer->lastms);
32156  } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) {
32158  } else if (realtime && !strcasecmp(v->name, "fullcontact")) {
32159  if (alt_fullcontact && !alt) {
32160  /* Reset, because the alternate also has a fullcontact and we
32161  * do NOT want the field value to be doubled. It might be
32162  * tempting to skip this, but the first table might not have
32163  * fullcontact and since we're here, we know that the alternate
32164  * absolutely does. */
32165  alt_fullcontact = 0;
32166  ast_str_reset(fullcontact);
32167  }
32168  /* Reconstruct field, because realtime separates our value at the ';' */
32169  if (ast_str_strlen(fullcontact) > 0) {
32170  ast_str_append(&fullcontact, 0, ";%s", v->value);
32171  } else {
32172  ast_str_set(&fullcontact, 0, "%s", v->value);
32173  }
32174  } else if (!strcasecmp(v->name, "qualify")) {
32175  if (!strcasecmp(v->value, "no")) {
32176  peer->maxms = 0;
32177  } else if (!strcasecmp(v->value, "yes")) {
32179  } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
32180  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);
32181  peer->maxms = 0;
32182  }
32183  if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && peer->maxms > 0) {
32184  /* This would otherwise cause a network storm, where the
32185  * qualify response refreshes the peer from the database,
32186  * which in turn causes another qualify to be sent, ad
32187  * infinitum. */
32188  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);
32189  peer->maxms = 0;
32190  }
32191  } else if (!strcasecmp(v->name, "keepalive")) {
32192  if (!strcasecmp(v->value, "no")) {
32193  peer->keepalive = 0;
32194  } else if (!strcasecmp(v->value, "yes")) {
32196  } else if (sscanf(v->value, "%30d", &peer->keepalive) != 1) {
32197  ast_log(LOG_WARNING, "Keep alive of peer '%s' should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", peer->name, v->lineno);
32198  peer->keepalive = 0;
32199  }
32200  } else if (!strcasecmp(v->name, "callcounter")) {
32201  peer->call_limit = ast_true(v->value) ? INT_MAX : 0;
32202  } else if (!strcasecmp(v->name, "call-limit")) {
32203  peer->call_limit = atoi(v->value);
32204  if (peer->call_limit < 0) {
32205  peer->call_limit = 0;
32206  }
32207  } else if (!strcasecmp(v->name, "busylevel")) {
32208  peer->busy_level = atoi(v->value);
32209  if (peer->busy_level < 0) {
32210  peer->busy_level = 0;
32211  }
32212  } else if (ast_cc_is_config_param(v->name)) {
32213  ast_cc_set_param(peer->cc_params, v->name, v->value);
32214  }
32215  }
32216 
32217  if (!devstate_only) {
32218  struct sip_mailbox *mailbox;
32219  AST_LIST_TRAVERSE_SAFE_BEGIN(&peer->mailboxes, mailbox, entry) {
32220  if (mailbox->status == SIP_MAILBOX_STATUS_UNKNOWN) {
32222  destroy_mailbox(mailbox);
32223  }
32224  }
32226  }
32227 
32229  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);
32231  }
32232 
32233  /* Note that Timer B is dependent upon T1 and MUST NOT be lower
32234  * than T1 * 64, according to RFC 3261, Section 17.1.1.2 */
32235  if (peer->timer_b < peer->timer_t1 * 64) {
32236  if (timerb_set && timert1_set) {
32237  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);
32238  } else if (timerb_set) {
32239  if ((peer->timer_t1 = peer->timer_b / 64) < global_t1min) {
32240  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);
32241  peer->timer_t1 = global_t1min;
32242  peer->timer_b = peer->timer_t1 * 64;
32243  }
32244  peer->timer_t1 = peer->timer_b / 64;
32245  } else {
32246  peer->timer_b = peer->timer_t1 * 64;
32247  }
32248  }
32249 
32250  if (!peer->default_outbound_transport) {
32251  /* Set default set of transports */
32253  /* Set default primary transport */
32255  }
32256 
32257  /* The default transport type set during build_peer should only replace the socket.type when...
32258  * 1. Registration is not present and the socket.type and default transport types are different.
32259  * 2. The socket.type is not an acceptable transport type after rebuilding peer.
32260  * 3. The socket.type is not set yet. */
32261  if (((peer->socket.type != peer->default_outbound_transport) && (peer->expire == -1)) ||
32262  !(peer->socket.type & peer->transports) || !(peer->socket.type)) {
32264  }
32265 
32266  ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags);
32267  ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags);
32268  ast_copy_flags(&peer->flags[2], &peerflags[2], mask[2].flags);
32269 
32270  if (ast_str_strlen(fullcontact)) {
32271  ast_string_field_set(peer, fullcontact, ast_str_buffer(fullcontact));
32272  peer->rt_fromcontact = TRUE;
32273  /* We have a hostname in the fullcontact, but if we don't have an
32274  * address listed on the entry (or if it's 'dynamic'), then we need to
32275  * parse the entry to obtain the IP address, so a dynamic host can be
32276  * contacted immediately after reload (as opposed to waiting for it to
32277  * register once again). But if we have an address for this peer and NAT was
32278  * specified, use that address instead. */
32279  /* XXX May need to revisit the final argument; does the realtime DB store whether
32280  * the original contact was over TLS or not? XXX */
32282  || ast_sockaddr_isnull(&peer->addr)) {
32283  __set_address_from_contact(ast_str_buffer(fullcontact), &peer->addr, 0);
32284  }
32285  }
32286 
32287  if (srvlookup && peer->dnsmgr == NULL) {
32288  char transport[MAXHOSTNAMELEN];
32289  char _srvlookup[MAXHOSTNAMELEN];
32290  char *params;
32291 
32292  ast_copy_string(_srvlookup, srvlookup, sizeof(_srvlookup));
32293  if ((params = strchr(_srvlookup, ';'))) {
32294  *params++ = '\0';
32295  }
32296 
32297  snprintf(transport, sizeof(transport), "_%s._%s", get_srv_service(peer->socket.type), get_srv_protocol(peer->socket.type));
32298 
32299  peer->addr.ss.ss_family = get_address_family_filter(peer->socket.type); /* Filter address family */
32300  if (ast_dnsmgr_lookup_cb(_srvlookup, &peer->addr, &peer->dnsmgr, sip_cfg.srvlookup && !peer->portinuri ? transport : NULL,
32301  on_dns_update_peer, sip_ref_peer(peer, "Store peer on dnsmgr"))) {
32302  ast_log(LOG_ERROR, "srvlookup failed for host: %s, on peer %s, removing peer\n", _srvlookup, peer->name);
32303  sip_unref_peer(peer, "dnsmgr lookup failed, getting rid of peer dnsmgr ref");
32304  sip_unref_peer(peer, "getting rid of a peer pointer");
32305  return NULL;
32306  }
32307  if (!peer->dnsmgr) {
32308  /* dnsmgr refresh disabeld, release reference */
32309  sip_unref_peer(peer, "dnsmgr disabled, unref peer");
32310  }
32311 
32312  ast_string_field_set(peer, tohost, srvlookup);
32313 
32315  int ha_error = 0;
32316 
32317  ast_append_acl("deny", ast_sockaddr_stringify_addr(&peer->addr), &sip_cfg.contact_acl, &ha_error, NULL);
32318  if (ha_error) {
32319  ast_log(LOG_ERROR, "Bad or unresolved host/IP entry in configuration for peer %s, cannot add to contact ACL\n", peer->name);
32320  }
32321  }
32322  } else if (peer->dnsmgr && !peer->host_dynamic) {
32323  /* force a refresh here on reload if dnsmgr already exists and host is set. */
32324  ast_dnsmgr_refresh(peer->dnsmgr);
32325  }
32326 
32327  if (port && !realtime && peer->host_dynamic) {
32328  ast_sockaddr_set_port(&peer->defaddr, port);
32329  } else if (port) {
32330  ast_sockaddr_set_port(&peer->addr, port);
32331  }
32332 
32333  if (ast_sockaddr_port(&peer->addr) == 0) {
32334  ast_sockaddr_set_port(&peer->addr,
32335  (peer->socket.type & AST_TRANSPORT_TLS) ?
32337  }
32338  if (ast_sockaddr_port(&peer->defaddr) == 0) {
32340  (peer->socket.type & AST_TRANSPORT_TLS) ?
32342  }
32343 
32344  if (realtime) {
32345  int enablepoke = 1;
32346 
32347  if (!sip_cfg.ignore_regexpire && peer->host_dynamic) {
32348  time_t nowtime = time(NULL);
32349 
32350  if ((nowtime - regseconds) > 0) {
32351  destroy_association(peer);
32352  memset(&peer->addr, 0, sizeof(peer->addr));
32353  peer->lastms = -1;
32354  enablepoke = 0;
32355  ast_debug(1, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
32356  }
32357  }
32358 
32359  /* Startup regular pokes */
32360  if (!devstate_only && enablepoke) {
32361  /*
32362  * We cannot poke the peer now in this thread without
32363  * a lock inversion so pass it off to the scheduler
32364  * thread.
32365  */
32367  0, /* Poke the peer ASAP */
32368  sip_poke_peer_now, peer,
32369  sip_unref_peer(_data, "removing poke peer ref"),
32370  sip_unref_peer(peer, "removing poke peer ref"),
32371  sip_ref_peer(peer, "adding poke peer ref"));
32372  }
32373  }
32374 
32375  if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) {
32376  sip_cfg.allowsubscribe = TRUE; /* No global ban any more */
32377  }
32378  /* If read-only RT backend, then refresh from local DB cache */
32379  if (peer->host_dynamic && (!peer->is_realtime || !sip_cfg.peer_rtupdate)) {
32380  reg_source_db(peer);
32381  }
32382 
32383  /* If they didn't request that MWI is sent *only* on subscribe, go ahead and
32384  * subscribe to it now. */
32385  if (!devstate_only && !ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) &&
32386  !AST_LIST_EMPTY(&peer->mailboxes)) {
32387  add_peer_mwi_subs(peer);
32388  /* Send MWI from the event cache only. This is so we can send initial
32389  * MWI if app_voicemail got loaded before chan_sip. If it is the other
32390  * way, then we will get events when app_voicemail gets loaded. */
32391  sip_send_mwi_to_peer(peer, 1);
32392  }
32393 
32394  peer->the_mark = 0;
32395 
32396  oldacl = ast_free_acl_list(oldacl);
32397  oldcontactacl = ast_free_acl_list(oldcontactacl);
32398  olddirectmediaacl = ast_free_acl_list(olddirectmediaacl);
32399  if (!ast_strlen_zero(peer->callback)) { /* build string from peer info */
32400  char *reg_string;
32401  if (ast_asprintf(&reg_string, "%s?%s:%s:%s@%s/%s", peer->name, S_OR(peer->fromuser, peer->username), S_OR(peer->remotesecret, peer->secret), peer->username, peer->tohost, peer->callback) >= 0) {
32402  sip_register(reg_string, 0); /* XXX TODO: count in registry_count */
32403  ast_free(reg_string);
32404  }
32405  }
32406 
32407  /* If an ACL change subscription is needed and doesn't exist, we need one. */
32408  if (acl_change_subscription_needed) {
32410  }
32411 
32412  return peer;
32413 }
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:290
static void on_dns_update_peer(struct ast_sockaddr *old, struct ast_sockaddr *new, void *data)
Definition: chan_sip.c:15029
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
int st_min_se
Definition: sip.h:978
#define SIP_PAGE3_ICE_SUPPORT
Definition: sip.h:390
struct ast_variable * next
static int speerobjs
Definition: chan_sip.c:879
static void destroy_association(struct sip_peer *peer)
Remove registration data from realtime database or AST/DB when registration expires.
Definition: chan_sip.c:16613
struct sockaddr_storage ss
Definition: netsock2.h:98
int ast_set_cc_agent_policy(struct ast_cc_config_params *config, enum ast_cc_agent_policies value)
Set the cc_agent_policy.
Definition: ccss.c:871
int keepalive
Definition: sip.h:1360
static char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: chan_iax2.c:428
struct ast_dnsmgr_entry * dnsmgr
Definition: sip.h:1351
static char mohinterpret[MAX_MUSICCLASS]
Definition: chan_alsa.c:119
int ast_rtp_dtls_cfg_parse(struct ast_rtp_dtls_cfg *dtls_cfg, const char *name, const char *value)
Parse DTLS related configuration options.
Definition: rtp_engine.c:3020
struct ast_namedgroups * named_pickupgroups
Definition: sip.h:1349
static int srvlookup
Definition: chan_iax2.c:358
#define SIP_PAGE2_ALLOWSUBSCRIBE
Definition: sip.h:335
static struct ast_variable * add_var(const char *buf, struct ast_variable *list)
implement the setvar config line
Definition: chan_sip.c:31464
struct ast_sockaddr addr
Definition: sip.h:1352
int maxms
Definition: sip.h:1357
int timer_t1
Definition: sip.h:1369
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&#39;d proxy. If dest is non-NULL, no allocation is performed a...
Definition: chan_sip.c:3491
#define FALSE
Definition: app_minivm.c:521
int keepalivesend
Definition: sip.h:1361
static char parkinglot[AST_MAX_CONTEXT]
Definition: chan_mgcp.c:163
static struct ast_tls_config default_tls_cfg
Default TLS connection configuration.
Definition: chan_sip.c:2377
int ast_callerid_split(const char *src, char *name, int namelen, char *num, int numlen)
Definition: callerid.c:1092
static struct ast_tone_zone * ast_tone_zone_unref(struct ast_tone_zone *tz)
Release a reference to an ast_tone_zone.
Definition: indications.h:205
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
Definition: ast_expr2.c:325
#define ao2_t_alloc(data_size, destructor_fn, debug_msg)
Definition: astobj2.h:409
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
struct ast_rtp_dtls_cfg dtls_cfg
Definition: sip.h:1381
definition of a sip proxy server
Definition: sip.h:721
static void sip_destroy_peer_fn(void *peer)
Definition: chan_sip.c:5303
struct ast_endpoint * ast_endpoint_create(const char *tech, const char *resource)
Create an endpoint struct.
#define ast_set2_flag(p, value, flag)
Definition: utils.h:94
#define ast_test_flag(p, flag)
Definition: utils.h:63
int rtpholdtimeout
Definition: sip.h:1344
int tcp_enabled
Definition: sip.h:788
static int global_t1min
Definition: chan_sip.c:848
static int get_address_family_filter(unsigned int transport)
Helper for dns resolution to filter by address family.
Definition: chan_sip.c:29558
static int global_dynamic_exclude_static
Definition: chan_sip.c:862
#define OBJ_POINTER
Definition: astobj2.h:1154
#define SIP_PAGE2_PREFERRED_CODEC
Definition: sip.h:332
static void reg_source_db(struct sip_peer *peer)
Get registration details from Asterisk DB.
Definition: chan_sip.c:16743
#define ast_set_flag(p, flag)
Definition: utils.h:70
int ast_cc_is_config_param(const char *const name)
Is this a CCSS configuration parameter?
Definition: ccss.c:846
#define LOG_WARNING
Definition: logger.h:274
static int rpeerobjs
Definition: chan_sip.c:880
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
static int global_rtptimeout
Definition: chan_sip.c:823
static int tmp()
Definition: bt_open.c:389
unsigned int flags
Definition: utils.h:200
Structure for variables, used for configurations and for channel variables.
int maxforwards
Definition: sip.h:1331
struct ast_sockaddr defaddr
Definition: sip.h:1362
A peer&#39;s mailbox.
Definition: sip.h:1261
Definition: sched.c:76
#define SIP_NAT_FORCE_RPORT
Definition: sip.h:283
#define AST_SCHED_DEL_UNREF(sched, id, refcall)
schedule task to get deleted and call unref function
Definition: sched.h:80
static const char * get_srv_protocol(enum ast_transport t)
Return protocol string for srv dns query.
Definition: chan_sip.c:3743
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
#define ao2_t_unlink(container, obj, tag)
Remove an object from a container.
Definition: astobj2.h:1596
unsigned short host_dynamic
Definition: sip.h:1314
unsigned short rt_fromcontact
Definition: sip.h:1313
int srvlookup
Definition: sip.h:758
Wrapper for an ast_acl linked list.
Definition: acl.h:76
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
#define SIP_PAGE2_SUBSCRIBEMWIONLY
Definition: sip.h:343
#define ao2_unlock(a)
Definition: astobj2.h:730
enum sip_peer_type type
Definition: sip.h:1375
#define ast_copy_flags(dest, src, flagz)
Definition: utils.h:84
#define ast_str_alloca(init_len)
Definition: strings.h:800
#define MAXHOSTNAMELEN
Definition: network.h:69
#define NULL
Definition: resample.c:96
#define sip_ref_peer(peer, tag)
Definition: sip.h:1894
static int default_maxcallbitrate
Definition: chan_sip.c:804
int ast_dnsmgr_refresh(struct ast_dnsmgr_entry *entry)
Force a refresh of a dnsmgr entry.
Definition: dnsmgr.c:239
int peer_rtupdate
Definition: sip.h:750
#define ast_cc_config_params_init()
Allocate and initialize an ast_cc_config_params structure.
Definition: ccss.h:135
int st_max_se
Definition: sip.h:979
int allowsubscribe
Definition: sip.h:777
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
static char cid_num[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:164
static unsigned int default_transports
Definition: chan_sip.c:806
#define SIP_PAGE3_SNOM_AOC
Definition: sip.h:384
unsigned short transports
Definition: sip.h:1311
struct sip_proxy * outboundproxy
Definition: sip.h:1350
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:755
char name[80]
Definition: sip.h:1274
struct ast_variable * chanvars
Definition: sip.h:1366
static struct ao2_container * peers_by_ip
Definition: chan_sip.c:1053
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
Definition: netsock2.h:140
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:269
#define AST_MAX_MAILBOX_UNIQUEID
Definition: mwi.h:574
#define ast_strlen_zero(foo)
Definition: strings.h:52
const ast_string_field tohost
Definition: sip.h:1306
#define SIP_PAGE3_FORCE_AVP
Definition: sip.h:393
int ast_format_cap_update_by_allow_disallow(struct ast_format_cap *cap, const char *list, int allowing)
Parse an "allow" or "deny" list and modify a format capabilities structure accordingly.
Definition: format_cap.c:320
int rtptimeout
Definition: sip.h:1343
#define SIP_PAGE2_USE_SRTP
Definition: sip.h:368
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
enum ama_flags ast_channel_string2amaflag(const char *flag)
Convert a string to a detail record AMA flag.
Definition: channel.c:4405
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:521
enum transfermodes allowtransfer
Definition: sip.h:1332
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
static char mailbox[AST_MAX_MAILBOX_UNIQUEID]
Definition: chan_mgcp.c:204
int ast_get_time_t(const char *src, time_t *dst, time_t _default, int *consumed)
get values from config variables.
Definition: main/utils.c:2198
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define STANDARD_TLS_PORT
Standard SIP TLS port from RFC 3261. DO NOT CHANGE THIS.
Definition: sip.h:178
int lastms
Definition: sip.h:1356
struct ast_namedgroups * named_callgroups
Definition: sip.h:1348
struct sip_peer * peer
Definition: sip.h:1265
struct ast_acl_list * acl
Definition: sip.h:1363
#define STANDARD_SIP_PORT
Standard SIP unsecure port for UDP and TCP from RFC 3261. DO NOT CHANGE THIS.
Definition: sip.h:176
int amaflags
Definition: sip.h:1323
static enum st_mode str2stmode(const char *s)
Definition: chan_sip.c:19995
A set of tones for a given locale.
Definition: indications.h:74
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:353
static char mohsuggest[MAX_MUSICCLASS]
Definition: chan_iax2.c:430
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
int call_limit
Definition: sip.h:1328
static int sip_poke_peer_now(const void *data)
Definition: chan_sip.c:16731
const ast_string_field remotesecret
Definition: sip.h:1306
#define ao2_lock(a)
Definition: astobj2.h:718
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static void add_realm_authentication(struct sip_auth_container **credentials, const char *configuration, int lineno)
Definition: chan_sip.c:31375
#define DEFAULT_MIN_SE
Definition: sip.h:120
static void set_peer_defaults(struct sip_peer *peer)
Set peer defaults before configuring specific configurations.
Definition: chan_sip.c:31482
const ast_string_field username
Definition: sip.h:1306
int ast_cc_set_param(struct ast_cc_config_params *params, const char *const name, const char *value)
set a CCSS configuration parameter, given its name
Definition: ccss.c:804
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
static int sip_send_mwi_to_peer(struct sip_peer *peer, int cache_only)
Send message waiting indication to alert peer that they&#39;ve got voicemail.
Definition: chan_sip.c:29756
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.
Definition: chan_sip.c:31075
struct sip_peer::@176 mailboxes
int maxcallbitrate
Definition: sip.h:1340
ast_group_t ast_get_group(const char *s)
Definition: channel.c:7718
int timer_b
Definition: sip.h:1370
int default_max_forwards
Definition: sip.h:789
unsigned int t38_maxdatagram
Definition: sip.h:1329
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
static void mark_parsed_methods(unsigned int *methods, char *methods_str)
Definition: chan_sip.c:9811
int ast_parse_caller_presentation(const char *data)
Convert caller ID text code to value (used in config file parsing)
Definition: callerid.c:1143
void ast_format_cap_remove_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Remove all formats matching a specific format type.
Definition: format_cap.c:525
struct ast_acl_list * directmediaacl
Definition: sip.h:1365
struct ast_cc_config_params * cc_params
Definition: sip.h:1377
#define SIP_PAGE3_DISCARD_REMOTE_HOLD_RETRIEVAL
Definition: sip.h:392
static int default_qualify
Definition: chan_sip.c:797
unsigned int enabled
Definition: rtp_engine.h:555
struct ast_namedgroups * ast_get_namedgroups(const char *s)
Create an ast_namedgroups set with group names from comma separated string.
Definition: channel.c:7775
int expire
Definition: sip.h:1341
#define LOG_ERROR
Definition: logger.h:285
#define SIP_PAGE2_Q850_REASON
Definition: sip.h:326
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: main/utils.c:1951
struct ast_format_cap * caps
Definition: sip.h:1342
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
struct ast_endpoint * endpoint
Definition: sip.h:1379
const ast_string_field fromdomain
Definition: sip.h:1306
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:537
const ast_string_field callback
Definition: sip.h:1306
static int sip_register(const char *value, int lineno)
create sip_registry object from register=> line in sip.conf and link into reg container ...
Definition: chan_sip.c:9679
struct ast_acl_list * ast_free_acl_list(struct ast_acl_list *acl)
Free a list of ACLs.
Definition: acl.c:233
#define SIP_PAGE2_HAVEPEERCONTEXT
Definition: sip.h:367
struct ast_tone_zone * ast_get_indication_zone(const char *country)
locate ast_tone_zone
Definition: indications.c:433
unsigned short the_mark
Definition: sip.h:1316
static struct ast_flags global_flags[3]
Definition: chan_sip.c:884
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
int ast_get_ip(struct ast_sockaddr *addr, const char *hostname)
Get the IP address given a hostname.
Definition: acl.c:1000
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
#define LOG_NOTICE
Definition: logger.h:263
#define SIP_PAGE2_RTCACHEFRIENDS
Definition: sip.h:323
#define SIP_PAGE3_NAT_AUTO_RPORT
Definition: sip.h:386
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
int ast_rtp_dtls_cfg_validate(struct ast_rtp_dtls_cfg *dtls_cfg)
Validates DTLS related configuration options.
Definition: rtp_engine.c:3094
static int global_timer_b
Definition: chan_sip.c:849
static int __set_address_from_contact(const char *fullcontact, struct ast_sockaddr *addr, int tcp)
Definition: chan_sip.c:16892
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
#define DEFAULT_MAXMS
Definition: chan_iax2.c:390
unsigned short deprecated_username
Definition: sip.h:1321
static const char name[]
Definition: cdr_mysql.c:74
#define ast_free(a)
Definition: astmm.h:182
unsigned short is_realtime
Definition: sip.h:1312
static enum st_refresher_param str2strefresherparam(const char *s)
Definition: chan_sip.c:20020
static int global_max_se
Definition: chan_sip.c:858
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
int rtpkeepalive
Definition: sip.h:1345
struct ast_acl_list * contactacl
Definition: sip.h:1364
static void destroy_mailbox(struct sip_mailbox *mailbox)
Definition: chan_sip.c:5275
static int global_qualifyfreq
Definition: chan_sip.c:851
enum st_mode st_mode_oper
Definition: sip.h:976
Structure used to handle boolean flags.
Definition: utils.h:199
unsigned short autoframing
Definition: sip.h:1317
static enum st_refresher_param global_st_refresher
Definition: chan_sip.c:856
static char cid_name[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:165
#define DEFAULT_KEEPALIVE_INTERVAL
Definition: sip.h:228
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.
Definition: chan_sip.c:31120
ast_group_t callgroup
Definition: sip.h:1346
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:653
static int can_parse_xml
Definition: chan_sip.c:872
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
struct sip_auth_container * auth
Definition: sip.h:1322
#define AST_SCHED_REPLACE_UNREF(id, sched, when, callback, data, unrefcall, addfailcall, refcall)
Definition: sched.h:150
char * strsep(char **str, const char *delims)
static enum st_mode global_st_mode
Definition: chan_sip.c:855
static void add_peer_mwi_subs(struct sip_peer *peer)
Definition: chan_sip.c:28499
enum ast_transport type
Definition: sip.h:798
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
void ast_append_acl(const char *sense, const char *stuff, struct ast_acl_list **path, int *error, int *named_acl_flag)
Add a rule to an ACL struct.
Definition: acl.c:430
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
struct ast_flags flags[3]
Definition: sip.h:1335
unsigned int portinuri
Definition: sip.h:1353
void ast_rtp_dtls_cfg_free(struct ast_rtp_dtls_cfg *dtls_cfg)
Free contents of a DTLS configuration structure.
Definition: rtp_engine.c:3131
#define TRUE
Definition: app_minivm.c:518
const ast_string_field secret
Definition: sip.h:1306
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 bein...
Definition: chan_sip.c:3538
static void acl_change_stasis_subscribe(void)
Definition: chan_sip.c:17562
#define ao2_t_find(container, arg, flags, tag)
Definition: astobj2.h:1754
#define SIP_PAGE3_SRTP_TAG_32
Definition: sip.h:385
enum ast_srtp_suite suite
Definition: rtp_engine.h:558
enum ast_transport default_outbound_transport
Definition: sip.h:1308
static void add_peer_mailboxes(struct sip_peer *peer, const char *value)
Definition: chan_sip.c:31589
const ast_string_field fromuser
Definition: sip.h:1306
int callingpres
Definition: sip.h:1324
Definition: search.h:40
int error(const char *format,...)
Definition: utils/frame.c:999
static int global_rtpholdtimeout
Definition: chan_sip.c:824
static const char * get_srv_service(enum ast_transport t)
Return service string for srv dns query.
Definition: chan_sip.c:3761
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
int qualifyfreq
Definition: sip.h:1358
#define SIP_PAGE3_IGNORE_PREFCAPS
Definition: sip.h:391
struct ast_acl_list * contact_acl
Definition: sip.h:786
struct ast_namedgroups * ast_unref_namedgroups(struct ast_namedgroups *groups)
Definition: channel.c:7832
static void set_socket_transport(struct sip_socket *socket, int transport)
Definition: chan_sip.c:16629
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
int busy_level
Definition: sip.h:1330
void ast_rtp_dtls_cfg_copy(const struct ast_rtp_dtls_cfg *src_cfg, struct ast_rtp_dtls_cfg *dst_cfg)
Copy contents of a DTLS configuration structure.
Definition: rtp_engine.c:3113
static struct ast_rtp_dtls_cfg default_dtls_cfg
Default DTLS connection configuration.
Definition: chan_sip.c:2380
struct sip_st_cfg stimer
Definition: sip.h:1368
static unsigned int default_primary_transport
Definition: chan_sip.c:807
enum st_refresher_param st_ref
Definition: sip.h:977
static snd_pcm_format_t format
Definition: chan_alsa.c:102
enum ast_cc_agent_policies ast_get_cc_agent_policy(struct ast_cc_config_params *config)
Get the cc_agent_policy.
Definition: ccss.c:866
static int global_rtpkeepalive
Definition: chan_sip.c:825
struct sip_socket socket
Definition: sip.h:1307
#define SIP_USEREQPHONE
Definition: sip.h:271
int pokeexpire
Definition: sip.h:1355
static const char config[]
Definition: chan_sip.c:690
int ast_dnsmgr_lookup_cb(const char *name, struct ast_sockaddr *result, struct ast_dnsmgr_entry **dnsmgr, const char *service, dns_update_func func, void *data)
Allocate and initialize a DNS manager entry, with update callback.
Definition: dnsmgr.c:196
static char vmexten[AST_MAX_EXTENSION]
Definition: chan_skinny.c:206
static int global_min_se
Definition: chan_sip.c:857
int ignore_regexpire
Definition: sip.h:753
int fromdomainport
Definition: sip.h:1371
ast_group_t pickupgroup
Definition: sip.h:1347
#define SIP_PAGE3_USE_AVPF
Definition: sip.h:389
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514
enum sip_mailbox_status status
Definition: sip.h:1266
unsigned int disallowed_methods
Definition: sip.h:1376
int enabled
Definition: tcptls.h:88

◆ build_reply_digest()

static int build_reply_digest ( struct sip_pvt p,
int  method,
char *  digest,
int  digest_len 
)
static

Build reply digest.

Returns
Returns -1 if we have no auth
Note
Build digest challenge for authentication of registrations and calls Also used for authentication of BYE

Definition at line 23139 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, AST_TRANSPORT_TLS, authl, authl_lock, sip_pvt::authname, sip_pvt::callid, sip_pvt::domain, find_realm_authentication(), sip_auth::md5secret, sip_pvt::nonce, sip_pvt::noncecount, sip_pvt::opaque, sip_pvt::peerauth, sip_pvt::peermd5secret, sip_pvt::peername, sip_pvt::peersecret, sip_pvt::qop, sip_pvt::realm, sip_pvt::relatedpeer, sip_peer::remotesecret, sip_pvt::sa, sip_auth::secret, sip_methods, sipdebug, sip_pvt::socket, text, sip_socket::type, sip_pvt::uri, sip_auth::username, and sip_pvt::username.

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

23140 {
23141  char a1[256];
23142  char a2[256];
23143  char a1_hash[256];
23144  char a2_hash[256];
23145  char resp[256];
23146  char resp_hash[256];
23147  char uri[256];
23148  char opaque[256] = "";
23149  char cnonce[80];
23150  const char *username;
23151  const char *secret;
23152  const char *md5secret;
23153  struct sip_auth *auth; /* Realm authentication credential */
23154  struct sip_auth_container *credentials;
23155 
23156  if (!ast_strlen_zero(p->domain))
23157  snprintf(uri, sizeof(uri), "%s:%s", p->socket.type == AST_TRANSPORT_TLS ? "sips" : "sip", p->domain);
23158  else if (!ast_strlen_zero(p->uri))
23159  ast_copy_string(uri, p->uri, sizeof(uri));
23160  else
23161  snprintf(uri, sizeof(uri), "%s:%s@%s", p->socket.type == AST_TRANSPORT_TLS ? "sips" : "sip", p->username, ast_sockaddr_stringify_host_remote(&p->sa));
23162 
23163  snprintf(cnonce, sizeof(cnonce), "%08lx", (unsigned long)ast_random());
23164 
23165  /* Check if we have peer credentials */
23166  ao2_lock(p);
23167  credentials = p->peerauth;
23168  if (credentials) {
23169  ao2_t_ref(credentials, +1, "Ref peer auth for digest");
23170  }
23171  ao2_unlock(p);
23172  auth = find_realm_authentication(credentials, p->realm);
23173  if (!auth) {
23174  /* If not, check global credentials */
23175  if (credentials) {
23176  ao2_t_ref(credentials, -1, "Unref peer auth for digest");
23177  }
23179  credentials = authl;
23180  if (credentials) {
23181  ao2_t_ref(credentials, +1, "Ref global auth for digest");
23182  }
23184  auth = find_realm_authentication(credentials, p->realm);
23185  }
23186 
23187  if (auth) {
23188  ast_debug(3, "use realm [%s] from peer [%s][%s]\n", auth->username, p->peername, p->username);
23189  username = auth->username;
23190  secret = auth->secret;
23191  md5secret = auth->md5secret;
23192  if (sipdebug)
23193  ast_debug(1, "Using realm %s authentication for call %s\n", p->realm, p->callid);
23194  } else {
23195  /* No authentication, use peer or register= config */
23196  username = p->authname;
23197  secret = p->relatedpeer
23199  ? p->relatedpeer->remotesecret : p->peersecret;
23200  md5secret = p->peermd5secret;
23201  }
23202  if (ast_strlen_zero(username)) {
23203  /* We have no authentication */
23204  if (credentials) {
23205  ao2_t_ref(credentials, -1, "Unref auth for digest");
23206  }
23207  return -1;
23208  }
23209 
23210  /* Calculate SIP digest response */
23211  snprintf(a1, sizeof(a1), "%s:%s:%s", username, p->realm, secret);
23212  snprintf(a2, sizeof(a2), "%s:%s", sip_methods[method].text, uri);
23213  if (!ast_strlen_zero(md5secret))
23214  ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
23215  else
23216  ast_md5_hash(a1_hash, a1);
23217  ast_md5_hash(a2_hash, a2);
23218 
23219  p->noncecount++;
23220  if (!ast_strlen_zero(p->qop))
23221  snprintf(resp, sizeof(resp), "%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, (unsigned)p->noncecount, cnonce, "auth", a2_hash);
23222  else
23223  snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, p->nonce, a2_hash);
23224  ast_md5_hash(resp_hash, resp);
23225 
23226  /* only include the opaque string if it's set */
23227  if (!ast_strlen_zero(p->opaque)) {
23228  snprintf(opaque, sizeof(opaque), ", opaque=\"%s\"", p->opaque);
23229  }
23230 
23231  /* XXX We hard code our qop to "auth" for now. XXX */
23232  if (!ast_strlen_zero(p->qop))
23233  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);
23234  else
23235  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);
23236 
23237  append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount);
23238 
23239  if (credentials) {
23240  ao2_t_ref(credentials, -1, "Unref auth for digest");
23241  }
23242  return 0;
23243 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
const ast_string_field realm
Definition: sip.h:1063
static const struct cfsip_methods sip_methods[]
struct sip_peer * relatedpeer
Definition: sip.h:1171
static struct sip_auth_container * authl
Authentication container for realm authentication.
Definition: chan_sip.c:1079
struct sip_socket socket
Definition: sip.h:1066
const ast_string_field username
Definition: sip.h:1063
int noncecount
Definition: sip.h:1142
const ast_string_field opaque
Definition: sip.h:1063
#define ast_mutex_lock(a)
Definition: lock.h:187
#define ao2_unlock(a)
Definition: astobj2.h:730
char * text
Definition: app_queue.c:1508
const ast_string_field peermd5secret
Definition: sip.h:1063
static ast_mutex_t authl_lock
Global authentication container protection while adjusting the references.
Definition: chan_sip.c:1081
const ast_string_field nonce
Definition: sip.h:1063
const ast_string_field qop
Definition: sip.h:1063
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ast_sockaddr sa
Definition: sip.h:1125
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
const ast_string_field peersecret
Definition: sip.h:1063
const ast_string_field remotesecret
Definition: sip.h:1306
long int ast_random(void)
Definition: main/utils.c:2064
#define ao2_lock(a)
Definition: astobj2.h:718
const char * method
Definition: res_pjsip.c:4335
const ast_string_field authname
Definition: sip.h:1063
const ast_string_field callid
Definition: sip.h:1063
const ast_string_field domain
Definition: sip.h:1063
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
static char * ast_sockaddr_stringify_host_remote(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only, suitable for a URL (with brack...
Definition: netsock2.h:349
const ast_string_field peername
Definition: sip.h:1063
static struct sip_auth * find_realm_authentication(struct sip_auth_container *credentials, const char *realm)
Definition: chan_sip.c:31444
char username[256]
Definition: sip.h:905
enum ast_transport type
Definition: sip.h:798
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
char secret[256]
Definition: sip.h:906
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406
sip_auth: Credentials for authentication to other SIP services
Definition: sip.h:902
char md5secret[256]
Definition: sip.h:907
void ast_md5_hash(char *output, const char *input)
Produces MD5 hash based on input string.
Definition: main/utils.c:248
Container of SIP authentication credentials.
Definition: sip.h:911
const ast_string_field uri
Definition: sip.h:1063
#define ast_mutex_unlock(a)
Definition: lock.h:188
struct sip_auth_container * peerauth
Definition: sip.h:1141

◆ build_route()

static void build_route ( struct sip_pvt p,
struct sip_request req,
int  backwards,
int  resp 
)
static

Build route list from Record-Route header.

Parameters
p
req
backwards
respthe SIP response code or 0 for a request

Definition at line 17201 of file chan_sip.c.

References __get_header(), ast_debug, get_in_brackets_const(), len(), sip_pvt::route, sip_pvt::route_persistent, sip_debug_test_pvt(), sip_get_header(), sip_route_add(), sip_route_clear(), sip_route_dump(), sip_route_empty, sip_route_first_uri(), sip_route_is_strict(), and sip_route_process_header().

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

17202 {
17203  int start = 0;
17204  const char *header;
17205 
17206  /* Once a persistent route is set, don't fool with it */
17207  if (!sip_route_empty(&p->route) && p->route_persistent) {
17208  ast_debug(1, "build_route: Retaining previous route: <%s>\n", sip_route_first_uri(&p->route));
17209  return;
17210  }
17211 
17212  sip_route_clear(&p->route);
17213 
17214  /* We only want to create the route set the first time this is called except
17215  it is called from a provisional response.*/
17216  if ((resp < 100) || (resp > 199)) {
17217  p->route_persistent = 1;
17218  }
17219 
17220  /* Build a tailq, then assign it to p->route when done.
17221  * If backwards, we add entries from the head so they end up
17222  * in reverse order. However, we do need to maintain a correct
17223  * tail pointer because the contact is always at the end.
17224  */
17225  /* 1st we pass through all the hops in any Record-Route headers */
17226  for (;;) {
17227  header = __get_header(req, "Record-Route", &start);
17228  if (*header == '\0') {
17229  break;
17230  }
17231  sip_route_process_header(&p->route, header, backwards);
17232  }
17233 
17234  /* Only append the contact if we are dealing with a strict router or have no route */
17235  if (sip_route_empty(&p->route) || sip_route_is_strict(&p->route)) {
17236  /* 2nd append the Contact: if there is one */
17237  /* Can be multiple Contact headers, comma separated values - we just take the first */
17238  int len;
17239  header = sip_get_header(req, "Contact");
17240  if (strchr(header, '<')) {
17241  get_in_brackets_const(header, &header, &len);
17242  } else {
17243  len = strlen(header);
17244  }
17245  if (header && len) {
17246  sip_route_add(&p->route, header, len, 0);
17247  }
17248  }
17249 
17250  /* For debugging dump what we ended up with */
17251  if (sip_debug_test_pvt(p)) {
17252  sip_route_dump(&p->route);
17253  }
17254 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
void sip_route_process_header(struct sip_route *route, const char *header, int inserthead)
Add routes from header.
Definition: route.c:79
void sip_route_clear(struct sip_route *route)
Free all routes in the list.
Definition: route.c:132
int get_in_brackets_const(const char *src, const char **start, int *length)
Get text in brackets on a const without copy.
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define sip_route_empty(route)
Check if route has no URI&#39;s.
Definition: route.h:118
struct sip_route route
Definition: sip.h:1139
static const char * __get_header(const struct sip_request *req, const char *name, int *start)
Definition: chan_sip.c:8562
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
const char * sip_route_add(struct sip_route *route, const char *uri, size_t len, int inserthead)
Add a new hop to the route.
Definition: route.c:47
unsigned short route_persistent
Definition: sip.h:1088
static int sip_debug_test_pvt(struct sip_pvt *p)
Test PVT for debugging output.
Definition: chan_sip.c:3649
int sip_route_is_strict(struct sip_route *route)
Check if the route is strict.
Definition: route.c:183
void sip_route_dump(const struct sip_route *route)
Verbose dump of all hops for debugging.
Definition: route.c:143
const char * sip_route_first_uri(const struct sip_route *route)
Get the URI of the route&#39;s first hop.
Definition: route.c:199

◆ build_via()

static void build_via ( struct sip_pvt p)
static

Build a Via header for a request.

Definition at line 3847 of file chan_sip.c.

References ast_sockaddr_stringify_remote(), ast_test_flag, sip_pvt::branch, sip_pvt::flags, get_transport_pvt(), sip_pvt::ourip, SIP_NAT_FORCE_RPORT, SIP_NAT_RPORT_PRESENT, and sip_pvt::via.

Referenced by __sip_alloc(), __sip_subscribe_mwi_do(), manager_sipnotify(), reqprep(), sip_cli_notify(), sip_msg_send(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_invite(), transmit_register(), and transmit_response_using_temp().

3848 {
3849  /* Work around buggy UNIDEN UIP200 firmware */
3850  const char *rport = (ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT) || ast_test_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT)) ? ";rport" : "";
3851 
3852  /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */
3853  snprintf(p->via, sizeof(p->via), "SIP/2.0/%s %s;branch=z9hG4bK%08x%s",
3854  get_transport_pvt(p),
3856  (unsigned)p->branch, rport);
3857 }
char via[128]
Definition: sip.h:1063
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_sockaddr ourip
Definition: sip.h:1136
#define SIP_NAT_FORCE_RPORT
Definition: sip.h:283
static char * ast_sockaddr_stringify_remote(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:277
struct ast_flags flags[3]
Definition: sip.h:1075
static const char * get_transport_pvt(struct sip_pvt *p)
Return transport of dialog.
Definition: chan_sip.c:3781
long branch
Definition: sip.h:1121
#define SIP_NAT_RPORT_PRESENT
Definition: sip.h:284

◆ cb_extensionstate()

static int cb_extensionstate ( const char *  context,
const char *  exten,
struct ast_state_cb_info info,
void *  data 
)
static

Callback for the devicestate notification (SUBSCRIBE) support subsystem.

Note
If you add an "hint" priority to the extension in the dial plan, you will get notifications on device state changes

Definition at line 17692 of file chan_sip.c.

References allow_notify_user_presence(), AST_HINT_UPDATE_PRESENCE, ast_state_cb_info::device_state_info, ast_state_cb_info::exten_state, extensionstate_update(), FALSE, ast_state_cb_info::presence_message, ast_state_cb_info::presence_state, ast_state_cb_info::presence_subtype, and ast_state_cb_info::reason.

Referenced by dialog_unlink_all(), and handle_request_subscribe().

17693 {
17694  struct sip_pvt *p = data;
17695  struct state_notify_data notify_data = {
17696  .state = info->exten_state,
17697  .device_state_info = info->device_state_info,
17698  .presence_state = info->presence_state,
17699  .presence_subtype = info->presence_subtype,
17700  .presence_message = info->presence_message,
17701  };
17702 
17704  /* ignore a presence triggered update if we know the useragent doesn't care */
17705  return 0;
17706  }
17707 
17708  return extensionstate_update(context, exten, &notify_data, p, FALSE);
17709 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
#define FALSE
Definition: app_minivm.c:521
const char * presence_message
Definition: pbx.h:108
static int extensionstate_update(const char *context, const char *exten, struct state_notify_data *data, struct sip_pvt *p, int force)
Callback for the devicestate notification (SUBSCRIBE) support subsystem.
Definition: chan_sip.c:17610
enum ast_state_cb_update_reason reason
Definition: pbx.h:103
static int allow_notify_user_presence(struct sip_pvt *p)
Definition: chan_sip.c:15187
enum ast_extension_states exten_state
Definition: pbx.h:104
enum ast_presence_state presence_state
Definition: pbx.h:106
const char * presence_subtype
Definition: pbx.h:107
struct ao2_container * device_state_info
Definition: pbx.h:105
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116

◆ cb_extensionstate_destroy()

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

Definition at line 17600 of file chan_sip.c.

References dialog_unref.

Referenced by handle_request_subscribe().

17601 {
17602  struct sip_pvt *p = data;
17603 
17604  dialog_unref(p, "the extensionstate containing this dialog ptr was destroyed");
17605 }
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005

◆ cc_epa_destructor()

static void cc_epa_destructor ( void *  data)
static

Definition at line 1664 of file chan_sip.c.

References ast_free, and sip_epa_entry::instance_data.

1665 {
1666  struct sip_epa_entry *epa_entry = data;
1667  struct cc_epa_entry *cc_entry = epa_entry->instance_data;
1668  ast_free(cc_entry);
1669 }
Definition: sip.h:1644
void * instance_data
Definition: sip.h:1680
Instance data for a Call completion EPA entry.
Definition: sip.h:1686
#define ast_free(a)
Definition: astmm.h:182

◆ cc_esc_publish_handler()

static int cc_esc_publish_handler ( struct sip_pvt pvt,
struct sip_request req,
struct event_state_compositor esc,
struct sip_esc_entry esc_entry 
)
static

Definition at line 28201 of file chan_sip.c.

References ao2_ref, ast_cc_agent_caller_available(), ast_cc_agent_caller_busy(), ast_log, ast_strlen_zero, ast_xml_close(), ast_xml_find_element(), ast_xml_free_text(), ast_xml_get_root(), ast_xml_get_text(), ast_xml_node_get_children(), ast_cc_agent::core_id, ast_cc_agent::device_name, FALSE, find_sip_cc_agent_by_notify_uri(), find_sip_cc_agent_by_subscribe_uri(), sip_cc_agent_pvt::is_available, LOG_NOTICE, LOG_WARNING, NULL, ast_cc_agent::private_data, REQ_OFFSET_TO_STR, sip_pidf_validate(), transmit_response(), and TRUE.

28202 {
28203  const char *uri = REQ_OFFSET_TO_STR(req, rlpart2);
28204  struct ast_cc_agent *agent;
28205  struct sip_cc_agent_pvt *agent_pvt;
28206  struct ast_xml_doc *pidf_doc = NULL;
28207  const char *basic_status = NULL;
28208  struct ast_xml_node *presence_node;
28209  struct ast_xml_node *presence_children;
28210  struct ast_xml_node *tuple_node;
28211  struct ast_xml_node *tuple_children;
28212  struct ast_xml_node *status_node;
28213  struct ast_xml_node *status_children;
28214  struct ast_xml_node *basic_node;
28215  int res = 0;
28216 
28217  if (!((agent = find_sip_cc_agent_by_notify_uri(uri)) || (agent = find_sip_cc_agent_by_subscribe_uri(uri)))) {
28218  ast_log(LOG_WARNING, "Could not find agent using uri '%s'\n", uri);
28219  transmit_response(pvt, "412 Conditional Request Failed", req);
28220  return -1;
28221  }
28222 
28223  agent_pvt = agent->private_data;
28224 
28225  if (sip_pidf_validate(req, &pidf_doc) == FALSE) {
28226  res = -1;
28227  goto cc_publish_cleanup;
28228  }
28229 
28230  /* It's important to note that the PIDF validation routine has no knowledge
28231  * of what we specifically want in this instance. A valid PIDF document could
28232  * have no tuples, or it could have tuples whose status element has no basic
28233  * element contained within. While not violating the PIDF spec, these are
28234  * insufficient for our needs in this situation
28235  */
28236  presence_node = ast_xml_get_root(pidf_doc);
28237  if (!(presence_children = ast_xml_node_get_children(presence_node))) {
28238  ast_log(LOG_WARNING, "No tuples within presence element.\n");
28239  res = -1;
28240  goto cc_publish_cleanup;
28241  }
28242 
28243  if (!(tuple_node = ast_xml_find_element(presence_children, "tuple", NULL, NULL))) {
28244  ast_log(LOG_NOTICE, "Couldn't find tuple node?\n");
28245  res = -1;
28246  goto cc_publish_cleanup;
28247  }
28248 
28249  /* We already made sure that the tuple has a status node when we validated the PIDF
28250  * document earlier. So there's no need to enclose this operation in an if statement.
28251  */
28252  tuple_children = ast_xml_node_get_children(tuple_node);
28253  /* coverity[null_returns: FALSE] */
28254  status_node = ast_xml_find_element(tuple_children, "status", NULL, NULL);
28255 
28256  if (!(status_children = ast_xml_node_get_children(status_node))) {
28257  ast_log(LOG_WARNING, "No basic elements within status element.\n");
28258  res = -1;
28259  goto cc_publish_cleanup;
28260  }
28261 
28262  if (!(basic_node = ast_xml_find_element(status_children, "basic", NULL, NULL))) {
28263  ast_log(LOG_WARNING, "Couldn't find basic node?\n");
28264  res = -1;
28265  goto cc_publish_cleanup;
28266  }
28267 
28268  basic_status = ast_xml_get_text(basic_node);
28269 
28270  if (ast_strlen_zero(basic_status)) {
28271  ast_log(LOG_NOTICE, "NOthing in basic node?\n");
28272  res = -1;
28273  goto cc_publish_cleanup;
28274  }
28275 
28276  if (!strcmp(basic_status, "open")) {
28277  agent_pvt->is_available = TRUE;
28278  ast_cc_agent_caller_available(agent->core_id, "Received PUBLISH stating SIP caller %s is available",
28279  agent->device_name);
28280  } else if (!strcmp(basic_status, "closed")) {
28281  agent_pvt->is_available = FALSE;
28282  ast_cc_agent_caller_busy(agent->core_id, "Received PUBLISH stating SIP caller %s is busy",
28283  agent->device_name);
28284  } else {
28285  ast_log(LOG_NOTICE, "Invalid content in basic element: %s\n", basic_status);
28286  }
28287 
28288 cc_publish_cleanup:
28289  if (basic_status) {
28290  ast_xml_free_text(basic_status);
28291  }
28292  if (pidf_doc) {
28293  ast_xml_close(pidf_doc);
28294  }
28295  ao2_ref(agent, -1);
28296  if (res) {
28297  transmit_response(pvt, "400 Bad Request", req);
28298  }
28299  return res;
28300 }
#define FALSE
Definition: app_minivm.c:521
void * private_data
Definition: ccss.h:871
#define LOG_WARNING
Definition: logger.h:274
char is_available
Definition: sip.h:1810
int ast_cc_agent_caller_busy(int core_id, const char *const debug,...)
Indicate that the caller is busy.
Definition: ccss.c:3809
static struct ast_cc_agent * find_sip_cc_agent_by_subscribe_uri(const char *const uri)
Definition: chan_sip.c:1863
#define NULL
Definition: resample.c:96
struct ast_xml_node * ast_xml_get_root(struct ast_xml_doc *doc)
Get the document root node.
Definition: xml.c:199
#define ast_strlen_zero(foo)
Definition: strings.h:52
static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req)
Transmit response, no retransmits.
Definition: chan_sip.c:12655
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Definition: astobj2.h:464
int ast_cc_agent_caller_available(int core_id, const char *const debug,...)
Indicate that a previously unavailable caller has become available.
Definition: ccss.c:3820
static struct ast_cc_agent * find_sip_cc_agent_by_notify_uri(const char *const uri)
Definition: chan_sip.c:1848
struct ast_xml_node * ast_xml_find_element(struct ast_xml_node *root_node, const char *name, const char *attrname, const char *attrvalue)
Find a node element by name.
Definition: xml.c:266
Structure representing an agent.
#define LOG_NOTICE
Definition: logger.h:263
unsigned int core_id
Definition: ccss.h:849
#define REQ_OFFSET_TO_STR(req, offset)
Definition: sip.h:858
void ast_xml_close(struct ast_xml_doc *doc)
Close an already open document and free the used structure.
Definition: xml.c:180
static int sip_pidf_validate(struct sip_request *req, struct ast_xml_doc **pidf_doc)
Makes sure that body is properly formatted PIDF.
Definition: chan_sip.c:28170
char device_name[1]
Definition: ccss.h:875
#define TRUE
Definition: app_minivm.c:518
const char * ast_xml_get_text(struct ast_xml_node *node)
Get an element content string.
Definition: xml.c:317
struct ast_xml_node * ast_xml_node_get_children(struct ast_xml_node *node)
Get the node&#39;s children.
Definition: xml.c:345
void ast_xml_free_text(const char *text)
Free a content element that was returned by ast_xml_get_text()
Definition: xml.c:229

◆ cc_handle_publish_error()

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

References ao2_callback, ao2_ref, ast_cc_monitor_failed(), ast_log, ast_strlen_zero, cc_epa_entry::core_id, sip_monitor_instance::device_name, sip_pvt::expiry, FALSE, find_sip_monitor_instance_by_suspension_entry(), sip_epa_entry::instance_data, LOG_WARNING, NULL, sip_get_header(), SIP_PUBLISH, and transmit_invite().

Referenced by sip_epa_unregister_all().

23871 {
23872  struct cc_epa_entry *cc_entry = epa_entry->instance_data;
23873  struct sip_monitor_instance *monitor_instance = ao2_callback(sip_monitor_instances, 0,
23875  const char *min_expires;
23876 
23877  if (!monitor_instance) {
23878  ast_log(LOG_WARNING, "Can't find monitor_instance corresponding to epa_entry %p.\n", epa_entry);
23879  return;
23880  }
23881 
23882  if (resp != 423) {
23883  ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->device_name,
23884  "Received error response to our PUBLISH");
23885  ao2_ref(monitor_instance, -1);
23886  return;
23887  }
23888 
23889  /* Allrighty, the other end doesn't like our Expires value. They think it's
23890  * too small, so let's see if they've provided a more sensible value. If they
23891  * haven't, then we'll just double our Expires value and see if they like that
23892  * instead.
23893  *
23894  * XXX Ideally this logic could be placed into its own function so that SUBSCRIBE,
23895  * PUBLISH, and REGISTER could all benefit from the same shared code.
23896  */
23897  min_expires = sip_get_header(req, "Min-Expires");
23898  if (ast_strlen_zero(min_expires)) {
23899  pvt->expiry *= 2;
23900  if (pvt->expiry < 0) {
23901  /* You dork! You overflowed! */
23902  ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->device_name,
23903  "PUBLISH expiry overflowed");
23904  ao2_ref(monitor_instance, -1);
23905  return;
23906  }
23907  } else if (sscanf(min_expires, "%30d", &pvt->expiry) != 1) {
23908  ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->device_name,
23909  "Min-Expires has non-numeric value");
23910  ao2_ref(monitor_instance, -1);
23911  return;
23912  }
23913  /* At this point, we have most certainly changed pvt->expiry, so try transmitting
23914  * again
23915  */
23917  ao2_ref(monitor_instance, -1);
23918 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
int ast_cc_monitor_failed(int core_id, const char *const monitor_name, const char *const debug,...)
Indicate that a failure has occurred on a specific monitor.
Definition: ccss.c:3941
#define FALSE
Definition: app_minivm.c:521
#define LOG_WARNING
Definition: logger.h:274
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.
Definition: chan_sip.c:14755
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
static int find_sip_monitor_instance_by_suspension_entry(void *obj, void *arg, int flags)
Definition: chan_sip.c:2081
struct ao2_container * sip_monitor_instances
Definition: chan_sip.c:1164
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
void * instance_data
Definition: sip.h:1680
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Definition: astobj2.h:464
int expiry
Definition: sip.h:1118
int core_id
Definition: sip.h:1694
Instance data for a Call completion EPA entry.
Definition: sip.h:1686
const ast_string_field device_name
Definition: sip.h:1819

◆ change_callid_pvt()

static void change_callid_pvt ( struct sip_pvt pvt,
const char *  callid 
)
static

Definition at line 8860 of file chan_sip.c.

References ao2_lock, ao2_t_link, ao2_unlock, ast_debug, ast_strdupa, ast_string_field_set, build_callid_pvt(), sip_pvt::callid, and CONTAINER_UNLINK.

Referenced by __sip_subscribe_mwi_do(), create_addr_from_peer(), manager_sipnotify(), sip_cli_notify(), sip_poke_peer(), sip_request_call(), and sip_send_mwi_to_peer().

8861 {
8862  int in_dialog_container;
8863  int in_rtp_container;
8864  char *oldid = ast_strdupa(pvt->callid);
8865 
8866  ao2_lock(dialogs);
8868  in_dialog_container = CONTAINER_UNLINK(dialogs, pvt,
8869  "About to change the callid -- remove the old name");
8870  in_rtp_container = CONTAINER_UNLINK(dialogs_rtpcheck, pvt,
8871  "About to change the callid -- remove the old name");
8872  if (callid) {
8873  ast_string_field_set(pvt, callid, callid);
8874  } else {
8875  build_callid_pvt(pvt);
8876  }
8877  if (in_dialog_container) {
8878  ao2_t_link(dialogs, pvt, "New dialog callid -- inserted back into table");
8879  }
8880  if (in_rtp_container) {
8881  ao2_t_link(dialogs_rtpcheck, pvt, "New dialog callid -- inserted back into table");
8882  }
8885 
8886  if (strcmp(oldid, pvt->callid)) {
8887  ast_debug(1, "SIP call-id changed from '%s' to '%s'\n", oldid, pvt->callid);
8888  }
8889 }
static struct ao2_container * dialogs
Definition: chan_sip.c:1043
#define ao2_t_link(container, obj, tag)
Add an object to a container.
Definition: astobj2.h:1547
#define CONTAINER_UNLINK(container, obj, tag)
Unlink the given object from the container and return TRUE if it was in the container.
Definition: chan_sip.c:8838
#define ao2_unlock(a)
Definition: astobj2.h:730
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ao2_lock(a)
Definition: astobj2.h:718
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
const ast_string_field callid
Definition: sip.h:1063
static void build_callid_pvt(struct sip_pvt *pvt)
Build SIP Call-ID value for a non-REGISTER transaction.
Definition: chan_sip.c:8829
struct ao2_container * dialogs_rtpcheck
Definition: chan_sip.c:1032
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ change_hold_state()

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

References append_history, ast_clear_flag, ast_set_flag, ast_str_buffer(), ast_test_flag, sip_request::data, sip_pvt::flags, sip_settings::notifyhold, sip_cfg, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_CALL_ONHOLD_ACTIVE, SIP_PAGE2_CALL_ONHOLD_INACTIVE, SIP_PAGE2_CALL_ONHOLD_ONEDIR, and sip_peer_hold().

Referenced by handle_request_invite(), and process_sdp().

10148 {
10149  if (sip_cfg.notifyhold && (!holdstate || !ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD))) {
10150  sip_peer_hold(dialog, holdstate);
10151  }
10152  append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", ast_str_buffer(req->data));
10153  if (!holdstate) { /* Put off remote hold */
10154  ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */
10155  return;
10156  }
10157  /* No address for RTP, we're on hold */
10158 
10159  /* Ensure hold flags are cleared so that overlapping flags do not conflict */
10161 
10162  if (sendonly == 1) /* One directional hold (sendonly/recvonly) */
10164  else if (sendonly == 2) /* Inactive stream */
10166  else
10168  return;
10169 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define SIP_PAGE2_CALL_ONHOLD_ONEDIR
Definition: sip.h:353
#define ast_set_flag(p, flag)
Definition: utils.h:70
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define SIP_PAGE2_CALL_ONHOLD_INACTIVE
Definition: sip.h:354
#define SIP_PAGE2_CALL_ONHOLD_ACTIVE
Definition: sip.h:352
#define SIP_PAGE2_CALL_ONHOLD
Definition: sip.h:351
struct ast_flags flags[3]
Definition: sip.h:1075
int notifyhold
Definition: sip.h:774
struct ast_str * data
Definition: sip.h:843
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
#define ast_clear_flag(p, flag)
Definition: utils.h:77
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406
static void sip_peer_hold(struct sip_pvt *p, int hold)
Change onhold state of a peer using a pvt structure.
Definition: chan_sip.c:17511

◆ change_redirecting_information()

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

References ast_debug, ast_free, AST_REDIRECTING_REASON_UNCONDITIONAL, ast_strdup, ast_strlen_zero, sip_pvt::cid_tag, ast_party_redirecting_reason::code, ast_party_redirecting::from, ast_set_party_redirecting::from, get_name_and_number(), get_rdnis(), sip_request::method, ast_party_id::name, ast_set_party_id::name, NULL, ast_party_id::number, ast_set_party_id::number, parse_moved_contact(), ast_party_redirecting::reason, sip_get_header(), sip_reason_code_to_str(), SIP_RESPONSE, ast_party_name::str, ast_party_number::str, ast_party_redirecting_reason::str, ast_party_id::tag, ast_party_redirecting::to, ast_set_party_redirecting::to, ast_party_name::valid, and ast_party_number::valid.

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

23531 {
23532  char *redirecting_from_name = NULL;
23533  char *redirecting_from_number = NULL;
23534  char *redirecting_to_name = NULL;
23535  char *redirecting_to_number = NULL;
23536  char *reason_str = NULL;
23538  int is_response = req->method == SIP_RESPONSE;
23539  int res = 0;
23540 
23541  res = get_rdnis(p, req, &redirecting_from_name, &redirecting_from_number, &reason, &reason_str);
23542  if (res == -1) {
23543  if (is_response) {
23544  get_name_and_number(sip_get_header(req, "TO"), &redirecting_from_name, &redirecting_from_number);
23545  } else {
23546  return;
23547  }
23548  }
23549 
23550  /* At this point, all redirecting "from" info should be filled in appropriately
23551  * on to the "to" info
23552  */
23553 
23554  if (is_response) {
23555  parse_moved_contact(p, req, &redirecting_to_name, &redirecting_to_number, set_call_forward);
23556  } else {
23557  get_name_and_number(sip_get_header(req, "TO"), &redirecting_to_name, &redirecting_to_number);
23558  }
23559 
23560  if (!ast_strlen_zero(redirecting_from_number)) {
23561  ast_debug(3, "Got redirecting from number %s\n", redirecting_from_number);
23562  update_redirecting->from.number = 1;
23563  redirecting->from.number.valid = 1;
23564  ast_free(redirecting->from.number.str);
23565  redirecting->from.number.str = redirecting_from_number;
23566  } else {
23567  ast_free(redirecting_from_number);
23568  }
23569  if (!ast_strlen_zero(redirecting_from_name)) {
23570  ast_debug(3, "Got redirecting from name %s\n", redirecting_from_name);
23571  update_redirecting->from.name = 1;
23572  redirecting->from.name.valid = 1;
23573  ast_free(redirecting->from.name.str);
23574  redirecting->from.name.str = redirecting_from_name;
23575  } else {
23576  ast_free(redirecting_from_name);
23577  }
23578  if (!ast_strlen_zero(p->cid_tag)) {
23579  ast_free(redirecting->from.tag);
23580  redirecting->from.tag = ast_strdup(p->cid_tag);
23581  ast_free(redirecting->to.tag);
23582  redirecting->to.tag = ast_strdup(p->cid_tag);
23583  }
23584  if (!ast_strlen_zero(redirecting_to_number)) {
23585  ast_debug(3, "Got redirecting to number %s\n", redirecting_to_number);
23586  update_redirecting->to.number = 1;
23587  redirecting->to.number.valid = 1;
23588  ast_free(redirecting->to.number.str);
23589  redirecting->to.number.str = redirecting_to_number;
23590  } else {
23591  ast_free(redirecting_to_number);
23592  }
23593  if (!ast_strlen_zero(redirecting_to_name)) {
23594  ast_debug(3, "Got redirecting to name %s\n", redirecting_to_name);
23595  update_redirecting->to.name = 1;
23596  redirecting->to.name.valid = 1;
23597  ast_free(redirecting->to.name.str);
23598  redirecting->to.name.str = redirecting_to_name;
23599  } else {
23600  ast_free(redirecting_to_name);
23601  }
23602  redirecting->reason.code = reason;
23603  ast_free(redirecting->reason.str);
23604  redirecting->reason.str = reason_str;
23605  if (reason_str) {
23606  ast_debug(3, "Got redirecting reason %s\n", ast_strlen_zero(reason_str)
23607  ? sip_reason_code_to_str(&redirecting->reason) : reason_str);
23608  }
23609 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
char * str
Subscriber phone number (Malloced)
Definition: channel.h:292
static const char * sip_reason_code_to_str(struct ast_party_redirecting_reason *reason)
Definition: chan_sip.c:2471
struct ast_party_name name
Subscriber name.
Definition: channel.h:341
static int get_rdnis(struct sip_pvt *p, struct sip_request *oreq, char **name, char **number, int *reason, char **reason_str)
Get referring dnis.
Definition: chan_sip.c:18394
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: channel.h:528
char * str
Subscriber name (Malloced)
Definition: channel.h:265
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.
Definition: chan_sip.c:23617
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
int code
enum AST_REDIRECTING_REASON value for redirection
Definition: channel.h:511
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ast_set_party_id from
Definition: channel.h:560
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
int get_name_and_number(const char *hdr, char **name, char **number)
Get name and number from sip header.
unsigned char number
Definition: channel.h:366
int method
Definition: sip.h:833
char * str
a string value for the redirecting reason
Definition: channel.h:508
#define ast_free(a)
Definition: astmm.h:182
struct ast_party_redirecting_reason reason
Reason for the redirection.
Definition: channel.h:543
char * tag
User-set "tag".
Definition: channel.h:355
struct ast_set_party_id to
Definition: channel.h:562
unsigned char name
Definition: channel.h:364
struct ast_party_id to
Call is redirecting to a new party (Sent to the caller)
Definition: channel.h:531
const ast_string_field cid_tag
Definition: sip.h:1063
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:280
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:298
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:343

◆ change_t38_state()

static void change_t38_state ( struct sip_pvt p,
int  state 
)
static

Change the T38 state on a SIP dialog.

Definition at line 5889 of file chan_sip.c.

References ast_channel_name(), 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, sip_pvt::owner, ast_control_t38_parameters::request_response, t38properties::state, invstate2stringtable::state, sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_LOCAL_REINVITE, T38_PEER_REINVITE, T38_REJECTED, t38properties::their_parms, and sip_pvt::udptl.

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

5890 {
5891  int old = p->t38.state;
5892  struct ast_channel *chan = p->owner;
5893  struct ast_control_t38_parameters parameters = { .request_response = 0 };
5894 
5895  /* Don't bother changing if we are already in the state wanted */
5896  if (old == state)
5897  return;
5898 
5899  p->t38.state = state;
5900  ast_debug(2, "T38 state changed to %u on channel %s\n", p->t38.state, chan ? ast_channel_name(chan) : "<none>");
5901 
5902  /* If no channel was provided we can't send off a control frame */
5903  if (!chan)
5904  return;
5905 
5906  /* Given the state requested and old state determine what control frame we want to queue up */
5907  switch (state) {
5908  case T38_PEER_REINVITE:
5909  parameters = p->t38.their_parms;
5910  parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
5912  ast_udptl_set_tag(p->udptl, "%s", ast_channel_name(chan));
5913  break;
5914  case T38_ENABLED:
5915  parameters = p->t38.their_parms;
5916  parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
5917  parameters.request_response = AST_T38_NEGOTIATED;
5918  ast_udptl_set_tag(p->udptl, "%s", ast_channel_name(chan));
5919  break;
5920  case T38_REJECTED:
5921  case T38_DISABLED:
5922  if (old == T38_ENABLED) {
5923  parameters.request_response = AST_T38_TERMINATED;
5924  } else if (old == T38_LOCAL_REINVITE) {
5925  parameters.request_response = AST_T38_REFUSED;
5926  }
5927  break;
5928  case T38_LOCAL_REINVITE:
5929  /* wait until we get a peer response before responding to local reinvite */
5930  break;
5931  }
5932 
5933  /* Woot we got a message, create a control frame and send it on! */
5934  if (parameters.request_response)
5935  ast_queue_control_data(chan, AST_CONTROL_T38_PARAMETERS, &parameters, sizeof(parameters));
5936 }
enum sip_cc_notify_state state
Definition: chan_sip.c:959
#define T38_ENABLED
Definition: chan_ooh323.c:102
Main Channel structure associated with a channel.
enum t38state state
Definition: sip.h:917
enum ast_control_t38 request_response
struct t38properties t38
Definition: sip.h:1113
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct ast_udptl * udptl
Definition: sip.h:1115
unsigned int ast_udptl_get_far_max_ifp(struct ast_udptl *udptl)
retrieves far max ifp
Definition: udptl.c:1016
#define T38_DISABLED
Definition: chan_ooh323.c:101
struct ast_control_t38_parameters their_parms
Definition: sip.h:919
struct ast_channel * owner
Definition: sip.h:1138
const char * ast_channel_name(const struct ast_channel *chan)
int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen)
Queue a control frame with payload.
Definition: channel.c:1238
void ast_udptl_set_tag(struct ast_udptl *udptl, const char *format,...)
Associates a character string &#39;tag&#39; with a UDPTL session.
Definition: udptl.c:1112

◆ check_auth()

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 
)
static

Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set)

Returns
0 on success, non-zero on error

XXX

Todo:
need a better return code here

XXX

Todo:
need a better return code here

Definition at line 17341 of file chan_sip.c.

References append_history, ast_copy_string(), AST_DYNSTR_BUILD_FAILED, ast_log, ast_md5_hash(), ast_str_buffer(), ast_str_set(), ast_str_thread_get(), ast_strlen_zero, AUTH_CHALLENGE_SENT, AUTH_SECRET_FAILED, AUTH_SUCCESSFUL, AUTH_USERNAME_MISMATCH, BOGUS_PEER_MD5SECRET, buf, build_nonce(), c, check_auth_buf, CHECK_AUTH_BUF_INITLEN, DEFAULT_TRANS_TIMEOUT, FALSE, sip_request::ignore, K_LAST, K_NONCE, K_RESP, K_URI, K_USER, LOG_NOTICE, LOG_WARNING, sip_pvt::nonce, NULL, sip_pvt::realm, digestkeys::s, S_OR, sip_auth_headers(), sip_digest_parser(), sip_get_header(), sip_methods, sip_scheddestroy(), sipdebug, sip_pvt::stalenonce, text, transmit_response_with_auth(), TRUE, and WWW_AUTH.

Referenced by check_peer_ok(), and register_verify().

17344 {
17345  const char *response;
17346  char *reqheader, *respheader;
17347  const char *authtoken;
17348  char a1_hash[256];
17349  char resp_hash[256]="";
17350  char *c;
17351  int is_bogus_peer = 0;
17352  int wrongnonce = FALSE;
17353  int good_response;
17354  const char *usednonce = p->nonce;
17355  struct ast_str *buf;
17356  int res;
17357 
17358  /* table of recognised keywords, and their value in the digest */
17359  struct digestkeys keys[] = {
17360  [K_RESP] = { "response=", "" },
17361  [K_URI] = { "uri=", "" },
17362  [K_USER] = { "username=", "" },
17363  [K_NONCE] = { "nonce=", "" },
17364  [K_LAST] = { NULL, NULL}
17365  };
17366 
17367  /* Always OK if no secret */
17368  if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret)) {
17369  return AUTH_SUCCESSFUL;
17370  }
17371 
17372  /* Always auth with WWW-auth since we're NOT a proxy */
17373  /* Using proxy-auth in a B2BUA may block proxy authorization in the same transaction */
17374  response = "401 Unauthorized";
17375 
17376  /*
17377  * Note the apparent swap of arguments below, compared to other
17378  * usages of sip_auth_headers().
17379  */
17380  sip_auth_headers(WWW_AUTH, &respheader, &reqheader);
17381 
17382  authtoken = sip_get_header(req, reqheader);
17383  if (req->ignore && !ast_strlen_zero(p->nonce) && ast_strlen_zero(authtoken)) {
17384  /* This is a retransmitted invite/register/etc, don't reconstruct authentication
17385  information */
17386  if (!reliable) {
17387  /* Resend message if this was NOT a reliable delivery. Otherwise the
17388  retransmission should get it */
17389  transmit_response_with_auth(p, response, req, p->nonce, reliable, respheader, 0);
17390  /* Schedule auto destroy in 32 seconds (according to RFC 3261) */
17392  }
17393  return AUTH_CHALLENGE_SENT;
17394  } else if (ast_strlen_zero(p->nonce) || ast_strlen_zero(authtoken)) {
17395  /* We have no auth, so issue challenge and request authentication */
17396  build_nonce(p, 1); /* Create nonce for challenge */
17397  transmit_response_with_auth(p, response, req, p->nonce, reliable, respheader, 0);
17398  /* Schedule auto destroy in 32 seconds */
17400  return AUTH_CHALLENGE_SENT;
17401  }
17402 
17403  /* --- We have auth, so check it */
17404 
17405  /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting
17406  an example in the spec of just what it is you're doing a hash on. */
17407 
17409  return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */
17410  }
17411 
17412  /* Make a copy of the response and parse it */
17413  res = ast_str_set(&buf, 0, "%s", authtoken);
17414 
17415  if (res == AST_DYNSTR_BUILD_FAILED) {
17416  return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */
17417  }
17418 
17419  c = ast_str_buffer(buf);
17420 
17421  sip_digest_parser(c, keys);
17422 
17423  /* We cannot rely on the bogus_peer having a bad md5 value. Someone could
17424  * use it to construct valid auth. */
17425  if (md5secret && strcmp(md5secret, BOGUS_PEER_MD5SECRET) == 0) {
17426  is_bogus_peer = 1;
17427  }
17428 
17429  /* Verify that digest username matches the username we auth as */
17430  if (strcmp(username, keys[K_USER].s) && !is_bogus_peer) {
17431  ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n",
17432  username, keys[K_USER].s);
17433  /* Oops, we're trying something here */
17434  return AUTH_USERNAME_MISMATCH;
17435  }
17436 
17437  /* Verify nonce from request matches our nonce, and the nonce has not already been responded to.
17438  * If this check fails, send 401 with new nonce */
17439  if (strcasecmp(p->nonce, keys[K_NONCE].s) || p->stalenonce) { /* XXX it was 'n'casecmp ? */
17440  wrongnonce = TRUE;
17441  usednonce = keys[K_NONCE].s;
17442  } else {
17443  p->stalenonce = 1; /* now, since the nonce has a response, mark it as stale so it can't be sent or responded to again */
17444  }
17445 
17446  if (!ast_strlen_zero(md5secret)) {
17447  ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
17448  } else {
17449  char a1[256];
17450 
17451  snprintf(a1, sizeof(a1), "%s:%s:%s", username, p->realm, secret);
17452  ast_md5_hash(a1_hash, a1);
17453  }
17454 
17455  /* compute the expected response to compare with what we received */
17456  {
17457  char a2[256];
17458  char a2_hash[256];
17459  char resp[256];
17460 
17461  snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text,
17462  S_OR(keys[K_URI].s, uri));
17463  ast_md5_hash(a2_hash, a2);
17464  snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash);
17465  ast_md5_hash(resp_hash, resp);
17466  }
17467 
17468  good_response = keys[K_RESP].s &&
17469  !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash)) &&
17470  !is_bogus_peer; /* lastly, check that the peer isn't the fake peer */
17471  if (wrongnonce) {
17472  if (good_response) {
17473  if (sipdebug)
17474  ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", sip_get_header(req, "From"));
17475  /* We got working auth token, based on stale nonce . */
17476  build_nonce(p, 0);
17477  transmit_response_with_auth(p, response, req, p->nonce, reliable, respheader, TRUE);
17478  } else {
17479  /* Everything was wrong, so give the device one more try with a new challenge */
17480  if (!req->ignore) {
17481  if (sipdebug) {
17482  ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", sip_get_header(req, "To"));
17483  }
17484  build_nonce(p, 1);
17485  } else {
17486  if (sipdebug) {
17487  ast_log(LOG_NOTICE, "Duplicate authentication received from '%s'\n", sip_get_header(req, "To"));
17488  }
17489  }
17490  transmit_response_with_auth(p, response, req, p->nonce, reliable, respheader, FALSE);
17491  }
17492 
17493  /* Schedule auto destroy in 32 seconds */
17495  return AUTH_CHALLENGE_SENT;
17496  }
17497  if (good_response) {
17498  append_history(p, "AuthOK", "Auth challenge successful for %s", username);
17499  return AUTH_SUCCESSFUL;
17500  }
17501 
17502  /* Ok, we have a bad username/secret pair */
17503  /* Tell the UAS not to re-send this authentication data, because
17504  it will continue to fail
17505  */
17506 
17507  return AUTH_SECRET_FAILED;
17508 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
Definition: sip.h:703
#define FALSE
Definition: app_minivm.c:521
const ast_string_field realm
Definition: sip.h:1063
void sip_auth_headers(enum sip_auth_type code, char **header, char **respheader)
return the request and response header for a 401 or 407 code
Definition: chan_sip.c:16549
static const struct cfsip_methods sip_methods[]
static struct ast_threadstorage check_auth_buf
Definition: sip.h:1883
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define DEFAULT_TRANS_TIMEOUT
Definition: sip.h:107
#define BOGUS_PEER_MD5SECRET
We can recognize the bogus peer by this invalid MD5 hash.
Definition: chan_sip.c:1058
static struct test_val c
char * text
Definition: app_queue.c:1508
#define NULL
Definition: resample.c:96
const ast_string_field nonce
Definition: sip.h:1063
#define ast_strlen_zero(foo)
Definition: strings.h:52
unsigned int stalenonce
Definition: sip.h:1143
void sip_digest_parser(char *c, struct digestkeys *keys)
Takes the digest response and parses it.
Definition: chan_sip.c:17309
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
#define ast_log
Definition: astobj2.c:42
sipmethod
SIP Request methods known by Asterisk.
Definition: sip.h:612
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
Definition: sip.h:707
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
#define LOG_NOTICE
Definition: logger.h:263
Definition: sip.h:705
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)
Respond with authorization request.
Definition: chan_sip.c:12754
Definition: sip.h:504
const char * s
Definition: sip.h:1880
static void build_nonce(struct sip_pvt *p, int forceupdate)
builds the sip_pvt&#39;s nonce field which is used for the authentication challenge. When forceupdate is ...
Definition: chan_sip.c:17300
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
#define TRUE
Definition: app_minivm.c:518
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406
char ignore
Definition: sip.h:839
Definition: sip.h:704
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
Definition: strings.h:861
void ast_md5_hash(char *output, const char *input)
Produces MD5 hash based on input string.
Definition: main/utils.c:248
#define CHECK_AUTH_BUF_INITLEN
Definition: sip.h:401
void sip_scheddestroy(struct sip_pvt *p, int ms)
Schedule destruction of SIP dialog.
Definition: chan_sip.c:4549
Definition: sip.h:706

◆ check_for_nat()

static void check_for_nat ( const struct ast_sockaddr addr,
struct sip_pvt p 
)
static

Check and see if the requesting UA is likely to be behind a NAT.

If the requesting NAT is behind NAT, set the * natdetected flag so that later, peers with nat=auto_* can use the value. Also, set the flags so that Asterisk responds identically whether or not a peer exists so as not to leak peer name information.

Definition at line 19134 of file chan_sip.c.

References ast_clear_flag, ast_debug, ast_set_flag, ast_sockaddr_cmp_addr(), ast_sockaddr_stringify_addr(), ast_strdupa, ast_test_flag, sip_pvt::flags, sip_pvt::natdetected, sip_pvt::recv, SIP_NAT_FORCE_RPORT, SIP_PAGE2_SYMMETRICRTP, SIP_PAGE3_NAT_AUTO_COMEDIA, and SIP_PAGE3_NAT_AUTO_RPORT.

Referenced by check_via(), and sip_request_call().

19135 {
19136 
19137  if (!addr || !p) {
19138  return;
19139  }
19140 
19141  if (ast_sockaddr_cmp_addr(addr, &p->recv)) {
19142  char *tmp_str = ast_strdupa(ast_sockaddr_stringify_addr(addr));
19143  ast_debug(3, "NAT detected for %s / %s\n", tmp_str, ast_sockaddr_stringify_addr(&p->recv));
19144  p->natdetected = 1;
19147  }
19150  }
19151  } else {
19152  p->natdetected = 0;
19155  }
19158  }
19159  }
19160 
19161 }
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:290
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ast_set_flag(p, flag)
Definition: utils.h:70
struct ast_sockaddr recv
Definition: sip.h:1135
#define SIP_NAT_FORCE_RPORT
Definition: sip.h:283
struct ast_flags flags[3]
Definition: sip.h:1075
int ast_sockaddr_cmp_addr(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares the addresses of two ast_sockaddr structures.
Definition: netsock2.c:413
#define SIP_PAGE2_SYMMETRICRTP
Definition: sip.h:327
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define SIP_PAGE3_NAT_AUTO_RPORT
Definition: sip.h:386
#define ast_clear_flag(p, flag)
Definition: utils.h:77
#define SIP_PAGE3_NAT_AUTO_COMEDIA
Definition: sip.h:387
unsigned short natdetected
Definition: sip.h:1094

◆ check_message_integrity()

static enum message_integrity check_message_integrity ( struct ast_str **  request,
struct ast_str **  overflow 
)
static

Check that a message received over TCP is a full message.

This will take the information read in and then determine if 1) The message is a full SIP request 2) The message is a partial SIP request 3) The message contains a full SIP request along with another partial request

Parameters
dataThe unparsed incoming SIP message.
requestThe resulting request with extra fragments removed.
overflowIf the message contains more than a full request, this is the remainder of the message
Returns
The resulting integrity of the message

Definition at line 2849 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 mock_tcp_loop(), and sip_tcptls_read().

2850 {
2851  char *message = ast_str_buffer(*request);
2852  char *body;
2853  int content_length;
2854  int message_len = ast_str_strlen(*request);
2855  int body_len;
2856 
2857  /* Important pieces to search for in a SIP request are \r\n\r\n. This
2858  * marks either
2859  * 1) The division between the headers and body
2860  * 2) The end of the SIP request
2861  */
2862  body = strstr(message, "\r\n\r\n");
2863  if (!body) {
2864  /* This is clearly a partial message since we haven't reached an end
2865  * yet.
2866  */
2867  return MESSAGE_FRAGMENT;
2868  }
2869  body += sizeof("\r\n\r\n") - 1;
2870  body_len = message_len - (body - message);
2871 
2872  body[-1] = '\0';
2873  content_length = read_raw_content_length(message);
2874  body[-1] = '\n';
2875 
2876  if (content_length < 0) {
2877  return MESSAGE_INVALID;
2878  } else if (content_length == 0) {
2879  /* We've definitely received an entire message. We need
2880  * to check if there's also a fragment of another message
2881  * in addition.
2882  */
2883  if (body_len == 0) {
2884  return MESSAGE_COMPLETE;
2885  } else {
2886  ast_str_append(overflow, 0, "%s", body);
2887  ast_str_truncate(*request, message_len - body_len);
2889  }
2890  }
2891  /* Positive content length. Let's see what sort of
2892  * message body we're dealing with.
2893  */
2894  if (body_len < content_length) {
2895  /* We don't have the full message body yet */
2896  return MESSAGE_FRAGMENT;
2897  } else if (body_len > content_length) {
2898  /* We have the full message plus a fragment of a further
2899  * message
2900  */
2901  ast_str_append(overflow, 0, "%s", body + content_length);
2902  ast_str_truncate(*request, message_len - (body_len - content_length));
2904  } else {
2905  /* Yay! Full message with no extra content */
2906  return MESSAGE_COMPLETE;
2907  }
2908 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
char * ast_str_truncate(struct ast_str *buf, ssize_t len)
Truncates the enclosed string to the given length.
Definition: strings.h:738
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
static int read_raw_content_length(const char *message)
Get the content length from an unparsed SIP message.
Definition: chan_sip.c:2789

◆ check_peer_ok()

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

References accountcode, sip_peer::accountcode, sip_peer::acl, sip_peer::addr, sip_settings::allowguest, sip_pvt::allowtransfer, sip_peer::allowtransfer, sip_settings::alwaysauthreject, sip_pvt::amaflags, sip_peer::amaflags, ao2_ref, ao2_t_global_obj_ref, ao2_t_ref, ast_apply_acl(), ast_cc_copy_config_params(), ast_copy_flags, ast_copy_string(), ast_debug, ast_format_cap_alloc, ast_format_cap_append_from_cap(), ast_format_cap_count(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_get_compatible(), ast_format_cap_get_framing(), ast_format_cap_remove_by_type(), ast_is_shrinkable_phonenumber(), AST_MEDIA_TYPE_UNKNOWN, ast_ref_namedgroups(), ast_rtp_codecs_set_framing(), ast_rtp_dtls_cfg_copy(), AST_RTP_DTMF, ast_rtp_instance_get_codecs(), ast_set_flag, ast_shrink_phone_number(), ast_sockaddr_copy(), ast_sockaddr_stringify(), ast_strdupa, ast_string_field_set, ast_strlen_zero, ast_test_flag, ast_unref_namedgroups(), ast_variables_destroy(), ast_verbose(), AUTH_ACL_FAILED, AUTH_DONT_KNOW, AUTH_RTP_FAILED, sip_pvt::autoframing, sip_peer::autoframing, sip_peer::call_limit, sip_pvt::callgroup, sip_peer::callgroup, sip_pvt::callingpres, sip_peer::callingpres, sip_pvt::caps, sip_peer::caps, sip_pvt::cc_params, sip_peer::cc_params, sip_pvt::chanvars, sip_peer::chanvars, check_auth(), cid_name, sip_peer::cid_name, cid_num, sip_peer::cid_num, sip_peer::cid_tag, context, sip_peer::context, copy_vars(), debug, dialog_initialize_rtp(), sip_pvt::disallowed_methods, sip_peer::disallowed_methods, do_setnat(), sip_pvt::dtls_cfg, sip_peer::dtls_cfg, dummy(), sip_peer::engine, FALSE, FINDALLDEVICES, FINDPEERS, FINDUSERS, sip_pvt::flags, sip_peer::flags, sip_peer::fullcontact, get_rpid(), global_shrinkcallerid, global_t1min, sip_pvt::jointcaps, sip_pvt::jointnoncodeccapability, language, sip_peer::language, sip_peer::lastms, sip_pvt::maxcallbitrate, sip_peer::maxcallbitrate, sip_pvt::maxforwards, sip_peer::maxforwards, sip_peer::maxms, sip_peer::md5secret, sip_peer::messagecontext, mohinterpret, sip_peer::mohinterpret, mohsuggest, sip_peer::mohsuggest, sip_peer::mwi_from, sip_peer::name, sip_pvt::named_callgroups, sip_peer::named_callgroups, sip_pvt::named_pickupgroups, sip_peer::named_pickupgroups, sip_pvt::natdetected, sip_pvt::noncodeccapability, NULL, parkinglot, sip_peer::parkinglot, parse_uri(), sip_pvt::peercaps, sip_pvt::peermd5secret, sip_monitor_instance::peername, sip_pvt::peersecret, sip_pvt::pickupgroup, sip_peer::pickupgroup, sip_pvt::recv, sip_pvt::rtp, sip_pvt::rtpholdtimeout, sip_peer::rtpholdtimeout, sip_pvt::rtpkeepalive, sip_peer::rtpkeepalive, sip_pvt::rtptimeout, sip_peer::rtptimeout, sip_peer::secret, set_peer_nat(), set_pvt_allowed_methods(), set_t38_capabilities(), SIP_CALL_LIMIT, sip_cfg, sip_debug_test_addr(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, sip_find_peer(), sip_find_peer_by_ip_and_exten(), SIP_FLAGS_TO_COPY, SIP_INSECURE_INVITE, SIP_INVITE, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_T38SUPPORT, SIP_PAGE3_FLAGS_TO_COPY, SIP_PAGE3_NAT_AUTO_RPORT, SIP_SUBSCRIBE, sip_unref_peer, sip_pvt::sipoptions, sip_peer::sipoptions, sip_pvt::socket, sip_peer::subscribecontext, sip_pvt::t38_maxdatagram, sip_peer::t38_maxdatagram, sip_pvt::timer_b, sip_peer::timer_b, sip_pvt::timer_t1, sip_peer::timer_t1, tmp(), TRUE, sip_socket::type, sip_pvt::udptl, sip_peer::username, sip_pvt::zone, and sip_peer::zone.

Referenced by check_user_full().

19241 {
19242  enum check_auth_result res;
19243  int debug = sip_debug_test_addr(addr);
19244  struct sip_peer *peer;
19245  struct sip_peer *bogus_peer;
19246 
19247  if (sipmethod == SIP_SUBSCRIBE) {
19248  /* For subscribes, match on device name only; for other methods,
19249  * match on IP address-port of the incoming request.
19250  */
19251  peer = sip_find_peer(of, NULL, TRUE, FINDALLDEVICES, FALSE, 0);
19252  } else {
19253  /* First find devices based on username (avoid all type=peer's) */
19254  peer = sip_find_peer(of, NULL, TRUE, FINDUSERS, FALSE, 0);
19255 
19256  /* Then find devices based on IP */
19257  if (!peer) {
19258  char *uri_tmp, *callback = NULL, *dummy;
19259  uri_tmp = ast_strdupa(uri2);
19260  parse_uri(uri_tmp, "sip:,sips:,tel:", &callback, &dummy, &dummy, &dummy);
19261  if (!ast_strlen_zero(callback) && (peer = sip_find_peer_by_ip_and_exten(&p->recv, callback, p->socket.type))) {
19262  ; /* found, fall through */
19263  } else {
19264  peer = sip_find_peer(NULL, &p->recv, TRUE, FINDPEERS, FALSE, p->socket.type);
19265  }
19266  }
19267  }
19268 
19269  if (!peer) {
19270  if (debug) {
19271  ast_verbose("No matching peer for '%s' from '%s'\n",
19272  of, ast_sockaddr_stringify(&p->recv));
19273  }
19274 
19275  /* If you don't mind, we can return 404s for devices that do
19276  * not exist: username disclosure. If we allow guests, there
19277  * is no way around that. */
19279  return AUTH_DONT_KNOW;
19280  }
19281 
19282  /* If you do mind, we use a peer that will never authenticate.
19283  * This ensures that we follow the same code path as regular
19284  * auth: less chance for username disclosure. */
19285  peer = ao2_t_global_obj_ref(g_bogus_peer, "check_peer_ok: Get the bogus peer.");
19286  if (!peer) {
19287  return AUTH_DONT_KNOW;
19288  }
19289  bogus_peer = peer;
19290  } else {
19291  bogus_peer = NULL;
19292  }
19293 
19294  if (!ast_apply_acl(peer->acl, addr, "SIP Peer ACL: ")) {
19295  ast_debug(2, "Found peer '%s' for '%s', but fails host access\n", peer->name, of);
19296  sip_unref_peer(peer, "sip_unref_peer: check_peer_ok: from sip_find_peer call, early return of AUTH_ACL_FAILED");
19297  return AUTH_ACL_FAILED;
19298  }
19299  if (debug && peer != bogus_peer) {
19300  ast_verbose("Found peer '%s' for '%s' from %s\n",
19301  peer->name, of, ast_sockaddr_stringify(&p->recv));
19302  }
19303 
19304  /* Set Frame packetization */
19305  if (p->rtp) {
19307  p->autoframing = peer->autoframing;
19308  }
19309 
19310  /* Take the peer */
19311  ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
19312  ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
19313  ast_copy_flags(&p->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY);
19314 
19315  if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) && p->udptl) {
19316  p->t38_maxdatagram = peer->t38_maxdatagram;
19318  }
19319 
19321 
19322  /* Copy SIP extensions profile to peer */
19323  /* XXX is this correct before a successful auth ? */
19324  if (p->sipoptions)
19325  peer->sipoptions = p->sipoptions;
19326 
19327  do_setnat(p);
19328 
19329  ast_string_field_set(p, peersecret, peer->secret);
19330  ast_string_field_set(p, peermd5secret, peer->md5secret);
19334  if (!ast_strlen_zero(peer->parkinglot)) {
19336  }
19337  ast_string_field_set(p, engine, peer->engine);
19339  set_pvt_allowed_methods(p, req);
19341  if (peer->callingpres) /* Peer calling pres setting will override RPID */
19342  p->callingpres = peer->callingpres;
19343  if (peer->maxms && peer->lastms)
19344  p->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms;
19345  else
19346  p->timer_t1 = peer->timer_t1;
19347 
19348  /* Set timer B to control transaction timeouts */
19349  if (peer->timer_b)
19350  p->timer_b = peer->timer_b;
19351  else
19352  p->timer_b = 64 * p->timer_t1;
19353 
19354  p->allowtransfer = peer->allowtransfer;
19355 
19356  if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) {
19357  /* Pretend there is no required authentication */
19358  ast_string_field_set(p, peersecret, NULL);
19359  ast_string_field_set(p, peermd5secret, NULL);
19360  }
19361  if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable))) {
19362 
19363  /* build_peer, called through sip_find_peer, is not able to check the
19364  * sip_pvt->natdetected flag in order to determine if the peer is behind
19365  * NAT or not when SIP_PAGE3_NAT_AUTO_RPORT or SIP_PAGE3_NAT_AUTO_COMEDIA
19366  * are set on the peer. So we check for that here and set the peer's
19367  * address accordingly. The address should ONLY be set once we are sure
19368  * authentication was a success. If, for example, an INVITE was sent that
19369  * matched the peer name but failed the authentication check, the address
19370  * would be updated, which is bad.
19371  */
19372  set_peer_nat(p, peer);
19373  if (p->natdetected && ast_test_flag(&peer->flags[2], SIP_PAGE3_NAT_AUTO_RPORT)) {
19374  ast_sockaddr_copy(&peer->addr, &p->recv);
19375  }
19376 
19377  /* If we have a call limit, set flag */
19378  if (peer->call_limit)
19380  ast_string_field_set(p, peername, peer->name);
19381  ast_string_field_set(p, authname, peer->name);
19382 
19384 
19385  if (sipmethod == SIP_INVITE) {
19386  /* destroy old channel vars and copy in new ones. */
19388  p->chanvars = copy_vars(peer->chanvars);
19389  }
19390 
19391  if (authpeer) {
19392  ao2_t_ref(peer, 1, "copy pointer into (*authpeer)");
19393  (*authpeer) = peer; /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */
19394  }
19395 
19396  if (!ast_strlen_zero(peer->username)) {
19398  /* Use the default username for authentication on outbound calls */
19399  /* XXX this takes the name from the caller... can we override ? */
19400  ast_string_field_set(p, authname, peer->username);
19401  }
19402  if (!get_rpid(p, req)) {
19403  if (!ast_strlen_zero(peer->cid_num)) {
19404  char *tmp = ast_strdupa(peer->cid_num);
19407  ast_string_field_set(p, cid_num, tmp);
19408  }
19409  if (!ast_strlen_zero(peer->cid_name))
19411  if (peer->callingpres)
19412  p->callingpres = peer->callingpres;
19413  }
19414  if (!ast_strlen_zero(peer->cid_tag)) {
19416  }
19418  if (!ast_strlen_zero(peer->context)) {
19420  }
19421  if (!ast_strlen_zero(peer->messagecontext)) {
19423  }
19424  if (!ast_strlen_zero(peer->mwi_from)) {
19426  }
19427  ast_string_field_set(p, peersecret, peer->secret);
19428  ast_string_field_set(p, peermd5secret, peer->md5secret);
19431  p->amaflags = peer->amaflags;
19432  p->callgroup = peer->callgroup;
19433  p->pickupgroup = peer->pickupgroup;
19442  ast_copy_string(p->zone, peer->zone, sizeof(p->zone));
19443  if (peer->maxforwards > 0) {
19444  p->maxforwards = peer->maxforwards;
19445  }
19446  if (ast_format_cap_count(p->peercaps)) {
19447  struct ast_format_cap *joint;
19448 
19450  if (joint) {
19452  ao2_ref(p->jointcaps, -1);
19453  p->jointcaps = joint;
19454  }
19455  }
19456  p->maxcallbitrate = peer->maxcallbitrate;
19457  if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
19458  (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
19460  else
19463  p->rtptimeout = peer->rtptimeout;
19464  p->rtpholdtimeout = peer->rtpholdtimeout;
19465  p->rtpkeepalive = peer->rtpkeepalive;
19466  if (!dialog_initialize_rtp(p)) {
19467  if (p->rtp) {
19469  p->autoframing = peer->autoframing;
19470  }
19471  } else {
19472  res = AUTH_RTP_FAILED;
19473  }
19474  }
19475  sip_unref_peer(peer, "check_peer_ok: sip_unref_peer: tossing temp ptr to peer from sip_find_peer");
19476 
19477  return res;
19478 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
struct ast_format_cap * peercaps
Definition: sip.h:1101
static int global_shrinkcallerid
Definition: chan_sip.c:829
static char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: chan_iax2.c:428
struct ast_cc_config_params * cc_params
Definition: sip.h:1218
static char mohinterpret[MAX_MUSICCLASS]
Definition: chan_alsa.c:119
struct ast_namedgroups * named_pickupgroups
Definition: sip.h:1349
struct ast_sockaddr addr
Definition: sip.h:1352
int maxms
Definition: sip.h:1357
int timer_t1
Definition: sip.h:1369
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 fou...
Definition: chan_sip.c:18266
#define FALSE
Definition: app_minivm.c:521
unsigned int ast_format_cap_get_framing(const struct ast_format_cap *cap)
Get the global framing.
Definition: format_cap.c:438
static char parkinglot[AST_MAX_CONTEXT]
Definition: chan_mgcp.c:163
int rtpholdtimeout
Definition: sip.h:1132
struct sip_peer * sip_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.
Definition: chan_sip.c:5851
ast_group_t callgroup
Definition: sip.h:1070
const ast_string_field language
Definition: sip.h:1306
const ast_string_field parkinglot
Definition: sip.h:1306
const ast_string_field mohsuggest
Definition: sip.h:1306
const ast_string_field mwi_from
Definition: sip.h:1306
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
int maxcallbitrate
Definition: sip.h:1106
int t38_maxdatagram
Definition: sip.h:1107
struct ast_rtp_dtls_cfg dtls_cfg
Definition: sip.h:1381
#define ast_test_flag(p, flag)
Definition: utils.h:63
int rtpholdtimeout
Definition: sip.h:1344
const ast_string_field messagecontext
Definition: sip.h:1306
int amaflags
Definition: sip.h:1146
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:171
static int global_t1min
Definition: chan_sip.c:848
const ast_string_field accountcode
Definition: sip.h:1306
#define ast_set_flag(p, flag)
Definition: utils.h:70
struct ast_rtp_codecs * ast_rtp_instance_get_codecs(struct ast_rtp_instance *instance)
Get the codecs structure of an RTP instance.
Definition: rtp_engine.c:727
static int debug
Global debug status.
Definition: res_xmpp.c:435
static void dummy(char *unused,...)
Definition: chan_unistim.c:220
struct ast_sockaddr recv
Definition: sip.h:1135
struct sip_socket socket
Definition: sip.h:1066
struct ast_namedgroups * named_pickupgroups
Definition: sip.h:1073
static int tmp()
Definition: bt_open.c:389
static int sip_debug_test_addr(const struct ast_sockaddr *addr)
See if we pass debug IP filter.
Definition: chan_sip.c:3610
#define SIP_DTMF_RFC2833
Definition: sip.h:276
int maxforwards
Definition: sip.h:1331
struct ast_namedgroups * named_callgroups
Definition: sip.h:1072
check_auth_result
Authentication result from check_auth* functions.
Definition: sip.h:517
#define SIP_CALL_LIMIT
Definition: sip.h:264
struct ast_format_cap * jointcaps
Definition: sip.h:1100
int rtpkeepalive
Definition: sip.h:1133
size_t ast_format_cap_count(const struct ast_format_cap *cap)
Get the number of formats present within the capabilities structure.
Definition: format_cap.c:395
struct ast_flags flags[3]
Definition: sip.h:1075
#define ast_copy_flags(dest, src, flagz)
Definition: utils.h:84
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
const ast_string_field peermd5secret
Definition: sip.h:1063
void ast_rtp_codecs_set_framing(struct ast_rtp_codecs *codecs, unsigned int framing)
Set the framing used for a set of codecs.
Definition: rtp_engine.c:1558
const ast_string_field subscribecontext
Definition: sip.h:1306
#define NULL
Definition: resample.c:96
int ast_is_shrinkable_phonenumber(const char *exten)
Check if a string consists only of digits and + # ( ) - . (meaning it can be cleaned with ast_shrink_...
Definition: callerid.c:1003
static char cid_num[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:164
int jointnoncodeccapability
Definition: sip.h:1105
char name[80]
Definition: sip.h:1274
struct ast_variable * chanvars
Definition: sip.h:1366
#define ast_strlen_zero(foo)
Definition: strings.h:52
int rtptimeout
Definition: sip.h:1343
char zone[MAX_TONEZONE_COUNTRY]
Definition: sip.h:1116
enum transfermodes allowtransfer
Definition: sip.h:1332
struct ast_rtp_dtls_cfg dtls_cfg
Definition: sip.h:1222
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
int lastms
Definition: sip.h:1356
struct ast_namedgroups * named_callgroups
Definition: sip.h:1348
int noncodeccapability
Definition: sip.h:1104
struct ast_acl_list * acl
Definition: sip.h:1363
int amaflags
Definition: sip.h:1323
int rtptimeout
Definition: sip.h:1131
const ast_string_field peersecret
Definition: sip.h:1063
static int dialog_initialize_rtp(struct sip_pvt *dialog)
Initialize RTP portion of a dialog.
Definition: chan_sip.c:6041
struct ast_format_cap * caps
Definition: sip.h:1099
static char mohsuggest[MAX_MUSICCLASS]
Definition: chan_iax2.c:430
int call_limit
Definition: sip.h:1328
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
const ast_string_field username
Definition: sip.h:1306
#define SIP_PAGE3_FLAGS_TO_COPY
Definition: sip.h:396
unsigned short autoframing
Definition: sip.h:1089
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
int maxforwards
Definition: sip.h:1065
int maxcallbitrate
Definition: sip.h:1340
const ast_string_field md5secret
Definition: sip.h:1306
int timer_b
Definition: sip.h:1370
struct ast_udptl * udptl
Definition: sip.h:1115
unsigned int t38_maxdatagram
Definition: sip.h:1329
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
static void set_t38_capabilities(struct sip_pvt *p)
Set the global T38 capabilities on a SIP dialog structure.
Definition: chan_sip.c:5939
int callingpres
Definition: sip.h:1117
sipmethod
SIP Request methods known by Asterisk.
Definition: sip.h:612
enum ast_acl_sense ast_apply_acl(struct ast_acl_list *acl_list, const struct ast_sockaddr *addr, const char *purpose)
Apply a set of rules to a given IP address.
Definition: acl.c:800
void ast_format_cap_remove_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Remove all formats matching a specific format type.
Definition: format_cap.c:525
#define SIP_PAGE2_FLAGS_TO_COPY
Definition: sip.h:375
struct ast_cc_config_params * cc_params
Definition: sip.h:1377
const ast_string_field mohinterpret
Definition: sip.h:1306
#define FINDUSERS
Definition: sip.h:52
struct ast_format_cap * caps
Definition: sip.h:1342
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
#define ao2_t_global_obj_ref(holder, tag)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:923
const ast_string_field zone
Definition: sip.h:1306
int parse_uri(char *uri, const char *scheme, char **ret_name, char **pass, char **hostport, char **transport)
parses a URI in its components.
const ast_string_field callback
Definition: sip.h:1306
const ast_string_field fullcontact
Definition: sip.h:1306
static struct ast_variable * copy_vars(struct ast_variable *src)
duplicate a list of channel variables,
Definition: chan_sip.c:2525
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
unsigned int disallowed_methods
Definition: sip.h:1201
int timer_b
Definition: sip.h:1096
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
#define SIP_PAGE3_NAT_AUTO_RPORT
Definition: sip.h:386
struct ast_namedgroups * ast_ref_namedgroups(struct ast_namedgroups *groups)
Definition: channel.c:7838
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
#define SIP_FLAGS_TO_COPY
Flags to copy from peer/user to dialog.
Definition: sip.h:313
int timer_t1
Definition: sip.h:1095
#define FINDPEERS
Definition: sip.h:53
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
int rtpkeepalive
Definition: sip.h:1345
int alwaysauthreject
Definition: sip.h:760
#define FINDALLDEVICES
Definition: sip.h:54
struct ast_rtp_instance * rtp
Definition: sip.h:1174
void ast_cc_copy_config_params(struct ast_cc_config_params *dest, const struct ast_cc_config_params *src)
copy CCSS configuration parameters from one structure to another
Definition: ccss.c:861
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)
Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers requ...
Definition: chan_sip.c:17341
unsigned short autoframing
Definition: sip.h:1317
static char cid_name[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:165
static void do_setnat(struct sip_pvt *p)
Set nat mode on the various data sockets.
Definition: chan_sip.c:5862
ast_group_t callgroup
Definition: sip.h:1346
const ast_string_field cid_name
Definition: sip.h:1306
#define SIP_PAGE2_T38SUPPORT
Definition: sip.h:346
enum transfermodes allowtransfer
Definition: sip.h:1137
#define SIP_DTMF
Definition: sip.h:275
enum ast_transport type
Definition: sip.h:798
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
struct ast_flags flags[3]
Definition: sip.h:1335
#define TRUE
Definition: app_minivm.c:518
const ast_string_field secret
Definition: sip.h:1306
static struct sip_peer * sip_find_peer_by_ip_and_exten(struct ast_sockaddr *addr, char *callbackexten, int transport)
Definition: chan_sip.c:5856
const ast_string_field cid_num
Definition: sip.h:1306
#define SIP_INSECURE_INVITE
Definition: sip.h:297
int callingpres
Definition: sip.h:1324
int allowguest
Definition: sip.h:759
static unsigned int set_pvt_allowed_methods(struct sip_pvt *pvt, struct sip_request *req)
Definition: chan_sip.c:9880
int ast_format_cap_append_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type)
Append the formats of provided type in src to dst.
Definition: format_cap.c:269
struct ast_namedgroups * ast_unref_namedgroups(struct ast_namedgroups *groups)
Definition: channel.c:7832
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
void ast_rtp_dtls_cfg_copy(const struct ast_rtp_dtls_cfg *src_cfg, struct ast_rtp_dtls_cfg *dst_cfg)
Copy contents of a DTLS configuration structure.
Definition: rtp_engine.c:3113
void ast_shrink_phone_number(char *n)
Shrink a phone number in place to just digits (more accurately it just removes ()&#39;s, .&#39;s, and -&#39;s...
Definition: callerid.c:947
#define AST_RTP_DTMF
Definition: rtp_engine.h:266
unsigned int sipoptions
Definition: sip.h:1334
int ast_format_cap_get_compatible(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2, struct ast_format_cap *result)
Find the compatible formats between two capabilities structures.
Definition: format_cap.c:630
static void set_peer_nat(const struct sip_pvt *p, struct sip_peer *peer)
Set the peers nat flags if they are using auto_* settings.
Definition: chan_sip.c:19103
const ast_string_field cid_tag
Definition: sip.h:1306
const ast_string_field engine
Definition: sip.h:1306
unsigned int sipoptions
Definition: sip.h:1097
#define SIP_DTMF_AUTO
Definition: sip.h:279
struct ast_variable * chanvars
Definition: sip.h:1180
ast_group_t pickupgroup
Definition: sip.h:1071
ast_group_t pickupgroup
Definition: sip.h:1347
const ast_string_field context
Definition: sip.h:1306
unsigned short natdetected
Definition: sip.h:1094
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514
unsigned int disallowed_methods
Definition: sip.h:1376

◆ check_pendings()

static void check_pendings ( struct sip_pvt p)
static

Check pending actions on SIP call.

Note
both sip_pvt and sip_pvt's owner channel (if present) must be locked for this function.
Run by the sched thread.

Definition at line 23735 of file chan_sip.c.

References ast_clear_flag, ast_debug, AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), ast_test_flag, sip_pvt::callid, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, INV_CALLING, INV_CANCELLED, INV_EARLY_MEDIA, INV_PROCEEDING, sip_pvt::invitestate, sip_pvt::lastinvite, sip_pvt::ongoing_reinvite, sip_pvt::owner, sip_pvt::pendinginvite, sip_pvt::reinviteid, SIP_BYE, SIP_CANCEL, SIP_NEEDREINVITE, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PENDINGBYE, sip_scheddestroy(), t38properties::state, sip_pvt::t38, T38_LOCAL_REINVITE, transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), TRUE, sip_pvt::waitid, and XMIT_RELIABLE.

Referenced by __sched_check_pendings(), reinvite_timeout(), retrans_pkt(), and sip_reinvite_retry().

23736 {
23737  if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
23738  if (p->reinviteid > -1) {
23739  /* Outstanding p->reinviteid timeout, so wait... */
23740  return;
23741  }
23743  /* if we can't BYE, then this is really a pending CANCEL */
23746  /* If the cancel occurred on an initial invite, cancel the pending BYE */
23749  }
23750  /* Actually don't destroy us yet, wait for the 487 on our original
23751  INVITE, but do set an autodestruct just in case we never get it. */
23752  } else {
23753  /* We have a pending outbound invite, don't send something
23754  * new in-transaction, unless it is a pending reinvite, then
23755  * by the time we are called here, we should probably just hang up. */
23756  if (p->pendinginvite && !p->ongoing_reinvite)
23757  return;
23758 
23759  if (p->owner) {
23761  }
23762  /* Perhaps there is an SD change INVITE outstanding */
23765  }
23767  } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) {
23768  /* if we can't REINVITE, hold it for later */
23769  if (p->pendinginvite
23770  || p->invitestate == INV_CALLING
23771  || p->invitestate == INV_PROCEEDING
23772  || p->invitestate == INV_EARLY_MEDIA
23773  || p->waitid > -1) {
23774  ast_debug(2, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid);
23775  } else {
23776  ast_debug(2, "Sending pending reinvite on '%s'\n", p->callid);
23777  /* Didn't get to reinvite yet, so do it now */
23780  }
23781  }
23782 }
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.
Definition: chan_sip.c:16564
#define FALSE
Definition: app_minivm.c:521
enum t38state state
Definition: sip.h:917
#define ast_test_flag(p, flag)
Definition: utils.h:63
uint32_t pendinginvite
Definition: sip.h:1147
int reinviteid
Definition: sip.h:1157
#define DEFAULT_TRANS_TIMEOUT
Definition: sip.h:107
unsigned int ongoing_reinvite
Definition: sip.h:1144
struct ast_flags flags[3]
Definition: sip.h:1075
Definition: sip.h:621
struct t38properties t38
Definition: sip.h:1113
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
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&#39;t retry...
Definition: chan_sip.c:16532
int waitid
Definition: sip.h:1156
static int transmit_reinvite_with_sdp(struct sip_pvt *p, int t38version, int oldsdp)
Transmit reinvite with SDP.
Definition: chan_sip.c:14212
const ast_string_field callid
Definition: sip.h:1063
int ast_softhangup_nolock(struct ast_channel *chan, int reason)
Softly hangup up a channel (no channel lock)
Definition: channel.c:2463
struct ast_channel * owner
Definition: sip.h:1138
enum invitestates invitestate
Definition: sip.h:1007
#define ast_clear_flag(p, flag)
Definition: utils.h:77
#define SIP_PENDINGBYE
Definition: sip.h:262
#define TRUE
Definition: app_minivm.c:518
uint32_t lastinvite
Definition: sip.h:1074
#define SIP_NEEDREINVITE
Definition: sip.h:261
#define SIP_PAGE2_DIALOG_ESTABLISHED
Definition: sip.h:358
void sip_scheddestroy(struct sip_pvt *p, int ms)
Schedule destruction of SIP dialog.
Definition: chan_sip.c:4549

◆ check_rtp_timeout()

static int 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

Returns
CMP_MATCH for items to be unlinked from dialogs_rtpcheck.
Todo:
Check video RTP keepalives

Do we need to move the lastrtptx to the RTP structure to have one for audio and one for video? It really does belong to the RTP structure.

Definition at line 29899 of file chan_sip.c.

References AST_CAUSE_REQUESTED_CHAN_UNAVAIL, ast_channel_hangupcause_set(), ast_channel_name(), 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, CMP_MATCH, sip_pvt::flags, keepalive, sip_pvt::lastrtprx, sip_pvt::lastrtptx, LOG_NOTICE, NULL, sip_pvt::owner, sip_pvt::redirip, sip_pvt::rtp, send_session_timeout(), SIP_PAGE2_CALL_ONHOLD, t38properties::state, sip_pvt::t38, T38_ENABLED, timeout, and sip_pvt::vrtp.

Referenced by dialog_checkrtp_cb().

29900 {
29901  int timeout;
29902  int hold_timeout;
29903  int keepalive;
29904 
29905  if (!dialog->rtp) {
29906  /*
29907  * We have no RTP. Since we don't do much with video RTP for
29908  * now, stop checking this dialog.
29909  */
29910  return CMP_MATCH;
29911  }
29912 
29913  /* If we have no active owner, no need to check timers */
29914  if (!dialog->owner) {
29915  return CMP_MATCH;
29916  }
29917 
29918  /* If the call is redirected outside Asterisk, no need to check timers */
29919  if (!ast_sockaddr_isnull(&dialog->redirip)) {
29920  return CMP_MATCH;
29921  }
29922 
29923  /* If the call is involved in a T38 fax session do not check RTP timeout */
29924  if (dialog->t38.state == T38_ENABLED) {
29925  return CMP_MATCH;
29926  }
29927  /* If the call is not in UP state return for later check. */
29928  if (ast_channel_state(dialog->owner) != AST_STATE_UP) {
29929  return 0;
29930  }
29931 
29932  /* Store these values locally to avoid multiple function calls */
29933  timeout = ast_rtp_instance_get_timeout(dialog->rtp);
29934  hold_timeout = ast_rtp_instance_get_hold_timeout(dialog->rtp);
29935  keepalive = ast_rtp_instance_get_keepalive(dialog->rtp);
29936 
29937  /* If we have no timers set, return now */
29938  if (!keepalive && !timeout && !hold_timeout) {
29939  return CMP_MATCH;
29940  }
29941 
29942  /* Check AUDIO RTP keepalives */
29943  if (dialog->lastrtptx && keepalive && (t > dialog->lastrtptx + keepalive)) {
29944  /* Need to send an empty RTP packet */
29945  dialog->lastrtptx = time(NULL);
29946  ast_rtp_instance_sendcng(dialog->rtp, 0);
29947  }
29948 
29949  /*! \todo Check video RTP keepalives
29950 
29951  Do we need to move the lastrtptx to the RTP structure to have one for audio and one
29952  for video? It really does belong to the RTP structure.
29953  */
29954 
29955  /* Check AUDIO RTP timers */
29956  if (dialog->lastrtprx && (timeout || hold_timeout) && (t > dialog->lastrtprx + timeout)) {
29957  if (!ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD) || (hold_timeout && (t > dialog->lastrtprx + hold_timeout))) {
29958  /* Needs a hangup */
29959  if (timeout) {
29960  if (!dialog->owner || ast_channel_trylock(dialog->owner)) {
29961  /*
29962  * Don't block, just try again later.
29963  * If there was no owner, the call is dead already.
29964  */
29965  return 0;
29966  }
29967  ast_log(LOG_NOTICE, "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n",
29968  ast_channel_name(dialog->owner), (long) (t - dialog->lastrtprx));
29969  send_session_timeout(dialog->owner, "RTPTimeout");
29970 
29971  /* Issue a softhangup - cause 44 (as used by Cisco for RTP timeouts) */
29974  ast_channel_unlock(dialog->owner);
29975  /* forget the timeouts for this call, since a hangup
29976  has already been requested and we don't want to
29977  repeatedly request hangups
29978  */
29979  ast_rtp_instance_set_timeout(dialog->rtp, 0);
29981  if (dialog->vrtp) {
29982  ast_rtp_instance_set_timeout(dialog->vrtp, 0);
29984  }
29985  /* finally unlink the dialog from dialogs_rtpcheck. */
29986  return CMP_MATCH;
29987  }
29988  }
29989  }
29990  return 0;
29991 }
#define T38_ENABLED
Definition: chan_ooh323.c:102
time_t lastrtprx
Definition: sip.h:1129
enum t38state state
Definition: sip.h:917
static uint32_t keepalive
Definition: res_pktccops.c:160
#define ast_test_flag(p, flag)
Definition: utils.h:63
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
int ast_rtp_instance_get_timeout(struct ast_rtp_instance *instance)
Get the RTP timeout value.
Definition: rtp_engine.c:2685
static int timeout
Definition: cdr_mysql.c:86
struct ast_sockaddr redirip
Definition: sip.h:1126
ast_channel_state
ast_channel states
Definition: channelstate.h:35
#define SIP_PAGE2_CALL_ONHOLD
Definition: sip.h:351
void ast_rtp_instance_set_timeout(struct ast_rtp_instance *instance, int timeout)
Set the RTP timeout value.
Definition: rtp_engine.c:2670
struct ast_flags flags[3]
Definition: sip.h:1075
#define NULL
Definition: resample.c:96
struct t38properties t38
Definition: sip.h:1113
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
#define ast_log
Definition: astobj2.c:42
int ast_rtp_instance_get_hold_timeout(struct ast_rtp_instance *instance)
Get the RTP timeout value for when an RTP instance is on hold.
Definition: rtp_engine.c:2690
static void send_session_timeout(struct ast_channel *chan, const char *source)
Sends a session timeout channel blob used to produce SessionTimeout AMI messages. ...
Definition: chan_sip.c:29879
int ast_rtp_instance_sendcng(struct ast_rtp_instance *instance, int level)
Send a comfort noise packet to the RTP instance.
Definition: rtp_engine.c:2772
struct ast_rtp_instance * vrtp
Definition: sip.h:1175
#define LOG_NOTICE
Definition: logger.h:263
int ast_softhangup_nolock(struct ast_channel *chan, int reason)
Softly hangup up a channel (no channel lock)
Definition: channel.c:2463
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_channel * owner
Definition: sip.h:1138
void ast_rtp_instance_set_hold_timeout(struct ast_rtp_instance *instance, int timeout)
Set the RTP timeout value for when the instance is on hold.
Definition: rtp_engine.c:2675
struct ast_rtp_instance * rtp
Definition: sip.h:1174
#define AST_CAUSE_REQUESTED_CHAN_UNAVAIL
Definition: causes.h:124
time_t lastrtptx
Definition: sip.h:1130
const char * ast_channel_name(const struct ast_channel *chan)
int ast_rtp_instance_get_keepalive(struct ast_rtp_instance *instance)
Get the RTP keepalive interval.
Definition: rtp_engine.c:2695
#define ast_channel_trylock(chan)
Definition: channel.h:2947

◆ check_sip_domain()

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

References ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero, domain::context, d, domain::domain, and result.

Referenced by func_check_sipdomain(), get_destination(), get_realm(), handle_request_refer(), and register_verify().

31315 {
31316  struct domain *d;
31317  int result = 0;
31318 
31321  if (strcasecmp(d->domain, domain)) {
31322  continue;
31323  }
31324 
31325  if (len && !ast_strlen_zero(d->context))
31327 
31328  result = 1;
31329  break;
31330  }
31332 
31333  return result;
31334 }
struct domain::@167 list
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
static struct test_val d
Domain data structure.
Definition: sip.h:888
#define ast_strlen_zero(foo)
Definition: strings.h:52
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static PGresult * result
Definition: cel_pgsql.c:88
char domain[MAXHOSTNAMELEN]
Definition: sip.h:889
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
char context[AST_MAX_EXTENSION]
Definition: sip.h:890

◆ check_user()

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, that needs to be unreferenced.

Definition at line 19621 of file chan_sip.c.

References check_user_full(), and NULL.

Referenced by handle_request_options(), handle_request_publish(), and receive_message().

19622 {
19623  return check_user_full(p, req, sipmethod, uri, reliable, addr, NULL);
19624 }
#define NULL
Definition: resample.c:96
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 u...
Definition: chan_sip.c:19486
sipmethod
SIP Request methods known by Asterisk.
Definition: sip.h:612

◆ check_user_full()

static enum check_auth_result check_user_full ( struct sip_pvt p,
struct sip_request req,
int  sipmethod,
const char *  uri,
enum xmittype  reliable,
struct ast_sockaddr addr,
struct sip_peer **  authpeer 
)
static

Check if matching user or peer is defined Match user on From: user name and peer on IP/port This is used on first invite (not re-invites) and subscribe requests.

Returns
0 on success, non-zero on failure

Definition at line 19486 of file chan_sip.c.

References sip_settings::allowguest, 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, AUTH_DONT_KNOW, AUTH_RTP_FAILED, AUTH_SECRET_FAILED, AUTH_SUCCESSFUL, build_contact(), check_peer_ok(), cid_name, cid_num, dialog_initialize_rtp(), exten, sip_pvt::exten, extract_host_from_hostport(), sip_pvt::flags, get_calleridname(), get_in_brackets(), get_rpid(), global_match_auth_username, global_rtpholdtimeout, global_rtpkeepalive, global_rtptimeout, global_shrinkcallerid, LOG_ERROR, LOG_NOTICE, name, NULL, sip_pvt::our_contact, parse_uri_legacy_check(), RAII_VAR, sip_pvt::rtpholdtimeout, sip_pvt::rtpkeepalive, sip_pvt::rtptimeout, sip_cfg, sip_get_header(), SIP_NAT_RPORT_PRESENT, SIP_PAGE2_RPORT_PRESENT, SIP_PEDANTIC_DECODE, strsep(), terminate_uri(), and tmp().

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

19489 {
19490  char *of, *name, *unused_password, *domain;
19491  RAII_VAR(char *, ofbuf, NULL, ast_free); /* beware, everyone starts pointing to this */
19492  RAII_VAR(char *, namebuf, NULL, ast_free);
19493  enum check_auth_result res = AUTH_DONT_KNOW;
19494  char calleridname[256];
19495  char *uri2 = ast_strdupa(uri);
19496 
19497  terminate_uri(uri2); /* trim extra stuff */
19498 
19499  ofbuf = ast_strdup(sip_get_header(req, "From"));
19500  /* XXX here tries to map the username for invite things */
19501 
19502  /* strip the display-name portion off the beginning of the FROM header. */
19503  if (!(of = (char *) get_calleridname(ofbuf, calleridname, sizeof(calleridname)))) {
19504  ast_log(LOG_ERROR, "FROM header can not be parsed\n");
19505  return res;
19506  }
19507 
19508  if (calleridname[0]) {
19509  ast_string_field_set(p, cid_name, calleridname);
19510  }
19511 
19512  if (ast_strlen_zero(p->exten)) {
19513  char *t = uri2;
19514  if (!strncasecmp(t, "sip:", 4)) {
19515  t += 4;
19516  } else if (!strncasecmp(t, "sips:", 5)) {
19517  t += 5;
19518  } else if (!strncasecmp(t, "tel:", 4)) { /* TEL URI INVITE */
19519  t += 4;
19520  }
19521  ast_string_field_set(p, exten, t);
19522  t = strchr(p->exten, '@');
19523  if (t)
19524  *t = '\0';
19525 
19526  if (ast_strlen_zero(p->our_contact)) {
19527  build_contact(p, req, 1);
19528  }
19529  }
19530 
19531  of = get_in_brackets(of);
19532 
19533  /* save the URI part of the From header */
19534  ast_string_field_set(p, from, of);
19535 
19536  if (parse_uri_legacy_check(of, "sip:,sips:,tel:", &name, &unused_password, &domain, NULL)) {
19537  ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
19538  }
19539 
19540  SIP_PEDANTIC_DECODE(name);
19541  SIP_PEDANTIC_DECODE(domain);
19542 
19543  extract_host_from_hostport(&domain);
19544 
19545  if (ast_strlen_zero(domain)) {
19546  /* <sip:name@[EMPTY]>, never good */
19547  ast_log(LOG_ERROR, "Empty domain name in FROM header\n");
19548  return res;
19549  }
19550 
19551  if (ast_strlen_zero(name)) {
19552  /* <sip:[EMPTY][@]hostport>. Asterisk 1.4 and 1.6 have always
19553  * treated that as a username, so we continue the tradition:
19554  * uri is now <sip:host@hostport>. */
19555  name = domain;
19556  } else {
19557  /* Non-empty name, try to get caller id from it */
19558  char *tmp = ast_strdupa(name);
19559  /* We need to be able to handle from-headers looking like
19560  <sip:8164444422;[email protected]:5060;user=phone;tag=SDadkoa01-gK0c3bdb43>
19561  */
19562  tmp = strsep(&tmp, ";");
19565  }
19566  ast_string_field_set(p, cid_num, tmp);
19567  }
19568 
19570  /*
19571  * XXX This is experimental code to grab the search key from the
19572  * Auth header's username instead of the 'From' name, if available.
19573  * Do not enable this block unless you understand the side effects (if any!)
19574  * Note, the search for "username" should be done in a more robust way.
19575  * Note2, at the moment we check both fields, though maybe we should
19576  * pick one or another depending on the request ? XXX
19577  */
19578  const char *hdr = sip_get_header(req, "Authorization");
19579  if (ast_strlen_zero(hdr)) {
19580  hdr = sip_get_header(req, "Proxy-Authorization");
19581  }
19582 
19583  if (!ast_strlen_zero(hdr) && (hdr = strstr(hdr, "username=\""))) {
19584  namebuf = name = ast_strdup(hdr + strlen("username=\""));
19585  name = strsep(&name, "\"");
19586  }
19587  }
19588 
19589  res = check_peer_ok(p, name, req, sipmethod, addr,
19590  authpeer, reliable, calleridname, uri2);
19591  if (res != AUTH_DONT_KNOW) {
19592  return res;
19593  }
19594 
19595  /* Finally, apply the guest policy */
19596  if (sip_cfg.allowguest) {
19597  /* Ignore check_return warning from Coverity for get_rpid below. */
19598  get_rpid(p, req);
19602  if (!dialog_initialize_rtp(p)) {
19603  res = AUTH_SUCCESSFUL;
19604  } else {
19605  res = AUTH_RTP_FAILED;
19606  }
19607  } else {
19608  res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */
19609  }
19610 
19613  }
19614 
19615  return res;
19616 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
static int global_shrinkcallerid
Definition: chan_sip.c:829
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
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 fou...
Definition: chan_sip.c:18266
char * get_in_brackets(char *tmp)
Pick out text in brackets from character string.
int rtpholdtimeout
Definition: sip.h:1132
#define ast_test_flag(p, flag)
Definition: utils.h:63
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.
Definition: chan_sip.c:19237
#define ast_set_flag(p, flag)
Definition: utils.h:70
static int global_rtptimeout
Definition: chan_sip.c:823
static int tmp()
Definition: bt_open.c:389
check_auth_result
Authentication result from check_auth* functions.
Definition: sip.h:517
int rtpkeepalive
Definition: sip.h:1133
struct ast_flags flags[3]
Definition: sip.h:1075
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
int ast_is_shrinkable_phonenumber(const char *exten)
Check if a string consists only of digits and + # ( ) - . (meaning it can be cleaned with ast_shrink_...
Definition: callerid.c:1003
static char cid_num[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:164
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define SIP_PAGE2_RPORT_PRESENT
Definition: sip.h:331
#define ast_log
Definition: astobj2.c:42
int rtptimeout
Definition: sip.h:1131
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
static int dialog_initialize_rtp(struct sip_pvt *dialog)
Initialize RTP portion of a dialog.
Definition: chan_sip.c:6041
const ast_string_field exten
Definition: sip.h:1063
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
sipmethod
SIP Request methods known by Asterisk.
Definition: sip.h:612
static void extract_host_from_hostport(char **hostport)
Terminate a host:port at the &#39;:&#39;.
Definition: chan_sip.c:17831
#define SIP_PEDANTIC_DECODE(str)
Definition: chan_sip.c:813
#define LOG_ERROR
Definition: logger.h:285
const char * get_calleridname(const char *input, char *output, size_t outputsize)
Get caller id name from SIP headers, copy into output buffer.
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
#define LOG_NOTICE
Definition: logger.h:263
#define SIP_NAT_RPORT_PRESENT
Definition: sip.h:284
static void build_contact(struct sip_pvt *p, struct sip_request *req, int incoming)
Build contact header.
Definition: chan_sip.c:14385
static const char name[]
Definition: cdr_mysql.c:74
#define ast_free(a)
Definition: astmm.h:182
static char cid_name[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:165
char * strsep(char **str, const char *delims)
static int global_match_auth_username
Definition: chan_sip.c:819
int allowguest
Definition: sip.h:759
static int global_rtpholdtimeout
Definition: chan_sip.c:824
char domain[MAXHOSTNAMELEN]
Definition: sip.h:889
static char * terminate_uri(char *uri)
Definition: chan_sip.c:17815
void ast_shrink_phone_number(char *n)
Shrink a phone number in place to just digits (more accurately it just removes ()&#39;s, .&#39;s, and -&#39;s...
Definition: callerid.c:947
static int global_rtpkeepalive
Definition: chan_sip.c:825
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
Definition: chan_sip.c:16880
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514
const ast_string_field our_contact
Definition: sip.h:1063

◆ check_via()

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

References ast_copy_string(), ast_log, ast_set_flag, ast_sockaddr_port, ast_sockaddr_resolve_first(), ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_strip(), ast_verbose(), c, check_for_nat(), sip_pvt::flags, LOG_WARNING, sip_pvt::recv, sip_pvt::sa, sip_debug_test_pvt(), sip_get_header(), sip_nat_mode(), SIP_NAT_RPORT_PRESENT, SIP_PAGE2_RPORT_PRESENT, sip_real_dst(), STANDARD_SIP_PORT, and tmp().

Referenced by __sip_alloc(), handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_register(), handle_request_subscribe(), and transmit_response_using_temp().

19165 {
19166  char via[512];
19167  char *c, *maddr;
19168  struct ast_sockaddr tmp = { { 0, } };
19169  uint16_t port;
19170 
19171  ast_copy_string(via, sip_get_header(req, "Via"), sizeof(via));
19172 
19173  /* If this is via WebSocket we don't use the Via header contents at all */
19174  if (!strncasecmp(via, "SIP/2.0/WS", 10)) {
19175  return;
19176  }
19177 
19178  /* Work on the leftmost value of the topmost Via header */
19179  c = strchr(via, ',');
19180  if (c)
19181  *c = '\0';
19182 
19183  /* Check for rport */
19184  c = strstr(via, ";rport");
19185  if (c && (c[6] != '=')) { /* rport query, not answer */
19188  }
19189 
19190  /* Check for maddr */
19191  maddr = strstr(via, "maddr=");
19192  if (maddr) {
19193  maddr += 6;
19194  c = maddr + strspn(maddr, "abcdefghijklmnopqrstuvwxyz"
19195  "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.:[]");
19196  *c = '\0';
19197  }
19198 
19199  c = strchr(via, ';');
19200  if (c)
19201  *c = '\0';
19202 
19203  c = strchr(via, ' ');
19204  if (c) {
19205  *c = '\0';
19206  c = ast_strip(c+1);
19207  if (strcasecmp(via, "SIP/2.0/UDP") && strcasecmp(via, "SIP/2.0/TCP") && strcasecmp(via, "SIP/2.0/TLS")) {
19208  ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via);
19209  return;
19210  }
19211 
19212  if (maddr && ast_sockaddr_resolve_first(&p->sa, maddr, 0)) {
19213  p->sa = p->recv;
19214  }
19215 
19216  if (ast_sockaddr_resolve_first(&tmp, c, 0)) {
19217  ast_log(LOG_WARNING, "Could not resolve socket address for '%s'\n", c);
19218  port = STANDARD_SIP_PORT;
19219  } else if (!(port = ast_sockaddr_port(&tmp))) {
19220  port = STANDARD_SIP_PORT;
19221  ast_sockaddr_set_port(&tmp, port);
19222  }
19223 
19224  ast_sockaddr_set_port(&p->sa, port);
19225 
19226  check_for_nat(&tmp, p);
19227 
19228  if (sip_debug_test_pvt(p)) {
19229  ast_verbose("Sending to %s (%s)\n",
19231  sip_nat_mode(p));
19232  }
19233  }
19234 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define LOG_WARNING
Definition: logger.h:274
struct ast_sockaddr recv
Definition: sip.h:1135
static int tmp()
Definition: bt_open.c:389
static struct test_val c
struct ast_flags flags[3]
Definition: sip.h:1075
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
Socket address structure.
Definition: netsock2.h:97
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:521
#define SIP_PAGE2_RPORT_PRESENT
Definition: sip.h:331
struct ast_sockaddr sa
Definition: sip.h:1125
#define ast_log
Definition: astobj2.c:42
#define STANDARD_SIP_PORT
Standard SIP unsecure port for UDP and TCP from RFC 3261. DO NOT CHANGE THIS.
Definition: sip.h:176
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:219
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. ...
Definition: chan_sip.c:34469
static const struct ast_sockaddr * sip_real_dst(const struct sip_pvt *p)
The real destination address for a write.
Definition: chan_sip.c:3633
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:537
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
#define SIP_NAT_RPORT_PRESENT
Definition: sip.h:284
static int sip_debug_test_pvt(struct sip_pvt *p)
Test PVT for debugging output.
Definition: chan_sip.c:3649
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static void check_for_nat(const struct ast_sockaddr *them, struct sip_pvt *p)
Check and see if the requesting UA is likely to be behind a NAT.
Definition: chan_sip.c:19134
static const char * sip_nat_mode(const struct sip_pvt *p)
Display SIP nat mode.
Definition: chan_sip.c:3643

◆ cleanup_all_regs()

static void cleanup_all_regs ( void  )
static

Definition at line 32502 of file chan_sip.c.

References ao2_t_callback, cleanup_registration(), NULL, OBJ_MULTIPLE, OBJ_NODATA, and OBJ_UNLINK.

Referenced by reload_config(), and unload_module().

32503 {
32505  cleanup_registration, NULL, "remove all SIP registry items");
32506 }
#define NULL
Definition: resample.c:96
static struct ao2_container * registry_list
The register list: Other SIP proxies we register with and receive calls from.
Definition: chan_sip.c:1061
static int cleanup_registration(void *obj, void *arg, int flags)
Definition: chan_sip.c:32489
#define ao2_t_callback(c, flags, cb_fn, arg, tag)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.
Definition: astobj2.h:1714

◆ cleanup_registration()

static int cleanup_registration ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 32489 of file chan_sip.c.

References __cleanup_registration(), ao2_t_ref, ast_sched_add(), and CMP_MATCH.

Referenced by cleanup_all_regs().

32490 {
32491  struct sip_registry *reg = obj;
32492 
32493  ao2_t_ref(reg, +1, "cleanup_registration action");
32494  if (ast_sched_add(sched, 0, __cleanup_registration, reg) < 0) {
32495  /* Uh Oh. Expect bad behavior. */
32496  ao2_t_ref(reg, -1, "Failed to schedule cleanup_registration action");
32497  }
32498 
32499  return CMP_MATCH;
32500 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
Definition: sched.c:76
Registrations with other SIP proxies.
Definition: sip.h:1396
static int __cleanup_registration(const void *data)
Definition: chan_sip.c:32459
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565

◆ cleanup_stale_contexts()

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

References ast_context_destroy_by_name(), ast_copy_string(), AST_MAX_CONTEXT, NULL, and strsep().

Referenced by reload_config().

20652 {
20653  char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT];
20654 
20655  while ((oldcontext = strsep(&old, "&"))) {
20656  stalecontext = NULL;
20657  ast_copy_string(newlist, new, sizeof(newlist));
20658  stringp = newlist;
20659  while ((newcontext = strsep(&stringp, "&"))) {
20660  if (!strcmp(newcontext, oldcontext)) {
20661  /* This is not the context you're looking for */
20662  stalecontext = NULL;
20663  break;
20664  } else if (strcmp(newcontext, oldcontext)) {
20665  stalecontext = oldcontext;
20666  }
20667 
20668  }
20669  ast_context_destroy_by_name(stalecontext, "SIP");
20670  }
20671 }
#define NULL
Definition: resample.c:96
int ast_context_destroy_by_name(const char *context, const char *registrar)
Destroy a context by name.
Definition: pbx.c:8244
#define AST_MAX_CONTEXT
Definition: channel.h:136
char * strsep(char **str, const char *delims)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401

◆ clear_peer_mailboxes()

static void clear_peer_mailboxes ( struct sip_peer peer)
static

Destroy all peer-related mailbox subscriptions

Definition at line 5293 of file chan_sip.c.

References destroy_mailbox(), mailbox, and REMOVE_MAILBOX_WITH_LOCKED_PEER.

Referenced by set_peer_defaults(), and sip_destroy_peer().

5294 {
5295  struct sip_mailbox *mailbox;
5296 
5297  /* Lock the peer while accessing/updating the linked list but NOT while destroying the mailbox */
5298  while ((mailbox = REMOVE_MAILBOX_WITH_LOCKED_PEER(peer))) {
5299  destroy_mailbox(mailbox);
5300  }
5301 }
A peer&#39;s mailbox.
Definition: sip.h:1261
static char mailbox[AST_MAX_MAILBOX_UNIQUEID]
Definition: chan_mgcp.c:204
#define REMOVE_MAILBOX_WITH_LOCKED_PEER(__peer)
Definition: chan_sip.c:5283
static void destroy_mailbox(struct sip_mailbox *mailbox)
Definition: chan_sip.c:5275

◆ clear_sip_domains()

static void clear_sip_domains ( void  )
static

Clear our domain list (at reload)

Definition at line 31337 of file chan_sip.c.

References ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and d.

Referenced by reload_config(), and unload_module().

31338 {
31339  struct domain *d;
31340 
31342  while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list)))
31343  ast_free(d);
31345 }
struct domain::@167 list
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
static struct test_val d
Domain data structure.
Definition: sip.h:888
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
#define ast_free(a)
Definition: astmm.h:182

◆ complete_sip_notify()

static char * complete_sip_notify ( const char *  line,
const char *  word,
int  pos,
int  state 
)
static

Support routine for 'sip notify' CLI.

Definition at line 22359 of file chan_sip.c.

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

Referenced by sip_cli_notify().

22360 {
22361  char *c = NULL;
22362 
22363  if (pos == 2) {
22364  int which = 0;
22365  char *cat = NULL;
22366  int wordlen = strlen(word);
22367 
22368  /* do completion for notify type */
22369 
22370  if (!notify_types)
22371  return NULL;
22372 
22373  while ( (cat = ast_category_browse(notify_types, cat)) ) {
22374  if (!strncasecmp(word, cat, wordlen) && ++which > state) {
22375  c = ast_strdup(cat);
22376  break;
22377  }
22378  }
22379  return c;
22380  }
22381 
22382  if (pos > 2)
22383  return complete_sip_peer(word, state, 0);
22384 
22385  return NULL;
22386 }
static struct ast_config * notify_types
Definition: chan_sip.c:1153
static struct test_val c
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3328
#define NULL
Definition: resample.c:96
static char * complete_sip_peer(const char *word, int state, int flags2)
Do completion on peer name.
Definition: chan_sip.c:22282
short word

◆ complete_sip_peer()

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

Do completion on peer name.

Definition at line 22282 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ast_strdup, ast_test_flag, sip_peer::flags, sip_peer::name, NULL, result, and sip_unref_peer.

Referenced by complete_sip_notify(), complete_sip_show_peer(), sip_do_debug(), and sip_prune_realtime().

22283 {
22284  char *result = NULL;
22285  int wordlen = strlen(word);
22286  int which = 0;
22287  struct ao2_iterator i = ao2_iterator_init(peers, 0);
22288  struct sip_peer *peer;
22289 
22290  while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) {
22291  /* locking of the object is not required because only the name and flags are being compared */
22292  if (!strncasecmp(word, peer->name, wordlen) &&
22293  (!flags2 || ast_test_flag(&peer->flags[1], flags2)) &&
22294  ++which > state)
22295  result = ast_strdup(peer->name);
22296  sip_unref_peer(peer, "toss iterator peer ptr before break");
22297  if (result) {
22298  break;
22299  }
22300  }
22302  return result;
22303 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
char name[80]
Definition: sip.h:1274
#define ao2_t_iterator_next(iter, tag)
Definition: astobj2.h:1931
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
struct ast_flags flags[3]
Definition: sip.h:1335
static PGresult * result
Definition: cel_pgsql.c:88
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
short word

◆ complete_sip_registered_peer()

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

Do completion on registered peer name.

Definition at line 22306 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ast_strdup, ast_test_flag, sip_peer::expire, sip_peer::flags, sip_peer::name, NULL, result, and sip_unref_peer.

Referenced by complete_sip_unregister().

22307 {
22308  char *result = NULL;
22309  int wordlen = strlen(word);
22310  int which = 0;
22311  struct ao2_iterator i;
22312  struct sip_peer *peer;
22313 
22314  i = ao2_iterator_init(peers, 0);
22315  while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) {
22316  if (!strncasecmp(word, peer->name, wordlen) &&
22317  (!flags2 || ast_test_flag(&peer->flags[1], flags2)) &&
22318  ++which > state && peer->expire > -1)
22319  result = ast_strdup(peer->name);
22320  if (result) {
22321  sip_unref_peer(peer, "toss iterator peer ptr before break");
22322  break;
22323  }
22324  sip_unref_peer(peer, "toss iterator peer ptr");
22325  }
22327  return result;
22328 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
char name[80]
Definition: sip.h:1274
int expire
Definition: sip.h:1341
#define ao2_t_iterator_next(iter, tag)
Definition: astobj2.h:1931
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
struct ast_flags flags[3]
Definition: sip.h:1335
static PGresult * result
Definition: cel_pgsql.c:88
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
short word

◆ complete_sip_show_history()

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

References complete_sipch(), and NULL.

Referenced by sip_show_history().

22332 {
22333  if (pos == 3)
22334  return complete_sipch(line, word, pos, state);
22335 
22336  return NULL;
22337 }
#define NULL
Definition: resample.c:96
static char * complete_sipch(const char *line, const char *word, int pos, int state)
Support routine for &#39;sip show channel&#39; and &#39;sip show history&#39; CLI This is in charge of generating all...
Definition: chan_sip.c:22252
short word

◆ complete_sip_show_peer()

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

References complete_sip_peer(), and NULL.

Referenced by sip_qualify_peer(), and sip_show_peer().

22341 {
22342  if (pos == 3) {
22343  return complete_sip_peer(word, state, 0);
22344  }
22345 
22346  return NULL;
22347 }
#define NULL
Definition: resample.c:96
static char * complete_sip_peer(const char *word, int state, int flags2)
Do completion on peer name.
Definition: chan_sip.c:22282
short word

◆ complete_sip_show_user()

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

References complete_sip_user(), and NULL.

Referenced by sip_show_user().

21501 {
21502  if (pos == 3)
21503  return complete_sip_user(word, state);
21504 
21505  return NULL;
21506 }
#define NULL
Definition: resample.c:96
static char * complete_sip_user(const char *word, int state)
Do completion on user name.
Definition: chan_sip.c:21470
short word

◆ complete_sip_unregister()

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

References complete_sip_registered_peer(), and NULL.

Referenced by sip_unregister().

22351 {
22352  if (pos == 2)
22354 
22355  return NULL;
22356 }
#define NULL
Definition: resample.c:96
static char * complete_sip_registered_peer(const char *word, int state, int flags2)
Do completion on registered peer name.
Definition: chan_sip.c:22306
short word

◆ complete_sip_user()

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

Do completion on user name.

Definition at line 21470 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_iterator_next, ao2_unlock, ast_strdup, sip_peer::name, NULL, result, SIP_TYPE_USER, sip_unref_peer, sip_peer::type, and user.

Referenced by complete_sip_show_user().

21471 {
21472  char *result = NULL;
21473  int wordlen = strlen(word);
21474  int which = 0;
21475  struct ao2_iterator user_iter;
21476  struct sip_peer *user;
21477 
21478  user_iter = ao2_iterator_init(peers, 0);
21479  while ((user = ao2_t_iterator_next(&user_iter, "iterate thru peers table"))) {
21480  ao2_lock(user);
21481  if (!(user->type & SIP_TYPE_USER)) {
21482  ao2_unlock(user);
21483  sip_unref_peer(user, "complete sip user");
21484  continue;
21485  }
21486  /* locking of the object is not required because only the name and flags are being compared */
21487  if (!strncasecmp(word, user->name, wordlen) && ++which > state) {
21488  result = ast_strdup(user->name);
21489  }
21490  ao2_unlock(user);
21491  sip_unref_peer(user, "complete sip user");
21492  if (result) {
21493  break;
21494  }
21495  }
21496  ao2_iterator_destroy(&user_iter);
21497  return result;
21498 }
static char user[512]
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_unlock(a)
Definition: astobj2.h:730
enum sip_peer_type type
Definition: sip.h:1375
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
char name[80]
Definition: sip.h:1274
#define ao2_lock(a)
Definition: astobj2.h:718
#define ao2_t_iterator_next(iter, tag)
Definition: astobj2.h:1931
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
static PGresult * result
Definition: cel_pgsql.c:88
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
short word

◆ complete_sipch()

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

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ast_strdup, c, sip_pvt::callid, dialog_unref, NULL, sip_pvt_lock, and sip_pvt_unlock.

Referenced by complete_sip_show_history(), and sip_show_channel().

22253 {
22254  int which=0;
22255  struct sip_pvt *cur;
22256  char *c = NULL;
22257  int wordlen = strlen(word);
22258  struct ao2_iterator i;
22259 
22260  if (pos != 3) {
22261  return NULL;
22262  }
22263 
22264  i = ao2_iterator_init(dialogs, 0);
22265  while ((cur = ao2_t_iterator_next(&i, "iterate thru dialogs"))) {
22266  sip_pvt_lock(cur);
22267  if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) {
22268  c = ast_strdup(cur->callid);
22269  sip_pvt_unlock(cur);
22270  dialog_unref(cur, "drop ref in iterator loop break");
22271  break;
22272  }
22273  sip_pvt_unlock(cur);
22274  dialog_unref(cur, "drop ref in iterator loop");
22275  }
22277  return c;
22278 }
static struct ao2_container * dialogs
Definition: chan_sip.c:1043
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
static struct test_val c
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
const ast_string_field callid
Definition: sip.h:1063
#define ao2_t_iterator_next(iter, tag)
Definition: astobj2.h:1931
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
short word

◆ configure_rtcp()

static void configure_rtcp ( struct sip_pvt p,
struct ast_rtp_instance instance,
int  which,
int  remote_rtcp_mux 
)
static

Definition at line 10194 of file chan_sip.c.

References ast_channel_set_fd(), ast_rtp_instance_fd(), AST_RTP_INSTANCE_RTCP_MUX, AST_RTP_INSTANCE_RTCP_STANDARD, ast_rtp_instance_set_prop(), AST_RTP_PROPERTY_RTCP, ast_test_flag, sip_pvt::flags, sip_pvt::owner, and SIP_PAGE3_RTCP_MUX.

Referenced by process_sdp().

10195 {
10196  int local_rtcp_mux = ast_test_flag(&p->flags[2], SIP_PAGE3_RTCP_MUX);
10197  int fd = -1;
10198 
10199  if (local_rtcp_mux && remote_rtcp_mux) {
10201  } else {
10203  fd = ast_rtp_instance_fd(instance, 1);
10204  }
10205 
10206  if (p->owner) {
10207  ast_channel_set_fd(p->owner, which, fd);
10208  }
10209 }
#define SIP_PAGE3_RTCP_MUX
Definition: sip.h:394
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_flags flags[3]
Definition: sip.h:1075
struct ast_channel * owner
Definition: sip.h:1138
int ast_rtp_instance_fd(struct ast_rtp_instance *instance, int rtcp)
Get the file descriptor for an RTP session (or RTCP)
Definition: rtp_engine.c:2192
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition: channel.c:2431
void ast_rtp_instance_set_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value)
Set the value of an RTP instance property.
Definition: rtp_engine.c:705

◆ construct_pidf_body()

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

Definition at line 2134 of file chan_sip.c.

References ast_copy_string(), ast_str_alloca, ast_str_append(), ast_str_buffer(), CC_OPEN, and generate_random_string().

Referenced by handle_cc_notify(), sip_cc_monitor_suspend(), and sip_cc_monitor_unsuspend().

2135 {
2136  struct ast_str *body = ast_str_alloca(size);
2137  char tuple_id[64];
2138 
2139  generate_random_string(tuple_id, sizeof(tuple_id));
2140 
2141  /* We'll make this a bare-bones pidf body. In state_notify_build_xml, the PIDF
2142  * body gets a lot more extra junk that isn't necessary, so we'll leave it out here.
2143  */
2144  ast_str_append(&body, 0, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
2145  /* XXX The entity attribute is currently set to the peer name associated with the
2146  * dialog. This is because we currently only call this function for call-completion
2147  * PUBLISH bodies. In such cases, the entity is completely disregarded. For other
2148  * event packages, it may be crucial to have a proper URI as the presentity so this
2149  * should be revisited as support is expanded.
2150  */
2151  ast_str_append(&body, 0, "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" entity=\"%s\">\n", presentity);
2152  ast_str_append(&body, 0, "<tuple id=\"%s\">\n", tuple_id);
2153  ast_str_append(&body, 0, "<status><basic>%s</basic></status>\n", state == CC_OPEN ? "open" : "closed");
2154  ast_str_append(&body, 0, "</tuple>\n");
2155  ast_str_append(&body, 0, "</presence>\n");
2156  ast_copy_string(pidf_body, ast_str_buffer(body), size);
2157  return 0;
2158 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
#define ast_str_alloca(init_len)
Definition: strings.h:800
Definition: sip.h:1546
static char * generate_random_string(char *buf, size_t size)
Generate 32 byte random string for callid&#39;s etc.
Definition: chan_sip.c:8797
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401

◆ copy_all_header()

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

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

Referenced by respprep().

11955 {
11956  int start = 0;
11957  int copied = 0;
11958  for (;;) {
11959  const char *tmp = __get_header(orig, field, &start);
11960 
11961  if (ast_strlen_zero(tmp))
11962  break;
11963  /* Add what we're responding to */
11964  add_header(req, field, tmp);
11965  copied++;
11966  }
11967  return copied ? 0 : -1;
11968 }
static int tmp()
Definition: bt_open.c:389
#define ast_strlen_zero(foo)
Definition: strings.h:52
static const char * __get_header(const struct sip_request *req, const char *name, int *start)
Definition: chan_sip.c:8562
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873

◆ copy_header()

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

References add_header(), ast_log, ast_strlen_zero, LOG_NOTICE, sip_get_header(), and tmp().

Referenced by reqprep(), and respprep().

11944 {
11945  const char *tmp = sip_get_header(orig, field);
11946 
11947  if (!ast_strlen_zero(tmp)) /* Add what we're responding to */
11948  return add_header(req, field, tmp);
11949  ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field);
11950  return -1;
11951 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
static int tmp()
Definition: bt_open.c:389
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#define LOG_NOTICE
Definition: logger.h:263
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873

◆ copy_request()

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

References ast_str_copy_string(), ast_str_create, ast_str_strlen(), sip_request::content, and sip_request::data.

Referenced by forked_invite_init(), handle_request_bye(), handle_request_invite(), handle_request_options(), handle_request_register(), handle_request_subscribe(), initialize_initreq(), parse_copy(), and receive_message().

14062 {
14063  /* XXX this function can encounter memory allocation errors, perhaps it
14064  * should return a value */
14065 
14066  struct ast_str *duplicate = dst->data;
14067  struct ast_str *duplicate_content = dst->content;
14068 
14069  /* copy the entire request then restore the original data and content
14070  * members from the dst request */
14071  *dst = *src;
14072  dst->data = duplicate;
14073  dst->content = duplicate_content;
14074 
14075  /* copy the data into the dst request */
14076  if (!dst->data && !(dst->data = ast_str_create(ast_str_strlen(src->data) + 1))) {
14077  return;
14078  }
14079  ast_str_copy_string(&dst->data, src->data);
14080 
14081  /* copy the content into the dst request (if it exists) */
14082  if (src->content) {
14083  if (!dst->content && !(dst->content = ast_str_create(ast_str_strlen(src->content) + 1))) {
14084  return;
14085  }
14086  ast_str_copy_string(&dst->content, src->content);
14087  }
14088 }
int ast_str_copy_string(struct ast_str **dst, struct ast_str *src)
Definition: strings.h:798
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
struct ast_str * data
Definition: sip.h:843
struct ast_str * content
Definition: sip.h:844
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ copy_socket_data()

static void copy_socket_data ( struct sip_socket to_sock,
const struct sip_socket from_sock 
)
static

Definition at line 5952 of file chan_sip.c.

References ao2_ref, ast_websocket_ref(), ast_websocket_unref(), NULL, sip_socket::tcptls_session, and sip_socket::ws_session.

Referenced by create_addr_from_peer(), handle_request_do(), parse_register_contact(), sip_poke_peer(), and transmit_response_using_temp().

5953 {
5954  if (to_sock->tcptls_session) {
5955  ao2_ref(to_sock->tcptls_session, -1);
5956  to_sock->tcptls_session = NULL;
5957  } else if (to_sock->ws_session) {
5958  ast_websocket_unref(to_sock->ws_session);
5959  to_sock->ws_session = NULL;
5960  }
5961 
5962  if (from_sock->tcptls_session) {
5963  ao2_ref(from_sock->tcptls_session, +1);
5964  } else if (from_sock->ws_session) {
5965  ast_websocket_ref(from_sock->ws_session);
5966  }
5967 
5968  *to_sock = *from_sock;
5969 }
#define NULL
Definition: resample.c:96
struct ast_websocket * ws_session
Definition: sip.h:802
void AST_OPTIONAL_API_NAME() ast_websocket_ref(struct ast_websocket *session)
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_tcptls_session_instance * tcptls_session
Definition: sip.h:801
void AST_OPTIONAL_API_NAME() ast_websocket_unref(struct ast_websocket *session)

◆ copy_vars()

static struct ast_variable * copy_vars ( struct ast_variable src)
static

duplicate a list of channel variables,

Returns
the copy.

Definition at line 2525 of file chan_sip.c.

References ast_variable_new, ast_variable::next, NULL, and tmp().

Referenced by check_peer_ok(), and create_addr_from_peer().

2526 {
2527  struct ast_variable *res = NULL, *tmp, *v = NULL;
2528 
2529  for (v = src ; v ; v = v->next) {
2530  if ((tmp = ast_variable_new(v->name, v->value, v->file))) {
2531  tmp->next = res;
2532  res = tmp;
2533  }
2534  }
2535  return res;
2536 }
struct ast_variable * next
static int tmp()
Definition: bt_open.c:389
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96
#define ast_variable_new(name, value, filename)

◆ copy_via_headers()

static int copy_via_headers ( struct sip_pvt p,
struct sip_request req,
const struct sip_request orig,
const char *  field 
)
static

Copy SIP VIA Headers from the request to the response.

Note
If the client indicates that it wishes to know the port we received from, it adds ;rport without an argument to the topmost via header. We need to add the port number (from our point of view) to that parameter.
   We always add ;received=<ip address> to the topmost via header.
Received: RFC 3261, rport RFC 3581

Definition at line 11978 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, end, sip_pvt::flags, LOG_NOTICE, NULL, sip_pvt::recv, SIP_NAT_FORCE_RPORT, and SIP_NAT_RPORT_PRESENT.

Referenced by respprep().

11979 {
11980  int copied = 0;
11981  int start = 0;
11982 
11983  for (;;) {
11984  char new[512];
11985  const char *oh = __get_header(orig, field, &start);
11986 
11987  if (ast_strlen_zero(oh))
11988  break;
11989 
11990  if (!copied) { /* Only check for empty rport in topmost via header */
11991  char leftmost[512], *others, *rport;
11992 
11993  /* Only work on leftmost value */
11994  ast_copy_string(leftmost, oh, sizeof(leftmost));
11995  others = strchr(leftmost, ',');
11996  if (others)
11997  *others++ = '\0';
11998 
11999  /* Find ;rport; (empty request) */
12000  rport = strstr(leftmost, ";rport");
12001  if (rport && *(rport+6) == '=')
12002  rport = NULL; /* We already have a parameter to rport */
12003 
12004  if (((ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT)) || (rport && ast_test_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT)))) {
12005  /* We need to add received port - rport */
12006  char *end;
12007 
12008  rport = strstr(leftmost, ";rport");
12009 
12010  if (rport) {
12011  end = strchr(rport + 1, ';');
12012  if (end)
12013  memmove(rport, end, strlen(end) + 1);
12014  else
12015  *rport = '\0';
12016  }
12017 
12018  /* Add rport to first VIA header if requested */
12019  snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s",
12021  ast_sockaddr_port(&p->recv),
12022  others ? "," : "", others ? others : "");
12023  } else {
12024  /* We should *always* add a received to the topmost via */
12025  snprintf(new, sizeof(new), "%s;received=%s%s%s",
12027  others ? "," : "", others ? others : "");
12028  }
12029  oh = new; /* the header to copy */
12030  } /* else add the following via headers untouched */
12031  add_header(req, field, oh);
12032  copied++;
12033  }
12034  if (!copied) {
12035  ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field);
12036  return -1;
12037  }
12038  return 0;
12039 }
static char * ast_sockaddr_stringify_addr_remote(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:317
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_sockaddr recv
Definition: sip.h:1135
#define SIP_NAT_FORCE_RPORT
Definition: sip.h:283
struct ast_flags flags[3]
Definition: sip.h:1075
#define NULL
Definition: resample.c:96
char * end
Definition: eagi_proxy.c:73
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:521
#define ast_log
Definition: astobj2.c:42
static const char * __get_header(const struct sip_request *req, const char *name, int *start)
Definition: chan_sip.c:8562
#define LOG_NOTICE
Definition: logger.h:263
#define SIP_NAT_RPORT_PRESENT
Definition: sip.h:284
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873

◆ create_addr()

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

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

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

Definition at line 6317 of file chan_sip.c.

References sip_pvt::allowed_methods, 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, AST_TRANSPORT_UDP, create_addr_from_peer(), default_sip_port(), dialog_initialize_rtp(), sip_settings::disallowed_methods, FALSE, FINDPEERS, get_srv_protocol(), get_srv_service(), global_rtpholdtimeout, global_rtpkeepalive, global_rtptimeout, global_t1, global_timer_b, host, LOG_WARNING, MAXHOSTNAMELEN, NULL, obproxy_get(), sip_monitor_instance::peername, sip_pvt::portinuri, sip_pvt::recv, ref_proxy(), sip_pvt::relatedpeer, sip_pvt::rtpholdtimeout, sip_pvt::rtpkeepalive, sip_pvt::rtptimeout, sip_pvt::sa, service, set_socket_transport(), sip_cfg, sip_find_peer(), sip_ref_peer, sip_unref_peer, sip_pvt::socket, sip_settings::srvlookup, sip_pvt::timer_b, sip_pvt::timer_t1, TRUE, and sip_socket::type.

Referenced by __sip_subscribe_mwi_do(), manager_sipnotify(), sip_cc_monitor_request_cc(), sip_cli_notify(), sip_msg_send(), sip_request_call(), transmit_publish(), and transmit_register().

6318 {
6319  struct sip_peer *peer;
6320  char *peername, *peername2, *hostn;
6321  char host[MAXHOSTNAMELEN];
6322  char service[MAXHOSTNAMELEN];
6323  int srv_ret = 0;
6324  int tportno;
6325 
6326  AST_DECLARE_APP_ARGS(hostport,
6327  AST_APP_ARG(host);
6328  AST_APP_ARG(port);
6329  );
6330 
6331  peername = ast_strdupa(opeer);
6332  peername2 = ast_strdupa(opeer);
6333  AST_NONSTANDARD_RAW_ARGS(hostport, peername2, ':');
6334 
6335  if (hostport.port)
6336  dialog->portinuri = 1;
6337 
6338  dialog->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */
6339  dialog->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */
6340  peer = sip_find_peer(peername, NULL, TRUE, FINDPEERS, FALSE, 0);
6341 
6342  if (peer) {
6343  int res;
6344  if (newdialog) {
6345  set_socket_transport(&dialog->socket, 0);
6346  }
6347  res = create_addr_from_peer(dialog, peer);
6348  dialog->relatedpeer = sip_ref_peer(peer, "create_addr: setting dialog's relatedpeer pointer");
6349  sip_unref_peer(peer, "create_addr: unref peer from sip_find_peer hashtab lookup");
6350  return res;
6351  } else if (ast_check_digits(peername)) {
6352  /* Although an IPv4 hostname *could* be represented as a 32-bit integer, it is uncommon and
6353  * it makes dialing SIP/${EXTEN} for a peer that isn't defined resolve to an IP that is
6354  * almost certainly not intended. It is much better to just reject purely numeric hostnames */
6355  ast_log(LOG_WARNING, "Purely numeric hostname (%s), and not a peer--rejecting!\n", peername);
6356  return -1;
6357  } else {
6358  dialog->rtptimeout = global_rtptimeout;
6361  if (dialog_initialize_rtp(dialog)) {
6362  return -1;
6363  }
6364  }
6365 
6366  ast_string_field_set(dialog, tohost, hostport.host);
6368 
6369  /* Get the outbound proxy information */
6370  ref_proxy(dialog, obproxy_get(dialog, NULL));
6371 
6372  if (addr) {
6373  /* This address should be updated using dnsmgr */
6374  ast_sockaddr_copy(&dialog->sa, addr);
6375  } else {
6376 
6377  /* Let's see if we can find the host in DNS. First try DNS SRV records,
6378  then hostname lookup */
6379  /*! \todo Fix this function. When we ask for SRV, we should check all transports
6380  In the future, we should first check NAPTR to find out transport preference
6381  */
6382  hostn = peername;
6383  /* Section 4.2 of RFC 3263 specifies that if a port number is specified, then
6384  * an A record lookup should be used instead of SRV.
6385  */
6386  if (!hostport.port && sip_cfg.srvlookup) {
6387  snprintf(service, sizeof(service), "_%s._%s.%s",
6388  get_srv_service(dialog->socket.type),
6389  get_srv_protocol(dialog->socket.type), peername);
6390  if ((srv_ret = ast_get_srv(NULL, host, sizeof(host), &tportno,
6391  service)) > 0) {
6392  hostn = host;
6393  }
6394  }
6395 
6396  if (ast_sockaddr_resolve_first_transport(&dialog->sa, hostn, 0, dialog->socket.type ? dialog->socket.type : AST_TRANSPORT_UDP)) {
6397  ast_log(LOG_WARNING, "No such host: %s\n", peername);
6398  return -1;
6399  }
6400 
6401  if (srv_ret > 0) {
6402  ast_sockaddr_set_port(&dialog->sa, tportno);
6403  }
6404  }
6405 
6406  if (!dialog->socket.type) {
6408  }
6409 
6410  if (!ast_sockaddr_port(&dialog->sa)) {
6411  ast_sockaddr_set_port(&dialog->sa, default_sip_port(dialog->socket.type));
6412  }
6413  ast_sockaddr_copy(&dialog->recv, &dialog->sa);
6414  return 0;
6415 }
#define FALSE
Definition: app_minivm.c:521
unsigned int allowed_methods
Definition: sip.h:1196
int rtpholdtimeout
Definition: sip.h:1132
struct sip_peer * sip_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.
Definition: chan_sip.c:5851
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:171
struct sip_peer * relatedpeer
Definition: sip.h:1171
unsigned int portinuri
Definition: sip.h:1124
#define LOG_WARNING
Definition: logger.h:274
struct ast_sockaddr recv
Definition: sip.h:1135
struct sip_socket socket
Definition: sip.h:1066
static int global_rtptimeout
Definition: chan_sip.c:823
unsigned int disallowed_methods
Definition: sip.h:772
enum ast_cc_service_type service
Definition: chan_sip.c:949
int rtpkeepalive
Definition: sip.h:1133
static const char * get_srv_protocol(enum ast_transport t)
Return protocol string for srv dns query.
Definition: chan_sip.c:3743
int srvlookup
Definition: sip.h:758
#define MAXHOSTNAMELEN
Definition: network.h:69
#define NULL
Definition: resample.c:96
#define sip_ref_peer(peer, tag)
Definition: sip.h:1894
const ast_string_field tohost
Definition: sip.h:1306
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:521
struct ast_sockaddr sa
Definition: sip.h:1125
#define ast_log
Definition: astobj2.c:42
int ast_get_srv(struct ast_channel *chan, char *host, int hostlen, int *port, const char *service)
Lookup entry in SRV records Returns 1 if found, 0 if not found, -1 on hangup.
Definition: srv.c:260
static char host[256]
Definition: muted.c:77
static struct sip_proxy * obproxy_get(struct sip_pvt *dialog, struct sip_peer *peer)
Get default outbound proxy or global proxy.
Definition: chan_sip.c:3549
int rtptimeout
Definition: sip.h:1131
static int dialog_initialize_rtp(struct sip_pvt *dialog)
Initialize RTP portion of a dialog.
Definition: chan_sip.c:6041
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define AST_NONSTANDARD_RAW_ARGS(args, parse, sep)
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:537
int timer_b
Definition: sip.h:1096
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
static int global_timer_b
Definition: chan_sip.c:849
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
int timer_t1
Definition: sip.h:1095
#define FINDPEERS
Definition: sip.h:53
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
static void ref_proxy(struct sip_pvt *pvt, struct sip_proxy *proxy)
maintain proper refcounts for a sip_pvt&#39;s outboundproxy
Definition: chan_sip.c:3293
int ast_check_digits(const char *arg)
Check if a string is only digits.
Definition: strings.h:1163
enum ast_transport type
Definition: sip.h:798
#define TRUE
Definition: app_minivm.c:518
static int global_t1
Definition: chan_sip.c:847
static int create_addr_from_peer(struct sip_pvt *r, struct sip_peer *peer)
Create address structure from peer reference. This function copies data from peer to the dialog...
Definition: chan_sip.c:6136
static int global_rtpholdtimeout
Definition: chan_sip.c:824
static const char * get_srv_service(enum ast_transport t)
Return service string for srv dns query.
Definition: chan_sip.c:3761
static int default_sip_port(enum ast_transport type)
The default sip port for the given transport.
Definition: chan_sip.c:6309
static void set_socket_transport(struct sip_socket *socket, int transport)
Definition: chan_sip.c:16629
static int global_rtpkeepalive
Definition: chan_sip.c:825
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
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. ...
Definition: chan_sip.c:34479
#define AST_APP_ARG(name)
Define an application argument.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ create_addr_from_peer()

static int create_addr_from_peer ( struct sip_pvt dialog,
struct sip_peer peer 
)
static

Create address structure from peer reference. This function copies data from peer to the dialog, so we don't have to look up the peer again from memory or database during the life time of the dialog.

Returns
-1 on error, 0 on success.

Definition at line 6136 of file chan_sip.c.

References __set_address_from_contact(), accountcode, sip_peer::accountcode, sip_peer::addr, sip_pvt::allowtransfer, sip_peer::allowtransfer, sip_pvt::amaflags, sip_peer::amaflags, ao2_lock, ao2_t_ref, ao2_unlock, ast_alloca, ast_cc_copy_config_params(), ast_copy_flags, ast_copy_string(), ast_duplicate_acl_list(), ast_format_cap_append_from_cap(), ast_format_cap_get_framing(), ast_format_cap_remove_by_type(), AST_MEDIA_TYPE_UNKNOWN, ast_ref_namedgroups(), ast_rtp_codecs_set_framing(), ast_rtp_dtls_cfg_copy(), 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, AST_TRANSPORT_TLS, ast_unref_namedgroups(), sip_peer::auth, sip_pvt::autoframing, sip_peer::autoframing, sip_peer::call_limit, sip_pvt::callgroup, sip_peer::callgroup, sip_pvt::callid, sip_pvt::callingpres, sip_peer::callingpres, sip_pvt::caps, sip_peer::caps, sip_pvt::cc_params, sip_peer::cc_params, change_callid_pvt(), sip_pvt::chanvars, sip_peer::chanvars, check_request_transport, cid_name, sip_peer::cid_name, cid_num, sip_peer::cid_num, sip_peer::cid_tag, context, sip_peer::context, copy_socket_data(), copy_vars(), sip_peer::defaddr, dialog_initialize_rtp(), sip_pvt::directmediaacl, sip_peer::directmediaacl, sip_pvt::disallowed_methods, sip_peer::disallowed_methods, sip_pvt::dtls_cfg, sip_peer::dtls_cfg, sip_peer::engine, sip_pvt::flags, sip_peer::flags, sip_peer::fromdomain, sip_pvt::fromdomainport, sip_peer::fromdomainport, sip_peer::fromuser, sip_peer::fullcontact, global_t1min, sip_request::headers, sip_pvt::initreq, sip_pvt::jointnoncodeccapability, language, sip_peer::language, sip_peer::lastms, sip_pvt::maxcallbitrate, sip_peer::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, mohinterpret, sip_peer::mohinterpret, mohsuggest, sip_peer::mohsuggest, sip_peer::mwi_from, sip_peer::name, sip_pvt::named_callgroups, sip_peer::named_callgroups, sip_pvt::named_pickupgroups, sip_peer::named_pickupgroups, sip_pvt::noncodeccapability, obproxy_get(), parkinglot, sip_peer::parkinglot, sip_peer::path, sip_pvt::peerauth, sip_monitor_instance::peername, sip_pvt::pickupgroup, sip_peer::pickupgroup, sip_pvt::portinuri, sip_peer::portinuri, sip_pvt::recv, ref_proxy(), sip_pvt::route, sip_pvt::rtp, sip_pvt::rtpholdtimeout, sip_peer::rtpholdtimeout, sip_pvt::rtpkeepalive, sip_peer::rtpkeepalive, sip_pvt::rtptimeout, sip_peer::rtptimeout, sip_pvt::sa, sip_peer::secret, SIP_CALL_LIMIT, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE3_FLAGS_TO_COPY, sip_route_copy(), sip_route_empty, sip_route_first_uri(), sip_pvt::socket, sip_peer::socket, sip_pvt::timer_b, sip_peer::timer_b, sip_pvt::timer_t1, sip_peer::timer_t1, sip_pvt::tohost, sip_peer::tohost, sip_socket::type, sip_peer::username, sip_pvt::zone, and sip_peer::zone.

Referenced by create_addr(), and sip_send_mwi_to_peer().

6137 {
6138  struct sip_auth_container *credentials;
6139 
6140  /* this checks that the dialog is contacting the peer on a valid
6141  * transport type based on the peers transport configuration,
6142  * otherwise, this function bails out */
6143  if (dialog->socket.type && check_request_transport(peer, dialog))
6144  return -1;
6145  copy_socket_data(&dialog->socket, &peer->socket);
6146 
6147  if (!(ast_sockaddr_isnull(&peer->addr) && ast_sockaddr_isnull(&peer->defaddr)) &&
6148  (!peer->maxms || ((peer->lastms >= 0) && (peer->lastms <= peer->maxms)))) {
6149  dialog->sa = ast_sockaddr_isnull(&peer->addr) ? peer->defaddr : peer->addr;
6150  dialog->recv = dialog->sa;
6151  } else
6152  return -1;
6153 
6154  /* XXX TODO: get flags directly from peer only as they are needed using dialog->relatedpeer */
6155  ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
6156  ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
6157  ast_copy_flags(&dialog->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY);
6158  /* Take the peer's caps */
6159  if (peer->caps) {
6162  }
6163  dialog->amaflags = peer->amaflags;
6164 
6165  ast_string_field_set(dialog, engine, peer->engine);
6166 
6167  ast_rtp_dtls_cfg_copy(&peer->dtls_cfg, &dialog->dtls_cfg);
6168 
6169  dialog->rtptimeout = peer->rtptimeout;
6170  dialog->rtpholdtimeout = peer->rtpholdtimeout;
6171  dialog->rtpkeepalive = peer->rtpkeepalive;
6172  sip_route_copy(&dialog->route, &peer->path);
6173  if (!sip_route_empty(&dialog->route)) {
6174  /* Parse SIP URI of first route-set hop and use it as target address */
6175  __set_address_from_contact(sip_route_first_uri(&dialog->route), &dialog->sa, dialog->socket.type == AST_TRANSPORT_TLS ? 1 : 0);
6176  }
6177 
6178  if (dialog_initialize_rtp(dialog)) {
6179  return -1;
6180  }
6181 
6182  if (dialog->rtp) { /* Audio */
6185  /* Set Frame packetization */
6186  dialog->autoframing = peer->autoframing;
6188  }
6189 
6190  /* XXX TODO: get fields directly from peer only as they are needed using dialog->relatedpeer */
6191  ast_string_field_set(dialog, peername, peer->name);
6192  ast_string_field_set(dialog, authname, peer->username);
6193  ast_string_field_set(dialog, username, peer->username);
6194  ast_string_field_set(dialog, peersecret, peer->secret);
6195  ast_string_field_set(dialog, peermd5secret, peer->md5secret);
6196  ast_string_field_set(dialog, mohsuggest, peer->mohsuggest);
6198  ast_string_field_set(dialog, tohost, peer->tohost);
6199  ast_string_field_set(dialog, fullcontact, peer->fullcontact);
6201  ast_string_field_set(dialog, context, peer->context);
6202  ast_string_field_set(dialog, cid_num, peer->cid_num);
6203  ast_string_field_set(dialog, cid_name, peer->cid_name);
6204  ast_string_field_set(dialog, cid_tag, peer->cid_tag);
6205  ast_string_field_set(dialog, mwi_from, peer->mwi_from);
6206  if (!ast_strlen_zero(peer->parkinglot)) {
6207  ast_string_field_set(dialog, parkinglot, peer->parkinglot);
6208  }
6209  ast_string_field_set(dialog, engine, peer->engine);
6210  ref_proxy(dialog, obproxy_get(dialog, peer));
6211  dialog->callgroup = peer->callgroup;
6212  dialog->pickupgroup = peer->pickupgroup;
6217  ast_copy_string(dialog->zone, peer->zone, sizeof(dialog->zone));
6218  dialog->allowtransfer = peer->allowtransfer;
6219  dialog->jointnoncodeccapability = dialog->noncodeccapability;
6220 
6221  /* Update dialog authorization credentials */
6222  ao2_lock(peer);
6223  credentials = peer->auth;
6224  if (credentials) {
6225  ao2_t_ref(credentials, +1, "Ref peer auth for dialog");
6226  }
6227  ao2_unlock(peer);
6228  ao2_lock(dialog);
6229  if (dialog->peerauth) {
6230  ao2_t_ref(dialog->peerauth, -1, "Unref old dialog peer auth");
6231  }
6232  dialog->peerauth = credentials;
6233  ao2_unlock(dialog);
6234 
6235  dialog->maxcallbitrate = peer->maxcallbitrate;
6236  dialog->disallowed_methods = peer->disallowed_methods;
6238  if (ast_strlen_zero(dialog->tohost))
6239  ast_string_field_set(dialog, tohost, ast_sockaddr_stringify_host_remote(&dialog->sa));
6240  if (!ast_strlen_zero(peer->fromdomain)) {
6241  ast_string_field_set(dialog, fromdomain, peer->fromdomain);
6242  if (!dialog->initreq.headers) {
6243  char *new_callid;
6244  char *tmpcall = ast_strdupa(dialog->callid);
6245  /* this sure looks to me like we are going to change the callid on this dialog!! */
6246  new_callid = strchr(tmpcall, '@');
6247  if (new_callid) {
6248  int callid_size;
6249 
6250  *new_callid = '\0';
6251 
6252  /* Change the dialog callid. */
6253  callid_size = strlen(tmpcall) + strlen(peer->fromdomain) + 2;
6254  new_callid = ast_alloca(callid_size);
6255  snprintf(new_callid, callid_size, "%s@%s", tmpcall, peer->fromdomain);
6256  change_callid_pvt(dialog, new_callid);
6257  }
6258  }
6259  }
6260  if (!ast_strlen_zero(peer->fromuser)) {
6261  ast_string_field_set(dialog, fromuser, peer->fromuser);
6262  }
6263  if (!ast_strlen_zero(peer->language)) {
6264  ast_string_field_set(dialog, language, peer->language);
6265  }
6266  /* Set timer T1 to RTT for this peer (if known by qualify=) */
6267  /* Minimum is settable or default to 100 ms */
6268  /* If there is a maxms and lastms from a qualify use that over a manual T1
6269  value. Otherwise, use the peer's T1 value. */
6270  if (peer->maxms && peer->lastms) {
6271  dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms;
6272  } else {
6273  dialog->timer_t1 = peer->timer_t1;
6274  }
6275 
6276  /* Set timer B to control transaction timeouts, the peer setting is the default and overrides
6277  the known timer */
6278  if (peer->timer_b) {
6279  dialog->timer_b = peer->timer_b;
6280  } else {
6281  dialog->timer_b = 64 * dialog->timer_t1;
6282  }
6283 
6284  if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
6285  (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) {
6286  dialog->noncodeccapability |= AST_RTP_DTMF;
6287  } else {
6288  dialog->noncodeccapability &= ~AST_RTP_DTMF;
6289  }
6290 
6292 
6293  if (peer->call_limit) {
6294  ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT);
6295  }
6296  if (!dialog->portinuri) {
6297  dialog->portinuri = peer->portinuri;
6298  }
6299  dialog->chanvars = copy_vars(peer->chanvars);
6300  if (peer->fromdomainport) {
6301  dialog->fromdomainport = peer->fromdomainport;
6302  }
6303  dialog->callingpres = peer->callingpres;
6304 
6305  return 0;
6306 }
#define check_request_transport(peer, tmpl)
generic function for determining if a correct transport is being used to contact a peer ...
Definition: chan_sip.c:2498
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
static char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: chan_iax2.c:428
struct ast_cc_config_params * cc_params
Definition: sip.h:1218
static char mohinterpret[MAX_MUSICCLASS]
Definition: chan_alsa.c:119
struct ast_namedgroups * named_pickupgroups
Definition: sip.h:1349
struct ast_sockaddr addr
Definition: sip.h:1352
int maxms
Definition: sip.h:1357
int timer_t1
Definition: sip.h:1369
void sip_route_copy(struct sip_route *dst, const struct sip_route *src)
copy route-set
Definition: route.c:115
unsigned int ast_format_cap_get_framing(const struct ast_format_cap *cap)
Get the global framing.
Definition: format_cap.c:438
int fromdomainport
Definition: sip.h:1220
static char parkinglot[AST_MAX_CONTEXT]
Definition: chan_mgcp.c:163
int rtpholdtimeout
Definition: sip.h:1132
ast_group_t callgroup
Definition: sip.h:1070
const ast_string_field language
Definition: sip.h:1306
const ast_string_field parkinglot
Definition: sip.h:1306
const ast_string_field mohsuggest
Definition: sip.h:1306
const ast_string_field mwi_from
Definition: sip.h:1306
int maxcallbitrate
Definition: sip.h:1106
struct ast_rtp_dtls_cfg dtls_cfg
Definition: sip.h:1381
#define ast_test_flag(p, flag)
Definition: utils.h:63
int rtpholdtimeout
Definition: sip.h:1344
int amaflags
Definition: sip.h:1146
static int global_t1min
Definition: chan_sip.c:848
const ast_string_field accountcode
Definition: sip.h:1306
unsigned int portinuri
Definition: sip.h:1124
#define ast_set_flag(p, flag)
Definition: utils.h:70
struct ast_rtp_codecs * ast_rtp_instance_get_codecs(struct ast_rtp_instance *instance)
Get the codecs structure of an RTP instance.
Definition: rtp_engine.c:727
struct ast_sockaddr recv
Definition: sip.h:1135
struct sip_socket socket
Definition: sip.h:1066
struct ast_namedgroups * named_pickupgroups
Definition: sip.h:1073
#define SIP_DTMF_RFC2833
Definition: sip.h:276
struct ast_sockaddr defaddr
Definition: sip.h:1362
struct ast_namedgroups * named_callgroups
Definition: sip.h:1072
#define SIP_CALL_LIMIT
Definition: sip.h:264
struct ast_acl_list * directmediaacl
Definition: sip.h:1134
int rtpkeepalive
Definition: sip.h:1133
#define ao2_unlock(a)
Definition: astobj2.h:730
struct ast_flags flags[3]
Definition: sip.h:1075
struct sip_route path
Definition: sip.h:1372
#define ast_copy_flags(dest, src, flagz)
Definition: utils.h:84
#define SIP_PAGE2_RFC2833_COMPENSATE
Definition: sip.h:356
void ast_rtp_codecs_set_framing(struct ast_rtp_codecs *codecs, unsigned int framing)
Set the framing used for a set of codecs.
Definition: rtp_engine.c:1558
static char cid_num[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:164
int jointnoncodeccapability
Definition: sip.h:1105
char name[80]
Definition: sip.h:1274
struct ast_variable * chanvars
Definition: sip.h:1366
#define ast_strlen_zero(foo)
Definition: strings.h:52
const ast_string_field tohost
Definition: sip.h:1306
int rtptimeout
Definition: sip.h:1343
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
char zone[MAX_TONEZONE_COUNTRY]
Definition: sip.h:1116
enum transfermodes allowtransfer
Definition: sip.h:1332
struct ast_sockaddr sa
Definition: sip.h:1125
struct ast_rtp_dtls_cfg dtls_cfg
Definition: sip.h:1222
int lastms
Definition: sip.h:1356
struct ast_namedgroups * named_callgroups
Definition: sip.h:1348
#define sip_route_empty(route)
Check if route has no URI&#39;s.
Definition: route.h:118
struct ast_acl_list * ast_duplicate_acl_list(struct ast_acl_list *original)
Duplicates the contests of a list of lists of host access rules.
Definition: acl.c:316
int noncodeccapability
Definition: sip.h:1104
static struct sip_proxy * obproxy_get(struct sip_pvt *dialog, struct sip_peer *peer)
Get default outbound proxy or global proxy.
Definition: chan_sip.c:3549
int amaflags
Definition: sip.h:1323
int rtptimeout
Definition: sip.h:1131
static int dialog_initialize_rtp(struct sip_pvt *dialog)
Initialize RTP portion of a dialog.
Definition: chan_sip.c:6041
struct ast_format_cap * caps
Definition: sip.h:1099
struct sip_request initreq
Definition: sip.h:1151
static char mohsuggest[MAX_MUSICCLASS]
Definition: chan_iax2.c:430
int call_limit
Definition: sip.h:1328
#define ao2_lock(a)
Definition: astobj2.h:718
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
const ast_string_field username
Definition: sip.h:1306
#define SIP_PAGE3_FLAGS_TO_COPY
Definition: sip.h:396
unsigned short autoframing
Definition: sip.h:1089
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
int maxcallbitrate
Definition: sip.h:1340
const ast_string_field md5secret
Definition: sip.h:1306
static void copy_socket_data(struct sip_socket *to_sock, const struct sip_socket *from_sock)
Definition: chan_sip.c:5952
int timer_b
Definition: sip.h:1370
int callingpres
Definition: sip.h:1117
void ast_format_cap_remove_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Remove all formats matching a specific format type.
Definition: format_cap.c:525
struct ast_acl_list * directmediaacl
Definition: sip.h:1365
#define SIP_PAGE2_FLAGS_TO_COPY
Definition: sip.h:375
struct sip_route route
Definition: sip.h:1139
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
struct ast_cc_config_params * cc_params
Definition: sip.h:1377
const ast_string_field mohinterpret
Definition: sip.h:1306
const ast_string_field callid
Definition: sip.h:1063
struct ast_format_cap * caps
Definition: sip.h:1342
const ast_string_field zone
Definition: sip.h:1306
const ast_string_field fromdomain
Definition: sip.h:1306
const ast_string_field fullcontact
Definition: sip.h:1306
static struct ast_variable * copy_vars(struct ast_variable *src)
duplicate a list of channel variables,
Definition: chan_sip.c:2525
unsigned int disallowed_methods
Definition: sip.h:1201
static void change_callid_pvt(struct sip_pvt *pvt, const char *callid)
Definition: chan_sip.c:8860
int timer_b
Definition: sip.h:1096
int headers
Definition: sip.h:832
struct ast_namedgroups * ast_ref_namedgroups(struct ast_namedgroups *groups)
Definition: channel.c:7838
static int __set_address_from_contact(const char *fullcontact, struct ast_sockaddr *addr, int tcp)
Definition: chan_sip.c:16892
static char * ast_sockaddr_stringify_host_remote(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only, suitable for a URL (with brack...
Definition: netsock2.h:349
#define SIP_FLAGS_TO_COPY
Flags to copy from peer/user to dialog.
Definition: sip.h:313
int timer_t1
Definition: sip.h:1095
int rtpkeepalive
Definition: sip.h:1345
struct ast_rtp_instance * rtp
Definition: sip.h:1174
void ast_cc_copy_config_params(struct ast_cc_config_params *dest, const struct ast_cc_config_params *src)
copy CCSS configuration parameters from one structure to another
Definition: ccss.c:861
static void ref_proxy(struct sip_pvt *pvt, struct sip_proxy *proxy)
maintain proper refcounts for a sip_pvt&#39;s outboundproxy
Definition: chan_sip.c:3293
unsigned short autoframing
Definition: sip.h:1317
static char cid_name[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:165
ast_group_t callgroup
Definition: sip.h:1346
const ast_string_field cid_name
Definition: sip.h:1306
struct sip_auth_container * auth
Definition: sip.h:1322
enum transfermodes allowtransfer
Definition: sip.h:1137
#define SIP_DTMF
Definition: sip.h:275
enum ast_transport type
Definition: sip.h:798
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
struct ast_flags flags[3]
Definition: sip.h:1335
unsigned int portinuri
Definition: sip.h:1353
const ast_string_field secret
Definition: sip.h:1306
const ast_string_field tohost
Definition: sip.h:1063
const ast_string_field cid_num
Definition: sip.h:1306
const ast_string_field fromuser
Definition: sip.h:1306
int callingpres
Definition: sip.h:1324
void ast_rtp_instance_set_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value)
Set the value of an RTP instance property.
Definition: rtp_engine.c:705
int ast_format_cap_append_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type)
Append the formats of provided type in src to dst.
Definition: format_cap.c:269
struct ast_namedgroups * ast_unref_namedgroups(struct ast_namedgroups *groups)
Definition: channel.c:7832
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
void ast_rtp_dtls_cfg_copy(const struct ast_rtp_dtls_cfg *src_cfg, struct ast_rtp_dtls_cfg *dst_cfg)
Copy contents of a DTLS configuration structure.
Definition: rtp_engine.c:3113
#define AST_RTP_DTMF
Definition: rtp_engine.h:266
struct sip_socket socket
Definition: sip.h:1307
const ast_string_field cid_tag
Definition: sip.h:1306
const ast_string_field engine
Definition: sip.h:1306
Container of SIP authentication credentials.
Definition: sip.h:911
const char * sip_route_first_uri(const struct sip_route *route)
Get the URI of the route&#39;s first hop.
Definition: route.c:199
#define SIP_DTMF_AUTO
Definition: sip.h:279
struct ast_variable * chanvars
Definition: sip.h:1180
ast_group_t pickupgroup
Definition: sip.h:1071
int fromdomainport
Definition: sip.h:1371
ast_group_t pickupgroup
Definition: sip.h:1347
const ast_string_field context
Definition: sip.h:1306
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514
struct sip_auth_container * peerauth
Definition: sip.h:1141
unsigned int disallowed_methods
Definition: sip.h:1376

◆ create_epa_entry()

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

Definition at line 1692 of file chan_sip.c.

References ao2_t_alloc, ast_copy_string(), sip_epa_entry::destination, epa_static_data::destructor, find_static_data(), NULL, and sip_epa_entry::static_data.

Referenced by sip_cc_monitor_suspend().

1693 {
1694  struct sip_epa_entry *epa_entry;
1695  const struct epa_static_data *static_data;
1696 
1697  if (!(static_data = find_static_data(event_package))) {
1698  return NULL;
1699  }
1700 
1701  if (!(epa_entry = ao2_t_alloc(sizeof(*epa_entry), static_data->destructor, "Allocate new EPA entry"))) {
1702  return NULL;
1703  }
1704 
1705  epa_entry->static_data = static_data;
1706  ast_copy_string(epa_entry->destination, destination, sizeof(epa_entry->destination));
1707  return epa_entry;
1708 }
Definition: sip.h:1644
#define ao2_t_alloc(data_size, destructor_fn, debug_msg)
Definition: astobj2.h:409
const struct epa_static_data * static_data
Definition: sip.h:1674
#define NULL
Definition: resample.c:96
static const struct epa_static_data * find_static_data(const char *const event_package)
Definition: chan_sip.c:1678
char destination[SIPBUFSIZE]
Definition: sip.h:1661
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
void(* destructor)(void *instance_data)
Definition: sip.h:1633

◆ create_esc_entry()

static struct sip_esc_entry* create_esc_entry ( struct event_state_compositor esc,
struct sip_request req,
const int  expires 
)
static

Definition at line 1790 of file chan_sip.c.

References ao2_alloc, ao2_ref, ast_sched_add(), create_new_sip_etag(), esc_entry_destructor(), sip_esc_entry::event, event_state_compositor::name, NULL, publish_expire(), and sip_esc_entry::sched_id.

Referenced by handle_sip_publish_initial().

1791 {
1792  struct sip_esc_entry *esc_entry;
1793  int expires_ms;
1794 
1795  if (!(esc_entry = ao2_alloc(sizeof(*esc_entry), esc_entry_destructor))) {
1796  return NULL;
1797  }
1798 
1799  esc_entry->event = esc->name;
1800 
1801  expires_ms = expires * 1000;
1802  /* Bump refcount for scheduler */
1803  ao2_ref(esc_entry, +1);
1804  esc_entry->sched_id = ast_sched_add(sched, expires_ms, publish_expire, esc_entry);
1805  if (esc_entry->sched_id == -1) {
1806  ao2_ref(esc_entry, -1);
1807  ao2_ref(esc_entry, -1);
1808  return NULL;
1809  }
1810 
1811  /* Note: This links the esc_entry into the ESC properly */
1812  create_new_sip_etag(esc_entry, 0);
1813 
1814  return esc_entry;
1815 }
int sched_id
Definition: sip.h:1750
Definition: sched.c:76
#define NULL
Definition: resample.c:96
common ESC items for all event types
Definition: sip.h:1715
const char * name
Definition: chan_sip.c:998
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static void esc_entry_destructor(void *obj)
Definition: chan_sip.c:1721
static void create_new_sip_etag(struct sip_esc_entry *esc_entry, int is_linked)
Definition: chan_sip.c:1777
const char * event
Definition: sip.h:1734
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565
static int publish_expire(const void *data)
Definition: chan_sip.c:1764

◆ create_new_sip_etag()

static void create_new_sip_etag ( struct sip_esc_entry esc_entry,
int  is_linked 
)
static

Definition at line 1777 of file chan_sip.c.

References ao2_link, ao2_unlink, ast_assert, ast_atomic_fetchadd_int(), event_state_compositor::compositor, sip_esc_entry::entity_tag, esc_etag_counter, sip_esc_entry::event, get_esc(), and NULL.

Referenced by create_esc_entry(), and transmit_response_with_sip_etag().

1778 {
1779  int new_etag = ast_atomic_fetchadd_int(&esc_etag_counter, +1);
1780  struct event_state_compositor *esc = get_esc(esc_entry->event);
1781 
1782  ast_assert(esc != NULL);
1783  if (is_linked) {
1784  ao2_unlink(esc->compositor, esc_entry);
1785  }
1786  snprintf(esc_entry->entity_tag, sizeof(esc_entry->entity_tag), "%d", new_etag);
1787  ao2_link(esc->compositor, esc_entry);
1788 }
The Event State Compositors.
Definition: chan_sip.c:996
#define ast_assert(a)
Definition: utils.h:695
#define NULL
Definition: resample.c:96
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:755
static struct event_state_compositor * get_esc(const char *const event_package)
Definition: chan_sip.c:1743
const char * event
Definition: sip.h:1734
#define ao2_unlink(container, obj)
Definition: astobj2.h:1598
static int esc_etag_counter
Definition: chan_sip.c:972
char entity_tag[30]
Definition: sip.h:1742
struct ao2_container * compositor
Definition: chan_sip.c:1000
#define ao2_link(container, obj)
Definition: astobj2.h:1549

◆ crypto_get_attrib()

static char* crypto_get_attrib ( struct ast_sdp_srtp srtp,
int  dtls_enabled,
int  default_taglen_32 
)
static

Definition at line 13503 of file chan_sip.c.

References ast_asprintf, ast_free, AST_LIST_NEXT, ast_sdp_srtp_get_attrib(), ast_strdup, ast_strlen_zero, copy(), NULL, and tmp().

Referenced by add_sdp().

13504 {
13505  struct ast_sdp_srtp *tmp = srtp;
13506  char *a_crypto;
13507 
13508  if (!tmp || dtls_enabled) {
13509  return NULL;
13510  }
13511 
13512  a_crypto = ast_strdup("");
13513  if (!a_crypto) {
13514  return NULL;
13515  }
13516 
13517  do {
13518  char *copy = a_crypto;
13519  const char *orig_crypto = ast_sdp_srtp_get_attrib(tmp, dtls_enabled, default_taglen_32);
13520 
13521  if (ast_strlen_zero(orig_crypto)) {
13522  ast_free(copy);
13523  return NULL;
13524  }
13525  if (ast_asprintf(&a_crypto, "%sa=crypto:%s\r\n", copy, orig_crypto) == -1) {
13526  ast_free(copy);
13527  return NULL;
13528  }
13529 
13530  ast_free(copy);
13531  } while ((tmp = AST_LIST_NEXT(tmp, sdp_srtp_list)));
13532 
13533  return a_crypto;
13534 }
structure for secure RTP audio
Definition: sdp_srtp.h:37
static int tmp()
Definition: bt_open.c:389
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:438
static int copy(char *infile, char *outfile)
Utility function to copy a file.
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:269
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_free(a)
Definition: astmm.h:182
struct ast_sdp_srtp::@318 sdp_srtp_list
const char * ast_sdp_srtp_get_attrib(struct ast_sdp_srtp *srtp, int dtls_enabled, int default_taglen_32)
Get the crypto attribute line for the srtp structure.
Definition: sdp_srtp.c:95

◆ default_sip_port()

static int default_sip_port ( enum ast_transport  type)
inlinestatic

The default sip port for the given transport.

Definition at line 6309 of file chan_sip.c.

References AST_TRANSPORT_TLS, STANDARD_SIP_PORT, and STANDARD_TLS_PORT.

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

6310 {
6312 }
static const char type[]
Definition: chan_ooh323.c:109
#define STANDARD_TLS_PORT
Standard SIP TLS port from RFC 3261. DO NOT CHANGE THIS.
Definition: sip.h:178
#define STANDARD_SIP_PORT
Standard SIP unsecure port for UDP and TCP from RFC 3261. DO NOT CHANGE THIS.
Definition: sip.h:176

◆ deinit_req()

static void deinit_req ( struct sip_request req)
static

Deinitialize SIP response/request.

Definition at line 12195 of file chan_sip.c.

References ast_free, sip_request::content, sip_request::data, and NULL.

Referenced by _sip_tcp_helper_thread(), send_request(), send_response(), sip_pvt_dtor(), sip_websocket_callback(), and sipsock_read().

12196 {
12197  if (req->data) {
12198  ast_free(req->data);
12199  req->data = NULL;
12200  }
12201  if (req->content) {
12202  ast_free(req->content);
12203  req->content = NULL;
12204  }
12205 }
#define NULL
Definition: resample.c:96
struct ast_str * data
Definition: sip.h:843
struct ast_str * content
Definition: sip.h:844
#define ast_free(a)
Definition: astmm.h:182

◆ deprecation_notice()

static void deprecation_notice ( void  )
static

Definition at line 35452 of file chan_sip.c.

References ast_log, and LOG_WARNING.

Referenced by _macro_exec(), load_module(), and startup_event_cb().

35453 {
35454  ast_log(LOG_WARNING, "chan_sip has no official maintainer and is deprecated. Migration to\n");
35455  ast_log(LOG_WARNING, "chan_pjsip is recommended. See guides at the Asterisk Wiki:\n");
35456  ast_log(LOG_WARNING, "https://wiki.asterisk.org/wiki/display/AST/Migrating+from+chan_sip+to+res_pjsip\n");
35457  ast_log(LOG_WARNING, "https://wiki.asterisk.org/wiki/display/AST/Configuring+res_pjsip\n");
35458 }
#define LOG_WARNING
Definition: logger.h:274
#define ast_log
Definition: astobj2.c:42

◆ destroy_association()

static void destroy_association ( struct sip_peer peer)
static

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

Definition at line 16613 of file chan_sip.c.

References ast_check_realtime(), ast_db_del(), ast_update_realtime(), sip_settings::ignore_regexpire, sip_peer::name, sip_settings::peer_rtupdate, sip_peer::rt_fromcontact, SENTINEL, and sip_cfg.

Referenced by build_peer(), and expire_register().

16614 {
16615  int realtimeregs = ast_check_realtime("sipregs");
16616  char *tablename = (realtimeregs) ? "sipregs" : "sippeers";
16617 
16618  if (!sip_cfg.ignore_regexpire) {
16619  if (peer->rt_fromcontact && sip_cfg.peer_rtupdate) {
16620  ast_update_realtime(tablename, "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "0", "regseconds", "0", "regserver", "", "useragent", "", "lastms", "0", SENTINEL);
16621  } else {
16622  ast_db_del("SIP/Registry", peer->name);
16623  ast_db_del("SIP/RegistryPath", peer->name);
16624  ast_db_del("SIP/PeerMethods", peer->name);
16625  }
16626  }
16627 }
int ast_check_realtime(const char *family)
Check if realtime engine is configured for family.
Definition: main/config.c:3363
unsigned short rt_fromcontact
Definition: sip.h:1313
int peer_rtupdate
Definition: sip.h:750
int ast_update_realtime(const char *family, const char *keyfield, const char *lookup,...) attribute_sentinel
Update realtime configuration.
Definition: main/config.c:3489
char name[80]
Definition: sip.h:1274
#define SENTINEL
Definition: compiler.h:87
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
int ast_db_del(const char *family, const char *key)
Delete entry in astdb.
Definition: main/db.c:429
int ignore_regexpire
Definition: sip.h:753

◆ destroy_escs()

static void destroy_escs ( void  )
static

Definition at line 1830 of file chan_sip.c.

References ao2_replace, ARRAY_LEN, event_state_compositors, and NULL.

Referenced by unload_module().

1831 {
1832  int i;
1833  for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) {
1834  ao2_replace(event_state_compositors[i].compositor, NULL);
1835  }
1836 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define NULL
Definition: resample.c:96
static struct event_state_compositor event_state_compositors[]
#define ao2_replace(dst, src)
Definition: astobj2.h:517

◆ destroy_mailbox()

static void destroy_mailbox ( struct sip_mailbox mailbox)
static

Destroy mailbox subscriptions

Definition at line 5275 of file chan_sip.c.

References ast_free, ast_mwi_unsubscribe_and_join(), and sip_mailbox::event_sub.

Referenced by build_peer(), and clear_peer_mailboxes().

5276 {
5277  if (mailbox->event_sub) {
5278  mailbox->event_sub = ast_mwi_unsubscribe_and_join(mailbox->event_sub);
5279  }
5280  ast_free(mailbox);
5281 }
struct ast_mwi_subscriber * event_sub
Definition: sip.h:1263
#define ast_free(a)
Definition: astmm.h:182
void * ast_mwi_unsubscribe_and_join(struct ast_mwi_subscriber *sub)
Unsubscribe from the stasis topic, block until the final message is received, and then unsubscribe fr...
Definition: mwi.c:254

◆ destroy_msg_headers()

static void destroy_msg_headers ( struct sip_pvt pvt)
static

Definition at line 12887 of file chan_sip.c.

References ast_free, AST_LIST_REMOVE_HEAD, and sip_pvt::msg_headers.

Referenced by sip_pvt_dtor(), and sip_sendtext().

12888 {
12889  struct sip_msg_hdr *doomed;
12890 
12891  while ((doomed = AST_LIST_REMOVE_HEAD(&pvt->msg_headers, next))) {
12892  ast_free(doomed);
12893  }
12894 }
struct sip_pvt::@173 msg_headers
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
#define ast_free(a)
Definition: astmm.h:182
struct sip_msg_hdr * next
Definition: sip.h:992

◆ destroy_realm_authentication()

static void destroy_realm_authentication ( void *  obj)
static

Definition at line 31355 of file chan_sip.c.

References ast_free, AST_LIST_REMOVE_HEAD, and sip_auth_container::list.

Referenced by add_realm_authentication().

31356 {
31357  struct sip_auth_container *credentials = obj;
31358  struct sip_auth *auth;
31359 
31360  while ((auth = AST_LIST_REMOVE_HEAD(&credentials->list, node))) {
31361  ast_free(auth);
31362  }
31363 }
Definition: test_heap.c:38
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
struct sip_auth_container::@170 list
#define ast_free(a)
Definition: astmm.h:182
sip_auth: Credentials for authentication to other SIP services
Definition: sip.h:902
Container of SIP authentication credentials.
Definition: sip.h:911

◆ determine_firstline_parts()

static int determine_firstline_parts ( struct sip_request req)
static

Parse first line of incoming SIP request.

Definition at line 14157 of file chan_sip.c.

References ast_debug, ast_skip_blanks(), ast_skip_nonblanks(), ast_str_buffer(), ast_trim_blanks(), sip_request::data, sip_request::rlpart1, and sip_request::rlpart2.

Referenced by parse_request().

14158 {
14159  char *e = ast_skip_blanks(ast_str_buffer(req->data)); /* there shouldn't be any */
14160  char *local_rlpart1;
14161 
14162  if (!*e)
14163  return -1;
14164  req->rlpart1 = e - ast_str_buffer(req->data); /* method or protocol */
14165  local_rlpart1 = e;
14166  e = ast_skip_nonblanks(e);
14167  if (*e)
14168  *e++ = '\0';
14169  /* Get URI or status code */
14170  e = ast_skip_blanks(e);
14171  if ( !*e )
14172  return -1;
14173  ast_trim_blanks(e);
14174 
14175  if (!strcasecmp(local_rlpart1, "SIP/2.0") ) { /* We have a response */
14176  if (strlen(e) < 3) /* status code is 3 digits */
14177  return -1;
14178  req->rlpart2 = e - ast_str_buffer(req->data);
14179  } else { /* We have a request */
14180  if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */
14181  ast_debug(3, "Oops. Bogus uri in <> %s\n", e);
14182  e++;
14183  if (!*e)
14184  return -1;
14185  }
14186  req->rlpart2 = e - ast_str_buffer(req->data); /* URI */
14187  e = ast_skip_nonblanks(e);
14188  if (*e)
14189  *e++ = '\0';
14190  e = ast_skip_blanks(e);
14191  if (strcasecmp(e, "SIP/2.0") ) {
14192  ast_debug(3, "Skipping packet - Bad request protocol %s\n", e);
14193  return -1;
14194  }
14195  }
14196  return 1;
14197 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
char * ast_skip_nonblanks(const char *str)
Gets a pointer to first whitespace character in a string.
Definition: strings.h:200
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct ast_str * data
Definition: sip.h:843
ptrdiff_t rlpart1
Definition: sip.h:830
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
char * ast_trim_blanks(char *str)
Trims trailing whitespace characters from a string.
Definition: strings.h:182
ptrdiff_t rlpart2
Definition: sip.h:831

◆ determine_sip_publish_type()

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

References ast_assert, ast_strlen_zero, DEFAULT_PUBLISH_EXPIRES, sip_request::lines, NULL, SIP_PUBLISH_INITIAL, SIP_PUBLISH_MODIFY, SIP_PUBLISH_REFRESH, SIP_PUBLISH_REMOVE, and SIP_PUBLISH_UNKNOWN.

Referenced by handle_request_publish().

28014 {
28015  int etag_present = !ast_strlen_zero(etag);
28016  int body_present = req->lines > 0;
28017 
28018  ast_assert(expires_int != NULL);
28019 
28020  if (ast_strlen_zero(expires)) {
28021  /* Section 6, item 4, second bullet point of RFC 3903 says to
28022  * use a locally-configured default expiration if none is provided
28023  * in the request
28024  */
28025  *expires_int = DEFAULT_PUBLISH_EXPIRES;
28026  } else if (sscanf(expires, "%30d", expires_int) != 1) {
28027  return SIP_PUBLISH_UNKNOWN;
28028  }
28029 
28030  if (*expires_int == 0) {
28031  return SIP_PUBLISH_REMOVE;
28032  } else if (!etag_present && body_present) {
28033  return SIP_PUBLISH_INITIAL;
28034  } else if (etag_present && !body_present) {
28035  return SIP_PUBLISH_REFRESH;
28036  } else if (etag_present && body_present) {
28037  return SIP_PUBLISH_MODIFY;
28038  }
28039 
28040  return SIP_PUBLISH_UNKNOWN;
28041 }
static const int DEFAULT_PUBLISH_EXPIRES
Definition: chan_sip.c:973
Unknown.
Definition: sip.h:1571
#define ast_assert(a)
Definition: utils.h:695
#define NULL
Definition: resample.c:96
Refresh.
Definition: sip.h:1590
#define ast_strlen_zero(foo)
Definition: strings.h:52
Remove.
Definition: sip.h:1607
Modify.
Definition: sip.h:1599
Initial.
Definition: sip.h:1581
int lines
Definition: sip.h:834

◆ dialog_checkrtp_cb()

static int dialog_checkrtp_cb ( void *  dialogobj,
void *  arg,
int  flags 
)
static

Check RTP Timeout on dialogs.

This is used with ao2_callback to check rtptimeout rtponholdtimeout and send rtpkeepalive packets.

Returns
CMP_MATCH for items to be unlinked from dialogs_rtpcheck.

Definition at line 20681 of file chan_sip.c.

References check_rtp_timeout(), CMP_MATCH, sip_pvt::rtp, sip_pvt_trylock, sip_pvt_unlock, and sip_pvt::vrtp.

Referenced by do_monitor().

20682 {
20683  struct sip_pvt *dialog = dialogobj;
20684  time_t *t = arg;
20685  int match_status;
20686 
20687  if (sip_pvt_trylock(dialog)) {
20688  return 0;
20689  }
20690 
20691  if (dialog->rtp || dialog->vrtp) {
20692  match_status = check_rtp_timeout(dialog, *t);
20693  } else {
20694  /* Dialog has no active RTP or VRTP. unlink it from dialogs_rtpcheck. */
20695  match_status = CMP_MATCH;
20696  }
20697  sip_pvt_unlock(dialog);
20698 
20699  return match_status;
20700 }
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define sip_pvt_trylock(x)
Definition: chan_sip.c:1045
struct ast_rtp_instance * vrtp
Definition: sip.h:1175
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
struct ast_rtp_instance * rtp
Definition: sip.h:1174
static int 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 i...
Definition: chan_sip.c:29899

◆ dialog_clean_rtp()

static void dialog_clean_rtp ( struct sip_pvt p)
static

Cleanup the RTP and SRTP portions of a dialog

Note
This procedure excludes vsrtp as it is initialized differently.

Definition at line 5975 of file chan_sip.c.

References ast_rtp_instance_destroy(), ast_sdp_srtp_destroy(), NULL, sip_pvt::rtp, sip_pvt::srtp, sip_pvt::trtp, sip_pvt::tsrtp, and sip_pvt::vrtp.

Referenced by dialog_initialize_rtp(), and sip_pvt_dtor().

5976 {
5977  if (p->rtp) {
5979  p->rtp = NULL;
5980  }
5981 
5982  if (p->vrtp) {
5984  p->vrtp = NULL;
5985  }
5986 
5987  if (p->trtp) {
5989  p->trtp = NULL;
5990  }
5991 
5992  if (p->srtp) {
5994  p->srtp = NULL;
5995  }
5996 
5997  if (p->tsrtp) {
5999  p->tsrtp = NULL;
6000  }
6001 }
struct ast_rtp_instance * trtp
Definition: sip.h:1176
struct ast_sdp_srtp * tsrtp
Definition: sip.h:1187
#define NULL
Definition: resample.c:96
struct ast_rtp_instance * vrtp
Definition: sip.h:1175
struct ast_rtp_instance * rtp
Definition: sip.h:1174
void ast_sdp_srtp_destroy(struct ast_sdp_srtp *srtp)
free a ast_sdp_srtp structure
Definition: sdp_srtp.c:51
int ast_rtp_instance_destroy(struct ast_rtp_instance *instance)
Destroy an RTP instance.
Definition: rtp_engine.c:458
struct ast_sdp_srtp * srtp
Definition: sip.h:1185

◆ dialog_cmp_cb()

static int dialog_cmp_cb ( void *  obj,
void *  arg,
int  flags 
)
static
Note
The only member of the dialog used here callid string

Definition at line 34643 of file chan_sip.c.

References sip_pvt::callid, CMP_MATCH, and CMP_STOP.

Referenced by load_module().

34644 {
34645  struct sip_pvt *pvt = obj, *pvt2 = arg;
34646 
34647  return !strcasecmp(pvt->callid, pvt2->callid) ? CMP_MATCH | CMP_STOP : 0;
34648 }
const ast_string_field callid
Definition: sip.h:1063
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005

◆ dialog_dump_func()

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

Definition at line 20520 of file chan_sip.c.

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

Referenced by sip_show_objects().

20521 {
20522  struct sip_pvt *pvt = userobj;
20523  int refc = ao2_t_ref(userobj, 0, "");
20524  struct ast_cli_args *a = (struct ast_cli_args *) arg;
20525 
20526  ast_cli(a->fd, "name: %s\ntype: dialog\nobjflags: %d\nrefcount: %d\n\n",
20527  pvt->callid, 0, refc);
20528  return 0;
20529 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const int fd
Definition: cli.h:159
const ast_string_field callid
Definition: sip.h:1063
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
static struct test_val a

◆ dialog_find_multiple()

static int dialog_find_multiple ( void *  obj,
void *  arg,
int  flags 
)
static
Note
Same as dialog_cmp_cb, except without the CMP_STOP on match

Definition at line 34633 of file chan_sip.c.

References sip_pvt::callid, and CMP_MATCH.

Referenced by __find_call().

34634 {
34635  struct sip_pvt *pvt = obj, *pvt2 = arg;
34636 
34637  return !strcasecmp(pvt->callid, pvt2->callid) ? CMP_MATCH : 0;
34638 }
const ast_string_field callid
Definition: sip.h:1063
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005

◆ dialog_hash_cb()

static int dialog_hash_cb ( const void *  obj,
const int  flags 
)
static
Note
The only member of the dialog used here callid string

Definition at line 34623 of file chan_sip.c.

References ast_str_case_hash(), and sip_pvt::callid.

Referenced by load_module().

34624 {
34625  const struct sip_pvt *pvt = obj;
34626 
34627  return ast_str_case_hash(pvt->callid);
34628 }
const ast_string_field callid
Definition: sip.h:1063
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
Definition: strings.h:1250

◆ dialog_initialize_dtls_srtp()

static int dialog_initialize_dtls_srtp ( const struct sip_pvt dialog,
struct ast_rtp_instance rtp,
struct ast_sdp_srtp **  srtp 
)
static

Initialize DTLS-SRTP support on an RTP instance.

Definition at line 6004 of file chan_sip.c.

References ast_log, ast_rtp_engine_srtp_is_registered(), ast_rtp_instance_get_dtls(), ast_sdp_srtp_alloc(), sip_pvt::dtls_cfg, ast_rtp_dtls_cfg::enabled, LOG_ERROR, and ast_rtp_engine_dtls::set_configuration.

Referenced by dialog_initialize_rtp().

6005 {
6006  struct ast_rtp_engine_dtls *dtls;
6007 
6008  if (!dialog->dtls_cfg.enabled) {
6009  return 0;
6010  }
6011 
6013  ast_log(LOG_ERROR, "No SRTP module loaded, can't setup SRTP session.\n");
6014  return -1;
6015  }
6016 
6017  if (!(dtls = ast_rtp_instance_get_dtls(rtp))) {
6018  ast_log(LOG_ERROR, "No DTLS-SRTP support present on engine for RTP instance '%p', was it compiled with support for it?\n",
6019  rtp);
6020  return -1;
6021  }
6022 
6023  if (dtls->set_configuration(rtp, &dialog->dtls_cfg)) {
6024  ast_log(LOG_ERROR, "Attempted to set an invalid DTLS-SRTP configuration on RTP instance '%p'\n",
6025  rtp);
6026  return -1;
6027  }
6028 
6029  if (!(*srtp = ast_sdp_srtp_alloc())) {
6030  ast_log(LOG_ERROR, "Failed to create required SRTP structure on RTP instance '%p'\n",
6031  rtp);
6032  return -1;
6033  }
6034 
6035  return 0;
6036 }
int(* set_configuration)(struct ast_rtp_instance *instance, const struct ast_rtp_dtls_cfg *dtls_cfg)
Definition: rtp_engine.h:572
struct ast_rtp_dtls_cfg dtls_cfg
Definition: sip.h:1222
#define ast_log
Definition: astobj2.c:42
Structure that represents the optional DTLS SRTP support within an RTP engine.
Definition: rtp_engine.h:570
unsigned int enabled
Definition: rtp_engine.h:555
#define LOG_ERROR
Definition: logger.h:285
struct ast_rtp_engine_dtls * ast_rtp_instance_get_dtls(struct ast_rtp_instance *instance)
Obtain a pointer to the DTLS support present on an RTP instance.
Definition: rtp_engine.c:3011
struct ast_sdp_srtp * ast_sdp_srtp_alloc(void)
allocate a ast_sdp_srtp structure
Definition: sdp_srtp.c:41
int ast_rtp_engine_srtp_is_registered(void)
Definition: rtp_engine.c:2731

◆ dialog_initialize_rtp()

static int dialog_initialize_rtp ( struct sip_pvt dialog)
static

Initialize RTP portion of a dialog.

Returns
-1 on failure, 0 on success

Definition at line 6041 of file chan_sip.c.

References __set_address_from_contact(), ast_format_cap_has_type(), AST_MEDIA_TYPE_VIDEO, ast_rtp_instance_get_ice(), ast_rtp_instance_new(), AST_RTP_INSTANCE_RTCP_STANDARD, 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_sockaddr_isnull(), ast_test_flag, bindaddr, sip_pvt::caps, dialog_clean_rtp(), dialog_initialize_dtls_srtp(), do_setnat(), sip_pvt::engine, sip_pvt::flags, global_cos_audio, global_cos_video, global_tos_audio, global_tos_video, sip_pvt::method, cfsip_methods::need_rtp, NULL, sip_pvt::rtp, rtpbindaddr, sip_pvt::rtpholdtimeout, sip_pvt::rtpkeepalive, sip_pvt::rtptimeout, SIP_DTMF, SIP_DTMF_RFC2833, sip_methods, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_TEXTSUPPORT, SIP_PAGE2_VIDEOSUPPORT, SIP_PAGE2_VIDEOSUPPORT_ALWAYS, SIP_PAGE3_ICE_SUPPORT, sip_pvt::srtp, ast_rtp_engine_ice::stop, sip_pvt::trtp, sip_pvt::tsrtp, sip_pvt::vrtp, and sip_pvt::vsrtp.

Referenced by check_peer_ok(), check_user_full(), create_addr(), and create_addr_from_peer().

6042 {
6043  struct ast_sockaddr bindaddr_tmp;
6044  struct ast_rtp_engine_ice *ice;
6045 
6046  if (!sip_methods[dialog->method].need_rtp) {
6047  return 0;
6048  }
6049 
6051  ast_sockaddr_copy(&bindaddr_tmp, &rtpbindaddr);
6052  } else {
6053  ast_sockaddr_copy(&bindaddr_tmp, &bindaddr);
6054  }
6055 
6056  /* Make sure previous RTP instances/FD's do not leak */
6057  dialog_clean_rtp(dialog);
6058 
6059  if (!(dialog->rtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) {
6060  return -1;
6061  }
6062 
6063  if (!ast_test_flag(&dialog->flags[2], SIP_PAGE3_ICE_SUPPORT) && (ice = ast_rtp_instance_get_ice(dialog->rtp))) {
6064  ice->stop(dialog->rtp);
6065  }
6066 
6067  if (dialog_initialize_dtls_srtp(dialog, dialog->rtp, &dialog->srtp)) {
6068  return -1;
6069  }
6070 
6073  if (!(dialog->vrtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) {
6074  return -1;
6075  }
6076 
6077  if (!ast_test_flag(&dialog->flags[2], SIP_PAGE3_ICE_SUPPORT) && (ice = ast_rtp_instance_get_ice(dialog->vrtp))) {
6078  ice->stop(dialog->vrtp);
6079  }
6080 
6081  if (dialog_initialize_dtls_srtp(dialog, dialog->vrtp, &dialog->vsrtp)) {
6082  return -1;
6083  }
6084 
6085  ast_rtp_instance_set_timeout(dialog->vrtp, dialog->rtptimeout);
6088 
6091  }
6092 
6093  if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_TEXTSUPPORT)) {
6094  if (!(dialog->trtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) {
6095  return -1;
6096  }
6097 
6098  if (!ast_test_flag(&dialog->flags[2], SIP_PAGE3_ICE_SUPPORT) && (ice = ast_rtp_instance_get_ice(dialog->trtp))) {
6099  ice->stop(dialog->trtp);
6100  }
6101 
6102  if (dialog_initialize_dtls_srtp(dialog, dialog->trtp, &dialog->tsrtp)) {
6103  return -1;
6104  }
6105 
6106  /* Do not timeout text as its not constant*/
6108 
6110  }
6111 
6112  ast_rtp_instance_set_timeout(dialog->rtp, dialog->rtptimeout);
6115 
6119 
6121 
6122  do_setnat(dialog);
6123 
6124  return 0;
6125 }
#define SIP_PAGE3_ICE_SUPPORT
Definition: sip.h:390
static unsigned int global_cos_video
Definition: chan_sip.c:839
static void dialog_clean_rtp(struct sip_pvt *p)
Definition: chan_sip.c:5975
int rtpholdtimeout
Definition: sip.h:1132
static int dialog_initialize_dtls_srtp(const struct sip_pvt *dialog, struct ast_rtp_instance *rtp, struct ast_sdp_srtp **srtp)
Initialize DTLS-SRTP support on an RTP instance.
Definition: chan_sip.c:6004
static unsigned int global_tos_audio
Definition: chan_sip.c:834
static struct ast_sockaddr rtpbindaddr
Definition: chan_sip.c:1133
const ast_string_field engine
Definition: sip.h:1063
struct ast_rtp_instance * trtp
Definition: sip.h:1176
#define ast_test_flag(p, flag)
Definition: utils.h:63
static const struct cfsip_methods sip_methods[]
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:171
struct ast_sdp_srtp * tsrtp
Definition: sip.h:1187
int ast_rtp_instance_set_qos(struct ast_rtp_instance *instance, int tos, int cos, const char *desc)
Set QoS parameters on an RTP session.
Definition: rtp_engine.c:2169
#define SIP_DTMF_RFC2833
Definition: sip.h:276
static unsigned int global_tos_video
Definition: chan_sip.c:835
Definition: sched.c:76
struct ast_rtp_engine_ice * ast_rtp_instance_get_ice(struct ast_rtp_instance *instance)
Obtain a pointer to the ICE support present on an RTP instance.
Definition: rtp_engine.c:2891
int rtpkeepalive
Definition: sip.h:1133
void ast_rtp_instance_set_timeout(struct ast_rtp_instance *instance, int timeout)
Set the RTP timeout value.
Definition: rtp_engine.c:2670
struct ast_flags flags[3]
Definition: sip.h:1075
#define SIP_PAGE2_RFC2833_COMPENSATE
Definition: sip.h:356
void(* stop)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:493
#define NULL
Definition: resample.c:96
Socket address structure.
Definition: netsock2.h:97
struct ast_sdp_srtp * vsrtp
Definition: sip.h:1186
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
int rtptimeout
Definition: sip.h:1131
struct ast_format_cap * caps
Definition: sip.h:1099
#define SIP_PAGE2_VIDEOSUPPORT_ALWAYS
Definition: sip.h:366
struct ast_sockaddr bindaddr
Definition: chan_sip.c:1106
int method
Definition: sip.h:1009
struct ast_rtp_instance * vrtp
Definition: sip.h:1175
void ast_rtp_instance_set_hold_timeout(struct ast_rtp_instance *instance, int timeout)
Set the RTP timeout value for when the instance is on hold.
Definition: rtp_engine.c:2675
struct ast_rtp_instance * rtp
Definition: sip.h:1174
void ast_rtp_instance_set_keepalive(struct ast_rtp_instance *instance, int timeout)
Set the RTP keepalive interval.
Definition: rtp_engine.c:2680
static void do_setnat(struct sip_pvt *p)
Set nat mode on the various data sockets.
Definition: chan_sip.c:5862
#define SIP_PAGE2_TEXTSUPPORT
Definition: sip.h:334
#define SIP_PAGE2_VIDEOSUPPORT
Definition: sip.h:333
#define SIP_DTMF
Definition: sip.h:275
Structure that represents the optional ICE support within an RTP engine.
Definition: rtp_engine.h:485
void ast_rtp_instance_set_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value)
Set the value of an RTP instance property.
Definition: rtp_engine.c:705
static unsigned int global_cos_audio
Definition: chan_sip.c:838
struct ast_sdp_srtp * srtp
Definition: sip.h:1185
struct ast_rtp_instance * ast_rtp_instance_new(const char *engine_name, struct ast_sched_context *sched, const struct ast_sockaddr *sa, void *data)
Create a new RTP instance.
Definition: rtp_engine.c:465
int ast_format_cap_has_type(const struct ast_format_cap *cap, enum ast_media_type type)
Find out if the capabilities structure has any formats of a specific type.
Definition: format_cap.c:615

◆ dialog_needdestroy()

static int dialog_needdestroy ( void *  dialogobj,
void *  arg,
int  flags 
)
static

Match dialogs that need to be destroyed.

This is used with ao2_callback to unlink/delete all dialogs that are marked needdestroy.

Todo:
Re-work this to improve efficiency. Currently, this function is called on every dialog after processing every incoming SIP/UDP packet, or potentially even more often when the scheduler has entries to run.

Definition at line 20712 of file chan_sip.c.

References ast_debug, ast_rtp_instance_get_bridged(), sip_pvt::callid, dialog_unlink_all(), sip_pvt::method, sip_pvt::needdestroy, sip_pvt::owner, sip_pvt::packets, sip_pvt::rtp, sip_methods, sip_pvt_trylock, sip_pvt_unlock, cfsip_methods::text, and sip_pvt::vrtp.

Referenced by do_monitor().

20713 {
20714  struct sip_pvt *dialog = dialogobj;
20715 
20716  if (sip_pvt_trylock(dialog)) {
20717  /* Don't block the monitor thread. This function is called often enough
20718  * that we can wait for the next time around. */
20719  return 0;
20720  }
20721 
20722  /* If we have sessions that needs to be destroyed, do it now */
20723  /* Check if we have outstanding requests not responsed to or an active call
20724  - if that's the case, wait with destruction */
20725  if (dialog->needdestroy && !dialog->packets && !dialog->owner) {
20726  /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */
20727  if (dialog->rtp && ast_rtp_instance_get_bridged(dialog->rtp)) {
20728  ast_debug(2, "Bridge still active. Delaying destruction of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text);
20729  sip_pvt_unlock(dialog);
20730  return 0;
20731  }
20732 
20733  if (dialog->vrtp && ast_rtp_instance_get_bridged(dialog->vrtp)) {
20734  ast_debug(2, "Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text);
20735  sip_pvt_unlock(dialog);
20736  return 0;
20737  }
20738 
20739  sip_pvt_unlock(dialog);
20740  /* no, the unlink should handle this: dialog_unref(dialog, "needdestroy: one more refcount decrement to allow dialog to be destroyed"); */
20741  /* the CMP_MATCH will unlink this dialog from the dialog hash table */
20742  dialog_unlink_all(dialog);
20743  return 0; /* the unlink_all should unlink this from the table, so.... no need to return a match */
20744  }
20745 
20746  sip_pvt_unlock(dialog);
20747 
20748  return 0;
20749 }
static const struct cfsip_methods sip_methods[]
unsigned short needdestroy
Definition: sip.h:1080
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
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 stor...
Definition: chan_sip.c:3367
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
const ast_string_field callid
Definition: sip.h:1063
#define sip_pvt_trylock(x)
Definition: chan_sip.c:1045
int method
Definition: sip.h:1009
struct ast_rtp_instance * vrtp
Definition: sip.h:1175
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
struct ast_channel * owner
Definition: sip.h:1138
struct sip_pkt * packets
Definition: sip.h:1177
struct ast_rtp_instance * rtp
Definition: sip.h:1174
char *const text
Definition: chan_sip.c:737
struct ast_rtp_instance * ast_rtp_instance_get_bridged(struct ast_rtp_instance *instance)
Get the other RTP instance that an instance is bridged to.
Definition: rtp_engine.c:2234

◆ dialog_unlink_all()

void dialog_unlink_all ( struct sip_pvt dialog)

Unlink a dialog from the dialogs container, as well as any other places that it may be currently stored.

Note
A reference to the dialog must be held before calling this function, and this function does not release that reference.

Definition at line 3367 of file chan_sip.c.

References __dialog_unlink_sched_items(), ao2_t_replace, ao2_t_unlink, append_history_full(), ast_channel_name(), ast_channel_tech_pvt(), ast_channel_tech_pvt_set(), ast_channel_unlock, ast_channel_unref, ast_debug, ast_extension_state_del(), ast_sched_add(), sip_peer::call, sip_registry::call, cb_extensionstate(), dialog_ref, dialog_unref, do_dialog_unlink_sched_items(), format, sip_peer::mwipvt, NULL, sip_pvt::registry, sip_pvt::relatedpeer, sip_pvt_lock_full(), sip_pvt_unlock, sip_set_owner(), and sip_pvt::stateid.

Referenced by __cleanup_registration(), __sip_autodestruct(), __sip_subscribe_mwi_do(), AST_TEST_DEFINE(), dialog_needdestroy(), handle_request_subscribe(), manager_sipnotify(), sip_cli_notify(), sip_destroy_peer(), sip_msg_send(), sip_poke_noanswer(), sip_poke_peer(), sip_registry_destroy(), sip_request_call(), sip_send_mwi_to_peer(), transmit_publish(), transmit_register(), and unload_module().

3368 {
3369  struct ast_channel *owner;
3370 
3371  dialog_ref(dialog, "Let's bump the count in the unlink so it doesn't accidentally become dead before we are done");
3372 
3373  ao2_t_unlink(dialogs, dialog, "unlinking dialog via ao2_unlink");
3374  ao2_t_unlink(dialogs_needdestroy, dialog, "unlinking dialog_needdestroy via ao2_unlink");
3375  ao2_t_unlink(dialogs_rtpcheck, dialog, "unlinking dialog_rtpcheck via ao2_unlink");
3376 
3377  /* Unlink us from the owner (channel) if we have one */
3378  owner = sip_pvt_lock_full(dialog);
3379  if (owner) {
3380  ast_debug(1, "Detaching from channel %s\n", ast_channel_name(owner));
3381  ast_channel_tech_pvt_set(owner, dialog_unref(ast_channel_tech_pvt(owner), "resetting channel dialog ptr in unlink_all"));
3382  ast_channel_unlock(owner);
3383  ast_channel_unref(owner);
3384  sip_set_owner(dialog, NULL);
3385  }
3386  sip_pvt_unlock(dialog);
3387 
3388  if (dialog->registry) {
3389  if (dialog->registry->call == dialog) {
3390  dialog->registry->call = dialog_unref(dialog->registry->call, "nulling out the registry's call dialog field in unlink_all");
3391  }
3392  ao2_t_replace(dialog->registry, NULL, "delete dialog->registry");
3393  }
3394  if (dialog->stateid != -1) {
3396  dialog->stateid = -1;
3397  }
3398  /* Remove link from peer to subscription of MWI */
3399  if (dialog->relatedpeer && dialog->relatedpeer->mwipvt == dialog) {
3400  dialog->relatedpeer->mwipvt = dialog_unref(dialog->relatedpeer->mwipvt, "delete ->relatedpeer->mwipvt");
3401  }
3402  if (dialog->relatedpeer && dialog->relatedpeer->call == dialog) {
3403  dialog->relatedpeer->call = dialog_unref(dialog->relatedpeer->call, "unset the relatedpeer->call field in tandem with relatedpeer field itself");
3404  }
3405 
3406  dialog_ref(dialog, "Stop scheduled items for unlink action");
3407  if (ast_sched_add(sched, 0, __dialog_unlink_sched_items, dialog) < 0) {
3408  /*
3409  * Uh Oh. Fall back to unscheduling things immediately
3410  * despite the potential deadlock risk.
3411  */
3412  dialog_unref(dialog, "Failed to schedule stop scheduled items for unlink action");
3414  }
3415 
3416  dialog_unref(dialog, "Let's unbump the count in the unlink so the poor pvt can disappear if it is time");
3417 }
static struct ao2_container * dialogs
Definition: chan_sip.c:1043
Main Channel structure associated with a channel.
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
struct ao2_container * dialogs_needdestroy
Definition: chan_sip.c:1024
struct sip_peer * relatedpeer
Definition: sip.h:1171
struct sip_pvt * call
Definition: sip.h:1424
int ast_extension_state_del(int id, ast_state_cb_type change_cb)
Deletes a state change watcher by ID.
Definition: pbx.c:3858
Definition: sched.c:76
#define ao2_t_replace(dst, src, tag)
Replace one object reference with another cleaning up the original.
Definition: astobj2.h:503
#define ao2_t_unlink(container, obj, tag)
Remove an object from a container.
Definition: astobj2.h:1596
static void sip_set_owner(struct sip_pvt *p, struct ast_channel *chan)
Set the owning channel on the sip_pvt object.
Definition: chan_sip.c:9450
#define NULL
Definition: resample.c:96
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct sip_registry * registry
Definition: sip.h:1173
static int __dialog_unlink_sched_items(const void *data)
Definition: chan_sip.c:3351
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
static int cb_extensionstate(const char *context, const char *exten, struct ast_state_cb_info *info, void *data)
Callback for the devicestate notification (SUBSCRIBE) support subsystem.
Definition: chan_sip.c:17692
static struct ast_channel * sip_pvt_lock_full(struct sip_pvt *pvt)
Definition: chan_sip.c:9400
#define ast_channel_unlock(chan)
Definition: channel.h:2946
int stateid
Definition: sip.h:1162
#define dialog_ref(dialog, tag)
when we create or delete references, make sure to use these functions so we keep track of the refcoun...
Definition: dialog.h:32
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565
struct sip_pvt * call
Definition: sip.h:1354
struct sip_pvt * mwipvt
Definition: sip.h:1367
const char * ast_channel_name(const struct ast_channel *chan)
static void do_dialog_unlink_sched_items(struct sip_pvt *dialog)
Definition: chan_sip.c:3308
struct ao2_container * dialogs_rtpcheck
Definition: chan_sip.c:1032
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)

◆ disable_dsp_detect()

static void disable_dsp_detect ( struct sip_pvt p)
static

Definition at line 4930 of file chan_sip.c.

References ast_dsp_free(), sip_pvt::dsp, and NULL.

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

4931 {
4932  if (p->dsp) {
4933  ast_dsp_free(p->dsp);
4934  p->dsp = NULL;
4935  }
4936 }
void ast_dsp_free(struct ast_dsp *dsp)
Definition: dsp.c:1770
#define NULL
Definition: resample.c:96
struct ast_dsp * dsp
Definition: sip.h:1169

◆ display_nat_warning()

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

Definition at line 32446 of file chan_sip.c.

References AST_CLI_YESNO, ast_log, ast_test_flag, CHANNEL_MODULE_LOAD, LOG_WARNING, and SIP_NAT_FORCE_RPORT.

Referenced by reload_config().

32446  {
32447  int global_nat, specific_nat;
32448 
32449  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))) {
32450  ast_log(LOG_WARNING, "!!! PLEASE NOTE: Setting 'nat' for a peer/user that differs from the global setting can make\n");
32451  ast_log(LOG_WARNING, "!!! the name of that peer/user discoverable by an attacker. Replies for non-existent peers/users\n");
32452  ast_log(LOG_WARNING, "!!! will be sent to a different port than replies for an existing peer/user. If at all possible,\n");
32453  ast_log(LOG_WARNING, "!!! use the global 'nat' setting and do not set 'nat' per peer/user.\n");
32454  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));
32455  }
32456 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define LOG_WARNING
Definition: logger.h:274
#define SIP_NAT_FORCE_RPORT
Definition: sip.h:283
#define ast_log
Definition: astobj2.c:42
static struct ast_flags global_flags[3]
Definition: chan_sip.c:884
#define AST_CLI_YESNO(x)
Return Yes or No depending on the argument.
Definition: cli.h:71

◆ do_cancel_destroy()

static void do_cancel_destroy ( struct sip_pvt pvt)
static

Definition at line 4443 of file chan_sip.c.

References append_history, AST_SCHED_DEL_UNREF, sip_pvt::autokillid, and dialog_unref.

Referenced by __sip_cancel_destroy(), and __sip_scheddestroy().

4444 {
4445  if (-1 < pvt->autokillid) {
4446  append_history(pvt, "CancelDestroy", "");
4448  dialog_unref(pvt, "Stop scheduled autokillid"));
4449  }
4450 }
int autokillid
Definition: sip.h:1158
Definition: sched.c:76
#define AST_SCHED_DEL_UNREF(sched, id, refcall)
schedule task to get deleted and call unref function
Definition: sched.h:80
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406

◆ do_dialog_unlink_sched_items()

static void do_dialog_unlink_sched_items ( struct sip_pvt dialog)
static

Definition at line 3308 of file chan_sip.c.

References ao2_t_ref, AST_SCHED_DEL_UNREF, sip_pvt::autokillid, dialog_unref, do_stop_session_timer(), FALSE, sip_pvt::initid, sip_pkt::next, sip_pvt::packets, sip_pvt::provisional_keepalive_sched_id, sip_pvt::reinviteid, sip_pvt::request_queue_sched_id, sip_pkt::retransid, sip_pvt_lock, sip_pvt_unlock, sip_st_dlg::st_active, sip_pvt::stimer, sip_pvt::t38id, and sip_pvt::waitid.

Referenced by __dialog_unlink_sched_items(), and dialog_unlink_all().

3309 {
3310  struct sip_pkt *cp;
3311 
3312  /* remove all current packets in this dialog */
3313  sip_pvt_lock(dialog);
3314  while ((cp = dialog->packets)) {
3315  /* Unlink and destroy the packet object. */
3316  dialog->packets = dialog->packets->next;
3318  ao2_t_ref(cp, -1, "Stop scheduled packet retransmission"));
3319  ao2_t_ref(cp, -1, "Packet retransmission list");
3320  }
3321  sip_pvt_unlock(dialog);
3322 
3323  AST_SCHED_DEL_UNREF(sched, dialog->waitid,
3324  dialog_unref(dialog, "Stop scheduled waitid"));
3325 
3326  AST_SCHED_DEL_UNREF(sched, dialog->initid,
3327  dialog_unref(dialog, "Stop scheduled initid"));
3328 
3330  dialog_unref(dialog, "Stop scheduled reinviteid"));
3331 
3333  dialog_unref(dialog, "Stop scheduled autokillid"));
3334 
3336  dialog_unref(dialog, "Stop scheduled request_queue_sched_id"));
3337 
3339  dialog_unref(dialog, "Stop scheduled provisional keepalive"));
3340 
3341  AST_SCHED_DEL_UNREF(sched, dialog->t38id,
3342  dialog_unref(dialog, "Stop scheduled t38id"));
3343 
3344  if (dialog->stimer) {
3345  dialog->stimer->st_active = FALSE;
3346  do_stop_session_timer(dialog);
3347  }
3348 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
sip packet - raw format for outbound packets that are sent or scheduled for transmission Packets are ...
Definition: sip.h:1231
#define FALSE
Definition: app_minivm.c:521
int autokillid
Definition: sip.h:1158
int reinviteid
Definition: sip.h:1157
int initid
Definition: sip.h:1155
int retransid
Definition: sip.h:1240
Definition: sched.c:76
#define AST_SCHED_DEL_UNREF(sched, id, refcall)
schedule task to get deleted and call unref function
Definition: sched.h:80
int st_active
Definition: sip.h:960
int provisional_keepalive_sched_id
Definition: sip.h:1109
int request_queue_sched_id
Definition: sip.h:1108
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
int waitid
Definition: sip.h:1156
struct sip_st_dlg * stimer
Definition: sip.h:1184
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
struct sip_pkt * next
Definition: sip.h:1232
static void do_stop_session_timer(struct sip_pvt *pvt)
Definition: chan_sip.c:30190
struct sip_pkt * packets
Definition: sip.h:1177
int t38id
Definition: sip.h:1159

◆ do_magic_pickup()

static int do_magic_pickup ( struct ast_channel channel,
const char *  extension,
const char *  context 
)
static
Note
No channel or pvt locks should be held while calling this function.

Definition at line 26048 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(), IGNORE_CONTEXT, LOG_ERROR, sip_settings::notifycid, pbx_exec(), pbx_findapp(), sip_cfg, and str.

Referenced by handle_request_invite().

26049 {
26051  struct ast_app *pickup = pbx_findapp("Pickup");
26052 
26053  if (!pickup) {
26054  ast_log(LOG_ERROR, "Unable to perform pickup: Application 'Pickup' not loaded (app_directed_pickup.so).\n");
26055  return -1;
26056  }
26057 
26058  ast_str_set(&str, 0, "%s@%s", extension, sip_cfg.notifycid == IGNORE_CONTEXT ? "PICKUPMARK" : context);
26059 
26060  ast_debug(2, "About to call Pickup(%s)\n", ast_str_buffer(str));
26061 
26062  /* There is no point in capturing the return value since pickup_exec
26063  doesn't return anything meaningful unless the passed data is an empty
26064  string (which in our case it will not be) */
26065  pbx_exec(channel, pickup, ast_str_buffer(str));
26066 
26067  return 0;
26068 }
enum notifycid_setting notifycid
Definition: sip.h:775
int pbx_exec(struct ast_channel *c, struct ast_app *app, const char *data)
Execute an application.
Definition: pbx_app.c:471
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define ast_str_alloca(init_len)
Definition: strings.h:800
const char * str
Definition: app_jack.c:147
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define AST_MAX_EXTENSION
Definition: channel.h:135
structure to hold extensions
#define LOG_ERROR
Definition: logger.h:285
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
#define AST_MAX_CONTEXT
Definition: channel.h:136
ast_app: A registered application
Definition: pbx_app.c:45
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
struct ast_app * pbx_findapp(const char *app)
Look up an application.
Definition: ael_main.c:165

◆ do_message_auth()

static int do_message_auth ( struct sip_pvt p,
int  resp,
const char *  rest,
struct sip_request req,
uint32_t  seqno 
)
static

Definition at line 25070 of file chan_sip.c.

References append_history, ast_debug, ast_log, ast_sockaddr_stringify(), sip_invite_param::auth_type, sip_pvt::authtries, sip_pvt::do_history, LOG_NOTICE, MAX_AUTHTRIES, sip_pvt::options, PROXY_AUTH, reply_digest(), sip_pvt::sa, sip_auth_headers(), SIP_MESSAGE, transmit_message(), and WWW_AUTH.

Referenced by handle_response_message().

25071 {
25072  char *header;
25073  char *respheader;
25074  char digest[1024];
25075 
25076  if (p->options) {
25077  p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH);
25078  }
25079 
25080  if (p->authtries == MAX_AUTHTRIES) {
25081  ast_log(LOG_NOTICE, "Failed to authenticate MESSAGE with host '%s'\n",
25082  ast_sockaddr_stringify(&p->sa));
25083  return -1;
25084  }
25085 
25086  ++p->authtries;
25087  sip_auth_headers((resp == 401 ? WWW_AUTH : PROXY_AUTH), &header, &respheader);
25088  memset(digest, 0, sizeof(digest));
25089  if (reply_digest(p, req, header, SIP_MESSAGE, digest, sizeof(digest))) {
25090  /* There's nothing to use for authentication */
25091  ast_debug(1, "Nothing to use for MESSAGE authentication\n");
25092  return -1;
25093  }
25094 
25095  if (p->do_history) {
25096  append_history(p, "MessageAuth", "Try: %d", p->authtries);
25097  }
25098 
25099  transmit_message(p, 0, 1);
25100  return 0;
25101 }
enum sip_auth_type auth_type
Definition: sip.h:867
void sip_auth_headers(enum sip_auth_type code, char **header, char **respheader)
return the request and response header for a 401 or 407 code
Definition: chan_sip.c:16549
struct sip_invite_param * options
Definition: sip.h:1183
struct ast_sockaddr sa
Definition: sip.h:1125
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
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
Definition: chan_sip.c:23062
#define MAX_AUTHTRIES
Definition: sip.h:109
static int transmit_message(struct sip_pvt *p, int init, int auth)
Transmit with SIP MESSAGE method.
Definition: chan_sip.c:16351
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
#define LOG_NOTICE
Definition: logger.h:263
unsigned short do_history
Definition: sip.h:1078
Definition: sip.h:504
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406
int authtries
Definition: sip.h:1111

◆ do_monitor()

static void * do_monitor ( void *  data)
static

The SIP monitoring thread.

Note
This thread monitors all the SIP sessions and peers that needs notification of mwi (and thus do not have a separate thread) indefinitely

Definition at line 29997 of file chan_sip.c.

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

Referenced by restart_monitor().

29998 {
29999  int res;
30000  time_t t;
30001  int reloading;
30002 
30003  /* Add an I/O event to our SIP UDP socket */
30004  if (sipsock > -1) {
30006  }
30007 
30008  /* From here on out, we die whenever asked */
30009  for(;;) {
30010  /* Check for a reload request */
30012  reloading = sip_reloading;
30013  sip_reloading = FALSE;
30015  if (reloading) {
30016  ast_verb(1, "Reloading SIP\n");
30018 
30019  /* Change the I/O fd of our UDP socket */
30020  if (sipsock > -1) {
30021  if (sipsock_read_id) {
30023  } else {
30025  }
30026  } else if (sipsock_read_id) {
30029  }
30030  }
30031 
30032  /* Check for dialogs needing to be killed */
30033  t = time(NULL);
30034 
30035  /*
30036  * Check dialogs with rtp and rtptimeout.
30037  * All dialogs which have rtp are in dialogs_rtpcheck.
30038  */
30040  dialog_checkrtp_cb, &t,
30041  "callback to check rtptimeout and hangup calls if necessary");
30042  /*
30043  * Check dialogs marked to be destroyed.
30044  * All dialogs with needdestroy set are in dialogs_needdestroy.
30045  */
30047  NULL, "callback to check dialogs which need to be destroyed");
30048 
30049  /* XXX TODO The scheduler usage in this module does not have sufficient
30050  * synchronization being done between running the scheduler and places
30051  * scheduling tasks. As it is written, any scheduled item may not run
30052  * any sooner than about 1 second, regardless of whether a sooner time
30053  * was asked for. */
30054 
30055  pthread_testcancel();
30056  /* Wait for sched or io */
30057  res = ast_sched_wait(sched);
30058  if ((res < 0) || (res > 1000)) {
30059  res = 1000;
30060  }
30061  res = ast_io_wait(io, res);
30062  if (res > 20) {
30063  ast_debug(1, "chan_sip: ast_io_wait ran %d all at once\n", res);
30064  }
30066  res = ast_sched_runq(sched);
30067  if (res >= 20) {
30068  ast_debug(1, "chan_sip: ast_sched_runq ran %d all at once\n", res);
30069  }
30071  }
30072 
30073  /* Never reached */
30074  return NULL;
30075 }
int ast_io_wait(struct io_context *ioc, int howlong)
Waits for IO.
Definition: io.c:278
static int sip_reloading
Definition: chan_sip.c:905
static int dialog_checkrtp_cb(void *dialogobj, void *arg, int flags)
Check RTP Timeout on dialogs.
Definition: chan_sip.c:20681
#define FALSE
Definition: app_minivm.c:521
int ast_sched_runq(struct ast_sched_context *con)
Runs the queue.
Definition: sched.c:755
struct ao2_container * dialogs_needdestroy
Definition: chan_sip.c:1024
static ast_mutex_t monlock
Protect the monitoring thread, so only one process can kill or start it, and not when it&#39;s doing some...
Definition: chan_sip.c:897
static enum channelreloadreason sip_reloadreason
Definition: chan_sip.c:906
#define AST_IO_IN
Definition: io.h:34
Definition: sched.c:76
int * ast_io_add(struct io_context *ioc, int fd, ast_io_cb callback, short events, void *data)
Adds an IO context.
Definition: io.c:162
static int * sipsock_read_id
Definition: chan_sip.c:910
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:463
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static ast_mutex_t sip_reload_lock
Definition: chan_sip.c:899
static struct io_context * io
Definition: chan_sip.c:909
static int sip_do_reload(enum channelreloadreason reason)
Reload module.
Definition: chan_sip.c:34384
#define ao2_t_callback(c, flags, cb_fn, arg, tag)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.
Definition: astobj2.h:1714
static int sipsock
Main socket for UDP SIP communication.
Definition: chan_sip.c:1104
static int dialog_needdestroy(void *dialogobj, void *arg, int flags)
Match dialogs that need to be destroyed.
Definition: chan_sip.c:20712
int ast_io_remove(struct io_context *ioc, int *id)
Removes an IO context.
Definition: io.c:245
int ast_sched_wait(struct ast_sched_context *con) attribute_warn_unused_result
Determines number of seconds until the next outstanding event to take place.
Definition: sched.c:431
int * ast_io_change(struct io_context *ioc, int *id, int fd, ast_io_cb callback, short events, void *data)
Changes an IO handler.
Definition: io.c:200
struct ao2_container * dialogs_rtpcheck
Definition: chan_sip.c:1032
#define ast_mutex_unlock(a)
Definition: lock.h:188
static int sipsock_read(int *id, int fd, short events, void *ignore)
Read data from SIP UDP socket.
Definition: chan_sip.c:29380

◆ do_proxy_auth()

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

References ast_calloc, ast_debug, sip_invite_param::auth, sip_invite_param::authheader, sip_pvt::authtries, NULL, sip_pvt::options, reply_digest(), sip_auth_headers(), SIP_INVITE, 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().

23037 {
23038  char *header, *respheader;
23039  char digest[1024];
23040 
23041  if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options))))
23042  return -2;
23043 
23044  p->authtries++;
23045  sip_auth_headers(code, &header, &respheader);
23046  ast_debug(2, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text);
23047  memset(digest, 0, sizeof(digest));
23048  if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) {
23049  /* No way to authenticate */
23050  return -1;
23051  }
23052  /* Now we have a reply digest */
23053  p->options->auth = digest;
23054  p->options->authheader = respheader;
23055  return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init, NULL);
23056 }
void sip_auth_headers(enum sip_auth_type code, char **header, char **respheader)
return the request and response header for a 401 or 407 code
Definition: chan_sip.c:16549
static const struct cfsip_methods sip_methods[]
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.
Definition: chan_sip.c:14755
#define NULL
Definition: resample.c:96
struct sip_invite_param * options
Definition: sip.h:1183
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
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
Definition: chan_sip.c:23062
sipmethod
SIP Request methods known by Asterisk.
Definition: sip.h:612
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
char *const text
Definition: chan_sip.c:737
char * authheader
Definition: sip.h:866
char * auth
Definition: sip.h:865
int authtries
Definition: sip.h:1111

◆ do_register_auth()

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

References append_history, ast_verbose(), sip_pvt::authtries, sip_pvt::do_history, sip_registry::hostname, sip_pvt::registry, reply_digest(), sip_auth_headers(), sip_debug_test_pvt(), SIP_REGISTER, and transmit_register().

Referenced by handle_response_register().

23013 {
23014  char *header, *respheader;
23015  char digest[1024];
23016 
23017  p->authtries++;
23018  sip_auth_headers(code, &header, &respheader);
23019  memset(digest, 0, sizeof(digest));
23020  if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) {
23021  /* There's nothing to use for authentication */
23022  /* No digest challenge in request */
23023  if (sip_debug_test_pvt(p) && p->registry)
23024  ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname);
23025  /* No old challenge */
23026  return -1;
23027  }
23028  if (p->do_history)
23029  append_history(p, "RegistryAuth", "Try: %d", p->authtries);
23030  if (sip_debug_test_pvt(p) && p->registry)
23031  ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname);
23032  return transmit_register(p->registry, SIP_REGISTER, digest, respheader);
23033 }
const ast_string_field hostname
Definition: sip.h:1414
void sip_auth_headers(enum sip_auth_type code, char **header, char **respheader)
return the request and response header for a 401 or 407 code
Definition: chan_sip.c:16549
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
struct sip_registry * registry
Definition: sip.h:1173
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
Definition: chan_sip.c:23062
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()) ...
Definition: chan_sip.c:16106
unsigned short do_history
Definition: sip.h:1078
static int sip_debug_test_pvt(struct sip_pvt *p)
Test PVT for debugging output.
Definition: chan_sip.c:3649
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406
int authtries
Definition: sip.h:1111

◆ do_setnat()

static void do_setnat ( struct sip_pvt p)
static

Set nat mode on the various data sockets.

Definition at line 5862 of file chan_sip.c.

References ast_debug, ast_rtp_instance_set_prop(), AST_RTP_PROPERTY_NAT, ast_test_flag, ast_udptl_setnat(), sip_pvt::flags, sip_pvt::rtp, SIP_PAGE2_SYMMETRICRTP, sip_pvt::trtp, sip_pvt::udptl, and sip_pvt::vrtp.

Referenced by __sip_alloc(), check_peer_ok(), dialog_initialize_rtp(), and sip_request_call().

5863 {
5864  const char *mode;
5865  int natflags;
5866 
5867  natflags = ast_test_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP);
5868  mode = natflags ? "On" : "Off";
5869 
5870  if (p->rtp) {
5871  ast_debug(1, "Setting NAT on RTP to %s\n", mode);
5873  }
5874  if (p->vrtp) {
5875  ast_debug(1, "Setting NAT on VRTP to %s\n", mode);
5877  }
5878  if (p->udptl) {
5879  ast_debug(1, "Setting NAT on UDPTL to %s\n", mode);
5880  ast_udptl_setnat(p->udptl, natflags);
5881  }
5882  if (p->trtp) {
5883  ast_debug(1, "Setting NAT on TRTP to %s\n", mode);
5885  }
5886 }
struct ast_rtp_instance * trtp
Definition: sip.h:1176
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_flags flags[3]
Definition: sip.h:1075
#define SIP_PAGE2_SYMMETRICRTP
Definition: sip.h:327
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct ast_udptl * udptl
Definition: sip.h:1115
struct ast_rtp_instance * vrtp
Definition: sip.h:1175
struct ast_rtp_instance * rtp
Definition: sip.h:1174
void ast_rtp_instance_set_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value)
Set the value of an RTP instance property.
Definition: rtp_engine.c:705
void ast_udptl_setnat(struct ast_udptl *udptl, int nat)
Definition: udptl.c:745

◆ do_stop_session_timer()

static void do_stop_session_timer ( struct sip_pvt pvt)
static

Definition at line 30190 of file chan_sip.c.

References ast_debug, AST_SCHED_DEL_UNREF, sip_pvt::callid, dialog_unref, sip_st_dlg::st_schedid, and sip_pvt::stimer.

Referenced by __start_session_timer(), __stop_session_timer(), and do_dialog_unlink_sched_items().

30191 {
30192  struct sip_st_dlg *stimer = pvt->stimer;
30193 
30194  if (-1 < stimer->st_schedid) {
30195  ast_debug(2, "Session timer stopped: %d - %s\n",
30196  stimer->st_schedid, pvt->callid);
30198  dialog_unref(pvt, "Stop scheduled session timer st_schedid"));
30199  }
30200 }
int st_schedid
Definition: sip.h:963
Definition: sched.c:76
#define AST_SCHED_DEL_UNREF(sched, id, refcall)
schedule task to get deleted and call unref function
Definition: sched.h:80
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
const ast_string_field callid
Definition: sip.h:1063
struct sip_st_dlg * stimer
Definition: sip.h:1184
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
Structure that encapsulates all attributes related to running SIP Session-Timers feature on a per dia...
Definition: sip.h:959

◆ domain_mode_to_text()

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

Print domain mode to cli.

Definition at line 20892 of file chan_sip.c.

References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.

Referenced by sip_show_domains().

20893 {
20894  switch (mode) {
20895  case SIP_DOMAIN_AUTO:
20896  return "[Automatic]";
20897  case SIP_DOMAIN_CONFIG:
20898  return "[Configured]";
20899  }
20900 
20901  return "";
20902 }

◆ dtmfmode2str()

static const char * dtmfmode2str ( int  mode)
static

Convert DTMF mode to printable string.

Definition at line 20598 of file chan_sip.c.

References map_x_s().

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

20599 {
20600  return map_x_s(dtmfstr, mode, "<error>");
20601 }
static const struct _map_x_s dtmfstr[]
mapping between dtmf flags and strings
Definition: chan_sip.c:20588
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
Definition: chan_sip.c:2411

◆ enable_dsp_detect()

static void enable_dsp_detect ( struct sip_pvt p)
static

Definition at line 4896 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, sip_pvt::dsp, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_RELAXDTMF, DSP_FEATURE_DIGIT_DETECT, DSP_FEATURE_FAX_DETECT, sip_pvt::flags, global_relaxdtmf, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, and SIP_PAGE2_FAX_DETECT_CNG.

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

4897 {
4898  int features = 0;
4899 
4900  if (p->dsp) {
4901  return;
4902  }
4903 
4904  if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) ||
4905  (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) {
4906  if (p->rtp) {
4908  }
4909  features |= DSP_FEATURE_DIGIT_DETECT;
4910  }
4911 
4913  features |= DSP_FEATURE_FAX_DETECT;
4914  }
4915 
4916  if (!features) {
4917  return;
4918  }
4919 
4920  if (!(p->dsp = ast_dsp_new())) {
4921  return;
4922  }
4923 
4924  ast_dsp_set_features(p->dsp, features);
4925  if (global_relaxdtmf) {
4927  }
4928 }
#define SIP_PAGE2_FAX_DETECT_CNG
Definition: sip.h:361
#define SIP_DTMF_INBAND
Definition: sip.h:277
int ast_rtp_instance_dtmf_mode_set(struct ast_rtp_instance *instance, enum ast_rtp_dtmf_mode dtmf_mode)
Set the DTMF mode that should be used.
Definition: rtp_engine.c:2123
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define DSP_DIGITMODE_DTMF
Definition: dsp.h:31
#define DSP_FEATURE_DIGIT_DETECT
Definition: dsp.h:28
struct ast_dsp * ast_dsp_new(void)
Allocates a new dsp, assumes 8khz for internal sample rate.
Definition: dsp.c:1745
struct ast_flags flags[3]
Definition: sip.h:1075
#define DSP_DIGITMODE_RELAXDTMF
Definition: dsp.h:37
#define DSP_FEATURE_FAX_DETECT
Definition: dsp.h:29
struct ast_dsp * dsp
Definition: sip.h:1169
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1755
struct ast_rtp_instance * rtp
Definition: sip.h:1174
#define SIP_DTMF
Definition: sip.h:275
static int global_relaxdtmf
Definition: chan_sip.c:821
#define SIP_DTMF_AUTO
Definition: sip.h:279
int ast_dsp_set_digitmode(struct ast_dsp *dsp, int digitmode)
Set digit mode.
Definition: dsp.c:1844

◆ esc_cmp_fn()

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

Definition at line 1735 of file chan_sip.c.

References CMP_MATCH, CMP_STOP, and sip_esc_entry::entity_tag.

Referenced by initialize_escs().

1736 {
1737  struct sip_esc_entry *entry1 = obj;
1738  struct sip_esc_entry *entry2 = arg;
1739 
1740  return (!strcmp(entry1->entity_tag, entry2->entity_tag)) ? (CMP_MATCH | CMP_STOP) : 0;
1741 }
common ESC items for all event types
Definition: sip.h:1715
char entity_tag[30]
Definition: sip.h:1742

◆ esc_entry_destructor()

static void esc_entry_destructor ( void *  obj)
static

Definition at line 1721 of file chan_sip.c.

References AST_SCHED_DEL, and sip_esc_entry::sched_id.

Referenced by create_esc_entry().

1722 {
1723  struct sip_esc_entry *esc_entry = obj;
1724  if (esc_entry->sched_id > -1) {
1725  AST_SCHED_DEL(sched, esc_entry->sched_id);
1726  }
1727 }
int sched_id
Definition: sip.h:1750
Definition: sched.c:76
common ESC items for all event types
Definition: sip.h:1715
#define AST_SCHED_DEL(sched, id)
Remove a scheduler entry.
Definition: sched.h:46

◆ esc_hash_fn()

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

Definition at line 1729 of file chan_sip.c.

References ast_str_hash(), and sip_esc_entry::entity_tag.

Referenced by initialize_escs().

1730 {
1731  const struct sip_esc_entry *entry = obj;
1732  return ast_str_hash(entry->entity_tag);
1733 }
common ESC items for all event types
Definition: sip.h:1715
char entity_tag[30]
Definition: sip.h:1742
Definition: search.h:40
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition: strings.h:1206

◆ expire_register()

static int expire_register ( const void *  data)
static

Expire registration of SIP peer.

Definition at line 16646 of file chan_sip.c.

References sip_peer::addr, ao2_ref, ao2_t_unlink, ast_debug, AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_endpoint_blob_publish(), AST_ENDPOINT_OFFLINE, ast_endpoint_set_state(), ast_endpoint_state_type(), ast_json_pack(), ast_json_unref(), ast_sockaddr_isnull(), ast_test_flag, ast_websocket_unref(), sip_peer::default_outbound_transport, destroy_association(), sip_peer::endpoint, sip_peer::expire, FALSE, sip_peer::flags, sip_peer::is_realtime, sip_peer::name, NULL, sip_peer::portinuri, RAII_VAR, register_peer_exten(), rpeerobjs, sip_peer::selfdestruct, set_socket_transport(), SIP_PAGE2_RTAUTOCLEAR, sip_unref_peer, sip_peer::socket, sip_socket::tcptls_session, and sip_socket::ws_session.

Referenced by parse_register_contact(), realtime_peer(), reg_source_db(), sip_show_sched(), and sip_unregister().

16647 {
16648  struct sip_peer *peer = (struct sip_peer *)data;
16649 
16650  if (!peer) { /* Hmmm. We have no peer. Weird. */
16651  return 0;
16652  }
16653 
16654  peer->expire = -1;
16655  peer->portinuri = 0;
16656 
16657  destroy_association(peer); /* remove registration data from storage */
16659 
16660  if (peer->socket.tcptls_session) {
16661  ao2_ref(peer->socket.tcptls_session, -1);
16662  peer->socket.tcptls_session = NULL;
16663  } else if (peer->socket.ws_session) {
16665  peer->socket.ws_session = NULL;
16666  }
16667 
16668  if (peer->endpoint) {
16669  RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
16671  blob = ast_json_pack("{s: s, s: s}",
16672  "peer_status", "Unregistered",
16673  "cause", "Expired");
16675  }
16676  register_peer_exten(peer, FALSE); /* Remove regexten */
16678 
16679  /* Do we need to release this peer from memory?
16680  Only for realtime peers and autocreated peers
16681  */
16682  if (peer->is_realtime) {
16683  ast_debug(3, "-REALTIME- peer expired registration. Name: %s. Realtime peer objects now %d\n", peer->name, rpeerobjs);
16684  }
16685 
16686  if (peer->selfdestruct ||
16688  ao2_t_unlink(peers, peer, "ao2_unlink of peer from peers table");
16689  }
16690  if (!ast_sockaddr_isnull(&peer->addr)) {
16691  /* We still need to unlink the peer from the peers_by_ip table,
16692  * otherwise we end up with multiple copies hanging around each
16693  * time a registration expires and the peer re-registers. */
16694  ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table");
16695  }
16696 
16697  /* Only clear the addr after we check for destruction. The addr must remain
16698  * in order to unlink from the peers_by_ip container correctly */
16699  memset(&peer->addr, 0, sizeof(peer->addr));
16700 
16701  sip_unref_peer(peer, "removing peer ref for expire_register");
16702 
16703  return 0;
16704 }
static void destroy_association(struct sip_peer *peer)
Remove registration data from realtime database or AST/DB when registration expires.
Definition: chan_sip.c:16613
struct ast_sockaddr addr
Definition: sip.h:1352
#define FALSE
Definition: app_minivm.c:521
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
#define ast_test_flag(p, flag)
Definition: utils.h:63
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
static int rpeerobjs
Definition: chan_sip.c:880
#define ao2_t_unlink(container, obj, tag)
Remove an object from a container.
Definition: astobj2.h:1596
void ast_endpoint_set_state(struct ast_endpoint *endpoint, enum ast_endpoint_state state)
Updates the state of the given endpoint.
#define NULL
Definition: resample.c:96
char name[80]
Definition: sip.h:1274
static struct ao2_container * peers_by_ip
Definition: chan_sip.c:1053
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
struct ast_websocket * ws_session
Definition: sip.h:802
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
int ast_devstate_changed(enum ast_device_state state, enum ast_devstate_cache cachable, const char *fmt,...)
Tells Asterisk the State for Device is changed.
Definition: devicestate.c:510
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_tcptls_session_instance * tcptls_session
Definition: sip.h:801
int expire
Definition: sip.h:1341
struct ast_endpoint * endpoint
Definition: sip.h:1379
struct stasis_message_type * ast_endpoint_state_type(void)
Message type for endpoint state changes.
static void register_peer_exten(struct sip_peer *peer, int onoff)
Automatically add peer extension to dial plan.
Definition: chan_sip.c:5238
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
unsigned short is_realtime
Definition: sip.h:1312
unsigned short selfdestruct
Definition: sip.h:1315
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
void ast_endpoint_blob_publish(struct ast_endpoint *endpoint, struct stasis_message_type *type, struct ast_json *blob)
Creates and publishes a ast_endpoint_blob message.
struct ast_flags flags[3]
Definition: sip.h:1335
unsigned int portinuri
Definition: sip.h:1353
enum ast_transport default_outbound_transport
Definition: sip.h:1308
Abstract JSON element (object, array, string, int, ...).
#define SIP_PAGE2_RTAUTOCLEAR
Definition: sip.h:324
static void set_socket_transport(struct sip_socket *socket, int transport)
Definition: chan_sip.c:16629
void AST_OPTIONAL_API_NAME() ast_websocket_unref(struct ast_websocket *session)
struct sip_socket socket
Definition: sip.h:1307

◆ extensionstate_update()

static int extensionstate_update ( const char *  context,
const char *  exten,
struct state_notify_data data,
struct sip_pvt p,
int  force 
)
static

Callback for the devicestate notification (SUBSCRIBE) support subsystem.

Note
If you add an "hint" priority to the extension in the dial plan, you will get notifications on device state changes

Definition at line 17610 of file chan_sip.c.

References ao2_cleanup, ao2_ref, append_history, ast_channel_creationtime(), AST_EXTENSION_DEACTIVATED, AST_EXTENSION_REMOVED, AST_EXTENSION_RINGING, ast_extension_state2str(), ast_set_flag, ast_string_field_set, ast_test_flag, ast_tvcmp(), ast_verb, DEFAULT_TRANS_TIMEOUT, state_notify_data::device_state_info, FALSE, find_ringing_channel(), sip_pvt::flags, sip_pvt::last_device_state_info, sip_pvt::last_presence_message, sip_pvt::last_presence_state, sip_pvt::last_presence_subtype, sip_pvt::last_ringing_channel_time, sip_pvt::laststate, NONE, NULL, sip_pvt::pendinginvite, state_notify_data::presence_message, state_notify_data::presence_state, state_notify_data::presence_subtype, ringing(), S_OR, SIP_PAGE2_STATECHANGEQUEUE, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), state_notify_data::state, sip_pvt::subscribed, transmit_state_notify(), and sip_pvt::username.

Referenced by cb_extensionstate(), handle_request_subscribe(), and handle_response_notify().

17611 {
17612  sip_pvt_lock(p);
17613 
17614  switch (data->state) {
17615  case AST_EXTENSION_DEACTIVATED: /* Retry after a while */
17616  case AST_EXTENSION_REMOVED: /* Extension is gone */
17617  sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); /* Delete subscription in 32 secs */
17618  ast_verb(2, "Extension state: Watcher for hint %s %s. Notify User %s\n", exten, data->state == AST_EXTENSION_DEACTIVATED ? "deactivated" : "removed", p->username);
17619  p->subscribed = NONE;
17620  append_history(p, "Subscribestatus", "%s", data->state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated");
17621  break;
17622  default: /* Tell user */
17623  if (force) {
17624  /* we must skip the next two checks for a queued state change or resubscribe */
17625  } else if ((p->laststate == data->state && (~data->state & AST_EXTENSION_RINGING)) &&
17626  (p->last_presence_state == data->presence_state &&
17627  !strcmp(p->last_presence_subtype, data->presence_subtype) &&
17628  !strcmp(p->last_presence_message, data->presence_message))) {
17629  /* don't notify unchanged state or unchanged early-state causing parties again */
17630  sip_pvt_unlock(p);
17631  return 0;
17632  } else if (data->state & AST_EXTENSION_RINGING) {
17633  /* check if another channel than last time is ringing now to be notified */
17635  if (ringing) {
17637  /* we assume here that no two channels have the exact same creation time */
17638  ao2_ref(ringing, -1);
17639  sip_pvt_unlock(p);
17640  return 0;
17641  } else {
17643  ao2_ref(ringing, -1);
17644  }
17645  }
17646  /* If no ringing channel was found, it doesn't necessarily indicate anything bad.
17647  * Likely, a device state change occurred for a custom device state, which does not
17648  * correspond to any channel. In such a case, just go ahead and pass the notification
17649  * along.
17650  */
17651  }
17652  /* ref before unref because the new could be the same as the old one. Don't risk destruction! */
17653  if (data->device_state_info) {
17654  ao2_ref(data->device_state_info, 1);
17655  }
17658  p->laststate = data->state;
17660  ast_string_field_set(p, last_presence_subtype, S_OR(data->presence_subtype, ""));
17661  ast_string_field_set(p, last_presence_message, S_OR(data->presence_message, ""));
17662  break;
17663  }
17664  if (p->subscribed != NONE) { /* Only send state NOTIFY if we know the format */
17665  if (!p->pendinginvite) {
17666  transmit_state_notify(p, data, 1, FALSE);
17667  if (p->last_device_state_info) {
17668  /* We don't need the saved ref anymore, don't keep channels ref'd. */
17671  }
17672  } else {
17673  /* We already have a NOTIFY sent that is not answered. Queue the state up.
17674  if many state changes happen meanwhile, we will only send a notification of the last one */
17676  }
17677  }
17678 
17679  if (!force) {
17680  ast_verb(2, "Extension Changed %s[%s] new state %s for Notify User %s %s\n", exten, context, ast_extension_state2str(data->state), p->username,
17681  ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE) ? "(queued)" : "");
17682  }
17683 
17684  sip_pvt_unlock(p);
17685 
17686  return 0;
17687 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
Main Channel structure associated with a channel.
enum subscriptiontype subscribed
Definition: sip.h:1161
#define FALSE
Definition: app_minivm.c:521
#define SIP_PAGE2_STATECHANGEQUEUE
Definition: sip.h:328
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define NONE
Definition: misdn_config.c:45
#define ast_set_flag(p, flag)
Definition: utils.h:70
uint32_t pendinginvite
Definition: sip.h:1147
#define DEFAULT_TRANS_TIMEOUT
Definition: sip.h:107
const ast_string_field username
Definition: sip.h:1063
struct ast_flags flags[3]
Definition: sip.h:1075
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:463
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
const char * presence_message
Definition: chan_sip.c:1012
static void ringing(struct ast_channel *chan)
Helper method to send a ringing indication to a channel in a bridge.
#define ao2_ref(o, delta)
Definition: astobj2.h:464
const char * ast_extension_state2str(int extension_state)
Return string representation of the state of an extension.
Definition: pbx.c:3126
int ast_tvcmp(struct timeval _a, struct timeval _b)
Compres two struct timeval instances returning -1, 0, 1 if the first arg is smaller, equal or greater to the second.
Definition: time.h:128
struct ao2_container * device_state_info
Definition: chan_sip.c:1009
const ast_string_field last_presence_message
Definition: sip.h:1063
struct timeval ast_channel_creationtime(struct ast_channel *chan)
struct ao2_container * last_device_state_info
Definition: sip.h:1164
static struct ast_channel * find_ringing_channel(struct ao2_container *device_state_info, struct sip_pvt *p)
Definition: chan_sip.c:15161
int last_presence_state
Definition: sip.h:1166
struct timeval last_ringing_channel_time
Definition: sip.h:1165
const char * presence_subtype
Definition: chan_sip.c:1011
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static int transmit_state_notify(struct sip_pvt *p, struct state_notify_data *data, int full, int timeout)
Used in the SUBSCRIBE notification subsystem (RFC3265)
Definition: chan_sip.c:15477
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406
int laststate
Definition: sip.h:1163
const ast_string_field last_presence_subtype
Definition: sip.h:1063
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
void sip_scheddestroy(struct sip_pvt *p, int ms)
Schedule destruction of SIP dialog.
Definition: chan_sip.c:4549
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ extract_host_from_hostport()

static void extract_host_from_hostport ( char **  hostport)
static

Terminate a host:port at the ':'.

Parameters
hostportThe address of the hostport string
Note
In the case of a bracket-enclosed IPv6 address, the hostport variable will contain the non-bracketed host as a result of calling this function.

Definition at line 17831 of file chan_sip.c.

References ast_sockaddr_split_hostport(), and PARSE_PORT_IGNORE.

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

17832 {
17833  char *dont_care;
17834  ast_sockaddr_split_hostport(*hostport, hostport, &dont_care, PARSE_PORT_IGNORE);
17835 }
int ast_sockaddr_split_hostport(char *str, char **host, char **port, int flags)
Splits a string into its host and port components.
Definition: netsock2.c:164

◆ extract_transferrer_headers()

static void extract_transferrer_headers ( const char *  prefix,
struct ast_channel peer,
const struct sip_request req 
)
static

Definition at line 18782 of file chan_sip.c.

References ast_begins_with(), ast_skip_blanks(), ast_str_alloca, ast_str_buffer(), ast_str_set(), sip_request::headers, pbx_builtin_setvar_helper(), and REQ_OFFSET_TO_STR.

Referenced by get_refer_info().

18783 {
18784  struct ast_str *pbxvar = ast_str_alloca(120);
18785  int i;
18786 
18787  /* The '*' alone matches all headers. */
18788  if (strcmp(prefix, "*") == 0) {
18789  prefix = "";
18790  }
18791 
18792  for (i = 0; i < req->headers; i++) {
18793  const char *header = REQ_OFFSET_TO_STR(req, header[i]);
18794  if (ast_begins_with(header, prefix)) {
18795  int hdrlen = strcspn(header, " \t:");
18796  const char *val = ast_skip_blanks(header + hdrlen);
18797  if (hdrlen > 0 && *val == ':') {
18798  ast_str_set(&pbxvar, -1, "~HASH~TRANSFER_DATA~%.*s~", hdrlen, header);
18799  pbx_builtin_setvar_helper(peer, ast_str_buffer(pbxvar), ast_skip_blanks(val + 1));
18800  }
18801  }
18802  }
18803 }
Definition: ast_expr2.c:325
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define ast_str_alloca(init_len)
Definition: strings.h:800
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
int headers
Definition: sip.h:832
#define REQ_OFFSET_TO_STR(req, offset)
Definition: sip.h:858
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Definition: strings.h:94
static char prefix[MAX_PREFIX]
Definition: http.c:141

◆ extract_uri()

static void extract_uri ( struct sip_pvt p,
struct sip_request req 
)
static

Check Contact: URI of SIP message.

Definition at line 14289 of file chan_sip.c.

References ast_copy_string(), ast_string_field_set, ast_strlen_zero, c, get_in_brackets(), remove_uri_parameters(), sip_get_header(), and SIPBUFSIZE.

Referenced by handle_incoming(), and handle_request_invite().

14290 {
14291  char stripped[SIPBUFSIZE];
14292  char *c;
14293 
14294  ast_copy_string(stripped, sip_get_header(req, "Contact"), sizeof(stripped));
14295  c = get_in_brackets(stripped);
14296  /* Cut the URI at the at sign after the @, not in the username part */
14297  c = remove_uri_parameters(c);
14298  if (!ast_strlen_zero(c)) {
14299  ast_string_field_set(p, uri, c);
14300  }
14301 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
char * get_in_brackets(char *tmp)
Pick out text in brackets from character string.
static struct test_val c
#define ast_strlen_zero(foo)
Definition: strings.h:52
static char * remove_uri_parameters(char *uri)
Definition: chan_sip.c:14275
#define SIPBUFSIZE
Definition: sip.h:56
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ faxec2str()

static const char* faxec2str ( int  faxec)
static

Definition at line 21175 of file chan_sip.c.

References map_x_s().

Referenced by _sip_show_peer(), and sip_show_settings().

21176 {
21177  return map_x_s(faxecmodes, faxec, "Unknown");
21178 }
static struct _map_x_s faxecmodes[]
Definition: chan_sip.c:21168
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
Definition: chan_sip.c:2411

◆ finalize_content()

static int finalize_content ( struct sip_request req)
static

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

Definition at line 11911 of file chan_sip.c.

References add_header(), ast_log, ast_str_append(), ast_str_buffer(), ast_str_strlen(), sip_request::content, sip_request::data, sip_request::lines, and LOG_WARNING.

Referenced by send_request(), and send_response().

11912 {
11913  char clen[10];
11914 
11915  if (req->lines) {
11916  ast_log(LOG_WARNING, "finalize_content() called on a message that has already been finalized\n");
11917  return -1;
11918  }
11919 
11920  snprintf(clen, sizeof(clen), "%zu", ast_str_strlen(req->content));
11921  add_header(req, "Content-Length", clen);
11922 
11923  if (ast_str_strlen(req->content)) {
11924  ast_str_append(&req->data, 0, "\r\n%s", ast_str_buffer(req->content));
11925  }
11926  req->lines = ast_str_strlen(req->content) ? 1 : 0;
11927  return 0;
11928 }
#define LOG_WARNING
Definition: logger.h:274
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
#define ast_log
Definition: astobj2.c:42
struct ast_str * data
Definition: sip.h:843
struct ast_str * content
Definition: sip.h:844
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
int lines
Definition: sip.h:834
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873

◆ find_alias()

static const char * find_alias ( const char *  name,
const char *  _default 
)
static

Find compressed SIP alias.

Definition at line 8534 of file chan_sip.c.

References ARRAY_LEN.

Referenced by __get_header(), and add_header().

8535 {
8536  int x;
8537 
8538  for (x = 0; x < ARRAY_LEN(aliases); x++) {
8539  if (!strcasecmp(aliases[x].fullname, name))
8540  return aliases[x].shortname;
8541  }
8542 
8543  return _default;
8544 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static const struct cfalias aliases[]
Definition: chan_sip.c:8510
static const char name[]
Definition: cdr_mysql.c:74

◆ find_by_callid_helper()

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

Definition at line 1869 of file chan_sip.c.

References sip_pvt::callid, CMP_MATCH, CMP_STOP, sip_cc_agent_pvt::original_callid, and ast_cc_agent::private_data.

Referenced by find_sip_cc_agent_by_original_callid().

1870 {
1871  struct ast_cc_agent *agent = obj;
1872  struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
1873  struct sip_pvt *call_pvt = arg;
1874 
1875  return !strcmp(agent_pvt->original_callid, call_pvt->callid) ? CMP_MATCH | CMP_STOP : 0;
1876 }
char original_callid[SIPBUFSIZE]
Definition: sip.h:1784
void * private_data
Definition: ccss.h:871
const ast_string_field callid
Definition: sip.h:1063
Structure representing an agent.
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005

◆ find_by_name()

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

Definition at line 5761 of file chan_sip.c.

References CMP_MATCH, CMP_STOP, FINDALLDEVICES, FINDPEERS, FINDUSERS, match(), sip_peer::name, SIP_TYPE_PEER, SIP_TYPE_USER, and sip_peer::type.

Referenced by sip_find_peer_full().

5762 {
5763  struct sip_peer *search = obj, *match = arg;
5764  int *which_objects = data;
5765 
5766  /* Usernames in SIP uri's are case sensitive. Domains are not */
5767  if (strcmp(search->name, match->name)) {
5768  return 0;
5769  }
5770 
5771  switch (*which_objects) {
5772  case FINDUSERS:
5773  if (!(search->type & SIP_TYPE_USER)) {
5774  return 0;
5775  }
5776  break;
5777  case FINDPEERS:
5778  if (!(search->type & SIP_TYPE_PEER)) {
5779  return 0;
5780  }
5781  break;
5782  case FINDALLDEVICES:
5783  break;
5784  }
5785 
5786  return CMP_MATCH | CMP_STOP;
5787 }
enum sip_peer_type type
Definition: sip.h:1375
static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Definition: chan_iax2.c:2315
char name[80]
Definition: sip.h:1274
#define FINDUSERS
Definition: sip.h:52
#define FINDPEERS
Definition: sip.h:53
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
#define FINDALLDEVICES
Definition: sip.h:54

◆ find_by_notify_uri_helper()

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

Definition at line 1839 of file chan_sip.c.

References CMP_MATCH, CMP_STOP, sip_cc_agent_pvt::notify_uri, ast_cc_agent::private_data, and sip_uri_cmp().

Referenced by find_sip_cc_agent_by_notify_uri().

1840 {
1841  struct ast_cc_agent *agent = obj;
1842  struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
1843  const char *uri = arg;
1844 
1845  return !sip_uri_cmp(agent_pvt->notify_uri, uri) ? CMP_MATCH | CMP_STOP : 0;
1846 }
void * private_data
Definition: ccss.h:871
int sip_uri_cmp(const char *input1, const char *input2)
Compare two URIs as described in RFC 3261 Section 19.1.4.
Structure representing an agent.
char notify_uri[SIPBUFSIZE]
Definition: sip.h:1802

◆ find_by_subscribe_uri_helper()

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

Definition at line 1854 of file chan_sip.c.

References CMP_MATCH, CMP_STOP, ast_cc_agent::private_data, sip_uri_cmp(), and sip_cc_agent_pvt::subscribe_uri.

Referenced by find_sip_cc_agent_by_subscribe_uri().

1855 {
1856  struct ast_cc_agent *agent = obj;
1857  struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
1858  const char *uri = arg;
1859 
1860  return !sip_uri_cmp(agent_pvt->subscribe_uri, uri) ? CMP_MATCH | CMP_STOP : 0;
1861 }
void * private_data
Definition: ccss.h:871
int sip_uri_cmp(const char *input1, const char *input2)
Compare two URIs as described in RFC 3261 Section 19.1.4.
char subscribe_uri[SIPBUFSIZE]
Definition: sip.h:1809
Structure representing an agent.

◆ find_closing_quote()

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

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

5075 {
5076  char last_char = '\0';
5077  const char *s;
5078  for (s = start; *s && s != lim; last_char = *s++) {
5079  if (*s == '"' && last_char != '\\')
5080  break;
5081  }
5082  return s;
5083 }

◆ find_full_alias()

static const char* find_full_alias ( const char *  name,
const char *  _default 
)
static

Find full SIP alias.

Definition at line 8547 of file chan_sip.c.

References ARRAY_LEN.

Referenced by func_headers_read2(), and set_message_vars_from_req().

8548 {
8549  int x;
8550 
8551  if (strlen(name) == 1) {
8552  /* We have a short header name to convert. */
8553  for (x = 0; x < ARRAY_LEN(aliases); ++x) {
8554  if (!strcasecmp(aliases[x].shortname, name))
8555  return aliases[x].fullname;
8556  }
8557  }
8558 
8559  return _default;
8560 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static const struct cfalias aliases[]
Definition: chan_sip.c:8510
static const char name[]
Definition: cdr_mysql.c:74

◆ find_realm_authentication()

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

Definition at line 31444 of file chan_sip.c.

References AST_LIST_TRAVERSE, sip_auth_container::list, NULL, and sip_auth::realm.

Referenced by build_reply_digest().

31445 {
31446  struct sip_auth *auth;
31447 
31448  if (credentials) {
31449  AST_LIST_TRAVERSE(&credentials->list, auth, node) {
31450  if (!strcasecmp(auth->realm, realm)) {
31451  break;
31452  }
31453  }
31454  } else {
31455  auth = NULL;
31456  }
31457 
31458  return auth;
31459 }
Definition: test_heap.c:38
#define NULL
Definition: resample.c:96
struct sip_auth_container::@170 list
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
char realm[AST_MAX_EXTENSION]
Definition: sip.h:904
sip_auth: Credentials for authentication to other SIP services
Definition: sip.h:902

◆ find_ringing_channel()

static struct ast_channel* find_ringing_channel ( struct ao2_container device_state_info,
struct sip_pvt p 
)
static

Definition at line 15161 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_channel_creationtime(), ast_channel_lock, ast_channel_ref, ast_channel_unlock, AST_DEVICE_RINGING, AST_DEVICE_RINGINUSE, ast_tvcmp(), ast_tvzero(), c, ast_device_state_info::causing_channel, ast_device_state_info::device_state, and NULL.

Referenced by extensionstate_update(), handle_request_subscribe(), and state_notify_build_xml().

15162 {
15163  struct ao2_iterator citer;
15165  struct ast_channel *c = NULL;
15166  struct timeval tv = {0,};
15167 
15168  /* iterate ringing devices and get the oldest of all causing channels */
15169  citer = ao2_iterator_init(device_state_info, 0);
15170  for (; (device_state = ao2_iterator_next(&citer)); ao2_ref(device_state, -1)) {
15171  if (!device_state->causing_channel || (device_state->device_state != AST_DEVICE_RINGING &&
15172  device_state->device_state != AST_DEVICE_RINGINUSE)) {
15173  continue;
15174  }
15175  ast_channel_lock(device_state->causing_channel);
15176  if (ast_tvzero(tv) || ast_tvcmp(ast_channel_creationtime(device_state->causing_channel), tv) < 0) {
15177  c = device_state->causing_channel;
15178  tv = ast_channel_creationtime(c);
15179  }
15180  ast_channel_unlock(device_state->causing_channel);
15181  }
15182  ao2_iterator_destroy(&citer);
15183  return c ? ast_channel_ref(c) : NULL;
15184 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:108
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
static struct test_val c
#define NULL
Definition: resample.c:96
struct ast_channel * causing_channel
Definition: pbx.h:98
#define ao2_ref(o, delta)
Definition: astobj2.h:464
enum ast_device_state device_state
Definition: pbx.h:97
int ast_tvcmp(struct timeval _a, struct timeval _b)
Compres two struct timeval instances returning -1, 0, 1 if the first arg is smaller, equal or greater to the second.
Definition: time.h:128
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
struct timeval ast_channel_creationtime(struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2970
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

◆ find_sdp()

static int find_sdp ( struct sip_request req)
static

Determine whether a SIP message contains an SDP in its body.

Parameters
reqthe SIP request to process
Returns
1 if SDP found, 0 if not found

Also updates req->sdp_start and req->sdp_count to indicate where the SDP lives in the message body.

Definition at line 10054 of file chan_sip.c.

References ast_log, ast_strdupa, ast_strlen_zero, FALSE, sip_request::lines, LOG_WARNING, REQ_OFFSET_TO_STR, sip_request::sdp_count, sip_request::sdp_start, sip_get_header(), strcasestr(), and TRUE.

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

10055 {
10056  const char *content_type;
10057  const char *content_length;
10058  const char *search;
10059  char *boundary;
10060  unsigned int x;
10061  int boundaryisquoted = FALSE;
10062  int found_application_sdp = FALSE;
10063  int found_end_of_headers = FALSE;
10064 
10065  content_length = sip_get_header(req, "Content-Length");
10066 
10067  if (!ast_strlen_zero(content_length)) {
10068  if (sscanf(content_length, "%30u", &x) != 1) {
10069  ast_log(LOG_WARNING, "Invalid Content-Length: %s\n", content_length);
10070  return 0;
10071  }
10072 
10073  /* Content-Length of zero means there can't possibly be an
10074  SDP here, even if the Content-Type says there is */
10075  if (x == 0)
10076  return 0;
10077  }
10078 
10079  content_type = sip_get_header(req, "Content-Type");
10080 
10081  /* if the body contains only SDP, this is easy */
10082  if (!strncasecmp(content_type, "application/sdp", 15)) {
10083  req->sdp_start = 0;
10084  req->sdp_count = req->lines;
10085  return req->lines ? 1 : 0;
10086  }
10087 
10088  /* if it's not multipart/mixed, there cannot be an SDP */
10089  if (strncasecmp(content_type, "multipart/mixed", 15))
10090  return 0;
10091 
10092  /* if there is no boundary marker, it's invalid */
10093  if ((search = strcasestr(content_type, ";boundary=")))
10094  search += 10;
10095  else if ((search = strcasestr(content_type, "; boundary=")))
10096  search += 11;
10097  else
10098  return 0;
10099 
10100  if (ast_strlen_zero(search))
10101  return 0;
10102 
10103  /* If the boundary is quoted with ", remove quote */
10104  if (*search == '\"') {
10105  search++;
10106  boundaryisquoted = TRUE;
10107  }
10108 
10109  /* make a duplicate of the string, with two extra characters
10110  at the beginning */
10111  boundary = ast_strdupa(search - 2);
10112  boundary[0] = boundary[1] = '-';
10113  /* Remove final quote */
10114  if (boundaryisquoted)
10115  boundary[strlen(boundary) - 1] = '\0';
10116 
10117  /* search for the boundary marker, the empty line delimiting headers from
10118  sdp part and the end boundry if it exists */
10119 
10120  for (x = 0; x < (req->lines); x++) {
10121  const char *line = REQ_OFFSET_TO_STR(req, line[x]);
10122  if (!strncasecmp(line, boundary, strlen(boundary))){
10123  if (found_application_sdp && found_end_of_headers) {
10124  req->sdp_count = (x - 1) - req->sdp_start;
10125  return 1;
10126  }
10127  found_application_sdp = FALSE;
10128  }
10129  if (!strcasecmp(line, "Content-Type: application/sdp"))
10130  found_application_sdp = TRUE;
10131 
10132  if (ast_strlen_zero(line)) {
10133  if (found_application_sdp && !found_end_of_headers){
10134  req->sdp_start = x;
10135  found_end_of_headers = TRUE;
10136  }
10137  }
10138  }
10139  if (found_application_sdp && found_end_of_headers) {
10140  req->sdp_count = x - req->sdp_start;
10141  return TRUE;
10142  }
10143  return FALSE;
10144 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
#define FALSE
Definition: app_minivm.c:521
#define LOG_WARNING
Definition: logger.h:274
unsigned int sdp_start
Definition: sip.h:835
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
char * strcasestr(const char *, const char *)
#define REQ_OFFSET_TO_STR(req, offset)
Definition: sip.h:858
unsigned int sdp_count
Definition: sip.h:836
#define TRUE
Definition: app_minivm.c:518
int lines
Definition: sip.h:834

◆ find_sip_cc_agent_by_notify_uri()

static struct ast_cc_agent* find_sip_cc_agent_by_notify_uri ( const char *const  uri)
static

Definition at line 1848 of file chan_sip.c.

References ast_cc_agent_callback(), and find_by_notify_uri_helper().

Referenced by cc_esc_publish_handler(), and get_destination().

1849 {
1850  struct ast_cc_agent *agent = ast_cc_agent_callback(0, find_by_notify_uri_helper, (char *)uri, "SIP");
1851  return agent;
1852 }
static int find_by_notify_uri_helper(void *obj, void *arg, int flags)
Definition: chan_sip.c:1839
struct ast_cc_agent * ast_cc_agent_callback(int flags, ao2_callback_fn *function, void *arg, const char *const type)
Call a callback on all agents of a specific type.
Definition: ccss.c:456

◆ find_sip_cc_agent_by_original_callid()

static struct ast_cc_agent* find_sip_cc_agent_by_original_callid ( struct sip_pvt pvt)
static

Definition at line 1878 of file chan_sip.c.

References ast_cc_agent_callback(), and find_by_callid_helper().

Referenced by add_cc_call_info_to_response().

1879 {
1880  struct ast_cc_agent *agent = ast_cc_agent_callback(0, find_by_callid_helper, pvt, "SIP");
1881  return agent;
1882 }
static int find_by_callid_helper(void *obj, void *arg, int flags)
Definition: chan_sip.c:1869
struct ast_cc_agent * ast_cc_agent_callback(int flags, ao2_callback_fn *function, void *arg, const char *const type)
Call a callback on all agents of a specific type.
Definition: ccss.c:456

◆ find_sip_cc_agent_by_subscribe_uri()

static struct ast_cc_agent* find_sip_cc_agent_by_subscribe_uri ( const char *const  uri)
static

Definition at line 1863 of file chan_sip.c.

References ast_cc_agent_callback(), and find_by_subscribe_uri_helper().

Referenced by cc_esc_publish_handler(), and handle_cc_subscribe().

1864 {
1865  struct ast_cc_agent *agent = ast_cc_agent_callback(0, find_by_subscribe_uri_helper, (char *)uri, "SIP");
1866  return agent;
1867 }
static int find_by_subscribe_uri_helper(void *obj, void *arg, int flags)
Definition: chan_sip.c:1854
struct ast_cc_agent * ast_cc_agent_callback(int flags, ao2_callback_fn *function, void *arg, const char *const type)
Call a callback on all agents of a specific type.
Definition: ccss.c:456

◆ find_sip_method()

static int find_sip_method ( const char *  msg)
static

find_sip_method: Find SIP method from header

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

3595 {
3596  int i, res = 0;
3597 
3598  if (ast_strlen_zero(msg)) {
3599  return 0;
3600  }
3601  for (i = 1; i < ARRAY_LEN(sip_methods) && !res; i++) {
3602  if (method_match(i, msg)) {
3603  res = sip_methods[i].id;
3604  }
3605  }
3606  return res;
3607 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static const struct cfsip_methods sip_methods[]
static int method_match(enum sipmethod id, const char *name)
returns true if &#39;name&#39; (with optional trailing whitespace) matches the sip method &#39;id&#39;...
Definition: chan_sip.c:3584
#define ast_strlen_zero(foo)
Definition: strings.h:52
enum sipmethod id
Definition: chan_sip.c:735

◆ find_sip_monitor_instance_by_subscription_pvt()

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

Definition at line 2075 of file chan_sip.c.

References CMP_MATCH, CMP_STOP, and sip_monitor_instance::subscription_pvt.

Referenced by handle_cc_notify(), and handle_response_subscribe().

2076 {
2077  struct sip_monitor_instance *monitor_instance = obj;
2078  return monitor_instance->subscription_pvt == arg ? CMP_MATCH | CMP_STOP : 0;
2079 }
struct sip_pvt * subscription_pvt
Definition: sip.h:1821

◆ find_sip_monitor_instance_by_suspension_entry()

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

◆ find_static_data()

static const struct epa_static_data* find_static_data ( const char *const  event_package)
static

Definition at line 1678 of file chan_sip.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, epa_static_data::name, epa_backend::next, NULL, and epa_backend::static_data.

Referenced by create_epa_entry().

1679 {
1680  const struct epa_backend *backend = NULL;
1681 
1684  if (!strcmp(backend->static_data->name, event_package)) {
1685  break;
1686  }
1687  }
1689  return backend ? backend->static_data : NULL;
1690 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
const struct epa_static_data * static_data
Definition: sip.h:1640
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define NULL
Definition: resample.c:96
const char * name
Definition: sip.h:1621
struct epa_backend * next
Definition: sip.h:1641
backend for an event publication agent
Definition: sip.h:1639
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490

◆ find_subscription_type()

static const struct cfsubscription_types * find_subscription_type ( enum subscriptiontype  subtype)
static

Find subscription type in array.

Definition at line 22130 of file chan_sip.c.

References ARRAY_LEN, subscription_types, and type.

Referenced by transmit_state_notify().

22131 {
22132  int i;
22133 
22134  for (i = 1; i < ARRAY_LEN(subscription_types); i++) {
22135  if (subscription_types[i].type == subtype) {
22136  return &subscription_types[i];
22137  }
22138  }
22139  return &subscription_types[0];
22140 }
static const char type[]
Definition: chan_ooh323.c:109
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static const struct cfsubscription_types subscription_types[]

◆ forked_invite_init()

static void forked_invite_init ( struct sip_request req,
const char *  new_theirtag,
struct sip_pvt original,
struct ast_sockaddr addr 
)
static

This function creates a dialog to handle a forked request. This dialog exists only to properly terminiate the forked request immediately.

Definition at line 9333 of file chan_sip.c.

References ast_strdupa, ast_string_field_set, sip_pvt::branch, build_route(), sip_pvt::callid, copy_request(), dialog_unref, sip_pvt::flags, sip_pvt::fullcontact, sip_pvt::initreq, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::logger_callid, sip_pvt::ocseq, sip_pvt::our_contact, parse_ok_contact(), pvt_set_needdestroy(), SIP_ACK, sip_alloc, SIP_BYE, SIP_INVITE, sip_pvt_lock, sip_pvt_trylock, sip_pvt_unlock, sip_pvt::tag, transmit_request(), TRUE, sip_pvt::uri, XMIT_RELIABLE, and XMIT_UNRELIABLE.

Referenced by __find_call().

9334 {
9335  struct sip_pvt *p;
9336  const char *callid;
9338 
9339  sip_pvt_lock(original);
9340  callid = ast_strdupa(original->callid);
9341  logger_callid = original->logger_callid;
9342  sip_pvt_unlock(original);
9343 
9344  p = sip_alloc(callid, addr, 1, SIP_INVITE, req, logger_callid);
9345  if (!p) {
9346  return; /* alloc error */
9347  }
9348 
9349  /* Lock p and original private structures. */
9350  sip_pvt_lock(p);
9351  while (sip_pvt_trylock(original)) {
9352  /* Can't use DEADLOCK_AVOIDANCE since p is an ao2 object */
9353  sip_pvt_unlock(p);
9354  sched_yield();
9355  sip_pvt_lock(p);
9356  }
9357 
9359  p->ocseq = original->ocseq;
9360  p->branch = original->branch;
9361 
9362  memcpy(&p->flags, &original->flags, sizeof(p->flags));
9363  copy_request(&p->initreq, &original->initreq);
9364  ast_string_field_set(p, theirtag, new_theirtag);
9365  ast_string_field_set(p, tag, original->tag);
9366  ast_string_field_set(p, uri, original->uri);
9369 
9370  sip_pvt_unlock(original);
9371 
9372  parse_ok_contact(p, req);
9373  build_route(p, req, 1, 0);
9374 
9377 
9378  pvt_set_needdestroy(p, "forked request"); /* this dialog will terminate once the BYE is responed to or times out. */
9379  sip_pvt_unlock(p);
9380  dialog_unref(p, "setup forked invite termination");
9381 }
ast_callid logger_callid
Definition: sip.h:1008
Definition: sip.h:619
unsigned int ast_callid
Definition: logger.h:87
struct ast_flags flags[3]
Definition: sip.h:1075
Definition: sip.h:621
static void build_route(struct sip_pvt *p, struct sip_request *req, int backwards, int resp)
Build route list from Record-Route header.
Definition: chan_sip.c:17201
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
const ast_string_field fullcontact
Definition: sip.h:1063
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
struct sip_request initreq
Definition: sip.h:1151
static void copy_request(struct sip_request *dst, const struct sip_request *src)
copy SIP request (mostly used to save request for responses)
Definition: chan_sip.c:14061
long branch
Definition: sip.h:1121
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define sip_alloc(callid, addr, useglobal_nat, intended_method, req, logger_callid)
Definition: dialog.h:39
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&#39;t retry...
Definition: chan_sip.c:16532
const ast_string_field theirtag
Definition: sip.h:1063
const ast_string_field callid
Definition: sip.h:1063
static void pvt_set_needdestroy(struct sip_pvt *pvt, const char *reason)
Definition: chan_sip.c:3429
#define sip_pvt_trylock(x)
Definition: chan_sip.c:1045
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
uint32_t ocseq
Definition: sip.h:1067
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
enum invitestates invitestate
Definition: sip.h:1007
#define TRUE
Definition: app_minivm.c:518
const ast_string_field tag
Definition: sip.h:1063
const ast_string_field uri
Definition: sip.h:1063
static int parse_ok_contact(struct sip_pvt *pvt, struct sip_request *req)
Save contact header for 200 OK on INVITE.
Definition: chan_sip.c:16811
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514
const ast_string_field our_contact
Definition: sip.h:1063

◆ func_check_sipdomain()

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

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

23397 {
23398  if (ast_strlen_zero(data)) {
23399  ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n");
23400  return -1;
23401  }
23402  if (check_sip_domain(data, NULL, 0))
23403  ast_copy_string(buf, data, len);
23404  else
23405  buf[0] = '\0';
23406  return 0;
23407 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
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
Definition: chan_sip.c:31314
#define LOG_WARNING
Definition: logger.h:274
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401

◆ func_header_read()

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

References __get_header(), args, AST_APP_ARG, ast_channel_lock, ast_channel_tech(), ast_channel_tech_pvt(), ast_channel_unlock, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero, sip_pvt::initreq, IS_SIP_TECH, LOG_WARNING, and NULL.

23247 {
23248  struct sip_pvt *p;
23249  const char *content = NULL;
23250  char *mutable_data = ast_strdupa(data);
23254  );
23255  int i, number, start = 0;
23256 
23257  if (!chan) {
23258  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function);
23259  return -1;
23260  }
23261 
23262  if (ast_strlen_zero(data)) {
23263  ast_log(LOG_WARNING, "This function requires a header name.\n");
23264  return -1;
23265  }
23266 
23267  ast_channel_lock(chan);
23268  if (!IS_SIP_TECH(ast_channel_tech(chan))) {
23269  ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
23270  ast_channel_unlock(chan);
23271  return -1;
23272  }
23273 
23274  AST_STANDARD_APP_ARGS(args, mutable_data);
23275  if (!args.number) {
23276  number = 1;
23277  } else {
23278  sscanf(args.number, "%30d", &number);
23279  if (number < 1)
23280  number = 1;
23281  }
23282 
23283  p = ast_channel_tech_pvt(chan);
23284 
23285  /* If there is no private structure, this channel is no longer alive */
23286  if (!p) {
23287  ast_channel_unlock(chan);
23288  return -1;
23289  }
23290 
23291  for (i = 0; i < number; i++)
23292  content = __get_header(&p->initreq, args.header, &start);
23293 
23294  if (ast_strlen_zero(content)) {
23295  ast_channel_unlock(chan);
23296  return -1;
23297  }
23298 
23299  ast_copy_string(buf, content, len);
23300  ast_channel_unlock(chan);
23301 
23302  return 0;
23303 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
void * ast_channel_tech_pvt(const struct ast_channel *chan)
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define LOG_WARNING
Definition: logger.h:274
const char * args
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
Number structure.
Definition: app_followme.c:154
#define ast_log
Definition: astobj2.c:42
struct sip_request initreq
Definition: sip.h:1151
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static const char * __get_header(const struct sip_request *req, const char *name, int *start)
Definition: chan_sip.c:8562
#define IS_SIP_TECH(t)
Definition: sip_utils.h:26
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
#define ast_channel_unlock(chan)
Definition: channel.h:2946
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
#define AST_APP_ARG(name)
Define an application argument.

◆ func_headers_read2()

static int func_headers_read2 ( struct ast_channel chan,
const char *  function,
char *  data,
struct ast_str **  buf,
ssize_t  maxlen 
)
static

Read unique list of SIP headers (dialplan function)

Definition at line 23311 of file chan_sip.c.

References args, AST_APP_ARG, ast_begins_with(), ast_channel_lock, ast_channel_tech(), ast_channel_tech_pvt(), ast_channel_unlock, AST_DECLARE_APP_ARGS, ast_log, ast_skip_blanks(), AST_STANDARD_APP_ARGS, ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_set(), ast_str_truncate(), ast_strdupa, find_full_alias(), sip_request::headers, sip_pvt::initreq, IS_SIP_TECH, LOG_WARNING, NULL, and REQ_OFFSET_TO_STR.

23312 {
23313  int i;
23314  struct sip_pvt *pvt;
23315  char *mutable_data = ast_strdupa(data);
23316  struct ast_str *token = ast_str_alloca(100);
23318  AST_APP_ARG(pattern);
23319  );
23320 
23321  if (!chan) {
23322  return -1;
23323  }
23324 
23325  ast_channel_lock(chan);
23326 
23327  if (!IS_SIP_TECH(ast_channel_tech(chan))) {
23328  ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
23329  ast_channel_unlock(chan);
23330  return -1;
23331  }
23332 
23333  pvt = ast_channel_tech_pvt(chan);
23334  if (!pvt) {
23335  ast_channel_unlock(chan);
23336  return -1;
23337  }
23338 
23339  AST_STANDARD_APP_ARGS(args, mutable_data);
23340  if (!args.pattern || strcmp(args.pattern, "*") == 0) {
23341  args.pattern = "";
23342  }
23343 
23344  for (i = 0; i < pvt->initreq.headers; i++) {
23345  const char *header = REQ_OFFSET_TO_STR(&pvt->initreq, header[i]);
23346  if (ast_begins_with(header, args.pattern)) {
23347  int hdrlen = strcspn(header, " \t:,"); /* Comma will break our logic, and illegal per RFC. */
23348  const char *term = ast_skip_blanks(header + hdrlen);
23349  if (hdrlen > 0 && *term == ':') { /* Header is malformed otherwise! */
23350  const char *s = NULL;
23351 
23352  /* Return short headers in full form always. */
23353  if (hdrlen == 1) {
23354  char short_hdr[2] = { header[0], '\0' };
23355  s = find_full_alias(short_hdr, NULL);
23356  }
23357  if (s) {
23358  /* Short header was found and expanded. */
23359  ast_str_set(&token, -1, "%s,", s);
23360  } else {
23361  /* Return the header as is, whether 1-character or not. */
23362  ast_str_set(&token, -1, "%.*s,", hdrlen, header);
23363  }
23364 
23365  /* Has the same header been already added? */
23366  s = ast_str_buffer(*buf);
23367  while ((s = strstr(s, ast_str_buffer(token))) != NULL) {
23368  /* Found suffix, but is it the full token? */
23369  if (s == ast_str_buffer(*buf) || s[-1] == ',')
23370  break;
23371  /* Only suffix matched, go on with the search after the comma. */
23372  s += hdrlen + 1;
23373  }
23374 
23375  /* s is null iff not broken from the loop, hence header not yet added. */
23376  if (s == NULL) {
23377  ast_str_append(buf, maxlen, "%s", ast_str_buffer(token));
23378  }
23379  }
23380  }
23381  }
23382 
23383  ast_str_truncate(*buf, -1); /* Trim the last comma. Safe if empty. */
23384 
23385  ast_channel_unlock(chan);
23386  return 0;
23387 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
static const char * find_full_alias(const char *name, const char *_default)
Find full SIP alias.
Definition: chan_sip.c:8547
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define LOG_WARNING
Definition: logger.h:274
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
#define ast_str_alloca(init_len)
Definition: strings.h:800
const char * args
#define NULL
Definition: resample.c:96
char * ast_str_truncate(struct ast_str *buf, ssize_t len)
Truncates the enclosed string to the given length.
Definition: strings.h:738
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
#define ast_log
Definition: astobj2.c:42
struct sip_request initreq
Definition: sip.h:1151
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define IS_SIP_TECH(t)
Definition: sip_utils.h:26
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
int headers
Definition: sip.h:832
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define REQ_OFFSET_TO_STR(req, offset)
Definition: sip.h:858
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Definition: strings.h:94
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
#define AST_APP_ARG(name)
Define an application argument.

◆ function_sippeer()

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

References sip_peer::accountcode, sip_peer::addr, ao2_ref, ast_copy_string(), ast_format_cap_get_format(), ast_format_cap_get_names(), AST_FORMAT_CAP_NAMES_LEN, ast_format_get_name(), ast_free, ast_print_group(), ast_print_namedgroups(), ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_str_alloca, ast_str_buffer(), ast_str_create, ast_test_flag, sip_peer::busy_level, sip_peer::call_limit, sip_peer::callgroup, sip_peer::caps, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::expire, FALSE, FINDPEERS, sip_peer::flags, sip_peer::host_dynamic, sip_peer::inuse, sip_peer::language, sip_peer::maxforwards, ast_variable::name, sip_peer::named_callgroups, sip_peer::named_pickupgroups, ast_variable::next, NULL, peer_mailboxes_to_str(), peer_status(), sip_peer::pickupgroup, sip_peer::regexten, sip_find_peer(), SIP_PAGE2_USE_SRTP, sip_unref_peer, strsep(), TRUE, sip_peer::useragent, and ast_variable::value.

23416 {
23417  struct sip_peer *peer;
23418  char *colname;
23419 
23420  if ((colname = strchr(data, ','))) {
23421  *colname++ = '\0';
23422  } else {
23423  colname = "ip";
23424  }
23425 
23426  if (!(peer = sip_find_peer(data, NULL, TRUE, FINDPEERS, FALSE, 0)))
23427  return -1;
23428 
23429  if (!strcasecmp(colname, "ip")) {
23431  } else if (!strcasecmp(colname, "port")) {
23432  snprintf(buf, len, "%d", ast_sockaddr_port(&peer->addr));
23433  } else if (!strcasecmp(colname, "status")) {
23434  peer_status(peer, buf, len);
23435  } else if (!strcasecmp(colname, "language")) {
23436  ast_copy_string(buf, peer->language, len);
23437  } else if (!strcasecmp(colname, "regexten")) {
23438  ast_copy_string(buf, peer->regexten, len);
23439  } else if (!strcasecmp(colname, "limit")) {
23440  snprintf(buf, len, "%d", peer->call_limit);
23441  } else if (!strcasecmp(colname, "busylevel")) {
23442  snprintf(buf, len, "%d", peer->busy_level);
23443  } else if (!strcasecmp(colname, "curcalls")) {
23444  snprintf(buf, len, "%d", peer->inuse);
23445  } else if (!strcasecmp(colname, "maxforwards")) {
23446  snprintf(buf, len, "%d", peer->maxforwards);
23447  } else if (!strcasecmp(colname, "accountcode")) {
23449  } else if (!strcasecmp(colname, "callgroup")) {
23450  ast_print_group(buf, len, peer->callgroup);
23451  } else if (!strcasecmp(colname, "pickupgroup")) {
23453  } else if (!strcasecmp(colname, "namedcallgroup")) {
23454  struct ast_str *tmp_str = ast_str_create(1024);
23455  if (tmp_str) {
23457  ast_free(tmp_str);
23458  }
23459  } else if (!strcasecmp(colname, "namedpickupgroup")) {
23460  struct ast_str *tmp_str = ast_str_create(1024);
23461  if (tmp_str) {
23463  ast_free(tmp_str);
23464  }
23465  } else if (!strcasecmp(colname, "useragent")) {
23466  ast_copy_string(buf, peer->useragent, len);
23467  } else if (!strcasecmp(colname, "mailbox")) {
23468  struct ast_str *mailbox_str = ast_str_alloca(512);
23469  peer_mailboxes_to_str(&mailbox_str, peer);
23470  ast_copy_string(buf, ast_str_buffer(mailbox_str), len);
23471  } else if (!strcasecmp(colname, "context")) {
23472  ast_copy_string(buf, peer->context, len);
23473  } else if (!strcasecmp(colname, "expire")) {
23474  snprintf(buf, len, "%d", peer->expire);
23475  } else if (!strcasecmp(colname, "dynamic")) {
23476  ast_copy_string(buf, peer->host_dynamic ? "yes" : "no", len);
23477  } else if (!strcasecmp(colname, "callerid_name")) {
23478  ast_copy_string(buf, peer->cid_name, len);
23479  } else if (!strcasecmp(colname, "callerid_num")) {
23480  ast_copy_string(buf, peer->cid_num, len);
23481  } else if (!strcasecmp(colname, "codecs")) {
23482  struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
23483  ast_format_cap_get_names(peer->caps, &codec_buf);
23484  ast_copy_string(buf, ast_str_buffer(codec_buf), len);
23485  } else if (!strcasecmp(colname, "encryption")) {
23486  snprintf(buf, len, "%u", ast_test_flag(&peer->flags[1], SIP_PAGE2_USE_SRTP));
23487  } else if (!strncasecmp(colname, "chanvar[", 8)) {
23488  char *chanvar=colname + 8;
23489  struct ast_variable *v;
23490 
23491  chanvar = strsep(&chanvar, "]");
23492  for (v = peer->chanvars ; v ; v = v->next) {
23493  if (!strcasecmp(v->name, chanvar)) {
23494  ast_copy_string(buf, v->value, len);
23495  }
23496  }
23497  } else if (!strncasecmp(colname, "codec[", 6)) {
23498  char *codecnum;
23499  struct ast_format *codec;
23500 
23501  codecnum = colname + 6; /* move past the '[' */
23502  codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */
23503  codec = ast_format_cap_get_format(peer->caps, atoi(codecnum));
23504  if (codec) {
23506  ao2_ref(codec, -1);
23507  } else {
23508  buf[0] = '\0';
23509  }
23510  } else {
23511  buf[0] = '\0';
23512  }
23513 
23514  sip_unref_peer(peer, "sip_unref_peer from function_sippeer, just before return");
23515 
23516  return 0;
23517 }
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:290
struct ast_variable * next
struct ast_namedgroups * named_pickupgroups
Definition: sip.h:1349
struct ast_sockaddr addr
Definition: sip.h:1352
#define FALSE
Definition: app_minivm.c:521
struct sip_peer * sip_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.
Definition: chan_sip.c:5851
const ast_string_field language
Definition: sip.h:1306
#define ast_test_flag(p, flag)
Definition: utils.h:63
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
const ast_string_field accountcode
Definition: sip.h:1306
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:326
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
Structure for variables, used for configurations and for channel variables.
int maxforwards
Definition: sip.h:1331
Definition of a media format.
Definition: format.c:43
unsigned short host_dynamic
Definition: sip.h:1314
#define ast_str_alloca(init_len)
Definition: strings.h:800
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
#define NULL
Definition: resample.c:96
static int peer_status(struct sip_peer *peer, char *status, int statuslen)
Definition: chan_sip.c:20043
struct ast_variable * chanvars
Definition: sip.h:1366
char * ast_print_group(char *buf, int buflen, ast_group_t group)
Print call and pickup groups into buffer.
Definition: channel.c:8133
#define SIP_PAGE2_USE_SRTP
Definition: sip.h:368
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:521
struct ast_namedgroups * named_callgroups
Definition: sip.h:1348
int call_limit
Definition: sip.h:1328
#define ao2_ref(o, delta)
Definition: astobj2.h:464
const ast_string_field useragent
Definition: sip.h:1306
int expire
Definition: sip.h:1341
struct ast_format_cap * caps
Definition: sip.h:1342
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
struct ast_codec * codec
Pointer to the codec in use for this format.
Definition: format.c:47
const ast_string_field regexten
Definition: sip.h:1306
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition: format_cap.c:736
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
#define ast_free(a)
Definition: astmm.h:182
#define FINDPEERS
Definition: sip.h:53
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
ast_group_t callgroup
Definition: sip.h:1346
const ast_string_field cid_name
Definition: sip.h:1306
char * strsep(char **str, const char *delims)
structure for queuing ARI channel variable setting
Definition: control.c:685
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
struct ast_flags flags[3]
Definition: sip.h:1335
#define TRUE
Definition: app_minivm.c:518
const ast_string_field cid_num
Definition: sip.h:1306
int inuse
Definition: sip.h:1325
struct ast_format * ast_format_cap_get_format(const struct ast_format_cap *cap, int position)
Get the format at a specific index.
Definition: format_cap.c:400
int busy_level
Definition: sip.h:1330
char * ast_print_namedgroups(struct ast_str **buf, struct ast_namedgroups *groups)
Print named call groups and named pickup groups.
Definition: channel.c:8158
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620
ast_group_t pickupgroup
Definition: sip.h:1347
const ast_string_field context
Definition: sip.h:1306
static void peer_mailboxes_to_str(struct ast_str **mailbox_str, struct sip_peer *peer)
list peer mailboxes to CLI
Definition: chan_sip.c:21157

◆ generate_random_string()

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

Generate 32 byte random string for callid's etc.

Definition at line 8797 of file chan_sip.c.

References ast_random(), and buf.

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

8798 {
8799  long val[4];
8800  int x;
8801 
8802  for (x=0; x<4; x++)
8803  val[x] = ast_random();
8804  snprintf(buf, size, "%08lx%08lx%08lx%08lx", (unsigned long)val[0], (unsigned long)val[1], (unsigned long)val[2], (unsigned long)val[3]);
8805 
8806  return buf;
8807 }
Definition: ast_expr2.c:325
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
long int ast_random(void)
Definition: main/utils.c:2064

◆ generate_uri()

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

Definition at line 8809 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(), AST_TRANSPORT_TLS, buf, generate_random_string(), sip_pvt::ourip, sip_pvt::socket, and sip_socket::type.

Referenced by add_cc_call_info_to_response(), and transmit_cc_notify().

8810 {
8811  struct ast_str *uri = ast_str_alloca(size);
8812  ast_str_set(&uri, 0, "%s", pvt->socket.type == AST_TRANSPORT_TLS ? "sips:" : "sip:");
8813  /* Here would be a great place to generate a UUID, but for now we'll
8814  * use the handy random string generation function we already have
8815  */
8816  ast_str_append(&uri, 0, "%s", generate_random_string(buf, size));
8817  ast_str_append(&uri, 0, "@%s", ast_sockaddr_stringify_remote(&pvt->ourip));
8818  ast_copy_string(buf, ast_str_buffer(uri), size);
8819  return buf;
8820 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
struct sip_socket socket
Definition: sip.h:1066
struct ast_sockaddr ourip
Definition: sip.h:1136
static char * ast_sockaddr_stringify_remote(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:277
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
#define ast_str_alloca(init_len)
Definition: strings.h:800
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
static char * generate_random_string(char *buf, size_t size)
Generate 32 byte random string for callid&#39;s etc.
Definition: chan_sip.c:8797
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
enum ast_transport type
Definition: sip.h:798
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401

◆ get_address_family_filter()

int get_address_family_filter ( unsigned int  transport)
static

Helper for dns resolution to filter by address family.

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

Definition at line 29558 of file chan_sip.c.

References ast_sockaddr_is_any(), ast_sockaddr_is_ipv6(), AST_TRANSPORT_TCP, AST_TRANSPORT_TLS, AST_TRANSPORT_UDP, AST_TRANSPORT_WS, AST_TRANSPORT_WSS, bindaddr, ast_tcptls_session_args::local_address, NULL, 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().

29559 {
29560  const struct ast_sockaddr *addr = NULL;
29561 
29562  if ((transport == AST_TRANSPORT_UDP) || !transport) {
29563  addr = &bindaddr;
29564  } else if (transport == AST_TRANSPORT_TCP || transport == AST_TRANSPORT_WS) {
29565  addr = &sip_tcp_desc.local_address;
29566  } else if (transport == AST_TRANSPORT_TLS || transport == AST_TRANSPORT_WSS) {
29567  addr = &sip_tls_desc.local_address;
29568  }
29569 
29570  if (ast_sockaddr_is_ipv6(addr) && ast_sockaddr_is_any(addr)) {
29571  return 0;
29572  }
29573 
29574  return addr->ss.ss_family;
29575 }
static struct ast_tcptls_session_args sip_tls_desc
The TCP/TLS server definition.
Definition: chan_sip.c:2394
struct sockaddr_storage ss
Definition: netsock2.h:98
static struct ast_tcptls_session_args sip_tcp_desc
The TCP server definition.
Definition: chan_sip.c:2383
#define NULL
Definition: resample.c:96
Socket address structure.
Definition: netsock2.h:97
int ast_sockaddr_is_any(const struct ast_sockaddr *addr)
Determine if the address type is unspecified, or "any" address.
Definition: netsock2.c:534
struct ast_sockaddr bindaddr
Definition: chan_sip.c:1106
struct ast_sockaddr local_address
Definition: tcptls.h:130
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
Definition: netsock2.c:524

◆ get_also_info()

static int get_also_info ( struct sip_pvt p,
struct sip_request oreq 
)
static

Call transfer support (old way, deprecated by the IETF)

Note
does not account for SIPS: uri requirements, nor check transport

Definition at line 19043 of file chan_sip.c.

References a, ast_canmatch_extension(), ast_channel_macrocontext(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_log, ast_string_field_set, ast_strlen_zero, ast_verbose(), c, context, sip_pvt::context, sip_settings::default_context, get_in_brackets(), sip_pvt::initreq, LOG_WARNING, NULL, sip_pvt::owner, parse_uri_legacy_check(), pbx_builtin_getvar_helper(), sip_pvt::refer, S_OR, sip_cfg, sip_debug_test_pvt(), sip_get_header(), SIP_PEDANTIC_DECODE, sip_refer_alloc(), and tmp().

Referenced by handle_request_bye().

19044 {
19045  char tmp[256] = "", *c, *a;
19046  struct sip_request *req = oreq ? oreq : &p->initreq;
19047  struct sip_refer *refer = NULL;
19048  const char *transfer_context = NULL;
19049 
19050  if (!sip_refer_alloc(p)) {
19051  return -1;
19052  }
19053 
19054  refer = p->refer;
19055 
19056  ast_copy_string(tmp, sip_get_header(req, "Also"), sizeof(tmp));
19057  c = get_in_brackets(tmp);
19058 
19059  if (parse_uri_legacy_check(c, "sip:,sips:", &c, NULL, &a, NULL)) {
19060  ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c);
19061  return -1;
19062  }
19063 
19066 
19067  if (!ast_strlen_zero(a)) {
19069  }
19070 
19071  if (sip_debug_test_pvt(p))
19072  ast_verbose("Looking for %s in %s\n", c, p->context);
19073 
19074  /* Determine transfer context */
19075  if (p->owner) {
19076  /* By default, use the context in the channel sending the REFER */
19077  transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT");
19078  if (ast_strlen_zero(transfer_context)) {
19079  transfer_context = ast_channel_macrocontext(p->owner);
19080  }
19081  }
19082  if (ast_strlen_zero(transfer_context)) {
19083  transfer_context = S_OR(p->context, sip_cfg.default_context);
19084  }
19085 
19086  if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) {
19087  /* This is a blind transfer */
19088  ast_debug(1, "SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context);
19089  ast_string_field_set(refer, refer_to, c);
19090  ast_string_field_set(refer, referred_by, "");
19091  ast_string_field_set(refer, refer_contact, "");
19092  /* Set new context */
19093  ast_string_field_set(p, context, transfer_context);
19094  return 0;
19095  } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) {
19096  return 1;
19097  }
19098 
19099  return -1;
19100 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
char * get_in_brackets(char *tmp)
Pick out text in brackets from character string.
static int sip_refer_alloc(struct sip_pvt *p)
Allocate SIP refer structure.
Definition: chan_sip.c:16370
#define LOG_WARNING
Definition: logger.h:274
static int tmp()
Definition: bt_open.c:389
static struct test_val c
const ast_string_field context
Definition: sip.h:1063
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
#define NULL
Definition: resample.c:96
int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks for a valid matching extension.
Definition: pbx.c:4194
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
#define ast_strlen_zero(foo)
Definition: strings.h:52
const ast_string_field refer_contact
Definition: sip.h:944
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
struct sip_request initreq
Definition: sip.h:1151
const ast_string_field refer_to
Definition: sip.h:944
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:4179
#define SIP_PEDANTIC_DECODE(str)
Definition: chan_sip.c:813
const ast_string_field referred_by
Definition: sip.h:944
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
struct ast_channel * owner
Definition: sip.h:1138
static int sip_debug_test_pvt(struct sip_pvt *p)
Test PVT for debugging output.
Definition: chan_sip.c:3649
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
struct sip_refer * refer
Definition: sip.h:1160
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
const char * ast_channel_macrocontext(const struct ast_channel *chan)
char default_context[AST_MAX_CONTEXT]
Definition: sip.h:782
const ast_string_field refer_to_domain
Definition: sip.h:944
Structure to handle SIP transfers. Dynamically allocated when needed.
Definition: sip.h:933
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
Definition: chan_sip.c:16880
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514
static struct test_val a

◆ get_cached_mwi()

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

Get cached MWI info.

Returns
TRUE if found MWI in cache

Definition at line 29726 of file chan_sip.c.

References ao2_cleanup, AST_LIST_TRAVERSE, ast_mwi_state_cache(), ast_mwi_state_type(), sip_mailbox::id, mailbox, sip_peer::mailboxes, ast_mwi_state::new_msgs, NULL, ast_mwi_state::old_msgs, RAII_VAR, stasis_cache_get(), and stasis_message_data().

Referenced by sip_send_mwi_to_peer().

29727 {
29728  struct sip_mailbox *mailbox;
29729  int in_cache;
29730 
29731  in_cache = 0;
29732  AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
29733  RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
29734  struct ast_mwi_state *mwi_state;
29735 
29737  if (!msg) {
29738  continue;
29739  }
29740 
29741  mwi_state = stasis_message_data(msg);
29742  *new += mwi_state->new_msgs;
29743  *old += mwi_state->old_msgs;
29744  in_cache = 1;
29745  }
29746 
29747  return in_cache;
29748 }
struct stasis_cache * ast_mwi_state_cache(void)
Backend cache for ast_mwi_topic_cached().
Definition: mwi.c:90
A peer&#39;s mailbox.
Definition: sip.h:1261
char id[1]
Definition: sip.h:1267
#define NULL
Definition: resample.c:96
static char mailbox[AST_MAX_MAILBOX_UNIQUEID]
Definition: chan_mgcp.c:204
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
int old_msgs
Definition: mwi.h:462
struct sip_peer::@176 mailboxes
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
struct stasis_message_type * ast_mwi_state_type(void)
Get the Stasis Message Bus API message type for MWI messages.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
int new_msgs
Definition: mwi.h:461
struct stasis_message * stasis_cache_get(struct stasis_cache *cache, struct stasis_message_type *type, const char *id)
Retrieve an item from the cache for the ast_eid_default entity.
Definition: stasis_cache.c:686
Definition: search.h:40
The structure that contains MWI state.
Definition: mwi.h:457

◆ get_content()

static char * get_content ( struct sip_request req)
static

Get message body content.

Definition at line 8610 of file chan_sip.c.

References ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_thread_get(), sip_request::lines, NULL, REQ_OFFSET_TO_STR, sip_content_buf, and str.

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

8611 {
8612  struct ast_str *str;
8613  int i;
8614 
8615  if (!(str = ast_str_thread_get(&sip_content_buf, 128))) {
8616  return NULL;
8617  }
8618 
8619  ast_str_reset(str);
8620 
8621  for (i = 0; i < req->lines; i++) {
8622  if (ast_str_append(&str, 0, "%s\n", REQ_OFFSET_TO_STR(req, line[i])) < 0) {
8623  return NULL;
8624  }
8625  }
8626 
8627  return ast_str_buffer(str);
8628 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
const char * str
Definition: app_jack.c:147
#define NULL
Definition: resample.c:96
static struct ast_threadstorage sip_content_buf
Definition: chan_sip.c:8607
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
#define REQ_OFFSET_TO_STR(req, offset)
Definition: sip.h:858
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:653
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
Definition: strings.h:861
int lines
Definition: sip.h:834

◆ get_content_line()

static char* get_content_line ( struct sip_request req,
char *  name,
char  delimiter 
)
static

Get a specific line from the message content.

Definition at line 8489 of file chan_sip.c.

References ast_skip_blanks(), len(), sip_request::lines, and REQ_OFFSET_TO_STR.

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

8490 {
8491  int i;
8492  int len = strlen(name);
8493  const char *line;
8494 
8495  for (i = 0; i < req->lines; i++) {
8496  line = REQ_OFFSET_TO_STR(req, line[i]);
8497  if (!strncasecmp(line, name, len) && line[len] == delimiter) {
8498  return ast_skip_blanks(line + len + 1);
8499  }
8500  }
8501 
8502  return "";
8503 }
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
static const char name[]
Definition: cdr_mysql.c:74
#define REQ_OFFSET_TO_STR(req, offset)
Definition: sip.h:858
int lines
Definition: sip.h:834

◆ get_destination()

static enum sip_get_dest_result get_destination ( struct sip_pvt p,
struct sip_request oreq,
int *  cc_recall_core_id 
)
static

Find out who the call is for.

We use the request uri as a destination. This code assumes authentication has been done, so that the device (peer/user) context is already set.

Returns
0 on success (found a matching extension), non-zero on failure
Note
If the incoming uri is a SIPS: uri, we are required to carry this across the dialplan, so that the outbound call also is a sips: call or encrypted IAX2 call. If that's not available, the call should FAIL.

Definition at line 18508 of file chan_sip.c.

References sip_settings::allow_external_domains, ao2_cleanup, ao2_ref, ast_canmatch_extension(), ast_cc_agent_recalling(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_free, ast_get_chan_features_pickup_config(), ast_get_hint(), AST_LIST_EMPTY, ast_log, AST_MAX_EXTENSION, ast_strdup, ast_strdupa, ast_string_field_set, ast_strlen_zero, ast_test_flag, ast_uri_decode(), ast_uri_sip_user, ast_verbose(), check_sip_domain(), sip_pvt::cid_num, context, sip_pvt::context, ast_cc_agent::core_id, ast_cc_agent::device_name, sip_pvt::domain, exten, extract_host_from_hostport(), find_sip_cc_agent_by_notify_uri(), sip_pvt::flags, get_in_brackets(), sip_pvt::initreq, LOG_ERROR, LOG_WARNING, sip_request::method, NULL, sip_cc_agent_pvt::original_exten, sip_pvt::owner, parse_uri_legacy_check(), ast_cc_agent::private_data, RAII_VAR, REQ_OFFSET_TO_STR, sip_request::rlpart2, S_OR, sip_cfg, sip_debug_test_pvt(), SIP_GET_DEST_EXTEN_FOUND, SIP_GET_DEST_EXTEN_MATCHMORE, SIP_GET_DEST_EXTEN_NOT_FOUND, SIP_GET_DEST_INVALID_URI, SIP_GET_DEST_REFUSED, sip_get_header(), SIP_INVITE, sip_methods, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_HAVEPEERCONTEXT, SIP_PEDANTIC_DECODE, SIP_REFER, SIP_SUBSCRIBE, sip_pvt::subscribecontext, cfsip_methods::text, and tmp().

Referenced by handle_request_invite(), handle_request_options(), handle_request_subscribe(), and receive_message().

18509 {
18510  char tmp[256] = "", *uri, *unused_password, *domain;
18511  RAII_VAR(char *, tmpf, NULL, ast_free);
18512  char *from = NULL;
18513  struct sip_request *req;
18514  char *decoded_uri;
18516  const char *pickupexten;
18517 
18518  if (!pickup_cfg) {
18519  ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
18520  pickupexten = "";
18521  } else {
18522  /* Don't need to duplicate since channel is locked for the duration of this function */
18523  pickupexten = pickup_cfg->pickupexten;
18524  }
18525 
18526  req = oreq;
18527  if (!req) {
18528  req = &p->initreq;
18529  }
18530 
18531  /* Find the request URI */
18532  if (req->rlpart2) {
18533  ast_copy_string(tmp, REQ_OFFSET_TO_STR(req, rlpart2), sizeof(tmp));
18534  }
18535 
18536  uri = ast_strdupa(get_in_brackets(tmp));
18537 
18538  if (parse_uri_legacy_check(uri, "sip:,sips:,tel:", &uri, &unused_password, &domain, NULL)) {
18539  ast_log(LOG_WARNING, "Not a SIP header (%s)?\n", uri);
18540  return SIP_GET_DEST_INVALID_URI;
18541  }
18542 
18543  SIP_PEDANTIC_DECODE(domain);
18544  SIP_PEDANTIC_DECODE(uri);
18545 
18546  extract_host_from_hostport(&domain);
18547 
18548  if (strncasecmp(get_in_brackets(tmp), "tel:", 4)) {
18549  ast_string_field_set(p, domain, domain);
18550  } else {
18551  ast_string_field_set(p, tel_phone_context, domain);
18552  }
18553 
18554  if (ast_strlen_zero(uri)) {
18555  /*
18556  * Either there really was no extension found or the request
18557  * URI had encoded nulls that made the string "empty". Use "s"
18558  * as the extension.
18559  */
18560  uri = "s";
18561  }
18562 
18563  /* Now find the From: caller ID and name */
18564  /* XXX Why is this done in get_destination? Isn't it already done?
18565  Needs to be checked
18566  */
18567  tmpf = ast_strdup(sip_get_header(req, "From"));
18568  if (!ast_strlen_zero(tmpf)) {
18569  from = get_in_brackets(tmpf);
18570  if (parse_uri_legacy_check(from, "sip:,sips:,tel:", &from, NULL, &domain, NULL)) {
18571  ast_log(LOG_WARNING, "Not a SIP header (%s)?\n", from);
18572  return SIP_GET_DEST_INVALID_URI;
18573  }
18574 
18575  SIP_PEDANTIC_DECODE(from);
18576  SIP_PEDANTIC_DECODE(domain);
18577 
18578  extract_host_from_hostport(&domain);
18579 
18580  ast_string_field_set(p, fromdomain, domain);
18581  }
18582 
18583  if (!AST_LIST_EMPTY(&domain_list)) {
18584  char domain_context[AST_MAX_EXTENSION];
18585 
18586  domain_context[0] = '\0';
18587  if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) {
18588  if (!sip_cfg.allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) {
18589  ast_debug(1, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain);
18590  return SIP_GET_DEST_REFUSED;
18591  }
18592  }
18593  /* If we don't have a peer (i.e. we're a guest call),
18594  * overwrite the original context */
18595  if (!ast_test_flag(&p->flags[1], SIP_PAGE2_HAVEPEERCONTEXT) && !ast_strlen_zero(domain_context)) {
18596  ast_string_field_set(p, context, domain_context);
18597  }
18598  }
18599 
18600  /* If the request coming in is a subscription and subscribecontext has been specified use it */
18601  if (req->method == SIP_SUBSCRIBE && !ast_strlen_zero(p->subscribecontext)) {
18603  }
18604 
18605  if (sip_debug_test_pvt(p)) {
18606  ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain);
18607  }
18608 
18609  /* Since extensions.conf can have unescaped characters, try matching a
18610  * decoded uri in addition to the non-decoded uri. */
18611  decoded_uri = ast_strdupa(uri);
18612  ast_uri_decode(decoded_uri, ast_uri_sip_user);
18613 
18614  /* If this is a subscription we actually just need to see if a hint exists for the extension */
18615  if (req->method == SIP_SUBSCRIBE) {
18616  int which = 0;
18617 
18618  if (ast_get_hint(NULL, 0, NULL, 0, NULL, p->context, uri)
18619  || (ast_get_hint(NULL, 0, NULL, 0, NULL, p->context, decoded_uri)
18620  && (which = 1))) {
18621  if (!oreq) {
18622  ast_string_field_set(p, exten, which ? decoded_uri : uri);
18623  }
18624  return SIP_GET_DEST_EXTEN_FOUND;
18625  } else {
18627  }
18628  } else {
18629  struct ast_cc_agent *agent;
18630  /* Check the dialplan for the username part of the request URI,
18631  the domain will be stored in the SIPDOMAIN variable
18632  Return 0 if we have a matching extension */
18633  if (ast_exists_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from))) {
18634  if (!oreq) {
18635  ast_string_field_set(p, exten, uri);
18636  }
18637  return SIP_GET_DEST_EXTEN_FOUND;
18638  }
18639  if (ast_exists_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from))
18640  || !strcmp(decoded_uri, pickupexten)) {
18641  if (!oreq) {
18642  ast_string_field_set(p, exten, decoded_uri);
18643  }
18644  return SIP_GET_DEST_EXTEN_FOUND;
18645  }
18646  if ((agent = find_sip_cc_agent_by_notify_uri(tmp))) {
18647  struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
18648  /* This is a CC recall. We can set p's extension to the exten from
18649  * the original INVITE
18650  */
18651  ast_string_field_set(p, exten, agent_pvt->original_exten);
18652  /* And we need to let the CC core know that the caller is attempting
18653  * his recall
18654  */
18655  ast_cc_agent_recalling(agent->core_id, "SIP caller %s is attempting recall",
18656  agent->device_name);
18657  if (cc_recall_core_id) {
18658  *cc_recall_core_id = agent->core_id;
18659  }
18660  ao2_ref(agent, -1);
18661  return SIP_GET_DEST_EXTEN_FOUND;
18662  }
18663  }
18664 
18666  && (ast_canmatch_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from))
18667  || ast_canmatch_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from))
18668  || !strncmp(decoded_uri, pickupexten, strlen(decoded_uri)))) {
18669  /* Overlap dialing is enabled and we need more digits to match an extension. */
18671  }
18672 
18674 }
void ast_uri_decode(char *s, struct ast_flags spec)
Decode URI, URN, URL (overwrite string)
Definition: main/utils.c:616
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
int ast_get_hint(char *hint, int hintsize, char *name, int namesize, struct ast_channel *c, const char *context, const char *exten)
If an extension hint exists, return non-zero.
Definition: pbx.c:4141
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
char * get_in_brackets(char *tmp)
Pick out text in brackets from character string.
struct ast_features_pickup_config * ast_get_chan_features_pickup_config(struct ast_channel *chan)
Get the pickup configuration options for a channel.
void * private_data
Definition: ccss.h:871
#define ast_test_flag(p, flag)
Definition: utils.h:63
static const struct cfsip_methods sip_methods[]
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
Definition: chan_sip.c:31314
#define LOG_WARNING
Definition: logger.h:274
static int tmp()
Definition: bt_open.c:389
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
struct ast_flags flags[3]
Definition: sip.h:1075
const ast_string_field context
Definition: sip.h:1063
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
const ast_string_field subscribecontext
Definition: sip.h:1063
#define NULL
Definition: resample.c:96
Domain data structure.
Definition: sip.h:888
int ast_cc_agent_recalling(int core_id, const char *const debug,...)
Tell the CC core that a caller is currently recalling.
Definition: ccss.c:3831
int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks for a valid matching extension.
Definition: pbx.c:4194
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
int allow_external_domains
Definition: sip.h:765
struct sip_request initreq
Definition: sip.h:1151
#define AST_MAX_EXTENSION
Definition: channel.h:135
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static struct ast_cc_agent * find_sip_cc_agent_by_notify_uri(const char *const uri)
Definition: chan_sip.c:1848
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:4179
static void extract_host_from_hostport(char **hostport)
Terminate a host:port at the &#39;:&#39;.
Definition: chan_sip.c:17831
#define SIP_PEDANTIC_DECODE(str)
Definition: chan_sip.c:813
#define SIP_PAGE2_ALLOWOVERLAP
Definition: sip.h:337
#define LOG_ERROR
Definition: logger.h:285
const ast_string_field cid_num
Definition: sip.h:1063
Structure representing an agent.
#define SIP_PAGE2_HAVEPEERCONTEXT
Definition: sip.h:367
const ast_string_field domain
Definition: sip.h:1063
int method
Definition: sip.h:833
static struct ast_flags global_flags[3]
Definition: chan_sip.c:884
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
unsigned int core_id
Definition: ccss.h:849
#define ast_free(a)
Definition: astmm.h:182
struct ast_channel * owner
Definition: sip.h:1138
char original_exten[SIPBUFSIZE]
Definition: sip.h:1791
#define REQ_OFFSET_TO_STR(req, offset)
Definition: sip.h:858
static int sip_debug_test_pvt(struct sip_pvt *p)
Test PVT for debugging output.
Definition: chan_sip.c:3649
char *const text
Definition: chan_sip.c:737
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
char device_name[1]
Definition: ccss.h:875
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Definition: sip.h:622
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
const struct ast_flags ast_uri_sip_user
Definition: main/utils.c:575
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
ptrdiff_t rlpart2
Definition: sip.h:831
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
Definition: chan_sip.c:16880
Configuration relating to call pickup.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ get_domain()

static int get_domain ( const char *  str,
char *  domain,
int  len 
)
static

Extract domain from SIP To/From header.

Returns
-1 on error, 1 if domain string is empty, 0 if domain was properly extracted
Note
TODO: Such code is all over SIP channel, there is a sense to organize this patern in one function

Definition at line 12782 of file chan_sip.c.

References a, ast_copy_string(), ast_log, ast_strlen_zero, get_in_brackets(), LOG_WARNING, and NULL.

Referenced by get_realm().

12783 {
12784  char tmpf[256];
12785  char *a, *from;
12786 
12787  *domain = '\0';
12788  ast_copy_string(tmpf, str, sizeof(tmpf));
12789  from = get_in_brackets(tmpf);
12790  if (!ast_strlen_zero(from)) {
12791  if (strncasecmp(from, "sip:", 4)) {
12792  ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from);
12793  return -1;
12794  }
12795  from += 4;
12796  } else
12797  from = NULL;
12798 
12799  if (from) {
12800  int bracket = 0;
12801 
12802  /* Strip any params or options from user */
12803  if ((a = strchr(from, ';')))
12804  *a = '\0';
12805  /* Strip port from domain if present */
12806  for (a = from; *a != '\0'; ++a) {
12807  if (*a == ':' && bracket == 0) {
12808  *a = '\0';
12809  break;
12810  } else if (*a == '[') {
12811  ++bracket;
12812  } else if (*a == ']') {
12813  --bracket;
12814  }
12815  }
12816  if ((a = strchr(from, '@'))) {
12817  *a = '\0';
12818  ast_copy_string(domain, a + 1, len);
12819  } else
12820  ast_copy_string(domain, from, len);
12821  }
12822 
12823  return ast_strlen_zero(domain);
12824 }
char * get_in_brackets(char *tmp)
Pick out text in brackets from character string.
#define LOG_WARNING
Definition: logger.h:274
const char * str
Definition: app_jack.c:147
#define NULL
Definition: resample.c:96
Domain data structure.
Definition: sip.h:888
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static struct test_val a

◆ get_esc()

static struct event_state_compositor* get_esc ( const char *const  event_package)
static

Definition at line 1743 of file chan_sip.c.

References ARRAY_LEN, event_state_compositors, name, and NULL.

Referenced by create_new_sip_etag(), handle_request_publish(), and publish_expire().

1743  {
1744  int i;
1745  for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) {
1746  if (!strcasecmp(event_package, event_state_compositors[i].name)) {
1747  return &event_state_compositors[i];
1748  }
1749  }
1750  return NULL;
1751 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define NULL
Definition: resample.c:96
static struct event_state_compositor event_state_compositors[]
static const char name[]
Definition: cdr_mysql.c:74

◆ get_esc_entry()

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

Definition at line 1753 of file chan_sip.c.

References ao2_find, ast_copy_string(), event_state_compositor::compositor, sip_esc_entry::entity_tag, and OBJ_POINTER.

Referenced by handle_sip_publish_modify(), handle_sip_publish_refresh(), and handle_sip_publish_remove().

1753  {
1754  struct sip_esc_entry *entry;
1755  struct sip_esc_entry finder;
1756 
1757  ast_copy_string(finder.entity_tag, entity_tag, sizeof(finder.entity_tag));
1758 
1759  entry = ao2_find(esc->compositor, &finder, OBJ_POINTER);
1760 
1761  return entry;
1762 }
#define OBJ_POINTER
Definition: astobj2.h:1154
common ESC items for all event types
Definition: sip.h:1715
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
char entity_tag[30]
Definition: sip.h:1742
Definition: search.h:40
struct ao2_container * compositor
Definition: chan_sip.c:1000

◆ get_insecure_variable_from_config()

static struct ast_variable * get_insecure_variable_from_config ( struct ast_config config)
static

Definition at line 5396 of file chan_sip.c.

References ast_category_browse(), ast_category_root(), ast_test_flag, ast_variable_retrieve(), NULL, set_insecure_flags(), SIP_INSECURE_PORT, and var.

Referenced by get_insecure_variable_from_sippeers().

5397 {
5398  struct ast_variable *var = NULL;
5399  struct ast_flags flags = {0};
5400  char *cat = NULL;
5401  const char *insecure;
5402  while ((cat = ast_category_browse(cfg, cat))) {
5403  insecure = ast_variable_retrieve(cfg, cat, "insecure");
5404  set_insecure_flags(&flags, insecure, -1);
5405  if (ast_test_flag(&flags, SIP_INSECURE_PORT)) {
5406  var = ast_category_root(cfg, cat);
5407  break;
5408  }
5409  }
5410  return var;
5411 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
unsigned int flags
Definition: utils.h:200
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
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.
Definition: chan_sip.c:31049
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3328
#define NULL
Definition: resample.c:96
#define SIP_INSECURE_PORT
Definition: sip.h:296
struct ast_variable * ast_category_root(struct ast_config *config, char *cat)
returns the root ast_variable of a config
Definition: main/config.c:1162
Structure used to handle boolean flags.
Definition: utils.h:199
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
Definition: main/config.c:694

◆ get_insecure_variable_from_sippeers()

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

Definition at line 5413 of file chan_sip.c.

References ast_config_destroy(), ast_load_realtime_multientry(), ast_variables_dup(), get_insecure_variable_from_config(), NULL, SENTINEL, and var.

Referenced by realtime_peer_by_addr().

5414 {
5415  struct ast_config *peerlist;
5416  struct ast_variable *var = NULL;
5417  if ((peerlist = ast_load_realtime_multientry("sippeers", column, value, "insecure LIKE", "%port%", SENTINEL))) {
5418  if ((var = get_insecure_variable_from_config(peerlist))) {
5419  /* Must clone, because var will get freed along with
5420  * peerlist. */
5421  var = ast_variables_dup(var);
5422  }
5423  ast_config_destroy(peerlist);
5424  }
5425  return var;
5426 }
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
#define NULL
Definition: resample.c:96
int value
Definition: syslog.c:37
#define SENTINEL
Definition: compiler.h:87
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
struct ast_config * ast_load_realtime_multientry(const char *family,...) attribute_sentinel
Retrieve realtime configuration.
Definition: main/config.c:3452
static struct ast_variable * get_insecure_variable_from_config(struct ast_config *config)
Definition: chan_sip.c:5396
struct ast_variable * ast_variables_dup(struct ast_variable *var)
Duplicate variable list.
Definition: main/config.c:545

◆ get_insecure_variable_from_sipregs()

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

Definition at line 5433 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(), done, NULL, sip_monitor_instance::peername, peers, SENTINEL, set_insecure_flags(), and SIP_INSECURE_PORT.

Referenced by realtime_peer_by_addr().

5434 {
5435  struct ast_variable *varregs = NULL;
5436  struct ast_config *regs, *peers;
5437  char *regscat;
5438  const char *regname;
5439 
5440  if (!(regs = ast_load_realtime_multientry("sipregs", column, value, SENTINEL))) {
5441  return NULL;
5442  }
5443 
5444  /* Load *all* peers that are probably insecure=port */
5445  if (!(peers = ast_load_realtime_multientry("sippeers", "insecure LIKE", "%port%", SENTINEL))) {
5446  ast_config_destroy(regs);
5447  return NULL;
5448  }
5449 
5450  /* Loop over the sipregs that match IP address and attempt to find an
5451  * insecure=port match to it in sippeers. */
5452  regscat = NULL;
5453  while ((regscat = ast_category_browse(regs, regscat)) && (regname = ast_variable_retrieve(regs, regscat, "name"))) {
5454  char *peerscat;
5455  const char *peername;
5456 
5457  peerscat = NULL;
5458  while ((peerscat = ast_category_browse(peers, peerscat)) && (peername = ast_variable_retrieve(peers, peerscat, "name"))) {
5459  if (!strcasecmp(regname, peername)) {
5460  /* Ensure that it really is insecure=port and
5461  * not something else. */
5462  const char *insecure = ast_variable_retrieve(peers, peerscat, "insecure");
5463  struct ast_flags flags = {0};
5464  set_insecure_flags(&flags, insecure, -1);
5465  if (ast_test_flag(&flags, SIP_INSECURE_PORT)) {
5466  /* ENOMEM checks till the bitter end. */
5467  if ((varregs = ast_variables_dup(ast_category_root(regs, regscat)))) {
5468  if (!(*var = ast_variables_dup(ast_category_root(peers, peerscat)))) {
5469  ast_variables_destroy(varregs);
5470  varregs = NULL;
5471  }
5472  }
5473  goto done;
5474  }
5475  }
5476  }
5477  }
5478 
5479 done:
5480  ast_config_destroy(regs);
5481  ast_config_destroy(peers);
5482  return varregs;
5483 }
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
static struct ao2_container * peers
The peer list: Users, Peers and Friends.
Definition: chan_sip.c:1052
#define ast_test_flag(p, flag)
Definition: utils.h:63
unsigned int flags
Definition: utils.h:200
Structure for variables, used for configurations and for channel variables.
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.
Definition: chan_sip.c:31049
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3328
#define NULL
Definition: resample.c:96
int value
Definition: syslog.c:37
#define SIP_INSECURE_PORT
Definition: sip.h:296
int done
Definition: test_amihooks.c:48
struct ast_variable * ast_category_root(struct ast_config *config, char *cat)
returns the root ast_variable of a config
Definition: main/config.c:1162
#define SENTINEL
Definition: compiler.h:87
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
struct ast_config * ast_load_realtime_multientry(const char *family,...) attribute_sentinel
Retrieve realtime configuration.
Definition: main/config.c:3452
Structure used to handle boolean flags.
Definition: utils.h:199
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
Definition: main/config.c:694
struct ast_variable * ast_variables_dup(struct ast_variable *var)
Duplicate variable list.
Definition: main/config.c:545

◆ get_name_from_variable()

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

Definition at line 5485 of file chan_sip.c.

References ast_strlen_zero, ast_variable::name, ast_variable::next, NULL, tmp(), and ast_variable::value.

Referenced by realtime_peer_by_addr(), and realtime_peer_get_sippeer_helper().

5486 {
5487  /* Don't expect this to return non-NULL. Both NULL and empty
5488  * values can cause the option to get removed from the variable
5489  * list. This is called on ast_variables gotten from both
5490  * ast_load_realtime and ast_load_realtime_multientry.
5491  * - ast_load_realtime removes options with empty values
5492  * - ast_load_realtime_multientry does not!
5493  * For consistent behaviour, we check for the empty name and
5494  * return NULL instead. */
5495  const struct ast_variable *tmp;
5496  for (tmp = var; tmp; tmp = tmp->next) {
5497  if (!strcasecmp(tmp->name, "name")) {
5498  if (!ast_strlen_zero(tmp->value)) {
5499  return tmp->value;
5500  }
5501  break;
5502  }
5503  }
5504  return NULL;
5505 }
struct ast_variable * next
static int tmp()
Definition: bt_open.c:389
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52

◆ get_our_media_address()

static void get_our_media_address ( struct sip_pvt p,
int  needvideo,
int  needtext,
struct ast_sockaddr addr,
struct ast_sockaddr vaddr,
struct ast_sockaddr taddr,
struct ast_sockaddr dest,
struct ast_sockaddr vdest,
struct ast_sockaddr tdest 
)
static

Set all IP media addresses for this call.

Note
called from add_sdp()

Definition at line 13410 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, media_address, sip_pvt::ourip, sip_pvt::redirip, sip_pvt::rtp, sip_pvt::tredirip, sip_pvt::trtp, sip_pvt::vredirip, and sip_pvt::vrtp.

Referenced by add_sdp().

13414 {
13415  int use_externip = 0;
13416 
13417  /* First, get our address */
13419  if (p->vrtp) {
13421  }
13422  if (p->trtp) {
13424  }
13425 
13426  /* If our real IP differs from the local address returned by the RTP engine, use it. */
13427  /* The premise is that if we are already using that IP to communicate with the client, */
13428  /* we should be using it for RTP too. */
13429  use_externip = ast_sockaddr_cmp_addr(&p->ourip, addr);
13430 
13431  /* Now, try to figure out where we want them to send data */
13432  /* Is this a re-invite to move the media out, then use the original offer from caller */
13433  if (!ast_sockaddr_isnull(&p->redirip)) { /* If we have a redirection IP, use it */
13434  ast_sockaddr_copy(dest, &p->redirip);
13435  } else {
13436  /*
13437  * Audio Destination IP:
13438  *
13439  * 1. Specifically configured media address.
13440  * 2. Local address as specified by the RTP engine.
13441  * 3. The local IP as defined by chan_sip.
13442  *
13443  * Audio Destination Port:
13444  *
13445  * 1. Provided by the RTP engine.
13446  */
13447  ast_sockaddr_copy(dest,
13449  !ast_sockaddr_is_any(addr) && !use_externip ? addr :
13450  &p->ourip);
13452  }
13453 
13454  if (needvideo) {
13455  /* Determine video destination */
13456  if (!ast_sockaddr_isnull(&p->vredirip)) {
13457  ast_sockaddr_copy(vdest, &p->vredirip);
13458  } else {
13459  /*
13460  * Video Destination IP:
13461  *
13462  * 1. Specifically configured media address.
13463  * 2. Local address as specified by the RTP engine.
13464  * 3. The local IP as defined by chan_sip.
13465  *
13466  * Video Destination Port:
13467  *
13468  * 1. Provided by the RTP engine.
13469  */
13470  ast_sockaddr_copy(vdest,
13472  !ast_sockaddr_is_any(vaddr) && !use_externip ? vaddr :
13473  &p->ourip);
13475  }
13476  }
13477 
13478  if (needtext) {
13479  /* Determine text destination */
13480  if (!ast_sockaddr_isnull(&p->tredirip)) {
13481  ast_sockaddr_copy(tdest, &p->tredirip);
13482  } else {
13483  /*
13484  * Text Destination IP:
13485  *
13486  * 1. Specifically configured media address.
13487  * 2. Local address as specified by the RTP engine.
13488  * 3. The local IP as defined by chan_sip.
13489  *
13490  * Text Destination Port:
13491  *
13492  * 1. Provided by the RTP engine.
13493  */
13494  ast_sockaddr_copy(tdest,
13496  !ast_sockaddr_is_any(taddr) && !use_externip ? taddr :
13497  &p->ourip);
13499  }
13500  }
13501 }
struct ast_rtp_instance * trtp
Definition: sip.h:1176
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:171
struct ast_sockaddr redirip
Definition: sip.h:1126
struct ast_sockaddr ourip
Definition: sip.h:1136
int ast_sockaddr_cmp_addr(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares the addresses of two ast_sockaddr structures.
Definition: netsock2.c:413
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:521
static struct ast_sockaddr media_address
Definition: chan_sip.c:1132
int ast_sockaddr_is_any(const struct ast_sockaddr *addr)
Determine if the address type is unspecified, or "any" address.
Definition: netsock2.c:534
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:537
struct ast_rtp_instance * vrtp
Definition: sip.h:1175
struct ast_sockaddr tredirip
Definition: sip.h:1128
struct ast_rtp_instance * rtp
Definition: sip.h:1174
void ast_rtp_instance_get_local_address(struct ast_rtp_instance *instance, struct ast_sockaddr *address)
Get the local address that we are expecting RTP on.
Definition: rtp_engine.c:643
struct ast_sockaddr vredirip
Definition: sip.h:1127

◆ get_pai()

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

References ast_channel_caller(), 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, sip_pvt::callingpres, cid_name, sip_pvt::cid_name, cid_num, sip_pvt::cid_num, get_in_brackets(), get_name_and_number(), global_shrinkcallerid, ast_party_caller::id, ast_party_id::name, NULL, ast_party_id::number, sip_pvt::owner, ast_party_name::presentation, ast_party_number::presentation, and sip_get_header().

Referenced by get_rpid().

18191 {
18192  char pai[256];
18193  char privacy[64];
18194  char *cid_num = NULL;
18195  char *cid_name = NULL;
18196  char emptyname[1] = "";
18198  char *uri = NULL;
18199  int is_anonymous = 0, do_update = 1, no_name = 0;
18200 
18201  ast_copy_string(pai, sip_get_header(req, "P-Asserted-Identity"), sizeof(pai));
18202 
18203  if (ast_strlen_zero(pai)) {
18204  return 0;
18205  }
18206 
18207  /* use the reqresp_parser function get_name_and_number*/
18208  if (get_name_and_number(pai, &cid_name, &cid_num)) {
18209  return 0;
18210  }
18211 
18213  ast_shrink_phone_number(cid_num);
18214  }
18215 
18216  uri = get_in_brackets(pai);
18217  if (!strncasecmp(uri, "sip:[email protected]", 31)) {
18219  /*XXX Assume no change in cid_num. Perhaps it should be
18220  * blanked?
18221  */
18222  ast_free(cid_num);
18223  is_anonymous = 1;
18224  cid_num = (char *)p->cid_num;
18225  }
18226 
18227  ast_copy_string(privacy, sip_get_header(req, "Privacy"), sizeof(privacy));
18228  if (!ast_strlen_zero(privacy) && strcasecmp(privacy, "none")) {
18230  }
18231  if (!cid_name) {
18232  no_name = 1;
18233  cid_name = (char *)emptyname;
18234  }
18235  /* Only return true if the supplied caller id is different */
18236  if (!strcasecmp(p->cid_num, cid_num) && !strcasecmp(p->cid_name, cid_name) && p->callingpres == callingpres) {
18237  do_update = 0;
18238  } else {
18239 
18240  ast_string_field_set(p, cid_num, cid_num);
18241  ast_string_field_set(p, cid_name, cid_name);
18242  p->callingpres = callingpres;
18243 
18244  if (p->owner) {
18245  ast_set_callerid(p->owner, cid_num, cid_name, NULL);
18246  ast_channel_caller(p->owner)->id.name.presentation = callingpres;
18247  ast_channel_caller(p->owner)->id.number.presentation = callingpres;
18248  }
18249  }
18250 
18251  /* get_name_and_number allocates memory for cid_num and cid_name so we have to free it */
18252  if (!is_anonymous) {
18253  ast_free(cid_num);
18254  }
18255  if (!no_name) {
18256  ast_free(cid_name);
18257  }
18258 
18259  return do_update;
18260 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
static int global_shrinkcallerid
Definition: chan_sip.c:829
int presentation
Q.931 encoded presentation-indicator encoded field.
Definition: channel.h:278
void ast_set_callerid(struct ast_channel *chan, const char *cid_num, const char *cid_name, const char *cid_ani)
Set caller ID number, name and ANI and generate AMI event.
Definition: channel.c:7434
char * get_in_brackets(char *tmp)
Pick out text in brackets from character string.
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
Definition: channel.h:296
struct ast_party_name name
Subscriber name.
Definition: channel.h:341
#define AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED
Definition: callerid.h:341
#define NULL
Definition: resample.c:96
int ast_is_shrinkable_phonenumber(const char *exten)
Check if a string consists only of digits and + # ( ) - . (meaning it can be cleaned with ast_shrink_...
Definition: callerid.c:1003
#define AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED
Definition: callerid.h:329
static char cid_num[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:164
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ast_party_id id
Caller party ID.
Definition: channel.h:421
int callingpres
Definition: sip.h:1117
int get_name_and_number(const char *hdr, char **name, char **number)
Get name and number from sip header.
const ast_string_field cid_num
Definition: sip.h:1063
#define ast_free(a)
Definition: astmm.h:182
struct ast_channel * owner
Definition: sip.h:1138
static char cid_name[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:165
const ast_string_field cid_name
Definition: sip.h:1063
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
void ast_shrink_phone_number(char *n)
Shrink a phone number in place to just digits (more accurately it just removes ()&#39;s, .&#39;s, and -&#39;s...
Definition: callerid.c:947
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:343

◆ get_rdnis()

static int get_rdnis ( struct sip_pvt p,
struct sip_request oreq,
char **  name,
char **  number,
int *  reason_code,
char **  reason_str 
)
static

Get referring dnis.

Parameters
pdialog information
oreqThe request to retrieve RDNIS from
[out]nameThe name of the party redirecting the call.
[out]numberThe number of the party redirecting the call.
[out]reason_codeThe numerical code corresponding to the reason for the redirection.
[out]reason_strA string describing the reason for redirection. Will never be zero-length
Return values
-1Could not retrieve RDNIS information
0RDNIS successfully retrieved

Definition at line 18394 of file chan_sip.c.

References ast_assert, ast_copy_string(), ast_free, ast_log, ast_redirecting_reason_parse(), AST_REDIRECTING_REASON_UNKNOWN, ast_strdup, ast_strip_quoted(), ast_strlen_zero, ast_verbose(), end, exten, get_in_brackets(), sip_pvt::initreq, LOG_WARNING, NULL, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::redircause, S_OR, sip_debug_test_pvt(), sip_get_header(), sip_set_redirstr(), strcasestr(), strsep(), and tmp().

Referenced by change_redirecting_information().

18395 {
18396  char tmp[256], *exten, *rexten, *rdomain, *rname = NULL;
18397  char *params, *reason_param = NULL;
18398  struct sip_request *req;
18399 
18400  ast_assert(reason_code != NULL);
18401  ast_assert(reason_str != NULL);
18402 
18403  req = oreq ? oreq : &p->initreq;
18404 
18405  ast_copy_string(tmp, sip_get_header(req, "Diversion"), sizeof(tmp));
18406  if (ast_strlen_zero(tmp))
18407  return -1;
18408 
18409  if ((params = strchr(tmp, '>'))) {
18410  params = strchr(params, ';');
18411  }
18412 
18413  exten = get_in_brackets(tmp);
18414  if (!strncasecmp(exten, "sip:", 4)) {
18415  exten += 4;
18416  } else if (!strncasecmp(exten, "sips:", 5)) {
18417  exten += 5;
18418  } else {
18419  ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", exten);
18420  return -1;
18421  }
18422 
18423  /* Get diversion-reason param if present */
18424  if (params) {
18425  *params = '\0'; /* Cut off parameters */
18426  params++;
18427  while (*params == ';' || *params == ' ')
18428  params++;
18429  /* Check if we have a reason parameter */
18430  if ((reason_param = strcasestr(params, "reason="))) {
18431  char *end;
18432  reason_param+=7;
18433  if ((end = strchr(reason_param, ';'))) {
18434  *end = '\0';
18435  }
18436  }
18437  }
18438 
18439  rdomain = exten;
18440  rexten = strsep(&rdomain, "@"); /* trim anything after @ */
18441  if (p->owner)
18442  pbx_builtin_setvar_helper(p->owner, "__SIPRDNISDOMAIN", rdomain);
18443 
18444  if (sip_debug_test_pvt(p)) {
18445  ast_verbose("RDNIS for this call is %s (reason %s)\n", exten, S_OR(reason_param, ""));
18446  }
18447  /*ast_string_field_set(p, rdnis, rexten);*/
18448 
18449  if (*tmp == '\"') {
18450  char *end_quote;
18451  rname = tmp + 1;
18452  end_quote = strchr(rname, '\"');
18453  if (end_quote) {
18454  *end_quote = '\0';
18455  }
18456  }
18457 
18458  if (number) {
18459  *number = ast_strdup(rexten);
18460  }
18461 
18462  if (name && rname) {
18463  *name = ast_strdup(rname);
18464  }
18465 
18466  if (!ast_strlen_zero(reason_param)) {
18467  *reason_str = ast_strdup(reason_param);
18468 
18469  /* Remove any enclosing double-quotes */
18470  if (*reason_param == '"') {
18471  reason_param = ast_strip_quoted(reason_param, "\"", "\"");
18472  }
18473 
18474  *reason_code = ast_redirecting_reason_parse(reason_param);
18475  if (*reason_code < 0) {
18476  *reason_code = AST_REDIRECTING_REASON_UNKNOWN;
18477  } else {
18478  ast_free(*reason_str);
18479  *reason_str = ast_strdup("");
18480  }
18481 
18482  if (!ast_strlen_zero(reason_param)) {
18483  sip_set_redirstr(p, reason_param);
18484  if (p->owner) {
18485  pbx_builtin_setvar_helper(p->owner, "__PRIREDIRECTREASON", p->redircause);
18486  pbx_builtin_setvar_helper(p->owner, "__SIPREDIRECTREASON", reason_param);
18487  }
18488  }
18489  }
18490 
18491  return 0;
18492 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
char * get_in_brackets(char *tmp)
Pick out text in brackets from character string.
#define LOG_WARNING
Definition: logger.h:274
int ast_redirecting_reason_parse(const char *data)
Convert redirecting reason text code to value (used in config file parsing)
Definition: callerid.c:1223
static int tmp()
Definition: bt_open.c:389
#define ast_assert(a)
Definition: utils.h:695
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
char * end
Definition: eagi_proxy.c:73
#define ast_strlen_zero(foo)
Definition: strings.h:52
Number structure.
Definition: app_followme.c:154
char * ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
Strip leading/trailing whitespace and quotes from a string.
Definition: main/utils.c:1639
#define ast_log
Definition: astobj2.c:42
struct sip_request initreq
Definition: sip.h:1151
const ast_string_field redircause
Definition: sip.h:1063
char * strcasestr(const char *, const char *)
static const char name[]
Definition: cdr_mysql.c:74
#define ast_free(a)
Definition: astmm.h:182
struct ast_channel * owner
Definition: sip.h:1138
static int sip_debug_test_pvt(struct sip_pvt *p)
Test PVT for debugging output.
Definition: chan_sip.c:3649
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
char * strsep(char **str, const char *delims)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
static void sip_set_redirstr(struct sip_pvt *p, char *reason)
Translate referring cause.
Definition: chan_sip.c:18157

◆ get_realm()

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

References AST_LIST_EMPTY, ast_string_field_set, ast_strlen_zero, check_sip_domain(), sip_settings::domainsasrealm, get_domain(), MAXHOSTNAMELEN, NULL, sip_settings::realm, sip_pvt::realm, sip_cfg, and sip_get_header().

Referenced by transmit_response_with_auth().

12831 {
12832  char domain[MAXHOSTNAMELEN];
12833 
12834  if (!ast_strlen_zero(p->realm))
12835  return;
12836 
12837  if (sip_cfg.domainsasrealm &&
12839  {
12840  /* Check From header first */
12841  if (!get_domain(sip_get_header(req, "From"), domain, sizeof(domain))) {
12842  if (check_sip_domain(domain, NULL, 0)) {
12843  ast_string_field_set(p, realm, domain);
12844  return;
12845  }
12846  }
12847  /* Check To header */
12848  if (!get_domain(sip_get_header(req, "To"), domain, sizeof(domain))) {
12849  if (check_sip_domain(domain, NULL, 0)) {
12850  ast_string_field_set(p, realm, domain);
12851  return;
12852  }
12853  }
12854  }
12855 
12856  /* Use default realm from config file */
12857  ast_string_field_set(p, realm, sip_cfg.realm);
12858 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
const ast_string_field realm
Definition: sip.h:1063
int domainsasrealm
Definition: sip.h:780
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
Definition: chan_sip.c:31314
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
#define MAXHOSTNAMELEN
Definition: network.h:69
#define NULL
Definition: resample.c:96
Domain data structure.
Definition: sip.h:888
#define ast_strlen_zero(foo)
Definition: strings.h:52
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
static int get_domain(const char *str, char *domain, int len)
Extract domain from SIP To/From header.
Definition: chan_sip.c:12782
char realm[MAXHOSTNAMELEN]
Definition: sip.h:779
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ get_refer_info()

static int get_refer_info ( struct sip_pvt transferer,
struct sip_request outgoing_req 
)
static

Call transfer support (the REFER method) Extracts Refer headers into pvt dialog structure.

Note
If we get a SIPS uri in the refer-to header, we're required to set up a secure signalling path to that extension. As a minimum, this needs to be added to a channel variable, if not a channel flag.

Definition at line 18812 of file chan_sip.c.

References ast_channel_bridge_peer(), ast_channel_cleanup, ast_channel_lock, ast_channel_macrocontext(), ast_channel_ref, ast_channel_unlock, ast_debug, ast_exists_extension(), ast_log, ast_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero, ast_uri_decode(), ast_uri_sip_user, ast_verbose(), sip_refer::attendedtransfer, sip_pvt::callid, sip_pvt::context, sip_settings::default_context, extract_transferrer_headers(), get_in_brackets(), sip_pvt::initreq, LOG_WARNING, NULL, sip_pvt::owner, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), sip_settings::pedanticsipchecking, RAII_VAR, sip_pvt::refer, sip_refer::replaces_callid, sip_refer::replaces_callid_fromtag, sip_refer::replaces_callid_totag, S_OR, sip_cfg, sip_debug_test_pvt(), sip_get_header(), SIP_PEDANTIC_DECODE, sip_pvt_lock_full(), sip_pvt_unlock, strcasestr(), sip_pvt::tag, and sip_pvt::theirtag.

Referenced by handle_request_refer().

18813 {
18814  const char *p_referred_by = NULL;
18815  char *h_refer_to = NULL;
18816  char *h_referred_by = NULL;
18817  char *refer_to;
18818  const char *p_refer_to;
18819  char *referred_by_uri = NULL;
18820  char *ptr;
18821  struct sip_request *req = NULL;
18822  const char *transfer_context = NULL;
18823  struct sip_refer *refer;
18824 
18825  req = outgoing_req;
18826  refer = transferer->refer;
18827 
18828  if (!req) {
18829  req = &transferer->initreq;
18830  }
18831 
18832  p_refer_to = sip_get_header(req, "Refer-To");
18833  if (ast_strlen_zero(p_refer_to)) {
18834  ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n");
18835  return -2; /* Syntax error */
18836  }
18837  h_refer_to = ast_strdupa(p_refer_to);
18838  refer_to = get_in_brackets(h_refer_to);
18839  if (!strncasecmp(refer_to, "sip:", 4)) {
18840  refer_to += 4; /* Skip sip: */
18841  } else if (!strncasecmp(refer_to, "sips:", 5)) {
18842  refer_to += 5;
18843  } else {
18844  ast_log(LOG_WARNING, "Can't transfer to non-sip: URI. (Refer-to: %s)?\n", refer_to);
18845  return -3;
18846  }
18847 
18848  /* Get referred by header if it exists */
18849  p_referred_by = sip_get_header(req, "Referred-By");
18850 
18851  /* Give useful transfer information to the dialplan */
18852  if (transferer->owner) {
18853  RAII_VAR(struct ast_channel *, peer, NULL, ast_channel_cleanup);
18854  RAII_VAR(struct ast_channel *, owner_relock, NULL, ast_channel_cleanup);
18855  RAII_VAR(struct ast_channel *, owner_ref, NULL, ast_channel_cleanup);
18856 
18857  /* Grab a reference to transferer->owner to prevent it from going away */
18858  owner_ref = ast_channel_ref(transferer->owner);
18859 
18860  /* Established locking order here is bridge, channel, pvt
18861  * and the bridge will be locked during ast_channel_bridge_peer */
18862  ast_channel_unlock(owner_ref);
18863  sip_pvt_unlock(transferer);
18864 
18865  peer = ast_channel_bridge_peer(owner_ref);
18866  if (peer) {
18867  const char *get_xfrdata;
18868 
18869  pbx_builtin_setvar_helper(peer, "SIPREFERRINGCONTEXT",
18870  S_OR(transferer->context, NULL));
18871  pbx_builtin_setvar_helper(peer, "__SIPREFERREDBYHDR",
18872  S_OR(p_referred_by, NULL));
18873 
18874  ast_channel_lock(peer);
18875  get_xfrdata = pbx_builtin_getvar_helper(peer, "GET_TRANSFERRER_DATA");
18876  if (!ast_strlen_zero(get_xfrdata)) {
18877  extract_transferrer_headers(get_xfrdata, peer, req);
18878  }
18879  ast_channel_unlock(peer);
18880  }
18881 
18882  owner_relock = sip_pvt_lock_full(transferer);
18883  if (!owner_relock) {
18884  ast_debug(3, "Unable to reacquire owner channel lock, channel is gone\n");
18885  return -5;
18886  }
18887  }
18888 
18889  if (!ast_strlen_zero(p_referred_by)) {
18890  h_referred_by = ast_strdupa(p_referred_by);
18891 
18892  referred_by_uri = get_in_brackets(h_referred_by);
18893 
18894  if (!strncasecmp(referred_by_uri, "sip:", 4)) {
18895  referred_by_uri += 4; /* Skip sip: */
18896  } else if (!strncasecmp(referred_by_uri, "sips:", 5)) {
18897  referred_by_uri += 5; /* Skip sips: */
18898  } else {
18899  ast_log(LOG_WARNING, "Huh? Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri);
18900  referred_by_uri = NULL;
18901  }
18902  }
18903 
18904  /* Check for arguments in the refer_to header */
18905  if ((ptr = strcasestr(refer_to, "replaces="))) {
18906  char *to = NULL, *from = NULL, *callid;
18907 
18908  /* This is an attended transfer */
18909  refer->attendedtransfer = 1;
18910 
18911  callid = ast_strdupa(ptr + 9);
18913  if ((ptr = strchr(callid, ';'))) { /* Find options */
18914  *ptr++ = '\0';
18915  }
18916  ast_string_field_set(refer, replaces_callid, callid);
18917 
18918  if (ptr) {
18919  /* Find the different tags before we destroy the string */
18920  to = strcasestr(ptr, "to-tag=");
18921  from = strcasestr(ptr, "from-tag=");
18922  }
18923 
18924  /* Grab the to header */
18925  if (to) {
18926  ptr = to + 7;
18927  if ((to = strchr(ptr, '&'))) {
18928  *to = '\0';
18929  }
18930  if ((to = strchr(ptr, ';'))) {
18931  *to = '\0';
18932  }
18934  }
18935 
18936  if (from) {
18937  ptr = from + 9;
18938  if ((from = strchr(ptr, '&'))) {
18939  *from = '\0';
18940  }
18941  if ((from = strchr(ptr, ';'))) {
18942  *from = '\0';
18943  }
18945  }
18946 
18947  if (!strcmp(refer->replaces_callid, transferer->callid) &&
18949  (!strcmp(refer->replaces_callid_fromtag, transferer->theirtag) &&
18950  !strcmp(refer->replaces_callid_totag, transferer->tag)))) {
18951  ast_log(LOG_WARNING, "Got an attempt to replace own Call-ID on %s\n", transferer->callid);
18952  return -4;
18953  }
18954 
18956  ast_debug(2, "Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", refer->replaces_callid);
18957  } else {
18958  ast_debug(2, "Attended transfer: Will use Replace-Call-ID : %s F-tag: %s T-tag: %s\n", refer->replaces_callid, refer->replaces_callid_fromtag ? refer->replaces_callid_fromtag : "<none>", refer->replaces_callid_totag ? refer->replaces_callid_totag : "<none>");
18959  }
18960  }
18961 
18962  if ((ptr = strchr(refer_to, '@'))) { /* Separate domain */
18963  char *urioption = NULL, *domain;
18964  int bracket = 0;
18965  *ptr++ = '\0';
18966 
18967  if ((urioption = strchr(ptr, ';'))) { /* Separate urioptions */
18968  *urioption++ = '\0';
18969  }
18970 
18971  domain = ptr;
18972 
18973  /* Remove :port */
18974  for (; *ptr != '\0'; ++ptr) {
18975  if (*ptr == ':' && bracket == 0) {
18976  *ptr = '\0';
18977  break;
18978  } else if (*ptr == '[') {
18979  ++bracket;
18980  } else if (*ptr == ']') {
18981  --bracket;
18982  }
18983  }
18984 
18985  SIP_PEDANTIC_DECODE(domain);
18986  SIP_PEDANTIC_DECODE(urioption);
18987 
18988  /* Save the domain for the dial plan */
18989  ast_string_field_set(refer, refer_to_domain, domain);
18990  if (urioption) {
18991  ast_string_field_set(refer, refer_to_urioption, urioption);
18992  }
18993  }
18994 
18995  if ((ptr = strchr(refer_to, ';'))) /* Remove options */
18996  *ptr = '\0';
18997 
18998  SIP_PEDANTIC_DECODE(refer_to);
18999  ast_string_field_set(refer, refer_to, refer_to);
19000 
19001  if (referred_by_uri) {
19002  if ((ptr = strchr(referred_by_uri, ';'))) /* Remove options */
19003  *ptr = '\0';
19004  SIP_PEDANTIC_DECODE(referred_by_uri);
19005  ast_string_field_build(refer, referred_by, "<sip:%s>", referred_by_uri);
19006  } else {
19007  ast_string_field_set(refer, referred_by, "");
19008  }
19009 
19010  /* Determine transfer context */
19011  if (transferer->owner) {
19012  /* By default, use the context in the channel sending the REFER */
19013  transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT");
19014  if (ast_strlen_zero(transfer_context)) {
19015  transfer_context = ast_channel_macrocontext(transferer->owner);
19016  }
19017  }
19018  if (ast_strlen_zero(transfer_context)) {
19019  transfer_context = S_OR(transferer->context, sip_cfg.default_context);
19020  }
19021 
19022  ast_string_field_set(refer, refer_to_context, transfer_context);
19023 
19024  /* Either an existing extension or the parking extension */
19025  if (refer->attendedtransfer || ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL)) {
19026  if (sip_debug_test_pvt(transferer)) {
19027  ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, S_OR(referred_by_uri, "Unknown"));
19028  }
19029  /* We are ready to transfer to the extension */
19030  return 0;
19031  }
19032  if (sip_debug_test_pvt(transferer))
19033  ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context);
19034 
19035  /* Failure, we can't find this extension */
19036  return -1;
19037 }
void ast_uri_decode(char *s, struct ast_flags spec)
Decode URI, URN, URL (overwrite string)
Definition: main/utils.c:616
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
char * get_in_brackets(char *tmp)
Pick out text in brackets from character string.
#define LOG_WARNING
Definition: logger.h:274
const ast_string_field replaces_callid_fromtag
Definition: sip.h:944
const ast_string_field context
Definition: sip.h:1063
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
#define NULL
Definition: resample.c:96
Domain data structure.
Definition: sip.h:888
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
#define ast_strlen_zero(foo)
Definition: strings.h:52
static void extract_transferrer_headers(const char *prefix, struct ast_channel *peer, const struct sip_request *req)
Definition: chan_sip.c:18782
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
const ast_string_field refer_to_context
Definition: sip.h:944
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
struct sip_request initreq
Definition: sip.h:1151
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2992
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
const ast_string_field theirtag
Definition: sip.h:1063
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:4179
const ast_string_field replaces_callid_totag
Definition: sip.h:944
int pedanticsipchecking
Definition: sip.h:756
const ast_string_field replaces_callid
Definition: sip.h:944
#define SIP_PEDANTIC_DECODE(str)
Definition: chan_sip.c:813
const ast_string_field callid
Definition: sip.h:1063
const ast_string_field referred_by
Definition: sip.h:944
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
char * strcasestr(const char *, const char *)
static struct ast_channel * sip_pvt_lock_full(struct sip_pvt *pvt)
Definition: chan_sip.c:9400
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_channel * owner
Definition: sip.h:1138
int attendedtransfer
Definition: sip.h:945
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
Definition: stringfields.h:550
static int sip_debug_test_pvt(struct sip_pvt *p)
Test PVT for debugging output.
Definition: chan_sip.c:3649
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
struct sip_refer * refer
Definition: sip.h:1160
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2970
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
struct ast_channel * ast_channel_bridge_peer(struct ast_channel *chan)
Get the channel&#39;s bridge peer only if the bridge is two-party.
Definition: channel.c:10765
const ast_string_field tag
Definition: sip.h:1063
const struct ast_flags ast_uri_sip_user
Definition: main/utils.c:575
const char * ast_channel_macrocontext(const struct ast_channel *chan)
char default_context[AST_MAX_CONTEXT]
Definition: sip.h:782
const ast_string_field refer_to_domain
Definition: sip.h:944
const ast_string_field refer_to_urioption
Definition: sip.h:944
Structure to handle SIP transfers. Dynamically allocated when needed.
Definition: sip.h:933
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ get_rpid()

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

References ast_channel_caller(), 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, sip_pvt::callingpres, cid_name, sip_pvt::cid_name, cid_num, sip_pvt::cid_num, end, sip_pvt::flags, get_pai(), global_shrinkcallerid, ast_party_caller::id, sip_pvt::initreq, ast_party_id::name, NULL, ast_party_id::number, sip_pvt::owner, ast_party_name::presentation, ast_party_number::presentation, sip_get_header(), SIP_TRUSTRPID, and tmp().

Referenced by check_peer_ok(), check_user_full(), handle_request_invite(), handle_request_update(), and handle_response_invite().

18267 {
18268  char tmp[256];
18269  struct sip_request *req;
18270  char *cid_num = "";
18271  char *cid_name = "";
18273  char *privacy = "";
18274  char *screen = "";
18275  char *start, *end;
18276 
18277  if (!ast_test_flag(&p->flags[0], SIP_TRUSTRPID))
18278  return 0;
18279  req = oreq;
18280  if (!req)
18281  req = &p->initreq;
18282  ast_copy_string(tmp, sip_get_header(req, "Remote-Party-ID"), sizeof(tmp));
18283  if (ast_strlen_zero(tmp)) {
18284  return get_pai(p, req);
18285  }
18286 
18287  /*
18288  * RPID is not:
18289  * rpid = (name-addr / addr-spec) *(SEMI rpi-token)
18290  * But it is:
18291  * rpid = [display-name] LAQUOT addr-spec RAQUOT *(SEMI rpi-token)
18292  * Ergo, calling parse_name_andor_addr() on it wouldn't be
18293  * correct because that would allow addr-spec style too.
18294  */
18295  start = tmp;
18296  /* Quoted (note that we're not dealing with escapes properly) */
18297  if (*start == '"') {
18298  *start++ = '\0';
18299  end = strchr(start, '"');
18300  if (!end)
18301  return 0;
18302  *end++ = '\0';
18303  cid_name = start;
18304  start = ast_skip_blanks(end);
18305  /* Unquoted */
18306  } else {
18307  cid_name = start;
18308  start = end = strchr(start, '<');
18309  if (!start) {
18310  return 0;
18311  }
18312  /* trim blanks if there are any. the mandatory NUL is done below */
18313  while (--end >= cid_name && *end < 33) {
18314  *end = '\0';
18315  }
18316  }
18317 
18318  if (*start != '<')
18319  return 0;
18320  *start++ = '\0';
18321  end = strchr(start, '@');
18322  if (!end)
18323  return 0;
18324  *end++ = '\0';
18325  if (strncasecmp(start, "sip:", 4))
18326  return 0;
18327  cid_num = start + 4;
18329  ast_shrink_phone_number(cid_num);
18330  start = end;
18331 
18332  end = strchr(start, '>');
18333  if (!end)
18334  return 0;
18335  *end++ = '\0';
18336  if (*end) {
18337  start = end;
18338  if (*start != ';')
18339  return 0;
18340  *start++ = '\0';
18341  while (!ast_strlen_zero(start)) {
18342  end = strchr(start, ';');
18343  if (end)
18344  *end++ = '\0';
18345  if (!strncasecmp(start, "privacy=", 8))
18346  privacy = start + 8;
18347  else if (!strncasecmp(start, "screen=", 7))
18348  screen = start + 7;
18349  start = end;
18350  }
18351 
18352  if (!strcasecmp(privacy, "full")) {
18353  if (!strcasecmp(screen, "yes"))
18355  else if (!strcasecmp(screen, "no"))
18357  } else {
18358  if (!strcasecmp(screen, "yes"))
18360  else if (!strcasecmp(screen, "no"))
18362  }
18363  }
18364 
18365  /* Only return true if the supplied caller id is different */
18366  if (!strcasecmp(p->cid_num, cid_num) && !strcasecmp(p->cid_name, cid_name) && p->callingpres == callingpres)
18367  return 0;
18368 
18369  ast_string_field_set(p, cid_num, cid_num);
18370  ast_string_field_set(p, cid_name, cid_name);
18371  p->callingpres = callingpres;
18372 
18373  if (p->owner) {
18374  ast_set_callerid(p->owner, cid_num, cid_name, NULL);
18375  ast_channel_caller(p->owner)->id.name.presentation = callingpres;
18376  ast_channel_caller(p->owner)->id.number.presentation = callingpres;
18377  }
18378 
18379  return 1;
18380 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
static int global_shrinkcallerid
Definition: chan_sip.c:829
int presentation
Q.931 encoded presentation-indicator encoded field.
Definition: channel.h:278
void ast_set_callerid(struct ast_channel *chan, const char *cid_num, const char *cid_name, const char *cid_ani)
Set caller ID number, name and ANI and generate AMI event.
Definition: channel.c:7434
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
Definition: channel.h:296
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_party_name name
Subscriber name.
Definition: channel.h:341
static int tmp()
Definition: bt_open.c:389
#define AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED
Definition: callerid.h:341
#define SIP_TRUSTRPID
Definition: sip.h:270
struct ast_flags flags[3]
Definition: sip.h:1075
#define NULL
Definition: resample.c:96
char * end
Definition: eagi_proxy.c:73
int ast_is_shrinkable_phonenumber(const char *exten)
Check if a string consists only of digits and + # ( ) - . (meaning it can be cleaned with ast_shrink_...
Definition: callerid.c:1003
#define AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED
Definition: callerid.h:329
static char cid_num[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:164
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN
Definition: callerid.h:344
struct ast_party_id id
Caller party ID.
Definition: channel.h:421
struct sip_request initreq
Definition: sip.h:1151
int callingpres
Definition: sip.h:1117
const ast_string_field cid_num
Definition: sip.h:1063
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 ...
Definition: chan_sip.c:18190
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
struct ast_channel * owner
Definition: sip.h:1138
static char cid_name[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:165
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
#define AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN
Definition: callerid.h:332
const ast_string_field cid_name
Definition: sip.h:1063
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
void ast_shrink_phone_number(char *n)
Shrink a phone number in place to just digits (more accurately it just removes ()&#39;s, .&#39;s, and -&#39;s...
Definition: callerid.c:947
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:343

◆ get_sdp_iterate()

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

References ast_skip_blanks(), len(), REQ_OFFSET_TO_STR, sip_request::sdp_count, and sip_request::sdp_start.

Referenced by has_media_level_attribute(), and process_sdp().

8445 {
8446  int len = strlen(name);
8447  const char *line;
8448 
8449  while (*start < (req->sdp_start + req->sdp_count)) {
8450  line = REQ_OFFSET_TO_STR(req, line[(*start)++]);
8451  if (!strncasecmp(line, name, len) && line[len] == '=') {
8452  return ast_skip_blanks(line + len + 1);
8453  }
8454  }
8455 
8456  /* if the line was not found, ensure that *start points past the SDP */
8457  (*start)++;
8458 
8459  return "";
8460 }
unsigned int sdp_start
Definition: sip.h:835
ptrdiff_t line[SIP_MAX_LINES]
Definition: sip.h:842
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
static const char name[]
Definition: cdr_mysql.c:74
#define REQ_OFFSET_TO_STR(req, offset)
Definition: sip.h:858
unsigned int sdp_count
Definition: sip.h:836

◆ get_sdp_line()

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

References ast_skip_blanks(), NULL, REQ_OFFSET_TO_STR, sip_request::sdp_count, sip_request::sdp_start, and type.

Referenced by has_media_level_attribute(), and process_sdp().

8468 {
8469  char type = '\0';
8470  const char *line = NULL;
8471 
8472  if (stop > (req->sdp_start + req->sdp_count)) {
8473  stop = req->sdp_start + req->sdp_count;
8474  }
8475 
8476  while (*start < stop) {
8477  line = REQ_OFFSET_TO_STR(req, line[(*start)++]);
8478  if (line[1] == '=') {
8479  type = line[0];
8480  *value = ast_skip_blanks(line + 2);
8481  break;
8482  }
8483  }
8484 
8485  return type;
8486 }
static const char type[]
Definition: chan_ooh323.c:109
unsigned int sdp_start
Definition: sip.h:835
unsigned int stop
Definition: app_meetme.c:1096
#define NULL
Definition: resample.c:96
int value
Definition: syslog.c:37
ptrdiff_t line[SIP_MAX_LINES]
Definition: sip.h:842
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
#define REQ_OFFSET_TO_STR(req, offset)
Definition: sip.h:858
unsigned int sdp_count
Definition: sip.h:836

◆ get_sip_pvt_from_replaces()

static int get_sip_pvt_from_replaces ( const char *  callid,
const char *  totag,
const char *  fromtag,
struct sip_pvt **  out_pvt,
struct ast_channel **  out_chan 
)
static

Find a companion dialog based on Replaces information.

This information may come from a Refer-To header in a REFER or from a Replaces header in an INVITE.

This function will find the appropriate sip_pvt and increment the refcount of both the sip_pvt and its owner channel. These two references are returned in the out parameters

Parameters
callidCallid to search for
totagto-tag parameter from Replaces
fromtagfrom-tag parameter from Replaces
[out]out_pvtThe found sip_pvt.
[out]out_chanThe found sip_pvt's owner channel.
Return values
0Success
non-zeroFailure

Definition at line 18693 of file chan_sip.c.

References ao2_cleanup, ao2_t_find, ast_channel_ref, ast_debug, ast_strlen_zero, ast_test_flag, sip_pvt::callid, lock, NULL, OBJ_POINTER, sip_settings::pedanticsipchecking, RAII_VAR, SCOPED_LOCK, sip_cfg, SIP_PAGE2_DIALOG_ESTABLISHED, sip_pvt_lock, sip_pvt_unlock, and TRUE.

Referenced by handle_request_invite(), and local_attended_transfer().

18695 {
18696  RAII_VAR(struct sip_pvt *, sip_pvt_ptr, NULL, ao2_cleanup);
18697  struct sip_pvt tmp_dialog = {
18698  .callid = callid,
18699  };
18700 
18701  if (totag) {
18702  ast_debug(4, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>");
18703  }
18704 
18705  /* Search dialogs and find the match */
18706 
18707  sip_pvt_ptr = ao2_t_find(dialogs, &tmp_dialog, OBJ_POINTER, "ao2_find of dialog in dialogs table");
18708  if (sip_pvt_ptr) {
18709  /* Go ahead and lock it (and its owner) before returning */
18710  SCOPED_LOCK(lock, sip_pvt_ptr, sip_pvt_lock, sip_pvt_unlock);
18712  unsigned char frommismatch = 0, tomismatch = 0;
18713 
18714  if (ast_strlen_zero(fromtag)) {
18715  ast_debug(4, "Matched %s call for callid=%s - no from tag specified, pedantic check fails\n",
18716  sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid);
18717  return -1;
18718  }
18719 
18720  if (ast_strlen_zero(totag)) {
18721  ast_debug(4, "Matched %s call for callid=%s - no to tag specified, pedantic check fails\n",
18722  sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid);
18723  return -1;
18724  }
18725  /* RFC 3891
18726  * > 3. User Agent Server Behavior: Receiving a Replaces Header
18727  * > The Replaces header contains information used to match an existing
18728  * > SIP dialog (call-id, to-tag, and from-tag). Upon receiving an INVITE
18729  * > with a Replaces header, the User Agent (UA) attempts to match this
18730  * > information with a confirmed or early dialog. The User Agent Server
18731  * > (UAS) matches the to-tag and from-tag parameters as if they were tags
18732  * > present in an incoming request. In other words, the to-tag parameter
18733  * > is compared to the local tag, and the from-tag parameter is compared
18734  * > to the remote tag.
18735  *
18736  * Thus, the totag is always compared to the local tag, regardless if
18737  * this our call is an incoming or outgoing call.
18738  */
18739  frommismatch = !!strcmp(fromtag, sip_pvt_ptr->theirtag);
18740  tomismatch = !!strcmp(totag, sip_pvt_ptr->tag);
18741 
18742  /* Don't check from if the dialog is not established, due to multi forking the from
18743  * can change when the call is not answered yet.
18744  */
18745  if ((frommismatch && ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) || tomismatch) {
18746  if (frommismatch) {
18747  ast_debug(4, "Matched %s call for callid=%s - pedantic from tag check fails; their tag is %s our tag is %s\n",
18748  sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid,
18749  fromtag, sip_pvt_ptr->theirtag);
18750  }
18751  if (tomismatch) {
18752  ast_debug(4, "Matched %s call for callid=%s - pedantic to tag check fails; their tag is %s our tag is %s\n",
18753  sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid,
18754  totag, sip_pvt_ptr->tag);
18755  }
18756  return -1;
18757  }
18758  }
18759 
18760  if (totag)
18761  ast_debug(4, "Matched %s call - their tag is %s Our tag is %s\n",
18762  sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING",
18763  sip_pvt_ptr->theirtag, sip_pvt_ptr->tag);
18764 
18765  *out_pvt = sip_pvt_ptr;
18766  if (out_chan) {
18767  *out_chan = sip_pvt_ptr->owner ? ast_channel_ref(sip_pvt_ptr->owner) : NULL;
18768  }
18769  }
18770 
18771  if (!sip_pvt_ptr) {
18772  /* return error if sip_pvt was not found */
18773  return -1;
18774  }
18775 
18776  /* If we're here sip_pvt_ptr has been copied to *out_pvt, prevent RAII_VAR cleanup */
18777  sip_pvt_ptr = NULL;
18778 
18779  return 0;
18780 }
static struct ao2_container * dialogs
Definition: chan_sip.c:1043
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define OBJ_POINTER
Definition: astobj2.h:1154
#define NULL
Definition: resample.c:96
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
ast_mutex_t lock
Definition: app_meetme.c:1091
#define SCOPED_LOCK(varname, lock, lockfunc, unlockfunc)
Scoped Locks.
Definition: lock.h:581
int pedanticsipchecking
Definition: sip.h:756
const ast_string_field callid
Definition: sip.h:1063
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2970
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define TRUE
Definition: app_minivm.c:518
#define ao2_t_find(container, arg, flags, tag)
Definition: astobj2.h:1754
#define SIP_PAGE2_DIALOG_ESTABLISHED
Definition: sip.h:358

◆ get_srv_protocol()

static const char* get_srv_protocol ( enum ast_transport  t)
inlinestatic

Return protocol string for srv dns query.

Definition at line 3743 of file chan_sip.c.

References AST_TRANSPORT_TCP, AST_TRANSPORT_TLS, AST_TRANSPORT_UDP, AST_TRANSPORT_WS, and AST_TRANSPORT_WSS.

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

3744 {
3745  switch (t) {
3746  case AST_TRANSPORT_UDP:
3747  return "udp";
3748  case AST_TRANSPORT_WS:
3749  return "ws";
3750  case AST_TRANSPORT_TLS:
3751  case AST_TRANSPORT_TCP:
3752  return "tcp";
3753  case AST_TRANSPORT_WSS:
3754  return "wss";
3755  }
3756 
3757  return "udp";
3758 }

◆ get_srv_service()

static const char* get_srv_service ( enum ast_transport  t)
inlinestatic

Return service string for srv dns query.

Definition at line 3761 of file chan_sip.c.

References AST_TRANSPORT_TCP, AST_TRANSPORT_TLS, AST_TRANSPORT_UDP, AST_TRANSPORT_WS, and AST_TRANSPORT_WSS.

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

3762 {
3763  switch (t) {
3764  case AST_TRANSPORT_TCP:
3765  case AST_TRANSPORT_UDP:
3766  case AST_TRANSPORT_WS:
3767  return "sip";
3768  case AST_TRANSPORT_TLS:
3769  case AST_TRANSPORT_WSS:
3770  return "sips";
3771  }
3772  return "sip";
3773 }

◆ get_transport_list()

static const char* get_transport_list ( unsigned int  transports)
inlinestatic

Return configuration of transports for a device.

Definition at line 3686 of file chan_sip.c.

References ast_threadstorage_get(), AST_TRANSPORT_TCP, AST_TRANSPORT_TLS, AST_TRANSPORT_UDP, AST_TRANSPORT_WS, AST_TRANSPORT_WSS, buf, sip_transport_str_buf, and SIP_TRANSPORT_STR_BUFSIZE.

Referenced by _sip_show_peer(), and sip_show_settings().

3687 {
3688  char *buf;
3689 
3690  if (!transports) {
3691  return "UNKNOWN";
3692  }
3693 
3695  return "";
3696  }
3697 
3698  memset(buf, 0, SIP_TRANSPORT_STR_BUFSIZE);
3699 
3700  if (transports & AST_TRANSPORT_UDP) {
3701  strncat(buf, "UDP,", SIP_TRANSPORT_STR_BUFSIZE - strlen(buf));
3702  }
3703  if (transports & AST_TRANSPORT_TCP) {
3704  strncat(buf, "TCP,", SIP_TRANSPORT_STR_BUFSIZE - strlen(buf));
3705  }
3706  if (transports & AST_TRANSPORT_TLS) {
3707  strncat(buf, "TLS,", SIP_TRANSPORT_STR_BUFSIZE - strlen(buf));
3708  }
3709  if (transports & AST_TRANSPORT_WS) {
3710  strncat(buf, "WS,", SIP_TRANSPORT_STR_BUFSIZE - strlen(buf));
3711  }
3712  if (transports & AST_TRANSPORT_WSS) {
3713  strncat(buf, "WSS,", SIP_TRANSPORT_STR_BUFSIZE - strlen(buf));
3714  }
3715 
3716  /* Remove the trailing ',' if present */
3717  if (strlen(buf)) {
3718  buf[strlen(buf) - 1] = 0;
3719  }
3720 
3721  return buf;
3722 }
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static struct ast_threadstorage sip_transport_str_buf
Definition: chan_sip.c:1073
#define SIP_TRANSPORT_STR_BUFSIZE
Size of the SIP transport buffer.
Definition: chan_sip.c:1076

◆ get_transport_pvt()

static const char* get_transport_pvt ( struct sip_pvt p)
inlinestatic

Return transport of dialog.

Note
this is based on a false assumption. We don't always use the outbound proxy for all requests in a dialog. It depends on the "force" parameter. The FIRST request is always sent to the ob proxy.
Todo:
Fix this function to work correctly

Definition at line 3781 of file chan_sip.c.

References sip_pvt::outboundproxy, set_socket_transport(), sip_get_transport(), sip_pvt::socket, sip_proxy::transport, and sip_socket::type.

Referenced by __sip_xmit(), and build_via().

3782 {
3783  if (p->outboundproxy && p->outboundproxy->transport) {
3785  }
3786 
3787  return sip_get_transport(p->socket.type);
3788 }
struct sip_socket socket
Definition: sip.h:1066
const char * sip_get_transport(enum ast_transport t)
Return transport as string.
Definition: chan_sip.c:3725
enum ast_transport type
Definition: sip.h:798
enum ast_transport transport
Definition: sip.h:726
static void set_socket_transport(struct sip_socket *socket, int transport)
Definition: chan_sip.c:16629
struct sip_proxy * outboundproxy
Definition: sip.h:1112

◆ get_transport_str2enum()

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

References ast_strlen_zero, AST_TRANSPORT_TCP, AST_TRANSPORT_TLS, AST_TRANSPORT_UDP, AST_TRANSPORT_WS, and AST_TRANSPORT_WSS.

Referenced by __set_address_from_contact(), and parse_register_contact().

3659 {
3660  int res = 0;
3661 
3662  if (ast_strlen_zero(transport)) {
3663  return res;
3664  }
3665 
3666  if (!strcasecmp(transport, "udp")) {
3667  res |= AST_TRANSPORT_UDP;
3668  }
3669  if (!strcasecmp(transport, "tcp")) {
3670  res |= AST_TRANSPORT_TCP;
3671  }
3672  if (!strcasecmp(transport, "tls")) {
3673  res |= AST_TRANSPORT_TLS;
3674  }
3675  if (!strcasecmp(transport, "ws")) {
3676  res |= AST_TRANSPORT_WS;
3677  }
3678  if (!strcasecmp(transport, "wss")) {
3679  res |= AST_TRANSPORT_WSS;
3680  }
3681 
3682  return res;
3683 }
#define ast_strlen_zero(foo)
Definition: strings.h:52

◆ gettag()

static const char * gettag ( const struct sip_request req,
const char *  header,
char *  tagbuf,
int  tagbufsize 
)
static

Get tag from packet.

Returns
Returns the pointer to the provided tag buffer, or NULL if the tag was not found.

Definition at line 25654 of file chan_sip.c.

References ast_copy_string(), NULL, sip_get_header(), strcasestr(), and strsep().

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

25655 {
25656  const char *thetag;
25657 
25658  if (!tagbuf)
25659  return NULL;
25660  tagbuf[0] = '\0'; /* reset the buffer */
25661  thetag = sip_get_header(req, header);
25662  thetag = strcasestr(thetag, ";tag=");
25663  if (thetag) {
25664  thetag += 5;
25665  ast_copy_string(tagbuf, thetag, tagbufsize);
25666  return strsep(&tagbuf, ";");
25667  }
25668  return NULL;
25669 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
#define NULL
Definition: resample.c:96
char * strcasestr(const char *, const char *)
char * strsep(char **str, const char *delims)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401

◆ handle_cc_notify()

static int handle_cc_notify ( struct sip_pvt pvt,
struct sip_request req 
)
static

Definition at line 25671 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, sip_epa_entry::body, CC_CLOSED, construct_pidf_body(), sip_monitor_instance::core_id, cc_epa_entry::current_state, sip_monitor_instance::device_name, find_sip_monitor_instance_by_subscription_pvt(), get_content_line(), get_in_brackets(), sip_epa_entry::instance_data, notify_uri(), sip_monitor_instance::notify_uri, sip_monitor_instance::peername, sip_get_header(), SIP_PUBLISH_INITIAL, status, sip_monitor_instance::suspension_entry, transmit_publish(), and transmit_response().

Referenced by handle_request_notify().

25672 {
25673  struct sip_monitor_instance *monitor_instance = ao2_callback(sip_monitor_instances, 0,
25675  const char *status = get_content_line(req, "cc-state", ':');
25676  struct cc_epa_entry *cc_entry;
25677  char *uri;
25678 
25679  if (!monitor_instance) {
25680  transmit_response(pvt, "400 Bad Request", req);
25681  return -1;
25682  }
25683 
25684  if (ast_strlen_zero(status)) {
25685  ao2_ref(monitor_instance, -1);
25686  transmit_response(pvt, "400 Bad Request", req);
25687  return -1;
25688  }
25689 
25690  if (!strcmp(status, "queued")) {
25691  /* We've been told that we're queued. This is the endpoint's way of telling
25692  * us that it has accepted our CC request. We need to alert the core of this
25693  * development
25694  */
25695  ast_cc_monitor_request_acked(monitor_instance->core_id, "SIP endpoint %s accepted request", monitor_instance->device_name);
25696  transmit_response(pvt, "200 OK", req);
25697  ao2_ref(monitor_instance, -1);
25698  return 0;
25699  }
25700 
25701  /* It's open! Yay! */
25702  uri = get_content_line(req, "cc-URI", ':');
25703  if (ast_strlen_zero(uri)) {
25704  uri = get_in_brackets((char *)sip_get_header(req, "From"));
25705  }
25706 
25707  ast_string_field_set(monitor_instance, notify_uri, uri);
25708  if (monitor_instance->suspension_entry) {
25709  cc_entry = monitor_instance->suspension_entry->instance_data;
25710  if (cc_entry->current_state == CC_CLOSED) {
25711  /* If we've created a suspension entry and the current state is closed, then that means
25712  * we got a notice from the CC core earlier to suspend monitoring, but because this particular
25713  * call leg had not yet notified us that it was ready for recall, it meant that we
25714  * could not yet send a PUBLISH. Now, however, we can.
25715  */
25716  construct_pidf_body(CC_CLOSED, monitor_instance->suspension_entry->body,
25717  sizeof(monitor_instance->suspension_entry->body), monitor_instance->peername);
25718  transmit_publish(monitor_instance->suspension_entry, SIP_PUBLISH_INITIAL, monitor_instance->notify_uri);
25719  } else {
25720  ast_cc_monitor_callee_available(monitor_instance->core_id, "SIP monitored callee has become available");
25721  }
25722  } else {
25723  ast_cc_monitor_callee_available(monitor_instance->core_id, "SIP monitored callee has become available");
25724  }
25725  ao2_ref(monitor_instance, -1);
25726  transmit_response(pvt, "200 OK", req);
25727 
25728  return 0;
25729 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
static int construct_pidf_body(enum sip_cc_publish_state state, char *pidf_body, size_t size, const char *presentity)
Definition: chan_sip.c:2134
char * get_in_brackets(char *tmp)
Pick out text in brackets from character string.
static int transmit_publish(struct sip_epa_entry *epa_entry, enum sip_publish_type publish_type, const char *const explicit_uri)
Definition: chan_sip.c:14711
static char * get_content_line(struct sip_request *req, char *name, char delimiter)
Get a specific line from the message content.
Definition: chan_sip.c:8489
const ast_string_field peername
Definition: sip.h:1819
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
int ast_cc_monitor_request_acked(int core_id, const char *const debug,...)
Indicate that an outbound entity has accepted our CC request.
Definition: ccss.c:3787
struct ao2_container * sip_monitor_instances
Definition: chan_sip.c:1164
const ast_string_field notify_uri
Definition: sip.h:1819
static int notify_uri(void *obj)
#define ast_strlen_zero(foo)
Definition: strings.h:52
enum sip_cc_publish_state current_state
Definition: sip.h:1704
void * instance_data
Definition: sip.h:1680
static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req)
Transmit response, no retransmits.
Definition: chan_sip.c:12655
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct sip_epa_entry * suspension_entry
Definition: sip.h:1822
Instance data for a Call completion EPA entry.
Definition: sip.h:1686
char body[SIPBUFSIZE]
Definition: sip.h:1668
Initial.
Definition: sip.h:1581
const ast_string_field device_name
Definition: sip.h:1819
static int find_sip_monitor_instance_by_subscription_pvt(void *obj, void *arg, int flags)
Definition: chan_sip.c:2075
int ast_cc_monitor_callee_available(const int core_id, const char *const debug,...)
Alert the core that a device being monitored has become available.
Definition: ccss.c:3798
jack_status_t status
Definition: app_jack.c:146
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ handle_cc_subscribe()

static int handle_cc_subscribe ( struct sip_pvt p,
struct sip_request req 
)
static

Definition at line 28516 of file chan_sip.c.

References ao2_ref, ast_cc_agent_accept_request(), ast_cc_failed(), ast_log, ast_strlen_zero, CALL_COMPLETION, ast_cc_agent::core_id, ast_cc_agent::device_name, dialog_ref, find_sip_cc_agent_by_subscribe_uri(), LOG_WARNING, ast_cc_agent::private_data, REQ_OFFSET_TO_STR, sip_get_header(), sip_cc_agent_pvt::subscribe_pvt, sip_pvt::subscribed, and transmit_response().

Referenced by handle_request_subscribe().

28517 {
28518  const char *uri = REQ_OFFSET_TO_STR(req, rlpart2);
28519  char *param_separator;
28520  struct ast_cc_agent *agent;
28521  struct sip_cc_agent_pvt *agent_pvt;
28522  const char *expires_str = sip_get_header(req, "Expires");
28523  int expires = -1; /* Just need it to be non-zero */
28524 
28525  if (!ast_strlen_zero(expires_str)) {
28526  sscanf(expires_str, "%30d", &expires);
28527  }
28528 
28529  if ((param_separator = strchr(uri, ';'))) {
28530  *param_separator = '\0';
28531  }
28532 
28534 
28535  if (!(agent = find_sip_cc_agent_by_subscribe_uri(uri))) {
28536  if (!expires) {
28537  /* Typically, if a 0 Expires reaches us and we can't find
28538  * the corresponding agent, it means that the CC transaction
28539  * has completed and so the calling side is just trying to
28540  * clean up its subscription. We'll just respond with a
28541  * 200 OK and be done with it
28542  */
28543  transmit_response(p, "200 OK", req);
28544  return 0;
28545  }
28546  ast_log(LOG_WARNING, "Invalid URI '%s' in CC subscribe\n", uri);
28547  transmit_response(p, "404 Not Found", req);
28548  return -1;
28549  }
28550 
28551  agent_pvt = agent->private_data;
28552 
28553  if (!expires) {
28554  /* We got sent a SUBSCRIBE and found an agent. This means that CC
28555  * is being canceled.
28556  */
28557  ast_cc_failed(agent->core_id, "CC is being canceled by %s", agent->device_name);
28558  transmit_response(p, "200 OK", req);
28559  ao2_ref(agent, -1);
28560  return 0;
28561  }
28562 
28563  agent_pvt->subscribe_pvt = dialog_ref(p, "SIP CC agent gains reference to subscription dialog");
28564  ast_cc_agent_accept_request(agent->core_id, "SIP caller %s has requested CC via SUBSCRIBE",
28565  agent->device_name);
28566 
28567  /* We don't send a response here. That is done in the agent's ack callback or in the
28568  * agent destructor, should a failure occur before we have responded
28569  */
28570  ao2_ref(agent, -1);
28571  return 0;
28572 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
enum subscriptiontype subscribed
Definition: sip.h:1161
int ast_cc_failed(int core_id, const char *const debug,...)
Indicate failure has occurred.
Definition: ccss.c:3879
void * private_data
Definition: ccss.h:871
#define LOG_WARNING
Definition: logger.h:274
static struct ast_cc_agent * find_sip_cc_agent_by_subscribe_uri(const char *const uri)
Definition: chan_sip.c:1863
int ast_cc_agent_accept_request(int core_id, const char *const debug,...)
Accept inbound CC request.
Definition: ccss.c:3776
#define ast_strlen_zero(foo)
Definition: strings.h:52
static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req)
Transmit response, no retransmits.
Definition: chan_sip.c:12655
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Definition: astobj2.h:464
Structure representing an agent.
unsigned int core_id
Definition: ccss.h:849
#define dialog_ref(dialog, tag)
when we create or delete references, make sure to use these functions so we keep track of the refcoun...
Definition: dialog.h:32
#define REQ_OFFSET_TO_STR(req, offset)
Definition: sip.h:858
struct sip_pvt * subscribe_pvt
Definition: sip.h:1796
char device_name[1]
Definition: ccss.h:875

◆ handle_common_options()

static int handle_common_options ( struct ast_flags flags,
struct ast_flags mask,
struct ast_variable v 
)
static

Handle flag-type options common to configuration of devices - peers.

Parameters
flagsarray of three struct ast_flags
maskarray of three struct ast_flags
vlinked list of config variables to process
Returns
non-zero if any config options were handled, zero otherwise

Definition at line 31120 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(), buf, ast_variable::lineno, LOG_WARNING, ast_variable::name, set_insecure_flags(), SIP_DIRECT_MEDIA, SIP_DIRECT_MEDIA_NAT, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, SIP_DTMF_SHORTINFO, SIP_G726_NONSTANDARD, SIP_INSECURE, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWOVERLAP_DTMF, SIP_PAGE2_ALLOWOVERLAP_YES, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_BUGGY_MWI, SIP_PAGE2_FAX_DETECT, SIP_PAGE2_FAX_DETECT_BOTH, SIP_PAGE2_FAX_DETECT_CNG, SIP_PAGE2_FAX_DETECT_T38, SIP_PAGE2_IGNORESDPVERSION, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_RPID_IMMEDIATE, SIP_PAGE2_RPID_UPDATE, SIP_PAGE2_TEXTSUPPORT, SIP_PAGE2_TRUST_ID_OUTBOUND, SIP_PAGE2_TRUST_ID_OUTBOUND_LEGACY, SIP_PAGE2_TRUST_ID_OUTBOUND_NO, SIP_PAGE2_TRUST_ID_OUTBOUND_YES, SIP_PAGE2_VIDEOSUPPORT, SIP_PAGE2_VIDEOSUPPORT_ALWAYS, SIP_PAGE3_DIRECT_MEDIA_OUTGOING, SIP_PAGE3_RTCP_MUX, sip_parse_nat_option(), SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_YES, SIP_PROMISCREDIR, SIP_REINVITE, SIP_REINVITE_UPDATE, SIP_SENDRPID, SIP_SENDRPID_PAI, SIP_SENDRPID_RPID, SIP_TRUSTRPID, SIP_USECLIENTCODE, SIP_USEPATH, strsep(), and ast_variable::value.

Referenced by build_peer(), and reload_config().

31121 {
31122  int res = 1;
31123 
31124  if (!strcasecmp(v->name, "trustrpid")) {
31125  ast_set_flag(&mask[0], SIP_TRUSTRPID);
31126  ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID);
31127  } else if (!strcasecmp(v->name, "supportpath")) {
31128  ast_set_flag(&mask[0], SIP_USEPATH);
31129  ast_set2_flag(&flags[0], ast_true(v->value), SIP_USEPATH);
31130  } else if (!strcasecmp(v->name, "sendrpid")) {
31131  ast_set_flag(&mask[0], SIP_SENDRPID);
31132  if (!strcasecmp(v->value, "pai")) {
31133  ast_set_flag(&flags[0], SIP_SENDRPID_PAI);
31134  } else if (!strcasecmp(v->value, "rpid")) {
31135  ast_set_flag(&flags[0], SIP_SENDRPID_RPID);
31136  } else if (ast_true(v->value)) {
31137  ast_set_flag(&flags[0], SIP_SENDRPID_RPID);
31138  }
31139  } else if (!strcasecmp(v->name, "rpid_update")) {
31142  } else if (!strcasecmp(v->name, "rpid_immediate")) {
31145  } else if (!strcasecmp(v->name, "trust_id_outbound")) {
31148  if (!strcasecmp(v->value, "legacy")) {
31150  } else if (ast_true(v->value)) {
31152  } else if (ast_false(v->value)) {
31154  } else {
31155  ast_log(LOG_WARNING, "Unknown trust_id_outbound mode '%s' on line %d, using legacy\n", v->value, v->lineno);
31157  }
31158  } else if (!strcasecmp(v->name, "g726nonstandard")) {
31161  } else if (!strcasecmp(v->name, "useclientcode")) {
31162  ast_set_flag(&mask[0], SIP_USECLIENTCODE);
31163  ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE);
31164  } else if (!strcasecmp(v->name, "dtmfmode")) {
31165  ast_set_flag(&mask[0], SIP_DTMF);
31166  ast_clear_flag(&flags[0], SIP_DTMF);
31167  if (!strcasecmp(v->value, "inband"))
31168  ast_set_flag(&flags[0], SIP_DTMF_INBAND);
31169  else if (!strcasecmp(v->value, "rfc2833"))
31170  ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
31171  else if (!strcasecmp(v->value, "info"))
31172  ast_set_flag(&flags[0], SIP_DTMF_INFO);
31173  else if (!strcasecmp(v->value, "shortinfo"))
31174  ast_set_flag(&flags[0], SIP_DTMF_SHORTINFO);
31175  else if (!strcasecmp(v->value, "auto"))
31176  ast_set_flag(&flags[0], SIP_DTMF_AUTO);
31177  else {
31178  ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno);
31179  ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
31180  }
31181  } else if (!strcasecmp(v->name, "nat")) {
31182  sip_parse_nat_option(v->value, mask, flags);
31183  } else if (!strcasecmp(v->name, "directmedia") || !strcasecmp(v->name, "canreinvite")) {
31184  ast_set_flag(&mask[0], SIP_REINVITE);
31185  ast_clear_flag(&flags[0], SIP_REINVITE);
31186  if (ast_true(v->value)) {
31188  } else if (!ast_false(v->value)) {
31189  char buf[64];
31190  char *word, *next = buf;
31191 
31192  ast_copy_string(buf, v->value, sizeof(buf));
31193  while ((word = strsep(&next, ","))) {
31194  if (!strcasecmp(word, "update")) {
31196  } else if (!strcasecmp(word, "nonat")) {
31197  ast_set_flag(&flags[0], SIP_DIRECT_MEDIA);
31199  } else if (!strcasecmp(word, "outgoing")) {
31200  ast_set_flag(&flags[0], SIP_DIRECT_MEDIA);
31203  } else {
31204  ast_log(LOG_WARNING, "Unknown directmedia mode '%s' on line %d\n", v->value, v->lineno);
31205  }
31206  }
31207  }
31208  } else if (!strcasecmp(v->name, "insecure")) {
31209  ast_set_flag(&mask[0], SIP_INSECURE);
31210  ast_clear_flag(&flags[0], SIP_INSECURE);
31211  set_insecure_flags(&flags[0], v->value, v->lineno);
31212  } else if (!strcasecmp(v->name, "progressinband")) {
31213  ast_set_flag(&mask[0], SIP_PROG_INBAND);
31214  ast_clear_flag(&flags[0], SIP_PROG_INBAND);
31215  if (ast_true(v->value))
31216  ast_set_flag(&flags[0], SIP_PROG_INBAND_YES);
31217  else if (!strcasecmp(v->value, "never"))
31218  ast_set_flag(&flags[0], SIP_PROG_INBAND_NEVER);
31219  } else if (!strcasecmp(v->name, "promiscredir")) {
31220  ast_set_flag(&mask[0], SIP_PROMISCREDIR);
31221  ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR);
31222  } else if (!strcasecmp(v->name, "videosupport")) {
31223  if (!strcasecmp(v->value, "always")) {
31226  } else {
31229  }
31230  } else if (!strcasecmp(v->name, "textsupport")) {
31233  res = 1;
31234  } else if (!strcasecmp(v->name, "allowoverlap")) {
31237  if (ast_true(v->value)) {
31239  } else if (!strcasecmp(v->value, "dtmf")){
31241  }
31242  } else if (!strcasecmp(v->name, "allowsubscribe")) {
31245  } else if (!strcasecmp(v->name, "ignoresdpversion")) {
31248  } else if (!strcasecmp(v->name, "faxdetect")) {
31250  if (ast_true(v->value)) {
31252  } else if (ast_false(v->value)) {
31254  } else {
31255  char *buf = ast_strdupa(v->value);
31256  char *word, *next = buf;
31257 
31258  while ((word = strsep(&next, ","))) {
31259  if (!strcasecmp(word, "cng")) {
31261  } else if (!strcasecmp(word, "t38")) {
31263  } else {
31264  ast_log(LOG_WARNING, "Unknown faxdetect mode '%s' on line %d.\n", word, v->lineno);
31265  }
31266  }
31267  }
31268  } else if (!strcasecmp(v->name, "rfc2833compensate")) {
31271  } else if (!strcasecmp(v->name, "buggymwi")) {
31272  ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI);
31274  } else if (!strcasecmp(v->name, "rtcp_mux")) {
31275  ast_set_flag(&mask[2], SIP_PAGE3_RTCP_MUX);
31277  } else
31278  res = 0;
31279 
31280  return res;
31281 }
#define SIP_PAGE2_FAX_DETECT_CNG
Definition: sip.h:361
#define SIP_PAGE3_RTCP_MUX
Definition: sip.h:394
#define SIP_DIRECT_MEDIA
Definition: sip.h:289
#define SIP_PAGE2_TRUST_ID_OUTBOUND_NO
Definition: sip.h:372
#define SIP_PAGE2_ALLOWSUBSCRIBE
Definition: sip.h:335
#define SIP_PAGE2_FAX_DETECT_BOTH
Definition: sip.h:363
#define SIP_DTMF_INBAND
Definition: sip.h:277
#define SIP_USEPATH
Definition: sip.h:305
#define ast_set2_flag(p, value, flag)
Definition: utils.h:94
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define SIP_PAGE2_FAX_DETECT
Definition: sip.h:360
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define LOG_WARNING
Definition: logger.h:274
#define SIP_TRUSTRPID
Definition: sip.h:270
#define SIP_PAGE3_DIRECT_MEDIA_OUTGOING
Definition: sip.h:388
#define SIP_DTMF_RFC2833
Definition: sip.h:276
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.
Definition: chan_sip.c:31049
#define SIP_PAGE2_RFC2833_COMPENSATE
Definition: sip.h:356
#define SIP_PAGE2_TRUST_ID_OUTBOUND
Definition: sip.h:370
#define SIP_PAGE2_TRUST_ID_OUTBOUND_YES
Definition: sip.h:373
#define SIP_PAGE2_RPID_IMMEDIATE
Definition: sip.h:330
#define SIP_SENDRPID_PAI
Definition: sip.h:308
#define SIP_PROG_INBAND
Definition: sip.h:300
#define ast_log
Definition: astobj2.c:42
#define SIP_PROG_INBAND_YES
Definition: sip.h:303
#define SIP_REINVITE
Definition: sip.h:287
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define SIP_PAGE2_VIDEOSUPPORT_ALWAYS
Definition: sip.h:366
#define SIP_PAGE2_IGNORESDPVERSION
Definition: sip.h:344
#define SIP_PAGE2_ALLOWOVERLAP
Definition: sip.h:337
#define SIP_PAGE2_ALLOWOVERLAP_YES
Definition: sip.h:339
#define SIP_REINVITE_UPDATE
Definition: sip.h:291
#define SIP_INSECURE
Definition: sip.h:294
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: main/utils.c:1951
#define SIP_DTMF_SHORTINFO
Definition: sip.h:280
#define SIP_PROG_INBAND_NEVER
Definition: sip.h:302
#define SIP_PAGE2_ALLOWOVERLAP_DTMF
Definition: sip.h:340
#define SIP_DIRECT_MEDIA_NAT
Definition: sip.h:290
void sip_parse_nat_option(const char *value, struct ast_flags *mask, struct ast_flags *flags)
Parse the comma-separated nat= option values.
#define SIP_PAGE2_BUGGY_MWI
Definition: sip.h:357
#define ast_clear_flag(p, flag)
Definition: utils.h:77
#define SIP_PAGE2_FAX_DETECT_T38
Definition: sip.h:362
#define SIP_PAGE2_TEXTSUPPORT
Definition: sip.h:334
#define SIP_PAGE2_VIDEOSUPPORT
Definition: sip.h:333
char * strsep(char **str, const char *delims)
#define SIP_DTMF
Definition: sip.h:275
#define SIP_USECLIENTCODE
Definition: sip.h:272
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define SIP_SENDRPID_RPID
Definition: sip.h:309
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"...
Definition: main/utils.c:1968
#define SIP_G726_NONSTANDARD
Definition: sip.h:310
#define SIP_PROMISCREDIR
Definition: sip.h:269
#define SIP_DTMF_INFO
Definition: sip.h:278
#define SIP_DTMF_AUTO
Definition: sip.h:279
#define SIP_PAGE2_RPID_UPDATE
Definition: sip.h:325
#define SIP_PAGE2_TRUST_ID_OUTBOUND_LEGACY
Definition: sip.h:371
short word
#define SIP_SENDRPID
Definition: sip.h:306

◆ handle_incoming()

static int handle_incoming ( struct sip_pvt p,
struct sip_request req,
struct ast_sockaddr addr,
int *  recount,
int *  nounlock 
)
static

Handle incoming SIP requests (methods)

Note
This is where all incoming requests go first.
called with p and p->owner locked

Definition at line 29065 of file chan_sip.c.

References __get_header(), __sip_ack(), sip_pvt::alreadygone, ast_alloca, ast_control_pvt_cause_code::ast_cause, ast_channel_hangupcause_hash_set(), AST_CHANNEL_NAME, ast_channel_name(), AST_CONTROL_PVT_CAUSE_CODE, AST_CONTROL_UPDATE_RTP_PEER, ast_copy_string(), ast_debug, ast_log, ast_queue_control(), ast_queue_control_data(), ast_random(), ast_skip_blanks(), ast_sockaddr_stringify(), ast_string_field_set, ast_strlen_zero, ast_test_flag, ast_verbose(), ast_control_pvt_cause_code::chan_name, ast_control_pvt_cause_code::code, sip_request::debug, DEFAULT_TRANS_TIMEOUT, ast_control_pvt_cause_code::emulate_sip_cause, error(), sip_pvt::exten, extract_uri(), FALSE, find_sdp(), sip_pvt::flags, gettag(), sip_pvt::glareinvite, global_store_sip_cause, 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(), hangup_sip2cause(), sip_request::has_to_tag, sip_request::headers, sip_pvt::icseq, cfsip_methods::id, sip_request::ignore, sip_pvt::initreq, INV_REQ_ERROR, INV_REQ_FAILED, INV_REQ_SUCCESS, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lastinvite, sip_pvt::lastmsg, len(), LOG_ERROR, LOG_NOTICE, LOG_WARNING, sip_request::method, sip_pvt::method, sip_pvt::nonce, NULL, sip_pvt::ocseq, sip_pvt::owner, sip_settings::pedanticsipchecking, sip_pvt::pendinginvite, process_sdp(), pvt_set_needdestroy(), sip_pvt::recv, REQ_OFFSET_TO_STR, sip_pvt::sa, sched_check_pendings(), SDP_T38_NONE, SIP_ACK, SIP_BYE, SIP_CANCEL, sip_cfg, SIP_DIRECT_MEDIA, sip_get_header(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NOTIFY, SIP_OPTIONS, SIP_PUBLISH, SIP_REFER, SIP_REGISTER, sip_report_security_event(), SIP_RESPONSE, sip_scheddestroy(), SIP_SUBSCRIBE, SIP_UPDATE, cfsip_methods::text, sip_pvt::theirtag, transmit_response(), transmit_response_reliable(), transmit_response_with_allow(), and transmit_response_with_retry_after().

Referenced by handle_request_do().

29066 {
29067  /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things
29068  relatively static */
29069  const char *cmd;
29070  const char *cseq;
29071  const char *useragent;
29072  const char *via;
29073  const char *callid;
29074  int via_pos = 0;
29075  uint32_t seqno;
29076  int len;
29077  int respid;
29078  int res = 0;
29079  const char *e;
29080  int error = 0;
29081  int oldmethod = p->method;
29082  int acked = 0;
29083 
29084  /* RFC 3261 - 8.1.1 A valid SIP request must contain To, From, CSeq, Call-ID and Via.
29085  * 8.2.6.2 Response must have To, From, Call-ID CSeq, and Via related to the request,
29086  * so we can check to make sure these fields exist for all requests and responses */
29087  cseq = sip_get_header(req, "Cseq");
29088  cmd = REQ_OFFSET_TO_STR(req, header[0]);
29089  /* Save the via_pos so we can check later that responses only have 1 Via header */
29090  via = __get_header(req, "Via", &via_pos);
29091  /* This must exist already because we've called find_call by now */
29092  callid = sip_get_header(req, "Call-ID");
29093 
29094  /* Must have Cseq */
29095  if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq) || ast_strlen_zero(via)) {
29096  ast_log(LOG_ERROR, "Dropping this SIP message with Call-ID '%s', it's incomplete.\n", callid);
29097  error = 1;
29098  }
29099  if (!error && sscanf(cseq, "%30u%n", &seqno, &len) != 1) {
29100  ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd);
29101  error = 1;
29102  }
29103  if (error) {
29104  if (!p->initreq.headers) { /* New call */
29105  pvt_set_needdestroy(p, "no headers");
29106  }
29107  return -1;
29108  }
29109  /* Get the command XXX */
29110 
29111  cmd = REQ_OFFSET_TO_STR(req, rlpart1);
29112  e = ast_skip_blanks(REQ_OFFSET_TO_STR(req, rlpart2));
29113 
29114  /* Save useragent of the client */
29115  useragent = sip_get_header(req, "User-Agent");
29116  if (!ast_strlen_zero(useragent))
29117  ast_string_field_set(p, useragent, useragent);
29118 
29119  /* Find out SIP method for incoming request */
29120  if (req->method == SIP_RESPONSE) { /* Response to our request */
29121  /* ignore means "don't do anything with it" but still have to
29122  * respond appropriately.
29123  * But in this case this is a response already, so we really
29124  * have nothing to do with this message, and even setting the
29125  * ignore flag is pointless.
29126  */
29127  if (ast_strlen_zero(e)) {
29128  return 0;
29129  }
29130  if (sscanf(e, "%30d %n", &respid, &len) != 1) {
29131  ast_log(LOG_WARNING, "Invalid response: '%s'\n", e);
29132  return 0;
29133  }
29134  if (respid <= 0) {
29135  ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid);
29136  return 0;
29137  }
29138  /* RFC 3261 - 8.1.3.3 If more than one Via header field value is present in a reponse
29139  * the UAC SHOULD discard the message. This is not perfect, as it will not catch multiple
29140  * headers joined with a comma. Fixing that would pretty much involve writing a new parser */
29141  if (!ast_strlen_zero(__get_header(req, "via", &via_pos))) {
29142  ast_log(LOG_WARNING, "Misrouted SIP response '%s' with Call-ID '%s', too many vias\n", e, callid);
29143  return 0;
29144  }
29145  if (p->ocseq && (p->ocseq < seqno)) {
29146  ast_debug(1, "Ignoring out of order response %u (expecting %u)\n", seqno, p->ocseq);
29147  return -1;
29148  } else {
29149  if ((respid == 200) || ((respid >= 300) && (respid <= 399))) {
29150  extract_uri(p, req);
29151  }
29152 
29153  if (p->owner) {
29154  struct ast_control_pvt_cause_code *cause_code;
29155  int data_size = sizeof(*cause_code);
29156  /* size of the string making up the cause code is "SIP " + cause length */
29157  data_size += 4 + strlen(REQ_OFFSET_TO_STR(req, rlpart2));
29158  cause_code = ast_alloca(data_size);
29159  memset(cause_code, 0, data_size);
29160 
29162 
29163  snprintf(cause_code->code, data_size - sizeof(*cause_code) + 1, "SIP %s", REQ_OFFSET_TO_STR(req, rlpart2));
29164 
29165  cause_code->ast_cause = hangup_sip2cause(respid);
29166  if (global_store_sip_cause) {
29167  cause_code->emulate_sip_cause = 1;
29168  }
29169 
29170  ast_queue_control_data(p->owner, AST_CONTROL_PVT_CAUSE_CODE, cause_code, data_size);
29171  ast_channel_hangupcause_hash_set(p->owner, cause_code, data_size);
29172  }
29173 
29174  handle_response(p, respid, e + len, req, seqno);
29175  }
29176  return 0;
29177  }
29178 
29179  /* New SIP request coming in
29180  (could be new request in existing SIP dialog as well...)
29181  */
29182  p->method = req->method; /* Find out which SIP method they are using */
29183  ast_debug(4, "**** Received %s (%u) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd);
29184 
29185  if (p->icseq && (p->icseq > seqno) ) {
29186  if (p->pendinginvite && seqno == p->pendinginvite && (req->method == SIP_ACK || req->method == SIP_CANCEL)) {
29187  ast_debug(2, "Got CANCEL or ACK on INVITE with transactions in between.\n");
29188  } else {
29189  ast_debug(1, "Ignoring too old SIP packet packet %u (expecting >= %u)\n", seqno, p->icseq);
29190  if (req->method == SIP_INVITE) {
29191  unsigned int ran = (ast_random() % 10) + 1;
29192  char seconds[4];
29193  snprintf(seconds, sizeof(seconds), "%u", ran);
29194  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 */
29195  } else if (req->method != SIP_ACK) {
29196  transmit_response(p, "500 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */
29197  }
29198  return -1;
29199  }
29200  } else if (p->icseq &&
29201  p->icseq == seqno &&
29202  req->method != SIP_ACK &&
29203  (p->method != SIP_CANCEL || p->alreadygone)) {
29204  /* ignore means "don't do anything with it" but still have to
29205  respond appropriately. We do this if we receive a repeat of
29206  the last sequence number */
29207  req->ignore = 1;
29208  ast_debug(3, "Ignoring SIP message because of retransmit (%s Seqno %u, ours %u)\n", sip_methods[p->method].text, p->icseq, seqno);
29209  }
29210 
29211  /* RFC 3261 section 9. "CANCEL has no effect on a request to which a UAS has
29212  * already given a final response." */
29213  if (!p->pendinginvite && (req->method == SIP_CANCEL)) {
29214  transmit_response(p, "481 Call/Transaction Does Not Exist", req);
29215  return res;
29216  }
29217 
29218  if (seqno >= p->icseq)
29219  /* Next should follow monotonically (but not necessarily
29220  incrementally -- thanks again to the genius authors of SIP --
29221  increasing */
29222  p->icseq = seqno;
29223 
29224  /* Find their tag if we haven't got it */
29225  if (ast_strlen_zero(p->theirtag)) {
29226  char tag[128];
29227 
29228  gettag(req, "From", tag, sizeof(tag));
29229  ast_string_field_set(p, theirtag, tag);
29230  }
29231  snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd);
29232 
29234  /* If this is a request packet without a from tag, it's not
29235  correct according to RFC 3261 */
29236  /* Check if this a new request in a new dialog with a totag already attached to it,
29237  RFC 3261 - section 12.2 - and we don't want to mess with recovery */
29238  if (!p->initreq.headers && req->has_to_tag) {
29239  /* If this is a first request and it got a to-tag, it is not for us */
29240  if (!req->ignore && req->method == SIP_INVITE) {
29241  /* Just because we think this is a dialog-starting INVITE with a to-tag
29242  * doesn't mean it actually is. It could be a reinvite for an established, but
29243  * unknown dialog. In such a case, we need to change our tag to the
29244  * incoming INVITE's to-tag so that they will recognize the 481 we send and
29245  * so that we will properly match their incoming ACK.
29246  */
29247  char totag[128];
29248  gettag(req, "To", totag, sizeof(totag));
29249  ast_string_field_set(p, tag, totag);
29250  p->pendinginvite = p->icseq;
29251  transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req);
29252  /* Will cease to exist after ACK */
29253  return res;
29254  } else if (req->method != SIP_ACK) {
29255  transmit_response(p, "481 Call/Transaction Does Not Exist", req);
29257  return res;
29258  }
29259  /* Otherwise, this is an ACK. It will always have a to-tag */
29260  }
29261  }
29262 
29263  if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY || p->method == SIP_PUBLISH)) {
29264  transmit_response(p, "400 Bad request", req);
29266  return -1;
29267  }
29268 
29269  /* Handle various incoming SIP methods in requests */
29270  switch (p->method) {
29271  case SIP_OPTIONS:
29272  res = handle_request_options(p, req, addr, e);
29273  break;
29274  case SIP_INVITE:
29275  res = handle_request_invite(p, req, addr, seqno, recount, e, nounlock);
29276 
29277  if (res < 9) {
29278  sip_report_security_event(NULL, &p->recv, p, req, res);
29279  }
29280 
29281  switch (res) {
29282  case INV_REQ_SUCCESS:
29283  res = 1;
29284  break;
29285  case INV_REQ_FAILED:
29286  res = 0;
29287  break;
29288  case INV_REQ_ERROR:
29289  res = -1;
29290  break;
29291  default:
29292  res = 0;
29293  break;
29294  }
29295 
29296  break;
29297  case SIP_REFER:
29298  res = handle_request_refer(p, req, seqno, nounlock);
29299  break;
29300  case SIP_CANCEL:
29301  res = handle_request_cancel(p, req);
29302  break;
29303  case SIP_BYE:
29304  res = handle_request_bye(p, req);
29305  break;
29306  case SIP_MESSAGE:
29307  res = handle_request_message(p, req, addr, e);
29308  break;
29309  case SIP_PUBLISH:
29310  res = handle_request_publish(p, req, addr, seqno, e);
29311  break;
29312  case SIP_SUBSCRIBE:
29313  res = handle_request_subscribe(p, req, addr, seqno, e);
29314  break;
29315  case SIP_REGISTER:
29316  res = handle_request_register(p, req, addr, e);
29317  sip_report_security_event(p->exten, NULL, p, req, res);
29318  break;
29319  case SIP_INFO:
29320  if (req->debug)
29321  ast_verbose("Receiving INFO!\n");
29322  if (!req->ignore)
29323  handle_request_info(p, req);
29324  else /* if ignoring, transmit response */
29325  transmit_response(p, "200 OK", req);
29326  break;
29327  case SIP_NOTIFY:
29328  res = handle_request_notify(p, req, addr, seqno, e);
29329  break;
29330  case SIP_UPDATE:
29331  res = handle_request_update(p, req);
29332  break;
29333  case SIP_ACK:
29334  /* Make sure we don't ignore this */
29335  if (seqno == p->pendinginvite) {
29337  p->pendinginvite = 0;
29338  acked = __sip_ack(p, seqno, 1 /* response */, 0);
29339  if (p->owner && find_sdp(req)) {
29340  if (process_sdp(p, req, SDP_T38_NONE, FALSE)) {
29341  return -1;
29342  }
29343  if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) {
29345  }
29346  }
29348  } else if (p->glareinvite == seqno) {
29349  /* handle ack for the 491 pending sent for glareinvite */
29350  p->glareinvite = 0;
29351  acked = __sip_ack(p, seqno, 1, 0);
29352  }
29353  if (!acked) {
29354  /* Got an ACK that did not match anything. Ignore
29355  * silently and restore previous method */
29356  p->method = oldmethod;
29357  }
29358  if (!p->lastinvite && ast_strlen_zero(p->nonce)) {
29359  pvt_set_needdestroy(p, "unmatched ACK");
29360  }
29361  break;
29362  default:
29363  transmit_response_with_allow(p, "501 Method Not Implemented", req, 0);
29364  ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n",
29365  cmd, ast_sockaddr_stringify(&p->sa));
29366  /* If this is some new method, and we don't have a call, destroy it now */
29367  if (!p->initreq.headers) {
29368  pvt_set_needdestroy(p, "unimplemented method");
29369  }
29370  break;
29371  }
29372  return res;
29373 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
Definition: sip.h:626
#define SIP_DIRECT_MEDIA
Definition: sip.h:289
uint32_t glareinvite
Definition: sip.h:1148
char debug
Definition: sip.h:837
#define FALSE
Definition: app_minivm.c:521
char chan_name[AST_CHANNEL_NAME]
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
Definition: channel.c:1231
char lastmsg[256]
Definition: sip.h:1145
#define ast_test_flag(p, flag)
Definition: utils.h:63
Definition: sip.h:619
static const struct cfsip_methods sip_methods[]
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.
Definition: chan_sip.c:12715
#define LOG_WARNING
Definition: logger.h:274
uint32_t pendinginvite
Definition: sip.h:1147
struct ast_sockaddr recv
Definition: sip.h:1135
#define DEFAULT_TRANS_TIMEOUT
Definition: sip.h:107
static int handle_request_refer(struct sip_pvt *p, struct sip_request *req, uint32_t seqno, int *nounlock)
Definition: chan_sip.c:27324
static const char * gettag(const struct sip_request *req, const char *header, char *tagbuf, int tagbufsize)
Get tag from packet.
Definition: chan_sip.c:25654
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.
Definition: chan_sip.c:12733
struct ast_flags flags[3]
Definition: sip.h:1075
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
Definition: sip.h:621
#define NULL
Definition: resample.c:96
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.
Definition: chan_sip.c:25732
const ast_string_field nonce
Definition: sip.h:1063
int hangup_sip2cause(int cause)
Convert SIP hangup causes to Asterisk hangup causes.
Definition: chan_sip.c:6986
#define ast_strlen_zero(foo)
Definition: strings.h:52
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.
Definition: chan_sip.c:12688
struct ast_sockaddr sa
Definition: sip.h:1125
static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req)
Transmit response, no retransmits.
Definition: chan_sip.c:12655
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: chan_sip.c:4570
unsigned short alreadygone
Definition: sip.h:1079
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
uint32_t icseq
Definition: sip.h:1068
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.
Definition: chan_sip.c:25171
static int global_store_sip_cause
Definition: chan_sip.c:860
struct sip_request initreq
Definition: sip.h:1151
static int find_sdp(struct sip_request *req)
Determine whether a SIP message contains an SDP in its body.
Definition: chan_sip.c:10054
long int ast_random(void)
Definition: main/utils.c:2064
const ast_string_field exten
Definition: sip.h:1063
static void extract_uri(struct sip_pvt *p, struct sip_request *req)
Check Contact: URI of SIP message.
Definition: chan_sip.c:14289
const ast_string_field theirtag
Definition: sip.h:1063
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.
Definition: chan_sip.c:28575
int pedanticsipchecking
Definition: sip.h:756
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
static const char * __get_header(const struct sip_request *req, const char *name, int *start)
Definition: chan_sip.c:8562
#define LOG_ERROR
Definition: logger.h:285
static int handle_request_bye(struct sip_pvt *p, struct sip_request *req)
Handle incoming BYE request.
Definition: chan_sip.c:27605
static void pvt_set_needdestroy(struct sip_pvt *pvt, const char *reason)
Definition: chan_sip.c:3429
enum sipmethod id
Definition: chan_sip.c:735
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int method
Definition: sip.h:1009
int method
Definition: sip.h:833
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
uint32_t ocseq
Definition: sip.h:1067
int headers
Definition: sip.h:832
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
#define LOG_NOTICE
Definition: logger.h:263
static int handle_request_update(struct sip_pvt *p, struct sip_request *req)
bare-bones support for SIP UPDATE
Definition: chan_sip.c:26164
#define AST_CHANNEL_NAME
Definition: channel.h:172
struct ast_channel * owner
Definition: sip.h:1138
#define REQ_OFFSET_TO_STR(req, offset)
Definition: sip.h:858
static int handle_request_cancel(struct sip_pvt *p, struct sip_request *req)
Handle incoming CANCEL request.
Definition: chan_sip.c:27538
enum invitestates invitestate
Definition: sip.h:1007
char *const text
Definition: chan_sip.c:737
static int handle_request_message(struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, const char *e)
Handle incoming MESSAGE request.
Definition: chan_sip.c:27820
static void handle_request_info(struct sip_pvt *p, struct sip_request *req)
Receive SIP INFO Message.
Definition: chan_sip.c:22622
static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action, int is_offer)
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().
Definition: chan_sip.c:10253
static int handle_request_publish(struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, const uint32_t seqno, const char *uri)
Definition: chan_sip.c:28410
static int handle_request_register(struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *sin, const char *e)
Handle incoming REGISTER request.
Definition: chan_sip.c:28991
Definition: sip.h:622
static void sched_check_pendings(struct sip_pvt *pvt)
Definition: chan_sip.c:23802
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
const char * ast_channel_name(const struct ast_channel *chan)
char ignore
Definition: sip.h:839
uint32_t lastinvite
Definition: sip.h:1074
int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen)
Queue a control frame with payload.
Definition: channel.c:1238
char has_to_tag
Definition: sip.h:838
int sip_report_security_event(const char *peer, struct ast_sockaddr *addr, const struct sip_pvt *p, const struct sip_request *req, const int res)
int error(const char *format,...)
Definition: utils/frame.c:999
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...
Definition: chan_sip.c:25900
void ast_channel_hangupcause_hash_set(struct ast_channel *chan, const struct ast_control_pvt_cause_code *cause_code, int datalen)
Sets the HANGUPCAUSE hash and optionally the SIP_CAUSE hash on the given channel. ...
Definition: channel.c:4391
void sip_scheddestroy(struct sip_pvt *p, int ms)
Schedule destruction of SIP dialog.
Definition: chan_sip.c:4549
static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, uint32_t seqno, int *recount, const char *e, int *nounlock)
Handle incoming INVITE request.
Definition: chan_sip.c:26347
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ handle_invite_replaces()

static int handle_invite_replaces ( struct sip_pvt p,
struct sip_request req,
int *  nounlock,
struct sip_pvt replaces_pvt,
struct ast_channel replaces_chan 
)
static

Handle the transfer part of INVITE with a replaces: header,.

This is used for call-pickup and for attended transfers initiated on remote endpoints (i.e. a REFER received on a remote server).

Note
p and p->owner are locked upon entering this function. If the call pickup or attended transfer is successful, then p->owner will be unlocked upon exiting this function. This is communicated to the caller through the nounlock parameter.
Parameters
pThe sip_pvt where the INVITE with Replaces was received
reqThe incoming INVITE
[out]nounlockIndicator if p->owner should remained locked. On successful transfer, this will be set true.
replaces_pvtsip_pvt referenced by Replaces header
replaces_chanreplaces_pvt's owner channel
Return values
0Success
non-zeroFailure

Definition at line 25984 of file chan_sip.c.

References ao2_ref, append_history, ast_bridge_impart(), AST_BRIDGE_IMPART_CHAN_INDEPENDENT, ast_bridge_transfer_acquire_bridge(), ast_can_pickup(), ast_channel_lock, ast_channel_move(), ast_channel_name(), ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_debug, ast_do_pickup(), ast_hangup(), ast_log, ast_raw_answer(), ast_setstate(), AST_STATE_RING, c, DEFAULT_TRANS_TIMEOUT, sip_request::ignore, LOG_ERROR, NULL, sip_pvt::owner, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), transmit_response(), and transmit_response_reliable().

Referenced by handle_request_invite().

25986 {
25987  struct ast_channel *c;
25988  struct ast_bridge *bridge;
25989 
25990  if (req->ignore) {
25991  return 0;
25992  }
25993 
25994  if (!p->owner) {
25995  /* What to do if no channel ??? */
25996  ast_log(LOG_ERROR, "Unable to create new channel. Invite/replace failed.\n");
25997  transmit_response_reliable(p, "503 Service Unavailable", req);
25998  append_history(p, "Xfer", "INVITE/Replace Failed. No new channel.");
26000  return 1;
26001  }
26002  append_history(p, "Xfer", "INVITE/Replace received");
26003 
26004  /* Get a ref to ensure the channel cannot go away on us. */
26005  c = ast_channel_ref(p->owner);
26006 
26007  /* Fake call progress */
26008  transmit_response(p, "100 Trying", req);
26010 
26011  ast_debug(4, "Invite/Replaces: preparing to replace %s with %s\n", ast_channel_name(replaces_chan), ast_channel_name(c));
26012 
26013  *nounlock = 1;
26014  ast_channel_unlock(c);
26015  sip_pvt_unlock(p);
26016 
26017  ast_raw_answer(c);
26018 
26019  bridge = ast_bridge_transfer_acquire_bridge(replaces_chan);
26020  if (bridge) {
26021  /*
26022  * We have two refs of the channel. One is held in c and the other
26023  * is notionally represented by p->owner. The impart is "stealing"
26024  * the p->owner ref on success so the bridging system can have
26025  * control of when the channel is hung up.
26026  */
26027  if (ast_bridge_impart(bridge, c, replaces_chan, NULL,
26029  ast_hangup(c);
26030  }
26031  ao2_ref(bridge, -1);
26032  } else {
26033  int pickedup;
26034  ast_channel_lock(replaces_chan);
26035  pickedup = ast_can_pickup(replaces_chan) && !ast_do_pickup(c, replaces_chan);
26036  ast_channel_unlock(replaces_chan);
26037  if (!pickedup) {
26038  ast_channel_move(replaces_chan, c);
26039  }
26040  ast_hangup(c);
26041  }
26042  ast_channel_unref(c);
26043  sip_pvt_lock(p);
26044  return 0;
26045 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
#define DEFAULT_TRANS_TIMEOUT
Definition: sip.h:107
int ast_do_pickup(struct ast_channel *chan, struct ast_channel *target)
Pickup a call target.
Definition: pickup.c:302
static struct test_val c
#define NULL
Definition: resample.c:96
int ast_channel_move(struct ast_channel *dest, struct ast_channel *source)
Move a channel from its current location to a new location.
Definition: channel.c:10867
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
int ast_raw_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2699
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
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.
Definition: chan_sip.c:12688
static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req)
Transmit response, no retransmits.
Definition: chan_sip.c:12655
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
struct ast_bridge * ast_bridge_transfer_acquire_bridge(struct ast_channel *chan)
Acquire the channel&#39;s bridge for transfer purposes.
Definition: bridge.c:4460
int ast_bridge_impart(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, enum ast_bridge_impart_flags flags) attribute_warn_unused_result
Impart a channel to a bridge (non-blocking)
Definition: bridge.c:1924
#define ao2_ref(o, delta)
Definition: astobj2.h:464
Structure that contains information about a bridge.
Definition: bridge.h:357
#define LOG_ERROR
Definition: logger.h:285
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_channel * owner
Definition: sip.h:1138
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
int ast_can_pickup(struct ast_channel *chan)
Test if a channel can be picked up.
Definition: pickup.c:77
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2970
const char * ast_channel_name(const struct ast_channel *chan)
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7486
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406
char ignore
Definition: sip.h:839
void sip_scheddestroy(struct sip_pvt *p, int ms)
Schedule destruction of SIP dialog.
Definition: chan_sip.c:4549

◆ handle_request_bye()

static int handle_request_bye ( struct sip_pvt p,
struct sip_request req 
)
static

Handle incoming BYE request.

Definition at line 27605 of file chan_sip.c.

References __sip_pretend_ack(), ao2_ref, append_history, ARRAY_LEN, ast_async_goto(), AST_CAUSE_PROTOCOL_ERROR, ast_channel_bridge_peer(), ast_channel_cleanup, ast_channel_hangupcause(), ast_channel_lock, ast_channel_ref, ast_channel_tech(), ast_channel_tech_pvt(), ast_channel_unlock, ast_clear_flag, ast_debug, ast_log, AST_MAX_USER_FIELD, ast_queue_hangup(), ast_queue_hangup_with_cause(), ast_queue_unhold(), ast_rtp_instance_get_quality(), ast_rtp_instance_set_stats_vars(), AST_RTP_INSTANCE_STAT_FIELD_QUALITY, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_JITTER, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_LOSS, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_RTT, ast_sockaddr_stringify(), ast_strdupa, ast_string_field_set, ast_strlen_zero, ast_test_flag, c, sip_pvt::callid, check_via(), context, sip_pvt::context, copy_request(), sip_settings::default_context, DEFAULT_TRANS_TIMEOUT, sip_pvt::do_history, sip_pvt::flags, get_also_info(), sip_request::ignore, sip_pvt::initreq, INV_TERMINATED, sip_pvt::invitestate, IS_SIP_TECH, LOG_NOTICE, LOG_WARNING, sip_request::method, NULL, sip_pvt::owner, parse_sip_options(), pbx_builtin_setvar_helper(), sip_pvt::pendinginvite, quality, RAII_VAR, sip_pvt::recv, sip_pvt::refer, sip_refer::refer_to, sip_pvt::rtp, sip_alreadygone(), sip_cfg, sip_get_header(), sip_methods, SIP_OUTGOING, SIP_PAGE2_DIALOG_ESTABLISHED, sip_pvt_lock, sip_pvt_lock_full(), sip_pvt_unlock, sip_queue_hangup_cause(), sip_scheddestroy_final(), sipdebug, sip_pvt::stimer, stop_media_flows(), stop_reinvite_retry(), stop_session_timer(), cfsip_methods::text, transmit_response(), transmit_response_reliable(), transmit_response_with_unsupported(), sip_pvt::trtp, use_reason_header(), and sip_pvt::vrtp.

Referenced by handle_incoming().

27606 {
27607  struct ast_channel *c=NULL;
27608  int res;
27609  const char *required;
27610  RAII_VAR(struct ast_channel *, peer_channel, NULL, ast_channel_cleanup);
27611  char quality_buf[AST_MAX_USER_FIELD], *quality;
27612 
27613  /* If we have an INCOMING invite that we haven't answered, terminate that transaction */
27614  if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !req->ignore) {
27615  transmit_response_reliable(p, "487 Request Terminated", &p->initreq);
27616  }
27617 
27618  __sip_pretend_ack(p);
27619 
27621 
27622  copy_request(&p->initreq, req);
27623  if (sipdebug)
27624  ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid);
27625  check_via(p, req);
27626  sip_alreadygone(p);
27627 
27628  if (p->owner) {
27629  RAII_VAR(struct ast_channel *, owner_relock, NULL, ast_channel_cleanup);
27630  RAII_VAR(struct ast_channel *, owner_ref, NULL, ast_channel_cleanup);
27631 
27632  /* Grab a reference to p->owner to prevent it from going away */
27633  owner_ref = ast_channel_ref(p->owner);
27634 
27635  /* Established locking order here is bridge, channel, pvt
27636  * and the bridge will be locked during ast_channel_bridge_peer */
27637  ast_channel_unlock(owner_ref);
27638  sip_pvt_unlock(p);
27639 
27640  peer_channel = ast_channel_bridge_peer(owner_ref);
27641 
27642  owner_relock = sip_pvt_lock_full(p);
27643  if (!owner_relock) {
27644  ast_debug(3, "Unable to reacquire owner channel lock, channel is gone\n");
27645  return 0;
27646  }
27647  }
27648 
27649  /* Get RTCP quality before end of call */
27650  if (p->rtp) {
27651  if (p->do_history) {
27652  if ((quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) {
27653  append_history(p, "RTCPaudio", "Quality:%s", quality);
27654  }
27655  if ((quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_JITTER, quality_buf, sizeof(quality_buf)))) {
27656  append_history(p, "RTCPaudioJitter", "Quality:%s", quality);
27657  }
27658  if ((quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_LOSS, quality_buf, sizeof(quality_buf)))) {
27659  append_history(p, "RTCPaudioLoss", "Quality:%s", quality);
27660  }
27661  if ((quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_RTT, quality_buf, sizeof(quality_buf)))) {
27662  append_history(p, "RTCPaudioRTT", "Quality:%s", quality);
27663  }
27664  }
27665 
27666  if (p->owner) {
27667  RAII_VAR(struct ast_channel *, owner_relock, NULL, ast_channel_cleanup);
27668  RAII_VAR(struct ast_channel *, owner_ref, NULL, ast_channel_cleanup);
27669  struct ast_rtp_instance *p_rtp;
27670 
27671  /* Grab a reference to p->owner to prevent it from going away */
27672  owner_ref = ast_channel_ref(p->owner);
27673 
27674  p_rtp = p->rtp;
27675  ao2_ref(p_rtp, +1);
27676 
27677  /* Established locking order here is bridge, channel, pvt
27678  * and the bridge and channel will be locked during
27679  * ast_rtp_instance_set_stats_vars */
27680  ast_channel_unlock(owner_ref);
27681  sip_pvt_unlock(p);
27682 
27683  ast_rtp_instance_set_stats_vars(owner_ref, p_rtp);
27684  ao2_ref(p_rtp, -1);
27685 
27686  if (peer_channel) {
27687  ast_channel_lock(peer_channel);
27688  if (IS_SIP_TECH(ast_channel_tech(peer_channel))) {
27689  struct sip_pvt *peer_pvt;
27690 
27691  peer_pvt = ast_channel_tech_pvt(peer_channel);
27692  if (peer_pvt) {
27693  ao2_ref(peer_pvt, +1);
27694  sip_pvt_lock(peer_pvt);
27695  if (peer_pvt->rtp) {
27696  struct ast_rtp_instance *peer_rtp;
27697 
27698  peer_rtp = peer_pvt->rtp;
27699  ao2_ref(peer_rtp, +1);
27700  ast_channel_unlock(peer_channel);
27701  sip_pvt_unlock(peer_pvt);
27702  ast_rtp_instance_set_stats_vars(peer_channel, peer_rtp);
27703  ao2_ref(peer_rtp, -1);
27704  ast_channel_lock(peer_channel);
27705  sip_pvt_lock(peer_pvt);
27706  }
27707  sip_pvt_unlock(peer_pvt);
27708  ao2_ref(peer_pvt, -1);
27709  }
27710  }
27711  ast_channel_unlock(peer_channel);
27712  }
27713 
27714  owner_relock = sip_pvt_lock_full(p);
27715  if (!owner_relock) {
27716  ast_debug(3, "Unable to reacquire owner channel lock, channel is gone\n");
27717  return 0;
27718  }
27719  }
27720  }
27721 
27722  if (p->vrtp && (quality = ast_rtp_instance_get_quality(p->vrtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) {
27723  if (p->do_history) {
27724  append_history(p, "RTCPvideo", "Quality:%s", quality);
27725  }
27726  if (p->owner) {
27727  pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", quality);
27728  }
27729  }
27730 
27731  if (p->trtp && (quality = ast_rtp_instance_get_quality(p->trtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) {
27732  if (p->do_history) {
27733  append_history(p, "RTCPtext", "Quality:%s", quality);
27734  }
27735  if (p->owner) {
27736  pbx_builtin_setvar_helper(p->owner, "RTPTEXTQOS", quality);
27737  }
27738  }
27739 
27740  stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
27741  if (p->stimer) {
27742  stop_session_timer(p); /* Stop Session-Timer */
27743  }
27744 
27745  use_reason_header(p, req);
27746  if (!ast_strlen_zero(sip_get_header(req, "Also"))) {
27747  ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n",
27749  if (ast_strlen_zero(p->context))
27751  res = get_also_info(p, req);
27752  if (!res) {
27753  c = p->owner;
27754  if (c) {
27755  if (peer_channel) {
27756  RAII_VAR(struct ast_channel *, owner_relock, NULL, ast_channel_cleanup);
27757  char *local_context = ast_strdupa(p->context);
27758  char *local_refer_to = ast_strdupa(p->refer->refer_to);
27759 
27760  /* Grab a reference to p->owner to prevent it from going away */
27761  ast_channel_ref(c);
27762 
27763  /* Don't actually hangup here... */
27764  ast_queue_unhold(c);
27765  ast_channel_unlock(c); /* async_goto can do a masquerade, no locks can be held during a masq */
27766  sip_pvt_unlock(p);
27767 
27768  ast_async_goto(peer_channel, local_context, local_refer_to, 1);
27769 
27770  owner_relock = sip_pvt_lock_full(p);
27772  if (!owner_relock) {
27773  ast_debug(3, "Unable to reacquire owner channel lock, channel is gone\n");
27774  return 0;
27775  }
27776  } else {
27777  ast_queue_hangup(p->owner);
27778  }
27779  }
27780  } else {
27781  ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_sockaddr_stringify(&p->recv));
27782  if (p->owner)
27784  }
27785  } else if (p->owner) {
27788  ast_debug(3, "Received bye, issuing owner hangup\n");
27789  } else {
27791  ast_debug(3, "Received bye, no owner, selfdestruct soon.\n");
27792  }
27794 
27795  /* Find out what they require */
27796  required = sip_get_header(req, "Require");
27797  if (!ast_strlen_zero(required)) {
27798  char unsupported[256] = { 0, };
27799  parse_sip_options(required, unsupported, ARRAY_LEN(unsupported));
27800  /* If there are any options required that we do not support,
27801  * then send a 420 with only those unsupported options listed */
27802  if (!ast_strlen_zero(unsupported)) {
27803  transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, unsupported);
27804  ast_log(LOG_WARNING, "Received SIP BYE with unsupported required extension: required:%s unsupported:%s\n", required, unsupported);
27805  } else {
27806  transmit_response(p, "200 OK", req);
27807  }
27808  } else {
27809  transmit_response(p, "200 OK", req);
27810  }
27811 
27812  /* Destroy any pending invites so we won't try to do another
27813  * scheduled reINVITE. */
27815 
27816  return 1;
27817 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
#define AST_CAUSE_PROTOCOL_ERROR
Definition: causes.h:144
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
Definition: channel.c:1150
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
void __sip_pretend_ack(struct sip_pvt *p)
Pretend to ack all packets called with p locked.
Definition: chan_sip.c:4615
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static int quality
Definition: codec_speex.c:62
void * ast_channel_tech_pvt(const struct ast_channel *chan)
struct ast_rtp_instance * trtp
Definition: sip.h:1176
#define ast_test_flag(p, flag)
Definition: utils.h:63
static const struct cfsip_methods sip_methods[]
static void stop_reinvite_retry(struct sip_pvt *pvt)
Definition: chan_sip.c:23846
int ast_queue_unhold(struct ast_channel *chan)
Queue an unhold frame.
Definition: channel.c:1216
#define LOG_WARNING
Definition: logger.h:274
uint32_t pendinginvite
Definition: sip.h:1147
static void check_via(struct sip_pvt *p, const struct sip_request *req)
check Via: header for hostname, port and rport request/answer
Definition: chan_sip.c:19164
struct ast_sockaddr recv
Definition: sip.h:1135
#define DEFAULT_TRANS_TIMEOUT
Definition: sip.h:107
static void sip_alreadygone(struct sip_pvt *dialog)
Encapsulate setting of SIP_ALREADYGONE to be able to trace it with debugging.
Definition: chan_sip.c:3460
static int get_also_info(struct sip_pvt *p, struct sip_request *oreq)
Call transfer support (old way, deprecated by the IETF)
Definition: chan_sip.c:19043
static struct test_val c
struct ast_flags flags[3]
Definition: sip.h:1075
const ast_string_field context
Definition: sip.h:1063
#define NULL
Definition: resample.c:96
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
Queue a hangup frame with hangupcause set.
Definition: channel.c:1166
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
static void stop_session_timer(struct sip_pvt *p)
Session-Timers: Stop session timer.
Definition: chan_sip.c:30213
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.
Definition: chan_sip.c:12688
static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req)
Transmit response, no retransmits.
Definition: chan_sip.c:12655
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static void sip_queue_hangup_cause(struct sip_pvt *p, int cause)
Definition: chan_sip.c:23981
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
struct sip_request initreq
Definition: sip.h:1151
static void copy_request(struct sip_request *dst, const struct sip_request *src)
copy SIP request (mostly used to save request for responses)
Definition: chan_sip.c:14061
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2992
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
const ast_string_field refer_to
Definition: sip.h:944
char * ast_rtp_instance_get_quality(struct ast_rtp_instance *instance, enum ast_rtp_instance_stat_field field, char *buf, size_t size)
Retrieve quality statistics about an RTP instance.
Definition: rtp_engine.c:2460
const ast_string_field callid
Definition: sip.h:1063
#define IS_SIP_TECH(t)
Definition: sip_utils.h:26
struct sip_st_dlg * stimer
Definition: sip.h:1184
int method
Definition: sip.h:833
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
struct ast_rtp_instance * vrtp
Definition: sip.h:1175
static void stop_media_flows(struct sip_pvt *p)
Immediately stop RTP, VRTP and UDPTL as applicable.
Definition: chan_sip.c:25156
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
#define LOG_NOTICE
Definition: logger.h:263
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
static struct ast_channel * sip_pvt_lock_full(struct sip_pvt *pvt)
Definition: chan_sip.c:9400
#define ast_channel_unlock(chan)
Definition: channel.h:2946
unsigned short do_history
Definition: sip.h:1078
struct ast_channel * owner
Definition: sip.h:1138
struct ast_rtp_instance * rtp
Definition: sip.h:1174
enum invitestates invitestate
Definition: sip.h:1007
#define ast_clear_flag(p, flag)
Definition: utils.h:77
char *const text
Definition: chan_sip.c:737
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
struct sip_refer * refer
Definition: sip.h:1160
static int use_reason_header(struct sip_pvt *pvt, struct sip_request *req)
Parses SIP reason header according to RFC3326 and sets channel&#39;s hangupcause if configured so and hea...
Definition: chan_sip.c:16841
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2970
void sip_scheddestroy_final(struct sip_pvt *p, int ms)
Schedule final destruction of SIP dialog.
Definition: chan_sip.c:4557
int ast_channel_hangupcause(const struct ast_channel *chan)
struct ast_channel * ast_channel_bridge_peer(struct ast_channel *chan)
Get the channel&#39;s bridge peer only if the bridge is two-party.
Definition: channel.c:10765
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406
int ast_async_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Set the channel to next execute the specified dialplan location.
Definition: pbx.c:7011
char ignore
Definition: sip.h:839
void ast_rtp_instance_set_stats_vars(struct ast_channel *chan, struct ast_rtp_instance *instance)
Set standard statistics from an RTP instance on a channel.
Definition: rtp_engine.c:2500
#define SIP_OUTGOING
Definition: sip.h:257
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
char default_context[AST_MAX_CONTEXT]
Definition: sip.h:782
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.
Definition: chan_sip.c:12661
#define SIP_PAGE2_DIALOG_ESTABLISHED
Definition: sip.h:358
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
unsigned int parse_sip_options(const char *options, char *unsupported, size_t unsupported_len)
Parse supported header in incoming packet.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514
#define AST_MAX_USER_FIELD
Definition: channel.h:175

◆ handle_request_cancel()

static int handle_request_cancel ( struct sip_pvt p,
struct sip_request req 
)
static

Handle incoming CANCEL request.

Definition at line 27538 of file chan_sip.c.

References __sip_pretend_ack(), ao2_t_ref, ast_channel_hangupcause(), ast_debug, AST_STATE_UP, ast_str_strlen(), ast_test_flag, check_via(), sip_request::data, DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, sip_pvt::initreq, INV_CANCELLED, INV_COMPLETED, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lastinvite, sip_pkt::next, NULL, sip_pvt::owner, sip_pvt::packets, sip_pkt::response_code, sip_pkt::seqno, sip_alreadygone(), SIP_INC_COUNT, SIP_PAGE2_CALL_ONHOLD, sip_queue_hangup_cause(), sip_scheddestroy(), stop_media_flows(), stop_retrans_pkt(), transmit_response(), transmit_response_reliable(), UNLINK, update_call_counter(), and use_reason_header().

Referenced by handle_incoming().

27539 {
27540 
27541  check_via(p, req);
27542  sip_alreadygone(p);
27543 
27544  if (p->owner && ast_channel_state(p->owner) == AST_STATE_UP) {
27545  /* This call is up, cancel is ignored, we need a bye */
27546  transmit_response(p, "200 OK", req);
27547  ast_debug(1, "Got CANCEL on an answered call. Ignoring... \n");
27548  return 0;
27549  }
27550 
27551  use_reason_header(p, req);
27552 
27553  /* At this point, we could have cancelled the invite at the same time
27554  as the other side sends a CANCEL. Our final reply with error code
27555  might not have been received by the other side before the CANCEL
27556  was sent, so let's just give up retransmissions and waiting for
27557  ACK on our error code. The call is hanging up any way. */
27558  if (p->invitestate == INV_TERMINATED || p->invitestate == INV_COMPLETED) {
27559  __sip_pretend_ack(p);
27560  }
27561  if (p->invitestate != INV_TERMINATED)
27563 
27566 
27567  stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
27568  if (p->owner) {
27570  } else {
27572  }
27573  if (p->initreq.data && ast_str_strlen(p->initreq.data) > 0) {
27574  struct sip_pkt *pkt, *prev_pkt;
27575  /* If the CANCEL we are receiving is a retransmission, and we already have scheduled
27576  * a reliable 487, then we don't want to schedule another one on top of the previous
27577  * one.
27578  *
27579  * As odd as this may sound, we can't rely on the previously-transmitted "reliable"
27580  * response in this situation. What if we've sent all of our reliable responses
27581  * already and now all of a sudden, we get this second CANCEL?
27582  *
27583  * The only way to do this correctly is to cancel our previously-scheduled reliably-
27584  * transmitted response and send a new one in its place.
27585  */
27586  for (pkt = p->packets, prev_pkt = NULL; pkt; prev_pkt = pkt, pkt = pkt->next) {
27587  if (pkt->seqno == p->lastinvite && pkt->response_code == 487) {
27588  /* Unlink and destroy the packet object. */
27589  UNLINK(pkt, p->packets, prev_pkt);
27590  stop_retrans_pkt(pkt);
27591  ao2_t_ref(pkt, -1, "Packet retransmission list");
27592  break;
27593  }
27594  }
27595  transmit_response_reliable(p, "487 Request Terminated", &p->initreq);
27596  transmit_response(p, "200 OK", req);
27597  return 1;
27598  } else {
27599  transmit_response(p, "481 Call Leg Does Not Exist", req);
27600  return 0;
27601  }
27602 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
sip packet - raw format for outbound packets that are sent or scheduled for transmission Packets are ...
Definition: sip.h:1231
void __sip_pretend_ack(struct sip_pvt *p)
Pretend to ack all packets called with p locked.
Definition: chan_sip.c:4615
static void stop_retrans_pkt(struct sip_pkt *pkt)
Definition: chan_sip.c:4251
#define ast_test_flag(p, flag)
Definition: utils.h:63
int response_code
Definition: sip.h:1238
static void check_via(struct sip_pvt *p, const struct sip_request *req)
check Via: header for hostname, port and rport request/answer
Definition: chan_sip.c:19164
#define DEFAULT_TRANS_TIMEOUT
Definition: sip.h:107
uint32_t seqno
Definition: sip.h:1235
static void sip_alreadygone(struct sip_pvt *dialog)
Encapsulate setting of SIP_ALREADYGONE to be able to trace it with debugging.
Definition: chan_sip.c:3460
ast_channel_state
ast_channel states
Definition: channelstate.h:35
#define DEC_CALL_LIMIT
Definition: sip.h:127
#define SIP_PAGE2_CALL_ONHOLD
Definition: sip.h:351
struct ast_flags flags[3]
Definition: sip.h:1075
#define NULL
Definition: resample.c:96
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 th...
Definition: chan_sip.c:6844
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.
Definition: chan_sip.c:12688
static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req)
Transmit response, no retransmits.
Definition: chan_sip.c:12655
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define SIP_INC_COUNT
Definition: sip.h:265
static void sip_queue_hangup_cause(struct sip_pvt *p, int cause)
Definition: chan_sip.c:23981
struct sip_request initreq
Definition: sip.h:1151
struct ast_str * data
Definition: sip.h:843
struct sip_pkt * next
Definition: sip.h:1232
static void stop_media_flows(struct sip_pvt *p)
Immediately stop RTP, VRTP and UDPTL as applicable.
Definition: chan_sip.c:25156
struct ast_channel * owner
Definition: sip.h:1138
struct sip_pkt * packets
Definition: sip.h:1177
enum invitestates invitestate
Definition: sip.h:1007
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
static int use_reason_header(struct sip_pvt *pvt, struct sip_request *req)
Parses SIP reason header according to RFC3326 and sets channel&#39;s hangupcause if configured so and hea...
Definition: chan_sip.c:16841
#define UNLINK(element, head, prev)
Definition: chan_sip.c:1157
int ast_channel_hangupcause(const struct ast_channel *chan)
uint32_t lastinvite
Definition: sip.h:1074
void sip_scheddestroy(struct sip_pvt *p, int ms)
Schedule destruction of SIP dialog.
Definition: chan_sip.c:4549

◆ handle_request_do()

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

References ao2_t_ref, append_history, ast_callid_threadassoc_add(), ast_callid_threadassoc_remove(), 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(), sip_request::authenticated, sip_pvt::callid, copy_socket_data(), sip_request::data, sip_request::debug, sip_pvt::do_history, find_call, find_sip_method(), handle_incoming(), sip_request::headers, sip_request::lines, sip_pvt::logger_callid, lws2sws(), sip_request::method, netlock, NULL, sip_pvt::owner, parse_request(), sip_settings::pedanticsipchecking, sip_pvt::recv, REQ_OFFSET_TO_STR, sip_cfg, sip_debug_test_addr(), sip_get_header(), sip_get_transport(), sip_pvt_lock_full(), sip_pvt_unlock, sip_request::socket, sip_pvt::socket, and sip_socket::type.

Referenced by _sip_tcp_helper_thread(), sip_websocket_callback(), and sipsock_read().

29425 {
29426  struct sip_pvt *p;
29427  struct ast_channel *owner_chan_ref = NULL;
29428  int recount = 0;
29429  int nounlock = 0;
29430 
29431  if (sip_debug_test_addr(addr)) /* Set the debug flag early on packet level */
29432  req->debug = 1;
29434  lws2sws(req->data); /* Fix multiline headers */
29435  if (req->debug) {
29436  ast_verbose("\n<--- SIP read from %s:%s --->\n%s\n<------------->\n",
29438  }
29439 
29440  if (parse_request(req) == -1) { /* Bad packet, can't parse */
29441  ast_str_reset(req->data); /* nulling this out is NOT a good idea here. */
29442  return 1;
29443  }
29444  req->method = find_sip_method(REQ_OFFSET_TO_STR(req, rlpart1));
29445 
29446  if (req->debug)
29447  ast_verbose("--- (%d headers %d lines)%s ---\n", req->headers, req->lines, (req->headers + req->lines == 0) ? " Nat keepalive" : "");
29448 
29449  if (req->headers < 2) { /* Must have at least two headers */
29450  ast_str_reset(req->data); /* nulling this out is NOT a good idea here. */
29451  return 1;
29452  }
29454 
29455  /* Find the active SIP dialog or create a new one */
29456  p = find_call(req, addr, req->method); /* returns p with a reference only. _NOT_ locked*/
29457  if (p == NULL) {
29458  ast_debug(1, "Invalid SIP message - rejected , no callid, len %zu\n", ast_str_strlen(req->data));
29460  return 1;
29461  }
29462 
29463  if (p->logger_callid) {
29465  }
29466 
29467  /* Lock both the pvt and the owner if owner is present. This will
29468  * not fail. */
29469  owner_chan_ref = sip_pvt_lock_full(p);
29470 
29471  copy_socket_data(&p->socket, &req->socket);
29472 
29473  ast_sockaddr_copy(&p->recv, addr);
29474 
29475  /* if we have an owner, then this request has been authenticated */
29476  if (p->owner) {
29477  req->authenticated = 1;
29478  }
29479 
29480  if (p->do_history) /* This is a request or response, note what it was for */
29481  append_history(p, "Rx", "%s / %s / %s", ast_str_buffer(req->data), sip_get_header(req, "CSeq"), REQ_OFFSET_TO_STR(req, rlpart2));
29482 
29483  if (handle_incoming(p, req, addr, &recount, &nounlock) == -1) {
29484  /* Request failed */
29485  ast_debug(1, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>");
29486  }
29487 
29488  if (recount) {
29490  }
29491 
29492  if (p->owner && !nounlock) {
29494  }
29495  if (owner_chan_ref) {
29496  ast_channel_unref(owner_chan_ref);
29497  }
29498  sip_pvt_unlock(p);
29500 
29501  if (p->logger_callid) {
29503  }
29504  ao2_t_ref(p, -1, "throw away dialog ptr from find_call at end of routine"); /* p is gone after the return */
29505 
29506  return 1;
29507 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
ast_callid logger_callid
Definition: sip.h:1008
Main Channel structure associated with a channel.
char debug
Definition: sip.h:837
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:171
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
struct ast_sockaddr recv
Definition: sip.h:1135
struct sip_socket socket
Definition: sip.h:1066
static int sip_debug_test_addr(const struct ast_sockaddr *addr)
See if we pass debug IP filter.
Definition: chan_sip.c:3610
const char * sip_get_transport(enum ast_transport t)
Return transport as string.
Definition: chan_sip.c:3725
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)
Definition: chan_sip.c:29065
#define ast_mutex_lock(a)
Definition: lock.h:187
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
#define NULL
Definition: resample.c:96
void ast_update_use_count(void)
Notify when usecount has been changed.
Definition: loader.c:2528
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
int ast_callid_threadassoc_remove(void)
Removes callid from thread storage of the calling thread.
Definition: logger.c:2003
int ast_callid_threadassoc_add(ast_callid callid)
Adds a known callid to thread storage of the calling thread.
Definition: logger.c:1984
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static ast_mutex_t netlock
Definition: chan_sip.c:893
static void copy_socket_data(struct sip_socket *to_sock, const struct sip_socket *from_sock)
Definition: chan_sip.c:5952
char authenticated
Definition: sip.h:840
static void lws2sws(struct ast_str *msgbuf)
Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled...
Definition: chan_sip.c:9894
int pedanticsipchecking
Definition: sip.h:756
const ast_string_field callid
Definition: sip.h:1063
struct ast_str * data
Definition: sip.h:843
int method
Definition: sip.h:833
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
int headers
Definition: sip.h:832
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
static struct ast_channel * sip_pvt_lock_full(struct sip_pvt *pvt)
Definition: chan_sip.c:9400
#define ast_channel_unlock(chan)
Definition: channel.h:2946
unsigned short do_history
Definition: sip.h:1078
struct ast_channel * owner
Definition: sip.h:1138
#define REQ_OFFSET_TO_STR(req, offset)
Definition: sip.h:858
static int parse_request(struct sip_request *req)
Parse a SIP message.
Definition: chan_sip.c:9954
static int find_sip_method(const char *msg)
find_sip_method: Find SIP method from header
Definition: chan_sip.c:3594
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:653
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
enum ast_transport type
Definition: sip.h:798
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406
#define find_call(req, addr, intended_method)
Definition: chan_sip.c:1240
struct sip_socket socket
Definition: sip.h:846
int lines
Definition: sip.h:834
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ handle_request_info()

static void handle_request_info ( struct sip_pvt p,
struct sip_request req 
)
static

Receive SIP INFO Message.

Definition at line 22622 of file chan_sip.c.

References ast_cdr_setuserfield(), ast_channel_name(), AST_CONTROL_FLASH, AST_CONTROL_VIDUPDATE, ast_debug, AST_FEATURE_MAX_LEN, AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_get_feature(), ast_log, AST_LOG_WARNING, ast_queue_control(), ast_queue_frame(), ast_strlen_zero, ast_test_flag, ast_verbose(), buf, c, sip_pvt::callid, DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, get_content(), get_content_line(), ast_frame_subclass::integer, ast_frame::len, LOG_ERROR, LOG_WARNING, sip_pvt::owner, sip_peer::record_off_feature, sip_peer::record_on_feature, sip_pvt::relatedpeer, sip_get_header(), sip_scheddestroy(), SIP_USECLIENTCODE, sipdebug, ast_frame::subclass, tmp(), and transmit_response().

Referenced by handle_incoming().

22623 {
22624  const char *buf = "";
22625  unsigned int event;
22626  const char *c = sip_get_header(req, "Content-Type");
22627 
22628  /* Need to check the media/type */
22629 
22630  if (!strcasecmp(c, "application/hook-flash")) {
22631  /* send a FLASH event, for ATAs that send flash as hook-flash not dtmf */
22632  struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_FLASH, } };
22633  ast_queue_frame(p->owner, &f);
22634  if (sipdebug) {
22635  ast_verbose("* DTMF-relay event received: FLASH\n");
22636  }
22637  transmit_response(p, "200 OK", req);
22638  return;
22639  }
22640 
22641  if (!strcasecmp(c, "application/dtmf-relay") ||
22642  !strcasecmp(c, "application/vnd.nortelnetworks.digits") ||
22643  !strcasecmp(c, "application/dtmf")) {
22644  unsigned int duration = 0;
22645 
22646  if (!p->owner) { /* not a PBX call */
22647  transmit_response(p, "481 Call leg/transaction does not exist", req);
22649  return;
22650  }
22651 
22652  /* If dtmf-relay or vnd.nortelnetworks.digits, parse the signal and duration;
22653  * otherwise use the body as the signal */
22654  if (strcasecmp(c, "application/dtmf")) {
22655  const char *tmp;
22656 
22657  if (ast_strlen_zero(buf = get_content_line(req, "Signal", '='))
22658  && ast_strlen_zero(buf = get_content_line(req, "d", '='))) {
22659  ast_log(LOG_WARNING, "Unable to retrieve DTMF signal for INFO message on "
22660  "call %s\n", p->callid);
22661  transmit_response(p, "200 OK", req);
22662  return;
22663  }
22664  if (!ast_strlen_zero((tmp = get_content_line(req, "Duration", '=')))) {
22665  sscanf(tmp, "%30u", &duration);
22666  }
22667  } else {
22668  /* Type is application/dtmf, simply use what's in the message body */
22669  buf = get_content(req);
22670  }
22671 
22672  /* An empty message body requires us to send a 200 OK */
22673  if (ast_strlen_zero(buf)) {
22674  transmit_response(p, "200 OK", req);
22675  return;
22676  }
22677 
22678  if (!duration) {
22679  duration = 100; /* 100 ms */
22680  }
22681 
22682  if (buf[0] == '*') {
22683  event = 10;
22684  } else if (buf[0] == '#') {
22685  event = 11;
22686  } else if (buf[0] == '!') {
22687  event = 16;
22688  } else if ('A' <= buf[0] && buf[0] <= 'D') {
22689  event = 12 + buf[0] - 'A';
22690  } else if ('a' <= buf[0] && buf[0] <= 'd') {
22691  event = 12 + buf[0] - 'a';
22692  } else if ((sscanf(buf, "%30u", &event) != 1) || event > 16) {
22693  ast_log(AST_LOG_WARNING, "Unable to convert DTMF event signal code to a valid "
22694  "value for INFO message on call %s\n", p->callid);
22695  transmit_response(p, "200 OK", req);
22696  return;
22697  }
22698 
22699  if (event == 16) {
22700  /* send a FLASH event */
22701  struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_FLASH, } };
22702  ast_queue_frame(p->owner, &f);
22703  if (sipdebug) {
22704  ast_verbose("* DTMF-relay event received: FLASH\n");
22705  }
22706  } else {
22707  /* send a DTMF event */
22708  struct ast_frame f = { AST_FRAME_DTMF, };
22709  if (event < 10) {
22710  f.subclass.integer = '0' + event;
22711  } else if (event == 10) {
22712  f.subclass.integer = '*';
22713  } else if (event == 11) {
22714  f.subclass.integer = '#';
22715  } else {
22716  f.subclass.integer = 'A' + (event - 12);
22717  }
22718  f.len = duration;
22719  ast_queue_frame(p->owner, &f);
22720  if (sipdebug) {
22721  ast_verbose("* DTMF-relay event received: %c\n", (int) f.subclass.integer);
22722  }
22723  }
22724  transmit_response(p, "200 OK", req);
22725  return;
22726  } else if (!strcasecmp(c, "application/media_control+xml")) {
22727  /* Eh, we'll just assume it's a fast picture update for now */
22728  if (p->owner) {
22730  }
22731  transmit_response(p, "200 OK", req);
22732  return;
22733  } else if (!ast_strlen_zero(c = sip_get_header(req, "X-ClientCode"))) {
22734  /* Client code (from SNOM phone) */
22735  if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) {
22736  if (p->owner) {
22738  }
22739  transmit_response(p, "200 OK", req);
22740  } else {
22741  transmit_response(p, "403 Forbidden", req);
22742  }
22743  return;
22744  } else if (!ast_strlen_zero(c = sip_get_header(req, "Record"))) {
22745  /* INFO messages generated by some phones to start/stop recording
22746  * on phone calls.
22747  */
22748 
22749  char feat[AST_FEATURE_MAX_LEN];
22750  int feat_res = -1;
22751  int j;
22752  struct ast_frame f = { AST_FRAME_DTMF, };
22753  int suppress_warning = 0; /* Supress warning if the feature is blank */
22754 
22755  if (!p->owner) { /* not a PBX call */
22756  transmit_response(p, "481 Call leg/transaction does not exist", req);
22758  return;
22759  }
22760 
22761  /* first, get the feature string, if it exists */
22762  if (p->relatedpeer) {
22763  if (!strcasecmp(c, "on")) {
22765  suppress_warning = 1;
22766  } else {
22767  feat_res = ast_get_feature(p->owner, p->relatedpeer->record_on_feature, feat, sizeof(feat));
22768  }
22769  } else if (!strcasecmp(c, "off")) {
22771  suppress_warning = 1;
22772  } else {
22773  feat_res = ast_get_feature(p->owner, p->relatedpeer->record_off_feature, feat, sizeof(feat));
22774  }
22775  } else {
22776  ast_log(LOG_ERROR, "Received INFO requesting to record with invalid value: %s\n", c);
22777  }
22778  }
22779  if (feat_res || ast_strlen_zero(feat)) {
22780  if (!suppress_warning) {
22781  ast_log(LOG_WARNING, "Recording requested, but no One Touch Monitor registered. (See features.conf)\n");
22782  }
22783  /* 403 means that we don't support this feature, so don't request it again */
22784  transmit_response(p, "403 Forbidden", req);
22785  return;
22786  }
22787  /* Send the feature code to the PBX as DTMF, just like the handset had sent it */
22788  f.len = 100;
22789  for (j = 0; j < strlen(feat); j++) {
22790  f.subclass.integer = feat[j];
22791  ast_queue_frame(p->owner, &f);
22792  if (sipdebug) {
22793  ast_verbose("* DTMF-relay event faked: %c\n", f.subclass.integer);
22794  }
22795  }
22796 
22797  ast_debug(1, "Got a Request to Record the channel, state %s\n", c);
22798  transmit_response(p, "200 OK", req);
22799  return;
22800  } else if (ast_strlen_zero(c = sip_get_header(req, "Content-Length")) || !strcasecmp(c, "0")) {
22801  /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */
22802  transmit_response(p, "200 OK", req);
22803  return;
22804  }
22805 
22806  /* Other type of INFO message, not really understood by Asterisk */
22807 
22808  ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf);
22809  transmit_response(p, "415 Unsupported media type", req);
22810  return;
22811 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
Definition: channel.c:1231
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct sip_peer * relatedpeer
Definition: sip.h:1171
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static char * get_content_line(struct sip_request *req, char *name, char delimiter)
Get a specific line from the message content.
Definition: chan_sip.c:8489
#define LOG_WARNING
Definition: logger.h:274
#define DEFAULT_TRANS_TIMEOUT
Definition: sip.h:107
static int tmp()
Definition: bt_open.c:389
#define AST_LOG_WARNING
Definition: logger.h:279
Definition: astman.c:222
static struct test_val c
struct ast_flags flags[3]
Definition: sip.h:1075
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
#define AST_FRAME_DTMF
struct ast_frame_subclass subclass
#define ast_strlen_zero(foo)
Definition: strings.h:52
static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req)
Transmit response, no retransmits.
Definition: chan_sip.c:12655
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
int ast_get_feature(struct ast_channel *chan, const char *feature, char *buf, size_t len)
Get the DTMF code for a call feature.
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel&#39;s frame queue.
Definition: channel.c:1139
const ast_string_field callid
Definition: sip.h:1063
#define LOG_ERROR
Definition: logger.h:285
const ast_string_field record_on_feature
Definition: sip.h:1306
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
struct ast_channel * owner
Definition: sip.h:1138
void ast_cdr_setuserfield(const char *channel_name, const char *userfield)
Set CDR user field for channel (stored in CDR)
Definition: cdr.c:3477
const ast_string_field record_off_feature
Definition: sip.h:1306
#define SIP_USECLIENTCODE
Definition: sip.h:272
const char * ast_channel_name(const struct ast_channel *chan)
#define AST_FEATURE_MAX_LEN
Data structure associated with a single frame of data.
static char * get_content(struct sip_request *req)
Get message body content.
Definition: chan_sip.c:8610
void sip_scheddestroy(struct sip_pvt *p, int ms)
Schedule destruction of SIP dialog.
Definition: chan_sip.c:4549

◆ handle_request_invite()

static int handle_request_invite ( struct sip_pvt p,
struct sip_request req,
struct ast_sockaddr addr,
uint32_t  seqno,
int *  recount,
const char *  e,
int *  nounlock 
)
static

Handle incoming INVITE request.

Note
If the INVITE has a Replaces header, it is part of an attended transfer. If so, we do not go through the dial plan but try to find the active call and masquerade into it

This is a spiral. What we need to do is to just change the outgoing INVITE so that it now routes to the new Request URI. Since we created the INVITE ourselves that should be all we need to do.

Todo:
XXX This needs to be reviewed. YOu don't change the request URI really, you route the packet correctly instead...

Definition at line 26347 of file chan_sip.c.

References __get_header(), __sip_ack(), ao2_cleanup, append_history, ARRAY_LEN, AST_CAUSE_FAILURE, ast_cc_agent_set_interfaces_chanvar(), ast_channel_hangupcause_set(), ast_channel_name(), 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_UPDATE_RTP_PEER, ast_copy_string(), ast_debug, ast_format_cap_append_from_cap(), ast_format_cap_count(), ast_format_cap_remove_by_type(), ast_get_chan_features_pickup_config(), ast_hangup(), ast_log, AST_MAX_CONTEXT, AST_MAX_EXTENSION, AST_MEDIA_TYPE_UNKNOWN, 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_queue_control(), ast_queue_frame(), ast_queue_unhold(), ast_rtp_instance_set_prop(), AST_RTP_PROPERTY_DTMF, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_set_flag, ast_set_party_id_all(), ast_setstate(), ast_setup_cc_recall_datastore(), ast_skip_blanks(), ast_sockaddr_stringify(), AST_SRTP_CRYPTO_OFFER_OK, 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_uri_sip_user, ast_verbose(), AUTH_CHALLENGE_SENT, AUTH_SESSION_LIMIT, sip_request::authenticated, sip_pvt::autokillid, build_contact(), build_route(), c, sip_pvt::callid, sip_pvt::callingpres, sip_pvt::caps, change_hold_state(), change_redirecting_information(), check_user_full(), check_via(), sip_pvt::cid_name, sip_pvt::cid_num, sip_pvt::cid_tag, connected, context, sip_pvt::context, copy_request(), sip_request::debug, DEC_CALL_LIMIT, sip_settings::default_context, DEFAULT_TRANS_TIMEOUT, sip_pvt::do_history, do_magic_pickup(), error(), exten, sip_pvt::exten, extract_uri(), FALSE, find_sdp(), sip_pvt::flags, get_destination(), get_rpid(), get_sip_pvt_from_replaces(), sip_pvt::glareinvite, handle_invite_replaces(), handle_request_invite_st(), sip_request::headers, ast_party_connected_line::id, ast_set_party_connected_line::id, sip_request::ignore, INC_CALL_LIMIT, sip_pvt::initreq, INV_COMPLETED, INV_CONFIRMED, INV_PROCEEDING, INV_REQ_ERROR, INV_REQ_FAILED, INV_REQ_SUCCESS, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::jointcaps, sip_pvt::lastinvite, lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, sip_pvt::logger_callid, make_our_tag(), sip_request::method, ast_party_id::name, ast_set_party_id::name, NULL, ast_party_id::number, ast_set_party_id::number, sip_pvt::owner, parse_ok_contact(), parse_oli(), parse_sip_options(), sip_settings::pedanticsipchecking, sip_pvt::peername, sip_pvt::pendinginvite, ast_party_name::presentation, ast_party_number::presentation, ast_set_party_connected_line::priv, process_sdp(), RAII_VAR, sip_pvt::recv, sip_pvt::relatedpeer, REQ_OFFSET_TO_STR, sip_pvt::reqsipoptions, restart_session_timer(), result, sip_pvt::rtp, S_OR, SCOPED_LOCK, SDP_T38_INITIATE, send_check_user_failure_response(), sip_pvt::session_modify, set_pvt_allowed_methods(), sip_alreadygone(), sip_cancel_destroy(), sip_cfg, SIP_DTMF, SIP_DTMF_RFC2833, SIP_GET_DEST_EXTEN_FOUND, SIP_GET_DEST_EXTEN_MATCHMORE, SIP_GET_DEST_EXTEN_NOT_FOUND, SIP_GET_DEST_INVALID_URI, SIP_GET_DEST_REFUSED, sip_get_header(), SIP_INVITE, sip_methods, sip_new(), SIP_OUTGOING, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWOVERLAP_YES, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PAGE2_RFC2833_COMPENSATE, sip_pickup(), sip_pvt_lock, sip_pvt_unlock, sip_ref_peer, sip_refer_alloc(), sip_report_failed_acl(), sip_scheddestroy(), sip_unref_peer, sip_uri_cmp(), sipdebug, sip_pvt::sipoptions, ast_party_connected_line::source, sip_pvt::srtp, start_t38_abort_timer(), t38properties::state, sip_pvt::stimer, ast_party_name::str, ast_party_number::str, strcasestr(), strsep(), sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_PEER_REINVITE, T38_REJECTED, 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, update_call_counter(), update_redirecting(), sip_pvt::username, ast_party_name::valid, ast_party_number::valid, XMIT_CRITICAL, XMIT_RELIABLE, and XMIT_UNRELIABLE.

Referenced by handle_incoming().

26348 {
26349  int res = INV_REQ_SUCCESS;
26350  int gotdest;
26351  const char *p_replaces;
26352  char *replace_id = NULL;
26353  const char *required;
26354  unsigned int required_profile = 0;
26355  struct ast_channel *c = NULL; /* New channel */
26356  struct sip_peer *authpeer = NULL; /* Matching Peer */
26357  int reinvite = 0;
26358  struct ast_party_redirecting redirecting;
26360  int supported_start = 0;
26361  int require_start = 0;
26362  char unsupported[256] = { 0, };
26363  struct {
26364  char exten[AST_MAX_EXTENSION];
26365  char context[AST_MAX_CONTEXT];
26366  } pickup = {
26367  .exten = "",
26368  };
26369  RAII_VAR(struct sip_pvt *, replaces_pvt, NULL, ao2_cleanup);
26370  RAII_VAR(struct ast_channel *, replaces_chan, NULL, ao2_cleanup);
26371 
26372  /* Find out what they support */
26373  if (!p->sipoptions) {
26374  const char *supported = NULL;
26375  do {
26376  supported = __get_header(req, "Supported", &supported_start);
26377  if (!ast_strlen_zero(supported)) {
26378  p->sipoptions |= parse_sip_options(supported, NULL, 0);
26379  }
26380  } while (!ast_strlen_zero(supported));
26381  }
26382 
26383  /* Find out what they require */
26384  do {
26385  required = __get_header(req, "Require", &require_start);
26386  if (!ast_strlen_zero(required)) {
26387  required_profile |= parse_sip_options(required, unsupported, ARRAY_LEN(unsupported));
26388  }
26389  } while (!ast_strlen_zero(required));
26390 
26391  /* If there are any options required that we do not support,
26392  * then send a 420 with only those unsupported options listed */
26393  if (!ast_strlen_zero(unsupported)) {
26394  transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, unsupported);
26395  ast_log(LOG_WARNING, "Received SIP INVITE with unsupported required extension: %s\n", unsupported);
26397  if (!p->lastinvite) {
26399  }
26400  res = -1;
26401  goto request_invite_cleanup;
26402  }
26403 
26404 
26405  /* The option tags may be present in Supported: or Require: headers.
26406  Include the Require: option tags for further processing as well */
26407  p->sipoptions |= required_profile;
26408  p->reqsipoptions = required_profile;
26409 
26410  /* Check if this is a loop */
26412  /* This is a call to ourself. Send ourselves an error code and stop
26413  processing immediately, as SIP really has no good mechanism for
26414  being able to call yourself */
26415  /* If pedantic is on, we need to check the tags. If they're different, this is
26416  in fact a forked call through a SIP proxy somewhere. */
26417  int different;
26418  const char *initial_rlpart2 = REQ_OFFSET_TO_STR(&p->initreq, rlpart2);
26419  const char *this_rlpart2 = REQ_OFFSET_TO_STR(req, rlpart2);
26421  different = sip_uri_cmp(initial_rlpart2, this_rlpart2);
26422  else
26423  different = strcmp(initial_rlpart2, this_rlpart2);
26424  if (!different) {
26425  transmit_response(p, "482 Loop Detected", req);
26428  res = INV_REQ_FAILED;
26429  goto request_invite_cleanup;
26430  } else {
26431  /*! This is a spiral. What we need to do is to just change the outgoing INVITE
26432  * so that it now routes to the new Request URI. Since we created the INVITE ourselves
26433  * that should be all we need to do.
26434  *
26435  * \todo XXX This needs to be reviewed. YOu don't change the request URI really, you route the packet
26436  * correctly instead...
26437  */
26438  char *uri = ast_strdupa(this_rlpart2);
26439  char *at = strchr(uri, '@');
26440  char *peerorhost;
26441  ast_debug(2, "Potential spiral detected. Original RURI was %s, new RURI is %s\n", initial_rlpart2, this_rlpart2);
26442  transmit_response(p, "100 Trying", req);
26443  if (at) {
26444  *at = '\0';
26445  }
26446  /* Parse out "sip:" */
26447  if ((peerorhost = strchr(uri, ':'))) {
26448  *peerorhost++ = '\0';
26449  }
26450  ast_string_field_set(p, theirtag, NULL);
26451  /* Treat this as if there were a call forward instead...
26452  */
26453  ast_channel_call_forward_set(p->owner, peerorhost);
26455  res = INV_REQ_FAILED;
26456  goto request_invite_cleanup;
26457  }
26458  }
26459 
26460  if (!req->ignore && p->pendinginvite) {
26462  /* What do these circumstances mean? We have received an INVITE for an "incoming" dialog for which we
26463  * have sent a final response. We have not yet received an ACK, though (which is why p->pendinginvite is non-zero).
26464  * We also know that the INVITE is not a retransmission, because otherwise the "ignore" flag would be set.
26465  * This means that either we are receiving a reinvite for a terminated dialog, or we are receiving an INVITE with
26466  * credentials based on one we challenged earlier.
26467  *
26468  * The action to take in either case is to treat the INVITE as though it contains an implicit ACK for the previous
26469  * transaction. Calling __sip_ack will take care of this by clearing the p->pendinginvite and removing the response
26470  * from the previous transaction from the list of outstanding packets.
26471  */
26472  __sip_ack(p, p->pendinginvite, 1, 0);
26473  } else {
26474  /* We already have a pending invite. Sorry. You are on hold. */
26475  p->glareinvite = seqno;
26476  transmit_response_reliable(p, "491 Request Pending", req);
26477  check_via(p, req);
26478  ast_debug(1, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid);
26479  /* Don't destroy dialog here */
26480  res = INV_REQ_FAILED;
26481  goto request_invite_cleanup;
26482  }
26483  }
26484 
26485  p_replaces = sip_get_header(req, "Replaces");
26486  if (!ast_strlen_zero(p_replaces)) {
26487  /* We have a replaces header */
26488  char *ptr;
26489  char *fromtag = NULL;
26490  char *totag = NULL;
26491  char *start, *to;
26492  int error = 0;
26493 
26494  if (p->owner) {
26495  ast_debug(3, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid);
26496  transmit_response_reliable(p, "400 Bad request", req); /* The best way to not accept the transfer */
26497  check_via(p, req);
26498  copy_request(&p->initreq, req);
26499  /* Do not destroy existing call */
26500  res = INV_REQ_ERROR;
26501  goto request_invite_cleanup;
26502  }
26503 
26504  if (sipdebug)
26505  ast_debug(3, "INVITE part of call transfer. Replaces [%s]\n", p_replaces);
26506  /* Create a buffer we can manipulate */
26507  replace_id = ast_strdupa(p_replaces);
26508  ast_uri_decode(replace_id, ast_uri_sip_user);
26509 
26510  if (!sip_refer_alloc(p)) {
26511  transmit_response_reliable(p, "500 Server Internal Error", req);
26512  append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory.");
26515  res = INV_REQ_ERROR;
26516  check_via(p, req);
26517  copy_request(&p->initreq, req);
26518  goto request_invite_cleanup;
26519  }
26520 
26521  /* Todo: (When we find phones that support this)
26522  if the replaces header contains ";early-only"
26523  we can only replace the call in early
26524  stage, not after it's up.
26525 
26526  If it's not in early mode, 486 Busy.
26527  */
26528 
26529  /* Skip leading whitespace */
26530  replace_id = ast_skip_blanks(replace_id);
26531 
26532  start = replace_id;
26533  while ( (ptr = strsep(&start, ";")) ) {
26534  ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */
26535  if ( (to = strcasestr(ptr, "to-tag=") ) )
26536  totag = to + 7; /* skip the keyword */
26537  else if ( (to = strcasestr(ptr, "from-tag=") ) ) {
26538  fromtag = to + 9; /* skip the keyword */
26539  fromtag = strsep(&fromtag, "&"); /* trim what ? */
26540  }
26541  }
26542 
26543  if (sipdebug)
26544  ast_debug(4, "Invite/replaces: Will use Replace-Call-ID : %s Fromtag: %s Totag: %s\n",
26545  replace_id,
26546  fromtag ? fromtag : "<no from tag>",
26547  totag ? totag : "<no to tag>");
26548 
26549  /* Try to find call that we are replacing.
26550  If we have a Replaces header, we need to cancel that call if we succeed with this call.
26551  First we cheat a little and look for a magic call-id from phones that support
26552  dialog-info+xml so we can do technology independent pickup... */
26553  if (strncmp(replace_id, "pickup-", 7) == 0) {
26554  RAII_VAR(struct sip_pvt *, subscription, NULL, ao2_cleanup);
26555  RAII_VAR(struct ast_channel *, subscription_chan, NULL, ao2_cleanup);
26556 
26557  replace_id += 7; /* Worst case we are looking at \0 */
26558 
26559  if (get_sip_pvt_from_replaces(replace_id, totag, fromtag, &subscription, &subscription_chan)) {
26560  ast_log(LOG_NOTICE, "Unable to find subscription with call-id: %s\n", replace_id);
26561  transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replaces)", req);
26562  error = 1;
26563  } else {
26564  SCOPED_LOCK(lock, subscription, sip_pvt_lock, sip_pvt_unlock);
26565  ast_log(LOG_NOTICE, "Trying to pick up %s@%s\n", subscription->exten, subscription->context);
26566  ast_copy_string(pickup.exten, subscription->exten, sizeof(pickup.exten));
26567  ast_copy_string(pickup.context, subscription->context, sizeof(pickup.context));
26568  }
26569  }
26570 
26571  if (!error && ast_strlen_zero(pickup.exten) && get_sip_pvt_from_replaces(replace_id,
26572  totag, fromtag, &replaces_pvt, &replaces_chan)) {
26573  ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id);
26574  transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replaces)", req);
26575  error = 1;
26576  }
26577 
26578  /* The matched call is the call from the transferer to Asterisk .
26579  We want to bridge the bridged part of the call to the
26580  incoming invite, thus taking over the refered call */
26581 
26582  if (replaces_pvt == p) {
26583  ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid);
26584  transmit_response_reliable(p, "400 Bad request", req); /* The best way to not accept the transfer */
26585  error = 1;
26586  }
26587 
26588  if (!error && ast_strlen_zero(pickup.exten) && !replaces_chan) {
26589  /* Oops, someting wrong anyway, no owner, no call */
26590  ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id);
26591  /* Check for better return code */
26592  transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replace)", req);
26593  error = 1;
26594  }
26595 
26596  if (!error && ast_strlen_zero(pickup.exten) &&
26597  ast_channel_state(replaces_chan) != AST_STATE_RINGING &&
26598  ast_channel_state(replaces_chan) != AST_STATE_RING &&
26599  ast_channel_state(replaces_chan) != AST_STATE_UP) {
26600  ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id);
26601  transmit_response_reliable(p, "603 Declined (Replaces)", req);
26602  error = 1;
26603  }
26604 
26605  if (error) { /* Give up this dialog */
26606  append_history(p, "Xfer", "INVITE/Replace Failed.");
26609  res = INV_REQ_ERROR;
26610  check_via(p, req);
26611  copy_request(&p->initreq, req);
26612  goto request_invite_cleanup;
26613  }
26614  }
26615 
26616  /* Check if this is an INVITE that sets up a new dialog or
26617  a re-invite in an existing dialog */
26618 
26619  if (!req->ignore) {
26620  int newcall = (p->initreq.headers ? TRUE : FALSE);
26621 
26622  sip_cancel_destroy(p);
26623 
26624  /* This also counts as a pending invite */
26625  p->pendinginvite = seqno;
26626  check_via(p, req);
26627 
26628  copy_request(&p->initreq, req); /* Save this INVITE as the transaction basis */
26629  if (sipdebug)
26630  ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid);
26631 
26632  /* Parse new contact both for existing (re-invite) and new calls. */
26633  parse_ok_contact(p, req);
26634 
26635  if (!p->owner) { /* Not a re-invite */
26636  if (req->debug)
26637  ast_verbose("Using INVITE request as basis request - %s\n", p->callid);
26638  if (newcall)
26639  append_history(p, "Invite", "New call: %s", p->callid);
26640  } else { /* Re-invite on existing call */
26641  ast_clear_flag(&p->flags[0], SIP_OUTGOING); /* This is now an inbound dialog */
26642  if (get_rpid(p, req)) {
26644  struct ast_set_party_connected_line update_connected;
26645 
26647  memset(&update_connected, 0, sizeof(update_connected));
26648 
26649  update_connected.id.number = 1;
26650  connected.id.number.valid = 1;
26651  connected.id.number.str = (char *) p->cid_num;
26652  connected.id.number.presentation = p->callingpres;
26653 
26654  update_connected.id.name = 1;
26655  connected.id.name.valid = 1;
26656  connected.id.name.str = (char *) p->cid_name;
26657  connected.id.name.presentation = p->callingpres;
26658 
26659  /* Invalidate any earlier private connected id representation */
26660  ast_set_party_id_all(&update_connected.priv);
26661 
26662  connected.id.tag = (char *) p->cid_tag;
26665  &update_connected);
26666  }
26667  /* Handle SDP here if we already have an owner */
26668  if (find_sdp(req)) {
26669  if (process_sdp(p, req, SDP_T38_INITIATE, TRUE)) {
26670  if (!ast_strlen_zero(sip_get_header(req, "Content-Encoding"))) {
26671  /* Asterisk does not yet support any Content-Encoding methods. Always
26672  * attempt to process the sdp, but return a 415 if a Content-Encoding header
26673  * was present after processing failed. */
26674  transmit_response_reliable(p, "415 Unsupported Media type", req);
26675  } else {
26676  transmit_response_reliable(p, "488 Not acceptable here", req);
26677  }
26678  if (!p->lastinvite)
26680  res = INV_REQ_ERROR;
26681  goto request_invite_cleanup;
26682  }
26684  } else {
26687  ast_debug(1, "Hm.... No sdp for the moment\n");
26688  /* Some devices signal they want to be put off hold by sending a re-invite
26689  *without* an SDP, which is supposed to mean "Go back to your state"
26690  and since they put os on remote hold, we go back to off hold */
26691  if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
26692  ast_queue_unhold(p->owner);
26693  /* Activate a re-invite */
26695  change_hold_state(p, req, FALSE, 0);
26696  }
26697  }
26698  if (p->do_history) /* This is a response, note what it was for */
26699  append_history(p, "ReInv", "Re-invite received");
26700  }
26701  } else if (req->debug)
26702  ast_verbose("Ignoring this INVITE request\n");
26703 
26704  if (!p->lastinvite && !req->ignore && !p->owner) {
26705  /* This is a new invite */
26706  /* Handle authentication if this is our first invite */
26707  int cc_recall_core_id = -1;
26708  set_pvt_allowed_methods(p, req);
26709  res = check_user_full(p, req, SIP_INVITE, e, XMIT_RELIABLE, addr, &authpeer);
26710  if (res == AUTH_CHALLENGE_SENT) {
26711  p->invitestate = INV_COMPLETED; /* Needs to restart in another INVITE transaction */
26712  goto request_invite_cleanup;
26713  }
26714  if (res < 0) { /* Something failed in authentication */
26718  goto request_invite_cleanup;
26719  }
26720 
26721  /* Successful authentication and peer matching so record the peer related to this pvt (for easy access to peer settings) */
26722  if (p->relatedpeer) {
26723  p->relatedpeer = sip_unref_peer(p->relatedpeer,"unsetting the relatedpeer field in the dialog, before it is set to something else.");
26724  }
26725  if (authpeer) {
26726  p->relatedpeer = sip_ref_peer(authpeer, "setting dialog's relatedpeer pointer");
26727  }
26728 
26729  req->authenticated = 1;
26730 
26731  /* We have a successful authentication, process the SDP portion if there is one */
26732  if (find_sdp(req)) {
26733  if (process_sdp(p, req, SDP_T38_INITIATE, TRUE)) {
26734  /* Asterisk does not yet support any Content-Encoding methods. Always
26735  * attempt to process the sdp, but return a 415 if a Content-Encoding header
26736  * was present after processing fails. */
26737  if (!ast_strlen_zero(sip_get_header(req, "Content-Encoding"))) {
26738  transmit_response_reliable(p, "415 Unsupported Media type", req);
26739  } else {
26740  /* Unacceptable codecs */
26741  transmit_response_reliable(p, "488 Not acceptable here", req);
26742  }
26745  ast_debug(1, "No compatible codecs for this SIP call.\n");
26746  res = INV_REQ_ERROR;
26747  goto request_invite_cleanup;
26748  }
26749  } else { /* No SDP in invite, call control session */
26752  ast_debug(2, "No SDP in Invite, third party call control\n");
26753  }
26754 
26755  /* Initialize the context if it hasn't been already */
26756  if (ast_strlen_zero(p->context))
26758 
26759 
26760  /* Check number of concurrent calls -vs- incoming limit HERE */
26761  ast_debug(1, "Checking SIP call limits for device %s\n", p->username);
26762  if ((res = update_call_counter(p, INC_CALL_LIMIT))) {
26763  if (res < 0) {
26764  ast_log(LOG_NOTICE, "Failed to place call for device %s, too many calls\n", p->username);
26765  transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req);
26768 
26769  res = AUTH_SESSION_LIMIT;
26770  }
26771 
26772  goto request_invite_cleanup;
26773  }
26774  gotdest = get_destination(p, NULL, &cc_recall_core_id); /* Get destination right away */
26775  extract_uri(p, req); /* Get the Contact URI */
26776  build_contact(p, req, 1); /* Build our contact header */
26777 
26778  if (p->rtp) {
26781  }
26782 
26783  if (!replace_id && (gotdest != SIP_GET_DEST_EXTEN_FOUND)) { /* No matching extension found */
26784  switch(gotdest) {
26786  transmit_response_reliable(p, "416 Unsupported URI scheme", req);
26787  break;
26791  transmit_response_reliable(p, "484 Address Incomplete", req);
26792  break;
26793  }
26794  /*
26795  * XXX We would have to implement collecting more digits in
26796  * chan_sip for any other schemes of overlap dialing.
26797  *
26798  * For SIP_PAGE2_ALLOWOVERLAP_DTMF it is better to do this in
26799  * the dialplan using the Incomplete application rather than
26800  * having the channel driver do it.
26801  */
26802  /* Fall through */
26804  {
26805  char *decoded_exten = ast_strdupa(p->exten);
26806  transmit_response_reliable(p, "404 Not Found", req);
26807  ast_uri_decode(decoded_exten, ast_uri_sip_user);
26808  ast_log(LOG_NOTICE, "Call from '%s' (%s) to extension"
26809  " '%s' rejected because extension not found in context '%s'.\n",
26810  S_OR(p->username, p->peername), ast_sockaddr_stringify(&p->recv), decoded_exten, p->context);
26811  sip_report_failed_acl(p, "no_extension_match");
26812  }
26813  break;
26814  case SIP_GET_DEST_REFUSED:
26815  default:
26816  transmit_response_reliable(p, "403 Forbidden", req);
26817  } /* end switch */
26818 
26822  res = INV_REQ_FAILED;
26823  goto request_invite_cleanup;
26824  } else {
26825  /* If no extension was specified, use the s one */
26826  /* Basically for calling to IP/Host name only */
26827  if (ast_strlen_zero(p->exten))
26828  ast_string_field_set(p, exten, "s");
26829  /* Initialize our tag */
26830 
26831  make_our_tag(p);
26832 
26833  if (handle_request_invite_st(p, req, reinvite)) {
26836  res = INV_REQ_ERROR;
26837  goto request_invite_cleanup;
26838  }
26839 
26840  /* First invitation - create the channel. Allocation
26841  * failures are handled below. */
26842 
26844 
26845  if (cc_recall_core_id != -1) {
26846  ast_setup_cc_recall_datastore(c, cc_recall_core_id);
26848  }
26849  *recount = 1;
26850 
26851  /* Save Record-Route for any later requests we make on this dialogue */
26852  build_route(p, req, 0, 0);
26853 
26854  if (c) {
26855  ast_party_redirecting_init(&redirecting);
26856  memset(&update_redirecting, 0, sizeof(update_redirecting));
26857  change_redirecting_information(p, req, &redirecting, &update_redirecting,
26858  FALSE); /*Will return immediately if no Diversion header is present */
26860  ast_party_redirecting_free(&redirecting);
26861  }
26862  }
26863  } else {
26864  ast_party_redirecting_init(&redirecting);
26865  memset(&update_redirecting, 0, sizeof(update_redirecting));
26866  if (sipdebug) {
26867  if (!req->ignore)
26868  ast_debug(2, "Got a SIP re-invite for call %s\n", p->callid);
26869  else
26870  ast_debug(2, "Got a SIP re-transmit of INVITE for call %s\n", p->callid);
26871  }
26872  if (!req->ignore)
26873  reinvite = 1;
26874 
26875  if (handle_request_invite_st(p, req, reinvite)) {
26877  if (!p->lastinvite) {
26879  }
26880  res = INV_REQ_ERROR;
26881  goto request_invite_cleanup;
26882  }
26883 
26884  c = p->owner;
26885  change_redirecting_information(p, req, &redirecting, &update_redirecting, FALSE); /*Will return immediately if no Diversion header is present */
26886  if (c) {
26888  }
26889  ast_party_redirecting_free(&redirecting);
26890  }
26891 
26892  /* Check if OLI/ANI-II is present in From: */
26893  parse_oli(req, p->owner);
26894 
26895  if (reinvite && p->stimer) {
26897  }
26898 
26899  if (!req->ignore && p)
26900  p->lastinvite = seqno;
26901 
26902  if (c && replace_id) { /* Attended transfer or call pickup - we're the target */
26903  if (!ast_strlen_zero(pickup.exten)) {
26904  append_history(p, "Xfer", "INVITE/Replace received");
26905 
26906  /* Let the caller know we're giving it a shot */
26907  transmit_response(p, "100 Trying", req);
26910 
26911  /* Do the pickup itself */
26912  ast_channel_unlock(c);
26913  *nounlock = 1;
26914 
26915  /* since p->owner (c) is unlocked, we need to go ahead and unlock pvt for both
26916  * magic pickup and ast_hangup. Both of these functions will attempt to lock
26917  * p->owner again, which can cause a deadlock if we already hold a lock on p.
26918  * Locking order is, channel then pvt. Dead lock avoidance must be used if
26919  * called the other way around. */
26920  sip_pvt_unlock(p);
26921  do_magic_pickup(c, pickup.exten, pickup.context);
26922  /* Now we're either masqueraded or we failed to pickup, in either case we... */
26923  ast_hangup(c);
26924  sip_pvt_lock(p); /* pvt is expected to remain locked on return, so re-lock it */
26925 
26926  res = INV_REQ_FAILED;
26927  goto request_invite_cleanup;
26928  } else {
26929  /* Go and take over the target call */
26930  if (sipdebug)
26931  ast_debug(4, "Sending this call to the invite/replaces handler %s\n", p->callid);
26932  res = handle_invite_replaces(p, req, nounlock, replaces_pvt, replaces_chan);
26933  goto request_invite_cleanup;
26934  }
26935  }
26936 
26937 
26938  if (c) { /* We have a call -either a new call or an old one (RE-INVITE) */
26939  enum ast_channel_state c_state = ast_channel_state(c);
26941  const char *pickupexten;
26942 
26943  if (!pickup_cfg) {
26944  ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
26945  pickupexten = "";
26946  } else {
26947  pickupexten = ast_strdupa(pickup_cfg->pickupexten);
26948  }
26949 
26950  if (c_state != AST_STATE_UP && reinvite &&
26952  /* If these conditions are true, and the channel is still in the 'ringing'
26953  * state, then this likely means that we have a situation where the initial
26954  * INVITE transaction has completed *but* the channel's state has not yet been
26955  * changed to UP. The reason this could happen is if the reinvite is received
26956  * on the SIP socket prior to an application calling ast_read on this channel
26957  * to read the answer frame we earlier queued on it. In this case, the reinvite
26958  * is completely legitimate so we need to handle this the same as if the channel
26959  * were already UP. Thus we are purposely falling through to the AST_STATE_UP case.
26960  */
26961  c_state = AST_STATE_UP;
26962  }
26963 
26964  switch(c_state) {
26965  case AST_STATE_DOWN:
26966  ast_debug(2, "%s: New call is still down.... Trying... \n", ast_channel_name(c));
26967  transmit_provisional_response(p, "100 Trying", req, 0);
26970  if (strcmp(p->exten, pickupexten)) { /* Call to extension -start pbx on this call */
26971  enum ast_pbx_result result;
26972 
26973  result = ast_pbx_start(c);
26974 
26975  switch(result) {
26976  case AST_PBX_FAILED:
26977  sip_alreadygone(p);
26978  ast_log(LOG_WARNING, "Failed to start PBX :(\n");
26980  transmit_response_reliable(p, "503 Unavailable", req);
26981  break;
26982  case AST_PBX_CALL_LIMIT:
26983  sip_alreadygone(p);
26984  ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n");
26986  transmit_response_reliable(p, "480 Temporarily Unavailable", req);
26987  res = AUTH_SESSION_LIMIT;
26988  break;
26989  case AST_PBX_SUCCESS:
26990  /* nothing to do */
26991  break;
26992  }
26993 
26994  if (result) {
26995 
26996  /* Unlock locks so ast_hangup can do its magic */
26997  ast_channel_unlock(c);
26998  *nounlock = 1;
26999  sip_pvt_unlock(p);
27000  ast_hangup(c);
27001  sip_pvt_lock(p);
27002  c = NULL;
27003  }
27004  } else { /* Pickup call in call group */
27005  if (sip_pickup(c)) {
27006  ast_log(LOG_WARNING, "Failed to start Group pickup by %s\n", ast_channel_name(c));
27007  transmit_response_reliable(p, "480 Temporarily Unavailable", req);
27008  sip_alreadygone(p);
27010 
27011  /* Unlock locks so ast_hangup can do its magic */
27012  ast_channel_unlock(c);
27013  *nounlock = 1;
27014 
27016  sip_pvt_unlock(p);
27017  ast_hangup(c);
27018  sip_pvt_lock(p);
27019  c = NULL;
27020  }
27021  }
27022  break;
27023  case AST_STATE_RING:
27024  transmit_provisional_response(p, "100 Trying", req, 0);
27026  break;
27027  case AST_STATE_RINGING:
27028  transmit_provisional_response(p, "180 Ringing", req, 0);
27030  break;
27031  case AST_STATE_UP:
27032  ast_debug(2, "%s: This call is UP.... \n", ast_channel_name(c));
27033 
27034  transmit_response(p, "100 Trying", req);
27035 
27036  if (p->t38.state == T38_PEER_REINVITE) {
27038  } else if (p->t38.state == T38_ENABLED) {
27040  transmit_response_with_t38_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (req->ignore ? XMIT_UNRELIABLE : XMIT_CRITICAL)));
27041  } else if ((p->t38.state == T38_DISABLED) || (p->t38.state == T38_REJECTED)) {
27042  /* If this is not a re-invite or something to ignore - it's critical */
27043  if (p->srtp && !ast_test_flag(p->srtp, AST_SRTP_CRYPTO_OFFER_OK)) {
27044  ast_log(LOG_WARNING, "Target does not support required crypto\n");
27045  transmit_response_reliable(p, "488 Not Acceptable Here (crypto)", req);
27046  } else {
27048  transmit_response_with_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (req->ignore ? XMIT_UNRELIABLE : XMIT_CRITICAL)), p->session_modify == TRUE ? FALSE : TRUE, FALSE);
27050  }
27051  }
27052 
27054  break;
27055  default:
27056  ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %u\n", ast_channel_state(c));
27057  transmit_response(p, "100 Trying", req);
27058  break;
27059  }
27060  } else {
27061  if (!req->ignore && p && (p->autokillid == -1)) {
27062  const char *msg;
27063 
27064  if ((!ast_format_cap_count(p->jointcaps)))
27065  msg = "488 Not Acceptable Here (codec error)";
27066  else {
27067  ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n");
27068  msg = "503 Unavailable";
27069  }
27070  transmit_response_reliable(p, msg, req);
27073  }
27074  }
27075 
27076 request_invite_cleanup:
27077 
27078  if (authpeer) {
27079  authpeer = sip_unref_peer(authpeer, "sip_unref_peer, from handle_request_invite authpeer");
27080  }
27081 
27082  return res;
27083 }
void ast_uri_decode(char *s, struct ast_flags spec)
Decode URI, URN, URL (overwrite string)
Definition: main/utils.c:616
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
ast_callid logger_callid
Definition: sip.h:1008
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
Definition: channel.c:2022
uint32_t glareinvite
Definition: sip.h:1148
#define T38_ENABLED
Definition: chan_ooh323.c:102
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
Main Channel structure associated with a channel.
char debug
Definition: sip.h:837
static void send_check_user_failure_response(struct sip_pvt *p, struct sip_request *req, int res, enum xmittype reliable)
Definition: chan_sip.c:19626
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 fou...
Definition: chan_sip.c:18266
#define FALSE
Definition: app_minivm.c:521
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
struct ast_features_pickup_config * ast_get_chan_features_pickup_config(struct ast_channel *chan)
Get the pickup configuration options for a channel.
static void start_t38_abort_timer(struct sip_pvt *pvt)
Definition: chan_sip.c:26144
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
Definition: channel.c:1231
static int sip_refer_alloc(struct sip_pvt *p)
Allocate SIP refer structure.
Definition: chan_sip.c:16370
enum t38state state
Definition: sip.h:917
#define ast_test_flag(p, flag)
Definition: utils.h:63
static const struct cfsip_methods sip_methods[]
struct sip_peer * relatedpeer
Definition: sip.h:1171
int autokillid
Definition: sip.h:1158
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
int ast_queue_unhold(struct ast_channel *chan)
Queue an unhold frame.
Definition: channel.c:1216
static int handle_invite_replaces(struct sip_pvt *p, struct sip_request *req, int *nounlock, struct sip_pvt *replaces_pvt, struct ast_channel *replaces_chan)
Handle the transfer part of INVITE with a replaces: header,.
Definition: chan_sip.c:25984
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define LOG_WARNING
Definition: logger.h:274
uint32_t pendinginvite
Definition: sip.h:1147
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition: pbx.c:4712
static void check_via(struct sip_pvt *p, const struct sip_request *req)
check Via: header for hostname, port and rport request/answer
Definition: chan_sip.c:19164
struct ast_sockaddr recv
Definition: sip.h:1135
#define DEFAULT_TRANS_TIMEOUT
Definition: sip.h:107
static void sip_alreadygone(struct sip_pvt *dialog)
Encapsulate setting of SIP_ALREADYGONE to be able to trace it with debugging.
Definition: chan_sip.c:3460
#define SIP_DTMF_RFC2833
Definition: sip.h:276
const ast_string_field username
Definition: sip.h:1063
ast_channel_state
ast_channel states
Definition: channelstate.h:35
struct ast_format_cap * jointcaps
Definition: sip.h:1100
#define DEC_CALL_LIMIT
Definition: sip.h:127
size_t ast_format_cap_count(const struct ast_format_cap *cap)
Get the number of formats present within the capabilities structure.
Definition: format_cap.c:395
#define SIP_PAGE2_CALL_ONHOLD
Definition: sip.h:351
static struct test_val c
struct ast_flags flags[3]
Definition: sip.h:1075
const ast_string_field context
Definition: sip.h:1063
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
#define SIP_PAGE2_RFC2833_COMPENSATE
Definition: sip.h:356
int sip_uri_cmp(const char *input1, const char *input2)
Compare two URIs as described in RFC 3261 Section 19.1.4.
#define NULL
Definition: resample.c:96
#define sip_ref_peer(peer, tag)
Definition: sip.h:1894
void sip_report_failed_acl(const struct sip_pvt *p, const char *aclname)
static void make_our_tag(struct sip_pvt *pvt)
Make our SIP dialog tag.
Definition: chan_sip.c:8908
static void build_route(struct sip_pvt *p, struct sip_request *req, int backwards, int resp)
Build route list from Record-Route header.
Definition: chan_sip.c:17201
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
struct t38properties t38
Definition: sip.h:1113
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 th...
Definition: chan_sip.c:6844
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
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.
Definition: chan_sip.c:12688
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 u...
Definition: chan_sip.c:19486
static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req)
Transmit response, no retransmits.
Definition: chan_sip.c:12655
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: chan_sip.c:4570
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
Definition: chan_sip.c:23528
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
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.
Definition: chan_sip.c:14125
void ast_channel_queue_connected_line_update(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Queue a connected line update frame on a channel.
Definition: channel.c:9202
int ast_cc_agent_set_interfaces_chanvar(struct ast_channel *chan)
Set the first level CC_INTERFACES channel variable for a channel.
Definition: ccss.c:3631
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
int ast_setup_cc_recall_datastore(struct ast_channel *chan, const int core_id)
Set up a CC recall datastore on a channel.
Definition: ccss.c:3405
static int do_magic_pickup(struct ast_channel *channel, const char *extension, const char *context)
Definition: chan_sip.c:26048
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.
Definition: chan_sip.c:18508
struct ast_format_cap * caps
Definition: sip.h:1099
struct sip_request initreq
Definition: sip.h:1151
ast_mutex_t lock
Definition: app_meetme.c:1091
#define AST_MAX_EXTENSION
Definition: channel.h:135
static void restart_session_timer(struct sip_pvt *p)
Session-Timers: Restart session timer.
Definition: chan_sip.c:30278
static void copy_request(struct sip_request *dst, const struct sip_request *src)
copy SIP request (mostly used to save request for responses)
Definition: chan_sip.c:14061
static int find_sdp(struct sip_request *req)
Determine whether a SIP message contains an SDP in its body.
Definition: chan_sip.c:10054
const ast_string_field exten
Definition: sip.h:1063
#define AST_SRTP_CRYPTO_OFFER_OK
Definition: sdp_srtp.h:44
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static struct ast_channel * sip_new(struct sip_pvt *i, int state, const char *title, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, ast_callid callid)
Initiate a call in the SIP channel.
Definition: chan_sip.c:8161
static void extract_uri(struct sip_pvt *p, struct sip_request *req)
Check Contact: URI of SIP message.
Definition: chan_sip.c:14289
#define SCOPED_LOCK(varname, lock, lockfunc, unlockfunc)
Scoped Locks.
Definition: lock.h:581
void ast_channel_set_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
Set the redirecting id information in the Asterisk channel.
Definition: channel.c:9215
char authenticated
Definition: sip.h:840
int callingpres
Definition: sip.h:1117
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel&#39;s frame queue.
Definition: channel.c:1139
int pedanticsipchecking
Definition: sip.h:756
ast_pbx_result
The result codes when starting the PBX on a channel with ast_pbx_start.
Definition: pbx.h:354
void ast_format_cap_remove_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Remove all formats matching a specific format type.
Definition: format_cap.c:525
#define AST_CAUSE_FAILURE
Definition: causes.h:149
static const char * __get_header(const struct sip_request *req, const char *name, int *start)
Definition: chan_sip.c:8562
#define SIP_PAGE2_ALLOWOVERLAP
Definition: sip.h:337
#define SIP_PAGE2_ALLOWOVERLAP_YES
Definition: sip.h:339
const ast_string_field callid
Definition: sip.h:1063
#define LOG_ERROR
Definition: logger.h:285
const ast_string_field cid_num
Definition: sip.h:1063
struct sip_st_dlg * stimer
Definition: sip.h:1184
static int get_sip_pvt_from_replaces(const char *callid, const char *totag, const char *fromtag, struct sip_pvt **out_pvt, struct ast_channel **out_chan)
Find a companion dialog based on Replaces information.
Definition: chan_sip.c:18693
#define T38_DISABLED
Definition: chan_ooh323.c:101
int method
Definition: sip.h:833
static int sip_pickup(struct ast_channel *chan)
Pickup a call using the subsystem in features.c This is executed in a separate thread.
Definition: chan_sip.c:25634
Connected Line/Party information.
Definition: channel.h:457
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
int headers
Definition: sip.h:832
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
Redirecting Line information. RDNIS (Redirecting Directory Number Information Service) Where a call d...
Definition: channel.h:523
#define LOG_NOTICE
Definition: logger.h:263
char * strcasestr(const char *, const char *)
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
unsigned int reqsipoptions
Definition: sip.h:1098
#define AST_MAX_CONTEXT
Definition: channel.h:136
static void build_contact(struct sip_pvt *p, struct sip_request *req, int incoming)
Build contact header.
Definition: chan_sip.c:14385
unsigned short do_history
Definition: sip.h:1078
struct ast_channel * owner
Definition: sip.h:1138
static int transmit_provisional_response(struct sip_pvt *p, const char *msg, const struct sip_request *req, int with_sdp)
Definition: chan_sip.c:12867
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
#define REQ_OFFSET_TO_STR(req, offset)
Definition: sip.h:858
const ast_string_field peername
Definition: sip.h:1063
struct ast_rtp_instance * rtp
Definition: sip.h:1174
enum invitestates invitestate
Definition: sip.h:1007
#define ast_clear_flag(p, flag)
Definition: utils.h:77
Indicate what information in ast_party_connected_line should be set.
Definition: channel.h:490
static void parse_oli(struct sip_request *req, struct ast_channel *chan)
Check for the presence of OLI tag(s) in the From header and set on the channel.
Definition: chan_sip.c:27087
char *const text
Definition: chan_sip.c:737
static void change_hold_state(struct sip_pvt *dialog, struct sip_request *req, int holdstate, int sendonly)
Change hold state for a call.
Definition: chan_sip.c:10147
struct ast_frame ast_null_frame
Definition: main/frame.c:79
static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action, int is_offer)
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().
Definition: chan_sip.c:10253
const ast_string_field cid_name
Definition: sip.h:1063
void ast_party_redirecting_free(struct ast_party_redirecting *doomed)
Destroy the redirecting information contents.
Definition: channel.c:2179
char * strsep(char **str, const char *delims)
struct ast_set_party_id to
Definition: channel.h:562
void sip_cancel_destroy(struct sip_pvt *pvt)
Cancel destruction of SIP dialog.
Definition: chan_sip.c:4464
#define SIP_DTMF
Definition: sip.h:275
Indicate what information in ast_party_redirecting should be set.
Definition: channel.h:556
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
const char * ast_channel_name(const struct ast_channel *chan)
void ast_party_redirecting_init(struct ast_party_redirecting *init)
Initialize the given redirecting structure.
Definition: channel.c:2122
#define TRUE
Definition: app_minivm.c:518
const ast_string_field cid_tag
Definition: sip.h:1063
unsigned short session_modify
Definition: sip.h:1087
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7486
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406
static PGresult * result
Definition: cel_pgsql.c:88
char ignore
Definition: sip.h:839
uint32_t lastinvite
Definition: sip.h:1074
const struct ast_flags ast_uri_sip_user
Definition: main/utils.c:575
int error(const char *format,...)
Definition: utils/frame.c:999
static unsigned int set_pvt_allowed_methods(struct sip_pvt *pvt, struct sip_request *req)
Definition: chan_sip.c:9880
void ast_rtp_instance_set_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value)
Set the value of an RTP instance property.
Definition: rtp_engine.c:705
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.
Definition: chan_sip.c:14041
#define SIP_OUTGOING
Definition: sip.h:257
int ast_format_cap_append_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type)
Append the formats of provided type in src to dst.
Definition: format_cap.c:269
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
struct ast_sdp_srtp * srtp
Definition: sip.h:1185
void ast_set_party_id_all(struct ast_set_party_id *update_id)
Set the update marker to update all information of a corresponding party id.
Definition: channel.c:1750
char default_context[AST_MAX_CONTEXT]
Definition: sip.h:782
static void update_redirecting(struct sip_pvt *p, const void *data, size_t datalen)
Send a provisional response indicating that a call was redirected.
Definition: chan_sip.c:15755
char connected
Definition: eagi_proxy.c:82
#define INC_CALL_LIMIT
Definition: sip.h:128
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.
Definition: chan_sip.c:12661
#define SIP_PAGE2_DIALOG_ESTABLISHED
Definition: sip.h:358
static int handle_request_invite_st(struct sip_pvt *p, struct sip_request *req, int reinvite)
Definition: chan_sip.c:26208
unsigned int sipoptions
Definition: sip.h:1097
unsigned int parse_sip_options(const char *options, char *unsupported, size_t unsupported_len)
Parse supported header in incoming packet.
void sip_scheddestroy(struct sip_pvt *p, int ms)
Schedule destruction of SIP dialog.
Definition: chan_sip.c:4549
static int parse_ok_contact(struct sip_pvt *pvt, struct sip_request *req)
Save contact header for 200 OK on INVITE.
Definition: chan_sip.c:16811
Configuration relating to call pickup.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ handle_request_invite_st()

static int handle_request_invite_st ( struct sip_pvt p,
struct sip_request req,
int  reinvite 
)
static

Definition at line 26208 of file chan_sip.c.

References ast_debug, ast_log, ast_strlen_zero, sip_pvt::callid, FALSE, global_max_se, LOG_ERROR, LOG_WARNING, MAX, parse_minse(), parse_session_expires(), sip_pvt::reqsipoptions, SESSION_TIMER_MODE_ACCEPT, SESSION_TIMER_MODE_ORIGINATE, SESSION_TIMER_MODE_REFUSE, SESSION_TIMER_REFRESHER_AUTO, SESSION_TIMER_REFRESHER_PARAM_UAC, SESSION_TIMER_REFRESHER_PARAM_UNKNOWN, SESSION_TIMER_REFRESHER_THEM, SESSION_TIMER_REFRESHER_US, sip_get_header(), SIP_OPT_TIMER, sip_st_alloc(), sip_pvt::sipoptions, sip_st_dlg::st_active, sip_st_dlg::st_active_peer_ua, st_get_mode(), st_get_refresher(), st_get_se(), sip_st_dlg::st_interval, sip_st_dlg::st_ref, sip_pvt::stimer, transmit_response_reliable(), transmit_response_with_minse(), transmit_response_with_unsupported(), and TRUE.

Referenced by handle_request_invite().

26209 {
26210  const char *p_uac_se_hdr; /* UAC's Session-Expires header string */
26211  const char *p_uac_min_se; /* UAC's requested Min-SE interval (char string) */
26212  int uac_max_se = -1; /* UAC's Session-Expires in integer format */
26213  int uac_min_se = -1; /* UAC's Min-SE in integer format */
26214  int st_active = FALSE; /* Session-Timer on/off boolean */
26215  int st_interval = 0; /* Session-Timer negotiated refresh interval */
26216  enum st_refresher tmp_st_ref = SESSION_TIMER_REFRESHER_AUTO; /* Session-Timer refresher */
26217  int dlg_min_se = -1;
26218  int dlg_max_se = global_max_se;
26219  int rtn;
26220 
26221  /* Session-Timers */
26222  if ((p->sipoptions & SIP_OPT_TIMER)) {
26224 
26225  /* The UAC has requested session-timers for this session. Negotiate
26226  the session refresh interval and who will be the refresher */
26227  ast_debug(2, "Incoming INVITE with 'timer' option supported\n");
26228 
26229  /* Allocate Session-Timers struct w/in the dialog */
26230  if (!p->stimer) {
26231  sip_st_alloc(p);
26232  }
26233 
26234  /* Parse the Session-Expires header */
26235  p_uac_se_hdr = sip_get_header(req, "Session-Expires");
26236  if (!ast_strlen_zero(p_uac_se_hdr)) {
26237  ast_debug(2, "INVITE also has \"Session-Expires\" header.\n");
26238  rtn = parse_session_expires(p_uac_se_hdr, &uac_max_se, &st_ref_param);
26240  if (rtn != 0) {
26241  transmit_response_reliable(p, "400 Session-Expires Invalid Syntax", req);
26242  return -1;
26243  }
26244  }
26245 
26246  /* Parse the Min-SE header */
26247  p_uac_min_se = sip_get_header(req, "Min-SE");
26248  if (!ast_strlen_zero(p_uac_min_se)) {
26249  ast_debug(2, "INVITE also has \"Min-SE\" header.\n");
26250  rtn = parse_minse(p_uac_min_se, &uac_min_se);
26251  if (rtn != 0) {
26252  transmit_response_reliable(p, "400 Min-SE Invalid Syntax", req);
26253  return -1;
26254  }
26255  }
26256 
26257  dlg_min_se = st_get_se(p, FALSE);
26258  switch (st_get_mode(p, 1)) {
26261  if (uac_max_se > 0 && uac_max_se < dlg_min_se) {
26262  transmit_response_with_minse(p, "422 Session Interval Too Small", req, dlg_min_se);
26263  return -1;
26264  }
26265 
26267  st_active = TRUE;
26268  if (st_ref_param == SESSION_TIMER_REFRESHER_PARAM_UNKNOWN) {
26269  tmp_st_ref = st_get_refresher(p);
26270  }
26271 
26272  dlg_max_se = st_get_se(p, TRUE);
26273  if (uac_max_se > 0) {
26274  if (dlg_max_se >= uac_min_se) {
26275  st_interval = (uac_max_se < dlg_max_se) ? uac_max_se : dlg_max_se;
26276  } else {
26277  st_interval = uac_max_se;
26278  }
26279  } else if (uac_min_se > 0) {
26280  st_interval = MAX(dlg_max_se, uac_min_se);
26281  } else {
26282  st_interval = dlg_max_se;
26283  }
26284  break;
26285 
26287  if (p->reqsipoptions & SIP_OPT_TIMER) {
26288  transmit_response_with_unsupported(p, "420 Option Disabled", req, "timer");
26289  ast_log(LOG_WARNING, "Received SIP INVITE with supported but disabled option: timer\n");
26290  return -1;
26291  }
26292  break;
26293 
26294  default:
26295  ast_log(LOG_ERROR, "Internal Error %u at %s:%d\n", st_get_mode(p, 1), __FILE__, __LINE__);
26296  break;
26297  }
26298  } else {
26299  /* The UAC did not request session-timers. Asterisk (UAS), will now decide
26300  (based on session-timer-mode in sip.conf) whether to run session-timers for
26301  this session or not. */
26302  switch (st_get_mode(p, 1)) {
26304  st_active = TRUE;
26305  st_interval = st_get_se(p, TRUE);
26306  tmp_st_ref = SESSION_TIMER_REFRESHER_US;
26308  break;
26309 
26310  default:
26311  break;
26312  }
26313  }
26314 
26315  if (reinvite == 0) {
26316  /* Session-Timers: Start session refresh timer based on negotiation/config */
26317  if (st_active == TRUE) {
26318  p->stimer->st_active = TRUE;
26319  p->stimer->st_interval = st_interval;
26320  p->stimer->st_ref = tmp_st_ref;
26321  }
26322  } else {
26323  if (p->stimer->st_active == TRUE) {
26324  /* Session-Timers: A re-invite request sent within a dialog will serve as
26325  a refresh request, no matter whether the re-invite was sent for refreshing
26326  the session or modifying it.*/
26327  ast_debug (2, "Restarting session-timers on a refresh - %s\n", p->callid);
26328 
26329  /* The UAC may be adjusting the session-timers mid-session */
26330  if (st_interval > 0) {
26331  p->stimer->st_interval = st_interval;
26332  p->stimer->st_ref = tmp_st_ref;
26333  }
26334  }
26335  }
26336 
26337  return 0;
26338 }
enum st_refresher st_ref
Definition: sip.h:962
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
#define FALSE
Definition: app_minivm.c:521
int st_active_peer_ua
Definition: sip.h:964
#define LOG_WARNING
Definition: logger.h:274
#define SIP_OPT_TIMER
Definition: sip.h:148
int st_active
Definition: sip.h:960
static enum st_mode st_get_mode(struct sip_pvt *, int no_cached)
Get the session-timer mode.
Definition: chan_sip.c:30447
#define ast_strlen_zero(foo)
Definition: strings.h:52
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.
Definition: chan_sip.c:12688
int st_interval
Definition: sip.h:961
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define MAX(a, b)
Definition: utils.h:228
static enum st_refresher st_get_refresher(struct sip_pvt *)
Get the entity (UAC or UAS) that&#39;s acting as the session-timer refresher.
Definition: chan_sip.c:30425
st_refresher_param
Definition: sip.h:582
static struct sip_st_dlg * sip_st_alloc(struct sip_pvt *const p)
Allocate Session-Timers struct w/in dialog.
Definition: chan_sip.c:8914
const ast_string_field callid
Definition: sip.h:1063
#define LOG_ERROR
Definition: logger.h:285
struct sip_st_dlg * stimer
Definition: sip.h:1184
unsigned int reqsipoptions
Definition: sip.h:1098
static int global_max_se
Definition: chan_sip.c:858
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)
Definition: chan_sip.c:12671
st_refresher
The entity playing the refresher role for Session-Timers.
Definition: sip.h:576
#define TRUE
Definition: app_minivm.c:518
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.
Definition: chan_sip.c:30306
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.
Definition: chan_sip.c:12661
unsigned int sipoptions
Definition: sip.h:1097
static int st_get_se(struct sip_pvt *, int max)
Get Max or Min SE (session timer expiry)
Definition: chan_sip.c:30393
static int parse_minse(const char *p_hdrval, int *const p_interval)
Session-Timers: Function for parsing Min-SE header.
Definition: chan_sip.c:30286

◆ handle_request_message()

static int handle_request_message ( struct sip_pvt p,
struct sip_request req,
struct ast_sockaddr addr,
const char *  e 
)
static

Handle incoming MESSAGE request.

Definition at line 27820 of file chan_sip.c.

References ast_verbose(), sip_request::debug, sip_request::ignore, receive_message(), sip_msg_send(), and transmit_response().

Referenced by handle_incoming().

27821 {
27822  if (!req->ignore) {
27823  if (req->debug)
27824  ast_verbose("Receiving message!\n");
27825  receive_message(p, req, addr, e);
27826  } else
27827  transmit_response(p, "202 Accepted", req);
27828  return 1;
27829 }
char debug
Definition: sip.h:837
static void receive_message(struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, const char *e)
Receive SIP MESSAGE method messages.
Definition: chan_sip.c:19707
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req)
Transmit response, no retransmits.
Definition: chan_sip.c:12655
char ignore
Definition: sip.h:839

◆ handle_request_notify()

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

References AST_CONTROL_TRANSFER, ast_debug, ast_log, ast_publish_mwi_state, ast_queue_control_data(), ast_skip_blanks(), ast_strdupa, ast_strlen_zero, AST_TRANSFER_FAILED, AST_TRANSFER_SUCCESS, buf, c, sip_pvt::callid, DEFAULT_TRANS_TIMEOUT, FALSE, FINDPEERS, get_content(), get_content_line(), handle_cc_notify(), sip_pvt::lastinvite, LOG_NOTICE, LOG_WARNING, mailbox, sip_subscription_mwi::mailbox, sip_pvt::mwi, NULL, sip_pvt::owner, sip_pvt::recv, sip_find_peer(), sip_get_header(), sip_scheddestroy(), sip_unref_peer, sipdebug, sip_pvt::socket, strsep(), transmit_response(), TRUE, sip_socket::type, and sip_peer::unsolicited_mailbox.

Referenced by handle_incoming().

25733 {
25734  /* This is mostly a skeleton for future improvements */
25735  /* Mostly created to return proper answers on notifications on outbound REFER's */
25736  int res = 0;
25737  const char *event = sip_get_header(req, "Event");
25738  char *sep;
25739 
25740  if( (sep = strchr(event, ';')) ) { /* XXX bug here - overwriting string ? */
25741  *sep++ = '\0';
25742  }
25743 
25744  if (sipdebug)
25745  ast_debug(2, "Got NOTIFY Event: %s\n", event);
25746 
25747  if (!strcmp(event, "refer")) {
25748  /* Save nesting depth for now, since there might be other events we will
25749  support in the future */
25750 
25751  /* Handle REFER notifications */
25752  char *buf, *cmd, *code;
25753  int respcode;
25754  int success = TRUE;
25755 
25756  /* EventID for each transfer... EventID is basically the REFER cseq
25757 
25758  We are getting notifications on a call that we transferred
25759  We should hangup when we are getting a 200 OK in a sipfrag
25760  Check if we have an owner of this event */
25761 
25762  /* Check the content type */
25763  if (strncasecmp(sip_get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) {
25764  /* We need a sipfrag */
25765  transmit_response(p, "400 Bad request", req);
25767  return -1;
25768  }
25769 
25770  /* Get the text of the attachment */
25771  if (ast_strlen_zero(buf = get_content(req))) {
25772  ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid);
25773  transmit_response(p, "400 Bad request", req);
25775  return -1;
25776  }
25777 
25778  /*
25779  From the RFC...
25780  A minimal, but complete, implementation can respond with a single
25781  NOTIFY containing either the body:
25782  SIP/2.0 100 Trying
25783 
25784  if the subscription is pending, the body:
25785  SIP/2.0 200 OK
25786  if the reference was successful, the body:
25787  SIP/2.0 503 Service Unavailable
25788  if the reference failed, or the body:
25789  SIP/2.0 603 Declined
25790 
25791  if the REFER request was accepted before approval to follow the
25792  reference could be obtained and that approval was subsequently denied
25793  (see Section 2.4.7).
25794 
25795  If there are several REFERs in the same dialog, we need to
25796  match the ID of the event header...
25797  */
25798  ast_debug(3, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf);
25799  cmd = ast_skip_blanks(buf);
25800  code = cmd;
25801  /* We are at SIP/2.0 */
25802  while(*code && (*code > 32)) { /* Search white space */
25803  code++;
25804  }
25805  *code++ = '\0';
25806  code = ast_skip_blanks(code);
25807  sep = code;
25808  sep++;
25809  while(*sep && (*sep > 32)) { /* Search white space */
25810  sep++;
25811  }
25812  *sep++ = '\0'; /* Response string */
25813  respcode = atoi(code);
25814  switch (respcode) {
25815  case 200: /* OK: The new call is up, hangup this call */
25816  /* Hangup the call that we are replacing */
25817  break;
25818  case 301: /* Moved permenantly */
25819  case 302: /* Moved temporarily */
25820  /* Do we get the header in the packet in this case? */
25821  success = FALSE;
25822  break;
25823  case 503: /* Service Unavailable: The new call failed */
25824  case 603: /* Declined: Not accepted */
25825  /* Cancel transfer, continue the current call */
25826  success = FALSE;
25827  break;
25828  case 0: /* Parse error */
25829  /* Cancel transfer, continue the current call */
25830  ast_log(LOG_NOTICE, "Error parsing sipfrag in NOTIFY in response to REFER.\n");
25831  success = FALSE;
25832  break;
25833  default:
25834  if (respcode < 200) {
25835  /* ignore provisional responses */
25836  success = -1;
25837  } else {
25838  ast_log(LOG_NOTICE, "Got unknown code '%d' in NOTIFY in response to REFER.\n", respcode);
25839  success = FALSE;
25840  }
25841  break;
25842  }
25843  if (success == FALSE) {
25844  ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n");
25845  }
25846 
25847  if (p->owner && success != -1) {
25849  ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
25850  }
25851  /* Confirm that we received this packet */
25852  transmit_response(p, "200 OK", req);
25853  } else if (!strcmp(event, "message-summary")) {
25854  const char *mailbox = NULL;
25855  char *c = ast_strdupa(get_content_line(req, "Voice-Message", ':'));
25856 
25857  if (!p->mwi) {
25858  struct sip_peer *peer = sip_find_peer(NULL, &p->recv, TRUE, FINDPEERS, FALSE, p->socket.type);
25859 
25860  if (peer) {
25861  mailbox = ast_strdupa(peer->unsolicited_mailbox);
25862  sip_unref_peer(peer, "removing unsolicited mwi ref");
25863  }
25864  } else {
25865  mailbox = p->mwi->mailbox;
25866  }
25867 
25868  if (!ast_strlen_zero(mailbox) && !ast_strlen_zero(c)) {
25869  char *old = strsep(&c, " ");
25870  char *new = strsep(&old, "/");
25871 
25872  ast_publish_mwi_state(mailbox, "SIP_Remote", atoi(new), atoi(old));
25873 
25874  transmit_response(p, "200 OK", req);
25875  } else {
25876  transmit_response(p, "489 Bad event", req);
25877  res = -1;
25878  }
25879  } else if (!strcmp(event, "keep-alive")) {
25880  /* Used by Sipura/Linksys for NAT pinhole,
25881  * just confirm that we received the packet. */
25882  transmit_response(p, "200 OK", req);
25883  } else if (!strcmp(event, "call-completion")) {
25884  res = handle_cc_notify(p, req);
25885  } else {
25886  /* We don't understand this event. */
25887  transmit_response(p, "489 Bad event", req);
25888  res = -1;
25889  }
25890 
25891  if (!p->lastinvite)
25893 
25894  return res;
25895 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
#define FALSE
Definition: app_minivm.c:521
struct sip_peer * sip_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.
Definition: chan_sip.c:5851
static int handle_cc_notify(struct sip_pvt *pvt, struct sip_request *req)
Definition: chan_sip.c:25671
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static char * get_content_line(struct sip_request *req, char *name, char delimiter)
Get a specific line from the message content.
Definition: chan_sip.c:8489
#define LOG_WARNING
Definition: logger.h:274
struct ast_sockaddr recv
Definition: sip.h:1135
#define DEFAULT_TRANS_TIMEOUT
Definition: sip.h:107
struct sip_socket socket
Definition: sip.h:1066
ast_control_transfer
Definition: astman.c:222
static struct test_val c
const ast_string_field mailbox
Definition: sip.h:1461
#define NULL
Definition: resample.c:96
#define ast_publish_mwi_state(mailbox, context, new_msgs, old_msgs)
Publish a MWI state update via stasis.
Definition: mwi.h:380
#define ast_strlen_zero(foo)
Definition: strings.h:52
static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req)
Transmit response, no retransmits.
Definition: chan_sip.c:12655
static char mailbox[AST_MAX_MAILBOX_UNIQUEID]
Definition: chan_mgcp.c:204
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
struct sip_subscription_mwi * mwi
Definition: sip.h:1192
const ast_string_field unsolicited_mailbox
Definition: sip.h:1306
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
const ast_string_field callid
Definition: sip.h:1063
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
#define LOG_NOTICE
Definition: logger.h:263
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
struct ast_channel * owner
Definition: sip.h:1138
#define FINDPEERS
Definition: sip.h:53
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
char * strsep(char **str, const char *delims)
enum ast_transport type
Definition: sip.h:798
#define TRUE
Definition: app_minivm.c:518
uint32_t lastinvite
Definition: sip.h:1074
int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen)
Queue a control frame with payload.
Definition: channel.c:1238
static char * get_content(struct sip_request *req)
Get message body content.
Definition: chan_sip.c:8610
void sip_scheddestroy(struct sip_pvt *p, int ms)
Schedule destruction of SIP dialog.
Definition: chan_sip.c:4549

◆ handle_request_options()

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

References ast_shutting_down(), ast_string_field_set, ast_strlen_zero, AUTH_CHALLENGE_SENT, sip_settings::auth_options_requests, build_contact(), check_user(), context, sip_pvt::context, copy_request(), sip_settings::default_context, DEFAULT_TRANS_TIMEOUT, get_destination(), sip_pvt::initreq, sip_pvt::lastinvite, NULL, send_check_user_failure_response(), set_pvt_allowed_methods(), sip_cfg, SIP_GET_DEST_EXTEN_FOUND, SIP_GET_DEST_EXTEN_MATCHMORE, SIP_GET_DEST_EXTEN_NOT_FOUND, SIP_GET_DEST_INVALID_URI, SIP_GET_DEST_REFUSED, SIP_OPTIONS, sip_scheddestroy(), transmit_response_with_allow(), and XMIT_UNRELIABLE.

Referenced by handle_incoming().

25901 {
25902  const char *msg;
25903  enum sip_get_dest_result gotdest;
25904  int res;
25905 
25906  if (p->lastinvite) {
25907  /* if this is a request in an active dialog, just confirm that the dialog exists. */
25908  transmit_response_with_allow(p, "200 OK", req, 0);
25909  return 0;
25910  }
25911 
25913  /* Do authentication if this OPTIONS request began the dialog */
25914  copy_request(&p->initreq, req);
25915  set_pvt_allowed_methods(p, req);
25916  res = check_user(p, req, SIP_OPTIONS, e, XMIT_UNRELIABLE, addr);
25917  if (res == AUTH_CHALLENGE_SENT) {
25919  return 0;
25920  }
25921  if (res < 0) { /* Something failed in authentication */
25924  return 0;
25925  }
25926  }
25927 
25928  /* must go through authentication before getting here */
25929  gotdest = get_destination(p, req, NULL);
25930  build_contact(p, req, 1);
25931 
25932  if (ast_strlen_zero(p->context))
25934 
25935  if (ast_shutting_down()) {
25936  /*
25937  * Not taking any new calls at this time.
25938  * Likely a server availability OPTIONS poll.
25939  */
25940  msg = "503 Unavailable";
25941  } else {
25942  msg = "404 Not Found";
25943  switch (gotdest) {
25945  msg = "416 Unsupported URI scheme";
25946  break;
25948  case SIP_GET_DEST_REFUSED:
25950  //msg = "404 Not Found";
25951  break;
25953  msg = "200 OK";
25954  break;
25955  }
25956  }
25957  transmit_response_with_allow(p, msg, req, 0);
25958 
25959  /* Destroy if this OPTIONS was the opening request, but not if
25960  it's in the middle of a normal call flow. */
25962 
25963  return 0;
25964 }
static void send_check_user_failure_response(struct sip_pvt *p, struct sip_request *req, int res, enum xmittype reliable)
Definition: chan_sip.c:19626
int ast_shutting_down(void)
Definition: asterisk.c:1834
#define DEFAULT_TRANS_TIMEOUT
Definition: sip.h:107
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.
Definition: chan_sip.c:12733
const ast_string_field context
Definition: sip.h:1063
sip_get_dest_result
Result from get_destination function.
Definition: sip.h:508
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
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.
Definition: chan_sip.c:18508
struct sip_request initreq
Definition: sip.h:1151
static void copy_request(struct sip_request *dst, const struct sip_request *src)
copy SIP request (mostly used to save request for responses)
Definition: chan_sip.c:14061
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
static void build_contact(struct sip_pvt *p, struct sip_request *req, int incoming)
Build contact header.
Definition: chan_sip.c:14385
uint32_t lastinvite
Definition: sip.h:1074
static unsigned int set_pvt_allowed_methods(struct sip_pvt *pvt, struct sip_request *req)
Definition: chan_sip.c:9880
int auth_options_requests
Definition: sip.h:761
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
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, that needs to be unreferenced.
Definition: chan_sip.c:19621
char default_context[AST_MAX_CONTEXT]
Definition: sip.h:782
void sip_scheddestroy(struct sip_pvt *p, int ms)
Schedule destruction of SIP dialog.
Definition: chan_sip.c:4549
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ handle_request_publish()

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

References __sip_ack(), ast_string_field_set, ast_strlen_zero, AUTH_CHALLENGE_SENT, AUTH_SUCCESSFUL, check_user(), DEFAULT_TRANS_TIMEOUT, determine_sip_publish_type(), sip_pvt::expiry, get_esc(), handle_sip_publish_initial(), handle_sip_publish_modify(), handle_sip_publish_refresh(), handle_sip_publish_remove(), sip_pvt::lastinvite, max_expiry, min_expiry, NULL, pvt_set_needdestroy(), send_check_user_failure_response(), sip_get_header(), SIP_PUBLISH, SIP_PUBLISH_INITIAL, SIP_PUBLISH_MODIFY, SIP_PUBLISH_REFRESH, SIP_PUBLISH_REMOVE, SIP_PUBLISH_UNKNOWN, sip_scheddestroy(), transmit_response(), transmit_response_with_minexpires(), and XMIT_UNRELIABLE.

Referenced by handle_incoming().

28411 {
28412  const char *etag = sip_get_header(req, "SIP-If-Match");
28413  const char *event = sip_get_header(req, "Event");
28414  struct event_state_compositor *esc;
28415  enum sip_publish_type publish_type;
28416  const char *expires_str = sip_get_header(req, "Expires");
28417  int expires_int;
28418  int auth_result;
28419  int handler_result = -1;
28420 
28421  if (ast_strlen_zero(event)) {
28422  transmit_response(p, "489 Bad Event", req);
28423  pvt_set_needdestroy(p, "missing Event: header");
28424  return -1;
28425  }
28426 
28427  if (!(esc = get_esc(event))) {
28428  transmit_response(p, "489 Bad Event", req);
28429  pvt_set_needdestroy(p, "unknown event package in publish");
28430  return -1;
28431  }
28432 
28433  auth_result = check_user(p, req, SIP_PUBLISH, uri, XMIT_UNRELIABLE, addr);
28434  if (auth_result == AUTH_CHALLENGE_SENT) {
28435  p->lastinvite = seqno;
28436  return 0;
28437  } else if (auth_result < 0) {
28438  send_check_user_failure_response(p, req, auth_result, XMIT_UNRELIABLE);
28440  ast_string_field_set(p, theirtag, NULL);
28441  return 0;
28442  } else if (auth_result == AUTH_SUCCESSFUL && p->lastinvite) {
28443  /* We need to stop retransmitting the 401 */
28444  __sip_ack(p, p->lastinvite, 1, 0);
28445  }
28446 
28447  publish_type = determine_sip_publish_type(req, event, etag, expires_str, &expires_int);
28448 
28449  if (expires_int > max_expiry) {
28450  expires_int = max_expiry;
28451  } else if (expires_int < min_expiry && expires_int > 0) {
28452  transmit_response_with_minexpires(p, "423 Interval too small", req, min_expiry);
28453  pvt_set_needdestroy(p, "Expires is less that the min expires allowed.");
28454  return 0;
28455  }
28456  p->expiry = expires_int;
28457 
28458  /* It is the responsibility of these handlers to formulate any response
28459  * sent for a PUBLISH
28460  */
28461  switch (publish_type) {
28462  case SIP_PUBLISH_UNKNOWN:
28463  transmit_response(p, "400 Bad Request", req);
28464  break;
28465  case SIP_PUBLISH_INITIAL:
28466  handler_result = handle_sip_publish_initial(p, req, esc, expires_int);
28467  break;
28468  case SIP_PUBLISH_REFRESH:
28469  handler_result = handle_sip_publish_refresh(p, req, esc, etag, expires_int);
28470  break;
28471  case SIP_PUBLISH_MODIFY:
28472  handler_result = handle_sip_publish_modify(p, req, esc, etag, expires_int);
28473  break;
28474  case SIP_PUBLISH_REMOVE:
28475  handler_result = handle_sip_publish_remove(p, req, esc, etag);
28476  break;
28477  default:
28478  transmit_response(p, "400 Impossible Condition", req);
28479  break;
28480  }
28481  if (!handler_result && p->expiry > 0) {
28482  sip_scheddestroy(p, (p->expiry + 10) * 1000);
28483  } else {
28484  pvt_set_needdestroy(p, "forcing expiration");
28485  }
28486 
28487  return handler_result;
28488 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
static void send_check_user_failure_response(struct sip_pvt *p, struct sip_request *req, int res, enum xmittype reliable)
Definition: chan_sip.c:19626
The Event State Compositors.
Definition: chan_sip.c:996
static int max_expiry
Definition: chan_sip.c:668
Unknown.
Definition: sip.h:1571
#define DEFAULT_TRANS_TIMEOUT
Definition: sip.h:107
Definition: astman.c:222
#define NULL
Definition: resample.c:96
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)
Definition: chan_sip.c:28354
static int handle_sip_publish_initial(struct sip_pvt *p, struct sip_request *req, struct event_state_compositor *esc, const int expires)
Definition: chan_sip.c:28304
Refresh.
Definition: sip.h:1590
#define ast_strlen_zero(foo)
Definition: strings.h:52
Remove.
Definition: sip.h:1607
static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req)
Transmit response, no retransmits.
Definition: chan_sip.c:12655
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: chan_sip.c:4570
static struct event_state_compositor * get_esc(const char *const event_package)
Definition: chan_sip.c:1743
int expiry
Definition: sip.h:1118
Modify.
Definition: sip.h:1599
static void pvt_set_needdestroy(struct sip_pvt *pvt, const char *reason)
Definition: chan_sip.c:3429
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)
Definition: chan_sip.c:28013
static int transmit_response_with_minexpires(struct sip_pvt *p, const char *msg, const struct sip_request *req, int minexpires)
Append Min-Expires header, content length before transmitting response.
Definition: chan_sip.c:12742
static int handle_sip_publish_remove(struct sip_pvt *p, struct sip_request *req, struct event_state_compositor *esc, const char *const etag)
Definition: chan_sip.c:28382
uint32_t lastinvite
Definition: sip.h:1074
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)
Definition: chan_sip.c:28326
sip_publish_type
The types of PUBLISH messages defined in RFC 3903.
Definition: sip.h:1562
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, that needs to be unreferenced.
Definition: chan_sip.c:19621
Initial.
Definition: sip.h:1581
void sip_scheddestroy(struct sip_pvt *p, int ms)
Schedule destruction of SIP dialog.
Definition: chan_sip.c:4549
static int min_expiry
Definition: chan_sip.c:667
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ handle_request_refer()

static int handle_request_refer ( struct sip_pvt p,
struct sip_request req,
uint32_t  seqno,
int *  nounlock 
)
static

Definition at line 27324 of file chan_sip.c.

References sip_settings::allow_external_domains, sip_pvt::allowtransfer, append_history, ast_bridge_transfer_blind(), AST_BRIDGE_TRANSFER_FAIL, AST_BRIDGE_TRANSFER_INVALID, AST_BRIDGE_TRANSFER_NOT_PERMITTED, AST_BRIDGE_TRANSFER_SUCCESS, ast_channel_cleanup, ast_channel_name(), ast_channel_ref, ast_channel_unlock, ast_clear_flag, ast_debug, ast_free_ptr(), AST_LIST_EMPTY, ast_log, ast_party_redirecting_free(), ast_party_redirecting_init(), ast_set_flag, ast_str_append(), ast_str_buffer(), ast_str_create, ast_strdupa, ast_string_field_set, ast_strlen_zero, ast_test_flag, ast_verbose(), sip_refer::attendedtransfer, blind_transfer_cb(), sip_pvt::callid, change_redirecting_information(), check_sip_domain(), context, sip_pvt::context, sip_request::debug, sip_settings::default_context, blind_transfer_cb_data::domain, sip_pvt::flags, get_refer_info(), sip_request::ignore, local_attended_transfer(), sip_refer::localtransfer, LOG_NOTICE, NULL, sip_pvt::owner, pvt_set_needdestroy(), RAII_VAR, blind_transfer_cb_data::redirecting, sip_pvt::refer, REFER_200OK, REFER_FAILED, REFER_SENT, sip_refer::refer_to, sip_refer::refer_to_context, sip_refer::refer_to_domain, sip_refer::referred_by, blind_transfer_cb_data::referred_by, blind_transfer_cb_data::replaces, sip_refer::replaces_callid, sip_refer::replaces_callid_fromtag, sip_refer::replaces_callid_totag, S_OR, sip_alreadygone(), sip_cfg, SIP_DEFER_BYE_ON_TRANSFER, SIP_GOTREFER, SIP_OUTGOING, sip_pvt_lock, sip_pvt_unlock, sip_refer_alloc(), sipdebug, sip_refer::status, TRANSFER_CLOSED, transmit_notify_with_sipfrag(), transmit_response(), TRUE, and blind_transfer_cb_data::update_redirecting.

Referenced by handle_incoming().

27325 {
27326  char *refer_to = NULL;
27327  char *refer_to_context = NULL;
27328  int res = 0;
27329  struct blind_transfer_cb_data cb_data;
27330  enum ast_transfer_result transfer_res;
27331  RAII_VAR(struct ast_channel *, transferer, NULL, ast_channel_cleanup);
27332  RAII_VAR(struct ast_str *, replaces_str, NULL, ast_free_ptr);
27333 
27334  if (req->debug) {
27335  ast_verbose("Call %s got a SIP call transfer from %s: (REFER)!\n",
27336  p->callid,
27337  ast_test_flag(&p->flags[0], SIP_OUTGOING) ? "callee" : "caller");
27338  }
27339 
27340  if (!p->owner) {
27341  /* This is a REFER outside of an existing SIP dialog */
27342  /* We can't handle that, so decline it */
27343  ast_debug(3, "Call %s: Declined REFER, outside of dialog...\n", p->callid);
27344  transmit_response(p, "603 Declined (No dialog)", req);
27345  if (!req->ignore) {
27346  append_history(p, "Xfer", "Refer failed. Outside of dialog.");
27347  sip_alreadygone(p);
27348  pvt_set_needdestroy(p, "outside of dialog");
27349  }
27350  return 0;
27351  }
27352 
27353  /* Check if transfer is allowed from this device */
27354  if (p->allowtransfer == TRANSFER_CLOSED ) {
27355  /* Transfer not allowed, decline */
27356  transmit_response(p, "603 Declined (policy)", req);
27357  append_history(p, "Xfer", "Refer failed. Allowtransfer == closed.");
27358  /* Do not destroy SIP session */
27359  return 0;
27360  }
27361 
27362  if (!req->ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
27363  /* Already have a pending REFER */
27364  transmit_response(p, "491 Request pending", req);
27365  append_history(p, "Xfer", "Refer failed. Request pending.");
27366  return 0;
27367  }
27368 
27369  /* Allocate memory for call transfer data */
27370  if (!sip_refer_alloc(p)) {
27371  transmit_response(p, "500 Internal Server Error", req);
27372  append_history(p, "Xfer", "Refer failed. Memory allocation error.");
27373  return -3;
27374  }
27375 
27376  res = get_refer_info(p, req); /* Extract headers */
27377 
27378  p->refer->status = REFER_SENT;
27379 
27380  if (res != 0) {
27381  switch (res) {
27382  case -2: /* Syntax error */
27383  transmit_response(p, "400 Bad Request (Refer-to missing)", req);
27384  append_history(p, "Xfer", "Refer failed. Refer-to missing.");
27385  if (req->debug) {
27386  ast_debug(1, "SIP transfer to black hole can't be handled (no refer-to: )\n");
27387  }
27388  break;
27389  case -3:
27390  transmit_response(p, "603 Declined (Non sip: uri)", req);
27391  append_history(p, "Xfer", "Refer failed. Non SIP uri");
27392  if (req->debug) {
27393  ast_debug(1, "SIP transfer to non-SIP uri denied\n");
27394  }
27395  break;
27396  default:
27397  /* Refer-to extension not found, fake a failed transfer */
27398  transmit_response(p, "202 Accepted", req);
27399  append_history(p, "Xfer", "Refer failed. Bad extension.");
27400  transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE);
27402  if (req->debug) {
27403  ast_debug(1, "SIP transfer to bad extension: %s\n", p->refer->refer_to);
27404  }
27405  break;
27406  }
27407  return 0;
27408  }
27409 
27410  if (ast_strlen_zero(p->context)) {
27412  }
27413 
27414  /* If we do not support SIP domains, all transfers are local */
27416  p->refer->localtransfer = 1;
27417  if (sipdebug) {
27418  ast_debug(3, "This SIP transfer is local : %s\n", p->refer->refer_to_domain);
27419  }
27421  /* This PBX doesn't bother with SIP domains or domain is local, so this transfer is local */
27422  p->refer->localtransfer = 1;
27423  } else if (sipdebug) {
27424  ast_debug(3, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain);
27425  }
27426 
27427  /* Is this a repeat of a current request? Ignore it */
27428  /* Don't know what else to do right now. */
27429  if (req->ignore) {
27430  return 0;
27431  }
27432 
27433  /* Get the transferer's channel */
27434  transferer = ast_channel_ref(p->owner);
27435 
27436  if (sipdebug) {
27437  ast_debug(3, "SIP %s transfer: Transferer channel %s\n",
27438  p->refer->attendedtransfer ? "attended" : "blind",
27439  ast_channel_name(transferer));
27440  }
27441 
27442  ast_set_flag(&p->flags[0], SIP_GOTREFER);
27443 
27444  /* From here on failures will be indicated with NOTIFY requests */
27445  transmit_response(p, "202 Accepted", req);
27446 
27447  /* Attended transfer: Find all call legs and bridge transferee with target*/
27448  if (p->refer->attendedtransfer) {
27449  /* both p and p->owner _MUST_ be locked while calling local_attended_transfer */
27450  if ((res = local_attended_transfer(p, transferer, seqno, nounlock))) {
27452  return res;
27453  }
27454  /* Fall through for remote transfers that we did not find locally */
27455  if (sipdebug) {
27456  ast_debug(4, "SIP attended transfer: Still not our call - generating INVITE with replaces\n");
27457  }
27458  /* Fallthrough if we can't find the call leg internally */
27459  }
27460 
27461  /* Copy data we can not safely access after letting the pvt lock go. */
27462  refer_to = ast_strdupa(p->refer->refer_to);
27463  refer_to_context = ast_strdupa(p->refer->refer_to_context);
27464 
27465  ast_party_redirecting_init(&cb_data.redirecting);
27466  memset(&cb_data.update_redirecting, 0, sizeof(cb_data.update_redirecting));
27467  change_redirecting_information(p, req, &cb_data.redirecting, &cb_data.update_redirecting, 0);
27468 
27469  cb_data.domain = ast_strdupa(p->refer->refer_to_domain);
27470  cb_data.referred_by = ast_strdupa(p->refer->referred_by);
27471 
27473  replaces_str = ast_str_create(128);
27474  if (!replaces_str) {
27475  ast_log(LOG_NOTICE, "Unable to create Replaces string for remote attended transfer. Transfer failed\n");
27477  ast_party_redirecting_free(&cb_data.redirecting);
27478  return -1;
27479  }
27480  ast_str_append(&replaces_str, 0, "%s%s%s%s%s", p->refer->replaces_callid,
27481  !ast_strlen_zero(p->refer->replaces_callid_totag) ? ";to-tag=" : "",
27482  S_OR(p->refer->replaces_callid_totag, ""),
27483  !ast_strlen_zero(p->refer->replaces_callid_fromtag) ? ";from-tag=" : "",
27485  cb_data.replaces = ast_str_buffer(replaces_str);
27486  } else {
27487  cb_data.replaces = NULL;
27488  }
27489 
27490  if (!*nounlock) {
27492  *nounlock = 1;
27493  }
27494 
27496  sip_pvt_unlock(p);
27497  transfer_res = ast_bridge_transfer_blind(1, transferer, refer_to, refer_to_context, blind_transfer_cb, &cb_data);
27498  sip_pvt_lock(p);
27499 
27500  switch (transfer_res) {
27502  res = -1;
27503  p->refer->status = REFER_FAILED;
27504  transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE);
27505  append_history(p, "Xfer", "Refer failed (only bridged calls).");
27507  break;
27509  res = -1;
27510  p->refer->status = REFER_FAILED;
27511  transmit_notify_with_sipfrag(p, seqno, "403 Forbidden", TRUE);
27512  append_history(p, "Xfer", "Refer failed (bridge does not permit transfers)");
27514  break;
27516  res = -1;
27517  p->refer->status = REFER_FAILED;
27518  transmit_notify_with_sipfrag(p, seqno, "500 Internal Server Error", TRUE);
27519  append_history(p, "Xfer", "Refer failed (internal error)");
27521  break;
27523  res = 0;
27524  p->refer->status = REFER_200OK;
27525  transmit_notify_with_sipfrag(p, seqno, "200 OK", TRUE);
27526  append_history(p, "Xfer", "Refer succeeded.");
27527  break;
27528  default:
27529  break;
27530  }
27531 
27533  ast_party_redirecting_free(&cb_data.redirecting);
27534  return res;
27535 }
Main Channel structure associated with a channel.
char debug
Definition: sip.h:837
static int local_attended_transfer(struct sip_pvt *transferer, struct ast_channel *transferer_chan, uint32_t seqno, int *nounlock)
Find all call legs and bridge transferee with target called from handle_request_refer.
Definition: chan_sip.c:27143
static int sip_refer_alloc(struct sip_pvt *p)
Allocate SIP refer structure.
Definition: chan_sip.c:16370
#define ast_test_flag(p, flag)
Definition: utils.h:63
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
Definition: chan_sip.c:31314
#define ast_set_flag(p, flag)
Definition: utils.h:70
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
enum referstatus status
Definition: sip.h:947
#define SIP_DEFER_BYE_ON_TRANSFER
Definition: sip.h:267
static void sip_alreadygone(struct sip_pvt *dialog)
Encapsulate setting of SIP_ALREADYGONE to be able to trace it with debugging.
Definition: chan_sip.c:3460
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
const ast_string_field replaces_callid_fromtag
Definition: sip.h:944
struct ast_flags flags[3]
Definition: sip.h:1075
const ast_string_field context
Definition: sip.h:1063
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
#define NULL
Definition: resample.c:96
ast_transfer_result
Definition: bridge.h:1115
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1771
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req)
Transmit response, no retransmits.
Definition: chan_sip.c:12655
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
Definition: chan_sip.c:23528
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.
Definition: chan_sip.c:18812
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
enum ast_transfer_result ast_bridge_transfer_blind(int is_external, struct ast_channel *transferer, const char *exten, const char *context, transfer_channel_cb new_channel_cb, void *user_data)
Blind transfer target to the extension and context provided.
Definition: bridge.c:4477
const ast_string_field refer_to_context
Definition: sip.h:944
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
int allow_external_domains
Definition: sip.h:765
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2992
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
const ast_string_field refer_to
Definition: sip.h:944
int localtransfer
Definition: sip.h:946
const ast_string_field replaces_callid_totag
Definition: sip.h:944
#define SIP_GOTREFER
Definition: sip.h:263
const ast_string_field replaces_callid
Definition: sip.h:944
const ast_string_field callid
Definition: sip.h:1063
const ast_string_field referred_by
Definition: sip.h:944
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
static void pvt_set_needdestroy(struct sip_pvt *pvt, const char *reason)
Definition: chan_sip.c:3429
static void blind_transfer_cb(struct ast_channel *chan, struct transfer_channel_data *user_data_wrapper, enum ast_transfer_type transfer_type)
Definition: chan_sip.c:27249
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
#define LOG_NOTICE
Definition: logger.h:263
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_channel * owner
Definition: sip.h:1138
int attendedtransfer
Definition: sip.h:945
#define ast_clear_flag(p, flag)
Definition: utils.h:77
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)
Definition: chan_sip.c:15636
struct sip_refer * refer
Definition: sip.h:1160
void ast_party_redirecting_free(struct ast_party_redirecting *doomed)
Destroy the redirecting information contents.
Definition: channel.c:2179
enum transfermodes allowtransfer
Definition: sip.h:1137
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2970
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
const char * ast_channel_name(const struct ast_channel *chan)
void ast_party_redirecting_init(struct ast_party_redirecting *init)
Initialize the given redirecting structure.
Definition: channel.c:2122
#define TRUE
Definition: app_minivm.c:518
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406
char ignore
Definition: sip.h:839
#define SIP_OUTGOING
Definition: sip.h:257
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
char default_context[AST_MAX_CONTEXT]
Definition: sip.h:782
const ast_string_field refer_to_domain
Definition: sip.h:944
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ handle_request_register()

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

References append_history, ast_debug, ast_log, ast_sockaddr_stringify(), AUTH_ACL_FAILED, AUTH_BAD_TRANSPORT, AUTH_CHALLENGE_SENT, AUTH_NOT_FOUND, AUTH_PEER_NOT_DYNAMIC, AUTH_RTP_FAILED, AUTH_SECRET_FAILED, AUTH_UNKNOWN_DOMAIN, AUTH_USERNAME_MISMATCH, sip_request::authenticated, sip_pvt::callid, check_via(), copy_request(), DEFAULT_TRANS_TIMEOUT, sip_request::headers, sip_pvt::initreq, LOG_NOTICE, LOG_WARNING, sip_request::method, register_verify(), sip_get_header(), sip_methods, SIP_REGISTER, sip_scheddestroy(), sipdebug, and cfsip_methods::text.

Referenced by handle_incoming().

28992 {
28993  enum check_auth_result res;
28994 
28995  /* If this is not the intial request, and the initial request isn't
28996  * a register, something screwy happened, so bail */
28997  if (p->initreq.headers && p->initreq.method != SIP_REGISTER) {
28998  ast_log(LOG_WARNING, "Ignoring spurious REGISTER with Call-ID: %s\n", p->callid);
28999  return -1;
29000  }
29001 
29002  /* Use this as the basis */
29003  copy_request(&p->initreq, req);
29004  if (sipdebug)
29005  ast_debug(4, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid);
29006  check_via(p, req);
29007 
29008  if ((res = register_verify(p, addr, req, e)) < 0) {
29009  const char *reason;
29010 
29011  switch (res) {
29012  case AUTH_SECRET_FAILED:
29013  reason = "Wrong password";
29014  break;
29016  reason = "Username/auth name mismatch";
29017  break;
29018  case AUTH_NOT_FOUND:
29019  reason = "No matching peer found";
29020  break;
29021  case AUTH_UNKNOWN_DOMAIN:
29022  reason = "Not a local domain";
29023  break;
29024  case AUTH_PEER_NOT_DYNAMIC:
29025  reason = "Peer is not supposed to register";
29026  break;
29027  case AUTH_ACL_FAILED:
29028  reason = "Device does not match ACL";
29029  break;
29030  case AUTH_BAD_TRANSPORT:
29031  reason = "Device not configured to use this transport type";
29032  break;
29033  case AUTH_RTP_FAILED:
29034  reason = "RTP initialization failed";
29035  break;
29036  default:
29037  reason = "Unknown failure";
29038  break;
29039  }
29040  ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n",
29041  sip_get_header(req, "To"), ast_sockaddr_stringify(addr),
29042  reason);
29043  append_history(p, "RegRequest", "Failed : Account %s : %s", sip_get_header(req, "To"), reason);
29044  } else {
29045  req->authenticated = 1;
29046  append_history(p, "RegRequest", "Succeeded : Account %s", sip_get_header(req, "To"));
29047  }
29048 
29049  if (res != AUTH_CHALLENGE_SENT) {
29050  /* Destroy the session, but keep us around for just a bit in case they don't
29051  get our 200 OK */
29053  }
29054 
29055  return res;
29056 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
static const struct cfsip_methods sip_methods[]
#define LOG_WARNING
Definition: logger.h:274
static void check_via(struct sip_pvt *p, const struct sip_request *req)
check Via: header for hostname, port and rport request/answer
Definition: chan_sip.c:19164
#define DEFAULT_TRANS_TIMEOUT
Definition: sip.h:107
check_auth_result
Authentication result from check_auth* functions.
Definition: sip.h:517
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
struct sip_request initreq
Definition: sip.h:1151
static void copy_request(struct sip_request *dst, const struct sip_request *src)
copy SIP request (mostly used to save request for responses)
Definition: chan_sip.c:14061
char authenticated
Definition: sip.h:840
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.
Definition: chan_sip.c:17861
const ast_string_field callid
Definition: sip.h:1063
int method
Definition: sip.h:833
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
int headers
Definition: sip.h:832
#define LOG_NOTICE
Definition: logger.h:263
char *const text
Definition: chan_sip.c:737
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406
void sip_scheddestroy(struct sip_pvt *p, int ms)
Schedule destruction of SIP dialog.
Definition: chan_sip.c:4549

◆ handle_request_subscribe()

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

References __get_header(), add_peer_mwi_subs(), allow_notify_user_presence(), sip_settings::allowsubscribe, ao2_cleanup, ao2_lock, ao2_ref, ao2_unlock, append_history, ast_channel_creationtime(), ast_debug, AST_EXTENSION_RINGING, ast_extension_state2str(), ast_extension_state_add_destroy_extended(), ast_extension_state_del(), ast_extension_state_extended(), ast_free, ast_hint_presence_state(), AST_LIST_EMPTY, ast_log, ast_set_flag, ast_sockaddr_stringify(), ast_strdupa, ast_string_field_build, ast_strlen_zero, ast_test_flag, ast_verbose(), AUTH_CHALLENGE_SENT, AUTH_SUCCESSFUL, buf, build_contact(), build_route(), CALL_COMPLETION, sip_pvt::callid, cb_extensionstate(), cb_extensionstate_destroy(), check_user_full(), check_via(), sip_pvt::context, copy_request(), CPIM_PIDF_XML, sip_request::debug, default_expiry, state_notify_data::device_state_info, DIALOG_INFO_XML, dialog_ref, dialog_unlink_all(), dialog_unref, sip_pvt::dialogver, sip_pvt::expiry, sip_pvt::exten, extensionstate_update(), find_ringing_channel(), sip_pvt::flags, sip_peer::flags, get_destination(), gettag(), handle_cc_subscribe(), sip_request::headers, if(), sip_request::ignore, sip_pvt::initreq, sip_pvt::last_ringing_channel_time, sip_pvt::lastinvite, sip_pvt::laststate, LOG_NOTICE, LOG_WARNING, sip_peer::mailboxes, make_our_tag(), max_subexpiry, sip_request::method, min_subexpiry, MWI_NOTIFICATION, sip_peer::mwipvt, sip_peer::name, sip_pvt::needdestroy, NONE, NULL, options, parse_ok_contact(), PIDF_XML, state_notify_data::presence_message, state_notify_data::presence_state, state_notify_data::presence_subtype, pvt_set_needdestroy(), sip_pvt::relatedpeer, ringing(), S_OR, sip_pvt::sa, send_check_user_failure_response(), set_pvt_allowed_methods(), sip_cancel_destroy(), sip_cfg, SIP_GET_DEST_EXTEN_FOUND, SIP_GET_DEST_INVALID_URI, sip_get_header(), sip_methods, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PAGE2_SUBSCRIBEMWIONLY, sip_pvt_lock, sip_pvt_unlock, sip_ref_peer, sip_scheddestroy(), sip_send_mwi_to_peer(), SIP_SUBSCRIBE, sip_unref_peer, sipdebug, state_notify_data::state, sip_pvt::stateid, sip_pvt::subscribecontext, sip_pvt::subscribed, subscribed, sip_pvt::subscribeuri, sip_pvt::tag, cfsip_methods::text, transmit_response(), transmit_response_with_minexpires(), TRUE, sip_pvt::useragent, sip_pvt::username, XMIT_UNRELIABLE, and XPIDF_XML.

Referenced by handle_incoming().

28576 {
28577  int res = 0;
28578  struct sip_peer *authpeer = NULL;
28579  char *event = ast_strdupa(sip_get_header(req, "Event")); /* Get Event package name */
28580  int resubscribe = (p->subscribed != NONE) && !req->ignore;
28581  char *options;
28582 
28583  if (p->initreq.headers) {
28584  /* We already have a dialog */
28585  if (p->initreq.method != SIP_SUBSCRIBE) {
28586  /* This is a SUBSCRIBE within another SIP dialog, which we do not support */
28587  /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */
28588  transmit_response(p, "403 Forbidden (within dialog)", req);
28589  /* Do not destroy session, since we will break the call if we do */
28590  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);
28591  return 0;
28592  } else if (req->debug) {
28593  if (resubscribe)
28594  ast_debug(1, "Got a re-subscribe on existing subscription %s\n", p->callid);
28595  else
28596  ast_debug(1, "Got a new subscription %s (possibly with auth) or retransmission\n", p->callid);
28597  }
28598  }
28599 
28600  /* Check if we have a global disallow setting on subscriptions.
28601  if so, we don't have to check peer settings after auth, which saves a lot of processing
28602  */
28603  if (!sip_cfg.allowsubscribe) {
28604  transmit_response(p, "403 Forbidden (policy)", req);
28605  pvt_set_needdestroy(p, "forbidden");
28606  return 0;
28607  }
28608 
28609  if (!req->ignore && !resubscribe) { /* Set up dialog, new subscription */
28610  const char *to = sip_get_header(req, "To");
28611  char totag[128];
28612  set_pvt_allowed_methods(p, req);
28613 
28614  /* Check to see if a tag was provided, if so this is actually a resubscription of a dialog we no longer know about */
28615  if (!ast_strlen_zero(to) && gettag(req, "To", totag, sizeof(totag))) {
28616  if (req->debug)
28617  ast_verbose("Received resubscription for a dialog we no longer know about. Telling remote side to subscribe again.\n");
28618  transmit_response(p, "481 Subscription does not exist", req);
28619  pvt_set_needdestroy(p, "subscription does not exist");
28620  return 0;
28621  }
28622 
28623  /* Use this as the basis */
28624  if (req->debug)
28625  ast_verbose("Creating new subscription\n");
28626 
28627  copy_request(&p->initreq, req);
28628  if (sipdebug)
28629  ast_debug(4, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid);
28630  check_via(p, req);
28631  build_route(p, req, 0, 0);
28632  } else if (req->debug && req->ignore)
28633  ast_verbose("Ignoring this SUBSCRIBE request\n");
28634 
28635  /* Find parameters to Event: header value and remove them for now */
28636  if (ast_strlen_zero(event)) {
28637  transmit_response(p, "489 Bad Event", req);
28638  ast_debug(2, "Received SIP subscribe for unknown event package: <none>\n");
28639  pvt_set_needdestroy(p, "unknown event package in subscribe");
28640  return 0;
28641  }
28642  if ((options = strchr(event, ';')) != NULL) {
28643  *options++ = '\0';
28644  }
28645 
28646  /* Handle authentication if we're new and not a retransmission. We can't just
28647  * use if !req->ignore, because then we'll end up sending
28648  * a 200 OK if someone retransmits without sending auth */
28649  if (p->subscribed == NONE || resubscribe) {
28650  res = check_user_full(p, req, SIP_SUBSCRIBE, e, XMIT_UNRELIABLE, addr, &authpeer);
28651 
28652  /* if an authentication response was sent, we are done here */
28653  if (res == AUTH_CHALLENGE_SENT) /* authpeer = NULL here */
28654  return 0;
28655  if (res != AUTH_SUCCESSFUL) {
28657  pvt_set_needdestroy(p, "authentication failed");
28658  return 0;
28659  }
28660  }
28661 
28662  /* At this point, we hold a reference to authpeer (if not NULL). It
28663  * must be released when done.
28664  */
28665 
28666  /* Check if this device is allowed to subscribe at all */
28668  transmit_response(p, "403 Forbidden (policy)", req);
28669  pvt_set_needdestroy(p, "subscription not allowed");
28670  if (authpeer) {
28671  sip_unref_peer(authpeer, "sip_unref_peer, from handle_request_subscribe (authpeer 1)");
28672  }
28673  return 0;
28674  }
28675 
28676  /* Get full contact header - this needs to be used as a request URI in NOTIFY's */
28677  parse_ok_contact(p, req);
28678  build_contact(p, req, 1);
28679 
28680  /* Initialize tag for new subscriptions */
28681  if (ast_strlen_zero(p->tag)) {
28682  make_our_tag(p);
28683  }
28684 
28685  if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */
28686  int gotdest;
28687  const char *accept;
28688  int start = 0;
28690  const char *unknown_accept = NULL;
28691 
28692  /* Get destination right away */
28693  gotdest = get_destination(p, NULL, NULL);
28694  if (gotdest != SIP_GET_DEST_EXTEN_FOUND) {
28695  if (gotdest == SIP_GET_DEST_INVALID_URI) {
28696  transmit_response(p, "416 Unsupported URI scheme", req);
28697  } else {
28698  transmit_response(p, "404 Not Found", req);
28699  }
28700  pvt_set_needdestroy(p, "subscription target not found");
28701  if (authpeer) {
28702  sip_unref_peer(authpeer, "sip_unref_peer, from handle_request_subscribe (authpeer 2)");
28703  }
28704  return 0;
28705  }
28706 
28707  /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */
28708  accept = __get_header(req, "Accept", &start);
28709  while ((subscribed == NONE) && !ast_strlen_zero(accept)) {
28710  if (strstr(accept, "application/pidf+xml")) {
28711  if (strstr(p->useragent, "Polycom")) {
28712  subscribed = XPIDF_XML; /* Older versions of Polycom firmware will claim pidf+xml, but really they only support xpidf+xml */
28713  } else {
28714  subscribed = PIDF_XML; /* RFC 3863 format */
28715  }
28716  } else if (strstr(accept, "application/dialog-info+xml")) {
28717  subscribed = DIALOG_INFO_XML;
28718  /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */
28719  } else if (strstr(accept, "application/cpim-pidf+xml")) {
28720  subscribed = CPIM_PIDF_XML; /* RFC 3863 format */
28721  } else if (strstr(accept, "application/xpidf+xml")) {
28722  subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */
28723  } else {
28724  unknown_accept = accept;
28725  }
28726  /* check to see if there is another Accept header present */
28727  accept = __get_header(req, "Accept", &start);
28728  }
28729 
28730  if (!start) {
28731  if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */
28732  transmit_response(p, "489 Bad Event", req);
28733  ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: "
28734  "stateid: %d, laststate: %d, dialogver: %u, subscribecont: "
28735  "'%s', subscribeuri: '%s'\n",
28736  p->stateid,
28737  p->laststate,
28738  p->dialogver,
28739  p->subscribecontext,
28740  p->subscribeuri);
28741  pvt_set_needdestroy(p, "no Accept header");
28742  if (authpeer) {
28743  sip_unref_peer(authpeer, "sip_unref_peer, from handle_request_subscribe (authpeer 2)");
28744  }
28745  return 0;
28746  }
28747  /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least.
28748  so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */
28749  } else if (subscribed == NONE) {
28750  /* Can't find a format for events that we know about */
28751  char buf[200];
28752 
28753  if (!ast_strlen_zero(unknown_accept)) {
28754  snprintf(buf, sizeof(buf), "489 Bad Event (format %s)", unknown_accept);
28755  } else {
28756  snprintf(buf, sizeof(buf), "489 Bad Event");
28757  }
28758  transmit_response(p, buf, req);
28759  ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format:"
28760  "'%s' pvt: subscribed: %d, stateid: %d, laststate: %d,"
28761  "dialogver: %u, subscribecont: '%s', subscribeuri: '%s'\n",
28762  unknown_accept,
28763  (int)p->subscribed,
28764  p->stateid,
28765  p->laststate,
28766  p->dialogver,
28767  p->subscribecontext,
28768  p->subscribeuri);
28769  pvt_set_needdestroy(p, "unrecognized format");
28770  if (authpeer) {
28771  sip_unref_peer(authpeer, "sip_unref_peer, from handle_request_subscribe (authpeer 2)");
28772  }
28773  return 0;
28774  } else {
28775  p->subscribed = subscribed;
28776  }
28777  } else if (!strcmp(event, "message-summary")) {
28778  int start = 0;
28779  int found_supported = 0;
28780  const char *accept;
28781 
28782  accept = __get_header(req, "Accept", &start);
28783  while (!found_supported && !ast_strlen_zero(accept)) {
28784  found_supported = strcmp(accept, "application/simple-message-summary") ? 0 : 1;
28785  if (!found_supported) {
28786  ast_debug(3, "Received SIP mailbox subscription for unknown format: %s\n", accept);
28787  }
28788  accept = __get_header(req, "Accept", &start);
28789  }
28790  /* If !start, there is no Accept header at all */
28791  if (start && !found_supported) {
28792  /* Format requested that we do not support */
28793  transmit_response(p, "406 Not Acceptable", req);
28794  ast_debug(2, "Received SIP mailbox subscription for unknown format\n");
28795  pvt_set_needdestroy(p, "unknown format");
28796  if (authpeer) {
28797  sip_unref_peer(authpeer, "sip_unref_peer, from handle_request_subscribe (authpeer 3)");
28798  }
28799  return 0;
28800  }
28801  /* Looks like they actually want a mailbox status
28802  This version of Asterisk supports mailbox subscriptions
28803  The subscribed URI needs to exist in the dial plan
28804  In most devices, this is configurable to the voicemailmain extension you use
28805  */
28806  if (!authpeer || AST_LIST_EMPTY(&authpeer->mailboxes)) {
28807  if (!authpeer) {
28808  transmit_response(p, "404 Not found", req);
28809  } else {
28810  transmit_response(p, "404 Not found (no mailbox)", req);
28811  ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", S_OR(authpeer->name, ""));
28812  }
28813  pvt_set_needdestroy(p, "received 404 response");
28814 
28815  if (authpeer) {
28816  sip_unref_peer(authpeer, "sip_unref_peer, from handle_request_subscribe (authpeer 3)");
28817  }
28818  return 0;
28819  }
28820 
28822  if (ast_test_flag(&authpeer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY)) {
28823  ao2_unlock(p);
28824  add_peer_mwi_subs(authpeer);
28825  ao2_lock(p);
28826  }
28827  if (authpeer->mwipvt != p) { /* Destroy old PVT if this is a new one */
28828  /* We only allow one subscription per peer */
28829  if (authpeer->mwipvt) {
28830  dialog_unlink_all(authpeer->mwipvt);
28831  authpeer->mwipvt = dialog_unref(authpeer->mwipvt, "unref dialog authpeer->mwipvt");
28832  }
28833  authpeer->mwipvt = dialog_ref(p, "setting peers' mwipvt to p");
28834  }
28835 
28836  if (p->relatedpeer != authpeer) {
28837  if (p->relatedpeer) {
28838  sip_unref_peer(p->relatedpeer, "Unref previously stored relatedpeer ptr");
28839  }
28840  p->relatedpeer = sip_ref_peer(authpeer, "setting dialog's relatedpeer pointer");
28841  }
28842  /* Do not release authpeer here */
28843  } else if (!strcmp(event, "call-completion")) {
28844  handle_cc_subscribe(p, req);
28845  } else { /* At this point, Asterisk does not understand the specified event */
28846  transmit_response(p, "489 Bad Event", req);
28847  ast_debug(2, "Received SIP subscribe for unknown event package: %s\n", event);
28848  pvt_set_needdestroy(p, "unknown event package");
28849  if (authpeer) {
28850  sip_unref_peer(authpeer, "sip_unref_peer, from handle_request_subscribe (authpeer 5)");
28851  }
28852  return 0;
28853  }
28854 
28855  if (!req->ignore) {
28856  p->lastinvite = seqno;
28857  }
28858  if (!p->needdestroy) {
28859  const char *expires_str = sip_get_header(req, "Expires");
28860 
28861  if (ast_strlen_zero(expires_str)) {
28862  p->expiry = default_expiry;
28863  } else {
28864  p->expiry = atoi(expires_str);
28865  }
28866 
28867  /* check if the requested expiry-time is within the approved limits from sip.conf */
28868  if (p->expiry > max_subexpiry) {
28869  p->expiry = max_subexpiry;
28870  } else if (p->expiry < min_subexpiry && p->expiry > 0) {
28871  transmit_response_with_minexpires(p, "423 Interval too small", req, min_subexpiry);
28872  ast_log(LOG_WARNING, "Received subscription for extension \"%s\" context \"%s\" "
28873  "with Expire header less than 'subminexpire' limit. Received \"Expire: %d\" min is %d\n",
28874  p->exten, p->context, p->expiry, min_subexpiry);
28875  pvt_set_needdestroy(p, "Expires is less that the min expires allowed.");
28876  if (authpeer) {
28877  sip_unref_peer(authpeer, "sip_unref_peer, from handle_request_subscribe (authpeer 6)");
28878  }
28879  return 0;
28880  }
28881 
28882  if (sipdebug) {
28883  const char *action = p->expiry > 0 ? "Adding" : "Removing";
28884  if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) {
28885  ast_debug(2, "%s subscription for mailbox notification - peer %s\n",
28886  action, p->relatedpeer->name);
28887  } else if (p->subscribed == CALL_COMPLETION) {
28888  ast_debug(2, "%s CC subscription for peer %s\n", action, p->username);
28889  } else {
28890  ast_debug(2, "%s subscription for extension %s context %s for peer %s\n",
28891  action, p->exten, p->context, p->username);
28892  }
28893  }
28894 
28895  /* Remove subscription expiry for renewals */
28896  sip_cancel_destroy(p);
28897  if (p->expiry > 0) {
28898  /* Set timer for destruction of call at expiration */
28899  sip_scheddestroy(p, (p->expiry + 10) * 1000);
28900  }
28901 
28902  if (p->subscribed == MWI_NOTIFICATION) {
28904  transmit_response(p, "200 OK", req);
28905  if (p->relatedpeer) { /* Send first notification */
28906  struct sip_peer *peer = p->relatedpeer;
28907  sip_ref_peer(peer, "ensure a peer ref is held during MWI sending");
28908  ao2_unlock(p);
28909  sip_send_mwi_to_peer(peer, 0);
28910  ao2_lock(p);
28911  sip_unref_peer(peer, "release a peer ref now that MWI is sent");
28912  }
28913  } else if (p->subscribed != CALL_COMPLETION) {
28914  struct state_notify_data data = { 0, };
28915  char *subtype = NULL;
28916  char *message = NULL;
28917  struct ao2_container *device_state_info = NULL;
28918 
28919  if (p->expiry > 0 && !resubscribe) {
28920  /* Add subscription for extension state from the PBX core */
28921  if (p->stateid != -1) {
28923  }
28924  dialog_ref(p, "copying dialog ptr into extension state struct");
28926  if (p->stateid == -1) {
28927  dialog_unref(p, "copying dialog ptr into extension state struct failed");
28928  }
28929  }
28930 
28931  sip_pvt_unlock(p);
28932  data.state = ast_extension_state_extended(NULL, p->context, p->exten, &device_state_info);
28933  sip_pvt_lock(p);
28934 
28935  if (data.state < 0) {
28936  ao2_cleanup(device_state_info);
28937  if (p->expiry > 0) {
28938  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));
28939  }
28940  transmit_response(p, "404 Not found", req);
28941  pvt_set_needdestroy(p, "no extension for SUBSCRIBE");
28942  if (authpeer) {
28943  sip_unref_peer(authpeer, "sip_unref_peer, from handle_request_subscribe (authpeer 6)");
28944  }
28945  return 0;
28946  }
28947  if (allow_notify_user_presence(p)) {
28948  data.presence_state = ast_hint_presence_state(NULL, p->context, p->exten, &subtype, &message);
28949  data.presence_subtype = subtype;
28950  data.presence_message = message;
28951  }
28953  transmit_response(p, "200 OK", req);
28954  /* RFC 3265: A notification must be sent on every subscribe, so force it */
28955  data.device_state_info = device_state_info;
28956  if (data.state & AST_EXTENSION_RINGING) {
28957  /* save last_ringing_channel_time if this state really contains a ringing channel
28958  * because extensionstate_update() doesn't do it if forced
28959  */
28961  if (ringing) {
28963  ao2_ref(ringing, -1);
28964  }
28965  /* If there is no channel, this likely indicates that the ringing indication
28966  * is due to a custom device state. These do not have associated channels.
28967  */
28968  }
28969  extensionstate_update(p->context, p->exten, &data, p, TRUE);
28970  append_history(p, "Subscribestatus", "%s", ast_extension_state2str(data.state));
28971  /* hide the 'complete' exten/context in the refer_to field for later display */
28972  ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context);
28973  /* Deleted the slow iteration of all sip dialogs to find old subscribes from this peer for exten@context */
28974 
28975  ao2_cleanup(device_state_info);
28976  ast_free(subtype);
28977  ast_free(message);
28978  }
28979  if (!p->expiry) {
28980  pvt_set_needdestroy(p, "forcing expiration");
28981  }
28982  }
28983 
28984  if (authpeer) {
28985  sip_unref_peer(authpeer, "unref pointer into (*authpeer)");
28986  }
28987  return 1;
28988 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
int ast_extension_state_add_destroy_extended(const char *context, const char *exten, ast_state_cb_type change_cb, ast_state_cb_destroy_type destroy_cb, void *data)
Add watcher for extended extension states with destructor.
Definition: pbx.c:3831
Main Channel structure associated with a channel.
char debug
Definition: sip.h:837
#define SIP_PAGE2_ALLOWSUBSCRIBE
Definition: sip.h:335
enum subscriptiontype subscribed
Definition: sip.h:1161
static void send_check_user_failure_response(struct sip_pvt *p, struct sip_request *req, int res, enum xmittype reliable)
Definition: chan_sip.c:19626
static int extensionstate_update(const char *context, const char *exten, struct state_notify_data *data, struct sip_pvt *p, int force)
Callback for the devicestate notification (SUBSCRIBE) support subsystem.
Definition: chan_sip.c:17610
#define ast_test_flag(p, flag)
Definition: utils.h:63
static const struct cfsip_methods sip_methods[]
#define NONE
Definition: misdn_config.c:45
struct sip_peer * relatedpeer
Definition: sip.h:1171
int ast_extension_state_del(int id, ast_state_cb_type change_cb)
Deletes a state change watcher by ID.
Definition: pbx.c:3858
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
uint32_t dialogver
Definition: sip.h:1167
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define LOG_WARNING
Definition: logger.h:274
static void check_via(struct sip_pvt *p, const struct sip_request *req)
check Via: header for hostname, port and rport request/answer
Definition: chan_sip.c:19164
unsigned short needdestroy
Definition: sip.h:1080
const ast_string_field username
Definition: sip.h:1063
if(!yyg->yy_init)
Definition: ast_expr2f.c:868
static const char * gettag(const struct sip_request *req, const char *header, char *tagbuf, int tagbufsize)
Get tag from packet.
Definition: chan_sip.c:25654
Definition: astman.c:222
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
#define SIP_PAGE2_SUBSCRIBEMWIONLY
Definition: sip.h:343
#define ao2_unlock(a)
Definition: astobj2.h:730
struct ast_flags flags[3]
Definition: sip.h:1075
const ast_string_field context
Definition: sip.h:1063
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
const ast_string_field subscribecontext
Definition: sip.h:1063
#define NULL
Definition: resample.c:96
#define sip_ref_peer(peer, tag)
Definition: sip.h:1894
int ast_hint_presence_state(struct ast_channel *c, const char *context, const char *exten, char **subtype, char **message)
Uses hint and presence state callback to get the presence state of an extension.
Definition: pbx.c:3226
int allowsubscribe
Definition: sip.h:777
static int handle_cc_subscribe(struct sip_pvt *p, struct sip_request *req)
Definition: chan_sip.c:28516
static void make_our_tag(struct sip_pvt *pvt)
Make our SIP dialog tag.
Definition: chan_sip.c:8908
static void build_route(struct sip_pvt *p, struct sip_request *req, int backwards, int resp)
Build route list from Record-Route header.
Definition: chan_sip.c:17201
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
char name[80]
Definition: sip.h:1274
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
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 u...
Definition: chan_sip.c:19486
static int allow_notify_user_presence(struct sip_pvt *p)
Definition: chan_sip.c:15187
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 stor...
Definition: chan_sip.c:3367
struct ast_sockaddr sa
Definition: sip.h:1125
static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req)
Transmit response, no retransmits.
Definition: chan_sip.c:12655
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
const char * presence_message
Definition: chan_sip.c:1012
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.
Definition: chan_sip.c:18508
Definition: sip.h:475
struct sip_request initreq
Definition: sip.h:1151
static int min_subexpiry
Definition: chan_sip.c:670
static void ringing(struct ast_channel *chan)
Helper method to send a ringing indication to a channel in a bridge.
static void copy_request(struct sip_request *dst, const struct sip_request *src)
copy SIP request (mostly used to save request for responses)
Definition: chan_sip.c:14061
#define ao2_ref(o, delta)
Definition: astobj2.h:464
const char * ast_extension_state2str(int extension_state)
Return string representation of the state of an extension.
Definition: pbx.c:3126
const ast_string_field exten
Definition: sip.h:1063
#define ao2_lock(a)
Definition: astobj2.h:718
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static int sip_send_mwi_to_peer(struct sip_peer *peer, int cache_only)
Send message waiting indication to alert peer that they&#39;ve got voicemail.
Definition: chan_sip.c:29756
struct sip_peer::@176 mailboxes
int expiry
Definition: sip.h:1118
static int default_expiry
Definition: chan_sip.c:669
int ast_extension_state_extended(struct ast_channel *c, const char *context, const char *exten, struct ao2_container **device_state_info)
Uses hint and devicestate callback to get the extended state of an extension.
Definition: pbx.c:3176
static const char * __get_header(const struct sip_request *req, const char *name, int *start)
Definition: chan_sip.c:8562
static int subscribed
Definition: manager.c:1476
const ast_string_field callid
Definition: sip.h:1063
const ast_string_field useragent
Definition: sip.h:1063
static void pvt_set_needdestroy(struct sip_pvt *pvt, const char *reason)
Definition: chan_sip.c:3429
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
static int transmit_response_with_minexpires(struct sip_pvt *p, const char *msg, const struct sip_request *req, int minexpires)
Append Min-Expires header, content length before transmitting response.
Definition: chan_sip.c:12742
struct ao2_container * device_state_info
Definition: chan_sip.c:1009
int method
Definition: sip.h:833
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
static void cb_extensionstate_destroy(int id, void *data)
Definition: chan_sip.c:17600
int headers
Definition: sip.h:832
struct timeval ast_channel_creationtime(struct ast_channel *chan)
static int cb_extensionstate(const char *context, const char *exten, struct ast_state_cb_info *info, void *data)
Callback for the devicestate notification (SUBSCRIBE) support subsystem.
Definition: chan_sip.c:17692
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
#define LOG_NOTICE
Definition: logger.h:263
Definition: sip.h:478
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
static void build_contact(struct sip_pvt *p, struct sip_request *req, int incoming)
Build contact header.
Definition: chan_sip.c:14385
#define ast_free(a)
Definition: astmm.h:182
int stateid
Definition: sip.h:1162
#define dialog_ref(dialog, tag)
when we create or delete references, make sure to use these functions so we keep track of the refcoun...
Definition: dialog.h:32
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
Definition: stringfields.h:550
static int max_subexpiry
Definition: chan_sip.c:671
char *const text
Definition: chan_sip.c:737
static struct ast_channel * find_ringing_channel(struct ao2_container *device_state_info, struct sip_pvt *p)
Definition: chan_sip.c:15161
struct timeval last_ringing_channel_time
Definition: sip.h:1165
const char * presence_subtype
Definition: chan_sip.c:1011
void sip_cancel_destroy(struct sip_pvt *pvt)
Cancel destruction of SIP dialog.
Definition: chan_sip.c:4464
static void add_peer_mwi_subs(struct sip_peer *peer)
Definition: chan_sip.c:28499
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct sip_pvt * mwipvt
Definition: sip.h:1367
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
struct ast_flags flags[3]
Definition: sip.h:1335
#define TRUE
Definition: app_minivm.c:518
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406
char ignore
Definition: sip.h:839
uint32_t lastinvite
Definition: sip.h:1074
const ast_string_field tag
Definition: sip.h:1063
int laststate
Definition: sip.h:1163
static unsigned int set_pvt_allowed_methods(struct sip_pvt *pvt, struct sip_request *req)
Definition: chan_sip.c:9880
Generic container type.
static struct test_options options
#define SIP_PAGE2_DIALOG_ESTABLISHED
Definition: sip.h:358
const ast_string_field subscribeuri
Definition: sip.h:1063
void sip_scheddestroy(struct sip_pvt *p, int ms)
Schedule destruction of SIP dialog.
Definition: chan_sip.c:4549
subscriptiontype
Type of subscription, based on the packages we do support, see subscription_types.
Definition: sip.h:473
static int parse_ok_contact(struct sip_pvt *pvt, struct sip_request *req)
Save contact header for 200 OK on INVITE.
Definition: chan_sip.c:16811

◆ handle_request_update()

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

References ast_channel_queue_connected_line_update(), AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, ast_party_connected_line_init(), ast_set_party_id_all(), ast_strlen_zero, sip_pvt::callingpres, sip_pvt::cid_name, sip_pvt::cid_num, sip_pvt::cid_tag, connected, 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, sip_pvt::owner, ast_party_name::presentation, ast_party_number::presentation, ast_set_party_connected_line::priv, sip_get_header(), 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().

26165 {
26166  if (ast_strlen_zero(sip_get_header(req, "X-Asterisk-rpid-update"))) {
26167  transmit_response(p, "501 Method Not Implemented", req);
26168  return 0;
26169  }
26170  if (!p->owner) {
26171  transmit_response(p, "481 Call/Transaction Does Not Exist", req);
26172  return 0;
26173  }
26174  if (get_rpid(p, req)) {
26176  struct ast_set_party_connected_line update_connected;
26177 
26179  memset(&update_connected, 0, sizeof(update_connected));
26180 
26181  update_connected.id.number = 1;
26182  connected.id.number.valid = 1;
26183  connected.id.number.str = (char *) p->cid_num;
26184  connected.id.number.presentation = p->callingpres;
26185 
26186  update_connected.id.name = 1;
26187  connected.id.name.valid = 1;
26188  connected.id.name.str = (char *) p->cid_name;
26189  connected.id.name.presentation = p->callingpres;
26190 
26191  /* Invalidate any earlier private connected id representation */
26192  ast_set_party_id_all(&update_connected.priv);
26193 
26194  connected.id.tag = (char *) p->cid_tag;
26196  ast_channel_queue_connected_line_update(p->owner, &connected, &update_connected);
26197  }
26198  transmit_response(p, "200 OK", req);
26199  return 0;
26200 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
Definition: channel.c:2022
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 fou...
Definition: chan_sip.c:18266
#define ast_strlen_zero(foo)
Definition: strings.h:52
static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req)
Transmit response, no retransmits.
Definition: chan_sip.c:12655
void ast_channel_queue_connected_line_update(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Queue a connected line update frame on a channel.
Definition: channel.c:9202
int callingpres
Definition: sip.h:1117
const ast_string_field cid_num
Definition: sip.h:1063
Connected Line/Party information.
Definition: channel.h:457
struct ast_channel * owner
Definition: sip.h:1138
Indicate what information in ast_party_connected_line should be set.
Definition: channel.h:490
const ast_string_field cid_name
Definition: sip.h:1063
const ast_string_field cid_tag
Definition: sip.h:1063
void ast_set_party_id_all(struct ast_set_party_id *update_id)
Set the update marker to update all information of a corresponding party id.
Definition: channel.c:1750
char connected
Definition: eagi_proxy.c:82

◆ handle_response()

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

Handle SIP response in dialogue.

Note
only called by handle_incoming

Definition at line 25171 of file chan_sip.c.

References __sip_ack(), __sip_semi_ack(), sip_pvt::allowed_methods, append_history, AST_CC_CCBS, ast_channel_hangupcause_set(), ast_channel_name(), 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(), sip_invite_param::auth_type, sip_pvt::authname, sip_pvt::authtries, c, sip_pvt::callid, change_redirecting_information(), sip_request::debug, sip_peer::disallowed_methods, do_proxy_auth(), FALSE, find_sdp(), find_sip_method(), sip_pvt::flags, 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(), sip_request::ignore, sip_pvt::initreq, LOG_NOTICE, LOG_WARNING, mark_method_allowed(), mark_method_unallowed(), MAX_AUTHTRIES, sip_pvt::options, sip_pvt::owner, sip_pvt::pendinginvite, process_sdp(), pvt_set_needdestroy(), sip_pvt::recv, sip_pvt::registry, sip_pvt::relatedpeer, sip_pvt::sa, SDP_T38_NONE, SIP_ACK, sip_alreadygone(), SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), sip_get_header(), sip_handle_cc(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NOTIFY, SIP_OPTIONS, SIP_OUTGOING, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWOVERLAP_YES, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PUBLISH, SIP_REFER, SIP_REGISTER, SIP_SUBSCRIBE, SIP_UPDATE, sipdebug, stop_media_flows(), text, sip_pvt::theirtag, transmit_request(), TRUE, update_redirecting(), use_reason_header(), and XMIT_UNRELIABLE.

Referenced by handle_incoming().

25172 {
25173  struct ast_channel *owner;
25174  int sipmethod;
25175  const char *c = sip_get_header(req, "Cseq");
25176  /* 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 */
25177  char *c_copy = ast_strdupa(c);
25178  /* Skip the Cseq and its subsequent spaces */
25179  const char *msg = ast_skip_blanks(ast_skip_nonblanks(c_copy));
25180  int ack_res = FALSE;
25181 
25182  if (!msg)
25183  msg = "";
25184 
25185  sipmethod = find_sip_method(msg);
25186  owner = p->owner;
25187  if (owner) {
25188  ast_channel_hangupcause_set(owner, 0);
25189  if (use_reason_header(p, req)) {
25190  /* Use the SIP cause */
25192  }
25193  }
25194 
25195  /* Acknowledge whatever it is destined for */
25196  if ((resp >= 100) && (resp <= 199)) {
25197  /* NON-INVITE messages do not ack a 1XX response. RFC 3261 section 17.1.2.2 */
25198  if (sipmethod == SIP_INVITE) {
25199  ack_res = __sip_semi_ack(p, seqno, 0, sipmethod);
25200  }
25201  } else {
25202  ack_res = __sip_ack(p, seqno, 0, sipmethod);
25203  }
25204 
25205  if (ack_res == FALSE) {
25206  /* RFC 3261 13.2.2.4 and 17.1.1.2 - We must re-send ACKs to re-transmitted final responses */
25207  if (sipmethod == SIP_INVITE && resp >= 200) {
25208  transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, resp < 300 ? TRUE: FALSE);
25209  }
25210 
25211  append_history(p, "Ignore", "Ignoring this retransmit\n");
25212  return;
25213  }
25214 
25215  /* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */
25216  if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite) {
25217  p->pendinginvite = 0;
25218  }
25219 
25220  /* Get their tag if we haven't already */
25221  if (ast_strlen_zero(p->theirtag) || (resp >= 200)) {
25222  char tag[128];
25223 
25224  gettag(req, "To", tag, sizeof(tag));
25225  ast_string_field_set(p, theirtag, tag);
25226  } else {
25227  /* Store theirtag to track for changes when 200 responses to invites are received without SDP */
25228  ast_string_field_set(p, theirprovtag, p->theirtag);
25229  }
25230 
25231  /* This needs to be configurable on a channel/peer level,
25232  not mandatory for all communication. Sadly enough, NAT implementations
25233  are not so stable so we can always rely on these headers.
25234  Temporarily disabled, while waiting for fix.
25235  Fix assigned to Rizzo :-)
25236  */
25237  /* check_via_response(p, req); */
25238 
25239  /* RFC 3261 Section 15 specifies that if we receive a 408 or 481
25240  * in response to a BYE, then we should end the current dialog
25241  * and session. It is known that at least one phone manufacturer
25242  * potentially will send a 404 in response to a BYE, so we'll be
25243  * liberal in what we accept and end the dialog and session if we
25244  * receive any of those responses to a BYE.
25245  */
25246  if ((resp == 404 || resp == 408 || resp == 481) && sipmethod == SIP_BYE) {
25247  pvt_set_needdestroy(p, "received 4XX response to a BYE");
25248  return;
25249  }
25250 
25251  if (p->relatedpeer && sipmethod == SIP_OPTIONS) {
25252  /* We don't really care what the response is, just that it replied back.
25253  Well, as long as it's not a 100 response... since we might
25254  need to hang around for something more "definitive" */
25255  if (resp != 100)
25256  handle_response_peerpoke(p, resp, req);
25257  } else if (sipmethod == SIP_REFER && resp >= 200) {
25258  handle_response_refer(p, resp, rest, req, seqno);
25259  } else if (sipmethod == SIP_PUBLISH) {
25260  /* SIP PUBLISH transcends this morass of doodoo and instead
25261  * we just always call the response handler. Good gravy!
25262  */
25263  handle_response_publish(p, resp, rest, req, seqno);
25264  } else if (sipmethod == SIP_INFO) {
25265  /* More good gravy! */
25266  handle_response_info(p, resp, rest, req, seqno);
25267  } else if (sipmethod == SIP_MESSAGE) {
25268  /* More good gravy! */
25269  handle_response_message(p, resp, rest, req, seqno);
25270  } else if (sipmethod == SIP_NOTIFY) {
25271  /* The gravy train continues to roll */
25272  handle_response_notify(p, resp, rest, req, seqno);
25273  } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
25274  switch(resp) {
25275  case 100: /* 100 Trying */
25276  case 101: /* 101 Dialog establishment */
25277  case 183: /* 183 Session Progress */
25278  case 180: /* 180 Ringing */
25279  case 182: /* 182 Queued */
25280  case 181: /* 181 Call Is Being Forwarded */
25281  if (sipmethod == SIP_INVITE)
25282  handle_response_invite(p, resp, rest, req, seqno);
25283  break;
25284  case 200: /* 200 OK */
25285  p->authtries = 0; /* Reset authentication counter */
25286  if (sipmethod == SIP_INVITE) {
25287  handle_response_invite(p, resp, rest, req, seqno);
25288  } else if (sipmethod == SIP_REGISTER) {
25289  handle_response_register(p, resp, rest, req, seqno);
25290  } else if (sipmethod == SIP_SUBSCRIBE) {
25292  handle_response_subscribe(p, resp, rest, req, seqno);
25293  } else if (sipmethod == SIP_BYE) { /* Ok, we're ready to go */
25294  pvt_set_needdestroy(p, "received 200 response");
25296  }
25297  break;
25298  case 401: /* Not www-authorized on SIP method */
25299  case 407: /* Proxy auth required */
25300  if (sipmethod == SIP_INVITE)
25301  handle_response_invite(p, resp, rest, req, seqno);
25302  else if (sipmethod == SIP_SUBSCRIBE)
25303  handle_response_subscribe(p, resp, rest, req, seqno);
25304  else if (p->registry && sipmethod == SIP_REGISTER)
25305  handle_response_register(p, resp, rest, req, seqno);
25306  else if (sipmethod == SIP_UPDATE) {
25307  handle_response_update(p, resp, rest, req, seqno);
25308  } else if (sipmethod == SIP_BYE) {
25309  if (p->options)
25310  p->options->auth_type = resp;
25311  if (ast_strlen_zero(p->authname)) {
25312  ast_log(LOG_WARNING, "Asked to authenticate %s, to %s but we have no matching peer!\n",
25313  msg, ast_sockaddr_stringify(&p->recv));
25314  pvt_set_needdestroy(p, "unable to authenticate BYE");
25315  } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, resp, sipmethod, 0)) {
25316  ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, sip_get_header(&p->initreq, "From"));
25317  pvt_set_needdestroy(p, "failed to authenticate BYE");
25318  }
25319  } else {
25320  ast_log(LOG_WARNING, "Got authentication request (%d) on %s to '%s'\n", resp, sip_methods[sipmethod].text, sip_get_header(req, "To"));
25321  pvt_set_needdestroy(p, "received 407 response");
25322  }
25323  break;
25324  case 403: /* Forbidden - we failed authentication */
25325  if (sipmethod == SIP_INVITE)
25326  handle_response_invite(p, resp, rest, req, seqno);
25327  else if (sipmethod == SIP_SUBSCRIBE)
25328  handle_response_subscribe(p, resp, rest, req, seqno);
25329  else if (p->registry && sipmethod == SIP_REGISTER)
25330  handle_response_register(p, resp, rest, req, seqno);
25331  else {
25332  ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg);
25333  pvt_set_needdestroy(p, "received 403 response");
25334  }
25335  break;
25336  case 400: /* Bad Request */
25337  case 414: /* Request URI too long */
25338  case 493: /* Undecipherable */
25339  case 404: /* Not found */
25340  if (p->registry && sipmethod == SIP_REGISTER)
25341  handle_response_register(p, resp, rest, req, seqno);
25342  else if (sipmethod == SIP_INVITE)
25343  handle_response_invite(p, resp, rest, req, seqno);
25344  else if (sipmethod == SIP_SUBSCRIBE)
25345  handle_response_subscribe(p, resp, rest, req, seqno);
25346  else if (owner)
25348  break;
25349  case 423: /* Interval too brief */
25350  if (sipmethod == SIP_REGISTER)
25351  handle_response_register(p, resp, rest, req, seqno);
25352  break;
25353  case 408: /* Request timeout - terminate dialog */
25354  if (sipmethod == SIP_INVITE)
25355  handle_response_invite(p, resp, rest, req, seqno);
25356  else if (sipmethod == SIP_REGISTER)
25357  handle_response_register(p, resp, rest, req, seqno);
25358  else if (sipmethod == SIP_BYE) {
25359  pvt_set_needdestroy(p, "received 408 response");
25360  ast_debug(4, "Got timeout on bye. Thanks for the answer. Now, kill this call\n");
25361  } else {
25362  if (owner)
25364  pvt_set_needdestroy(p, "received 408 response");
25365  }
25366  break;
25367 
25368  case 428:
25369  case 422: /* Session-Timers: Session Interval Too Small */
25370  if (sipmethod == SIP_INVITE) {
25371  handle_response_invite(p, resp, rest, req, seqno);
25372  }
25373  break;
25374  case 480:
25375  if (sipmethod == SIP_INVITE) {
25376  handle_response_invite(p, resp, rest, req, seqno);
25377  } else if (sipmethod == SIP_SUBSCRIBE) {
25378  handle_response_subscribe(p, resp, rest, req, seqno);
25379  } else if (owner) {
25380  /* No specific handler. Default to congestion */
25382  }
25383  break;
25384  case 481: /* Call leg does not exist */
25385  if (sipmethod == SIP_INVITE) {
25386  handle_response_invite(p, resp, rest, req, seqno);
25387  } else if (sipmethod == SIP_SUBSCRIBE) {
25388  handle_response_subscribe(p, resp, rest, req, seqno);
25389  } else if (sipmethod == SIP_BYE) {
25390  /* The other side has no transaction to bye,
25391  just assume it's all right then */
25392  ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
25393  } else if (sipmethod == SIP_CANCEL) {
25394  /* The other side has no transaction to cancel,
25395  just assume it's all right then */
25396  ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
25397  } else {
25398  ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
25399  /* Guessing that this is not an important request */
25400  }
25401  break;
25402  case 487:
25403  if (sipmethod == SIP_INVITE)
25404  handle_response_invite(p, resp, rest, req, seqno);
25405  break;
25406  case 415: /* Unsupported media type */
25407  case 488: /* Not acceptable here - codec error */
25408  case 606: /* Not Acceptable */
25409  if (sipmethod == SIP_INVITE)
25410  handle_response_invite(p, resp, rest, req, seqno);
25411  break;
25412  case 491: /* Pending */
25413  if (sipmethod == SIP_INVITE)
25414  handle_response_invite(p, resp, rest, req, seqno);
25415  else {
25416  ast_debug(1, "Got 491 on %s, unsupported. Call ID %s\n", sip_methods[sipmethod].text, p->callid);
25417  pvt_set_needdestroy(p, "received 491 response");
25418  }
25419  break;
25420  case 405: /* Method not allowed */
25421  case 501: /* Not Implemented */
25422  mark_method_unallowed(&p->allowed_methods, sipmethod);
25423  if (p->relatedpeer) {
25425  }
25426  if (sipmethod == SIP_INVITE)
25427  handle_response_invite(p, resp, rest, req, seqno);
25428  else
25429  ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_sockaddr_stringify(&p->sa), msg);
25430  break;
25431  default:
25432  if ((resp >= 200) && (resp < 300)) { /* on any 2XX response do the following */
25433  if (sipmethod == SIP_INVITE) {
25434  handle_response_invite(p, resp, rest, req, seqno);
25435  }
25436  } else if ((resp >= 300) && (resp < 700)) {
25437  /* Fatal response */
25438  if ((resp != 487))
25439  ast_verb(3, "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_sockaddr_stringify(&p->sa));
25440 
25441  if (sipmethod == SIP_INVITE)
25442  stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
25443 
25444  /* XXX Locking issues?? XXX */
25445  switch(resp) {
25446  case 300: /* Multiple Choices */
25447  case 301: /* Moved permanently */
25448  case 302: /* Moved temporarily */
25449  case 305: /* Use Proxy */
25450  if (p->owner) {
25451  struct ast_party_redirecting redirecting;
25453 
25454  ast_party_redirecting_init(&redirecting);
25455  memset(&update_redirecting, 0, sizeof(update_redirecting));
25456  change_redirecting_information(p, req, &redirecting,
25458  ast_channel_set_redirecting(p->owner, &redirecting,
25460  ast_party_redirecting_free(&redirecting);
25461  }
25462  /* Fall through */
25463  case 486: /* Busy here */
25464  case 600: /* Busy everywhere */
25465  case 603: /* Decline */
25466  if (p->owner) {
25467  sip_handle_cc(p, req, AST_CC_CCBS);
25469  }
25470  break;
25471  case 482: /* Loop Detected */
25472  case 404: /* Not Found */
25473  case 410: /* Gone */
25474  case 400: /* Bad Request */
25475  case 500: /* Server error */
25476  if (sipmethod == SIP_SUBSCRIBE) {
25477  handle_response_subscribe(p, resp, rest, req, seqno);
25478  break;
25479  }
25480  /* Fall through */
25481  case 502: /* Bad gateway */
25482  case 503: /* Service Unavailable */
25483  case 504: /* Server Timeout */
25484  if (owner)
25486  break;
25487  case 484: /* Address Incomplete */
25488  if (owner && sipmethod != SIP_BYE) {
25489  switch (ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) {
25492  break;
25493  default:
25495  break;
25496  }
25497  }
25498  break;
25499  default:
25500  /* Send hangup */
25501  if (owner && sipmethod != SIP_BYE)
25503  break;
25504  }
25505  /* ACK on invite */
25506  if (sipmethod == SIP_INVITE)
25508  sip_alreadygone(p);
25509  if (!p->owner) {
25510  pvt_set_needdestroy(p, "transaction completed");
25511  }
25512  } else if ((resp >= 100) && (resp < 200)) {
25513  if (sipmethod == SIP_INVITE) {
25514  if (!req->ignore) {
25515  sip_cancel_destroy(p);
25516  }
25517  if (find_sdp(req))
25518  process_sdp(p, req, SDP_T38_NONE, FALSE);
25519  if (p->owner) {
25520  /* Queue a progress frame */
25522  }
25523  }
25524  } else
25525  ast_log(LOG_NOTICE, "Don't know how to handle a %d %s response from %s\n", resp, rest, p->owner ? ast_channel_name(p->owner) : ast_sockaddr_stringify(&p->sa));
25526  }
25527  } else {
25528  /* Responses to OUTGOING SIP requests on INCOMING calls
25529  get handled here. As well as out-of-call message responses */
25530  if (req->debug)
25531  ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg);
25532 
25533  if (sipmethod == SIP_INVITE && resp == 200) {
25534  /* Tags in early session is replaced by the tag in 200 OK, which is
25535  the final reply to our INVITE */
25536  char tag[128];
25537 
25538  gettag(req, "To", tag, sizeof(tag));
25539  ast_string_field_set(p, theirtag, tag);
25540  }
25541 
25542  switch(resp) {
25543  case 200:
25544  if (sipmethod == SIP_INVITE) {
25545  handle_response_invite(p, resp, rest, req, seqno);
25546  } else if (sipmethod == SIP_CANCEL) {
25547  ast_debug(1, "Got 200 OK on CANCEL\n");
25548 
25549  /* Wait for 487, then destroy */
25550  } else if (sipmethod == SIP_BYE) {
25551  pvt_set_needdestroy(p, "transaction completed");
25552  }
25553  break;
25554  case 401: /* www-auth */
25555  case 407:
25556  if (sipmethod == SIP_INVITE)
25557  handle_response_invite(p, resp, rest, req, seqno);
25558  else if (sipmethod == SIP_BYE) {
25559  if (p->authtries == MAX_AUTHTRIES || do_proxy_auth(p, req, resp, sipmethod, 0)) {
25560  ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, sip_get_header(&p->initreq, "From"));
25561  pvt_set_needdestroy(p, "failed to authenticate BYE");
25562  }
25563  }
25564  break;
25565  case 481: /* Call leg does not exist */
25566  if (sipmethod == SIP_INVITE) {
25567  /* Re-invite failed */
25568  handle_response_invite(p, resp, rest, req, seqno);
25569  } else if (sipmethod == SIP_BYE) {
25570  pvt_set_needdestroy(p, "received 481 response");
25571  } else if (sipdebug) {
25572  ast_debug(1, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid);
25573  }
25574  break;
25575  case 501: /* Not Implemented */
25576  if (sipmethod == SIP_INVITE)
25577  handle_response_invite(p, resp, rest, req, seqno);
25578  break;
25579  default: /* Errors without handlers */
25580  if ((resp >= 100) && (resp < 200)) {
25581  if (sipmethod == SIP_INVITE) { /* re-invite */
25582  if (!req->ignore) {
25583  sip_cancel_destroy(p);
25584  }
25585  }
25586  } else if ((resp >= 200) && (resp < 300)) { /* on any unrecognized 2XX response do the following */
25587  if (sipmethod == SIP_INVITE) {
25588  handle_response_invite(p, resp, rest, req, seqno);
25589  }
25590  } else if ((resp >= 300) && (resp < 700)) {
25591  if ((resp != 487))
25592  ast_verb(3, "Incoming call: Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_sockaddr_stringify(&p->sa));
25593  switch(resp) {
25594  case 415: /* Unsupported media type */
25595  case 488: /* Not acceptable here - codec error */
25596  case 603: /* Decline */
25597  case 500: /* Server error */
25598  case 502: /* Bad gateway */
25599  case 503: /* Service Unavailable */
25600  case 504: /* Server timeout */
25601  /* re-invite failed */
25602  if (sipmethod == SIP_INVITE) {
25603  sip_cancel_destroy(p);
25604  }
25605  break;
25606  }
25607  }
25608  break;
25609  }
25610  }
25611 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
Definition: sip.h:626
static void handle_response_message(struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno)
Definition: chan_sip.c:25111
Main Channel structure associated with a channel.
char debug
Definition: sip.h:837
#define FALSE
Definition: app_minivm.c:521
unsigned int allowed_methods
Definition: sip.h:1196
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
Definition: channel.c:1231
static void handle_response_subscribe(struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno)
Definition: chan_sip.c:24618
enum sip_auth_type auth_type
Definition: sip.h:867
#define ast_test_flag(p, flag)
Definition: utils.h:63
Definition: sip.h:619
static const struct cfsip_methods sip_methods[]
struct sip_peer * relatedpeer
Definition: sip.h:1171
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define LOG_WARNING
Definition: logger.h:274
uint32_t pendinginvite
Definition: sip.h:1147
struct ast_sockaddr recv
Definition: sip.h:1135
static void sip_alreadygone(struct sip_pvt *dialog)
Encapsulate setting of SIP_ALREADYGONE to be able to trace it with debugging.
Definition: chan_sip.c:3460
static const char * gettag(const struct sip_request *req, const char *header, char *tagbuf, int tagbufsize)
Get tag from packet.
Definition: chan_sip.c:25654
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.
Definition: chan_sip.c:23036
static struct test_val c
struct ast_flags flags[3]
Definition: sip.h:1075
char * text
Definition: app_queue.c:1508
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
Definition: sip.h:621
static void handle_response_publish(struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno)
Definition: chan_sip.c:23920
#define ast_verb(level,...)
Definition: logger.h:463
char * ast_skip_nonblanks(const char *str)
Gets a pointer to first whitespace character in a string.
Definition: strings.h:200
struct sip_invite_param * options
Definition: sip.h:1183
int hangup_sip2cause(int cause)
Convert SIP hangup causes to Asterisk hangup causes.
Definition: chan_sip.c:6986
static void handle_response_notify(struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno)
Definition: chan_sip.c:24566
int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
Queue a hangup frame with hangupcause set.
Definition: channel.c:1166
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ast_sockaddr sa
Definition: sip.h:1125
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: chan_sip.c:4632
static void handle_response_info(struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno)
Definition: chan_sip.c:25037
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: chan_sip.c:4570
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
Definition: chan_sip.c:23528
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
struct sip_registry * registry
Definition: sip.h:1173
struct sip_request initreq
Definition: sip.h:1151
static int find_sdp(struct sip_request *req)
Determine whether a SIP message contains an SDP in its body.
Definition: chan_sip.c:10054
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
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&#39;t retry...
Definition: chan_sip.c:16532
void ast_channel_set_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
Set the redirecting id information in the Asterisk channel.
Definition: channel.c:9215
const ast_string_field theirtag
Definition: sip.h:1063
#define MAX_AUTHTRIES
Definition: sip.h:109
const ast_string_field authname
Definition: sip.h:1063
sipmethod
SIP Request methods known by Asterisk.
Definition: sip.h:612
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.
Definition: chan_sip.c:23860
#define SIP_PAGE2_ALLOWOVERLAP
Definition: sip.h:337
#define SIP_PAGE2_ALLOWOVERLAP_YES
Definition: sip.h:339
const ast_string_field callid
Definition: sip.h:1063
static void pvt_set_needdestroy(struct sip_pvt *pvt, const char *reason)
Definition: chan_sip.c:3429
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
static void stop_media_flows(struct sip_pvt *p)
Immediately stop RTP, VRTP and UDPTL as applicable.
Definition: chan_sip.c:25156
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.
Definition: chan_sip.c:24807
Redirecting Line information. RDNIS (Redirecting Directory Number Information Service) Where a call d...
Definition: channel.h:523
#define LOG_NOTICE
Definition: logger.h:263
struct ast_channel * owner
Definition: sip.h:1138
static void sip_handle_cc(struct sip_pvt *pvt, struct sip_request *req, enum ast_cc_service_type service)
Definition: chan_sip.c:2322
static int find_sip_method(const char *msg)
find_sip_method: Find SIP method from header
Definition: chan_sip.c:3594
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.
Definition: chan_sip.c:24006
#define ast_clear_flag(p, flag)
Definition: utils.h:77
static void handle_response_peerpoke(struct sip_pvt *p, int resp, struct sip_request *req)
Handle qualification responses (OPTIONS)
Definition: chan_sip.c:24962
static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action, int is_offer)
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().
Definition: chan_sip.c:10253
static int use_reason_header(struct sip_pvt *pvt, struct sip_request *req)
Parses SIP reason header according to RFC3326 and sets channel&#39;s hangupcause if configured so and hea...
Definition: chan_sip.c:16841
void ast_party_redirecting_free(struct ast_party_redirecting *doomed)
Destroy the redirecting information contents.
Definition: channel.c:2179
void sip_cancel_destroy(struct sip_pvt *pvt)
Cancel destruction of SIP dialog.
Definition: chan_sip.c:4464
Indicate what information in ast_party_redirecting should be set.
Definition: channel.h:556
Definition: sip.h:622
const char * ast_channel_name(const struct ast_channel *chan)
void ast_party_redirecting_init(struct ast_party_redirecting *init)
Initialize the given redirecting structure.
Definition: channel.c:2122
#define TRUE
Definition: app_minivm.c:518
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406
char ignore
Definition: sip.h:839
#define SIP_OUTGOING
Definition: sip.h:257
static void mark_method_allowed(unsigned int *allowed_methods, enum sipmethod method)
Definition: chan_sip.c:9795
static void update_redirecting(struct sip_pvt *p, const void *data, size_t datalen)
Send a provisional response indicating that a call was redirected.
Definition: chan_sip.c:15755
#define SIP_PAGE2_DIALOG_ESTABLISHED
Definition: sip.h:358
static void handle_response_refer(struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno)
Definition: chan_sip.c:24707
int authtries
Definition: sip.h:1111
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514
unsigned int disallowed_methods
Definition: sip.h:1376
static void mark_method_unallowed(unsigned int *allowed_methods, enum sipmethod method)
Definition: chan_sip.c:9800

◆ handle_response_info()

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

References sip_pvt::allowed_methods, ast_log, ast_sockaddr_stringify(), ast_verb, sip_peer::disallowed_methods, LOG_WARNING, mark_method_allowed(), mark_method_unallowed(), sip_pvt::relatedpeer, sip_pvt::sa, SIP_INFO, sip_methods, cfsip_methods::text, and text.

Referenced by handle_response().

25038 {
25039  int sipmethod = SIP_INFO;
25040 
25041  switch (resp) {
25042  case 401: /* Not www-authorized on SIP method */
25043  case 407: /* Proxy auth required */
25044  ast_log(LOG_WARNING, "Host '%s' requests authentication (%d) for '%s'\n",
25045  ast_sockaddr_stringify(&p->sa), resp, sip_methods[sipmethod].text);
25046  break;
25047  case 405: /* Method not allowed */
25048  case 501: /* Not Implemented */
25049  mark_method_unallowed(&p->allowed_methods, sipmethod);
25050  if (p->relatedpeer) {
25052  }
25053  ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n",
25054  ast_sockaddr_stringify(&p->sa), sip_methods[sipmethod].text);
25055  break;
25056  default:
25057  if (300 <= resp && resp < 700) {
25058  ast_verb(3, "Got SIP %s response %d \"%s\" back from host '%s'\n",
25059  sip_methods[sipmethod].text, resp, rest, ast_sockaddr_stringify(&p->sa));
25060  }
25061  break;
25062  }
25063 }
Definition: sip.h:626
unsigned int allowed_methods
Definition: sip.h:1196
static const struct cfsip_methods sip_methods[]
struct sip_peer * relatedpeer
Definition: sip.h:1171
#define LOG_WARNING
Definition: logger.h:274
char * text
Definition: app_queue.c:1508
#define ast_verb(level,...)
Definition: logger.h:463
struct ast_sockaddr sa
Definition: sip.h:1125
#define ast_log
Definition: astobj2.c:42
sipmethod
SIP Request methods known by Asterisk.
Definition: sip.h:612
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
char *const text
Definition: chan_sip.c:737
static void mark_method_allowed(unsigned int *allowed_methods, enum sipmethod method)
Definition: chan_sip.c:9795
unsigned int disallowed_methods
Definition: sip.h:1376
static void mark_method_unallowed(unsigned int *allowed_methods, enum sipmethod method)
Definition: chan_sip.c:9800

◆ handle_response_invite()

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

References sip_pvt::alreadygone, append_history, ast_alloca, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_NORMAL_CLEARING, AST_CC_CCNR, ast_channel_hangupcause_set(), ast_channel_queue_connected_line_update(), ast_channel_queue_redirecting_update(), ast_channel_redirecting(), AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_UPDATE_RTP_PEER, ast_debug, AST_DEVICE_UNKNOWN, ast_devstate_changed(), AST_DEVSTATE_NOT_CACHABLE, ast_log, ast_null_frame, ast_party_connected_line_init(), ast_party_redirecting_free(), ast_party_redirecting_init(), ast_party_redirecting_set_init(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, ast_queue_control(), ast_queue_frame(), ast_queue_hangup_with_cause(), ast_random(), ast_redirecting_reason_parse(), AST_REDIRECTING_REASON_UNKNOWN, ast_rtp_instance_activate(), ast_rtp_instance_get_requested_target_address(), ast_sched_add(), AST_SCHED_DEL_UNREF, ast_set_flag, ast_set_party_id_all(), ast_setstate(), ast_sockaddr_isnull(), AST_STATE_RINGING, AST_STATE_UP, ast_string_field_set, ast_strlen_zero, ast_test_flag, sip_invite_param::auth_type, sip_pvt::authtries, build_route(), sip_pvt::callid, sip_pvt::callingpres, change_redirecting_information(), change_t38_state(), sip_pvt::cid_name, sip_pvt::cid_num, sip_pvt::cid_tag, ast_party_redirecting_reason::code, connected, DEC_CALL_LIMIT, DEC_CALL_RINGING, DEFAULT_TRANS_TIMEOUT, dialog_ref, dialog_unref, do_proxy_auth(), FALSE, find_sdp(), sip_pvt::flags, get_rpid(), hangup_sip2cause(), sip_pvt::hangupcause, ast_party_connected_line::id, ast_set_party_connected_line::id, sip_request::ignore, sip_pvt::initid, sip_pvt::initreq, INV_CALLING, INV_CANCELLED, INV_COMPLETED, INV_EARLY_MEDIA, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, LOG_NOTICE, LOG_WARNING, MAX_AUTHTRIES, ast_party_id::name, ast_set_party_id::name, sip_peer::name, NULL, ast_party_id::number, ast_set_party_id::number, sip_pvt::ongoing_reinvite, sip_pvt::options, sip_pvt::outgoing_call, sip_pvt::owner, parse_ok_contact(), parse_session_expires(), sip_pvt::pendinginvite, ast_party_name::presentation, ast_party_number::presentation, ast_set_party_connected_line::priv, ast_set_party_redirecting::priv_from, ast_set_party_redirecting::priv_orig, ast_set_party_redirecting::priv_to, proc_422_rsp(), process_sdp(), pvt_set_needdestroy(), ast_party_redirecting::reason, sip_pvt::relatedpeer, sip_pvt::route, sip_pvt::rtp, sched_check_pendings(), SDP_T38_ACCEPT, SDP_T38_NONE, SESSION_TIMER_MODE_ORIGINATE, SESSION_TIMER_MODE_REFUSE, SESSION_TIMER_REFRESHER_PARAM_UAC, SESSION_TIMER_REFRESHER_PARAM_UAS, SESSION_TIMER_REFRESHER_THEM, SESSION_TIMER_REFRESHER_US, set_address_from_contact(), set_pvt_allowed_methods(), SIP_ACK, sip_alreadygone(), sip_cancel_destroy(), sip_get_header(), sip_handle_cc(), SIP_INVITE, SIP_OUTGOING, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PENDINGBYE, SIP_PROGRESS_SENT, sip_queue_hangup_cause(), sip_reinvite_retry(), sip_route_empty, sip_scheddestroy(), ast_party_connected_line::source, sip_st_dlg::st_active, sip_st_dlg::st_active_peer_ua, st_get_mode(), st_get_se(), sip_st_dlg::st_interval, sip_st_dlg::st_ref, start_session_timer(), t38properties::state, sip_pvt::stimer, stop_reinviteid(), ast_party_name::str, ast_party_number::str, ast_party_redirecting_reason::str, sip_pvt::t38, T38_DISABLED, T38_LOCAL_REINVITE, T38_REJECTED, ast_party_id::tag, sip_pvt::theirprovtag, sip_pvt::theirtag, transmit_reinvite_with_sdp(), transmit_request(), TRUE, sip_pvt::udptl, update_call_counter(), update_redirecting(), ast_party_name::valid, ast_party_number::valid, sip_pvt::waitid, XMIT_ERROR, and XMIT_UNRELIABLE.

Referenced by handle_response().

24007 {
24008  int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING);
24009  int res = 0;
24010  int xmitres = 0;
24011  int reinvite = ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
24012  char *p_hdrval;
24013  int rtn;
24015  struct ast_set_party_connected_line update_connected;
24016 
24017  if (reinvite) {
24018  ast_debug(4, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid);
24019  } else {
24020  ast_debug(4, "SIP response %d to standard invite\n", resp);
24021  }
24022 
24023  if (p->alreadygone) { /* This call is already gone */
24024  ast_debug(1, "Got response on call that is already terminated: %s (ignoring)\n", p->callid);
24025  return;
24026  }
24027 
24028  /* Acknowledge sequence number - This only happens on INVITE from SIP-call */
24029  /* Don't auto congest anymore since we've gotten something useful back */
24030  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"));
24031 
24032  /* RFC3261 says we must treat every 1xx response (but not 100)
24033  that we don't recognize as if it was 183.
24034  */
24035  if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 181 && resp != 182 && resp != 183) {
24036  resp = 183;
24037  }
24038 
24039  /* For INVITE, treat all 2XX responses as we would a 200 response */
24040  if ((resp >= 200) && (resp < 300)) {
24041  resp = 200;
24042  }
24043 
24044  /* Any response between 100 and 199 is PROCEEDING */
24045  if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING) {
24047  }
24048 
24049  /* Final response, not 200 ? */
24050  if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA )) {
24052  }
24053 
24054  if ((resp >= 200 && reinvite)) {
24055  p->ongoing_reinvite = 0;
24056  stop_reinviteid(p);
24057  }
24058 
24059  /* Final response, clear out pending invite */
24060  if ((resp == 200 || resp >= 300) && p->pendinginvite && seqno == p->pendinginvite) {
24061  p->pendinginvite = 0;
24062  }
24063 
24064  /* If this is a response to our initial INVITE, we need to set what we can use
24065  * for this peer.
24066  */
24067  if (!reinvite) {
24068  set_pvt_allowed_methods(p, req);
24069  }
24070 
24071  switch (resp) {
24072  case 100: /* Trying */
24073  case 101: /* Dialog establishment */
24074  if (!req->ignore && p->invitestate != INV_CANCELLED) {
24075  sip_cancel_destroy(p);
24076  }
24078  break;
24079 
24080  case 180: /* 180 Ringing */
24081  case 182: /* 182 Queued */
24082  if (!req->ignore && p->invitestate != INV_CANCELLED) {
24083  sip_cancel_destroy(p);
24084  }
24085  /* Store Route-set from provisional SIP responses so
24086  * early-dialog request can be routed properly
24087  * */
24088  parse_ok_contact(p, req);
24089  if (!reinvite) {
24090  build_route(p, req, 1, resp);
24091  }
24092  if (!req->ignore && p->owner) {
24093  if (get_rpid(p, req)) {
24094  /* Queue a connected line update */
24096  memset(&update_connected, 0, sizeof(update_connected));
24097 
24098  update_connected.id.number = 1;
24099  connected.id.number.valid = 1;
24100  connected.id.number.str = (char *) p->cid_num;
24101  connected.id.number.presentation = p->callingpres;
24102 
24103  update_connected.id.name = 1;
24104  connected.id.name.valid = 1;
24105  connected.id.name.str = (char *) p->cid_name;
24106  connected.id.name.presentation = p->callingpres;
24107 
24108  /* Invalidate any earlier private connected id representation */
24109  ast_set_party_id_all(&update_connected.priv);
24110 
24111  connected.id.tag = (char *) p->cid_tag;
24114  &update_connected);
24115  }
24116  sip_handle_cc(p, req, AST_CC_CCNR);
24118  if (ast_channel_state(p->owner) != AST_STATE_UP) {
24120  if (p->relatedpeer) {
24122  }
24123  }
24124  }
24125  if (find_sdp(req)) {
24126  if (p->invitestate != INV_CANCELLED) {
24128  }
24129  res = process_sdp(p, req, SDP_T38_NONE, FALSE);
24130  if (!req->ignore && p->owner) {
24131  /* Queue a progress frame only if we have SDP in 180 or 182 */
24133  /* We have not sent progress, but we have been sent progress so enable early media */
24135  }
24137  }
24139  break;
24140 
24141  case 181: /* Call Is Being Forwarded */
24142  if (!req->ignore && p->invitestate != INV_CANCELLED) {
24143  sip_cancel_destroy(p);
24144  }
24145  /* Store Route-set from provisional SIP responses so
24146  * early-dialog request can be routed properly
24147  * */
24148  parse_ok_contact(p, req);
24149  if (!reinvite) {
24150  build_route(p, req, 1, resp);
24151  }
24152  if (!req->ignore && p->owner) {
24153  struct ast_party_redirecting redirecting;
24155 
24156  ast_party_redirecting_init(&redirecting);
24157  memset(&update_redirecting, 0, sizeof(update_redirecting));
24158  change_redirecting_information(p, req, &redirecting, &update_redirecting,
24159  FALSE);
24160 
24161  /* Invalidate any earlier private redirecting id representations */
24165 
24168  ast_party_redirecting_free(&redirecting);
24169  sip_handle_cc(p, req, AST_CC_CCNR);
24170  }
24172  break;
24173 
24174  case 183: /* Session progress */
24175  if (!req->ignore && p->invitestate != INV_CANCELLED) {
24176  sip_cancel_destroy(p);
24177  }
24178  /* Store Route-set from provisional SIP responses so
24179  * early-dialog request can be routed properly
24180  * */
24181  parse_ok_contact(p, req);
24182  if (!reinvite) {
24183  build_route(p, req, 1, resp);
24184  }
24185  if (!req->ignore && p->owner) {
24186  if (get_rpid(p, req)) {
24187  /* Queue a connected line update */
24189  memset(&update_connected, 0, sizeof(update_connected));
24190 
24191  update_connected.id.number = 1;
24192  connected.id.number.valid = 1;
24193  connected.id.number.str = (char *) p->cid_num;
24194  connected.id.number.presentation = p->callingpres;
24195 
24196  update_connected.id.name = 1;
24197  connected.id.name.valid = 1;
24198  connected.id.name.str = (char *) p->cid_name;
24199  connected.id.name.presentation = p->callingpres;
24200 
24201  /* Invalidate any earlier private connected id representation */
24202  ast_set_party_id_all(&update_connected.priv);
24203 
24204  connected.id.tag = (char *) p->cid_tag;
24207  &update_connected);
24208  }
24209  sip_handle_cc(p, req, AST_CC_CCNR);
24210  }
24211  if (find_sdp(req)) {
24212  if (p->invitestate != INV_CANCELLED) {
24214  }
24215  res = process_sdp(p, req, SDP_T38_NONE, FALSE);
24216  if (!req->ignore && p->owner) {
24217  /* Queue a progress frame */
24219  /* We have not sent progress, but we have been sent progress so enable early media */
24221  }
24223  } else {
24224  /* Alcatel PBXs are known to send 183s with no SDP after sending
24225  * a 100 Trying response. We're just going to treat this sort of thing
24226  * the same as we would treat a 180 Ringing
24227  */
24228  if (!req->ignore && p->owner) {
24230  }
24231  }
24233  break;
24234 
24235  case 200: /* 200 OK on invite - someone's answering our call */
24236  if (!req->ignore && p->invitestate != INV_CANCELLED) {
24237  sip_cancel_destroy(p);
24238  }
24239  p->authtries = 0;
24240  if (find_sdp(req)) {
24241  res = process_sdp(p, req, SDP_T38_ACCEPT, FALSE);
24242  if (res && !req->ignore) {
24243  if (!reinvite) {
24244  /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */
24245  /* For re-invites, we try to recover */
24248  if (p->owner) {
24251  }
24252  }
24253  }
24255  } else if (!reinvite) {
24256  struct ast_sockaddr remote_address = {{0,}};
24257 
24259  if (ast_sockaddr_isnull(&remote_address) || (!ast_strlen_zero(p->theirprovtag) && strcmp(p->theirtag, p->theirprovtag))) {
24260  ast_log(LOG_WARNING, "Received response: \"200 OK\" from '%s' without SDP\n", p->relatedpeer->name);
24263  }
24264  }
24265 
24266  if (!req->ignore && p->owner) {
24267  int rpid_changed;
24268 
24269  rpid_changed = get_rpid(p, req);
24270  if (rpid_changed || !reinvite) {
24271  /* Queue a connected line update */
24273  memset(&update_connected, 0, sizeof(update_connected));
24274  if (rpid_changed
24275  || !ast_strlen_zero(p->cid_num)
24277  update_connected.id.number = 1;
24278  connected.id.number.valid = 1;
24279  connected.id.number.str = (char *) p->cid_num;
24280  connected.id.number.presentation = p->callingpres;
24281  }
24282  if (rpid_changed
24283  || !ast_strlen_zero(p->cid_name)
24285  update_connected.id.name = 1;
24286  connected.id.name.valid = 1;
24287  connected.id.name.str = (char *) p->cid_name;
24288  connected.id.name.presentation = p->callingpres;
24289  }
24290  if (update_connected.id.number || update_connected.id.name) {
24291  /* Invalidate any earlier private connected id representation */
24292  ast_set_party_id_all(&update_connected.priv);
24293 
24294  connected.id.tag = (char *) p->cid_tag;
24297  &update_connected);
24298  }
24299  }
24300  }
24301 
24302  /* Parse contact header for continued conversation */
24303  /* When we get 200 OK, we know which device (and IP) to contact for this call */
24304  /* This is important when we have a SIP proxy between us and the phone */
24305  if (outgoing) {
24307  parse_ok_contact(p, req);
24308  /* Save Record-Route for any later requests we make on this dialogue */
24309  if (!reinvite) {
24310  build_route(p, req, 1, resp);
24311  }
24312  if(set_address_from_contact(p)) {
24313  /* Bad contact - we don't know how to reach this device */
24314  /* We need to ACK, but then send a bye */
24315  if (sip_route_empty(&p->route) && !req->ignore) {
24317  }
24318  }
24319 
24320  }
24321 
24322  if (!req->ignore && p->owner) {
24323  if (!reinvite && !res) {
24325  } else { /* RE-invite */
24326  if (p->t38.state == T38_DISABLED || p->t38.state == T38_REJECTED) {
24328  } else {
24330  }
24331  }
24332  } else {
24333  /* It's possible we're getting an 200 OK after we've tried to disconnect
24334  by sending CANCEL */
24335  /* First send ACK, then send bye */
24336  if (!req->ignore) {
24338  }
24339  }
24340 
24341  /* Check for Session-Timers related headers */
24342  if (st_get_mode(p, 0) != SESSION_TIMER_MODE_REFUSE) {
24343  p_hdrval = (char*)sip_get_header(req, "Session-Expires");
24344  if (!ast_strlen_zero(p_hdrval)) {
24345  /* UAS supports Session-Timers */
24346  enum st_refresher_param st_ref_param;
24347  int tmp_st_interval = 0;
24348  rtn = parse_session_expires(p_hdrval, &tmp_st_interval, &st_ref_param);
24349  if (rtn != 0) {
24351  } else if (tmp_st_interval < st_get_se(p, FALSE)) {
24352  ast_log(LOG_WARNING, "Got Session-Expires less than local Min-SE in 200 OK, tearing down call\n");
24354  }
24355  if (st_ref_param == SESSION_TIMER_REFRESHER_PARAM_UAC) {
24357  } else if (st_ref_param == SESSION_TIMER_REFRESHER_PARAM_UAS) {
24359  } else {
24360  ast_log(LOG_WARNING, "Unknown refresher on %s\n", p->callid);
24361  }
24362  if (tmp_st_interval) {
24363  p->stimer->st_interval = tmp_st_interval;
24364  }
24365  p->stimer->st_active = TRUE;
24368  } else {
24369  /* UAS doesn't support Session-Timers */
24374  }
24375  }
24376  }
24377 
24378 
24379  /* If I understand this right, the branch is different for a non-200 ACK only */
24382  xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE);
24384  break;
24385 
24386  case 407: /* Proxy authentication */
24387  case 401: /* Www auth */
24388  /* First we ACK */
24389  xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
24390  if (p->options) {
24391  p->options->auth_type = resp;
24392  }
24393 
24394  /* Then we AUTH */
24395  ast_string_field_set(p, theirtag, NULL); /* forget their old tag, so we don't match tags when getting response */
24396  if (!req->ignore) {
24397  if (p->authtries < MAX_AUTHTRIES) {
24398  p->invitestate = INV_CALLING;
24399  }
24400  if (p->authtries == MAX_AUTHTRIES || do_proxy_auth(p, req, resp, SIP_INVITE, 1)) {
24401  ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", sip_get_header(&p->initreq, "From"));
24402  pvt_set_needdestroy(p, "failed to authenticate on INVITE");
24403  sip_alreadygone(p);
24404  if (p->owner) {
24406  }
24407  }
24408  }
24409  break;
24410 
24411  case 403: /* Forbidden */
24412  /* First we ACK */
24413  xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
24414  ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", sip_get_header(&p->initreq, "From"));
24415  if (!req->ignore && p->owner) {
24417  }
24418  break;
24419 
24420  case 400: /* Bad Request */
24421  case 414: /* Bad request URI */
24422  case 493: /* Undecipherable */
24423  case 404: /* Not found */
24424  xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
24425  if (p->owner && !req->ignore) {
24427  }
24428  break;
24429 
24430  case 481: /* Call leg does not exist */
24431  /* Could be REFER caused INVITE with replaces */
24432  ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid);
24433  xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
24434  if (p->owner) {
24436  }
24437  break;
24438 
24439  case 422: /* Session-Timers: Session interval too small */
24440  xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
24441  ast_string_field_set(p, theirtag, NULL);
24442  p->invitestate = INV_CALLING;
24443  proc_422_rsp(p, req);
24444  break;
24445 
24446  case 428: /* Use identity header - rfc 4474 - not supported by Asterisk yet */
24447  xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
24448  append_history(p, "Identity", "SIP identity is required. Not supported by Asterisk.");
24449  ast_log(LOG_WARNING, "SIP identity required by proxy. SIP dialog '%s'. Giving up.\n", p->callid);
24450  if (p->owner && !req->ignore) {
24452  }
24453  break;
24454 
24455  case 480: /* Temporarily unavailable. */
24456  /* RFC 3261 encourages setting the reason phrase to something indicative
24457  * of why the endpoint is not available. We will make this readable via the
24458  * redirecting reason.
24459  */
24460  xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
24461  append_history(p, "TempUnavailable", "Endpoint is temporarily unavailable.");
24462  if (p->owner && !req->ignore) {
24463  struct ast_party_redirecting redirecting;
24465  char *quoted_rest = ast_alloca(strlen(rest) + 3);
24466 
24468  memset(&update_redirecting, 0, sizeof(update_redirecting));
24469 
24470  redirecting.reason.code = ast_redirecting_reason_parse(rest);
24471  if (redirecting.reason.code < 0) {
24472  sprintf(quoted_rest, "\"%s\"", rest);/* Safe */
24473 
24474  redirecting.reason.code = AST_REDIRECTING_REASON_UNKNOWN;
24475  redirecting.reason.str = quoted_rest;
24476  } else {
24477  redirecting.reason.str = "";
24478  }
24479 
24481 
24483  }
24484  break;
24485  case 487: /* Cancelled transaction */
24486  /* We have sent CANCEL on an outbound INVITE
24487  This transaction is already scheduled to be killed by sip_hangup().
24488  */
24489  xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
24490  if (p->owner && !req->ignore) {
24492  append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request");
24493  } else if (!req->ignore) {
24495  append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog.");
24496  }
24499  break;
24500  case 415: /* Unsupported media type */
24501  case 488: /* Not acceptable here */
24502  case 606: /* Not Acceptable */
24503  xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
24504  if (p->udptl && p->t38.state == T38_LOCAL_REINVITE) {
24506  /* Try to reset RTP timers */
24507  /* XXX Why is this commented away??? */
24508  //ast_rtp_set_rtptimers_onhold(p->rtp);
24509 
24510  /* Trigger a reinvite back to audio */
24512  } else {
24513  /* We can't set up this call, so give up */
24514  if (p->owner && !req->ignore) {
24516  }
24517  }
24518  break;
24519  case 491: /* Pending */
24520  xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
24521  if (p->owner && !req->ignore) {
24522  if (ast_channel_state(p->owner) != AST_STATE_UP) {
24524  } else {
24525  /* This is a re-invite that failed. */
24526  /* Reset the flag after a while
24527  */
24528  int wait;
24529 
24530  /* RFC 3261, if owner of call, wait between 2.1 to 4 seconds,
24531  * if not owner of call, wait 0 to 2 seconds */
24532  if (p->outgoing_call) {
24533  wait = 2100 + ast_random() % 2000;
24534  } else {
24535  wait = ast_random() % 2000;
24536  }
24537  dialog_ref(p, "Schedule waitid for sip_reinvite_retry.");
24538  p->waitid = ast_sched_add(sched, wait, sip_reinvite_retry, p);
24539  if (p->waitid < 0) {
24540  /* Uh Oh. Expect bad behavior. */
24541  dialog_ref(p, "Failed to schedule waitid");
24542  }
24543  ast_debug(2, "Reinvite race. Scheduled sip_reinvite_retry in %d secs in handle_response_invite (waitid %d, dialog '%s')\n",
24544  wait, p->waitid, p->callid);
24545  }
24546  }
24547  break;
24548 
24549  case 408: /* Request timeout */
24550  case 405: /* Not allowed */
24551  case 501: /* Not implemented */
24552  xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
24553  if (p->owner) {
24555  }
24556  break;
24557  }
24558  if (xmitres == XMIT_ERROR) {
24559  ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid);
24560  }
24561 }
enum st_refresher st_ref
Definition: sip.h:962
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
int ast_rtp_instance_activate(struct ast_rtp_instance *instance)
Indicate to the RTP engine that packets are now expected to be sent/received on the RTP instance...
Definition: rtp_engine.c:2647
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
Definition: channel.c:2022
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 fou...
Definition: chan_sip.c:18266
#define FALSE
Definition: app_minivm.c:521
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
Definition: channel.c:1231
enum sip_auth_type auth_type
Definition: sip.h:867
int st_active_peer_ua
Definition: sip.h:964
int hangupcause
Definition: sip.h:1190
enum t38state state
Definition: sip.h:917
#define ast_test_flag(p, flag)
Definition: utils.h:63
Definition: sip.h:619
struct sip_peer * relatedpeer
Definition: sip.h:1171
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define LOG_WARNING
Definition: logger.h:274
uint32_t pendinginvite
Definition: sip.h:1147
int initid
Definition: sip.h:1155
#define DEFAULT_TRANS_TIMEOUT
Definition: sip.h:107
int ast_redirecting_reason_parse(const char *data)
Convert redirecting reason text code to value (used in config file parsing)
Definition: callerid.c:1223
static void sip_alreadygone(struct sip_pvt *dialog)
Encapsulate setting of SIP_ALREADYGONE to be able to trace it with debugging.
Definition: chan_sip.c:3460
unsigned short outgoing_call
Definition: sip.h:1083
const ast_string_field theirprovtag
Definition: sip.h:1063
Definition: sched.c:76
ast_channel_state
ast_channel states
Definition: channelstate.h:35
#define AST_SCHED_DEL_UNREF(sched, id, refcall)
schedule task to get deleted and call unref function
Definition: sched.h:80
#define DEC_CALL_LIMIT
Definition: sip.h:127
unsigned int ongoing_reinvite
Definition: sip.h:1144
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.
Definition: chan_sip.c:23036
struct ast_flags flags[3]
Definition: sip.h:1075
int st_active
Definition: sip.h:960
#define NULL
Definition: resample.c:96
static enum st_mode st_get_mode(struct sip_pvt *, int no_cached)
Get the session-timer mode.
Definition: chan_sip.c:30447
Socket address structure.
Definition: netsock2.h:97
static void build_route(struct sip_pvt *p, struct sip_request *req, int backwards, int resp)
Build route list from Record-Route header.
Definition: chan_sip.c:17201
char name[80]
Definition: sip.h:1274
struct t38properties t38
Definition: sip.h:1113
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 th...
Definition: chan_sip.c:6844
struct sip_invite_param * options
Definition: sip.h:1183
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 bet...
Definition: chan_sip.c:23817
int hangup_sip2cause(int cause)
Convert SIP hangup causes to Asterisk hangup causes.
Definition: chan_sip.c:6986
int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
Queue a hangup frame with hangupcause set.
Definition: channel.c:1166
#define ast_strlen_zero(foo)
Definition: strings.h:52
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
int st_interval
Definition: sip.h:961
unsigned short alreadygone
Definition: sip.h:1079
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
Definition: chan_sip.c:23528
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define sip_route_empty(route)
Check if route has no URI&#39;s.
Definition: route.h:118
static void sip_queue_hangup_cause(struct sip_pvt *p, int cause)
Definition: chan_sip.c:23981
static int set_address_from_contact(struct sip_pvt *pvt)
Change the other partys IP address based on given contact.
Definition: chan_sip.c:16947
int ast_devstate_changed(enum ast_device_state state, enum ast_devstate_cache cachable, const char *fmt,...)
Tells Asterisk the State for Device is changed.
Definition: devicestate.c:510
void ast_channel_queue_connected_line_update(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Queue a connected line update frame on a channel.
Definition: channel.c:9202
#define DEC_CALL_RINGING
Definition: sip.h:129
struct sip_request initreq
Definition: sip.h:1151
static int find_sdp(struct sip_request *req)
Determine whether a SIP message contains an SDP in its body.
Definition: chan_sip.c:10054
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
long int ast_random(void)
Definition: main/utils.c:2064
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&#39;t retry...
Definition: chan_sip.c:16532
const ast_string_field theirtag
Definition: sip.h:1063
st_refresher_param
Definition: sip.h:582
#define MAX_AUTHTRIES
Definition: sip.h:109
struct ast_udptl * udptl
Definition: sip.h:1115
int callingpres
Definition: sip.h:1117
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel&#39;s frame queue.
Definition: channel.c:1139
struct sip_route route
Definition: sip.h:1139
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
int waitid
Definition: sip.h:1156
#define XMIT_ERROR
Definition: sip.h:58
static int transmit_reinvite_with_sdp(struct sip_pvt *p, int t38version, int oldsdp)
Transmit reinvite with SDP.
Definition: chan_sip.c:14212
const ast_string_field callid
Definition: sip.h:1063
static void pvt_set_needdestroy(struct sip_pvt *pvt, const char *reason)
Definition: chan_sip.c:3429
const ast_string_field cid_num
Definition: sip.h:1063
struct sip_st_dlg * stimer
Definition: sip.h:1184
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
#define T38_DISABLED
Definition: chan_ooh323.c:101
Connected Line/Party information.
Definition: channel.h:457
Redirecting Line information. RDNIS (Redirecting Directory Number Information Service) Where a call d...
Definition: channel.h:523
#define LOG_NOTICE
Definition: logger.h:263
static void start_session_timer(struct sip_pvt *p)
Session-Timers: Start session timer.
Definition: chan_sip.c:30265
struct ast_channel * owner
Definition: sip.h:1138
#define dialog_ref(dialog, tag)
when we create or delete references, make sure to use these functions so we keep track of the refcoun...
Definition: dialog.h:32
static void stop_reinviteid(struct sip_pvt *pvt)
Definition: chan_sip.c:7186
static void sip_handle_cc(struct sip_pvt *pvt, struct sip_request *req, enum ast_cc_service_type service)
Definition: chan_sip.c:2322
struct ast_rtp_instance * rtp
Definition: sip.h:1174
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565
enum invitestates invitestate
Definition: sip.h:1007
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
Indicate what information in ast_party_connected_line should be set.
Definition: channel.h:490
#define AST_PRES_RESTRICTION
Definition: callerid.h:323
struct ast_frame ast_null_frame
Definition: main/frame.c:79
static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action, int is_offer)
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().
Definition: chan_sip.c:10253
const ast_string_field cid_name
Definition: sip.h:1063
#define SIP_PENDINGBYE
Definition: sip.h:262
void ast_party_redirecting_free(struct ast_party_redirecting *doomed)
Destroy the redirecting information contents.
Definition: channel.c:2179
static void proc_422_rsp(struct sip_pvt *p, struct sip_request *rsp)
Handle 422 response to INVITE with session-timer requested.
Definition: chan_sip.c:30365
void sip_cancel_destroy(struct sip_pvt *pvt)
Cancel destruction of SIP dialog.
Definition: chan_sip.c:4464
Indicate what information in ast_party_redirecting should be set.
Definition: channel.h:556
static void change_t38_state(struct sip_pvt *p, int state)
Change the T38 state on a SIP dialog.
Definition: chan_sip.c:5889
static void sched_check_pendings(struct sip_pvt *pvt)
Definition: chan_sip.c:23802
void ast_party_redirecting_init(struct ast_party_redirecting *init)
Initialize the given redirecting structure.
Definition: channel.c:2122
#define TRUE
Definition: app_minivm.c:518
void ast_rtp_instance_get_requested_target_address(struct ast_rtp_instance *instance, struct ast_sockaddr *address)
Get the requested target address of the remote endpoint.
Definition: rtp_engine.c:673
const ast_string_field cid_tag
Definition: sip.h:1063
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7486
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406
#define AST_PRES_ALLOWED
Definition: callerid.h:324
char ignore
Definition: sip.h:839
void ast_party_redirecting_set_init(struct ast_party_redirecting *init, const struct ast_party_redirecting *guide)
Initialize the given redirecting id structure using the given guide for a set update operation...
Definition: channel.c:2153
static unsigned int set_pvt_allowed_methods(struct sip_pvt *pvt, struct sip_request *req)
Definition: chan_sip.c:9880
void ast_channel_queue_redirecting_update(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
Queue a redirecting update frame on a channel.
Definition: channel.c:10392
#define SIP_OUTGOING
Definition: sip.h:257
void ast_set_party_id_all(struct ast_set_party_id *update_id)
Set the update marker to update all information of a corresponding party id.
Definition: channel.c:1750
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.
Definition: chan_sip.c:30306
static void update_redirecting(struct sip_pvt *p, const void *data, size_t datalen)
Send a provisional response indicating that a call was redirected.
Definition: chan_sip.c:15755
#define AST_CAUSE_BEARERCAPABILITY_NOTAVAIL
Definition: causes.h:129
char connected
Definition: eagi_proxy.c:82
#define SIP_PAGE2_DIALOG_ESTABLISHED
Definition: sip.h:358
static int st_get_se(struct sip_pvt *, int max)
Get Max or Min SE (session timer expiry)
Definition: chan_sip.c:30393
void sip_scheddestroy(struct sip_pvt *p, int ms)
Schedule destruction of SIP dialog.
Definition: chan_sip.c:4549
#define SIP_PROGRESS_SENT
Definition: sip.h:260
static int parse_ok_contact(struct sip_pvt *pvt, struct sip_request *req)
Save contact header for 200 OK on INVITE.
Definition: chan_sip.c:16811
int authtries
Definition: sip.h:1111
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ handle_response_message()

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

References sip_pvt::allowed_methods, ast_log, ast_sockaddr_stringify(), ast_test_flag, ast_verb, sip_pvt::authtries, sip_peer::disallowed_methods, do_message_auth(), sip_pvt::flags, LOG_WARNING, mark_method_allowed(), mark_method_unallowed(), pvt_set_needdestroy(), sip_pvt::relatedpeer, sip_pvt::sa, SIP_MESSAGE, sip_methods, SIP_PAGE2_DIALOG_ESTABLISHED, cfsip_methods::text, and text.

Referenced by handle_response().

25112 {
25113  int sipmethod = SIP_MESSAGE;
25114  int in_dialog = ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
25115 
25116  switch (resp) {
25117  case 401: /* Not www-authorized on SIP method */
25118  case 407: /* Proxy auth required */
25119  if (do_message_auth(p, resp, rest, req, seqno) && !in_dialog) {
25120  pvt_set_needdestroy(p, "MESSAGE authentication failed");
25121  }
25122  break;
25123  case 405: /* Method not allowed */
25124  case 501: /* Not Implemented */
25125  mark_method_unallowed(&p->allowed_methods, sipmethod);
25126  if (p->relatedpeer) {
25128  }
25129  ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n",
25130  ast_sockaddr_stringify(&p->sa), sip_methods[sipmethod].text);
25131  if (!in_dialog) {
25132  pvt_set_needdestroy(p, "MESSAGE not implemented or allowed");
25133  }
25134  break;
25135  default:
25136  if (100 <= resp && resp < 200) {
25137  /* Must allow provisional responses for out-of-dialog requests. */
25138  } else if (200 <= resp && resp < 300) {
25139  p->authtries = 0; /* Reset authentication counter */
25140  if (!in_dialog) {
25141  pvt_set_needdestroy(p, "MESSAGE delivery accepted");
25142  }
25143  } else if (300 <= resp && resp < 700) {
25144  ast_verb(3, "Got SIP %s response %d \"%s\" back from host '%s'\n",
25145  sip_methods[sipmethod].text, resp, rest, ast_sockaddr_stringify(&p->sa));
25146  if (!in_dialog) {
25147  pvt_set_needdestroy(p, (300 <= resp && resp < 600)
25148  ? "MESSAGE delivery failed" : "MESSAGE delivery refused");
25149  }
25150  }
25151  break;
25152  }
25153 }
unsigned int allowed_methods
Definition: sip.h:1196
#define ast_test_flag(p, flag)
Definition: utils.h:63
static const struct cfsip_methods sip_methods[]
struct sip_peer * relatedpeer
Definition: sip.h:1171
#define LOG_WARNING
Definition: logger.h:274
struct ast_flags flags[3]
Definition: sip.h:1075
char * text
Definition: app_queue.c:1508
static int do_message_auth(struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno)
Definition: chan_sip.c:25070
#define ast_verb(level,...)
Definition: logger.h:463
struct ast_sockaddr sa
Definition: sip.h:1125
#define ast_log
Definition: astobj2.c:42
sipmethod
SIP Request methods known by Asterisk.
Definition: sip.h:612
static void pvt_set_needdestroy(struct sip_pvt *pvt, const char *reason)
Definition: chan_sip.c:3429
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
char *const text
Definition: chan_sip.c:737
static void mark_method_allowed(unsigned int *allowed_methods, enum sipmethod method)
Definition: chan_sip.c:9795
#define SIP_PAGE2_DIALOG_ESTABLISHED
Definition: sip.h:358
int authtries
Definition: sip.h:1111
unsigned int disallowed_methods
Definition: sip.h:1376
static void mark_method_unallowed(unsigned int *allowed_methods, enum sipmethod method)
Definition: chan_sip.c:9800

◆ handle_response_notify()

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

References ast_channel_name(), ast_clear_flag, ast_debug, ast_log, ast_sockaddr_stringify(), ast_string_field_set, ast_strlen_zero, ast_test_flag, sip_pvt::authname, sip_pvt::authtries, sip_pvt::callid, sip_pvt::context, do_proxy_auth(), sip_pvt::exten, extensionstate_update(), sip_pvt::flags, sip_pvt::initreq, sip_pvt::last_device_state_info, sip_pvt::last_presence_message, sip_pvt::last_presence_state, sip_pvt::last_presence_subtype, sip_pvt::laststate, LOG_NOTICE, LOG_WARNING, NONE, sip_pvt::notify, NULL, sip_pvt::owner, pvt_set_needdestroy(), sip_pvt::recv, sip_pvt::refer, sip_get_header(), SIP_NOTIFY, SIP_PAGE2_STATECHANGEQUEUE, state_notify_data::state, sip_pvt::subscribed, and TRUE.

Referenced by handle_response().

24567 {
24568  switch (resp) {
24569  case 200: /* Notify accepted */
24570  /* They got the notify, this is the end */
24571  if (p->owner) {
24572  if (p->refer) {
24573  ast_log(LOG_NOTICE, "Got OK on REFER Notify message\n");
24574  } else {
24575  ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", ast_channel_name(p->owner));
24576  }
24577  } else {
24578  if (p->subscribed == NONE && !p->refer) {
24579  ast_debug(4, "Got 200 accepted on NOTIFY %s\n", p->callid);
24580  pvt_set_needdestroy(p, "received 200 response");
24581  }
24583  struct state_notify_data data = {
24584  .state = p->laststate,
24585  .device_state_info = p->last_device_state_info,
24586  .presence_state = p->last_presence_state,
24587  .presence_subtype = p->last_presence_subtype,
24588  .presence_message = p->last_presence_message,
24589  };
24590  /* Ready to send the next state we have on queue */
24592  extensionstate_update(p->context, p->exten, &data, p, TRUE);
24593  }
24594  }
24595  break;
24596  case 401: /* Not www-authorized on SIP method */
24597  case 407: /* Proxy auth */
24598  if (!p->notify) {
24599  break; /* Only device notify can use NOTIFY auth */
24600  }
24601  ast_string_field_set(p, theirtag, NULL);
24602  if (ast_strlen_zero(p->authname)) {
24603  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));
24604  pvt_set_needdestroy(p, "unable to authenticate NOTIFY");
24605  }
24606  if (p->authtries > 1 || do_proxy_auth(p, req, resp, SIP_NOTIFY, 0)) {
24607  ast_log(LOG_NOTICE, "Failed to authenticate on NOTIFY to '%s'\n", sip_get_header(&p->initreq, "From"));
24608  pvt_set_needdestroy(p, "failed to authenticate NOTIFY");
24609  }
24610  break;
24611  case 481: /* Call leg does not exist */
24612  pvt_set_needdestroy(p, "Received 481 response for NOTIFY");
24613  break;
24614  }
24615 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
enum subscriptiontype subscribed
Definition: sip.h:1161
static int extensionstate_update(const char *context, const char *exten, struct state_notify_data *data, struct sip_pvt *p, int force)
Callback for the devicestate notification (SUBSCRIBE) support subsystem.
Definition: chan_sip.c:17610
#define SIP_PAGE2_STATECHANGEQUEUE
Definition: sip.h:328
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define NONE
Definition: misdn_config.c:45
#define LOG_WARNING
Definition: logger.h:274
struct ast_sockaddr recv
Definition: sip.h:1135
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.
Definition: chan_sip.c:23036
struct ast_flags flags[3]
Definition: sip.h:1075
const ast_string_field context
Definition: sip.h:1063
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
struct sip_request initreq
Definition: sip.h:1151
const ast_string_field exten
Definition: sip.h:1063
const ast_string_field authname
Definition: sip.h:1063
const ast_string_field callid
Definition: sip.h:1063
static void pvt_set_needdestroy(struct sip_pvt *pvt, const char *reason)
Definition: chan_sip.c:3429
const ast_string_field last_presence_message
Definition: sip.h:1063
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
#define LOG_NOTICE
Definition: logger.h:263
struct ast_channel * owner
Definition: sip.h:1138
struct ao2_container * last_device_state_info
Definition: sip.h:1164
#define ast_clear_flag(p, flag)
Definition: utils.h:77
struct sip_refer * refer
Definition: sip.h:1160
int last_presence_state
Definition: sip.h:1166
const char * ast_channel_name(const struct ast_channel *chan)
#define TRUE
Definition: app_minivm.c:518
int laststate
Definition: sip.h:1163
const ast_string_field last_presence_subtype
Definition: sip.h:1063
struct sip_notify * notify
Definition: sip.h:1140
int authtries
Definition: sip.h:1111
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ handle_response_peerpoke()

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

Handle qualification responses (OPTIONS)

Definition at line 24962 of file chan_sip.c.

References ast_check_realtime(), AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_endpoint_blob_publish(), AST_ENDPOINT_ONLINE, ast_endpoint_set_state(), ast_endpoint_state_type(), ast_json_pack(), ast_json_unref(), ast_log, AST_SCHED_REPLACE_UNREF, ast_tvdiff_ms(), ast_tvnow(), ast_update_realtime(), sip_peer::call, DEFAULT_FREQ_NOTOK, dialog_unref, sip_peer::endpoint, sip_peer::lastms, LOG_NOTICE, sip_peer::maxms, sip_peer::name, NULL, sip_settings::peer_rtupdate, sip_peer::pokeexpire, sip_peer::ps, pvt_set_needdestroy(), sip_peer::qualifyfreq, RAII_VAR, sip_settings::regextenonqualify, register_peer_exten(), sip_pvt::relatedpeer, SENTINEL, sip_cfg, sip_poke_peer_s(), sip_ref_peer, sip_unref_peer, and TRUE.

Referenced by handle_response().

24963 {
24964  struct sip_peer *peer = /* sip_ref_peer( */ p->relatedpeer /* , "bump refcount on p, as it is being used in this function(handle_response_peerpoke)")*/ ; /* hope this is already refcounted! */
24965  int statechanged, is_reachable, was_reachable;
24966  int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps);
24967 
24968  /*
24969  * Compute the response time to a ping (goes in peer->lastms.)
24970  * -1 means did not respond, 0 means unknown,
24971  * 1..maxms is a valid response, >maxms means late response.
24972  */
24973  if (pingtime < 1) { /* zero = unknown, so round up to 1 */
24974  pingtime = 1;
24975  }
24976 
24977  if (!peer->maxms) { /* this should never happens */
24978  pvt_set_needdestroy(p, "got OPTIONS response but qualify is not enabled");
24979  return;
24980  }
24981 
24982  /* Now determine new state and whether it has changed.
24983  * Use some helper variables to simplify the writing
24984  * of the expressions.
24985  */
24986  was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms;
24987  is_reachable = pingtime <= peer->maxms;
24988  statechanged = peer->lastms == 0 /* yes, unknown before */
24989  || was_reachable != is_reachable;
24990 
24991  peer->lastms = pingtime;
24992  peer->call = dialog_unref(peer->call, "unref dialog peer->call");
24993  if (statechanged) {
24994  const char *s = is_reachable ? "Reachable" : "Lagged";
24995  char str_lastms[20];
24996 
24997  snprintf(str_lastms, sizeof(str_lastms), "%d", pingtime);
24998 
24999  ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n",
25000  peer->name, s, pingtime, peer->maxms);
25002  if (sip_cfg.peer_rtupdate) {
25003  ast_update_realtime(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", "name", peer->name, "lastms", str_lastms, SENTINEL);
25004  }
25005  if (peer->endpoint) {
25006  RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
25008  blob = ast_json_pack("{s: s, s: i}",
25009  "peer_status", s,
25010  "time", pingtime);
25012  }
25013 
25014  if (is_reachable && sip_cfg.regextenonqualify) {
25015  register_peer_exten(peer, TRUE);
25016  }
25017  }
25018 
25019  pvt_set_needdestroy(p, "got OPTIONS response");
25020 
25021  /* Try again eventually */
25023  is_reachable ? peer->qualifyfreq : DEFAULT_FREQ_NOTOK,
25024  sip_poke_peer_s, peer,
25025  sip_unref_peer(_data, "removing poke peer ref"),
25026  sip_unref_peer(peer, "removing poke peer ref"),
25027  sip_ref_peer(peer, "adding poke peer ref"));
25028 }
int maxms
Definition: sip.h:1357
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
struct sip_peer * relatedpeer
Definition: sip.h:1171
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
int ast_check_realtime(const char *family)
Check if realtime engine is configured for family.
Definition: main/config.c:3363
Definition: sched.c:76
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
void ast_endpoint_set_state(struct ast_endpoint *endpoint, enum ast_endpoint_state state)
Updates the state of the given endpoint.
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
#define NULL
Definition: resample.c:96
#define sip_ref_peer(peer, tag)
Definition: sip.h:1894
int peer_rtupdate
Definition: sip.h:750
int ast_update_realtime(const char *family, const char *keyfield, const char *lookup,...) attribute_sentinel
Update realtime configuration.
Definition: main/config.c:3489
char name[80]
Definition: sip.h:1274
#define ast_log
Definition: astobj2.c:42
int lastms
Definition: sip.h:1356
#define SENTINEL
Definition: compiler.h:87
int ast_devstate_changed(enum ast_device_state state, enum ast_devstate_cache cachable, const char *fmt,...)
Tells Asterisk the State for Device is changed.
Definition: devicestate.c:510
static int sip_poke_peer_s(const void *data)
Poke peer (send qualify to check if peer is alive and well)
Definition: chan_sip.c:16707
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
struct ast_endpoint * endpoint
Definition: sip.h:1379
static void pvt_set_needdestroy(struct sip_pvt *pvt, const char *reason)
Definition: chan_sip.c:3429
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
struct stasis_message_type * ast_endpoint_state_type(void)
Message type for endpoint state changes.
static void register_peer_exten(struct sip_peer *peer, int onoff)
Automatically add peer extension to dial plan.
Definition: chan_sip.c:5238
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
#define LOG_NOTICE
Definition: logger.h:263
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
struct sip_pvt * call
Definition: sip.h:1354
void ast_endpoint_blob_publish(struct ast_endpoint *endpoint, struct stasis_message_type *type, struct ast_json *blob)
Creates and publishes a ast_endpoint_blob message.
#define AST_SCHED_REPLACE_UNREF(id, sched, when, callback, data, unrefcall, addfailcall, refcall)
Definition: sched.h:150
struct timeval ps
Definition: sip.h:1359
#define TRUE
Definition: app_minivm.c:518
Abstract JSON element (object, array, string, int, ...).
int qualifyfreq
Definition: sip.h:1358
int pokeexpire
Definition: sip.h:1355
#define DEFAULT_FREQ_NOTOK
Definition: chan_iax2.c:392
int regextenonqualify
Definition: sip.h:766

◆ handle_response_publish()

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

References sip_pvt::allowed_methods, ast_assert, ast_copy_string(), ast_log, ast_string_field_set, ast_strlen_zero, sip_invite_param::auth_type, sip_pvt::authtries, do_proxy_auth(), sip_epa_entry::entity_tag, sip_pvt::epa_entry, epa_static_data::handle_error, epa_static_data::handle_ok, sip_pvt::initreq, LOG_NOTICE, mark_method_unallowed(), MAX_AUTHTRIES, NULL, sip_pvt::options, PROXY_AUTH, pvt_set_needdestroy(), sip_alreadygone(), sip_get_header(), SIP_PUBLISH, sip_epa_entry::static_data, and WWW_AUTH.

Referenced by handle_response().

23921 {
23922  struct sip_epa_entry *epa_entry = p->epa_entry;
23923  const char *etag = sip_get_header(req, "Sip-ETag");
23924 
23925  ast_assert(epa_entry != NULL);
23926 
23927  if (resp == 401 || resp == 407) {
23928  ast_string_field_set(p, theirtag, NULL);
23929  if (p->options) {
23930  p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH);
23931  }
23932  if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, resp, SIP_PUBLISH, 0)) {
23933  ast_log(LOG_NOTICE, "Failed to authenticate on PUBLISH to '%s'\n", sip_get_header(&p->initreq, "From"));
23934  pvt_set_needdestroy(p, "Failed to authenticate on PUBLISH");
23935  sip_alreadygone(p);
23936  }
23937  return;
23938  }
23939 
23940  if (resp == 501 || resp == 405) {
23942  }
23943 
23944  if (resp == 200) {
23945  p->authtries = 0;
23946  /* If I've read section 6, item 6 of RFC 3903 correctly,
23947  * an ESC will only generate a new etag when it sends a 200 OK
23948  */
23949  if (!ast_strlen_zero(etag)) {
23950  ast_copy_string(epa_entry->entity_tag, etag, sizeof(epa_entry->entity_tag));
23951  }
23952  /* The nominal case. Everything went well. Everybody is happy.
23953  * Each EPA will have a specific action to take as a result of this
23954  * development, so ... callbacks!
23955  */
23956  if (epa_entry->static_data->handle_ok) {
23957  epa_entry->static_data->handle_ok(p, req, epa_entry);
23958  }
23959  } else {
23960  /* Rather than try to make individual callbacks for each error
23961  * type, there is just a single error callback. The callback
23962  * can distinguish between error messages and do what it needs to
23963  */
23964  if (epa_entry->static_data->handle_error) {
23965  epa_entry->static_data->handle_error(p, resp, req, epa_entry);
23966  }
23967  }
23968 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
Definition: sip.h:1644
unsigned int allowed_methods
Definition: sip.h:1196
enum sip_auth_type auth_type
Definition: sip.h:867
const struct epa_static_data * static_data
Definition: sip.h:1674
static void sip_alreadygone(struct sip_pvt *dialog)
Encapsulate setting of SIP_ALREADYGONE to be able to trace it with debugging.
Definition: chan_sip.c:3460
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.
Definition: chan_sip.c:23036
#define ast_assert(a)
Definition: utils.h:695
#define NULL
Definition: resample.c:96
void(* handle_error)(struct sip_pvt *, const int resp, struct sip_request *, struct sip_epa_entry *)
Definition: sip.h:1629
struct sip_invite_param * options
Definition: sip.h:1183
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
void(* handle_ok)(struct sip_pvt *, struct sip_request *, struct sip_epa_entry *)
Definition: sip.h:1625
struct sip_request initreq
Definition: sip.h:1151
struct sip_epa_entry * epa_entry
Definition: sip.h:1219
#define MAX_AUTHTRIES
Definition: sip.h:109
char entity_tag[SIPBUFSIZE]
Definition: sip.h:1655
static void pvt_set_needdestroy(struct sip_pvt *pvt, const char *reason)
Definition: chan_sip.c:3429
#define LOG_NOTICE
Definition: logger.h:263
Definition: sip.h:504
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int authtries
Definition: sip.h:1111
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514
static void mark_method_unallowed(unsigned int *allowed_methods, enum sipmethod method)
Definition: chan_sip.c:9800

◆ handle_response_refer()

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 24707 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, sip_pvt::authname, sip_pvt::authtries, sip_pvt::callid, do_proxy_auth(), sip_pvt::initreq, LOG_NOTICE, LOG_WARNING, sip_pvt::owner, pvt_set_needdestroy(), sip_pvt::recv, sip_pvt::refer, REFER_ACCEPTED, REFER_FAILED, REFER_NOAUTH, sip_refer::refer_to, sip_get_header(), SIP_REFER, and sip_refer::status.

Referenced by handle_response().

24708 {
24710 
24711  /* If no refer structure exists, then do nothing */
24712  if (!p->refer)
24713  return;
24714 
24715  switch (resp) {
24716  case 202: /* Transfer accepted */
24717  /* We need to do something here */
24718  /* The transferee is now sending INVITE to target */
24719  p->refer->status = REFER_ACCEPTED;
24720  /* Now wait for next message */
24721  ast_debug(3, "Got 202 accepted on transfer\n");
24722  /* We should hang along, waiting for NOTIFY's here */
24723  break;
24724 
24725  case 401: /* Not www-authorized on SIP method */
24726  case 407: /* Proxy auth */
24727  if (ast_strlen_zero(p->authname)) {
24728  ast_log(LOG_WARNING, "Asked to authenticate REFER to %s but we have no matching peer or realm auth!\n",
24730  if (p->owner) {
24731  ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
24732  }
24733  pvt_set_needdestroy(p, "unable to authenticate REFER");
24734  }
24735  if (p->authtries > 1 || do_proxy_auth(p, req, resp, SIP_REFER, 0)) {
24736  ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", sip_get_header(&p->initreq, "From"));
24737  p->refer->status = REFER_NOAUTH;
24738  if (p->owner) {
24739  ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
24740  }
24741  pvt_set_needdestroy(p, "failed to authenticate REFER");
24742  }
24743  break;
24744 
24745  case 405: /* Method not allowed */
24746  /* Return to the current call onhold */
24747  /* Status flag needed to be reset */
24748  ast_log(LOG_NOTICE, "SIP transfer to %s failed, REFER not allowed. \n", p->refer->refer_to);
24749  pvt_set_needdestroy(p, "received 405 response");
24750  p->refer->status = REFER_FAILED;
24751  if (p->owner) {
24752  ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
24753  }
24754  break;
24755 
24756  case 481: /* Call leg does not exist */
24757 
24758  /* A transfer with Replaces did not work */
24759  /* OEJ: We should Set flag, cancel the REFER, go back
24760  to original call - but right now we can't */
24761  ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid);
24762  if (p->owner)
24764  pvt_set_needdestroy(p, "received 481 response");
24765  break;
24766 
24767  case 500: /* Server error */
24768  case 501: /* Method not implemented */
24769  /* Return to the current call onhold */
24770  /* Status flag needed to be reset */
24771  ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to);
24772  pvt_set_needdestroy(p, "received 500/501 response");
24773  p->refer->status = REFER_FAILED;
24774  if (p->owner) {
24775  ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
24776  }
24777  break;
24778  case 603: /* Transfer declined */
24779  ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to);
24780  p->refer->status = REFER_FAILED;
24781  pvt_set_needdestroy(p, "received 603 response");
24782  if (p->owner) {
24783  ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
24784  }
24785  break;
24786  default:
24787  /* We should treat unrecognized 9xx as 900. 400 is actually
24788  specified as a possible response, but any 4-6xx is
24789  theoretically possible. */
24790 
24791  if (resp < 299) { /* 1xx cases don't get here */
24792  ast_log(LOG_WARNING, "SIP transfer to %s had unexpected 2xx response (%d), confusion is possible. \n", p->refer->refer_to, resp);
24793  } else {
24794  ast_log(LOG_WARNING, "SIP transfer to %s with response (%d). \n", p->refer->refer_to, resp);
24795  }
24796 
24797  p->refer->status = REFER_FAILED;
24798  pvt_set_needdestroy(p, "received failure response");
24799  if (p->owner) {
24800  ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
24801  }
24802  break;
24803  }
24804 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
Definition: channel.c:1231
#define LOG_WARNING
Definition: logger.h:274
enum referstatus status
Definition: sip.h:947
struct ast_sockaddr recv
Definition: sip.h:1135
ast_control_transfer
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.
Definition: chan_sip.c:23036
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
struct sip_request initreq
Definition: sip.h:1151
const ast_string_field refer_to
Definition: sip.h:944
const ast_string_field authname
Definition: sip.h:1063
const ast_string_field callid
Definition: sip.h:1063
static void pvt_set_needdestroy(struct sip_pvt *pvt, const char *reason)
Definition: chan_sip.c:3429
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
#define LOG_NOTICE
Definition: logger.h:263
struct ast_channel * owner
Definition: sip.h:1138
struct sip_refer * refer
Definition: sip.h:1160
Definition: sip.h:622
int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen)
Queue a control frame with payload.
Definition: channel.c:1238
int authtries
Definition: sip.h:1111

◆ handle_response_register()

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

References __get_header(), ao2_t_replace, ast_debug, ast_log, ast_string_field_set, ast_strlen_zero, ast_tvnow(), sip_pvt::authtries, sip_registry::call, sip_pvt::callid, sip_registry::configured_expiry, default_expiry, dialog_unref, do_register_auth(), sip_registry::expiry, EXPIRY_GUARD_LIMIT, EXPIRY_GUARD_MIN, EXPIRY_GUARD_PCT, EXPIRY_GUARD_SECS, global_reg_retry_403, sip_registry::hostname, sip_pvt::initreq, LOG_NOTICE, LOG_WARNING, MAX, MAX_AUTHTRIES, max_expiry, NULL, sip_pvt::our_contact, sip_pvt::peername, pvt_set_needdestroy(), sip_registry::refresh, REG_STATE_NOAUTH, REG_STATE_REGISTERED, REG_STATE_REJECTED, REG_STATE_UNREGISTERED, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, regstate2str(), sip_registry::regtime, S_OR, sip_get_header(), sip_publish_registry(), SIP_REGISTER, sipdebug, start_reregister_timeout(), stop_register_timeout(), strcasestr(), sip_registry::timeout, transmit_register(), sip_pvt::username, and sip_registry::username.

Referenced by handle_response().

24808 {
24809  int expires, expires_ms;
24810  struct sip_registry *r;
24811  r = p->registry;
24812 
24813  switch (resp) {
24814  case 401: /* Unauthorized */
24815  if (p->authtries == MAX_AUTHTRIES || do_register_auth(p, req, resp)) {
24816  ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries);
24817  pvt_set_needdestroy(p, "failed to authenticate REGISTER");
24818  }
24819  break;
24820  case 403: /* Forbidden */
24821  if (global_reg_retry_403) {
24822  ast_log(LOG_NOTICE, "Treating 403 response to REGISTER as non-fatal for %s@%s\n",
24823  p->registry->username, p->registry->hostname);
24824  ast_string_field_set(r, nonce, "");
24825  ast_string_field_set(p, nonce, "");
24826  break;
24827  }
24828  ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname);
24832  pvt_set_needdestroy(p, "received 403 response");
24833  break;
24834  case 404: /* Not found */
24835  ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username, p->registry->hostname);
24836  pvt_set_needdestroy(p, "received 404 response");
24837  if (r->call)
24838  r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 404");
24842  break;
24843  case 407: /* Proxy auth */
24844  if (p->authtries == MAX_AUTHTRIES || do_register_auth(p, req, resp)) {
24845  ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", sip_get_header(&p->initreq, "From"), p->authtries);
24846  pvt_set_needdestroy(p, "failed to authenticate REGISTER");
24847  }
24848  break;
24849  case 408: /* Request timeout */
24850  /* Got a timeout response, so reset the counter of failed responses */
24851  if (r) {
24852  r->regattempts = 0;
24853  } else {
24854  ast_log(LOG_WARNING, "Got a 408 response to our REGISTER on call %s after we had destroyed the registry object\n", p->callid);
24855  }
24856  break;
24857  case 423: /* Interval too brief */
24858  r->expiry = atoi(sip_get_header(req, "Min-Expires"));
24859  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);
24860  if (r->call) {
24861  r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 423");
24862  pvt_set_needdestroy(p, "received 423 response");
24863  }
24864  if (r->expiry > max_expiry) {
24865  ast_log(LOG_WARNING, "Required expiration time from %s@%s is too high, giving up\n", p->registry->username, p->registry->hostname);
24866  r->expiry = r->configured_expiry;
24869  } else {
24872  }
24874  break;
24875  case 400: /* Bad request */
24876  case 414: /* Request URI too long */
24877  case 493: /* Undecipherable */
24878  case 479: /* Kamailio/OpenSIPS: Not able to process the URI - address is wrong in register*/
24879  ast_log(LOG_WARNING, "Got error %d on register to %s@%s, giving up (check config)\n", resp, p->registry->username, p->registry->hostname);
24880  pvt_set_needdestroy(p, "received 4xx response");
24881  if (r->call)
24882  r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 4xx");
24886  break;
24887  case 200: /* 200 OK */
24888  if (!r) {
24889  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));
24890  pvt_set_needdestroy(p, "received erroneous 200 response");
24891  return 0;
24892  }
24893 
24894  ast_debug(1, "Registration successful\n");
24895  if (r->timeout > -1) {
24896  ast_debug(1, "Cancelling timeout %d\n", r->timeout);
24897  }
24900  r->regtime = ast_tvnow(); /* Reset time of last successful registration */
24902  r->regattempts = 0;
24903  if (r->call)
24904  r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 200");
24905  ao2_t_replace(p->registry, NULL, "unref registry entry p->registry");
24906 
24907  /* destroy dialog now to avoid interference with next register */
24908  pvt_set_needdestroy(p, "Registration successfull");
24909 
24910  /* set us up for re-registering
24911  * figure out how long we got registered for
24912  * according to section 6.13 of RFC, contact headers override
24913  * expires headers, so check those first */
24914  expires = 0;
24915 
24916  /* XXX todo: try to save the extra call */
24917  if (!ast_strlen_zero(sip_get_header(req, "Contact"))) {
24918  const char *contact = NULL;
24919  const char *tmptmp = NULL;
24920  int start = 0;
24921  for(;;) {
24922  contact = __get_header(req, "Contact", &start);
24923  /* this loop ensures we get a contact header about our register request */
24924  if(!ast_strlen_zero(contact)) {
24925  if( (tmptmp=strstr(contact, p->our_contact))) {
24926  contact=tmptmp;
24927  break;
24928  }
24929  } else
24930  break;
24931  }
24932  tmptmp = strcasestr(contact, "expires=");
24933  if (tmptmp) {
24934  if (sscanf(tmptmp + 8, "%30d", &expires) != 1) {
24935  expires = 0;
24936  }
24937  }
24938 
24939  }
24940  if (!expires)
24941  expires=atoi(sip_get_header(req, "expires"));
24942  if (!expires)
24943  expires=default_expiry;
24944 
24945  expires_ms = expires * 1000;
24946  if (expires <= EXPIRY_GUARD_LIMIT)
24947  expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT), EXPIRY_GUARD_MIN);
24948  else
24949  expires_ms -= EXPIRY_GUARD_SECS * 1000;
24950  if (sipdebug)
24951  ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000);
24952 
24953  r->refresh= (int) expires_ms / 1000;
24954 
24955  /* Schedule re-registration before we expire */
24956  start_reregister_timeout(r, expires_ms);
24957  }
24958  return 1;
24959 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
static int max_expiry
Definition: chan_sip.c:668
const ast_string_field hostname
Definition: sip.h:1414
const ast_string_field username
Definition: sip.h:1414
enum sipregistrystate regstate
Definition: sip.h:1425
struct sip_pvt * call
Definition: sip.h:1424
#define LOG_WARNING
Definition: logger.h:274
int configured_expiry
Definition: sip.h:1419
const ast_string_field username
Definition: sip.h:1063
#define ao2_t_replace(dst, src, tag)
Replace one object reference with another cleaning up the original.
Definition: astobj2.h:503
Registrations with other SIP proxies.
Definition: sip.h:1396
#define EXPIRY_GUARD_PCT
Definition: sip.h:85
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
struct sip_registry * registry
Definition: sip.h:1173
#define MAX(a, b)
Definition: utils.h:228
#define EXPIRY_GUARD_SECS
Definition: sip.h:74
struct sip_request initreq
Definition: sip.h:1151
const ast_string_field nonce
Definition: sip.h:1414
#define EXPIRY_GUARD_MIN
Definition: sip.h:76
#define MAX_AUTHTRIES
Definition: sip.h:109
int regattempts
Definition: sip.h:1421
static int default_expiry
Definition: chan_sip.c:669
static const char * __get_header(const struct sip_request *req, const char *name, int *start)
Definition: chan_sip.c:8562
static void sip_publish_registry(const char *username, const char *domain, const char *status)
Definition: chan_sip.c:15852
#define EXPIRY_GUARD_LIMIT
Definition: sip.h:75
const ast_string_field callid
Definition: sip.h:1063
static int global_reg_retry_403
Definition: chan_sip.c:828
static void pvt_set_needdestroy(struct sip_pvt *pvt, const char *reason)
Definition: chan_sip.c:3429
static void start_reregister_timeout(struct sip_registry *reg, int ms)
Definition: chan_sip.c:15945
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
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()) ...
Definition: chan_sip.c:16106
static const char * regstate2str(enum sipregistrystate regstate) attribute_const
Convert registration state status to string.
Definition: chan_sip.c:15847
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
#define LOG_NOTICE
Definition: logger.h:263
char * strcasestr(const char *, const char *)
const ast_string_field peername
Definition: sip.h:1063
static int do_register_auth(struct sip_pvt *p, struct sip_request *req, enum sip_auth_type code)
Authenticate for outbound registration.
Definition: chan_sip.c:23012
int expiry
Definition: sip.h:1420
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
int timeout
Definition: sip.h:1422
static void stop_register_timeout(struct sip_registry *reg)
Definition: chan_sip.c:16050
int refresh
Definition: sip.h:1423
struct timeval regtime
Definition: sip.h:1426
int authtries
Definition: sip.h:1111
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514
const ast_string_field our_contact
Definition: sip.h:1063

◆ handle_response_subscribe()

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

References ao2_callback, ao2_ref, ao2_t_ref, ast_cc_monitor_failed(), ast_debug, ast_free, ast_log, ast_string_field_set, sip_pvt::authtries, sip_subscription_mwi::call, CALL_COMPLETION, sip_monitor_instance::core_id, sip_monitor_instance::device_name, do_proxy_auth(), find_sip_monitor_instance_by_subscription_pvt(), sip_pvt::initreq, LOG_NOTICE, LOG_WARNING, sip_pvt::mwi, mwi_expiry, MWI_NOTIFICATION, NULL, sip_pvt::options, sip_invite_param::outboundproxy, pvt_set_needdestroy(), set_pvt_allowed_methods(), sip_alreadygone(), sip_get_header(), SIP_SUBSCRIBE, start_mwi_subscription(), sip_pvt::subscribed, sip_subscription_mwi::subscribed, and transmit_response_with_date().

Referenced by handle_response().

24619 {
24620  if (p->subscribed == CALL_COMPLETION) {
24621  struct sip_monitor_instance *monitor_instance;
24622 
24623  if (resp < 300) {
24624  return;
24625  }
24626 
24627  /* Final failure response received. */
24628  monitor_instance = ao2_callback(sip_monitor_instances, 0,
24630  if (monitor_instance) {
24631  ast_cc_monitor_failed(monitor_instance->core_id,
24632  monitor_instance->device_name,
24633  "Received error response to our SUBSCRIBE");
24634  ao2_ref(monitor_instance, -1);
24635  }
24636  return;
24637  }
24638 
24639  if (p->subscribed != MWI_NOTIFICATION) {
24640  return;
24641  }
24642  if (!p->mwi) {
24643  return;
24644  }
24645 
24646  switch (resp) {
24647  case 200: /* Subscription accepted */
24648  ast_debug(3, "Got 200 OK on subscription for MWI\n");
24649  set_pvt_allowed_methods(p, req);
24650  if (p->options) {
24651  if (p->options->outboundproxy) {
24652  ao2_ref(p->options->outboundproxy, -1);
24653  }
24654  ast_free(p->options);
24655  p->options = NULL;
24656  }
24657  p->mwi->subscribed = 1;
24659  break;
24660  case 401:
24661  case 407:
24662  ast_string_field_set(p, theirtag, NULL);
24663  if (p->authtries > 1 || do_proxy_auth(p, req, resp, SIP_SUBSCRIBE, 0)) {
24664  ast_log(LOG_NOTICE, "Failed to authenticate on SUBSCRIBE to '%s'\n", sip_get_header(&p->initreq, "From"));
24665  p->mwi->call = NULL;
24666  ao2_t_ref(p->mwi, -1, "failed to authenticate SUBSCRIBE");
24667  pvt_set_needdestroy(p, "failed to authenticate SUBSCRIBE");
24668  }
24669  break;
24670  case 403:
24671  transmit_response_with_date(p, "200 OK", req);
24672  ast_log(LOG_WARNING, "Authentication failed while trying to subscribe for MWI.\n");
24673  p->mwi->call = NULL;
24674  ao2_t_ref(p->mwi, -1, "received 403 response");
24675  pvt_set_needdestroy(p, "received 403 response");
24676  sip_alreadygone(p);
24677  break;
24678  case 404:
24679  ast_log(LOG_WARNING, "Subscription failed for MWI. The remote side said that a mailbox may not have been configured.\n");
24680  p->mwi->call = NULL;
24681  ao2_t_ref(p->mwi, -1, "received 404 response");
24682  pvt_set_needdestroy(p, "received 404 response");
24683  break;
24684  case 481:
24685  ast_log(LOG_WARNING, "Subscription failed for MWI. The remote side said that our dialog did not exist.\n");
24686  p->mwi->call = NULL;
24687  ao2_t_ref(p->mwi, -1, "received 481 response");
24688  pvt_set_needdestroy(p, "received 481 response");
24689  break;
24690 
24691  case 400: /* Bad Request */
24692  case 414: /* Request URI too long */
24693  case 493: /* Undecipherable */
24694  case 500:
24695  case 501:
24696  ast_log(LOG_WARNING, "Subscription failed for MWI. The remote side may have suffered a heart attack.\n");
24697  p->mwi->call = NULL;
24698  ao2_t_ref(p->mwi, -1, "received 500/501 response");
24699  pvt_set_needdestroy(p, "received serious error (500/501/493/414/400) response");
24700  break;
24701  }
24702 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
int ast_cc_monitor_failed(int core_id, const char *const monitor_name, const char *const debug,...)
Indicate that a failure has occurred on a specific monitor.
Definition: ccss.c:3941
enum subscriptiontype subscribed
Definition: sip.h:1161
struct sip_proxy * outboundproxy
Definition: sip.h:870
unsigned int subscribed
Definition: sip.h:1465
#define LOG_WARNING
Definition: logger.h:274
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
static void sip_alreadygone(struct sip_pvt *dialog)
Encapsulate setting of SIP_ALREADYGONE to be able to trace it with debugging.
Definition: chan_sip.c:3460
struct ao2_container * sip_monitor_instances
Definition: chan_sip.c:1164
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.
Definition: chan_sip.c:23036
#define NULL
Definition: resample.c:96
struct sip_invite_param * options
Definition: sip.h:1183
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
struct sip_subscription_mwi * mwi
Definition: sip.h:1192
struct sip_request initreq
Definition: sip.h:1151
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct sip_pvt * call
Definition: sip.h:1466
static void pvt_set_needdestroy(struct sip_pvt *pvt, const char *reason)
Definition: chan_sip.c:3429
#define LOG_NOTICE
Definition: logger.h:263
#define ast_free(a)
Definition: astmm.h:182
static int transmit_response_with_date(struct sip_pvt *p, const char *msg, const struct sip_request *req)
Add date before transmitting response.
Definition: chan_sip.c:12724
static void start_mwi_subscription(struct sip_subscription_mwi *mwi, int ms)
Definition: chan_sip.c:14989
static unsigned int set_pvt_allowed_methods(struct sip_pvt *pvt, struct sip_request *req)
Definition: chan_sip.c:9880
const ast_string_field device_name
Definition: sip.h:1819
static int find_sip_monitor_instance_by_subscription_pvt(void *obj, void *arg, int flags)
Definition: chan_sip.c:2075
static int mwi_expiry
Definition: chan_sip.c:672
int authtries
Definition: sip.h:1111
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ handle_response_update()

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

References ast_log, sip_invite_param::auth_type, sip_pvt::authtries, do_proxy_auth(), sip_pvt::initreq, LOG_NOTICE, MAX_AUTHTRIES, sip_pvt::options, PROXY_AUTH, sip_get_header(), SIP_UPDATE, and WWW_AUTH.

Referenced by handle_response().

23861 {
23862  if (p->options) {
23863  p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH);
23864  }
23865  if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, resp, SIP_UPDATE, 1)) {
23866  ast_log(LOG_NOTICE, "Failed to authenticate on UPDATE to '%s'\n", sip_get_header(&p->initreq, "From"));
23867  }
23868 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
enum sip_auth_type auth_type
Definition: sip.h:867
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.
Definition: chan_sip.c:23036
struct sip_invite_param * options
Definition: sip.h:1183
#define ast_log
Definition: astobj2.c:42
struct sip_request initreq
Definition: sip.h:1151
#define MAX_AUTHTRIES
Definition: sip.h:109
#define LOG_NOTICE
Definition: logger.h:263
Definition: sip.h:504
int authtries
Definition: sip.h:1111

◆ handle_sip_publish_initial()

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

References ao2_ref, event_state_compositor::callbacks, create_esc_entry(), sip_esc_publish_callbacks::initial_handler, transmit_response(), and transmit_response_with_sip_etag().

Referenced by handle_request_publish().

28305 {
28306  struct sip_esc_entry *esc_entry = create_esc_entry(esc, req, expires);
28307  int res = 0;
28308 
28309  if (!esc_entry) {
28310  transmit_response(p, "503 Internal Server Failure", req);
28311  return -1;
28312  }
28313 
28314  if (esc->callbacks->initial_handler) {
28315  res = esc->callbacks->initial_handler(p, req, esc, esc_entry);
28316  }
28317 
28318  if (!res) {
28319  transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 0);
28320  }
28321 
28322  ao2_ref(esc_entry, -1);
28323  return res;
28324 }
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)
Definition: chan_sip.c:12570
const struct sip_esc_publish_callbacks * callbacks
Definition: chan_sip.c:999
common ESC items for all event types
Definition: sip.h:1715
static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req)
Transmit response, no retransmits.
Definition: chan_sip.c:12655
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static struct sip_esc_entry * create_esc_entry(struct event_state_compositor *esc, struct sip_request *req, const int expires)
Definition: chan_sip.c:1790
const esc_publish_callback initial_handler
Definition: sip.h:1772

◆ handle_sip_publish_modify()

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

References ao2_ref, AST_SCHED_REPLACE_UNREF, event_state_compositor::callbacks, get_esc_entry(), sip_esc_publish_callbacks::modify_handler, publish_expire(), sip_esc_entry::sched_id, transmit_response(), and transmit_response_with_sip_etag().

Referenced by handle_request_publish().

28355 {
28356  struct sip_esc_entry *esc_entry = get_esc_entry(etag, esc);
28357  int expires_ms = expires * 1000;
28358  int res = 0;
28359 
28360  if (!esc_entry) {
28361  transmit_response(p, "412 Conditional Request Failed", req);
28362  return -1;
28363  }
28364 
28365  AST_SCHED_REPLACE_UNREF(esc_entry->sched_id, sched, expires_ms, publish_expire, esc_entry,
28366  ao2_ref(_data, -1),
28367  ao2_ref(esc_entry, -1),
28368  ao2_ref(esc_entry, +1));
28369 
28370  if (esc->callbacks->modify_handler) {
28371  res = esc->callbacks->modify_handler(p, req, esc, esc_entry);
28372  }
28373 
28374  if (!res) {
28375  transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 1);
28376  }
28377 
28378  ao2_ref(esc_entry, -1);
28379  return res;
28380 }
int sched_id
Definition: sip.h:1750
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)
Definition: chan_sip.c:12570
static struct sip_esc_entry * get_esc_entry(const char *entity_tag, struct event_state_compositor *esc)
Definition: chan_sip.c:1753
Definition: sched.c:76
const struct sip_esc_publish_callbacks * callbacks
Definition: chan_sip.c:999
common ESC items for all event types
Definition: sip.h:1715
const esc_publish_callback modify_handler
Definition: sip.h:1774
static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req)
Transmit response, no retransmits.
Definition: chan_sip.c:12655
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static int publish_expire(const void *data)
Definition: chan_sip.c:1764
#define AST_SCHED_REPLACE_UNREF(id, sched, when, callback, data, unrefcall, addfailcall, refcall)
Definition: sched.h:150

◆ handle_sip_publish_refresh()

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

References ao2_ref, AST_SCHED_REPLACE_UNREF, event_state_compositor::callbacks, get_esc_entry(), publish_expire(), sip_esc_publish_callbacks::refresh_handler, sip_esc_entry::sched_id, transmit_response(), and transmit_response_with_sip_etag().

Referenced by handle_request_publish().

28327 {
28328  struct sip_esc_entry *esc_entry = get_esc_entry(etag, esc);
28329  int expires_ms = expires * 1000;
28330  int res = 0;
28331 
28332  if (!esc_entry) {
28333  transmit_response(p, "412 Conditional Request Failed", req);
28334  return -1;
28335  }
28336 
28337  AST_SCHED_REPLACE_UNREF(esc_entry->sched_id, sched, expires_ms, publish_expire, esc_entry,
28338  ao2_ref(_data, -1),
28339  ao2_ref(esc_entry, -1),
28340  ao2_ref(esc_entry, +1));
28341 
28342  if (esc->callbacks->refresh_handler) {
28343  res = esc->callbacks->refresh_handler(p, req, esc, esc_entry);
28344  }
28345 
28346  if (!res) {
28347  transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 1);
28348  }
28349 
28350  ao2_ref(esc_entry, -1);
28351  return res;
28352 }
int sched_id
Definition: sip.h:1750
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)
Definition: chan_sip.c:12570
static struct sip_esc_entry * get_esc_entry(const char *entity_tag, struct event_state_compositor *esc)
Definition: chan_sip.c:1753
Definition: sched.c:76
const struct sip_esc_publish_callbacks * callbacks
Definition: chan_sip.c:999
common ESC items for all event types
Definition: sip.h:1715
static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req)
Transmit response, no retransmits.
Definition: chan_sip.c:12655
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static int publish_expire(const void *data)
Definition: chan_sip.c:1764
#define AST_SCHED_REPLACE_UNREF(id, sched, when, callback, data, unrefcall, addfailcall, refcall)
Definition: sched.h:150
const esc_publish_callback refresh_handler
Definition: sip.h:1773

◆ handle_sip_publish_remove()

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

References ao2_ref, ao2_unlink, AST_SCHED_DEL, event_state_compositor::callbacks, event_state_compositor::compositor, get_esc_entry(), sip_esc_publish_callbacks::remove_handler, sip_esc_entry::sched_id, transmit_response(), and transmit_response_with_sip_etag().

Referenced by handle_request_publish().

28383 {
28384  struct sip_esc_entry *esc_entry = get_esc_entry(etag, esc);
28385  int res = 0;
28386 
28387  if (!esc_entry) {
28388  transmit_response(p, "412 Conditional Request Failed", req);
28389  return -1;
28390  }
28391 
28392  AST_SCHED_DEL(sched, esc_entry->sched_id);
28393  /* Scheduler's ref of the esc_entry */
28394  ao2_ref(esc_entry, -1);
28395 
28396  if (esc->callbacks->remove_handler) {
28397  res = esc->callbacks->remove_handler(p, req, esc, esc_entry);
28398  }
28399 
28400  if (!res) {
28401  transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 1);
28402  }
28403 
28404  /* Ref from finding the esc_entry earlier in function */
28405  ao2_unlink(esc->compositor, esc_entry);
28406  ao2_ref(esc_entry, -1);
28407  return res;
28408 }
int sched_id
Definition: sip.h:1750
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)
Definition: chan_sip.c:12570
static struct sip_esc_entry * get_esc_entry(const char *entity_tag, struct event_state_compositor *esc)
Definition: chan_sip.c:1753
Definition: sched.c:76
const struct sip_esc_publish_callbacks * callbacks
Definition: chan_sip.c:999
common ESC items for all event types
Definition: sip.h:1715
static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req)
Transmit response, no retransmits.
Definition: chan_sip.c:12655
#define AST_SCHED_DEL(sched, id)
Remove a scheduler entry.
Definition: sched.h:46
#define ao2_ref(o, delta)
Definition: astobj2.h:464
const esc_publish_callback remove_handler
Definition: sip.h:1775
#define ao2_unlink(container, obj)
Definition: astobj2.h:1598
struct ao2_container * compositor
Definition: chan_sip.c:1000

◆ handle_t38_options()

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

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

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

Definition at line 31075 of file chan_sip.c.

References ast_clear_flag, ast_log, ast_set2_flag, ast_set_flag, ast_strdupa, ast_true(), buf, config, global_t38_maxdatagram, ast_variable::lineno, LOG_WARNING, ast_variable::name, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_T38SUPPORT_UDPTL_FEC, SIP_PAGE2_T38SUPPORT_UDPTL_REDUNDANCY, SIP_PAGE2_UDPTL_DESTINATION, strsep(), and ast_variable::value.

Referenced by build_peer(), and reload_config().

31077 {
31078  int res = 1;
31079 
31080  if (!strcasecmp(v->name, "t38pt_udptl")) {
31081  char *buf = ast_strdupa(v->value);
31082  char *word, *next = buf;
31083 
31085 
31086  while ((word = strsep(&next, ","))) {
31087  if (ast_true(word) || !strcasecmp(word, "fec")) {
31090  } else if (!strcasecmp(word, "redundancy")) {
31093  } else if (!strcasecmp(word, "none")) {
31096  } else if (!strncasecmp(word, "maxdatagram=", 12)) {
31097  if (sscanf(&word[12], "%30u", maxdatagram) != 1) {
31098  ast_log(LOG_WARNING, "Invalid maxdatagram '%s' at line %d of %s\n", v->value, v->lineno, config);
31099  *maxdatagram = global_t38_maxdatagram;
31100  }
31101  }
31102  }
31103  } else if (!strcasecmp(v->name, "t38pt_usertpsource")) {
31106  } else {
31107  res = 0;
31108  }
31109 
31110  return res;
31111 }
#define ast_set2_flag(p, value, flag)
Definition: utils.h:94
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define LOG_WARNING
Definition: logger.h:274
static unsigned int global_t38_maxdatagram
Definition: chan_sip.c:885
#define ast_log
Definition: astobj2.c:42
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define SIP_PAGE2_T38SUPPORT_UDPTL_FEC
Definition: sip.h:348
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: main/utils.c:1951
#define SIP_PAGE2_UDPTL_DESTINATION
Definition: sip.h:365
#define ast_clear_flag(p, flag)
Definition: utils.h:77
#define SIP_PAGE2_T38SUPPORT
Definition: sip.h:346
char * strsep(char **str, const char *delims)
#define SIP_PAGE2_T38SUPPORT_UDPTL
Definition: sip.h:347
#define SIP_PAGE2_T38SUPPORT_UDPTL_REDUNDANCY
Definition: sip.h:349
static const char config[]
Definition: chan_sip.c:690
short word

◆ hangup_cause2sip()

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 7108 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_INTERWORKING, 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, ast_debug, and NULL.

Referenced by sip_hangup().

7109 {
7110  switch (cause) {
7111  case AST_CAUSE_UNALLOCATED: /* 1 */
7112  case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */
7113  case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */
7114  return "404 Not Found";
7115  case AST_CAUSE_CONGESTION: /* 34 */
7116  case AST_CAUSE_SWITCH_CONGESTION: /* 42 */
7117  return "503 Service Unavailable";
7118  case AST_CAUSE_NO_USER_RESPONSE: /* 18 */
7119  return "408 Request Timeout";
7120  case AST_CAUSE_NO_ANSWER: /* 19 */
7121  case AST_CAUSE_UNREGISTERED: /* 20 */
7122  return "480 Temporarily unavailable";
7123  case AST_CAUSE_CALL_REJECTED: /* 21 */
7124  return "403 Forbidden";
7125  case AST_CAUSE_NUMBER_CHANGED: /* 22 */
7126  return "410 Gone";
7127  case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */
7128  return "480 Temporarily unavailable";
7130  return "484 Address incomplete";
7131  case AST_CAUSE_USER_BUSY:
7132  return "486 Busy here";
7133  case AST_CAUSE_FAILURE:
7134  return "500 Server internal failure";
7135  case AST_CAUSE_FACILITY_REJECTED: /* 29 */
7136  return "501 Not Implemented";
7138  return "503 Service Unavailable";
7139  /* Used in chan_iax2 */
7141  return "502 Bad Gateway";
7142  case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */
7143  return "488 Not Acceptable Here";
7144  case AST_CAUSE_INTERWORKING: /* Unspecified Interworking issues */
7145  return "500 Network error";
7146 
7147  case AST_CAUSE_NOTDEFINED:
7148  default:
7149  ast_debug(1, "AST hangup cause %d (no match found in SIP)\n", cause);
7150  return NULL;
7151  }
7152 
7153  /* Never reached */
7154  return 0;
7155 }
#define AST_CAUSE_SWITCH_CONGESTION
Definition: causes.h:122
#define AST_CAUSE_UNALLOCATED
Definition: causes.h:97
#define AST_CAUSE_FACILITY_REJECTED
Definition: causes.h:116
#define NULL
Definition: resample.c:96
#define AST_CAUSE_NO_USER_RESPONSE
Definition: causes.h:107
#define AST_CAUSE_INVALID_NUMBER_FORMAT
Definition: causes.h:115
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define AST_CAUSE_NO_ROUTE_TRANSIT_NET
Definition: causes.h:98
#define AST_CAUSE_CHAN_NOT_IMPLEMENTED
Definition: causes.h:131
#define AST_CAUSE_NO_ANSWER
Definition: causes.h:108
#define AST_CAUSE_NOTDEFINED
Definition: causes.h:154
#define AST_CAUSE_DESTINATION_OUT_OF_ORDER
Definition: causes.h:114
#define AST_CAUSE_FAILURE
Definition: causes.h:149
#define AST_CAUSE_NORMAL_UNSPECIFIED
Definition: causes.h:118
#define AST_CAUSE_UNREGISTERED
Definition: causes.h:153
#define AST_CAUSE_NUMBER_CHANGED
Definition: causes.h:111
#define AST_CAUSE_INTERWORKING
Definition: causes.h:145
#define AST_CAUSE_NO_ROUTE_DESTINATION
Definition: causes.h:99
#define AST_CAUSE_USER_BUSY
Definition: causes.h:106
#define AST_CAUSE_CALL_REJECTED
Definition: causes.h:110
#define AST_CAUSE_BEARERCAPABILITY_NOTAVAIL
Definition: causes.h:129
#define AST_CAUSE_CONGESTION
Definition: causes.h:152

◆ hangup_sip2cause()

int hangup_sip2cause ( int  cause)

Convert SIP hangup causes to Asterisk hangup causes.

Definition at line 6986 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_incoming(), handle_response(), and handle_response_invite().

6987 {
6988  /* Possible values taken from causes.h */
6989 
6990  switch(cause) {
6991  case 401: /* Unauthorized */
6992  return AST_CAUSE_CALL_REJECTED;
6993  case 403: /* Not found */
6994  return AST_CAUSE_CALL_REJECTED;
6995  case 404: /* Not found */
6996  return AST_CAUSE_UNALLOCATED;
6997  case 405: /* Method not allowed */
6998  return AST_CAUSE_INTERWORKING;
6999  case 407: /* Proxy authentication required */
7000  return AST_CAUSE_CALL_REJECTED;
7001  case 408: /* No reaction */
7003  case 409: /* Conflict */
7005  case 410: /* Gone */
7006  return AST_CAUSE_NUMBER_CHANGED;
7007  case 411: /* Length required */
7008  return AST_CAUSE_INTERWORKING;
7009  case 413: /* Request entity too large */
7010  return AST_CAUSE_INTERWORKING;
7011  case 414: /* Request URI too large */
7012  return AST_CAUSE_INTERWORKING;
7013  case 415: /* Unsupported media type */
7014  return AST_CAUSE_INTERWORKING;
7015  case 420: /* Bad extension */
7017  case 480: /* No answer */
7018  return AST_CAUSE_NO_ANSWER;
7019  case 481: /* No answer */
7020  return AST_CAUSE_INTERWORKING;
7021  case 482: /* Loop detected */
7022  return AST_CAUSE_INTERWORKING;
7023  case 483: /* Too many hops */
7024  return AST_CAUSE_NO_ANSWER;
7025  case 484: /* Address incomplete */
7027  case 485: /* Ambiguous */
7028  return AST_CAUSE_UNALLOCATED;
7029  case 486: /* Busy everywhere */
7030  return AST_CAUSE_BUSY;
7031  case 487: /* Request terminated */
7032  return AST_CAUSE_INTERWORKING;
7033  case 488: /* No codecs approved */
7035  case 491: /* Request pending */
7036  return AST_CAUSE_INTERWORKING;
7037  case 493: /* Undecipherable */
7038  return AST_CAUSE_INTERWORKING;
7039  case 500: /* Server internal failure */
7040  return AST_CAUSE_FAILURE;
7041  case 501: /* Call rejected */
7043  case 502:
7045  case 503: /* Service unavailable */
7046  return AST_CAUSE_CONGESTION;
7047  case 504: /* Gateway timeout */
7049  case 505: /* SIP version not supported */
7050  return AST_CAUSE_INTERWORKING;
7051  case 600: /* Busy everywhere */
7052  return AST_CAUSE_USER_BUSY;
7053  case 603: /* Decline */
7054  return AST_CAUSE_CALL_REJECTED;
7055  case 604: /* Does not exist anywhere */
7056  return AST_CAUSE_UNALLOCATED;
7057  case 606: /* Not acceptable */
7059  default:
7060  if (cause < 500 && cause >= 400) {
7061  /* 4xx class error that is unknown - someting wrong with our request */
7062  return AST_CAUSE_INTERWORKING;
7063  } else if (cause < 600 && cause >= 500) {
7064  /* 5xx class error - problem in the remote end */
7065  return AST_CAUSE_CONGESTION;
7066  } else if (cause < 700 && cause >= 600) {
7067  /* 6xx - global errors in the 4xx class */
7068  return AST_CAUSE_INTERWORKING;
7069  }
7070  return AST_CAUSE_NORMAL;
7071  }
7072  /* Never reached */
7073  return 0;
7074 }
#define AST_CAUSE_NORMAL_TEMPORARY_FAILURE
Definition: causes.h:121
#define AST_CAUSE_UNALLOCATED
Definition: causes.h:97
#define AST_CAUSE_FACILITY_REJECTED
Definition: causes.h:116
#define AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE
Definition: causes.h:142
#define AST_CAUSE_NO_USER_RESPONSE
Definition: causes.h:107
#define AST_CAUSE_INVALID_NUMBER_FORMAT
Definition: causes.h:115
#define AST_CAUSE_NO_ANSWER
Definition: causes.h:108
#define AST_CAUSE_DESTINATION_OUT_OF_ORDER
Definition: causes.h:114
#define AST_CAUSE_NORMAL
Definition: causes.h:150
#define AST_CAUSE_FAILURE
Definition: causes.h:149
#define AST_CAUSE_NUMBER_CHANGED
Definition: causes.h:111
#define AST_CAUSE_INTERWORKING
Definition: causes.h:145
#define AST_CAUSE_NO_ROUTE_DESTINATION
Definition: causes.h:99
#define AST_CAUSE_USER_BUSY
Definition: causes.h:106
#define AST_CAUSE_BUSY
Definition: causes.h:148
#define AST_CAUSE_CALL_REJECTED
Definition: causes.h:110
#define AST_CAUSE_BEARERCAPABILITY_NOTAVAIL
Definition: causes.h:129
#define AST_CAUSE_CONGESTION
Definition: causes.h:152

◆ has_media_level_attribute()

static int has_media_level_attribute ( int  start,
struct sip_request req,
const char *  attr 
)
static

Definition at line 10230 of file chan_sip.c.

References get_sdp_iterate(), get_sdp_line(), type, and value.

Referenced by process_sdp().

10231 {
10232  int next = start;
10233  char type;
10234  const char *value;
10235 
10236  /* We don't care about the return result here */
10237  get_sdp_iterate(&next, req, "m");
10238 
10239  while ((type = get_sdp_line(&start, next, req, &value)) != '\0') {
10240  if (type == 'a' && !strcasecmp(value, attr)) {
10241  return 1;
10242  }
10243  }
10244 
10245  return 0;
10246 }
static const char type[]
Definition: chan_ooh323.c:109
static const char * get_sdp_iterate(int *start, struct sip_request *req, const char *name)
Lookup &#39;name&#39; in the SDP starting at the &#39;start&#39; line. Returns the matching line, and &#39;start&#39; is upda...
Definition: chan_sip.c:8444
static char get_sdp_line(int *start, int stop, struct sip_request *req, const char **value)
Fetches the next valid SDP line between the &#39;start&#39; line (inclusive) and the &#39;stop&#39; line (exclusive)...
Definition: chan_sip.c:8467
int value
Definition: syslog.c:37

◆ has_media_stream()

static int has_media_stream ( struct sip_pvt p,
enum media_type  m 
)
static

Check the media stream list to see if the given type already exists.

Definition at line 10183 of file chan_sip.c.

References AST_LIST_TRAVERSE, NULL, sip_pvt::offered_media, and offered_media::type.

Referenced by process_sdp().

10184 {
10185  struct offered_media *offer = NULL;
10186  AST_LIST_TRAVERSE(&p->offered_media, offer, next) {
10187  if (m == offer->type) {
10188  return 1;
10189  }
10190  }
10191  return 0;
10192 }
#define NULL
Definition: resample.c:96
enum media_type type
Definition: sip.h:985
Structure for remembering offered media in an INVITE, to make sure we reply to all media streams...
Definition: sip.h:984
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
struct offered_media * next
Definition: sip.h:987
struct sip_pvt::@174 offered_media

◆ init_req()

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

Initialize SIP request.

Definition at line 12173 of file chan_sip.c.

References ast_free, ast_str_create, ast_str_set(), sip_request::content, sip_request::data, sip_request::header, sip_request::headers, sip_request::method, NULL, sip_methods, SIP_MIN_PACKET, and cfsip_methods::text.

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

12174 {
12175  /* Initialize a request */
12176  memset(req, 0, sizeof(*req));
12177  if (!(req->data = ast_str_create(SIP_MIN_PACKET)))
12178  goto e_return;
12179  if (!(req->content = ast_str_create(SIP_MIN_PACKET)))
12180  goto e_free_data;
12181  req->method = sipmethod;
12182  req->header[0] = 0;
12183  ast_str_set(&req->data, 0, "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip);
12184  req->headers++;
12185  return 0;
12186 
12187 e_free_data:
12188  ast_free(req->data);
12189  req->data = NULL;
12190 e_return:
12191  return -1;
12192 }
static const struct cfsip_methods sip_methods[]
ptrdiff_t header[SIP_MAX_HEADERS]
Definition: sip.h:841
#define NULL
Definition: resample.c:96
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
sipmethod
SIP Request methods known by Asterisk.
Definition: sip.h:612
struct ast_str * data
Definition: sip.h:843
struct ast_str * content
Definition: sip.h:844
int method
Definition: sip.h:833
int headers
Definition: sip.h:832
#define ast_free(a)
Definition: astmm.h:182
char *const text
Definition: chan_sip.c:737
#define SIP_MIN_PACKET
Definition: sip.h:114
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ init_resp()

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

Initialize SIP response, based on SIP request.

Definition at line 12151 of file chan_sip.c.

References ast_free, ast_str_create, ast_str_set(), sip_request::content, sip_request::data, sip_request::header, sip_request::headers, sip_request::method, NULL, SIP_MIN_PACKET, and SIP_RESPONSE.

Referenced by respprep().

12152 {
12153  /* Initialize a response */
12154  memset(resp, 0, sizeof(*resp));
12155  resp->method = SIP_RESPONSE;
12156  if (!(resp->data = ast_str_create(SIP_MIN_PACKET)))
12157  goto e_return;
12158  if (!(resp->content = ast_str_create(SIP_MIN_PACKET)))
12159  goto e_free_data;
12160  resp->header[0] = 0;
12161  ast_str_set(&resp->data, 0, "SIP/2.0 %s\r\n", msg);
12162  resp->headers++;
12163  return 0;
12164 
12165 e_free_data:
12166  ast_free(resp->data);
12167  resp->data = NULL;
12168 e_return:
12169  return -1;
12170 }
ptrdiff_t header[SIP_MAX_HEADERS]
Definition: sip.h:841
#define NULL
Definition: resample.c:96
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
struct ast_str * data
Definition: sip.h:843
struct ast_str * content
Definition: sip.h:844
int method
Definition: sip.h:833
int headers
Definition: sip.h:832
#define ast_free(a)
Definition: astmm.h:182
#define SIP_MIN_PACKET
Definition: sip.h:114
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ initialize_escs()

static int initialize_escs ( void  )
static

Definition at line 1817 of file chan_sip.c.

References AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_hash, ARRAY_LEN, event_state_compositor::compositor, esc_cmp_fn(), esc_hash_fn(), ESC_MAX_BUCKETS, event_state_compositors, and NULL.

Referenced by load_module().

1818 {
1819  int i, res = 0;
1820  for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) {
1823  if (!event_state_compositors[i].compositor) {
1824  res = -1;
1825  }
1826  }
1827  return res;
1828 }
static int esc_cmp_fn(void *obj, void *arg, int flags)
Definition: chan_sip.c:1735
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define NULL
Definition: resample.c:96
static struct event_state_compositor event_state_compositors[]
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Definition: astobj2.h:1310
static int esc_hash_fn(const void *obj, const int flags)
Definition: chan_sip.c:1729
struct ao2_container * compositor
Definition: chan_sip.c:1000
static const int ESC_MAX_BUCKETS
Definition: chan_sip.c:1016

◆ initialize_initreq()

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

References ast_debug, ast_verbose(), sip_pvt::callid, copy_request(), sip_request::debug, sip_request::headers, sip_pvt::initreq, sip_request::lines, sip_request::method, parse_request(), sip_methods, and cfsip_methods::text.

Referenced by transmit_invite(), transmit_message(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_reinvite_with_sdp(), and update_connectedline().

3445 {
3446  if (p->initreq.headers) {
3447  ast_debug(1, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid);
3448  } else {
3449  ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid);
3450  }
3451  /* Use this as the basis */
3452  copy_request(&p->initreq, req);
3453  parse_request(&p->initreq);
3454  if (req->debug) {
3455  ast_verbose("Initreq: %d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
3456  }
3457 }
char debug
Definition: sip.h:837
static const struct cfsip_methods sip_methods[]
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct sip_request initreq
Definition: sip.h:1151
static void copy_request(struct sip_request *dst, const struct sip_request *src)
copy SIP request (mostly used to save request for responses)
Definition: chan_sip.c:14061
const ast_string_field callid
Definition: sip.h:1063
int method
Definition: sip.h:833
int headers
Definition: sip.h:832
static int parse_request(struct sip_request *req)
Parse a SIP message.
Definition: chan_sip.c:9954
char *const text
Definition: chan_sip.c:737
int lines
Definition: sip.h:834

◆ initialize_udptl()

static int initialize_udptl ( struct sip_pvt p)
static

Definition at line 7862 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, sip_pvt::flags, global_cos_audio, global_t38_maxdatagram, global_tos_audio, sip_pvt::owner, sip_pvt::relatedpeer, set_t38_capabilities(), SIP_PAGE2_SYMMETRICRTP, SIP_PAGE2_T38SUPPORT, SIP_UDPTL_FD, sip_pvt::t38_maxdatagram, sip_peer::t38_maxdatagram, and sip_pvt::udptl.

Referenced by process_sdp(), process_sdp_a_image(), and sip_indicate().

7863 {
7864  int natflags = ast_test_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP);
7865 
7866  if (!ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) {
7867  return 1;
7868  }
7869 
7870  /* If we've already initialized T38, don't take any further action */
7871  if (p->udptl) {
7872  return 0;
7873  }
7874 
7875  /* T38 can be supported by this dialog, create it and set the derived properties */
7876  if ((p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, &bindaddr))) {
7877  if (p->owner) {
7879  }
7880 
7884 
7885  ast_debug(1, "Setting NAT on UDPTL to %s\n", natflags ? "On" : "Off");
7886  ast_udptl_setnat(p->udptl, natflags);
7887  } else {
7888  ast_log(AST_LOG_WARNING, "UDPTL creation failed - disabling T38 for this dialog\n");
7890  return 1;
7891  }
7892 
7893  return 0;
7894 }
static unsigned int global_tos_audio
Definition: chan_sip.c:834
int t38_maxdatagram
Definition: sip.h:1107
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct sip_peer * relatedpeer
Definition: sip.h:1171
#define AST_LOG_WARNING
Definition: logger.h:279
Definition: sched.c:76
struct ast_flags flags[3]
Definition: sip.h:1075
static unsigned int global_t38_maxdatagram
Definition: chan_sip.c:885
#define SIP_PAGE2_SYMMETRICRTP
Definition: sip.h:327
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
struct ast_udptl * udptl
Definition: sip.h:1115
unsigned int t38_maxdatagram
Definition: sip.h:1329
static struct io_context * io
Definition: chan_sip.c:909
static void set_t38_capabilities(struct sip_pvt *p)
Set the global T38 capabilities on a SIP dialog structure.
Definition: chan_sip.c:5939
struct ast_sockaddr bindaddr
Definition: chan_sip.c:1106
int ast_udptl_setqos(struct ast_udptl *udptl, unsigned int tos, unsigned int cos)
Definition: udptl.c:1125
struct ast_channel * owner
Definition: sip.h:1138
int ast_udptl_fd(const struct ast_udptl *udptl)
Definition: udptl.c:730
#define ast_clear_flag(p, flag)
Definition: utils.h:77
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition: channel.c:2431
struct ast_udptl * ast_udptl_new_with_bindaddr(struct ast_sched_context *sched, struct io_context *io, int callbackmode, struct ast_sockaddr *in)
Definition: udptl.c:1028
#define SIP_PAGE2_T38SUPPORT
Definition: sip.h:346
static unsigned int global_cos_audio
Definition: chan_sip.c:838
void ast_udptl_setnat(struct ast_udptl *udptl, int nat)
Definition: udptl.c:745

◆ initreqprep()

static void initreqprep ( struct sip_request req,
struct sip_pvt p,
int  sipmethod,
const char *const  explicit_uri 
)
static

Initiate new SIP request to peer/user.

Todo:
Need to add back the VXML URL here at some point, possibly use build_string for all this junk

Definition at line 14410 of file chan_sip.c.

References add_header(), add_max_forwards(), add_route(), ast_channel_connected_effective_id(), ast_copy_string(), AST_DIGIT_ANYNUM, AST_DYNSTR_BUILD_FAILED, ast_escape_quoted(), ast_free, ast_log, ast_party_id_presentation(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, ast_sockaddr_port, ast_sockaddr_stringify_host_remote(), ast_str_append(), ast_str_buffer(), ast_str_create, ast_str_make_space, ast_str_set(), ast_str_strlen(), ast_string_field_set, ast_strlen_zero, ast_test_flag, ast_uri_encode(), ast_uri_sip_user, build_contact(), CALLERID_UNKNOWN, sip_pvt::callid, d, default_callerid, exten, sip_pvt::flags, sip_pvt::fromdomain, FROMDOMAIN_INVALID, sip_pvt::fromdomainport, sip_pvt::fromname, sip_pvt::fromuser, sip_pvt::fullcontact, global_useragent, init_req(), sip_pvt::lastmsg, LOG_ERROR, sip_pvt::mwi_from, ast_party_id::name, NULL, ast_party_id::number, sip_pvt::ocseq, sip_pvt::options, sip_pvt::our_contact, sip_pvt::ourip, ourport, sip_pvt::owner, sip_settings::pedanticsipchecking, sip_pvt::portinuri, sip_pvt::route, sip_pvt::sa, sip_cfg, sip_methods, SIP_NOTIFY, sip_standard_port(), SIP_USEREQPHONE, SIPBUFSIZE, SIPHEADER, sip_pvt::socket, STANDARD_SIP_PORT, ast_party_name::str, ast_party_number::str, sip_pvt::tag, cfsip_methods::text, sip_pvt::theirtag, sip_pvt::todnid, sip_pvt::tohost, sip_socket::type, sip_pvt::uri, sip_invite_param::uri_options, sip_pvt::username, ast_party_name::valid, ast_party_number::valid, sip_pvt::via, and sip_invite_param::vxml_url.

Referenced by transmit_invite(), transmit_message(), and transmit_notify_with_mwi().

14411 {
14412 #define SIPHEADER 256
14413  struct ast_str *invite = ast_str_create(SIPHEADER);
14414  struct ast_str *from = ast_str_create(SIPHEADER);
14415  struct ast_str *to = ast_str_create(SIPHEADER);
14416  char tmp_n[SIPBUFSIZE/2]; /* build a local copy of 'n' if needed */
14417  char tmp_l[SIPBUFSIZE/2]; /* build a local copy of 'l' if needed */
14418  const char *l = NULL; /* XXX what is this, exactly ? */
14419  const char *n = NULL; /* XXX what is this, exactly ? */
14420  const char *d = NULL; /* domain in from header */
14421  const char *urioptions = "";
14422  int ourport;
14423  int cid_has_name = 1;
14424  int cid_has_num = 1;
14425  struct ast_party_id connected_id;
14426  int ret;
14427 
14428  if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) {
14429  const char *s = p->username; /* being a string field, cannot be NULL */
14430 
14431  /* Test p->username against allowed characters in AST_DIGIT_ANY
14432  If it matches the allowed characters list, then sipuser = ";user=phone"
14433  If not, then sipuser = ""
14434  */
14435  /* + is allowed in first position in a tel: uri */
14436  if (*s == '+')
14437  s++;
14438  for (; *s; s++) {
14439  if (!strchr(AST_DIGIT_ANYNUM, *s) )
14440  break;
14441  }
14442  /* If we have only digits, add ;user=phone to the uri */
14443  if (!*s)
14444  urioptions = ";user=phone";
14445  }
14446 
14447 
14448  snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text);
14449 
14450  if (ast_strlen_zero(p->fromdomain)) {
14452  }
14453  if (p->owner) {
14454  connected_id = ast_channel_connected_effective_id(p->owner);
14455 
14457  if (connected_id.number.valid) {
14458  l = connected_id.number.str;
14459  }
14460  if (connected_id.name.valid) {
14461  n = connected_id.name.str;
14462  }
14463  } else {
14464  /* Even if we are using RPID, we shouldn't leak information in the From if the user wants
14465  * their callerid restricted */
14466  l = "anonymous";
14467  n = CALLERID_UNKNOWN;
14468  d = FROMDOMAIN_INVALID;
14469  }
14470  }
14471 
14472  /* Hey, it's a NOTIFY! See if they've configured a mwi_from.
14473  * XXX Right now, this logic works because the only place that mwi_from
14474  * is set on the sip_pvt is in sip_send_mwi_to_peer. If things changed, then
14475  * we might end up putting the mwi_from setting into other types of NOTIFY
14476  * messages as well.
14477  */
14478  if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->mwi_from)) {
14479  l = p->mwi_from;
14480  }
14481 
14482  if (ast_strlen_zero(l)) {
14483  cid_has_num = 0;
14484  l = default_callerid;
14485  }
14486  if (ast_strlen_zero(n)) {
14487  cid_has_name = 0;
14488  n = l;
14489  }
14490 
14491  /* Allow user to be overridden */
14492  if (!ast_strlen_zero(p->fromuser))
14493  l = p->fromuser;
14494  else /* Save for any further attempts */
14495  ast_string_field_set(p, fromuser, l);
14496 
14497  /* Allow user to be overridden */
14498  if (!ast_strlen_zero(p->fromname))
14499  n = p->fromname;
14500  else /* Save for any further attempts */
14501  ast_string_field_set(p, fromname, n);
14502 
14503  /* Allow domain to be overridden */
14504  if (!ast_strlen_zero(p->fromdomain))
14505  d = p->fromdomain;
14506  else /* Save for any further attempts */
14507  ast_string_field_set(p, fromdomain, d);
14508 
14509  ast_copy_string(tmp_l, l, sizeof(tmp_l));
14511  ast_uri_encode(l, tmp_l, sizeof(tmp_l), ast_uri_sip_user);
14512  }
14513 
14515 
14516  if (!sip_standard_port(p->socket.type, ourport)) {
14517  ret = ast_str_set(&from, 0, "<sip:%s@%s:%d>;tag=%s", tmp_l, d, ourport, p->tag);
14518  } else {
14519  ret = ast_str_set(&from, 0, "<sip:%s@%s>;tag=%s", tmp_l, d, p->tag);
14520  }
14521  if (ret == AST_DYNSTR_BUILD_FAILED) {
14522  /* We don't have an escape path from here... */
14523  ast_log(LOG_ERROR, "The From header was truncated in call '%s'. This call setup will fail.\n", p->callid);
14524  /* Make sure that the field contains something non-broken.
14525  See https://issues.asterisk.org/jira/browse/ASTERISK-26069
14526  */
14527  ast_str_set(&from, 3, "<>");
14528 
14529  }
14530 
14531  /* If a caller id name was specified, prefix a display name, if there is enough room. */
14532  if (cid_has_name || !cid_has_num) {
14533  size_t written = ast_str_strlen(from);
14534  size_t name_len;
14536  ast_escape_quoted(n, tmp_n, sizeof(tmp_n));
14537  n = tmp_n;
14538  }
14539  name_len = strlen(n);
14540  ret = ast_str_make_space(&from, name_len + written + 4);
14541 
14542  if (ret == 0) {
14543  /* needed again, as ast_str_make_space coud've changed the pointer */
14544  char *from_buf = ast_str_buffer(from);
14545 
14546  memmove(from_buf + name_len + 3, from_buf, written + 1);
14547  from_buf[0] = '"';
14548  memcpy(from_buf + 1, n, name_len);
14549  from_buf[name_len + 1] = '"';
14550  from_buf[name_len + 2] = ' ';
14551  }
14552  }
14553 
14554  if (!ast_strlen_zero(explicit_uri)) {
14555  ast_str_set(&invite, 0, "%s", explicit_uri);
14556  } else {
14557  /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */
14558  if (!ast_strlen_zero(p->fullcontact)) {
14559  /* If we have full contact, trust it */
14560  ast_str_append(&invite, 0, "%s", p->fullcontact);
14561  } else {
14562  /* Otherwise, use the username while waiting for registration */
14563  ast_str_append(&invite, 0, "sip:");
14564  if (!ast_strlen_zero(p->username)) {
14565  n = p->username;
14567  ast_uri_encode(n, tmp_n, sizeof(tmp_n), ast_uri_sip_user);
14568  n = tmp_n;
14569  }
14570  ast_str_append(&invite, 0, "%s@", n);
14571  }
14572  ast_str_append(&invite, 0, "%s", p->tohost);
14573  if (p->portinuri) {
14574  ast_str_append(&invite, 0, ":%d", ast_sockaddr_port(&p->sa));
14575  }
14576  ast_str_append(&invite, 0, "%s", urioptions);
14577  }
14578  }
14579 
14580  /* If custom URI options have been provided, append them */
14581  if (p->options && !ast_strlen_zero(p->options->uri_options))
14582  ast_str_append(&invite, 0, ";%s", p->options->uri_options);
14583 
14584  /* This is the request URI, which is the next hop of the call
14585  which may or may not be the destination of the call
14586  */
14587  ast_string_field_set(p, uri, ast_str_buffer(invite));
14588 
14589  if (!ast_strlen_zero(p->todnid)) {
14590  /*! \todo Need to add back the VXML URL here at some point, possibly use build_string for all this junk */
14591  if (!strchr(p->todnid, '@')) {
14592  /* We have no domain in the dnid */
14593  ret = ast_str_set(&to, 0, "<sip:%s@%s>%s%s", p->todnid, p->tohost, ast_strlen_zero(p->theirtag) ? "" : ";tag=", p->theirtag);
14594  } else {
14595  ret = ast_str_set(&to, 0, "<sip:%s>%s%s", p->todnid, ast_strlen_zero(p->theirtag) ? "" : ";tag=", p->theirtag);
14596  }
14597  } else {
14598  if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) {
14599  /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */
14600  ret = ast_str_set(&to, 0, "<%s%s>;tag=%s", (strncasecmp(p->uri, "sip:", 4) ? "sip:" : ""), p->uri, p->theirtag);
14601  } else if (p->options && p->options->vxml_url) {
14602  /* If there is a VXML URL append it to the SIP URL */
14603  ret = ast_str_set(&to, 0, "<%s>;%s", p->uri, p->options->vxml_url);
14604  } else {
14605  ret = ast_str_set(&to, 0, "<%s>", p->uri);
14606  }
14607  }
14608  if (ret == AST_DYNSTR_BUILD_FAILED) {
14609  /* We don't have an escape path from here... */
14610  ast_log(LOG_ERROR, "The To header was truncated in call '%s'. This call setup will fail.\n", p->callid);
14611  /* Make sure that the field contains something non-broken.
14612  See https://issues.asterisk.org/jira/browse/ASTERISK-26069
14613  */
14614  ast_str_set(&to, 3, "<>");
14615  }
14616 
14617  init_req(req, sipmethod, p->uri);
14618  /* now tmp_n is available so reuse it to build the CSeq */
14619  snprintf(tmp_n, sizeof(tmp_n), "%u %s", ++p->ocseq, sip_methods[sipmethod].text);
14620 
14621  add_header(req, "Via", p->via);
14622  add_max_forwards(p, req);
14623  /* This will be a no-op most of the time. However, under certain circumstances,
14624  * NOTIFY messages will use this function for preparing the request and should
14625  * have Route headers present.
14626  */
14627  add_route(req, &p->route, 0);
14628 
14629  add_header(req, "From", ast_str_buffer(from));
14630  add_header(req, "To", ast_str_buffer(to));
14631  ast_string_field_set(p, exten, l);
14632  build_contact(p, req, 0);
14633  add_header(req, "Contact", p->our_contact);
14634  add_header(req, "Call-ID", p->callid);
14635  add_header(req, "CSeq", tmp_n);
14637  add_header(req, "User-Agent", global_useragent);
14638  }
14639 
14640  ast_free(from);
14641  ast_free(to);
14642  ast_free(invite);
14643 }
Information needed to identify an endpoint in a call.
Definition: channel.h:339
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
int fromdomainport
Definition: sip.h:1220
char lastmsg[256]
Definition: sip.h:1145
char via[128]
Definition: sip.h:1063
#define ast_test_flag(p, flag)
Definition: utils.h:63
static const struct cfsip_methods sip_methods[]
static void add_route(struct sip_request *req, struct sip_route *route, int skip)
Add route header into request per learned route.
Definition: chan_sip.c:12042
unsigned int portinuri
Definition: sip.h:1124
#define ast_str_make_space(buf, new_len)
Definition: strings.h:780
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
static char global_useragent[AST_MAX_EXTENSION]
Definition: chan_sip.c:843
static struct test_val d
int ast_party_id_presentation(const struct ast_party_id *id)
Determine the overall presentation value for the given party.
Definition: channel.c:1821
struct sip_socket socket
Definition: sip.h:1066
char * ast_uri_encode(const char *string, char *outbuf, int buflen, struct ast_flags spec)
Turn text string to URI-encoded XX version.
Definition: main/utils.c:577
const ast_string_field username
Definition: sip.h:1063
struct ast_sockaddr ourip
Definition: sip.h:1136
static int init_req(struct sip_request *req, int sipmethod, const char *recip)
Initialize SIP request.
Definition: chan_sip.c:12173
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
struct ast_flags flags[3]
Definition: sip.h:1075
static char default_callerid[AST_MAX_EXTENSION]
Definition: chan_sip.c:791
#define NULL
Definition: resample.c:96
const ast_string_field fullcontact
Definition: sip.h:1063
const ast_string_field fromuser
Definition: sip.h:1063
struct sip_invite_param * options
Definition: sip.h:1183
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define FROMDOMAIN_INVALID
Definition: sip.h:94
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:521
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
struct ast_sockaddr sa
Definition: sip.h:1125
#define ast_log
Definition: astobj2.c:42
const char * vxml_url
Definition: sip.h:864
static int add_max_forwards(struct sip_pvt *dialog, struct sip_request *req)
Add &#39;Max-Forwards&#39; header to SIP message.
Definition: chan_sip.c:11901
#define STANDARD_SIP_PORT
Standard SIP unsecure port for UDP and TCP from RFC 3261. DO NOT CHANGE THIS.
Definition: sip.h:176
static int sip_standard_port(enum ast_transport type, int port)
Returns the port to use for this socket.
Definition: chan_sip.c:29515
const ast_string_field fromdomain
Definition: sip.h:1063
#define AST_DIGIT_ANYNUM
Definition: file.h:49
const ast_string_field theirtag
Definition: sip.h:1063
sipmethod
SIP Request methods known by Asterisk.
Definition: sip.h:612
int pedanticsipchecking
Definition: sip.h:756
struct sip_route route
Definition: sip.h:1139
const ast_string_field callid
Definition: sip.h:1063
#define LOG_ERROR
Definition: logger.h:285
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
struct ast_party_id ast_channel_connected_effective_id(struct ast_channel *chan)
const char * uri_options
Definition: sip.h:863
#define SIPBUFSIZE
Definition: sip.h:56
#define SIPHEADER
uint32_t ocseq
Definition: sip.h:1067
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
static void build_contact(struct sip_pvt *p, struct sip_request *req, int incoming)
Build contact header.
Definition: chan_sip.c:14385
static char * ast_sockaddr_stringify_host_remote(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only, suitable for a URL (with brack...
Definition: netsock2.h:349
#define ast_free(a)
Definition: astmm.h:182
char * ast_escape_quoted(const char *string, char *outbuf, int buflen)
Escape characters found in a quoted string.
Definition: main/utils.c:635
struct ast_channel * owner
Definition: sip.h:1138
const ast_string_field mwi_from
Definition: sip.h:1063
#define CALLERID_UNKNOWN
Definition: sip.h:93
char *const text
Definition: chan_sip.c:737
#define AST_PRES_RESTRICTION
Definition: callerid.h:323
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
enum ast_transport type
Definition: sip.h:798
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
const ast_string_field tohost
Definition: sip.h:1063
#define AST_PRES_ALLOWED
Definition: callerid.h:324
const ast_string_field tag
Definition: sip.h:1063
const struct ast_flags ast_uri_sip_user
Definition: main/utils.c:575
const ast_string_field todnid
Definition: sip.h:1063
const ast_string_field fromname
Definition: sip.h:1063
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873
static int ourport
Definition: chan_mgcp.c:240
#define SIP_USEREQPHONE
Definition: sip.h:271
const ast_string_field uri
Definition: sip.h:1063
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514
const ast_string_field our_contact
Definition: sip.h:1063

◆ insecure2str()

static const char * insecure2str ( int  mode)
static

Convert Insecure setting to printable string.

Definition at line 20618 of file chan_sip.c.

References map_x_s().

Referenced by _sip_show_peer().

20619 {
20620  return map_x_s(insecurestr, mode, "<error>");
20621 }
static const struct _map_x_s insecurestr[]
Definition: chan_sip.c:20609
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
Definition: chan_sip.c:2411

◆ interpret_t38_parameters()

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

References AST_CONTROL_T38_PARAMETERS, ast_queue_control_data(), 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, sip_pvt::flags, sip_pvt::initreq, ast_control_t38_parameters::max_ifp, MIN, t38properties::our_parms, sip_pvt::owner, sip_pvt::pendinginvite, ast_control_t38_parameters::rate_management, ast_control_t38_parameters::request_response, SIP_NEEDREINVITE, SIP_PAGE2_T38SUPPORT, SIP_PENDINGBYE, t38properties::state, stop_t38_abort_timer(), sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_LOCAL_REINVITE, T38_PEER_REINVITE, T38_REJECTED, t38properties::their_parms, ast_control_t38_parameters::transcoding_jbig, ast_control_t38_parameters::transcoding_mmr, transmit_reinvite_with_sdp(), transmit_response_reliable(), transmit_response_with_t38_sdp(), TRUE, sip_pvt::udptl, ast_control_t38_parameters::version, and XMIT_CRITICAL.

Referenced by sip_indicate().

7754 {
7755  int res = 0;
7756 
7757  if (!ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) || !p->udptl) {
7758  return -1;
7759  }
7760  switch (parameters->request_response) {
7761  case AST_T38_NEGOTIATED:
7762  case AST_T38_REQUEST_NEGOTIATE: /* Request T38 */
7763  /* Negotiation can not take place without a valid max_ifp value. */
7764  if (!parameters->max_ifp) {
7765  if (p->t38.state == T38_PEER_REINVITE) {
7767  transmit_response_reliable(p, "488 Not acceptable here", &p->initreq);
7768  }
7770  break;
7771  } else if (p->t38.state == T38_PEER_REINVITE) {
7773  p->t38.our_parms = *parameters;
7774  /* modify our parameters to conform to the peer's parameters,
7775  * based on the rules in the ITU T.38 recommendation
7776  */
7777  if (!p->t38.their_parms.fill_bit_removal) {
7779  }
7780  if (!p->t38.their_parms.transcoding_mmr) {
7782  }
7783  if (!p->t38.their_parms.transcoding_jbig) {
7785  }
7791  } else if ((p->t38.state != T38_ENABLED) || ((p->t38.state == T38_ENABLED) &&
7792  (parameters->request_response == AST_T38_REQUEST_NEGOTIATE))) {
7793  p->t38.our_parms = *parameters;
7796  if (!p->pendinginvite) {
7798  } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
7800  }
7801  }
7802  break;
7803  case AST_T38_TERMINATED:
7804  case AST_T38_REFUSED:
7805  case AST_T38_REQUEST_TERMINATE: /* Shutdown T38 */
7806  if (p->t38.state == T38_PEER_REINVITE) {
7809  transmit_response_reliable(p, "488 Not acceptable here", &p->initreq);
7810  } else if (p->t38.state == T38_ENABLED) {
7813  }
7814  break;
7815  case AST_T38_REQUEST_PARMS: { /* Application wants remote's parameters re-sent */
7816  struct ast_control_t38_parameters parameters = p->t38.their_parms;
7817 
7818  if (p->t38.state == T38_PEER_REINVITE) {
7820  parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
7822  if (p->owner) {
7823  ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, &parameters, sizeof(parameters));
7824  }
7825  /* we need to return a positive value here, so that applications that
7826  * send this request can determine conclusively whether it was accepted or not...
7827  * older versions of chan_sip would just silently accept it and return zero.
7828  */
7829  res = AST_T38_REQUEST_PARMS;
7830  }
7831  break;
7832  }
7833  default:
7834  res = -1;
7835  break;
7836  }
7837 
7838  return res;
7839 }
#define T38_ENABLED
Definition: chan_ooh323.c:102
#define FALSE
Definition: app_minivm.c:521
void ast_udptl_set_local_max_ifp(struct ast_udptl *udptl, unsigned int max_ifp)
Definition: udptl.c:973
enum t38state state
Definition: sip.h:917
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_control_t38_parameters our_parms
Definition: sip.h:918
#define ast_set_flag(p, flag)
Definition: utils.h:70
uint32_t pendinginvite
Definition: sip.h:1147
enum ast_control_t38 request_response
struct ast_flags flags[3]
Definition: sip.h:1075
struct t38properties t38
Definition: sip.h:1113
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.
Definition: chan_sip.c:12688
#define MIN(a, b)
Definition: utils.h:226
struct sip_request initreq
Definition: sip.h:1151
struct ast_udptl * udptl
Definition: sip.h:1115
unsigned int ast_udptl_get_far_max_ifp(struct ast_udptl *udptl)
retrieves far max ifp
Definition: udptl.c:1016
static int transmit_reinvite_with_sdp(struct sip_pvt *p, int t38version, int oldsdp)
Transmit reinvite with SDP.
Definition: chan_sip.c:14212
#define T38_DISABLED
Definition: chan_ooh323.c:101
struct ast_control_t38_parameters their_parms
Definition: sip.h:919
struct ast_channel * owner
Definition: sip.h:1138
static void stop_t38_abort_timer(struct sip_pvt *pvt)
Definition: chan_sip.c:26116
#define SIP_PAGE2_T38SUPPORT
Definition: sip.h:346
#define SIP_PENDINGBYE
Definition: sip.h:262
static void change_t38_state(struct sip_pvt *p, int state)
Change the T38 state on a SIP dialog.
Definition: chan_sip.c:5889
#define TRUE
Definition: app_minivm.c:518
enum ast_control_t38_rate_management rate_management
int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen)
Queue a control frame with payload.
Definition: channel.c:1238
#define SIP_NEEDREINVITE
Definition: sip.h:261
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.
Definition: chan_sip.c:14041

◆ is_method_allowed()

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

Referenced by sip_sendtext(), and update_connectedline().

9807 {
9808  return ((*allowed_methods) >> method) & 1;
9809 }
const char * method
Definition: res_pjsip.c:4335

◆ load_module()

static int load_module ( void  )
static

Load the module.

Module loading including tests for configuration or dependencies. This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE, or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails tests return AST_MODULE_LOAD_FAILURE. If the module can not load the configuration file or other non-critical problem return AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.

Definition at line 35495 of file chan_sip.c.

References AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_hash, AO2_CONTAINER_ALLOC_OPT_INSERT_BEGIN, ao2_t_container_alloc_hash, ao2_t_container_alloc_list, ao2_t_global_obj_replace_unref, 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_format_cap_alloc, ast_format_cap_append_by_type(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_fully_booted, ast_log, ast_logger_register_level(), ast_manager_get_topic(), ast_manager_register_xml, AST_MEDIA_TYPE_AUDIO, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_msg_tech_register(), ast_realtime_require_field(), ast_register_application_xml, ast_rtp_glue_register, ast_sched_context_create(), ast_sip_api_provider_register(), ast_string_field_set, AST_TEST_REGISTER, ast_verbose(), ast_websocket_add_protocol(), BOGUS_PEER_MD5SECRET, can_parse_xml, ast_channel_tech::capabilities, sip_settings::caps, CHANNEL_MODULE_LOAD, deprecation_notice(), dialog_cmp_cb(), dialog_hash_cb(), EVENT_FLAG_REPORTING, EVENT_FLAG_SYSTEM, sip_peer::flags, HASH_DIALOG_SIZE, HASH_PEER_SIZE, HASH_REGISTRY_SIZE, initialize_escs(), io_context_create(), LOG_ERROR, log_level, LOG_WARNING, manager_show_registry(), manager_sip_peer_status(), manager_sip_qualify_peer(), manager_sip_show_peer(), manager_sip_show_peers(), manager_sipnotify(), network_change_stasis_subscribe(), NULL, peer_cmp_cb(), peer_hash_cb(), peer_iphash_cb(), sip_settings::peer_rtupdate, registry_cmp_cb(), registry_hash_cb(), reload_config(), restart_monitor(), RQ_CHAR, RQ_INTEGER4, RQ_UINTEGER2, ast_channel_tech::send_digit_begin, SENTINEL, sip_addheader(), sip_cfg, sip_dtmfmode(), sip_epa_register(), SIP_INSECURE, sip_is_xml_parsable(), sip_keepalive_all_peers(), sip_monitor_instance_cmp_fn(), sip_monitor_instance_hash_fn(), sip_poke_all_peers(), sip_register_tests(), sip_reloadreason, sip_removeheader(), sip_reqresp_parser_init(), sip_send_all_mwi_subscriptions(), sip_send_all_registers(), sip_sendcustominfo(), sip_tech_info, sip_websocket_callback(), startup_event_cb(), STASIS_MESSAGE_TYPE_INIT, stasis_subscribe_pool, temp_peer(), threadt_cmp_cb(), threadt_hash_cb(), unload_module(), and sip_settings::websocket_enabled.

Referenced by unload_module().

35496 {
35497  struct sip_peer *bogus_peer;
35498 
35499  ast_verbose("SIP channel loading...\n");
35500  log_level = ast_logger_register_level("SIP_HISTORY");
35501  if (log_level < 0) {
35502  ast_log(LOG_WARNING, "Unable to register history log level\n");
35503  }
35504 
35505  if (STASIS_MESSAGE_TYPE_INIT(session_timeout_type)) {
35506  unload_module();
35507  return AST_MODULE_LOAD_DECLINE;
35508  }
35509 
35511  unload_module();
35512  return AST_MODULE_LOAD_DECLINE;
35513  }
35514 
35516  unload_module();
35517  return AST_MODULE_LOAD_DECLINE;
35518  }
35519 
35520  /* the fact that ao2_containers can't resize automatically is a major worry! */
35521  /* if the number of objects gets above MAX_XXX_BUCKETS, things will slow down */
35523  peer_hash_cb, NULL, peer_cmp_cb, "allocate peers");
35525  peer_iphash_cb, NULL, NULL, "allocate peers_by_ip");
35527  dialog_hash_cb, NULL, dialog_cmp_cb, "allocate dialogs");
35529  NULL, NULL, NULL, "allocate dialogs_needdestroy");
35531  dialog_hash_cb, NULL, dialog_cmp_cb, "allocate dialogs for rtpchecks");
35533  threadt_hash_cb, NULL, threadt_cmp_cb, "allocate threadt table");
35535  || !threadt) {
35536  ast_log(LOG_ERROR, "Unable to create primary SIP container(s)\n");
35537  unload_module();
35538  return AST_MODULE_LOAD_DECLINE;
35539  }
35540 
35542  unload_module();
35543  return AST_MODULE_LOAD_DECLINE;
35544  }
35546 
35548  registry_hash_cb, NULL, registry_cmp_cb, "allocate registry_list");
35550  AO2_CONTAINER_ALLOC_OPT_INSERT_BEGIN, NULL, NULL, "allocate subscription_mwi_list");
35551 
35552  if (!(sched = ast_sched_context_create())) {
35553  ast_log(LOG_ERROR, "Unable to create scheduler context\n");
35554  unload_module();
35555  return AST_MODULE_LOAD_DECLINE;
35556  }
35557 
35558  if (!(io = io_context_create())) {
35559  ast_log(LOG_ERROR, "Unable to create I/O context\n");
35560  unload_module();
35561  return AST_MODULE_LOAD_DECLINE;
35562  }
35563 
35565 
35567  if (reload_config(sip_reloadreason)) { /* Load the configuration from sip.conf */
35568  unload_module();
35569  return AST_MODULE_LOAD_DECLINE;
35570  }
35571 
35572  /* Initialize bogus peer. Can be done first after reload_config() */
35573  if (!(bogus_peer = temp_peer("(bogus_peer)"))) {
35574  ast_log(LOG_ERROR, "Unable to create bogus_peer for authentication\n");
35575  unload_module();
35576  return AST_MODULE_LOAD_DECLINE;
35577  }
35578  /* Make sure the auth will always fail. */
35580  ast_clear_flag(&bogus_peer->flags[0], SIP_INSECURE);
35581  ao2_t_global_obj_replace_unref(g_bogus_peer, bogus_peer, "Set the initial bogus peer.");
35582  ao2_t_ref(bogus_peer, -1, "Module load is done with the bogus peer.");
35583 
35584  /* Prepare the version that does not require DTMF BEGIN frames.
35585  * We need to use tricks such as memcpy and casts because the variable
35586  * has const fields.
35587  */
35588  memcpy(&sip_tech_info, &sip_tech, sizeof(sip_tech));
35589  memset((void *) &sip_tech_info.send_digit_begin, 0, sizeof(sip_tech_info.send_digit_begin));
35590 
35592  unload_module();
35593  return AST_MODULE_LOAD_DECLINE;
35594  }
35595 
35596  /* Make sure we can register our sip channel type */
35598  ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n");
35599  unload_module();
35600  return AST_MODULE_LOAD_DECLINE;
35601  }
35602 
35603 #ifdef TEST_FRAMEWORK
35604  AST_TEST_REGISTER(test_sip_mwi_subscribe_parse);
35605  AST_TEST_REGISTER(test_tcp_message_fragmentation);
35606  AST_TEST_REGISTER(get_in_brackets_const_test);
35607 #endif
35608 
35609  /* Register all CLI functions for SIP */
35611 
35612  /* Tell the RTP engine about our RTP glue */
35614 
35615  /* Register dialplan applications */
35619 #ifdef TEST_FRAMEWORK
35621 #endif
35622 
35623  /* Register dialplan functions */
35628 
35629  /* Register manager commands */
35640  initialize_escs();
35641 
35643  unload_module();
35644  return AST_MODULE_LOAD_DECLINE;
35645  }
35646 
35647  if (sip_reqresp_parser_init() == -1) {
35648  ast_log(LOG_ERROR, "Unable to initialize the SIP request and response parser\n");
35649  unload_module();
35650  return AST_MODULE_LOAD_DECLINE;
35651  }
35652 
35653  if (can_parse_xml) {
35654  /* SIP CC agents require the ability to parse XML PIDF bodies
35655  * in incoming PUBLISH requests
35656  */
35658  unload_module();
35659  return AST_MODULE_LOAD_DECLINE;
35660  }
35661  }
35663  unload_module();
35664  return AST_MODULE_LOAD_DECLINE;
35665  }
35668  if (!sip_monitor_instances) {
35669  unload_module();
35670  return AST_MODULE_LOAD_DECLINE;
35671  }
35672 
35673  /* And start the monitor for the first time */
35674  restart_monitor();
35675 
35676  if (sip_cfg.peer_rtupdate) {
35677  ast_realtime_require_field(ast_check_realtime("sipregs") ? "sipregs" : "sippeers",
35678  "name", RQ_CHAR, 10,
35679  "ipaddr", RQ_CHAR, INET6_ADDRSTRLEN - 1,
35680  "port", RQ_UINTEGER2, 5,
35681  "regseconds", RQ_INTEGER4, 11,
35682  "defaultuser", RQ_CHAR, 10,
35683  "fullcontact", RQ_CHAR, 35,
35684  "regserver", RQ_CHAR, 20,
35685  "useragent", RQ_CHAR, 20,
35686  "lastms", RQ_INTEGER4, 11,
35687  SENTINEL);
35688  }
35689 
35690 
35693 
35694  if (sip_cfg.websocket_enabled) {
35696  }
35697 
35698  if (ast_fully_booted) {
35700  } else {
35702  }
35703 
35704  return AST_MODULE_LOAD_SUCCESS;
35705 }
static const struct epa_static_data cc_epa_static_data
Definition: chan_sip.c:1671
static struct ao2_container * dialogs
Definition: chan_sip.c:1043
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
static struct ao2_container * threadt
The table of TCP threads.
Definition: chan_sip.c:1049
int ast_cc_agent_register(const struct ast_cc_agent_callbacks *callbacks)
Register a set of agent callbacks with the core.
Definition: ccss.c:1239
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static int sip_monitor_instance_cmp_fn(void *obj, void *arg, int flags)
Definition: chan_sip.c:2028
static void startup_event_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Event callback which indicates we&#39;re fully booted.
Definition: chan_sip.c:35461
struct ao2_container * dialogs_needdestroy
Definition: chan_sip.c:1024
static int registry_cmp_cb(void *obj, void *arg, int flags)
Definition: chan_sip.c:34672
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
Definition: stasis.h:1501
#define ao2_t_global_obj_replace_unref(holder, obj, tag)
Replace an ao2 object in the global holder, throwing away any old object.
Definition: astobj2.h:906
#define LOG_WARNING
Definition: logger.h:274
static int unload_module(void)
PBX unload module API.
Definition: chan_sip.c:35708
static struct ast_rtp_glue sip_rtp_glue
Definition: chan_sip.c:34005
static struct ast_cli_entry cli_sip[]
SIP Cli commands definition.
Definition: chan_sip.c:34698
int ast_check_realtime(const char *family)
Check if realtime engine is configured for family.
Definition: main/config.c:3363
static int initialize_escs(void)
Definition: chan_sip.c:1817
static int sip_is_xml_parsable(void)
Definition: chan_sip.c:34232
static enum channelreloadreason sip_reloadreason
Definition: chan_sip.c:906
#define ast_rtp_glue_register(glue)
Definition: rtp_engine.h:847
#define BOGUS_PEER_MD5SECRET
We can recognize the bogus peer by this invalid MD5 hash.
Definition: chan_sip.c:1058
static int peer_cmp_cb(void *obj, void *arg, int flags)
Definition: chan_sip.c:34498
Definition: sched.c:76
#define AST_TEST_REGISTER(cb)
Definition: test.h:127
struct ao2_container * sip_monitor_instances
Definition: chan_sip.c:1164
#define ao2_t_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn, tag)
Allocate and initialize a list container.
Definition: astobj2.h:1333
int ast_msg_tech_register(const struct ast_msg_tech *tech)
Register a message technology.
Definition: message.c:1569
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
int ast_format_cap_append_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Add all codecs Asterisk knows about for a specific type to the capabilities structure.
Definition: format_cap.c:216
int(*const send_digit_begin)(struct ast_channel *chan, char digit)
Start sending a literal DTMF digit.
Definition: channel.h:684
static void sip_websocket_callback(struct ast_websocket *session, struct ast_variable *parameters, struct ast_variable *headers)
SIP WebSocket connection handler.
Definition: chan_sip.c:2678
static const int HASH_PEER_SIZE
Definition: chan_sip.c:943
int ast_channel_register(const struct ast_channel_tech *tech)
Register a channel technology (a new channel driver) Called by a channel module to register the kind ...
Definition: channel.c:539
static struct ast_custom_function sippeer_function
Structure to declare a dialplan function: SIPPEER.
Definition: chan_sip.c:23520
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
static int peer_iphash_cb(const void *obj, const int flags)
Definition: chan_sip.c:34510
static char * app_sipaddheader
Definition: chan_sip.c:34017
#define NULL
Definition: resample.c:96
int peer_rtupdate
Definition: sip.h:750
int websocket_enabled
Definition: sip.h:791
static int log_level
Definition: chan_sip.c:665
static int manager_sip_peer_status(struct mansession *s, const struct message *m)
Show SIP peers in the manager API.
Definition: chan_sip.c:21014
static int sip_epa_register(const struct epa_static_data *static_data)
Definition: chan_sip.c:1635
static struct ao2_container * registry_list
The register list: Other SIP proxies we register with and receive calls from.
Definition: chan_sip.c:1061
static int manager_sip_show_peer(struct mansession *s, const struct message *m)
Show SIP peers in the manager API.
Definition: chan_sip.c:20939
static struct ao2_container * peers_by_ip
Definition: chan_sip.c:1053
Insert objects at the beginning of the container. (Otherwise it is the opposite; insert at the end...
Definition: astobj2.h:1176
static int manager_show_registry(struct mansession *s, const struct message *m)
Show SIP registrations in the manager API.
Definition: chan_sip.c:20178
int AST_OPTIONAL_API_NAME() ast_websocket_add_protocol(const char *name, ast_websocket_callback callback)
static struct ast_custom_function sip_header_function
Definition: chan_sip.c:23305
int ast_cc_monitor_register(const struct ast_cc_monitor_callbacks *callbacks)
Register a set of monitor callbacks with the core.
Definition: ccss.c:1184
static void deprecation_notice(void)
Definition: chan_sip.c:35452
static int reload_config(enum channelreloadreason reason)
Re-read SIP.conf config file.
Definition: chan_sip.c:32514
#define EVENT_FLAG_SYSTEM
Definition: manager.h:71
#define ast_log
Definition: astobj2.c:42
#define SENTINEL
Definition: compiler.h:87
static const struct ast_msg_tech sip_msg_tech
Definition: chan_sip.c:27833
int ast_realtime_require_field(const char *family,...) attribute_sentinel
Inform realtime what fields that may be stored.
Definition: main/config.c:3382
static void network_change_stasis_subscribe(void)
Definition: chan_sip.c:17547
int ast_sip_api_provider_register(const struct ast_sip_api_tech *provider)
Register a SIP API provider.
Definition: sip_api.c:39
#define ast_fully_booted
Definition: options.h:115
static char * app_sipsendcustominfo
Definition: chan_sip.c:34020
static const int HASH_DIALOG_SIZE
Definition: chan_sip.c:944
static int threadt_hash_cb(const void *obj, const int flags)
Definition: chan_sip.c:34606
static int sip_addheader(struct ast_channel *chan, const char *data)
Add a SIP header to an outbound INVITE.
Definition: chan_sip.c:34078
const ast_string_field md5secret
Definition: sip.h:1306
static struct ast_custom_function sip_headers_function
Definition: chan_sip.c:23389
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
static struct io_context * io
Definition: chan_sip.c:909
int ast_logger_register_level(const char *name)
Register a new logger level.
Definition: logger.c:2503
static int sip_monitor_instance_hash_fn(const void *obj, const int flags)
Definition: chan_sip.c:2022
struct ast_sched_context * ast_sched_context_create(void)
Create a scheduler context.
Definition: sched.c:236
static int dialog_cmp_cb(void *obj, void *arg, int flags)
Definition: chan_sip.c:34643
static int sip_dtmfmode(struct ast_channel *chan, const char *data)
Set the DTMFmode for an outbound SIP call (application)
Definition: chan_sip.c:34024
static int peer_hash_cb(const void *obj, const int flags)
Definition: chan_sip.c:34488
#define SIP_INSECURE
Definition: sip.h:294
#define LOG_ERROR
Definition: logger.h:285
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Definition: astobj2.h:1310
static void sip_send_all_mwi_subscriptions(void)
Send all MWI subscriptions.
Definition: chan_sip.c:34326
static int sip_removeheader(struct ast_channel *chan, const char *data)
Remove SIP headers added previously with SipAddHeader application.
Definition: chan_sip.c:34118
static int threadt_cmp_cb(void *obj, void *arg, int flags)
Definition: chan_sip.c:34613
static void sip_poke_all_peers(void)
Send a poke to all known peers.
Definition: chan_sip.c:34242
#define stasis_subscribe_pool(topic, callback, data)
Definition: stasis.h:682
static struct ast_cc_agent_callbacks sip_cc_agent_callbacks
Definition: chan_sip.c:1618
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
static struct sip_peer * temp_peer(const char *name)
Create temporary peer (used in autocreatepeer mode)
Definition: chan_sip.c:31550
struct ast_format_cap * capabilities
Definition: channel.h:633
static int sip_sendcustominfo(struct ast_channel *chan, const char *data)
Send a custom INFO message via AST_CONTROL_CUSTOM indication.
Definition: chan_sip.c:34152
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
#define ao2_t_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn, tag)
Allocate and initialize a hash container with the desired number of buckets.
Definition: astobj2.h:1308
static int manager_sipnotify(struct mansession *s, const struct message *m)
Definition: chan_sip.c:15659
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static int registry_hash_cb(const void *obj, const int flags)
Definition: chan_sip.c:34651
struct stasis_topic * ast_manager_get_topic(void)
Get the Stasis Message Bus API topic for AMI.
Definition: manager.c:1720
struct ast_format_cap * caps
Global list of addresses dynamic peers are not allowed to use.
Definition: sip.h:787
#define ast_clear_flag(p, flag)
Definition: utils.h:77
static void sip_register_tests(void)
SIP test registration.
Definition: chan_sip.c:34725
static char * app_dtmfmode
Definition: chan_sip.c:34016
#define EVENT_FLAG_REPORTING
Definition: manager.h:80
static int can_parse_xml
Definition: chan_sip.c:872
static struct ast_cc_monitor_callbacks sip_cc_monitor_callbacks
Definition: chan_sip.c:2093
static struct ao2_container * subscription_mwi_list
The MWI subscription list.
Definition: chan_sip.c:1064
struct ast_flags flags[3]
Definition: sip.h:1335
static int manager_sip_qualify_peer(struct mansession *s, const struct message *m)
Qualify SIP peers in the manager API.
Definition: chan_sip.c:21115
static int manager_sip_show_peers(struct mansession *s, const struct message *m)
Show SIP peers in the manager API.
Definition: chan_sip.c:20231
static const struct ast_sip_api_tech chan_sip_api_provider
Definition: chan_sip.c:35446
static int restart_monitor(void)
Start the channel monitor thread.
Definition: chan_sip.c:30078
static int dialog_hash_cb(const void *obj, const int flags)
Definition: chan_sip.c:34623
static const int HASH_REGISTRY_SIZE
Definition: chan_sip.c:945
int sip_reqresp_parser_init(void)
initialize request and response parser data
struct ast_channel_tech sip_tech
Definition of this channel for PBX channel registration.
Definition: chan_sip.c:1573
struct ao2_container * dialogs_rtpcheck
Definition: chan_sip.c:1032
static void sip_send_all_registers(void)
Send all known registrations.
Definition: chan_sip.c:34298
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...
Definition: chan_sip.c:1606
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:186
static char * app_sipremoveheader
Definition: chan_sip.c:34018
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1508
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:626
static struct ast_custom_function checksipdomain_function
Definition: chan_sip.c:23409
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514
static void sip_keepalive_all_peers(void)
Send a keepalive to all known peers.
Definition: chan_sip.c:34275
struct io_context * io_context_create(void)
Creates a context Create a context for I/O operations Basically mallocs an IO structure and sets up s...
Definition: io.c:81

◆ local_attended_transfer()

static int local_attended_transfer ( struct sip_pvt transferer,
struct ast_channel transferer_chan,
uint32_t  seqno,
int *  nounlock 
)
static

Find all call legs and bridge transferee with target called from handle_request_refer.

Note
this function assumes two locks to begin with, sip_pvt transferer and current.chan1 (the pvt's owner)... 2 additional locks are held at the beginning of the function, targetcall_pvt, and targetcall_pvt's owner channel (which is stored in target.chan1). These 2 locks MUST be let go by the end of the function. Do not be confused into thinking a pvt's owner is the same thing as the channels locked at the beginning of this function, after the masquerade this may not be true. Be consistent and unlock only the exact same pointers that were locked to begin with.

If this function is successful, only the transferer pvt lock will remain on return. Setting nounlock indicates to handle_request_do() that the pvt's owner it locked does not require an unlock.

Definition at line 27143 of file chan_sip.c.

References ao2_cleanup, append_history, ast_bridge_transfer_attended(), AST_BRIDGE_TRANSFER_FAIL, AST_BRIDGE_TRANSFER_INVALID, AST_BRIDGE_TRANSFER_NOT_PERMITTED, AST_BRIDGE_TRANSFER_SUCCESS, ast_channel_unlock, ast_clear_flag, ast_debug, ast_set_flag, sip_pvt::flags, get_sip_pvt_from_replaces(), sip_refer::localtransfer, NULL, RAII_VAR, sip_pvt::refer, REFER_200OK, REFER_FAILED, sip_refer::replaces_callid, sip_refer::replaces_callid_fromtag, sip_refer::replaces_callid_totag, SIP_DEFER_BYE_ON_TRANSFER, SIP_GOTREFER, sip_pvt_lock, sip_pvt_unlock, sip_refer::status, transmit_notify_with_sipfrag(), and TRUE.

Referenced by handle_request_refer().

27144 {
27145  RAII_VAR(struct sip_pvt *, targetcall_pvt, NULL, ao2_cleanup);
27146  RAII_VAR(struct ast_channel *, targetcall_chan, NULL, ao2_cleanup);
27147  enum ast_transfer_result transfer_res;
27148 
27149  /* Check if the call ID of the replaces header does exist locally */
27151  transferer->refer->replaces_callid_totag,
27152  transferer->refer->replaces_callid_fromtag,
27153  &targetcall_pvt, &targetcall_chan)) {
27154  if (transferer->refer->localtransfer) {
27155  /* We did not find the refered call. Sorry, can't accept then */
27156  /* Let's fake a response from someone else in order
27157  to follow the standard */
27158  transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE);
27159  append_history(transferer, "Xfer", "Refer failed");
27160  ast_clear_flag(&transferer->flags[0], SIP_GOTREFER);
27161  transferer->refer->status = REFER_FAILED;
27162  return -1;
27163  }
27164  /* Fall through for remote transfers that we did not find locally */
27165  ast_debug(3, "SIP attended transfer: Not our call - generating INVITE with replaces\n");
27166  return 0;
27167  }
27168 
27169  if (!targetcall_chan) { /* No active channel */
27170  ast_debug(4, "SIP attended transfer: Error: No owner of target call\n");
27171  /* Cancel transfer */
27172  transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE);
27173  append_history(transferer, "Xfer", "Refer failed");
27174  ast_clear_flag(&transferer->flags[0], SIP_GOTREFER);
27175  transferer->refer->status = REFER_FAILED;
27176  return -1;
27177  }
27178 
27179  ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */
27180 
27181  sip_pvt_unlock(transferer);
27182  ast_channel_unlock(transferer_chan);
27183  *nounlock = 1;
27184 
27185  transfer_res = ast_bridge_transfer_attended(transferer_chan, targetcall_chan);
27186 
27187  sip_pvt_lock(transferer);
27188 
27189  switch (transfer_res) {
27191  transferer->refer->status = REFER_200OK;
27192  transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE);
27193  append_history(transferer, "Xfer", "Refer succeeded");
27194  return 1;
27196  transferer->refer->status = REFER_FAILED;
27197  transmit_notify_with_sipfrag(transferer, seqno, "500 Internal Server Error", TRUE);
27198  append_history(transferer, "Xfer", "Refer failed (internal error)");
27200  return -1;
27202  transferer->refer->status = REFER_FAILED;
27203  transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE);
27204  append_history(transferer, "Xfer", "Refer failed (invalid bridge state)");
27206  return -1;
27208  transferer->refer->status = REFER_FAILED;
27209  transmit_notify_with_sipfrag(transferer, seqno, "403 Forbidden", TRUE);
27210  append_history(transferer, "Xfer", "Refer failed (operation not permitted)");
27212  return -1;
27213  default:
27214  break;
27215  }
27216 
27217  return 1;
27218 }
Main Channel structure associated with a channel.
enum ast_transfer_result ast_bridge_transfer_attended(struct ast_channel *to_transferee, struct ast_channel *to_transfer_target)
Attended transfer.
Definition: bridge.c:4729
#define ast_set_flag(p, flag)
Definition: utils.h:70
enum referstatus status
Definition: sip.h:947
#define SIP_DEFER_BYE_ON_TRANSFER
Definition: sip.h:267
const ast_string_field replaces_callid_fromtag
Definition: sip.h:944
struct ast_flags flags[3]
Definition: sip.h:1075
#define NULL
Definition: resample.c:96
ast_transfer_result
Definition: bridge.h:1115
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
int localtransfer
Definition: sip.h:946
const ast_string_field replaces_callid_totag
Definition: sip.h:944
#define SIP_GOTREFER
Definition: sip.h:263
const ast_string_field replaces_callid
Definition: sip.h:944
static int get_sip_pvt_from_replaces(const char *callid, const char *totag, const char *fromtag, struct sip_pvt **out_pvt, struct ast_channel **out_chan)
Find a companion dialog based on Replaces information.
Definition: chan_sip.c:18693
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_clear_flag(p, flag)
Definition: utils.h:77
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)
Definition: chan_sip.c:15636
struct sip_refer * refer
Definition: sip.h:1160
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define TRUE
Definition: app_minivm.c:518
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406

◆ lws2sws()

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

References ast_str_buffer(), ast_str_strlen(), ast_str_update(), and len().

Referenced by handle_request_do(), and read_raw_content_length().

9895 {
9896  char *msgbuf = ast_str_buffer(data);
9897  int len = ast_str_strlen(data);
9898  int h = 0, t = 0;
9899  int lws = 0;
9900  int just_read_eol = 0;
9901  int done_with_headers = 0;
9902 
9903  while (h < len) {
9904  /* Eliminate all CRs */
9905  if (msgbuf[h] == '\r') {
9906  h++;
9907  continue;
9908  }
9909  /* Check for end-of-line */
9910  if (msgbuf[h] == '\n') {
9911  if (just_read_eol) {
9912  done_with_headers = 1;
9913  } else {
9914  just_read_eol = 1;
9915  }
9916  /* Check for end-of-message */
9917  if (h + 1 == len)
9918  break;
9919  /* Check for a continuation line */
9920  if (!done_with_headers
9921  && (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t')) {
9922  /* Merge continuation line */
9923  h++;
9924  continue;
9925  }
9926  /* Propagate LF and start new line */
9927  msgbuf[t++] = msgbuf[h++];
9928  lws = 0;
9929  continue;
9930  } else {
9931  just_read_eol = 0;
9932  }
9933  if (!done_with_headers
9934  && (msgbuf[h] == ' ' || msgbuf[h] == '\t')) {
9935  if (lws) {
9936  h++;
9937  continue;
9938  }
9939  msgbuf[t++] = msgbuf[h++];
9940  lws = 1;
9941  continue;
9942  }
9943  msgbuf[t++] = msgbuf[h++];
9944  if (lws)
9945  lws = 0;
9946  }
9947  msgbuf[t] = '\0';
9948  ast_str_update(data);
9949 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
void ast_str_update(struct ast_str *buf)
Update the length of the buffer, after using ast_str merely as a buffer.
Definition: strings.h:663

◆ make_our_tag()

static void make_our_tag ( struct sip_pvt pvt)
static

Make our SIP dialog tag.

Definition at line 8908 of file chan_sip.c.

References ast_random(), and ast_string_field_build.

Referenced by __sip_alloc(), handle_request_invite(), handle_request_subscribe(), and transmit_response_using_temp().

8909 {
8910  ast_string_field_build(pvt, tag, "as%08lx", (unsigned long)ast_random());
8911 }
long int ast_random(void)
Definition: main/utils.c:2064
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
Definition: stringfields.h:550

◆ manager_show_registry()

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

Show SIP registrations in the manager API.

Definition at line 20178 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_iterator_next, ao2_t_ref, ao2_unlock, ast_strlen_zero, astman_append(), astman_get_header(), astman_send_list_complete_end(), astman_send_list_complete_start(), astman_send_listack(), sip_registry::hostname, sip_registry::portno, sip_registry::refresh, sip_registry::regdomain, sip_registry::regdomainport, sip_registry::regstate, regstate2str(), sip_registry::regtime, S_OR, STANDARD_SIP_PORT, total, and sip_registry::username.

Referenced by load_module().

20179 {
20180  const char *id = astman_get_header(m, "ActionID");
20181  char idtext[256] = "";
20182  int total = 0;
20183  struct ao2_iterator iter;
20184  struct sip_registry *iterator;
20185 
20186  if (!ast_strlen_zero(id))
20187  snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
20188 
20189  astman_send_listack(s, m, "Registrations will follow", "start");
20190 
20191  iter = ao2_iterator_init(registry_list, 0);
20192  while ((iterator = ao2_t_iterator_next(&iter, "manager_show_registry iter"))) {
20193  ao2_lock(iterator);
20194 
20195  astman_append(s,
20196  "Event: RegistryEntry\r\n"
20197  "%s"
20198  "Host: %s\r\n"
20199  "Port: %d\r\n"
20200  "Username: %s\r\n"
20201  "Domain: %s\r\n"
20202  "DomainPort: %d\r\n"
20203  "Refresh: %d\r\n"
20204  "State: %s\r\n"
20205  "RegistrationTime: %ld\r\n"
20206  "\r\n",
20207  idtext,
20208  iterator->hostname,
20209  iterator->portno ? iterator->portno : STANDARD_SIP_PORT,
20210  iterator->username,
20211  S_OR(iterator->regdomain,iterator->hostname),
20212  iterator->regdomainport ? iterator->regdomainport : STANDARD_SIP_PORT,
20213  iterator->refresh,
20214  regstate2str(iterator->regstate),
20215  (long) iterator->regtime.tv_sec);
20216 
20217  ao2_unlock(iterator);
20218  ao2_t_ref(iterator, -1, "manager_show_registry iter");
20219  total++;
20220  }
20221  ao2_iterator_destroy(&iter);
20222 
20223  astman_send_list_complete_start(s, m, "RegistrationsComplete", total);
20225 
20226  return 0;
20227 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3080
const ast_string_field hostname
Definition: sip.h:1414
const ast_string_field username
Definition: sip.h:1414
enum sipregistrystate regstate
Definition: sip.h:1425
int portno
Definition: sip.h:1416
void astman_send_list_complete_start(struct mansession *s, const struct message *m, const char *event_name, int count)
Start the list complete event.
Definition: manager.c:3237
Registrations with other SIP proxies.
Definition: sip.h:1396
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_unlock(a)
Definition: astobj2.h:730
static struct ao2_container * registry_list
The register list: Other SIP proxies we register with and receive calls from.
Definition: chan_sip.c:1061
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
int regdomainport
Definition: sip.h:1417
#define STANDARD_SIP_PORT
Standard SIP unsecure port for UDP and TCP from RFC 3261. DO NOT CHANGE THIS.
Definition: sip.h:176
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:3245
#define ao2_lock(a)
Definition: astobj2.h:718
#define ao2_t_iterator_next(iter, tag)
Definition: astobj2.h:1931
static const char * regstate2str(enum sipregistrystate regstate) attribute_const
Convert registration state status to string.
Definition: chan_sip.c:15847
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
const ast_string_field regdomain
Definition: sip.h:1414
static int total
Definition: res_adsi.c:968
int refresh
Definition: sip.h:1423
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
struct timeval regtime
Definition: sip.h:1426
void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag)
Send ack in manager transaction to begin a list.
Definition: manager.c:3201

◆ manager_sip_peer_status()

static int manager_sip_peer_status ( struct mansession s,
const struct message m 
)
static

Show SIP peers in the manager API.

Definition at line 21014 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_iterator_next, ao2_unlock, ast_strlen_zero, astman_get_header(), astman_send_error(), astman_send_list_complete_end(), astman_send_list_complete_start(), astman_send_listack(), FALSE, FINDPEERS, NULL, send_manager_peer_status(), sip_find_peer(), sip_unref_peer, and TRUE.

Referenced by load_module().

21015 {
21016  const char *id = astman_get_header(m,"ActionID");
21017  const char *peer_name = astman_get_header(m,"Peer");
21018  char idText[256];
21019  struct sip_peer *peer = NULL;
21020  int num_peers = 0;
21021 
21022  idText[0] = '\0';
21023  if (!ast_strlen_zero(id)) {
21024  snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
21025  }
21026 
21027  if (!ast_strlen_zero(peer_name)) {
21028  /* strip SIP/ from the begining of the peer name */
21029  if (strlen(peer_name) >= 4 && !strncasecmp("SIP/", peer_name, 4)) {
21030  peer_name += 4;
21031  }
21032 
21033  peer = sip_find_peer(peer_name, NULL, TRUE, FINDPEERS, FALSE, 0);
21034  if (!peer) {
21035  astman_send_error(s, m, "No such peer");
21036  return 0;
21037  }
21038  }
21039 
21040  astman_send_listack(s, m, "Peer status will follow", "start");
21041 
21042  if (!peer) {
21043  struct ao2_iterator i = ao2_iterator_init(peers, 0);
21044 
21045  while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table for SIPpeerstatus"))) {
21046  ao2_lock(peer);
21047  send_manager_peer_status(s, peer, idText);
21048  ao2_unlock(peer);
21049  sip_unref_peer(peer, "unref peer for SIPpeerstatus");
21050  ++num_peers;
21051  }
21053  } else {
21054  ao2_lock(peer);
21055  send_manager_peer_status(s, peer, idText);
21056  ao2_unlock(peer);
21057  sip_unref_peer(peer, "unref peer for SIPpeerstatus");
21058  ++num_peers;
21059  }
21060 
21061  astman_send_list_complete_start(s, m, "SIPpeerstatusComplete", num_peers);
21063 
21064  return 0;
21065 }
#define FALSE
Definition: app_minivm.c:521
struct sip_peer * sip_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.
Definition: chan_sip.c:5851
void astman_send_list_complete_start(struct mansession *s, const struct message *m, const char *event_name, int count)
Start the list complete event.
Definition: manager.c:3237
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:3245
#define ao2_lock(a)
Definition: astobj2.h:718
#define ao2_t_iterator_next(iter, tag)
Definition: astobj2.h:1931
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
#define FINDPEERS
Definition: sip.h:53
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
static void send_manager_peer_status(struct mansession *s, struct sip_peer *peer, const char *idText)
Definition: chan_sip.c:20981
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
#define TRUE
Definition: app_minivm.c:518
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag)
Send ack in manager transaction to begin a list.
Definition: manager.c:3201

◆ manager_sip_qualify_peer()

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

Qualify SIP peers in the manager API.

Definition at line 21115 of file chan_sip.c.

References _sip_qualify_peer(), ast_strlen_zero, astman_get_header(), and astman_send_error().

Referenced by load_module().

21116 {
21117  const char *a[4];
21118  const char *peer;
21119 
21120  peer = astman_get_header(m, "Peer");
21121  if (ast_strlen_zero(peer)) {
21122  astman_send_error(s, m, "Peer: <name> missing.");
21123  return 0;
21124  }
21125  a[0] = "sip";
21126  a[1] = "qualify";
21127  a[2] = "peer";
21128  a[3] = peer;
21129 
21130  _sip_qualify_peer(1, -1, s, m, 4, a);
21131  return 0;
21132 }
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
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.
Definition: chan_sip.c:21084
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159
static struct test_val a

◆ manager_sip_show_peer()

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

Show SIP peers in the manager API.

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

20940 {
20941  const char *a[4];
20942  const char *peer;
20943 
20944  peer = astman_get_header(m, "Peer");
20945  if (ast_strlen_zero(peer)) {
20946  astman_send_error(s, m, "Peer: <name> missing.");
20947  return 0;
20948  }
20949  a[0] = "sip";
20950  a[1] = "show";
20951  a[2] = "peer";
20952  a[3] = peer;
20953 
20954  _sip_show_peer(1, -1, s, m, 4, a);
20955  astman_append(s, "\r\n" );
20956  return 0;
20957 }
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3080
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
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)
Definition: chan_sip.c:21181
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159
static struct test_val a

◆ manager_sip_show_peers()

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

Show SIP peers in the manager API.

Definition at line 20231 of file chan_sip.c.

References _sip_show_peers(), a, ast_strlen_zero, astman_get_header(), astman_send_list_complete_end(), astman_send_list_complete_start(), astman_send_listack(), and total.

Referenced by load_module().

20232 {
20233  const char *id = astman_get_header(m, "ActionID");
20234  const char *a[] = {"sip", "show", "peers"};
20235  char idtext[256] = "";
20236  int total = 0;
20237 
20238  if (!ast_strlen_zero(id))
20239  snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
20240 
20241  astman_send_listack(s, m, "Peer status list will follow", "start");
20242 
20243  /* List the peers in separate manager events */
20244  _sip_show_peers(-1, &total, s, m, 3, a);
20245 
20246  /* Send final confirmation */
20247  astman_send_list_complete_start(s, m, "PeerlistComplete", total);
20249  return 0;
20250 }
void astman_send_list_complete_start(struct mansession *s, const struct message *m, const char *event_name, int count)
Start the list complete event.
Definition: manager.c:3237
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.
Definition: chan_sip.c:20295
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:3245
static int total
Definition: res_adsi.c:968
void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag)
Send ack in manager transaction to begin a list.
Definition: manager.c:3201
static struct test_val a

◆ manager_sipnotify()

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

Definition at line 15659 of file chan_sip.c.

References ao2_find, ast_log, ast_set_flag, ast_sip_ouraddrfor(), 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(), build_via(), sip_pvt::callid, change_callid_pvt(), sip_notify::content, create_addr(), dialog_unlink_all(), dialog_unref, sip_pvt::flags, sip_notify::headers, LOG_WARNING, ast_variable::name, ast_variable::next, sip_pvt::notify, NULL, OBJ_SEARCH_OBJECT, ORDER_NATURAL, sip_pvt::ourip, sip_pvt::sa, sip_alloc, SIP_NOTIFY, sip_notify_alloc(), SIP_OUTGOING, sip_scheddestroy(), SIP_TRANS_TIMEOUT, transmit_invite(), ast_variable::value, and var.

Referenced by load_module().

15660 {
15661  const char *channame = astman_get_header(m, "Channel");
15663  const char *callid = astman_get_header(m, "Call-ID");
15664  struct sip_pvt *p;
15665  struct ast_variable *header, *var;
15666 
15667  if (ast_strlen_zero(channame)) {
15668  astman_send_error(s, m, "SIPNotify requires a channel name");
15669  ast_variables_destroy(vars);
15670  return 0;
15671  }
15672 
15673  if (!strncasecmp(channame, "sip/", 4)) {
15674  channame += 4;
15675  }
15676 
15677  /* check if Call-ID header is set */
15678  if (!ast_strlen_zero(callid)) {
15679  struct sip_pvt tmp_dialog = {
15680  .callid = callid,
15681  };
15682 
15683  p = ao2_find(dialogs, &tmp_dialog, OBJ_SEARCH_OBJECT);
15684  if (!p) {
15685  astman_send_error(s, m, "Call-ID not found");
15686  ast_variables_destroy(vars);
15687  return 0;
15688  }
15689 
15690  if (!(p->notify)) {
15691  sip_notify_alloc(p);
15692  } else {
15694  }
15695  } else {
15696  if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL, 0))) {
15697  astman_send_error(s, m, "Unable to build sip pvt data for notify (memory/socket error)");
15698  ast_variables_destroy(vars);
15699  return 0;
15700  }
15701 
15702  if (create_addr(p, channame, NULL, 1)) {
15703  /* Maybe they're not registered, etc. */
15704  dialog_unlink_all(p);
15705  dialog_unref(p, "unref dialog inside for loop" );
15706  /* sip_destroy(p); */
15707  astman_send_error(s, m, "Could not create address");
15708  ast_variables_destroy(vars);
15709  return 0;
15710  }
15711 
15712  /* Notify is outgoing call */
15713  ast_set_flag(&p->flags[0], SIP_OUTGOING);
15714  sip_notify_alloc(p);
15715 
15716  }
15717 
15718  p->notify->headers = header = ast_variable_new("Subscription-State", "terminated", "");
15719 
15720  for (var = vars; var; var = var->next) {
15721  if (!strcasecmp(var->name, "Content")) {
15722  if (ast_str_strlen(p->notify->content))
15723  ast_str_append(&p->notify->content, 0, "\r\n");
15724  ast_str_append(&p->notify->content, 0, "%s", var->value);
15725  } else if (!strcasecmp(var->name, "Content-Length")) {
15726  ast_log(LOG_WARNING, "it is not necessary to specify Content-Length, ignoring\n");
15727  } else {
15728  header->next = ast_variable_new(var->name, var->value, "");
15729  header = header->next;
15730  }
15731  }
15732 
15733  if (ast_strlen_zero(callid)) {
15734  /* Now that we have the peer's address, set our ip and change callid */
15735  ast_sip_ouraddrfor(&p->sa, &p->ourip, p);
15736  build_via(p);
15737 
15738  change_callid_pvt(p, NULL);
15739 
15741  transmit_invite(p, SIP_NOTIFY, 0, 2, NULL);
15742  } else {
15744  transmit_invite(p, SIP_NOTIFY, 0, 1, NULL);
15745  }
15746  dialog_unref(p, "bump down the count of p since we're done with it.");
15747 
15748  astman_send_ack(s, m, "Notify Sent");
15749  ast_variables_destroy(vars);
15750  return 0;
15751 }
static struct ao2_container * dialogs
Definition: chan_sip.c:1043
struct ast_variable * next
static void build_via(struct sip_pvt *p)
Build a Via header for a request.
Definition: chan_sip.c:3847
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
struct ast_str * content
Definition: sip.h:953
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define LOG_WARNING
Definition: logger.h:274
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.
Definition: chan_sip.c:14755
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
struct ast_sockaddr ourip
Definition: sip.h:1136
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3191
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?
Definition: chan_sip.c:3866
struct ast_flags flags[3]
Definition: sip.h:1075
#define NULL
Definition: resample.c:96
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
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 stor...
Definition: chan_sip.c:3367
struct ast_sockaddr sa
Definition: sip.h:1125
#define ast_log
Definition: astobj2.c:42
static int sip_notify_alloc(struct sip_pvt *p)
Allocate SIP refer structure.
Definition: chan_sip.c:16388
#define sip_alloc(callid, addr, useglobal_nat, intended_method, req, logger_callid)
Definition: dialog.h:39
#define ast_variable_new(name, value, filename)
const ast_string_field callid
Definition: sip.h:1063
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
static void change_callid_pvt(struct sip_pvt *pvt, const char *callid)
Definition: chan_sip.c:8860
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
struct ast_variable * headers
Definition: sip.h:952
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
The arg parameter is an object of the same type.
Definition: astobj2.h:1091
struct ast_variable * astman_get_variables_order(const struct message *m, enum variable_orders order)
Get a linked list of the Variable: headers with order specified.
Definition: manager.c:2911
#define SIP_TRANS_TIMEOUT
Definition: sip.h:102
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 TR...
Definition: chan_sip.c:6317
#define SIP_OUTGOING
Definition: sip.h:257
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159
void sip_scheddestroy(struct sip_pvt *p, int ms)
Schedule destruction of SIP dialog.
Definition: chan_sip.c:4549
struct sip_notify * notify
Definition: sip.h:1140

◆ map_s_x()

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

References _map_x_s::s, and _map_x_s::x.

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

2427 {
2428  const struct _map_x_s *cur;
2429 
2430  for (cur = table; cur->s; cur++) {
2431  if (!strcasecmp(cur->s, s)) {
2432  return cur->x;
2433  }
2434  }
2435  return errorvalue;
2436 }
int x
Definition: sip.h:928
generic struct to map between strings and integers. Fill it with x-s pairs, terminate with an entry w...
Definition: sip.h:927
const char * s
Definition: sip.h:929

◆ map_x_s()

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

References _map_x_s::s, and _map_x_s::x.

Referenced by allowoverlap2str(), autocreatepeer2str(), dtmfmode2str(), faxec2str(), insecure2str(), referstatus2str(), regstate2str(), stmode2str(), strefresher2str(), strefresherparam2str(), and trust_id_outbound2str().

2412 {
2413  const struct _map_x_s *cur;
2414 
2415  for (cur = table; cur->s; cur++) {
2416  if (cur->x == x) {
2417  return cur->s;
2418  }
2419  }
2420  return errorstring;
2421 }
int x
Definition: sip.h:928
generic struct to map between strings and integers. Fill it with x-s pairs, terminate with an entry w...
Definition: sip.h:927
const char * s
Definition: sip.h:929

◆ mark_method_allowed()

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

Definition at line 9795 of file chan_sip.c.

References method.

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

9796 {
9797  (*allowed_methods) |= (1 << method);
9798 }
const char * method
Definition: res_pjsip.c:4335

◆ mark_method_unallowed()

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

Definition at line 9800 of file chan_sip.c.

References method.

Referenced by handle_response(), handle_response_info(), handle_response_message(), and handle_response_publish().

9801 {
9802  (*allowed_methods) &= ~(1 << method);
9803 }
const char * method
Definition: res_pjsip.c:4335

◆ mark_parsed_methods()

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

Definition at line 9811 of file chan_sip.c.

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

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

9812 {
9813  char *method;
9814  for (method = strsep(&methods_str, ","); !ast_strlen_zero(method); method = strsep(&methods_str, ",")) {
9815  int id = find_sip_method(ast_skip_blanks(method));
9816  if (id == SIP_UNKNOWN) {
9817  continue;
9818  }
9820  }
9821 }
static struct @481 methods[]
#define ast_strlen_zero(foo)
Definition: strings.h:52
const char * method
Definition: res_pjsip.c:4335
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
static int find_sip_method(const char *msg)
find_sip_method: Find SIP method from header
Definition: chan_sip.c:3594
char * strsep(char **str, const char *delims)
static void mark_method_allowed(unsigned int *allowed_methods, enum sipmethod method)
Definition: chan_sip.c:9795

◆ match_and_cleanup_peer_sched()

static int match_and_cleanup_peer_sched ( void *  peerobj,
void *  arg,
int  flags 
)
static

Definition at line 3232 of file chan_sip.c.

References ast_dnsmgr_release(), CMP_MATCH, sip_peer::dnsmgr, NULL, peer_sched_cleanup(), SIP_PEERS_ALL, sip_unref_peer, and sip_peer::the_mark.

Referenced by unlink_peers_from_tables().

3233 {
3234  struct sip_peer *peer = peerobj;
3235  peer_unlink_flag_t which = *(peer_unlink_flag_t *)arg;
3236 
3237  if (which == SIP_PEERS_ALL || peer->the_mark) {
3238  peer_sched_cleanup(peer);
3239  if (peer->dnsmgr) {
3240  ast_dnsmgr_release(peer->dnsmgr);
3241  peer->dnsmgr = NULL;
3242  sip_unref_peer(peer, "Release peer from dnsmgr");
3243  }
3244  return CMP_MATCH;
3245  }
3246  return 0;
3247 }
struct ast_dnsmgr_entry * dnsmgr
Definition: sip.h:1351
#define NULL
Definition: resample.c:96
peer_unlink_flag_t
Definition: chan_sip.c:3225
void ast_dnsmgr_release(struct ast_dnsmgr_entry *entry)
Free a DNS manager entry.
Definition: dnsmgr.c:136
unsigned short the_mark
Definition: sip.h:1316
static void peer_sched_cleanup(struct sip_peer *peer)
Definition: chan_sip.c:3209
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273

◆ match_req_to_dialog()

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

Definition at line 9177 of file chan_sip.c.

References ast_strlen_zero, ast_test_flag, match_req_args::authentication_present, sip_pvt::callid, match_req_args::callid, sip_pvt::flags, match_req_args::fromtag, sip_request::headers, sip_pvt::init_icseq, sip_pvt::initreq, sip_pvt::initviabranch, sip_pvt::initviasentby, sip_pvt::invite_branch, sip_pvt::method, match_req_args::method, NULL, REQ_OFFSET_TO_STR, match_req_args::respid, match_req_args::ruri, match_req_args::seqno, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_REQ_FORKED, SIP_REQ_LOOP_DETECTED, SIP_REQ_MATCH, SIP_REQ_NOT_MATCH, SIP_RESPONSE, sip_uri_cmp(), sip_pvt::tag, sip_pvt::theirtag, match_req_args::totag, match_req_args::viabranch, and match_req_args::viasentby.

Referenced by __find_call().

9178 {
9179  const char *init_ruri = NULL;
9180  if (sip_pvt_ptr->initreq.headers) {
9181  init_ruri = REQ_OFFSET_TO_STR(&sip_pvt_ptr->initreq, rlpart2);
9182  }
9183 
9184  /*
9185  * Match Tags and call-id to Dialog
9186  */
9187  if (!ast_strlen_zero(arg->callid) && strcmp(sip_pvt_ptr->callid, arg->callid)) {
9188  /* call-id does not match. */
9189  return SIP_REQ_NOT_MATCH;
9190  }
9191  if (arg->method == SIP_RESPONSE) {
9192  /* Verify fromtag of response matches the tag we gave them. */
9193  if (strcmp(arg->fromtag, sip_pvt_ptr->tag)) {
9194  /* fromtag from response does not match our tag */
9195  return SIP_REQ_NOT_MATCH;
9196  }
9197 
9198  /* Verify totag if we have one stored for this dialog, but never be strict about this for
9199  * a response until the dialog is established */
9200  if (!ast_strlen_zero(sip_pvt_ptr->theirtag) && ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) {
9201  if (ast_strlen_zero(arg->totag)) {
9202  /* missing totag when they already gave us one earlier */
9203  return SIP_REQ_NOT_MATCH;
9204  }
9205  /* compare the totag of response with the tag we have stored for them */
9206  if (strcmp(arg->totag, sip_pvt_ptr->theirtag)) {
9207  /* totag did not match what we had stored for them. */
9208  char invite_branch[32] = { 0, };
9209  if (sip_pvt_ptr->invite_branch) {
9210  snprintf(invite_branch, sizeof(invite_branch), "z9hG4bK%08x", (unsigned)sip_pvt_ptr->invite_branch);
9211  }
9212  /* Forked Request Detection
9213  *
9214  * If this is a 200ok response and the totags do not match, this
9215  * might be a forked response to an outgoing Request. Detection of
9216  * a forked response must meet the criteria below.
9217  *
9218  * 1. must be a 2xx Response
9219  * 2. call-d equal to call-id of Request. this is done earlier
9220  * 3. from-tag equal to from-tag of Request. this is done earlier
9221  * 4. branch parameter equal to branch of inital Request
9222  * 5. to-tag _NOT_ equal to previous 2xx response that already established the dialog.
9223  */
9224  if ((arg->respid == 200) &&
9225  !ast_strlen_zero(invite_branch) &&
9226  !ast_strlen_zero(arg->viabranch) &&
9227  !strcmp(invite_branch, arg->viabranch)) {
9228  return SIP_REQ_FORKED;
9229  }
9230 
9231  /* The totag did not match the one we had stored, and this is not a Forked Request. */
9232  return SIP_REQ_NOT_MATCH;
9233  }
9234  }
9235  } else {
9236  /* Verify the fromtag of Request matches the tag they provided earlier.
9237  * If this is a Request with authentication credentials, forget their old
9238  * tag as it is not valid after the 401 or 407 response. */
9239  if (!arg->authentication_present && strcmp(arg->fromtag, sip_pvt_ptr->theirtag)) {
9240  /* their tag does not match the one was have stored for them */
9241  return SIP_REQ_NOT_MATCH;
9242  }
9243  /* Verify if totag is present in Request, that it matches what we gave them as our tag earlier */
9244  if (!ast_strlen_zero(arg->totag) && (strcmp(arg->totag, sip_pvt_ptr->tag))) {
9245  /* totag from Request does not match our tag */
9246  return SIP_REQ_NOT_MATCH;
9247  }
9248  }
9249 
9250  /*
9251  * Compare incoming request against initial transaction.
9252  *
9253  * This is a best effort attempt at distinguishing forked requests from
9254  * our initial transaction. If all the elements are NOT in place to evaluate
9255  * this, this block is ignored and the dialog match is made regardless.
9256  * Once the totag is established after the dialog is confirmed, this is not necessary.
9257  *
9258  * CRITERIA required for initial transaction matching.
9259  *
9260  * 1. Is a Request
9261  * 2. Callid and theirtag match (this is done in the dialog matching block)
9262  * 3. totag is NOT present
9263  * 4. CSeq matchs our initial transaction's cseq number
9264  * 5. pvt has init via branch parameter stored
9265  */
9266  if ((arg->method != SIP_RESPONSE) && /* must be a Request */
9267  ast_strlen_zero(arg->totag) && /* must not have a totag */
9268  (sip_pvt_ptr->init_icseq == arg->seqno) && /* the cseq must be the same as this dialogs initial cseq */
9269  !ast_strlen_zero(sip_pvt_ptr->initviabranch) && /* The dialog must have started with a RFC3261 compliant branch tag */
9270  init_ruri) { /* the dialog must have an initial request uri associated with it */
9271  /* This Request matches all the criteria required for Loop/Merge detection.
9272  * Now we must go down the path of comparing VIA's and RURIs. */
9273  if (ast_strlen_zero(arg->viabranch) ||
9274  strcmp(arg->viabranch, sip_pvt_ptr->initviabranch) ||
9275  ast_strlen_zero(arg->viasentby) ||
9276  strcmp(arg->viasentby, sip_pvt_ptr->initviasentby)) {
9277  /* At this point, this request does not match this Dialog.*/
9278 
9279  /* if methods are different this is just a mismatch */
9280  if ((sip_pvt_ptr->method != arg->method)) {
9281  return SIP_REQ_NOT_MATCH;
9282  }
9283 
9284  /* If RUIs are different, this is a forked request to a separate URI.
9285  * Returning a mismatch allows this Request to be processed separately. */
9286  if (sip_uri_cmp(init_ruri, arg->ruri)) {
9287  /* not a match, request uris are different */
9288  return SIP_REQ_NOT_MATCH;
9289  }
9290 
9291  /* Loop/Merge Detected
9292  *
9293  * ---Current Matches to Initial Request---
9294  * request uri
9295  * Call-id
9296  * their-tag
9297  * no totag present
9298  * method
9299  * cseq
9300  *
9301  * --- Does not Match Initial Request ---
9302  * Top Via
9303  *
9304  * Without the same Via, this can not match our initial transaction for this dialog,
9305  * but given that this Request matches everything else associated with that initial
9306  * Request this is most certainly a Forked request in which we have already received
9307  * part of the fork.
9308  */
9309  return SIP_REQ_LOOP_DETECTED;
9310  }
9311  } /* end of Request Via check */
9312 
9313  /* Match Authentication Request.
9314  *
9315  * A Request with an Authentication header must come back with the
9316  * same Request URI. Otherwise it is not a match.
9317  */
9318  if ((arg->method != SIP_RESPONSE) && /* Must be a Request type to even begin checking this */
9319  ast_strlen_zero(arg->totag) && /* no totag is present to match */
9320  arg->authentication_present && /* Authentication header is present in Request */
9321  sip_uri_cmp(init_ruri, arg->ruri)) { /* Compare the Request URI of both the last Request and this new one */
9322 
9323  /* Authentication was provided, but the Request URI did not match the last one on this dialog. */
9324  return SIP_REQ_NOT_MATCH;
9325  }
9326 
9327  return SIP_REQ_MATCH;
9328 }
uint32_t init_icseq
Definition: sip.h:1069
const char * viabranch
Definition: chan_sip.c:9158
const char * ruri
Definition: chan_sip.c:9157
#define ast_test_flag(p, flag)
Definition: utils.h:63
const char * viasentby
Definition: chan_sip.c:9159
struct ast_flags flags[3]
Definition: sip.h:1075
int sip_uri_cmp(const char *input1, const char *input2)
Compare two URIs as described in RFC 3261 Section 19.1.4.
#define NULL
Definition: resample.c:96
const char * fromtag
Definition: chan_sip.c:9150
#define ast_strlen_zero(foo)
Definition: strings.h:52
int authentication_present
Definition: chan_sip.c:9162
struct sip_request initreq
Definition: sip.h:1151
const char * totag
Definition: chan_sip.c:9149
const ast_string_field theirtag
Definition: sip.h:1063
const ast_string_field callid
Definition: sip.h:1063
const ast_string_field initviasentby
Definition: sip.h:1063
int method
Definition: sip.h:1009
int headers
Definition: sip.h:832
#define REQ_OFFSET_TO_STR(req, offset)
Definition: sip.h:858
const ast_string_field initviabranch
Definition: sip.h:1063
uint32_t seqno
Definition: chan_sip.c:9151
const char * callid
Definition: chan_sip.c:9148
const ast_string_field tag
Definition: sip.h:1063
#define SIP_PAGE2_DIALOG_ESTABLISHED
Definition: sip.h:358
long invite_branch
Definition: sip.h:1122

◆ method_match()

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

References len(), sip_methods, and text.

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

3585 {
3586  int len = strlen(sip_methods[id].text);
3587  int l_name = name ? strlen(name) : 0;
3588  /* true if the string is long enough, and ends with whitespace, and matches */
3589  return (l_name >= len && name && name[len] < 33 &&
3590  !strncasecmp(sip_methods[id].text, name, len));
3591 }
static const struct cfsip_methods sip_methods[]
char * text
Definition: app_queue.c:1508
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static const char name[]
Definition: cdr_mysql.c:74

◆ mock_tcp_loop()

static int mock_tcp_loop ( char *  fragments[],
size_t  num_fragments,
struct ast_str **  overflow,
char **  messages,
int *  num_messages,
struct ast_test test 
)
static

Imitation TCP reception loop.

This imitates the logic used by SIP's TCP code. Its purpose is to either 1) Combine fragments into a single message 2) Break up combined messages into single messages

Parameters
fragmentsThe message fragments. This simulates the data received on a TCP socket.
num_fragmentsThis indicates the number of fragments to receive
overflowThis is a place to stash extra data if more than one message is received in a single fragment
[out]messagesThe parsed messages are placed in this array
[out]num_messagesThe number of messages that were parsed
testUsed for printing messages
Return values
0Success
-1Failure

Definition at line 34932 of file chan_sip.c.

References ast_free, ast_str_append(), ast_str_buffer(), ast_str_create, ast_str_reset(), ast_str_strlen(), ast_test_status_update, check_message_integrity(), end, and MESSAGE_FRAGMENT.

Referenced by AST_TEST_DEFINE().

34934 {
34935  struct ast_str *req_data;
34936  int i = 0;
34937  int res = 0;
34938 
34939  req_data = ast_str_create(128);
34940  ast_str_reset(*overflow);
34941 
34942  while (i < num_fragments || ast_str_strlen(*overflow) > 0) {
34944  ast_str_reset(req_data);
34945  while (message_integrity == MESSAGE_FRAGMENT) {
34946  if (ast_str_strlen(*overflow) > 0) {
34947  ast_str_append(&req_data, 0, "%s", ast_str_buffer(*overflow));
34948  ast_str_reset(*overflow);
34949  } else {
34950  ast_str_append(&req_data, 0, "%s", fragments[i++]);
34951  }
34952  message_integrity = check_message_integrity(&req_data, overflow);
34953  }
34954  if (strcmp(ast_str_buffer(req_data), messages[*num_messages])) {
34955  ast_test_status_update(test, "Mismatch in SIP messages.\n");
34956  ast_test_status_update(test, "Expected message:\n%s", messages[*num_messages]);
34957  ast_test_status_update(test, "Parsed message:\n%s", ast_str_buffer(req_data));
34958  res = -1;
34959  goto end;
34960  } else {
34961  ast_test_status_update(test, "Successfully read message:\n%s", ast_str_buffer(req_data));
34962  }
34963  (*num_messages)++;
34964  }
34965 
34966 end:
34967  ast_free(req_data);
34968  return res;
34969 };
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.
Definition: chan_sip.c:2849
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
char * end
Definition: eagi_proxy.c:73
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
#define ast_free(a)
Definition: astmm.h:182
message_integrity
Indication of a TCP message&#39;s integrity.
Definition: chan_sip.c:2761
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:653
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ mwi_event_cb()

static void mwi_event_cb ( void *  userdata,
struct stasis_subscription sub,
struct stasis_message msg 
)
static

Receive MWI events that we have subscribed to.

Definition at line 17528 of file chan_sip.c.

References ast_mwi_state_type(), peer_in_destruction, sip_send_mwi_to_peer(), stasis_message_type(), and stasis_subscription_final_message().

Referenced by add_peer_mwi_subs().

17529 {
17530  struct sip_peer *peer = userdata;
17531 
17532  /*
17533  * peer can't be NULL here but the peer can be in the process of being
17534  * destroyed. If it is, we don't want to send any messages. In most cases,
17535  * the peer is actually gone and there's no sense sending NOTIFYs that will
17536  * never be answered.
17537  */
17538  if (stasis_subscription_final_message(sub, msg) || peer_in_destruction(peer)) {
17539  return;
17540  }
17541 
17542  if (ast_mwi_state_type() == stasis_message_type(msg)) {
17543  sip_send_mwi_to_peer(peer, 0);
17544  }
17545 }
#define peer_in_destruction(peer)
Definition: chan_sip.c:1337
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
static int sip_send_mwi_to_peer(struct sip_peer *peer, int cache_only)
Send message waiting indication to alert peer that they&#39;ve got voicemail.
Definition: chan_sip.c:29756
int stasis_subscription_final_message(struct stasis_subscription *sub, struct stasis_message *msg)
Determine whether a message is the final message to be received on a subscription.
Definition: stasis.c:1176
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
struct stasis_message_type * ast_mwi_state_type(void)
Get the Stasis Message Bus API message type for MWI messages.

◆ network_change_sched_cb()

static int network_change_sched_cb ( const void *  data)
static

Definition at line 17579 of file chan_sip.c.

References network_change_sched_id, sip_send_all_mwi_subscriptions(), and sip_send_all_registers().

Referenced by network_change_stasis_cb().

17580 {
17584  return 0;
17585 }
static int network_change_sched_id
Definition: chan_sip.c:889
static void sip_send_all_mwi_subscriptions(void)
Send all MWI subscriptions.
Definition: chan_sip.c:34326
static void sip_send_all_registers(void)
Send all known registrations.
Definition: chan_sip.c:34298

◆ network_change_stasis_cb()

static void network_change_stasis_cb ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Definition at line 17587 of file chan_sip.c.

References ast_network_change_type(), ast_sched_add(), ast_verb, network_change_sched_cb(), network_change_sched_id, NULL, and stasis_message_type().

Referenced by network_change_stasis_subscribe().

17588 {
17589  /* This callback is only concerned with network change messages from the system topic. */
17590  if (stasis_message_type(message) != ast_network_change_type()) {
17591  return;
17592  }
17593 
17594  ast_verb(1, "SIP, got a network change message, renewing all SIP registrations.\n");
17595  if (network_change_sched_id == -1) {
17597  }
17598 }
struct stasis_message_type * ast_network_change_type(void)
A stasis_message_type for network changes.
Definition: sched.c:76
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:463
static int network_change_sched_id
Definition: chan_sip.c:889
static int network_change_sched_cb(const void *data)
Definition: chan_sip.c:17579
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565

◆ network_change_stasis_subscribe()

static void network_change_stasis_subscribe ( void  )
static

Definition at line 17547 of file chan_sip.c.

References ast_network_change_type(), ast_system_topic(), network_change_stasis_cb(), NULL, stasis_subscribe, stasis_subscription_accept_message_type(), STASIS_SUBSCRIPTION_FILTER_SELECTIVE, and stasis_subscription_set_filter().

Referenced by load_module(), and reload_config().

17548 {
17549  if (!network_change_sub) {
17554  }
17555 }
struct stasis_message_type * ast_network_change_type(void)
A stasis_message_type for network changes.
int stasis_subscription_set_filter(struct stasis_subscription *subscription, enum stasis_subscription_message_filter filter)
Set the message type filtering level on a subscription.
Definition: stasis.c:1079
#define NULL
Definition: resample.c:96
static struct stasis_subscription * network_change_sub
Definition: chan_sip.c:887
#define stasis_subscribe(topic, callback, data)
Definition: stasis.h:652
struct stasis_topic * ast_system_topic(void)
A Stasis Message Bus API topic which publishes messages regarding system changes. ...
int stasis_subscription_accept_message_type(struct stasis_subscription *subscription, const struct stasis_message_type *type)
Indicate to a subscription that we are interested in a message type.
Definition: stasis.c:1025
static void network_change_stasis_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: chan_sip.c:17587

◆ network_change_stasis_unsubscribe()

static void network_change_stasis_unsubscribe ( void  )
static

Definition at line 17557 of file chan_sip.c.

References stasis_unsubscribe_and_join().

Referenced by reload_config(), and unload_module().

17558 {
17560 }
static struct stasis_subscription * network_change_sub
Definition: chan_sip.c:887
struct stasis_subscription * stasis_unsubscribe_and_join(struct stasis_subscription *subscription)
Cancel a subscription, blocking until the last message is processed.
Definition: stasis.c:1136

◆ obproxy_get()

static struct sip_proxy* obproxy_get ( struct sip_pvt dialog,
struct sip_peer peer 
)
static

Get default outbound proxy or global proxy.

Definition at line 3549 of file chan_sip.c.

References append_history, ast_debug, sip_proxy::name, NULL, sip_pvt::options, sip_settings::outboundproxy, sip_invite_param::outboundproxy, sip_peer::outboundproxy, sip_cfg, and sipdebug.

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

3550 {
3551  if (dialog && dialog->options && dialog->options->outboundproxy) {
3552  if (sipdebug) {
3553  ast_debug(1, "OBPROXY: Applying dialplan set OBproxy to this call\n");
3554  }
3555  append_history(dialog, "OBproxy", "Using dialplan obproxy %s", dialog->options->outboundproxy->name);
3556  return dialog->options->outboundproxy;
3557  }
3558  if (peer && peer->outboundproxy) {
3559  if (sipdebug) {
3560  ast_debug(1, "OBPROXY: Applying peer OBproxy to this call\n");
3561  }
3562  append_history(dialog, "OBproxy", "Using peer obproxy %s", peer->outboundproxy->name);
3563  return peer->outboundproxy;
3564  }
3565  if (sip_cfg.outboundproxy.name[0]) {
3566  if (sipdebug) {
3567  ast_debug(1, "OBPROXY: Applying global OBproxy to this call\n");
3568  }
3569  append_history(dialog, "OBproxy", "Using global obproxy %s", sip_cfg.outboundproxy.name);
3570  return &sip_cfg.outboundproxy;
3571  }
3572  if (sipdebug) {
3573  ast_debug(1, "OBPROXY: Not applying OBproxy to this call\n");
3574  }
3575  return NULL;
3576 }
struct sip_proxy * outboundproxy
Definition: sip.h:870
#define NULL
Definition: resample.c:96
struct sip_proxy * outboundproxy
Definition: sip.h:1350
struct sip_invite_param * options
Definition: sip.h:1183
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
char name[MAXHOSTNAMELEN]
Definition: sip.h:722
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406
struct sip_proxy outboundproxy
Definition: sip.h:781

◆ offered_media_list_destroy()

static void offered_media_list_destroy ( struct sip_pvt p)
static

Destroy SDP media offer list.

Definition at line 6663 of file chan_sip.c.

References ast_free, AST_LIST_REMOVE_HEAD, offered_media::decline_m_line, and sip_pvt::offered_media.

Referenced by process_sdp(), sip_pvt_dtor(), transmit_invite(), and transmit_reinvite_with_sdp().

6664 {
6665  struct offered_media *offer;
6666  while ((offer = AST_LIST_REMOVE_HEAD(&p->offered_media, next))) {
6667  ast_free(offer->decline_m_line);
6668  ast_free(offer);
6669  }
6670 }
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
Structure for remembering offered media in an INVITE, to make sure we reply to all media streams...
Definition: sip.h:984
#define ast_free(a)
Definition: astmm.h:182
char * decline_m_line
Definition: sip.h:986
struct offered_media * next
Definition: sip.h:987
struct sip_pvt::@174 offered_media

◆ on_dns_update_mwi()

static void on_dns_update_mwi ( struct ast_sockaddr old,
struct ast_sockaddr new,
void *  data 
)
static

Definition at line 15058 of file chan_sip.c.

References ast_debug, ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_strdupa, sip_subscription_mwi::hostname, and sip_subscription_mwi::us.

Referenced by __sip_subscribe_mwi_do().

15059 {
15060  struct sip_subscription_mwi *mwi = data;
15061  const char *old_str;
15062 
15063  /* This shouldn't happen, but just in case */
15064  if (ast_sockaddr_isnull(new)) {
15065  ast_debug(1, "Empty sockaddr change...ignoring!\n");
15066  return;
15067  }
15068 
15069  old_str = ast_strdupa(ast_sockaddr_stringify(old));
15070  ast_debug(1, "Changing mwi %s from %s to %s\n", mwi->hostname, old_str, ast_sockaddr_stringify(new));
15071  ast_sockaddr_copy(&mwi->us, new);
15072 }
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:171
const ast_string_field hostname
Definition: sip.h:1461
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
struct ast_sockaddr us
Definition: sip.h:1468
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
Definition of an MWI subscription to another server.
Definition: sip.h:1454

◆ on_dns_update_peer()

static void on_dns_update_peer ( struct ast_sockaddr old,
struct ast_sockaddr new,
void *  data 
)
static

Definition at line 15029 of file chan_sip.c.

References sip_peer::addr, 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, default_sip_port(), sip_peer::name, sip_peer::socket, and sip_socket::type.

Referenced by build_peer(), and transmit_register().

15030 {
15031  struct sip_peer *peer = data;
15032  const char *old_str;
15033 
15034  /* This shouldn't happen, but just in case */
15035  if (ast_sockaddr_isnull(new)) {
15036  ast_debug(1, "Empty sockaddr change...ignoring!\n");
15037  return;
15038  }
15039 
15040  if (!ast_sockaddr_isnull(&peer->addr)) {
15041  ao2_unlink(peers_by_ip, peer);
15042  }
15043 
15044  if (!ast_sockaddr_port(new)) {
15046  }
15047 
15048  old_str = ast_strdupa(ast_sockaddr_stringify(old));
15049  ast_debug(1, "Changing peer %s address from %s to %s\n", peer->name, old_str, ast_sockaddr_stringify(new));
15050 
15051  ao2_lock(peer);
15052  ast_sockaddr_copy(&peer->addr, new);
15053  ao2_unlock(peer);
15054 
15055  ao2_link(peers_by_ip, peer);
15056 }
struct ast_sockaddr addr
Definition: sip.h:1352
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:171
#define ao2_unlock(a)
Definition: astobj2.h:730
char name[80]
Definition: sip.h:1274
static struct ao2_container * peers_by_ip
Definition: chan_sip.c:1053
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:521
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ao2_lock(a)
Definition: astobj2.h:718
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define ao2_unlink(container, obj)
Definition: astobj2.h:1598
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:537
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
enum ast_transport type
Definition: sip.h:798
static int default_sip_port(enum ast_transport type)
The default sip port for the given transport.
Definition: chan_sip.c:6309
struct sip_socket socket
Definition: sip.h:1307
#define ao2_link(container, obj)
Definition: astobj2.h:1549

◆ on_dns_update_registry()

static void on_dns_update_registry ( struct ast_sockaddr old,
struct ast_sockaddr new,
void *  data 
)
static

Definition at line 15008 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, sip_registry::hostname, sip_registry::peername, sip_registry::portno, S_OR, and sip_registry::us.

Referenced by transmit_register().

15009 {
15010  struct sip_registry *reg = data;
15011  const char *old_str;
15012 
15013  /* This shouldn't happen, but just in case */
15014  if (ast_sockaddr_isnull(new)) {
15015  ast_debug(1, "Empty sockaddr change...ignoring!\n");
15016  return;
15017  }
15018 
15019  if (!ast_sockaddr_port(new)) {
15020  ast_sockaddr_set_port(new, reg->portno);
15021  }
15022 
15023  old_str = ast_strdupa(ast_sockaddr_stringify(old));
15024 
15025  ast_debug(1, "Changing registry %s from %s to %s\n", S_OR(reg->peername, reg->hostname), old_str, ast_sockaddr_stringify(new));
15026  ast_sockaddr_copy(&reg->us, new);
15027 }
const ast_string_field hostname
Definition: sip.h:1414
int portno
Definition: sip.h:1416
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:171
Registrations with other SIP proxies.
Definition: sip.h:1396
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:521
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
struct ast_sockaddr us
Definition: sip.h:1430
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:537
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
const ast_string_field peername
Definition: sip.h:1414
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79

◆ parse_allowed_methods()

static unsigned int parse_allowed_methods ( struct sip_request req)
static

parse the Allow header to see what methods the endpoint we are communicating with allows.

We parse the allow header on incoming Registrations and save the result to the SIP peer that is registering. When the registration expires, we clear what we know about the peer's allowed methods. When the peer re-registers, we once again parse to see if the list of allowed methods has changed.

For peers that do not register, we parse the first message we receive during a call to see what is allowed, and save the information for the duration of the call.

Parameters
reqThe SIP request we are parsing
Return values
Themethods allowed

Definition at line 9838 of file chan_sip.c.

References ast_strdupa, ast_strip_quoted(), ast_strlen_zero, mark_parsed_methods(), methods, sip_get_header(), and SIP_UNKNOWN.

Referenced by set_pvt_allowed_methods().

9839 {
9840  char *allow = ast_strdupa(sip_get_header(req, "Allow"));
9841  unsigned int allowed_methods = SIP_UNKNOWN;
9842 
9843  if (ast_strlen_zero(allow)) {
9844  /* I have witnessed that REGISTER requests from Polycom phones do not
9845  * place the phone's allowed methods in an Allow header. Instead, they place the
9846  * allowed methods in a methods= parameter in the Contact header.
9847  */
9848  char *contact = ast_strdupa(sip_get_header(req, "Contact"));
9849  char *methods = strstr(contact, ";methods=");
9850 
9851  if (ast_strlen_zero(methods)) {
9852  /* RFC 3261 states:
9853  *
9854  * "The absence of an Allow header field MUST NOT be
9855  * interpreted to mean that the UA sending the message supports no
9856  * methods. Rather, it implies that the UA is not providing any
9857  * information on what methods it supports."
9858  *
9859  * For simplicity, we'll assume that the peer allows all known
9860  * SIP methods if they have no Allow header. We can then clear out the necessary
9861  * bits if the peer lets us know that we have sent an unsupported method.
9862  */
9863  return UINT_MAX;
9864  }
9865  allow = ast_strip_quoted(methods + 9, "\"", "\"");
9866  }
9867  mark_parsed_methods(&allowed_methods, allow);
9868  return allowed_methods;
9869 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
static struct @481 methods[]
#define ast_strlen_zero(foo)
Definition: strings.h:52
char * ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
Strip leading/trailing whitespace and quotes from a string.
Definition: main/utils.c:1639
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static void mark_parsed_methods(unsigned int *methods, char *methods_str)
Definition: chan_sip.c:9811

◆ parse_copy()

static void parse_copy ( struct sip_request dst,
const struct sip_request src 
)
static

Copy SIP request, parse it.

Definition at line 4656 of file chan_sip.c.

References copy_request(), and parse_request().

Referenced by send_request(), and send_response().

4657 {
4658  copy_request(dst, src);
4659  parse_request(dst);
4660 }
static void copy_request(struct sip_request *dst, const struct sip_request *src)
copy SIP request (mostly used to save request for responses)
Definition: chan_sip.c:14061
static int parse_request(struct sip_request *req)
Parse a SIP message.
Definition: chan_sip.c:9954

◆ parse_minse()

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

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

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

30287 {
30288  if (ast_strlen_zero(p_hdrval)) {
30289  ast_log(LOG_WARNING, "Null Min-SE header\n");
30290  return -1;
30291  }
30292 
30293  *p_interval = 0;
30294  p_hdrval = ast_skip_blanks(p_hdrval);
30295  if (!sscanf(p_hdrval, "%30d", p_interval)) {
30296  ast_log(LOG_WARNING, "Parsing of Min-SE header failed %s\n", p_hdrval);
30297  return -1;
30298  }
30299 
30300  ast_debug(2, "Received Min-SE: %d\n", *p_interval);
30301  return 0;
30302 }
#define LOG_WARNING
Definition: logger.h:274
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157

◆ parse_moved_contact()

static void parse_moved_contact ( struct sip_pvt p,
struct sip_request req,
char **  name,
char **  number,
int  set_call_forward 
)
static

Parse 302 Moved temporalily response.

Todo:
XXX Doesn't redirect over TLS on sips: uri's. If we get a redirect to a SIPS: uri, this needs to be going back to the dialplan (this is a request for a secure signalling path). Note that transport=tls is deprecated, but we need to support it on incoming requests.

Definition at line 23617 of file chan_sip.c.

References ao2_ref, ast_copy_string(), ast_debug, ast_log, ast_strdup, ast_strlen_zero, ast_test_flag, AST_TRANSPORT_TCP, AST_TRANSPORT_TLS, AST_TRANSPORT_UDP, ast_uri_decode(), ast_uri_sip_user, ast_websocket_unref(), find_closing_quote(), sip_pvt::flags, get_in_brackets(), host, LOG_NOTICE, NULL, sip_pvt::owner, pbx_builtin_setvar_helper(), remove_uri_parameters(), set_socket_transport(), sip_get_header(), sip_get_transport(), SIP_PROMISCREDIR, SIPBUFSIZE, sip_pvt::socket, strcasestr(), sip_socket::tcptls_session, and sip_socket::ws_session.

Referenced by change_redirecting_information().

23618 {
23619  char contact[SIPBUFSIZE];
23620  char *contact_name = NULL;
23621  char *contact_number = NULL;
23622  char *separator, *trans;
23623  char *domain;
23625 
23626  ast_copy_string(contact, sip_get_header(req, "Contact"), sizeof(contact));
23627  if ((separator = strchr(contact, ',')))
23628  *separator = '\0';
23629 
23630  contact_number = get_in_brackets(contact);
23631  if ((trans = strcasestr(contact_number, ";transport="))) {
23632  trans += 11;
23633 
23634  if ((separator = strchr(trans, ';')))
23635  *separator = '\0';
23636 
23637  if (!strncasecmp(trans, "tcp", 3))
23638  transport = AST_TRANSPORT_TCP;
23639  else if (!strncasecmp(trans, "tls", 3))
23640  transport = AST_TRANSPORT_TLS;
23641  else {
23642  if (strncasecmp(trans, "udp", 3))
23643  ast_debug(1, "received contact with an invalid transport, '%s'\n", contact_number);
23644  /* This will assume UDP for all unknown transports */
23645  transport = AST_TRANSPORT_UDP;
23646  }
23647  }
23648  contact_number = remove_uri_parameters(contact_number);
23649 
23650  if (p->socket.tcptls_session) {
23651  ao2_ref(p->socket.tcptls_session, -1);
23652  p->socket.tcptls_session = NULL;
23653  } else if (p->socket.ws_session) {
23655  p->socket.ws_session = NULL;
23656  }
23657 
23658  set_socket_transport(&p->socket, transport);
23659 
23660  if (set_call_forward && ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) {
23661  char *host = NULL;
23662  if (!strncasecmp(contact_number, "sip:", 4))
23663  contact_number += 4;
23664  else if (!strncasecmp(contact_number, "sips:", 5))
23665  contact_number += 5;
23666  separator = strchr(contact_number, '/');
23667  if (separator)
23668  *separator = '\0';
23669  if ((host = strchr(contact_number, '@'))) {
23670  *host++ = '\0';
23671  ast_debug(2, "Found promiscuous redirection to 'SIP/%s::::%s@%s'\n", contact_number, sip_get_transport(transport), host);
23672  if (p->owner)
23673  ast_channel_call_forward_build(p->owner, "SIP/%s::::%s@%s", contact_number, sip_get_transport(transport), host);
23674  } else {
23675  ast_debug(2, "Found promiscuous redirection to 'SIP/::::%s@%s'\n", sip_get_transport(transport), contact_number);
23676  if (p->owner)
23677  ast_channel_call_forward_build(p->owner, "SIP/::::%s@%s", sip_get_transport(transport), contact_number);
23678  }
23679  } else {
23680  separator = strchr(contact, '@');
23681  if (separator) {
23682  *separator++ = '\0';
23683  domain = separator;
23684  } else {
23685  /* No username part */
23686  domain = contact;
23687  }
23688  separator = strchr(contact, '/'); /* WHEN do we hae a forward slash in the URI? */
23689  if (separator)
23690  *separator = '\0';
23691 
23692  if (!strncasecmp(contact_number, "sip:", 4))
23693  contact_number += 4;
23694  else if (!strncasecmp(contact_number, "sips:", 5))
23695  contact_number += 5;
23696  separator = strchr(contact_number, ';'); /* And username ; parameters? */
23697  if (separator)
23698  *separator = '\0';
23699  ast_uri_decode(contact_number, ast_uri_sip_user);
23700  if (set_call_forward) {
23701  ast_debug(2, "Received 302 Redirect to extension '%s' (domain %s)\n", contact_number, domain);
23702  if (p->owner) {
23703  pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain);
23704  ast_channel_call_forward_set(p->owner, contact_number);
23705  }
23706  }
23707  }
23708 
23709  /* We've gotten the number for the contact, now get the name */
23710 
23711  if (*contact == '\"') {
23712  contact_name = contact + 1;
23713  if (!(separator = (char *)find_closing_quote(contact_name, NULL))) {
23714  ast_log(LOG_NOTICE, "No closing quote on name in Contact header? %s\n", contact);
23715  }
23716  *separator = '\0';
23717  }
23718 
23719  if (name && !ast_strlen_zero(contact_name)) {
23720  *name = ast_strdup(contact_name);
23721  }
23722  if (number) {
23723  *number = ast_strdup(contact_number);
23724  }
23725 }
void ast_uri_decode(char *s, struct ast_flags spec)
Decode URI, URN, URL (overwrite string)
Definition: main/utils.c:616
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
char * get_in_brackets(char *tmp)
Pick out text in brackets from character string.
#define ast_test_flag(p, flag)
Definition: utils.h:63
ast_transport
Definition: netsock2.h:59
struct sip_socket socket
Definition: sip.h:1066
const char * sip_get_transport(enum ast_transport t)
Return transport as string.
Definition: chan_sip.c:3725
struct ast_flags flags[3]
Definition: sip.h:1075
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
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...
Definition: chan_sip.c:5074
#define NULL
Definition: resample.c:96
Domain data structure.
Definition: sip.h:888
#define ast_strlen_zero(foo)
Definition: strings.h:52
Number structure.
Definition: app_followme.c:154
struct ast_websocket * ws_session
Definition: sip.h:802
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static char host[256]
Definition: muted.c:77
static char * remove_uri_parameters(char *uri)
Definition: chan_sip.c:14275
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_tcptls_session_instance * tcptls_session
Definition: sip.h:801
#define SIPBUFSIZE
Definition: sip.h:56
#define LOG_NOTICE
Definition: logger.h:263
char * strcasestr(const char *, const char *)
static const char name[]
Definition: cdr_mysql.c:74
struct ast_channel * owner
Definition: sip.h:1138
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
const struct ast_flags ast_uri_sip_user
Definition: main/utils.c:575
#define SIP_PROMISCREDIR
Definition: sip.h:269
static void set_socket_transport(struct sip_socket *socket, int transport)
Definition: chan_sip.c:16629
void AST_OPTIONAL_API_NAME() ast_websocket_unref(struct ast_websocket *session)
enum ast_transport transport
Definition: sip.h:1415

◆ parse_ok_contact()

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

References ast_copy_string(), ast_string_field_set, c, get_in_brackets(), sip_get_header(), SIPBUFSIZE, and TRUE.

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

16812 {
16813  char contact[SIPBUFSIZE];
16814  char *c;
16815 
16816  /* Look for brackets */
16817  ast_copy_string(contact, sip_get_header(req, "Contact"), sizeof(contact));
16818  c = get_in_brackets(contact);
16819 
16820  /* Save full contact to call pvt for later bye or re-invite */
16821  ast_string_field_set(pvt, fullcontact, c);
16822 
16823  /* Save URI for later ACKs, BYE or RE-invites */
16824  ast_string_field_set(pvt, okcontacturi, c);
16825 
16826  /* We should return false for URI:s we can't handle,
16827  like tel:, mailto:,ldap: etc */
16828  return TRUE;
16829 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
char * get_in_brackets(char *tmp)
Pick out text in brackets from character string.
static struct test_val c
#define SIPBUFSIZE
Definition: sip.h:56
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define TRUE
Definition: app_minivm.c:518
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ parse_oli()

static void parse_oli ( struct sip_request req,
struct ast_channel chan 
)
static

Check for the presence of OLI tag(s) in the From header and set on the channel.

Definition at line 27087 of file chan_sip.c.

References ast_party_caller::ani2, ast_channel_caller(), ast_strlen_zero, NULL, sip_get_header(), and strcasestr().

Referenced by handle_request_invite().

27088 {
27089  const char *from = NULL;
27090  const char *s = NULL;
27091  int ani2 = 0;
27092 
27093  if (!chan || !req) {
27094  /* null pointers are not helpful */
27095  return;
27096  }
27097 
27098  from = sip_get_header(req, "From");
27099  if (ast_strlen_zero(from)) {
27100  /* no From header */
27101  return;
27102  }
27103 
27104  /* Look for the possible OLI tags. */
27105  if ((s = strcasestr(from, ";isup-oli="))) {
27106  s += 10;
27107  } else if ((s = strcasestr(from, ";ss7-oli="))) {
27108  s += 9;
27109  } else if ((s = strcasestr(from, ";oli="))) {
27110  s += 5;
27111  }
27112 
27113  if (ast_strlen_zero(s)) {
27114  /* OLI tag is missing, or present with nothing following the '=' sign */
27115  return;
27116  }
27117 
27118  /* just in case OLI is quoted */
27119  if (*s == '\"') {
27120  s++;
27121  }
27122 
27123  if (sscanf(s, "%d", &ani2)) {
27124  ast_channel_caller(chan)->ani2 = ani2;
27125  }
27126 
27127  return;
27128 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
int ani2
Automatic Number Identification 2 (Info Digits)
Definition: channel.h:434
char * strcasestr(const char *, const char *)

◆ parse_register_contact()

static enum parse_register_result parse_register_contact ( struct sip_pvt pvt,
struct sip_peer p,
struct sip_request req 
)
static

Parse contact header and save registration (peer registration)

Todo:
Check NAPTR/SRV if we have not got a port in the URI

Definition at line 16961 of file chan_sip.c.

References __get_header(), sip_peer::addr, ao2_t_link, ao2_t_unlink, ast_apply_acl(), ast_copy_string(), ast_db_put(), ast_debug, ast_endpoint_blob_publish(), AST_ENDPOINT_ONLINE, ast_endpoint_set_state(), ast_endpoint_state_type(), ast_free, ast_json_pack(), ast_json_unref(), ast_log, ast_sched_add(), AST_SCHED_DEL_UNREF, ast_sched_when(), AST_SENSE_ALLOW, ast_set2_flag, 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_str_buffer(), ast_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero, ast_test_flag, AST_TRANSPORT_WS, AST_TRANSPORT_WSS, ast_verb, build_path(), sip_settings::contact_acl, sip_peer::contactacl, copy_socket_data(), default_expiry, default_sip_port(), sip_peer::endpoint, sip_peer::expire, expire_register(), sip_pvt::expiry, FALSE, sip_pvt::flags, sip_peer::flags, sip_peer::fullcontact, get_in_brackets(), get_transport_str2enum(), sip_peer::is_realtime, LOG_NOTICE, LOG_WARNING, max_expiry, min_expiry, sip_peer::name, NULL, PARSE_REGISTER_DENIED, PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, parse_uri_legacy_check(), sip_peer::path, sip_settings::peer_rtupdate, sip_peer::portinuri, RAII_VAR, sip_pvt::recv, register_peer_exten(), sip_peer::rt_fromcontact, set_socket_transport(), sip_cfg, sip_get_header(), SIP_NAT_FORCE_RPORT, SIP_NAT_RPORT_PRESENT, SIP_PAGE2_RTCACHEFRIENDS, sip_poke_peer(), sip_pvt_lock, sip_pvt_unlock, sip_ref_peer, sip_route_empty, sip_route_list(), sip_unref_peer, SIP_USEPATH, SIPBUFSIZE, sip_pvt::sipoptions, sip_peer::sipoptions, sip_request::socket, sip_pvt::socket, sip_peer::socket, strcasestr(), strsep(), sip_peer::transports, TRUE, sip_socket::type, sip_peer::useragent, and sip_peer::username.

Referenced by register_verify().

16962 {
16963  char contact[SIPBUFSIZE];
16964  char data[SIPBUFSIZE];
16965  const char *expires = sip_get_header(req, "Expires");
16966  int expire = atoi(expires);
16967  char *curi = NULL, *hostport = NULL, *transport = NULL;
16968  int transport_type;
16969  const char *useragent;
16970  struct ast_sockaddr oldsin, testsa;
16971  char *firstcuri = NULL;
16972  int start = 0;
16973  int wildcard_found = 0;
16974  int single_binding_found = 0;
16975 
16976  ast_copy_string(contact, __get_header(req, "Contact", &start), sizeof(contact));
16977 
16978  if (ast_strlen_zero(expires)) { /* No expires header, try look in Contact: */
16979  char *s = strcasestr(contact, ";expires=");
16980  if (s) {
16981  expires = strsep(&s, ";"); /* trim ; and beyond */
16982  if (sscanf(expires + 9, "%30d", &expire) != 1) {
16983  expire = default_expiry;
16984  }
16985  } else {
16986  /* Nothing has been specified */
16987  expire = default_expiry;
16988  }
16989  }
16990 
16991  if (expire > max_expiry) {
16992  expire = max_expiry;
16993  }
16994  if (expire < min_expiry && expire != 0) {
16995  expire = min_expiry;
16996  }
16997  pvt->expiry = expire;
16998 
16999  copy_socket_data(&pvt->socket, &req->socket);
17000 
17001  do {
17002  /* Look for brackets */
17003  curi = contact;
17004  if (strchr(contact, '<') == NULL) /* No <, check for ; and strip it */
17005  strsep(&curi, ";"); /* This is Header options, not URI options */
17006  curi = get_in_brackets(contact);
17007  if (!firstcuri) {
17008  firstcuri = ast_strdupa(curi);
17009  }
17010 
17011  if (!strcasecmp(curi, "*")) {
17012  wildcard_found = 1;
17013  } else {
17014  single_binding_found = 1;
17015  }
17016 
17017  if (wildcard_found && (ast_strlen_zero(expires) || expire != 0 || single_binding_found)) {
17018  /* Contact header parameter "*" detected, so punt if: Expires header is missing,
17019  * Expires value is not zero, or another Contact header is present. */
17020  return PARSE_REGISTER_FAILED;
17021  }
17022 
17023  ast_copy_string(contact, __get_header(req, "Contact", &start), sizeof(contact));
17024  } while (!ast_strlen_zero(contact));
17025  curi = firstcuri;
17026 
17027  /* if they did not specify Contact: or Expires:, they are querying
17028  what we currently have stored as their contact address, so return
17029  it
17030  */
17031  if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) {
17032  /* If we have an active registration, tell them when the registration is going to expire */
17033  if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact)) {
17034  pvt->expiry = ast_sched_when(sched, peer->expire);
17035  }
17036  return PARSE_REGISTER_QUERY;
17037  } else if (!strcasecmp(curi, "*") || !expire) { /* Unregister this peer */
17038  /* This means remove all registrations and return OK */
17039  AST_SCHED_DEL_UNREF(sched, peer->expire,
17040  sip_unref_peer(peer, "remove register expire ref"));
17041  ast_verb(3, "Unregistered SIP '%s'\n", peer->name);
17042  expire_register(sip_ref_peer(peer,"add ref for explicit expire_register"));
17043  return PARSE_REGISTER_UPDATE;
17044  }
17045 
17046  /* Store whatever we got as a contact from the client */
17047  ast_string_field_set(peer, fullcontact, curi);
17048 
17049  /* For the 200 OK, we should use the received contact */
17050  ast_string_field_build(pvt, our_contact, "<%s>", curi);
17051 
17052  /* Make sure it's a SIP URL */
17053  if (ast_strlen_zero(curi) || parse_uri_legacy_check(curi, "sip:,sips:", &curi, NULL, &hostport, &transport)) {
17054  ast_log(LOG_NOTICE, "Not a valid SIP contact (missing sip:/sips:) trying to use anyway\n");
17055  }
17056 
17057  /* handle the transport type specified in Contact header. */
17058  if (!(transport_type = get_transport_str2enum(transport))) {
17059  transport_type = pvt->socket.type;
17060  }
17061 
17062  /* if the peer's socket type is different than the Registration
17063  * transport type, change it. If it got this far, it is a
17064  * supported type, but check just in case */
17065  if ((peer->socket.type != transport_type) && (peer->transports & transport_type)) {
17066  set_socket_transport(&peer->socket, transport_type);
17067  }
17068 
17069  oldsin = peer->addr;
17070 
17071  /* If we were already linked into the peers_by_ip container unlink ourselves so nobody can find us */
17072  if (!ast_sockaddr_isnull(&peer->addr) && (!peer->is_realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS))) {
17073  ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table");
17074  }
17075 
17076  if ((transport_type != AST_TRANSPORT_WS) && (transport_type != AST_TRANSPORT_WSS) &&
17077  (!ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) && !ast_test_flag(&pvt->flags[0], SIP_NAT_RPORT_PRESENT))) {
17078  /* use the data provided in the Contact header for call routing */
17079  ast_debug(1, "Store REGISTER's Contact header for call routing.\n");
17080  /* XXX This could block for a long time XXX */
17081  /*! \todo Check NAPTR/SRV if we have not got a port in the URI */
17082  if (ast_sockaddr_resolve_first_transport(&testsa, hostport, 0, peer->socket.type)) {
17083  ast_log(LOG_WARNING, "Invalid hostport '%s'\n", hostport);
17084  ast_string_field_set(peer, fullcontact, "");
17085  ast_string_field_set(pvt, our_contact, "");
17086  return PARSE_REGISTER_FAILED;
17087  }
17088 
17089  /* If we have a port number in the given URI, make sure we do remember to not check for NAPTR/SRV records.
17090  The hostport part is actually a host. */
17091  peer->portinuri = ast_sockaddr_port(&testsa) ? TRUE : FALSE;
17092 
17093  if (!ast_sockaddr_port(&testsa)) {
17094  ast_sockaddr_set_port(&testsa, default_sip_port(transport_type));
17095  }
17096 
17097  ast_sockaddr_copy(&peer->addr, &testsa);
17098  } else {
17099  /* Don't trust the contact field. Just use what they came to us
17100  with */
17101  ast_debug(1, "Store REGISTER's src-IP:port for call routing.\n");
17102  peer->addr = pvt->recv;
17103  }
17104 
17105  /* Check that they're allowed to register at this IP */
17106  if (ast_apply_acl(sip_cfg.contact_acl, &peer->addr, "SIP contact ACL: ") != AST_SENSE_ALLOW ||
17107  ast_apply_acl(peer->contactacl, &peer->addr, "SIP contact ACL: ") != AST_SENSE_ALLOW) {
17108  ast_log(LOG_WARNING, "Domain '%s' disallowed by contact ACL (violating IP %s)\n", hostport,
17109  ast_sockaddr_stringify_addr(&peer->addr));
17110  ast_string_field_set(peer, fullcontact, "");
17111  ast_string_field_set(pvt, our_contact, "");
17112  return PARSE_REGISTER_DENIED;
17113  }
17114 
17115  /* if the Contact header information copied into peer->addr matches the
17116  * received address, and the transport types are the same, then copy socket
17117  * data into the peer struct */
17118  if ((peer->socket.type == pvt->socket.type) &&
17119  !ast_sockaddr_cmp(&peer->addr, &pvt->recv)) {
17120  copy_socket_data(&peer->socket, &pvt->socket);
17121  }
17122 
17123  /* Now that our address has been updated put ourselves back into the container for lookups */
17124  if (!peer->is_realtime || ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
17125  ao2_t_link(peers_by_ip, peer, "ao2_link into peers_by_ip table");
17126  }
17127 
17128  /* Save SIP options profile */
17129  peer->sipoptions = pvt->sipoptions;
17130 
17131  if (!ast_strlen_zero(curi) && ast_strlen_zero(peer->username)) {
17132  ast_string_field_set(peer, username, curi);
17133  }
17134 
17135  AST_SCHED_DEL_UNREF(sched, peer->expire,
17136  sip_unref_peer(peer, "remove register expire ref"));
17137 
17138  if (peer->is_realtime && !ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
17139  peer->expire = -1;
17140  } else {
17141  peer->expire = ast_sched_add(sched, (expire + 10) * 1000, expire_register,
17142  sip_ref_peer(peer, "add registration ref"));
17143  if (peer->expire == -1) {
17144  sip_unref_peer(peer, "remote registration ref");
17145  }
17146  }
17147  if (!build_path(pvt, peer, req, NULL)) {
17148  /* Tell the dialog to use the Path header in the response */
17149  ast_set2_flag(&pvt->flags[0], 1, SIP_USEPATH);
17150  }
17151  snprintf(data, sizeof(data), "%s:%d:%s:%s", ast_sockaddr_stringify(&peer->addr),
17152  expire, peer->username, peer->fullcontact);
17153  /* We might not immediately be able to reconnect via TCP, but try caching it anyhow */
17154  if (!peer->rt_fromcontact || !sip_cfg.peer_rtupdate) {
17155  if (!sip_route_empty(&peer->path)) {
17156  struct ast_str *r = sip_route_list(&peer->path, 0, 0);
17157  if (r) {
17158  ast_db_put("SIP/RegistryPath", peer->name, ast_str_buffer(r));
17159  ast_free(r);
17160  }
17161  }
17162  ast_db_put("SIP/Registry", peer->name, data);
17163  }
17164 
17165  if (peer->endpoint) {
17166  RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
17168  blob = ast_json_pack("{s: s, s: s}",
17169  "peer_status", "Registered",
17170  "address", ast_sockaddr_stringify(&peer->addr));
17171  ast_endpoint_blob_publish(peer->endpoint, ast_endpoint_state_type(), blob);
17172  }
17173 
17174  /* Is this a new IP address for us? */
17175  if (ast_sockaddr_cmp(&peer->addr, &oldsin)) {
17176  ast_verb(3, "Registered SIP '%s' at %s\n", peer->name,
17177  ast_sockaddr_stringify(&peer->addr));
17178  }
17179  sip_pvt_unlock(pvt);
17180  sip_poke_peer(peer, 0);
17181  sip_pvt_lock(pvt);
17182  register_peer_exten(peer, 1);
17183 
17184  /* Save User agent */
17185  useragent = sip_get_header(req, "User-Agent");
17186  if (strcasecmp(useragent, peer->useragent)) {
17187  ast_string_field_set(peer, useragent, useragent);
17188  ast_verb(4, "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name);
17189  }
17190  return PARSE_REGISTER_UPDATE;
17191 }
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:290
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
static int expire_register(const void *data)
Expire registration of SIP peer.
Definition: chan_sip.c:16646
#define FALSE
Definition: app_minivm.c:521
char * get_in_brackets(char *tmp)
Pick out text in brackets from character string.
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
static int max_expiry
Definition: chan_sip.c:668
int expire
Definition: sip.h:1418
#define SIP_USEPATH
Definition: sip.h:305
#define ast_set2_flag(p, value, flag)
Definition: utils.h:94
#define ast_test_flag(p, flag)
Definition: utils.h:63
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:171
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
#define LOG_WARNING
Definition: logger.h:274
static int build_path(struct sip_pvt *p, struct sip_peer *peer, struct sip_request *req, const char *pathbuf)
Build route list from Path header RFC 3327 requires that the Path header contains SIP URIs with lr pa...
Definition: chan_sip.c:17260
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
struct ast_sockaddr recv
Definition: sip.h:1135
struct sip_socket socket
Definition: sip.h:1066
Definition: sched.c:76
#define SIP_NAT_FORCE_RPORT
Definition: sip.h:283
#define ao2_t_link(container, obj, tag)
Add an object to a container.
Definition: astobj2.h:1547
#define AST_SCHED_DEL_UNREF(sched, id, refcall)
schedule task to get deleted and call unref function
Definition: sched.h:80
#define ao2_t_unlink(container, obj, tag)
Remove an object from a container.
Definition: astobj2.h:1596
void ast_endpoint_set_state(struct ast_endpoint *endpoint, enum ast_endpoint_state state)
Updates the state of the given endpoint.
struct ast_flags flags[3]
Definition: sip.h:1075
#define NULL
Definition: resample.c:96
int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares two ast_sockaddr structures.
Definition: netsock2.c:388
#define sip_ref_peer(peer, tag)
Definition: sip.h:1894
int peer_rtupdate
Definition: sip.h:750
Socket address structure.
Definition: netsock2.h:97
#define ast_verb(level,...)
Definition: logger.h:463
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
static struct ao2_container * peers_by_ip
Definition: chan_sip.c:1053
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
struct ast_str * sip_route_list(const struct sip_route *route, int formatcli, int skip)
Make the comma separated list of route hops.
Definition: route.c:155
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:521
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define sip_route_empty(route)
Check if route has no URI&#39;s.
Definition: route.h:118
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
int expiry
Definition: sip.h:1118
static void copy_socket_data(struct sip_socket *to_sock, const struct sip_socket *from_sock)
Definition: chan_sip.c:5952
enum ast_acl_sense ast_apply_acl(struct ast_acl_list *acl_list, const struct ast_sockaddr *addr, const char *purpose)
Apply a set of rules to a given IP address.
Definition: acl.c:800
static int default_expiry
Definition: chan_sip.c:669
static const char * __get_header(const struct sip_request *req, const char *name, int *start)
Definition: chan_sip.c:8562
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:537
#define SIPBUFSIZE
Definition: sip.h:56
struct stasis_message_type * ast_endpoint_state_type(void)
Message type for endpoint state changes.
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
static struct ast_flags global_flags[3]
Definition: chan_sip.c:884
static void register_peer_exten(struct sip_peer *peer, int onoff)
Automatically add peer extension to dial plan.
Definition: chan_sip.c:5238
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
#define LOG_NOTICE
Definition: logger.h:263
long ast_sched_when(struct ast_sched_context *con, int id)
Returns the number of seconds before an event takes place.
Definition: sched.c:814
#define SIP_NAT_RPORT_PRESENT
Definition: sip.h:284
#define SIP_PAGE2_RTCACHEFRIENDS
Definition: sip.h:323
char * strcasestr(const char *, const char *)
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
#define ast_free(a)
Definition: astmm.h:182
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
Definition: stringfields.h:550
static int get_transport_str2enum(const char *transport)
Return int representing a bit field of transport types found in const char *transport.
Definition: chan_sip.c:3658
void ast_endpoint_blob_publish(struct ast_endpoint *endpoint, struct stasis_message_type *type, struct ast_json *blob)
Creates and publishes a ast_endpoint_blob message.
char * strsep(char **str, const char *delims)
enum ast_transport type
Definition: sip.h:798
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define TRUE
Definition: app_minivm.c:518
static int sip_poke_peer(struct sip_peer *peer, int force)
Check availability of peer, also keep NAT open.
Definition: chan_sip.c:30583
Abstract JSON element (object, array, string, int, ...).
int ast_db_put(const char *family, const char *key, const char *value)
Store value addressed by family/key.
Definition: main/db.c:327
struct sip_socket socket
Definition: sip.h:846
static int default_sip_port(enum ast_transport type)
The default sip port for the given transport.
Definition: chan_sip.c:6309
struct ast_acl_list * contact_acl
Definition: sip.h:786
static void set_socket_transport(struct sip_socket *socket, int transport)
Definition: chan_sip.c:16629
enum ast_transport transport
Definition: sip.h:1415
unsigned int sipoptions
Definition: sip.h:1097
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. ...
Definition: chan_sip.c:34479
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
Definition: chan_sip.c:16880
static int min_expiry
Definition: chan_sip.c:667
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ parse_request()

static int parse_request ( struct sip_request req)
static

Parse a SIP message.

Note
this function is used both on incoming and outgoing packets

Definition at line 9954 of file chan_sip.c.

References ast_debug, ast_log, ast_str_buffer(), ast_str_strlen(), ast_strlen_zero, c, sip_request::data, determine_firstline_parts(), sip_request::header, sip_request::headers, sip_request::line, sip_request::lines, LOG_WARNING, SIP_MAX_HEADERS, SIP_MAX_LINES, and sipdebug.

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

9955 {
9956  char *c = ast_str_buffer(req->data);
9957  ptrdiff_t *dst = req->header;
9958  int i = 0;
9959  unsigned int lim = SIP_MAX_HEADERS - 1;
9960  unsigned int skipping_headers = 0;
9961  ptrdiff_t current_header_offset = 0;
9962  char *previous_header = "";
9963 
9964  req->header[0] = 0;
9965  req->headers = -1; /* mark that we are working on the header */
9966  for (; *c; c++) {
9967  if (*c == '\r') { /* remove \r */
9968  *c = '\0';
9969  } else if (*c == '\n') { /* end of this line */
9970  *c = '\0';
9971  current_header_offset = (c + 1) - ast_str_buffer(req->data);
9972  previous_header = ast_str_buffer(req->data) + dst[i];
9973  if (skipping_headers) {
9974  /* check to see if this line is blank; if so, turn off
9975  the skipping flag, so the next line will be processed
9976  as a body line */
9977  if (ast_strlen_zero(previous_header)) {
9978  skipping_headers = 0;
9979  }
9980  dst[i] = current_header_offset; /* record start of next line */
9981  continue;
9982  }
9983  if (sipdebug) {
9984  ast_debug(4, "%7s %2d [%3d]: %s\n",
9985  req->headers < 0 ? "Header" : "Body",
9986  i, (int) strlen(previous_header), previous_header);
9987  }
9988  if (ast_strlen_zero(previous_header) && req->headers < 0) {
9989  req->headers = i; /* record number of header lines */
9990  dst = req->line; /* start working on the body */
9991  i = 0;
9992  lim = SIP_MAX_LINES - 1;
9993  } else { /* move to next line, check for overflows */
9994  if (i++ == lim) {
9995  /* if we're processing headers, then skip any remaining
9996  headers and move on to processing the body, otherwise
9997  we're done */
9998  if (req->headers != -1) {
9999  break;
10000  } else {
10001  req->headers = i;
10002  dst = req->line;
10003  i = 0;
10004  lim = SIP_MAX_LINES - 1;
10005  skipping_headers = 1;
10006  }
10007  }
10008  }
10009  dst[i] = current_header_offset; /* record start of next line */
10010  }
10011  }
10012 
10013  /* Check for last header or body line without CRLF. The RFC for SDP requires CRLF,
10014  but since some devices send without, we'll be generous in what we accept. However,
10015  if we've already reached the maximum number of lines for portion of the message
10016  we were parsing, we can't accept any more, so just ignore it.
10017  */
10018  previous_header = ast_str_buffer(req->data) + dst[i];
10019  if ((i < lim) && !ast_strlen_zero(previous_header)) {
10020  if (sipdebug) {
10021  ast_debug(4, "%7s %2d [%3d]: %s\n",
10022  req->headers < 0 ? "Header" : "Body",
10023  i, (int) strlen(previous_header), previous_header );
10024  }
10025  i++;
10026  }
10027 
10028  /* update count of header or body lines */
10029  if (req->headers >= 0) { /* we are in the body */
10030  req->lines = i;
10031  } else { /* no body */
10032  req->headers = i;
10033  req->lines = 0;
10034  /* req->data->used will be a NULL byte */
10035  req->line[0] = ast_str_strlen(req->data);
10036  }
10037 
10038  if (*c) {
10039  ast_log(LOG_WARNING, "Too many lines, skipping <%s>\n", c);
10040  }
10041 
10042  /* Split up the first line parts */
10043  return determine_firstline_parts(req);
10044 }
#define SIP_MAX_HEADERS
Definition: sip.h:111
#define LOG_WARNING
Definition: logger.h:274
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
ptrdiff_t header[SIP_MAX_HEADERS]
Definition: sip.h:841
static struct test_val c
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
ptrdiff_t line[SIP_MAX_LINES]
Definition: sip.h:842
struct ast_str * data
Definition: sip.h:843
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
int headers
Definition: sip.h:832
static int determine_firstline_parts(struct sip_request *req)
Parse first line of incoming SIP request.
Definition: chan_sip.c:14157
#define SIP_MAX_LINES
Definition: sip.h:112
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
int lines
Definition: sip.h:834

◆ parse_session_expires()

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

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

Referenced by handle_request_invite_st(), and handle_response_invite().

30307 {
30308  char *p_token;
30309  int ref_idx;
30310  char *p_se_hdr;
30311 
30312  if (ast_strlen_zero(p_hdrval)) {
30313  ast_log(LOG_WARNING, "Null Session-Expires header\n");
30314  return -1;
30315  }
30316 
30318  *p_interval = 0;
30319 
30320  p_se_hdr = ast_strdupa(p_hdrval);
30321  p_se_hdr = ast_skip_blanks(p_se_hdr);
30322 
30323  while ((p_token = strsep(&p_se_hdr, ";"))) {
30324  p_token = ast_skip_blanks(p_token);
30325  if (!sscanf(p_token, "%30d", p_interval)) {
30326  ast_log(LOG_WARNING, "Parsing of Session-Expires failed\n");
30327  return -1;
30328  }
30329 
30330  ast_debug(2, "Session-Expires: %d\n", *p_interval);
30331 
30332  if (!p_se_hdr)
30333  continue;
30334 
30335  p_se_hdr = ast_skip_blanks(p_se_hdr);
30336  ref_idx = strlen("refresher=");
30337  if (!strncasecmp(p_se_hdr, "refresher=", ref_idx)) {
30338  p_se_hdr += ref_idx;
30339  p_se_hdr = ast_skip_blanks(p_se_hdr);
30340 
30341  if (!strncasecmp(p_se_hdr, "uac", strlen("uac"))) {
30343  ast_debug(2, "Refresher: UAC\n");
30344  } else if (!strncasecmp(p_se_hdr, "uas", strlen("uas"))) {
30346  ast_debug(2, "Refresher: UAS\n");
30347  } else {
30348  ast_log(LOG_WARNING, "Invalid refresher value %s\n", p_se_hdr);
30349  return -1;
30350  }
30351  break;
30352  }
30353  }
30354  return 0;
30355 }
#define LOG_WARNING
Definition: logger.h:274
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
char * strsep(char **str, const char *delims)

◆ parse_uri_legacy_check()

static int parse_uri_legacy_check ( char *  uri,
const char *  scheme,
char **  user,
char **  pass,
char **  hostport,
char **  transport 
)
static

parse uri in a way that allows semicolon stripping if legacy mode is enabled

Note
This calls parse_uri which has the unexpected property that passing more arguments results in more splitting. Most common is to leave out the pass argument, causing user to contain user:pass if available.

Definition at line 16880 of file chan_sip.c.

References sip_settings::legacy_useroption_parsing, 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().

16881 {
16882  int ret = parse_uri(uri, scheme, user, pass, hostport, transport);
16883  if (sip_cfg.legacy_useroption_parsing) { /* if legacy mode is active, strip semis from the user field */
16884  char *p;
16885  if ((p = strchr(uri, (int)';'))) {
16886  *p = '\0';
16887  }
16888  }
16889  return ret;
16890 }
static char pass[512]
int legacy_useroption_parsing
Definition: sip.h:767
int parse_uri(char *uri, const char *scheme, char **ret_name, char **pass, char **hostport, char **transport)
parses a URI in its components.
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
structure to hold users read from users.conf

◆ peer_cmp_cb()

static int peer_cmp_cb ( void *  obj,
void *  arg,
int  flags 
)
static
Note
The only member of the peer used here is the name field

Definition at line 34498 of file chan_sip.c.

References CMP_MATCH, CMP_STOP, and sip_peer::name.

Referenced by load_module().

34499 {
34500  struct sip_peer *peer = obj, *peer2 = arg;
34501 
34502  return !strcasecmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0;
34503 }
char name[80]
Definition: sip.h:1274
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273

◆ peer_dump_func()

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

Definition at line 20509 of file chan_sip.c.

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

Referenced by sip_show_objects().

20510 {
20511  struct sip_peer *peer = userobj;
20512  int refc = ao2_t_ref(userobj, 0, "");
20513  struct ast_cli_args *a = (struct ast_cli_args *) arg;
20514 
20515  ast_cli(a->fd, "name: %s\ntype: peer\nobjflags: %d\nrefcount: %d\n\n",
20516  peer->name, 0, refc);
20517  return 0;
20518 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
char name[80]
Definition: sip.h:1274
const int fd
Definition: cli.h:159
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
static struct test_val a

◆ peer_hash_cb()

static int peer_hash_cb ( const void *  obj,
const int  flags 
)
static
Note
The only member of the peer used here is the name field

Definition at line 34488 of file chan_sip.c.

References ast_str_case_hash(), and sip_peer::name.

Referenced by load_module().

34489 {
34490  const struct sip_peer *peer = obj;
34491 
34492  return ast_str_case_hash(peer->name);
34493 }
char name[80]
Definition: sip.h:1274
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
Definition: strings.h:1250

◆ peer_ipcmp_cb_full()

static int peer_ipcmp_cb_full ( void *  obj,
void *  arg,
void *  data,
int  flags 
)
static

Match Peers by IP and Port number.

This function has two modes.

  • If the peer arg does not have INSECURE_PORT set, then we will only return a match for a peer that matches both the IP and port.
  • If the peer arg does have the INSECURE_PORT flag set, then we will return a match for UDP peers with insecure=port set, or a peer that does NOT have host=dynamic for other protocols (or have a valid Contact: header in REGISTER). This callback will be used twice when doing peer matching, as per the two modes described above.
Note
the peer's addr struct provides to fields combined to make a key: the sin_addr.s_addr and sin_port fields (transport is compared separately).

Definition at line 34543 of file chan_sip.c.

References sip_peer::addr, ast_sockaddr_cmp_addr(), ast_sockaddr_port, ast_strlen_zero, ast_test_flag, AST_TRANSPORT_UDP, AST_TRANSPORT_WS, AST_TRANSPORT_WSS, sip_peer::callback, CMP_MATCH, CMP_STOP, sip_peer::flags, sip_peer::host_dynamic, SIP_INSECURE_PORT, SIP_NAT_FORCE_RPORT, and sip_peer::transports.

Referenced by sip_find_peer_full().

34544 {
34545  struct sip_peer *peer = obj, *peer2 = arg;
34546  char *callback = data;
34547 
34548  if (!ast_strlen_zero(callback) && strcasecmp(peer->callback, callback)) {
34549  /* We require a callback extension match, but don't have one */
34550  return 0;
34551  }
34552 
34553  /* At this point, we match the callback extension if we need to. Carry on. */
34554 
34555  if (ast_sockaddr_cmp_addr(&peer->addr, &peer2->addr)) {
34556  /* IP doesn't match */
34557  return 0;
34558  }
34559 
34560  if ((peer->transports & peer2->transports) == 0) {
34561  /* transport setting doesn't match */
34562  return 0;
34563  }
34564 
34565  if (!ast_test_flag(&peer2->flags[0], SIP_INSECURE_PORT)) {
34566  /* On the first pass only match if ports match. */
34567  return ast_sockaddr_port(&peer->addr) == ast_sockaddr_port(&peer2->addr) ?
34568  (CMP_MATCH | CMP_STOP) : 0;
34569  }
34570 
34571  /* We can reach here only if peer2 is for SIP_INSECURE_PORT, in
34572  * other words, the second pass where we only try to match against IP.
34573  *
34574  * Some special handling for UDP vs non-UDP (TCP, TLS, WS and WSS), since
34575  * for non-UDP the source port won't typically be controlled, we only want
34576  * to check the source IP, but only if the host isn't dynamic. This isn't
34577  * done in the first pass so that if a peer registers from the same IP as
34578  * a static IP peer that registration (port match) will take prescedence).
34579  */
34580  if (peer2->transports == AST_TRANSPORT_UDP) {
34581  /* We are allowing match without port for peers configured that
34582  * way in this pass through the peers. */
34583  return ast_test_flag(&peer->flags[0], SIP_INSECURE_PORT) ?
34584  (CMP_MATCH | CMP_STOP) : 0;
34585  }
34586 
34587  if (!peer->host_dynamic) {
34588  return CMP_MATCH | CMP_STOP;
34589  }
34590 
34591  /* Conditions taken from parse_register_contact() */
34592  if (peer2->transports & (AST_TRANSPORT_WS | AST_TRANSPORT_WSS)) {
34593  /* The contact address of websockets is always the transport source address and port */
34594  return 0;
34595  }
34596 
34597  if (ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT)) {
34598  /* The contact address of NATed peers is always the transport source address and port */
34599  return 0;
34600  }
34601 
34602  /* Have to assume that we used the registered contact header (non-NAT) */
34603  return CMP_MATCH | CMP_STOP;
34604 }
struct ast_sockaddr addr
Definition: sip.h:1352
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define SIP_NAT_FORCE_RPORT
Definition: sip.h:283
unsigned short host_dynamic
Definition: sip.h:1314
unsigned short transports
Definition: sip.h:1311
int ast_sockaddr_cmp_addr(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares the addresses of two ast_sockaddr structures.
Definition: netsock2.c:413
#define SIP_INSECURE_PORT
Definition: sip.h:296
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:521
const ast_string_field callback
Definition: sip.h:1306
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
struct ast_flags flags[3]
Definition: sip.h:1335

◆ peer_iphash_cb()

static int peer_iphash_cb ( const void *  obj,
const int  flags 
)
static

Hash function based on the peer's ip address. For IPv6, we use the end of the address.

Todo:
Find a better hashing function

Definition at line 34510 of file chan_sip.c.

References sip_peer::addr, ast_log, ast_sockaddr_hash(), ast_sockaddr_isnull(), and LOG_ERROR.

Referenced by load_module().

34511 {
34512  const struct sip_peer *peer = obj;
34513  int ret = 0;
34514 
34515  if (ast_sockaddr_isnull(&peer->addr)) {
34516  ast_log(LOG_ERROR, "Empty address\n");
34517  }
34518 
34519  ret = ast_sockaddr_hash(&peer->addr);
34520 
34521  if (ret < 0) {
34522  ret = -ret;
34523  }
34524 
34525  return ret;
34526 }
struct ast_sockaddr addr
Definition: sip.h:1352
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
#define ast_log
Definition: astobj2.c:42
int ast_sockaddr_hash(const struct ast_sockaddr *addr)
Computes a hash value from the address. The port is ignored.
Definition: netsock2.c:548
#define LOG_ERROR
Definition: logger.h:285
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273

◆ peer_mailboxes_to_str()

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

list peer mailboxes to CLI

Definition at line 21157 of file chan_sip.c.

References AST_LIST_NEXT, AST_LIST_TRAVERSE, ast_str_append(), sip_mailbox::id, mailbox, and sip_peer::mailboxes.

Referenced by _sip_show_peer(), function_sippeer(), show_channels_cb(), and sip_send_mwi_to_peer().

21158 {
21159  struct sip_mailbox *mailbox;
21160 
21161  AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
21162  ast_str_append(mailbox_str, 0, "%s%s",
21163  mailbox->id,
21164  AST_LIST_NEXT(mailbox, entry) ? "," : "");
21165  }
21166 }
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:438
A peer&#39;s mailbox.
Definition: sip.h:1261
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
char id[1]
Definition: sip.h:1267
static char mailbox[AST_MAX_MAILBOX_UNIQUEID]
Definition: chan_mgcp.c:204
struct sip_peer::@176 mailboxes
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
Definition: search.h:40

◆ peer_markall_autopeers_func()

static int peer_markall_autopeers_func ( void *  device,
void *  arg,
int  flags 
)
static

Definition at line 32424 of file chan_sip.c.

References sip_peer::selfdestruct, and sip_peer::the_mark.

Referenced by reload_config().

32425 {
32426  struct sip_peer *peer = device;
32427  if (peer->selfdestruct) {
32428  peer->the_mark = 1;
32429  }
32430  return 0;
32431 }
unsigned short the_mark
Definition: sip.h:1316
unsigned short selfdestruct
Definition: sip.h:1315
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273

◆ peer_markall_func()

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

Definition at line 32415 of file chan_sip.c.

References sip_peer::selfdestruct, and sip_peer::the_mark.

Referenced by reload_config().

32416 {
32417  struct sip_peer *peer = device;
32418  if (!peer->selfdestruct) {
32419  peer->the_mark = 1;
32420  }
32421  return 0;
32422 }
unsigned short the_mark
Definition: sip.h:1316
unsigned short selfdestruct
Definition: sip.h:1315
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273

◆ peer_sched_cleanup()

static void peer_sched_cleanup ( struct sip_peer peer)
static

Definition at line 3209 of file chan_sip.c.

References AST_SCHED_DEL_UNREF, sip_peer::expire, sip_peer::keepalivesend, sip_peer::pokeexpire, and sip_unref_peer.

Referenced by match_and_cleanup_peer_sched(), and set_peer_defaults().

3210 {
3211  if (peer->pokeexpire != -1) {
3213  sip_unref_peer(peer, "removing poke peer ref"));
3214  }
3215  if (peer->expire != -1) {
3217  sip_unref_peer(peer, "remove register expire ref"));
3218  }
3219  if (peer->keepalivesend != -1) {
3221  sip_unref_peer(peer, "remove keepalive peer ref"));
3222  }
3223 }
int keepalivesend
Definition: sip.h:1361
Definition: sched.c:76
#define AST_SCHED_DEL_UNREF(sched, id, refcall)
schedule task to get deleted and call unref function
Definition: sched.h:80
int expire
Definition: sip.h:1341
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
int pokeexpire
Definition: sip.h:1355

◆ peer_status()

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

Definition at line 20043 of file chan_sip.c.

References ast_copy_string(), sip_peer::lastms, and sip_peer::maxms.

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

20044 {
20045  int res = 0;
20046  if (peer->maxms) {
20047  if (peer->lastms < 0) {
20048  ast_copy_string(status, "UNREACHABLE", statuslen);
20049  } else if (peer->lastms > peer->maxms) {
20050  snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
20051  res = 1;
20052  } else if (peer->lastms) {
20053  snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
20054  res = 1;
20055  } else {
20056  ast_copy_string(status, "UNKNOWN", statuslen);
20057  }
20058  } else {
20059  ast_copy_string(status, "Unmonitored", statuslen);
20060  /* Checking if port is 0 */
20061  res = -1;
20062  }
20063  return res;
20064 }
int maxms
Definition: sip.h:1357
int lastms
Definition: sip.h:1356
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
jack_status_t status
Definition: app_jack.c:146

◆ peercomparefunc()

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

Definition at line 20272 of file chan_sip.c.

Referenced by sip_show_peers().

20273 {
20274  struct sip_peer **ap = (struct sip_peer **)a;
20275  struct sip_peer **bp = (struct sip_peer **)b;
20276  return strcmp((*ap)->name, (*bp)->name);
20277 }
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
static struct test_val b
static struct test_val a

◆ pidf_validate_presence()

static int pidf_validate_presence ( struct ast_xml_doc *  doc)
static

Definition at line 28084 of file chan_sip.c.

References ast_log, ast_strlen_zero, ast_xml_find_namespace(), ast_xml_free_attr(), ast_xml_get_attribute(), ast_xml_get_ns_href(), ast_xml_get_root(), ast_xml_node_get_children(), ast_xml_node_get_name(), ast_xml_node_get_next(), entity, FALSE, LOG_WARNING, NULL, pidf_validate_tuple(), and TRUE.

Referenced by sip_pidf_validate().

28085 {
28086  struct ast_xml_node *presence_node = ast_xml_get_root(doc);
28087  struct ast_xml_node *child_nodes;
28088  struct ast_xml_node *node_iterator;
28089  struct ast_xml_ns *ns;
28090  const char *entity;
28091  const char *namespace;
28092  const char presence_namespace[] = "urn:ietf:params:xml:ns:pidf";
28093 
28094  if (!presence_node) {
28095  ast_log(LOG_WARNING, "Unable to retrieve root node of the XML document\n");
28096  return FALSE;
28097  }
28098  /* Okay, we managed to open the document! YAY! Now, let's start making sure it's all PIDF-ified
28099  * correctly.
28100  */
28101  if (strcmp(ast_xml_node_get_name(presence_node), "presence")) {
28102  ast_log(LOG_WARNING, "Root node of PIDF document is not 'presence'. Invalid\n");
28103  return FALSE;
28104  }
28105 
28106  /* The presence element must have an entity attribute and an xmlns attribute. Furthermore
28107  * the xmlns attribute must be "urn:ietf:params:xml:ns:pidf"
28108  */
28109  if (!(entity = ast_xml_get_attribute(presence_node, "entity"))) {
28110  ast_log(LOG_WARNING, "Presence element of PIDF document has no 'entity' attribute\n");
28111  return FALSE;
28112  }
28113  /* We're not interested in what the entity is, just that it exists */
28114  ast_xml_free_attr(entity);
28115 
28116  if (!(ns = ast_xml_find_namespace(doc, presence_node, NULL))) {
28117  ast_log(LOG_WARNING, "Couldn't find default namespace...\n");
28118  return FALSE;
28119  }
28120 
28121  namespace = ast_xml_get_ns_href(ns);
28122  if (ast_strlen_zero(namespace) || strcmp(namespace, presence_namespace)) {
28123  ast_log(LOG_WARNING, "PIDF document has invalid namespace value %s\n", namespace);
28124  return FALSE;
28125  }
28126 
28127  if (!(child_nodes = ast_xml_node_get_children(presence_node))) {
28128  ast_log(LOG_WARNING, "PIDF document has no elements as children of 'presence'. Invalid\n");
28129  return FALSE;
28130  }
28131 
28132  /* Check for tuple elements. RFC 3863 says that PIDF documents can have any number of
28133  * tuples, including 0. The big thing here is that if there are tuple elements present,
28134  * they have to have a single status element within.
28135  *
28136  * The RFC is worded such that tuples should appear as the first elements as children of
28137  * the presence element. However, we'll be accepting of documents which may place other elements
28138  * before the tuple(s).
28139  */
28140  for (node_iterator = child_nodes; node_iterator;
28141  node_iterator = ast_xml_node_get_next(node_iterator)) {
28142  if (strcmp(ast_xml_node_get_name(node_iterator), "tuple")) {
28143  /* Not a tuple. We don't give a rat's hind quarters */
28144  continue;
28145  }
28146  if (pidf_validate_tuple(node_iterator) == FALSE) {
28147  ast_log(LOG_WARNING, "Unable to validate tuple\n");
28148  return FALSE;
28149  }
28150  }
28151 
28152  return TRUE;
28153 }
static int pidf_validate_tuple(struct ast_xml_node *tuple_node)
Definition: chan_sip.c:28044
#define FALSE
Definition: app_minivm.c:521
#define LOG_WARNING
Definition: logger.h:274
static int entity
Definition: isdn_lib.c:259
#define NULL
Definition: resample.c:96
struct ast_xml_node * ast_xml_get_root(struct ast_xml_doc *doc)
Get the document root node.
Definition: xml.c:199
#define ast_strlen_zero(foo)
Definition: strings.h:52
const char * ast_xml_get_attribute(struct ast_xml_node *node, const char *attrname)
Get a node attribute by name.
Definition: xml.c:236
void ast_xml_free_attr(const char *attribute)
Free an attribute returned by ast_xml_get_attribute()
Definition: xml.c:222
#define ast_log
Definition: astobj2.c:42
#define TRUE
Definition: app_minivm.c:518
struct ast_xml_ns * ast_xml_find_namespace(struct ast_xml_doc *doc, struct ast_xml_node *node, const char *ns_name)
Definition: xml.c:307
struct ast_xml_node * ast_xml_node_get_next(struct ast_xml_node *node)
Get the next node in the same level.
Definition: xml.c:350
struct ast_xml_node * ast_xml_node_get_children(struct ast_xml_node *node)
Get the node&#39;s children.
Definition: xml.c:345
const char * ast_xml_node_get_name(struct ast_xml_node *node)
Get the name of a node.
Definition: xml.c:340

◆ pidf_validate_tuple()

static int pidf_validate_tuple ( struct ast_xml_node *  tuple_node)
static

Definition at line 28044 of file chan_sip.c.

References ast_log, ast_xml_free_attr(), ast_xml_get_attribute(), ast_xml_node_get_children(), ast_xml_node_get_name(), ast_xml_node_get_next(), FALSE, id, LOG_WARNING, and TRUE.

Referenced by pidf_validate_presence().

28045 {
28046  const char *id;
28047  int status_found = FALSE;
28048  struct ast_xml_node *tuple_children;
28049  struct ast_xml_node *tuple_children_iterator;
28050  /* Tuples have to have an id attribute or they're invalid */
28051  if (!(id = ast_xml_get_attribute(tuple_node, "id"))) {
28052  ast_log(LOG_WARNING, "Tuple XML element has no attribute 'id'\n");
28053  return FALSE;
28054  }
28055  /* We don't care what it actually is, just that it's there */
28056  ast_xml_free_attr(id);
28057  /* This is a tuple. It must have a status element */
28058  if (!(tuple_children = ast_xml_node_get_children(tuple_node))) {
28059  /* The tuple has no children. It sucks */
28060  ast_log(LOG_WARNING, "Tuple XML element has no child elements\n");
28061  return FALSE;
28062  }
28063  for (tuple_children_iterator = tuple_children; tuple_children_iterator;
28064  tuple_children_iterator = ast_xml_node_get_next(tuple_children_iterator)) {
28065  /* Similar to the wording used regarding tuples, the status element should appear
28066  * first. However, we will once again relax things and accept the status at any
28067  * position. We will enforce that only a single status element can be present.
28068  */
28069  if (strcmp(ast_xml_node_get_name(tuple_children_iterator), "status")) {
28070  /* Not the status, we don't care */
28071  continue;
28072  }
28073  if (status_found == TRUE) {
28074  /* THERE CAN BE ONLY ONE!!! */
28075  ast_log(LOG_WARNING, "Multiple status elements found in tuple. Only one allowed\n");
28076  return FALSE;
28077  }
28078  status_found = TRUE;
28079  }
28080  return status_found;
28081 }
#define FALSE
Definition: app_minivm.c:521
#define LOG_WARNING
Definition: logger.h:274
const char * ast_xml_get_attribute(struct ast_xml_node *node, const char *attrname)
Get a node attribute by name.
Definition: xml.c:236
void ast_xml_free_attr(const char *attribute)
Free an attribute returned by ast_xml_get_attribute()
Definition: xml.c:222
#define ast_log
Definition: astobj2.c:42
#define TRUE
Definition: app_minivm.c:518
enum queue_result id
Definition: app_queue.c:1507
struct ast_xml_node * ast_xml_node_get_next(struct ast_xml_node *node)
Get the next node in the same level.
Definition: xml.c:350
struct ast_xml_node * ast_xml_node_get_children(struct ast_xml_node *node)
Get the node&#39;s children.
Definition: xml.c:345
const char * ast_xml_node_get_name(struct ast_xml_node *node)
Get the name of a node.
Definition: xml.c:340

◆ port_str2int()

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.

converts ascii port to int representation.

Definition at line 3538 of file chan_sip.c.

References ast_strlen_zero.

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

3539 {
3540  int port = standard;
3541  if (ast_strlen_zero(pt) || (sscanf(pt, "%30d", &port) != 1) || (port < 1) || (port > 65535)) {
3542  port = standard;
3543  }
3544 
3545  return port;
3546 }
#define ast_strlen_zero(foo)
Definition: strings.h:52

◆ print_group()

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

Print call group and pickup group.

Definition at line 20571 of file chan_sip.c.

References ast_cli(), ast_print_group(), and buf.

Referenced by _sip_show_peer(), and sip_show_user().

20572 {
20573  char buf[256];
20574  ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) );
20575 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
char * ast_print_group(char *buf, int buflen, ast_group_t group)
Print call and pickup groups into buffer.
Definition: channel.c:8133

◆ print_named_groups()

static void print_named_groups ( int  fd,
struct ast_namedgroups *  groups,
int  crlf 
)
static

Print named call groups and pickup groups.

Definition at line 20578 of file chan_sip.c.

References ast_cli(), ast_free, ast_print_namedgroups(), ast_str_create, and buf.

Referenced by _sip_show_peer(), and sip_show_user().

20579 {
20580  struct ast_str *buf = ast_str_create(1024);
20581  if (buf) {
20582  ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_namedgroups(&buf, group) );
20583  ast_free(buf);
20584  }
20585 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
#define ast_free(a)
Definition: astmm.h:182
char * ast_print_namedgroups(struct ast_str **buf, struct ast_namedgroups *groups)
Print named call groups and named pickup groups.
Definition: channel.c:8158
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ proc_422_rsp()

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

References ast_log, ast_strlen_zero, LOG_WARNING, NULL, parse_minse(), sip_get_header(), SIP_INVITE, sip_st_dlg::st_cached_min_se, sip_st_dlg::st_interval, sip_pvt::stimer, and transmit_invite().

Referenced by handle_response_invite().

30366 {
30367  int rtn;
30368  const char *p_hdrval;
30369  int minse;
30370 
30371  p_hdrval = sip_get_header(rsp, "Min-SE");
30372  if (ast_strlen_zero(p_hdrval)) {
30373  ast_log(LOG_WARNING, "422 response without a Min-SE header\n");
30374  return;
30375  }
30376  rtn = parse_minse(p_hdrval, &minse);
30377  if (rtn != 0) {
30378  ast_log(LOG_WARNING, "Parsing of Min-SE header failed %s\n", p_hdrval);
30379  return;
30380  }
30381  p->stimer->st_cached_min_se = minse;
30382  if (p->stimer->st_interval < minse) {
30383  p->stimer->st_interval = minse;
30384  }
30385  transmit_invite(p, SIP_INVITE, 1, 2, NULL);
30386 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
#define LOG_WARNING
Definition: logger.h:274
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.
Definition: chan_sip.c:14755
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
int st_interval
Definition: sip.h:961
#define ast_log
Definition: astobj2.c:42
struct sip_st_dlg * stimer
Definition: sip.h:1184
int st_cached_min_se
Definition: sip.h:965
static int parse_minse(const char *p_hdrval, int *const p_interval)
Session-Timers: Function for parsing Min-SE header.
Definition: chan_sip.c:30286

◆ proc_session_timer()

static int proc_session_timer ( const void *  vp)
static

Session-Timers: Process session refresh timeout event.

Note
Run by the sched thread.

Definition at line 30132 of file chan_sip.c.

References ast_assert, ast_channel_unlock, ast_channel_unref, ast_debug, ast_log, AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, sip_pvt::callid, dialog_unref, FALSE, LOG_WARNING, NULL, sip_pvt::owner, send_session_timeout(), SESSION_TIMER_REFRESHER_US, sip_pvt_lock_full(), sip_pvt_unlock, sip_st_dlg::st_active, sip_st_dlg::st_ref, sip_st_dlg::st_schedid, t38properties::state, sip_pvt::stimer, sip_pvt::t38, T38_ENABLED, transmit_reinvite_with_sdp(), and TRUE.

Referenced by __start_session_timer().

30133 {
30134  struct sip_pvt *p = (struct sip_pvt *) vp;
30135  struct sip_st_dlg *stimer = p->stimer;
30136  int res = 0;
30137 
30138  ast_assert(stimer != NULL);
30139 
30140  ast_debug(2, "Session timer expired: %d - %s\n", stimer->st_schedid, p->callid);
30141 
30142  if (!p->owner) {
30143  goto return_unref;
30144  }
30145 
30146  if ((stimer->st_active != TRUE) || (ast_channel_state(p->owner) != AST_STATE_UP)) {
30147  goto return_unref;
30148  }
30149 
30150  if (stimer->st_ref == SESSION_TIMER_REFRESHER_US) {
30151  res = 1;
30152  if (T38_ENABLED == p->t38.state) {
30154  } else {
30156  }
30157  } else {
30158  struct ast_channel *owner;
30159 
30160  ast_log(LOG_WARNING, "Session-Timer expired - %s\n", p->callid);
30161 
30162  owner = sip_pvt_lock_full(p);
30163  if (owner) {
30164  send_session_timeout(owner, "SIPSessionTimer");
30166  ast_channel_unlock(owner);
30167  ast_channel_unref(owner);
30168  }
30169  sip_pvt_unlock(p);
30170  }
30171 
30172 return_unref:
30173  if (!res) {
30174  /* Session timer processing is no longer needed. */
30175  ast_debug(2, "Session timer stopped: %d - %s\n",
30176  stimer->st_schedid, p->callid);
30177  /* Don't pass go, don't collect $200.. we are the scheduled
30178  * callback. We can rip ourself out here. */
30179  stimer->st_schedid = -1;
30180  stimer->st_active = FALSE;
30181 
30182  /* If we are not asking to be rescheduled, then we need to release our
30183  * reference to the dialog. */
30184  dialog_unref(p, "Session timer st_schedid complete");
30185  }
30186 
30187  return res;
30188 }
enum st_refresher st_ref
Definition: sip.h:962
#define T38_ENABLED
Definition: chan_ooh323.c:102
Main Channel structure associated with a channel.
#define FALSE
Definition: app_minivm.c:521
int st_schedid
Definition: sip.h:963
enum t38state state
Definition: sip.h:917
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
#define LOG_WARNING
Definition: logger.h:274
ast_channel_state
ast_channel states
Definition: channelstate.h:35
#define ast_assert(a)
Definition: utils.h:695
int st_active
Definition: sip.h:960
#define NULL
Definition: resample.c:96
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
struct t38properties t38
Definition: sip.h:1113
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static int transmit_reinvite_with_sdp(struct sip_pvt *p, int t38version, int oldsdp)
Transmit reinvite with SDP.
Definition: chan_sip.c:14212
const ast_string_field callid
Definition: sip.h:1063
static void send_session_timeout(struct ast_channel *chan, const char *source)
Sends a session timeout channel blob used to produce SessionTimeout AMI messages. ...
Definition: chan_sip.c:29879
struct sip_st_dlg * stimer
Definition: sip.h:1184
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
int ast_softhangup_nolock(struct ast_channel *chan, int reason)
Softly hangup up a channel (no channel lock)
Definition: channel.c:2463
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
static struct ast_channel * sip_pvt_lock_full(struct sip_pvt *pvt)
Definition: chan_sip.c:9400
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_channel * owner
Definition: sip.h:1138
#define TRUE
Definition: app_minivm.c:518
Structure that encapsulates all attributes related to running SIP Session-Timers feature on a per dia...
Definition: sip.h:959

◆ process_crypto()

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

Definition at line 34339 of file chan_sip.c.

References ast_debug, ast_log, ast_rtp_instance_get_dtls(), ast_sdp_crypto_alloc(), ast_sdp_crypto_process(), ast_sdp_srtp_alloc(), ast_test_flag, sip_pvt::dtls_cfg, ast_rtp_dtls_cfg::enabled, FALSE, sip_pvt::flags, LOG_WARNING, SIP_OUTGOING, ast_rtp_engine_dtls::stop, and TRUE.

Referenced by process_sdp().

34341 {
34342  struct ast_rtp_engine_dtls *dtls;
34343 
34344  /* If no RTP instance exists for this media stream don't bother processing the crypto line */
34345  if (!rtp) {
34346  ast_debug(3, "Received offer with crypto line for media stream that is not enabled\n");
34347  return FALSE;
34348  }
34349 
34350  if (strncasecmp(a, "crypto:", 7)) {
34351  return FALSE;
34352  }
34353  /* skip "crypto:" */
34354  a += strlen("crypto:");
34355 
34356  if (!*srtp) {
34357  if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
34358  ast_log(LOG_WARNING, "Ignoring unexpected crypto attribute in SDP answer\n");
34359  return FALSE;
34360  }
34361 
34362  if (!(*srtp = ast_sdp_srtp_alloc())) {
34363  return FALSE;
34364  }
34365  }
34366 
34367  if (!(*srtp)->crypto && !((*srtp)->crypto = ast_sdp_crypto_alloc())) {
34368  return FALSE;
34369  }
34370 
34371  if (ast_sdp_crypto_process(rtp, *srtp, a) < 0) {
34372  return FALSE;
34373  }
34374 
34375  if ((dtls = ast_rtp_instance_get_dtls(rtp))) {
34376  dtls->stop(rtp);
34377  p->dtls_cfg.enabled = 0;
34378  }
34379 
34380  return TRUE;
34381 }
#define FALSE
Definition: app_minivm.c:521
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define LOG_WARNING
Definition: logger.h:274
int ast_sdp_crypto_process(struct ast_rtp_instance *rtp, struct ast_sdp_srtp *srtp, const char *attr)
Parse the a=crypto line from SDP and set appropriate values on the ast_sdp_crypto struct...
Definition: sdp_srtp.c:79
void(* stop)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:576
struct ast_flags flags[3]
Definition: sip.h:1075
struct ast_rtp_dtls_cfg dtls_cfg
Definition: sip.h:1222
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
Structure that represents the optional DTLS SRTP support within an RTP engine.
Definition: rtp_engine.h:570
unsigned int enabled
Definition: rtp_engine.h:555
struct ast_rtp_engine_dtls * ast_rtp_instance_get_dtls(struct ast_rtp_instance *instance)
Obtain a pointer to the DTLS support present on an RTP instance.
Definition: rtp_engine.c:3011
struct ast_sdp_srtp * ast_sdp_srtp_alloc(void)
allocate a ast_sdp_srtp structure
Definition: sdp_srtp.c:41
struct ast_sdp_crypto * ast_sdp_crypto_alloc(void)
Initialize an return an ast_sdp_crypto struct.
Definition: sdp_srtp.c:71
#define TRUE
Definition: app_minivm.c:518
#define SIP_OUTGOING
Definition: sip.h:257
static struct test_val a

◆ process_sdp()

static int process_sdp ( struct sip_pvt p,
struct sip_request req,
int  t38action,
int  is_offer 
)
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 10253 of file chan_sip.c.

References ast_rtp_engine_dtls::active, ao2_cleanup, ao2_ref, ast_async_goto(), ast_calloc, ast_channel_caller(), ast_channel_context(), ast_channel_exten(), ast_channel_lock, ast_channel_macrocontext(), ast_channel_name(), ast_channel_nativeformats(), ast_channel_nativeformats_set(), ast_channel_readformat(), ast_channel_set_fd(), ast_channel_unlock, ast_channel_writeformat(), ast_clear_flag, ast_debug, ast_exists_extension(), ast_format_cap_alloc, ast_format_cap_append, ast_format_cap_append_from_cap(), ast_format_cap_count(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_get_compatible(), ast_format_cap_get_format(), ast_format_cap_get_format_framing(), ast_format_cap_get_names(), ast_format_cap_has_type(), ast_format_cap_iscompatible_format(), AST_FORMAT_CAP_NAMES_LEN, ast_format_cap_remove_by_type(), AST_FORMAT_CMP_NOT_EQUAL, ast_format_t140_red, AST_LIST_INSERT_TAIL, ast_log, AST_LOG_NOTICE, ast_malloc, AST_MEDIA_TYPE_AUDIO, AST_MEDIA_TYPE_TEXT, AST_MEDIA_TYPE_UNKNOWN, AST_MEDIA_TYPE_VIDEO, ast_null_frame, ast_queue_frame(), ast_queue_hold(), ast_queue_unhold(), ast_rtp_codecs_get_framing(), AST_RTP_CODECS_NULL_INIT, ast_rtp_codecs_payload_formats(), ast_rtp_codecs_payloads_copy(), ast_rtp_codecs_payloads_destroy(), ast_rtp_codecs_payloads_initialize(), ast_rtp_codecs_payloads_set_m_type(), ast_rtp_codecs_payloads_xover(), ast_rtp_codecs_set_framing(), AST_RTP_DTMF, ast_rtp_instance_get_codecs(), ast_rtp_instance_get_dtls(), ast_rtp_instance_get_remote_address, AST_RTP_INSTANCE_RTCP_DISABLED, 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_sdp_srtp_alloc(), ast_sdp_srtp_destroy(), 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_SRTP_CRYPTO_OFFER_OK, 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_verb, ast_verbose(), sip_pvt::callid, sip_pvt::caps, change_hold_state(), change_t38_state(), codecs, configure_rtcp(), debug, offered_media::decline_m_line, FALSE, sip_pvt::flags, get_sdp_iterate(), get_sdp_line(), has_media_level_attribute(), has_media_stream(), ast_party_caller::id, initialize_udptl(), sip_pvt::jointcaps, sip_pvt::jointnoncodeccapability, sip_pvt::lastinvite, sip_pvt::lastrtprx, sip_pvt::lastrtptx, len(), LOG_ERROR, LOG_NOTICE, LOG_WARNING, sip_request::method, sip_pvt::mohsuggest, sip_pvt::noncodeccapability, sip_pvt::notext, sip_pvt::novideo, NULL, ast_party_id::number, sip_pvt::offered_media, offered_media_list_destroy(), sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::peercaps, process_crypto(), process_sdp_a_audio(), process_sdp_a_dtls(), process_sdp_a_ice(), process_sdp_a_image(), process_sdp_a_rtcp_mux(), process_sdp_a_sendonly(), process_sdp_a_text(), process_sdp_a_video(), process_sdp_c(), process_sdp_o(), sip_pvt::red, sip_pvt::redirip, sip_pvt::rtp, S_COR, S_OR, SDP_AUDIO, SDP_IMAGE, sip_request::sdp_start, SDP_T38_ACCEPT, SDP_T38_INITIATE, SDP_TEXT, SDP_UNKNOWN, SDP_VIDEO, sip_pvt::session_modify, set_ice_components(), SIP_AUDIO_RTCP_FD, sip_debug_test_pvt(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_FAX_DETECT_T38, SIP_PAGE2_PREFERRED_CODEC, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_SYMMETRICRTP, SIP_PAGE2_UDPTL_DESTINATION, SIP_PAGE2_USE_SRTP, SIP_PAGE3_DISCARD_REMOTE_HOLD_RETRIEVAL, SIP_PAGE3_USE_AVPF, SIP_RESPONSE, SIP_VIDEO_RTCP_FD, SIPBUFSIZE, sockaddr_is_null_or_any(), sip_pvt::srtp, start_ice(), t38properties::state, ast_party_number::str, sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_LOCAL_REINVITE, T38_PEER_REINVITE, T38_REJECTED, text, t38properties::their_parms, sip_pvt::trtp, TRUE, sip_pvt::tsrtp, type, offered_media::type, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_NONE, ast_party_number::valid, value, sip_pvt::vrtp, and sip_pvt::vsrtp.

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

10254 {
10255  int res = 0;
10256 
10257  /* Iterators for SDP parsing */
10258  int start = req->sdp_start;
10259  int next = start;
10260  int iterator = start;
10261 
10262  /* Temporary vars for SDP parsing */
10263  char type = '\0';
10264  const char *value = NULL;
10265  const char *m = NULL; /* SDP media offer */
10266  const char *nextm = NULL;
10267  int len = -1;
10268  struct offered_media *offer;
10269 
10270  /* Host information */
10271  struct ast_sockaddr sessionsa;
10272  struct ast_sockaddr audiosa;
10273  struct ast_sockaddr videosa;
10274  struct ast_sockaddr textsa;
10275  struct ast_sockaddr imagesa;
10276  struct ast_sockaddr *sa = NULL; /*!< RTP audio destination IP address */
10277  struct ast_sockaddr *vsa = NULL; /*!< RTP video destination IP address */
10278  struct ast_sockaddr *tsa = NULL; /*!< RTP text destination IP address */
10279  struct ast_sockaddr *isa = NULL; /*!< UDPTL image destination IP address */
10280  int portno = -1; /*!< RTP audio destination port number */
10281  int vportno = -1; /*!< RTP video destination port number */
10282  int tportno = -1; /*!< RTP text destination port number */
10283  int udptlportno = -1; /*!< UDPTL image destination port number */
10284 
10285  /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */
10289 
10290  int peernoncodeccapability = 0, vpeernoncodeccapability = 0, tpeernoncodeccapability = 0;
10291 
10292  struct ast_rtp_codecs newaudiortp = AST_RTP_CODECS_NULL_INIT;
10293  struct ast_rtp_codecs newvideortp = AST_RTP_CODECS_NULL_INIT;
10294  struct ast_rtp_codecs newtextrtp = AST_RTP_CODECS_NULL_INIT;
10295  struct ast_format_cap *newjointcapability = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT); /* Negotiated capability */
10297  int newnoncodeccapability;
10298 
10299  const char *codecs;
10300  unsigned int codec;
10301 
10302  /* SRTP */
10303  int secure_audio = FALSE;
10304  int secure_video = FALSE;
10305 
10306  /* RTCP Multiplexing */
10307  int remote_rtcp_mux_audio = FALSE;
10308  int remote_rtcp_mux_video = FALSE;
10309 
10310  /* Others */
10311  int sendonly = -1;
10312  unsigned int numberofports;
10313  int last_rtpmap_codec = 0;
10314  int red_data_pt[10]; /* For T.140 RED */
10315  int red_num_gen = 0; /* For T.140 RED */
10316  char red_fmtp[100] = "empty"; /* For T.140 RED */
10317  int debug = sip_debug_test_pvt(p);
10318 
10319  /* START UNKNOWN */
10320  struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
10321  struct ast_format *tmp_fmt;
10322  /* END UNKNOWN */
10323 
10324  /* Initial check */
10325  if (!p->rtp) {
10326  ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n");
10327  res = -1;
10328  goto process_sdp_cleanup;
10329  }
10330  if (!peercapability || !vpeercapability || !tpeercapability || !newpeercapability || !newjointcapability) {
10331  res = -1;
10332  goto process_sdp_cleanup;
10333  }
10334 
10335  if (ast_rtp_codecs_payloads_initialize(&newaudiortp) || ast_rtp_codecs_payloads_initialize(&newvideortp) ||
10336  ast_rtp_codecs_payloads_initialize(&newtextrtp)) {
10337  res = -1;
10338  goto process_sdp_cleanup;
10339  }
10340 
10341  /* Update our last rtprx when we receive an SDP, too */
10342  p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */
10343 
10345 
10346  /* Scan for the first media stream (m=) line to limit scanning of globals */
10347  nextm = get_sdp_iterate(&next, req, "m");
10348  if (ast_strlen_zero(nextm)) {
10349  ast_log(LOG_WARNING, "Insufficient information for SDP (m= not found)\n");
10350  res = -1;
10351  goto process_sdp_cleanup;
10352  }
10353 
10354  /* Scan session level SDP parameters (lines before first media stream) */
10355  while ((type = get_sdp_line(&iterator, next - 1, req, &value)) != '\0') {
10356  int processed = FALSE;
10357  switch (type) {
10358  case 'o':
10359  /* If we end up receiving SDP that doesn't actually modify the session we don't want to treat this as a fatal
10360  * error. We just want to ignore the SDP and let the rest of the packet be handled as normal.
10361  */
10362  if (!process_sdp_o(value, p)) {
10363  res = (p->session_modify == FALSE) ? 0 : -1;
10364  goto process_sdp_cleanup;
10365  }
10366  processed = TRUE;
10367  break;
10368  case 'c':
10369  if (process_sdp_c(value, &sessionsa)) {
10370  processed = TRUE;
10371  sa = &sessionsa;
10372  vsa = sa;
10373  tsa = sa;
10374  isa = sa;
10375  }
10376  break;
10377  case 'a':
10378  if (process_sdp_a_sendonly(value, &sendonly)) {
10379  processed = TRUE;
10380  }
10381  else if (process_sdp_a_audio(value, p, &newaudiortp, &last_rtpmap_codec))
10382  processed = TRUE;
10383  else if (process_sdp_a_video(value, p, &newvideortp, &last_rtpmap_codec))
10384  processed = TRUE;
10385  else if (process_sdp_a_text(value, p, &newtextrtp, red_fmtp, &red_num_gen, red_data_pt, &last_rtpmap_codec))
10386  processed = TRUE;
10387  else if (process_sdp_a_image(value, p))
10388  processed = TRUE;
10389 
10390  if (process_sdp_a_ice(value, p, p->rtp, 0)) {
10391  processed = TRUE;
10392  }
10393  if (process_sdp_a_ice(value, p, p->vrtp, 0)) {
10394  processed = TRUE;
10395  }
10396  if (process_sdp_a_ice(value, p, p->trtp, 0)) {
10397  processed = TRUE;
10398  }
10399 
10400  if (process_sdp_a_dtls(value, p, p->rtp)) {
10401  processed = TRUE;
10402  if (p->srtp) {
10404  }
10405  }
10406  if (process_sdp_a_dtls(value, p, p->vrtp)) {
10407  processed = TRUE;
10408  if (p->vsrtp) {
10410  }
10411  }
10412  if (process_sdp_a_dtls(value, p, p->trtp)) {
10413  processed = TRUE;
10414  if (p->tsrtp) {
10416  }
10417  }
10418 
10419  break;
10420  }
10421 
10422  ast_debug(3, "Processing session-level SDP %c=%s... %s\n", type, value, (processed == TRUE)? "OK." : "UNSUPPORTED OR FAILED.");
10423  }
10424 
10425  /* default: novideo and notext set */
10426  p->novideo = TRUE;
10427  p->notext = TRUE;
10428 
10429  /* Scan media stream (m=) specific parameters loop */
10430  while (!ast_strlen_zero(nextm)) {
10431  int audio = FALSE;
10432  int video = FALSE;
10433  int image = FALSE;
10434  int text = FALSE;
10435  int processed_crypto = FALSE;
10436  int rtcp_mux_offered = 0;
10437  char protocol[18] = {0,};
10438  unsigned int x;
10439  struct ast_rtp_engine_dtls *dtls;
10440 
10441  numberofports = 0;
10442  len = -1;
10443  start = next;
10444  m = nextm;
10445  iterator = next;
10446  nextm = get_sdp_iterate(&next, req, "m");
10447 
10448  if (!(offer = ast_calloc(1, sizeof(*offer)))) {
10449  ast_log(LOG_WARNING, "Failed to allocate memory for SDP offer list\n");
10450  res = -1;
10451  goto process_sdp_cleanup;
10452  }
10453  AST_LIST_INSERT_TAIL(&p->offered_media, offer, next);
10454  offer->type = SDP_UNKNOWN;
10455 
10456  /* We need to check for this ahead of time */
10457  rtcp_mux_offered = has_media_level_attribute(iterator, req, "rtcp-mux");
10458 
10459  /* Check for 'audio' media offer */
10460  if (p->rtp && strncmp(m, "audio ", 6) == 0) {
10461  if ((sscanf(m, "audio %30u/%30u %17s %n", &x, &numberofports, protocol, &len) == 3 && len > 0) ||
10462  (sscanf(m, "audio %30u %17s %n", &x, protocol, &len) == 2 && len > 0)) {
10463  codecs = m + len;
10464  /* produce zero-port m-line since it may be needed later
10465  * length is "m=audio 0 " + protocol + " " + codecs + "\r\n\0" */
10466  if (!(offer->decline_m_line = ast_malloc(10 + strlen(protocol) + 1 + strlen(codecs) + 3))) {
10467  ast_log(LOG_WARNING, "Failed to allocate memory for SDP offer declination\n");
10468  res = -1;
10469  goto process_sdp_cleanup;
10470  }
10471  /* guaranteed to be exactly the right length */
10472  sprintf(offer->decline_m_line, "m=audio 0 %s %s\r\n", protocol, codecs);
10473 
10474  if (x == 0) {
10475  ast_debug(1, "Ignoring audio media offer because port number is zero\n");
10476  continue;
10477  }
10478 
10479  if (has_media_stream(p, SDP_AUDIO)) {
10480  ast_log(LOG_WARNING, "Declining non-primary audio stream: %s\n", m);
10481  continue;
10482  }
10483 
10484  /* Check number of ports offered for stream */
10485  if (numberofports > 1) {
10486  ast_log(LOG_WARNING, "%u ports offered for audio media, not supported by Asterisk. Will try anyway...\n", numberofports);
10487  }
10488 
10489  if ((!strcmp(protocol, "RTP/SAVPF") || !strcmp(protocol, "UDP/TLS/RTP/SAVPF")) && !ast_test_flag(&p->flags[2], SIP_PAGE3_USE_AVPF)) {
10490  if (req->method != SIP_RESPONSE) {
10491  ast_log(LOG_NOTICE, "Received SAVPF profle in audio offer but AVPF is not enabled, enabling: %s\n", m);
10492  secure_audio = 1;
10494  }
10495  else {
10496 
10497  ast_log(LOG_WARNING, "Received SAVPF profle in audio answer but AVPF is not enabled: %s\n", m);
10498  continue;
10499  }
10500  } else if ((!strcmp(protocol, "RTP/SAVP") || !strcmp(protocol, "UDP/TLS/RTP/SAVP")) && ast_test_flag(&p->flags[2], SIP_PAGE3_USE_AVPF)) {
10501  if (req->method != SIP_RESPONSE) {
10502  ast_log(LOG_NOTICE, "Received SAVP profle in audio offer but AVPF is enabled, disabling: %s\n", m);
10503  secure_audio = 1;
10505  }
10506  else {
10507  ast_log(LOG_WARNING, "Received SAVP profile in audio offer but AVPF is enabled: %s\n", m);
10508  continue;
10509  }
10510  } else if (!strcmp(protocol, "UDP/TLS/RTP/SAVP") || !strcmp(protocol, "UDP/TLS/RTP/SAVPF")) {
10511  secure_audio = 1;
10512 
10513  processed_crypto = 1;
10514  if (p->srtp) {
10516  }
10517  } else if (!strcmp(protocol, "RTP/SAVP") || !strcmp(protocol, "RTP/SAVPF")) {
10518  secure_audio = 1;
10519  } else if (!strcmp(protocol, "RTP/AVPF") && !ast_test_flag(&p->flags[2], SIP_PAGE3_USE_AVPF)) {
10520  if (req->method != SIP_RESPONSE) {
10521  ast_log(LOG_NOTICE, "Received AVPF profile in audio offer but AVPF is not enabled, enabling: %s\n", m);
10523  }
10524  else {
10525  ast_log(LOG_WARNING, "Received AVP profile in audio answer but AVPF is enabled: %s\n", m);
10526  continue;
10527  }
10528  } else if (!strcmp(protocol, "RTP/AVP") && ast_test_flag(&p->flags[2], SIP_PAGE3_USE_AVPF)) {
10529  if (req->method != SIP_RESPONSE) {
10530  ast_log(LOG_NOTICE, "Received AVP profile in audio answer but AVPF is enabled, disabling: %s\n", m);
10532  }
10533  else {
10534  ast_log(LOG_WARNING, "Received AVP profile in audio answer but AVPF is enabled: %s\n", m);
10535  continue;
10536  }
10537  } else if ((!strcmp(protocol, "UDP/TLS/RTP/SAVP") || !strcmp(protocol, "UDP/TLS/RTP/SAVPF")) &&
10538  (!(dtls = ast_rtp_instance_get_dtls(p->rtp)) || !dtls->active(p->rtp))) {
10539  ast_log(LOG_WARNING, "Received UDP/TLS in audio offer but DTLS is not enabled: %s\n", m);
10540  continue;
10541  } else if (strcmp(protocol, "RTP/AVP") && strcmp(protocol, "RTP/AVPF")) {
10542  ast_log(LOG_WARNING, "Unknown RTP profile in audio offer: %s\n", m);
10543  continue;
10544  }
10545 
10546  audio = TRUE;
10547  offer->type = SDP_AUDIO;
10548  portno = x;
10549 
10550  /* Scan through the RTP payload types specified in a "m=" line: */
10551  for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) {
10552  if (sscanf(codecs, "%30u%n", &codec, &len) != 1) {
10553  ast_log(LOG_WARNING, "Invalid syntax in RTP audio format list: %s\n", codecs);
10554  res = -1;
10555  goto process_sdp_cleanup;
10556  }
10557  if (debug) {
10558  ast_verbose("Found RTP audio format %u\n", codec);
10559  }
10560 
10561  ast_rtp_codecs_payloads_set_m_type(&newaudiortp, NULL, codec);
10562  }
10563  } else {
10564  ast_log(LOG_WARNING, "Rejecting audio media offer due to invalid or unsupported syntax: %s\n", m);
10565  res = -1;
10566  goto process_sdp_cleanup;
10567  }
10568  }
10569  /* Check for 'video' media offer */
10570  else if (p->vrtp && strncmp(m, "video ", 6) == 0) {
10571  if ((sscanf(m, "video %30u/%30u %17s %n", &x, &numberofports, protocol, &len) == 3 && len > 0) ||
10572  (sscanf(m, "video %30u %17s %n", &x, protocol, &len) == 2 && len > 0)) {
10573  codecs = m + len;
10574  /* produce zero-port m-line since it may be needed later
10575  * length is "m=video 0 " + protocol + " " + codecs + "\r\n\0" */
10576  if (!(offer->decline_m_line = ast_malloc(10 + strlen(protocol) + 1 + strlen(codecs) + 3))) {
10577  ast_log(LOG_WARNING, "Failed to allocate memory for SDP offer declination\n");
10578  res = -1;
10579  goto process_sdp_cleanup;
10580  }
10581  /* guaranteed to be exactly the right length */
10582  sprintf(offer->decline_m_line, "m=video 0 %s %s\r\n", protocol, codecs);
10583 
10584  if (x == 0) {
10585  ast_debug(1, "Ignoring video stream offer because port number is zero\n");
10586  continue;
10587  }
10588 
10589  /* Check number of ports offered for stream */
10590  if (numberofports > 1) {
10591  ast_log(LOG_WARNING, "%u ports offered for video stream, not supported by Asterisk. Will try anyway...\n", numberofports);
10592  }
10593 
10594  if (has_media_stream(p, SDP_VIDEO)) {
10595  ast_log(LOG_WARNING, "Declining non-primary video stream: %s\n", m);
10596  continue;
10597  }
10598 
10599  if ((!strcmp(protocol, "RTP/SAVPF") || !strcmp(protocol, "UDP/TLS/RTP/SAVPF")) && !ast_test_flag(&p->flags[2], SIP_PAGE3_USE_AVPF)) {
10600  ast_log(LOG_WARNING, "Received SAVPF profle in video offer but AVPF is not enabled: %s\n", m);
10601  continue;
10602  } else if ((!strcmp(protocol, "RTP/SAVP") || !strcmp(protocol, "UDP/TLS/RTP/SAVP")) && ast_test_flag(&p->flags[2], SIP_PAGE3_USE_AVPF)) {
10603  ast_log(LOG_WARNING, "Received SAVP profile in video offer but AVPF is enabled: %s\n", m);
10604  continue;
10605  } else if (!strcmp(protocol, "UDP/TLS/RTP/SAVP") || !strcmp(protocol, "UDP/TLS/RTP/SAVPF")) {
10606  secure_video = 1;
10607 
10608  processed_crypto = 1;
10609  if (p->vsrtp || (p->vsrtp = ast_sdp_srtp_alloc())) {
10611  }
10612  } else if (!strcmp(protocol, "RTP/SAVP") || !strcmp(protocol, "RTP/SAVPF")) {
10613  secure_video = 1;
10614  } else if (!strcmp(protocol, "RTP/AVPF") && !ast_test_flag(&p->flags[2], SIP_PAGE3_USE_AVPF)) {
10615  ast_log(LOG_WARNING, "Received AVPF profile in video offer but AVPF is not enabled: %s\n", m);
10616  continue;
10617  } else if (!strcmp(protocol, "RTP/AVP") && ast_test_flag(&p->flags[2], SIP_PAGE3_USE_AVPF)) {
10618  ast_log(LOG_WARNING, "Received AVP profile in video offer but AVPF is enabled: %s\n", m);
10619  continue;
10620  } else if (strcmp(protocol, "RTP/AVP") && strcmp(protocol, "RTP/AVPF")) {
10621  ast_log(LOG_WARNING, "Unknown RTP profile in video offer: %s\n", m);
10622  continue;
10623  }
10624 
10625  video = TRUE;
10626  p->novideo = FALSE;
10627  offer->type = SDP_VIDEO;
10628  vportno = x;
10629 
10630  /* Scan through the RTP payload types specified in a "m=" line: */
10631  for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) {
10632  if (sscanf(codecs, "%30u%n", &codec, &len) != 1) {
10633  ast_log(LOG_WARNING, "Invalid syntax in RTP video format list: %s\n", codecs);
10634  res = -1;
10635  goto process_sdp_cleanup;
10636  }
10637  if (debug) {
10638  ast_verbose("Found RTP video format %u\n", codec);
10639  }
10640  ast_rtp_codecs_payloads_set_m_type(&newvideortp, NULL, codec);
10641  }
10642  } else {
10643  ast_log(LOG_WARNING, "Rejecting video media offer due to invalid or unsupported syntax: %s\n", m);
10644  res = -1;
10645  goto process_sdp_cleanup;
10646  }
10647  }
10648  /* Check for 'text' media offer */
10649  else if (p->trtp && strncmp(m, "text ", 5) == 0) {
10650  if ((sscanf(m, "text %30u/%30u %17s %n", &x, &numberofports, protocol, &len) == 3 && len > 0) ||
10651  (sscanf(m, "text %30u %17s %n", &x, protocol, &len) == 2 && len > 0)) {
10652  codecs = m + len;
10653  /* produce zero-port m-line since it may be needed later
10654  * length is "m=text 0 " + protocol + " " + codecs + "\r\n\0" */
10655  if (!(offer->decline_m_line = ast_malloc(9 + strlen(protocol) + 1 + strlen(codecs) + 3))) {
10656  ast_log(LOG_WARNING, "Failed to allocate memory for SDP offer declination\n");
10657  res = -1;
10658  goto process_sdp_cleanup;
10659  }
10660  /* guaranteed to be exactly the right length */
10661  sprintf(offer->decline_m_line, "m=text 0 %s %s\r\n", protocol, codecs);
10662 
10663  if (x == 0) {
10664  ast_debug(1, "Ignoring text stream offer because port number is zero\n");
10665  continue;
10666  }
10667 
10668  /* Check number of ports offered for stream */
10669  if (numberofports > 1) {
10670  ast_log(LOG_WARNING, "%u ports offered for text stream, not supported by Asterisk. Will try anyway...\n", numberofports);
10671  }
10672 
10673  if (!strcmp(protocol, "RTP/AVPF") && !ast_test_flag(&p->flags[2], SIP_PAGE3_USE_AVPF)) {
10674  ast_log(LOG_WARNING, "Received AVPF profile in text offer but AVPF is not enabled: %s\n", m);
10675  continue;
10676  } else if (!strcmp(protocol, "RTP/AVP") && ast_test_flag(&p->flags[2], SIP_PAGE3_USE_AVPF)) {
10677  ast_log(LOG_WARNING, "Received AVP profile in text offer but AVPF is enabled: %s\n", m);
10678  continue;
10679  } else if (strcmp(protocol, "RTP/AVP") && strcmp(protocol, "RTP/AVPF")) {
10680  ast_log(LOG_WARNING, "Unknown RTP profile in text offer: %s\n", m);
10681  continue;
10682  }
10683 
10684  if (has_media_stream(p, SDP_TEXT)) {
10685  ast_log(LOG_WARNING, "Declining non-primary text stream: %s\n", m);
10686  continue;
10687  }
10688 
10689  text = TRUE;
10690  p->notext = FALSE;
10691  offer->type = SDP_TEXT;
10692  tportno = x;
10693 
10694  /* Scan through the RTP payload types specified in a "m=" line: */
10695  for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) {
10696  if (sscanf(codecs, "%30u%n", &codec, &len) != 1) {
10697  ast_log(LOG_WARNING, "Invalid syntax in RTP video format list: %s\n", codecs);
10698  res = -1;
10699  goto process_sdp_cleanup;
10700  }
10701  if (debug) {
10702  ast_verbose("Found RTP text format %u\n", codec);
10703  }
10704  ast_rtp_codecs_payloads_set_m_type(&newtextrtp, NULL, codec);
10705  }
10706  } else {
10707  ast_log(LOG_WARNING, "Rejecting text stream offer due to invalid or unsupported syntax: %s\n", m);
10708  res = -1;
10709  goto process_sdp_cleanup;
10710  }
10711  }
10712  /* Check for 'image' media offer */
10713  else if (strncmp(m, "image ", 6) == 0) {
10714  if (((sscanf(m, "image %30u udptl t38%n", &x, &len) == 1 && len > 0) ||
10715  (sscanf(m, "image %30u UDPTL t38%n", &x, &len) == 1 && len > 0))) {
10716  /* produce zero-port m-line since it may be needed later
10717  * length is "m=image 0 udptl t38" + "\r\n\0" */
10718  if (!(offer->decline_m_line = ast_malloc(22))) {
10719  ast_log(LOG_WARNING, "Failed to allocate memory for SDP offer declination\n");
10720  res = -1;
10721  goto process_sdp_cleanup;
10722  }
10723  /* guaranteed to be exactly the right length */
10724  strcpy(offer->decline_m_line, "m=image 0 udptl t38\r\n");
10725 
10726  if (x == 0) {
10727  ast_debug(1, "Ignoring image stream offer because port number is zero\n");
10728  continue;
10729  }
10730 
10731  if (initialize_udptl(p)) {
10732  ast_log(LOG_WARNING, "Failed to initialize UDPTL, declining image stream\n");
10733  continue;
10734  }
10735 
10736  if (has_media_stream(p, SDP_IMAGE)) {
10737  ast_log(LOG_WARNING, "Declining non-primary image stream: %s\n", m);
10738  continue;
10739  }
10740 
10741  image = TRUE;
10742  if (debug) {
10743  ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid);
10744  }
10745 
10746  offer->type = SDP_IMAGE;
10747  udptlportno = x;
10748 
10749  if (p->t38.state != T38_ENABLED) {
10750  memset(&p->t38.their_parms, 0, sizeof(p->t38.their_parms));
10751 
10752  /* default EC to none, the remote end should
10753  * respond with the EC they want to use */
10755  }
10756  } else if (sscanf(m, "image %30u %17s t38%n", &x, protocol, &len) == 2 && len > 0) {
10757  ast_log(LOG_WARNING, "Declining image stream due to unsupported transport: %s\n", m);
10758  /* produce zero-port m-line since this is guaranteed to be declined
10759  * length is "m=image 0 strlen(protocol) t38" + "\r\n\0" */
10760  if (!(offer->decline_m_line = ast_malloc(10 + strlen(protocol) + 7))) {
10761  ast_log(LOG_WARNING, "Failed to allocate memory for SDP offer declination\n");
10762  res = -1;
10763  goto process_sdp_cleanup;
10764  }
10765  /* guaranteed to be exactly the right length */
10766  sprintf(offer->decline_m_line, "m=image 0 %s t38\r\n", protocol);
10767  continue;
10768  } else {
10769  ast_log(LOG_WARNING, "Rejecting image media offer due to invalid or unsupported syntax: %s\n", m);
10770  res = -1;
10771  goto process_sdp_cleanup;
10772  }
10773  } else {
10774  char type[20] = {0,};
10775  if ((sscanf(m, "%19s %30u/%30u %n", type, &x, &numberofports, &len) == 3 && len > 0) ||
10776  (sscanf(m, "%19s %30u %n", type, &x, &len) == 2 && len > 0)) {
10777  /* produce zero-port m-line since it may be needed later
10778  * length is "m=" + type + " 0 " + remainder + "\r\n\0" */
10779  if (!(offer->decline_m_line = ast_malloc(2 + strlen(type) + 3 + strlen(m + len) + 3))) {
10780  ast_log(LOG_WARNING, "Failed to allocate memory for SDP offer declination\n");
10781  res = -1;
10782  goto process_sdp_cleanup;
10783  }
10784  /* guaranteed to be long enough */
10785  sprintf(offer->decline_m_line, "m=%s 0 %s\r\n", type, m + len);
10786  continue;
10787  } else {
10788  ast_log(LOG_WARNING, "Unsupported top-level media type in offer: %s\n", m);
10789  res = -1;
10790  goto process_sdp_cleanup;
10791  }
10792  }
10793 
10794  /* Media stream specific parameters */
10795  while ((type = get_sdp_line(&iterator, next - 1, req, &value)) != '\0') {
10796  int processed = FALSE;
10797 
10798  switch (type) {
10799  case 'c':
10800  if (audio) {
10801  if (process_sdp_c(value, &audiosa)) {
10802  processed = TRUE;
10803  sa = &audiosa;
10804  }
10805  } else if (video) {
10806  if (process_sdp_c(value, &videosa)) {
10807  processed = TRUE;
10808  vsa = &videosa;
10809  }
10810  } else if (text) {
10811  if (process_sdp_c(value, &textsa)) {
10812  processed = TRUE;
10813  tsa = &textsa;
10814  }
10815  } else if (image) {
10816  if (process_sdp_c(value, &imagesa)) {
10817  processed = TRUE;
10818  isa = &imagesa;
10819  }
10820  }
10821  break;
10822  case 'a':
10823  /* Audio specific scanning */
10824  if (audio) {
10825  if (process_sdp_a_ice(value, p, p->rtp, rtcp_mux_offered)) {
10826  processed = TRUE;
10827  } else if (process_sdp_a_dtls(value, p, p->rtp)) {
10828  processed_crypto = TRUE;
10829  processed = TRUE;
10830  if (p->srtp) {
10832  }
10833  } else if (process_sdp_a_sendonly(value, &sendonly)) {
10834  processed = TRUE;
10835  } else if (!processed_crypto && process_crypto(p, p->rtp, &p->srtp, value)) {
10836  processed_crypto = TRUE;
10837  processed = TRUE;
10838  if (secure_audio == FALSE) {
10839  ast_log(AST_LOG_NOTICE, "Processed audio crypto attribute without SAVP specified; accepting anyway\n");
10840  secure_audio = TRUE;
10841  }
10842  } else if (process_sdp_a_audio(value, p, &newaudiortp, &last_rtpmap_codec)) {
10843  processed = TRUE;
10844  } else if (process_sdp_a_rtcp_mux(value, p, &remote_rtcp_mux_audio)) {
10845  processed = TRUE;
10846  }
10847  }
10848  /* Video specific scanning */
10849  else if (video) {
10850  if (process_sdp_a_ice(value, p, p->vrtp, rtcp_mux_offered)) {
10851  processed = TRUE;
10852  } else if (process_sdp_a_dtls(value, p, p->vrtp)) {
10853  processed_crypto = TRUE;
10854  processed = TRUE;
10855  if (p->vsrtp) {
10857  }
10858  } else if (!processed_crypto && process_crypto(p, p->vrtp, &p->vsrtp, value)) {
10859  processed_crypto = TRUE;
10860  processed = TRUE;
10861  if (secure_video == FALSE) {
10862  ast_log(AST_LOG_NOTICE, "Processed video crypto attribute without SAVP specified; accepting anyway\n");
10863  secure_video = TRUE;
10864  }
10865  } else if (process_sdp_a_video(value, p, &newvideortp, &last_rtpmap_codec)) {
10866  processed = TRUE;
10867  } else if (process_sdp_a_rtcp_mux(value, p, &remote_rtcp_mux_video)) {
10868  processed = TRUE;
10869  }
10870  }
10871  /* Text (T.140) specific scanning */
10872  else if (text) {
10873  if (process_sdp_a_ice(value, p, p->trtp, rtcp_mux_offered)) {
10874  processed = TRUE;
10875  } else if (process_sdp_a_text(value, p, &newtextrtp, red_fmtp, &red_num_gen, red_data_pt, &last_rtpmap_codec)) {
10876  processed = TRUE;
10877  } else if (!processed_crypto && process_crypto(p, p->trtp, &p->tsrtp, value)) {
10878  processed_crypto = TRUE;
10879  processed = TRUE;
10880  }
10881  }
10882  /* Image (T.38 FAX) specific scanning */
10883  else if (image) {
10884  if (process_sdp_a_image(value, p))
10885  processed = TRUE;
10886  }
10887  break;
10888  }
10889 
10890  ast_debug(3, "Processing media-level (%s) SDP %c=%s... %s\n",
10891  (audio == TRUE)? "audio" : (video == TRUE)? "video" : (text == TRUE)? "text" : "image",
10892  type, value,
10893  (processed == TRUE)? "OK." : "UNSUPPORTED OR FAILED.");
10894  }
10895 
10896  /* Ensure crypto lines are provided where necessary */
10897  if (audio && secure_audio && !processed_crypto) {
10898  ast_log(LOG_WARNING, "Rejecting secure audio stream without encryption details: %s\n", m);
10899  res = -1;
10900  goto process_sdp_cleanup;
10901  } else if (video && secure_video && !processed_crypto) {
10902  ast_log(LOG_WARNING, "Rejecting secure video stream without encryption details: %s\n", m);
10903  res = -1;
10904  goto process_sdp_cleanup;
10905  }
10906  }
10907 
10908  /* Sanity checks */
10909  if (!sa && !vsa && !tsa && !isa) {
10910  ast_log(LOG_WARNING, "Insufficient information in SDP (c=)...\n");
10911  res = -1;
10912  goto process_sdp_cleanup;
10913  }
10914 
10915  if ((portno == -1) &&
10916  (vportno == -1) &&
10917  (tportno == -1) &&
10918  (udptlportno == -1)) {
10919  ast_log(LOG_WARNING, "Failing due to no acceptable offer found\n");
10920  res = -1;
10921  goto process_sdp_cleanup;
10922  }
10923 
10924  if (p->srtp && p->udptl && udptlportno != -1) {
10925  ast_debug(1, "Terminating SRTP due to T.38 UDPTL\n");
10927  p->srtp = NULL;
10928  }
10929 
10930  if (secure_audio && !(p->srtp && (ast_test_flag(p->srtp, AST_SRTP_CRYPTO_OFFER_OK)))) {
10931  ast_log(LOG_WARNING, "Can't provide secure audio requested in SDP offer\n");
10932  res = -1;
10933  goto process_sdp_cleanup;
10934  }
10935 
10936  if (!secure_audio && p->srtp) {
10937  ast_log(LOG_WARNING, "Failed to receive SDP offer/answer with required SRTP crypto attributes for audio\n");
10938  res = -1;
10939  goto process_sdp_cleanup;
10940  }
10941 
10942  if (secure_video && !(p->vsrtp && (ast_test_flag(p->vsrtp, AST_SRTP_CRYPTO_OFFER_OK)))) {
10943  ast_log(LOG_WARNING, "Can't provide secure video requested in SDP offer\n");
10944  res = -1;
10945  goto process_sdp_cleanup;
10946  }
10947 
10948  if (!p->novideo && !secure_video && p->vsrtp) {
10949  ast_log(LOG_WARNING, "Failed to receive SDP offer/answer with required SRTP crypto attributes for video\n");
10950  res = -1;
10951  goto process_sdp_cleanup;
10952  }
10953 
10954  if (!(secure_audio || secure_video || (p->udptl && udptlportno != -1)) && ast_test_flag(&p->flags[1], SIP_PAGE2_USE_SRTP)) {
10955  ast_log(LOG_WARNING, "Matched device setup to use SRTP, but request was not!\n");
10956  res = -1;
10957  goto process_sdp_cleanup;
10958  }
10959 
10960  if (udptlportno == -1) {
10962  }
10963 
10964  if (is_offer) {
10965  /*
10966  * Setup rx payload type mapping to prefer the mapping
10967  * from the peer that the RFC says we SHOULD use.
10968  */
10969  ast_rtp_codecs_payloads_xover(&newaudiortp, &newaudiortp, NULL);
10970  ast_rtp_codecs_payloads_xover(&newvideortp, &newvideortp, NULL);
10971  ast_rtp_codecs_payloads_xover(&newtextrtp, &newtextrtp, NULL);
10972  }
10973 
10974  /* Now gather all of the codecs that we are asked for: */
10975  ast_rtp_codecs_payload_formats(&newaudiortp, peercapability, &peernoncodeccapability);
10976  ast_rtp_codecs_payload_formats(&newvideortp, vpeercapability, &vpeernoncodeccapability);
10977  ast_rtp_codecs_payload_formats(&newtextrtp, tpeercapability, &tpeernoncodeccapability);
10978 
10979  ast_format_cap_append_from_cap(newpeercapability, peercapability, AST_MEDIA_TYPE_AUDIO);
10980  ast_format_cap_append_from_cap(newpeercapability, vpeercapability, AST_MEDIA_TYPE_VIDEO);
10981  ast_format_cap_append_from_cap(newpeercapability, tpeercapability, AST_MEDIA_TYPE_TEXT);
10982 
10983  ast_format_cap_get_compatible(p->caps, newpeercapability, newjointcapability);
10984  if (!ast_format_cap_count(newjointcapability) && udptlportno == -1) {
10985  ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n");
10986  /* Do NOT Change current setting */
10987  res = -1;
10988  goto process_sdp_cleanup;
10989  }
10990 
10991  newnoncodeccapability = p->noncodeccapability & peernoncodeccapability;
10992 
10993  if (debug) {
10994  /* shame on whoever coded this.... */
10995  struct ast_str *cap_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
10996  struct ast_str *peer_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
10997  struct ast_str *vpeer_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
10998  struct ast_str *tpeer_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
10999  struct ast_str *joint_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
11000  struct ast_str *s1 = ast_str_alloca(SIPBUFSIZE);
11001  struct ast_str *s2 = ast_str_alloca(SIPBUFSIZE);
11002  struct ast_str *s3 = ast_str_alloca(SIPBUFSIZE);
11003 
11004  ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s/text=%s, combined - %s\n",
11005  ast_format_cap_get_names(p->caps, &cap_buf),
11006  ast_format_cap_get_names(peercapability, &peer_buf),
11007  ast_format_cap_get_names(vpeercapability, &vpeer_buf),
11008  ast_format_cap_get_names(tpeercapability, &tpeer_buf),
11009  ast_format_cap_get_names(newjointcapability, &joint_buf));
11010 
11011  ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n",
11013  ast_rtp_lookup_mime_multiple2(s2, NULL, peernoncodeccapability, 0, 0),
11014  ast_rtp_lookup_mime_multiple2(s3, NULL, newnoncodeccapability, 0, 0));
11015  }
11016 
11017  /* When UDPTL is negotiated it is expected that there are no compatible codecs as audio or
11018  * video is not being transported, thus we continue in this function further up if that is
11019  * the case. If we receive an SDP answer containing both a UDPTL stream and another media
11020  * stream however we need to check again to ensure that there is at least one joint codec
11021  * instead of assuming there is one.
11022  */
11023  if ((portno != -1 || vportno != -1 || tportno != -1) && ast_format_cap_count(newjointcapability)) {
11024  /* We are now ready to change the sip session and RTP structures with the offered codecs, since
11025  they are acceptable */
11026  unsigned int framing;
11028  ast_format_cap_append_from_cap(p->jointcaps, newjointcapability, AST_MEDIA_TYPE_UNKNOWN); /* Our joint codec profile for this call */
11030  ast_format_cap_append_from_cap(p->peercaps, newpeercapability, AST_MEDIA_TYPE_UNKNOWN); /* The other side's capability in latest offer */
11031  p->jointnoncodeccapability = newnoncodeccapability; /* DTMF capabilities */
11032 
11033  tmp_fmt = ast_format_cap_get_format(p->jointcaps, 0);
11034  framing = ast_format_cap_get_format_framing(p->jointcaps, tmp_fmt);
11035  /* respond with single most preferred joint codec, limiting the other side's choice */
11038  ast_format_cap_append(p->jointcaps, tmp_fmt, framing);
11039  }
11040  if (!ast_rtp_codecs_get_framing(&newaudiortp)) {
11041  /* Peer did not force us to use a specific framing, so use our own */
11042  ast_rtp_codecs_set_framing(&newaudiortp, framing);
11043  }
11044  ao2_ref(tmp_fmt, -1);
11045  }
11046 
11047  /* Setup audio address and port */
11048  if (p->rtp) {
11049  if (sa && portno > 0) {
11050  /* Start ICE negotiation here, only when it is response, and setting that we are conrolling agent,
11051  as we are offerer */
11052  set_ice_components(p, p->rtp, remote_rtcp_mux_audio);
11053  if (req->method == SIP_RESPONSE) {
11054  start_ice(p->rtp, 1);
11055  }
11056  ast_sockaddr_set_port(sa, portno);
11058  if (debug) {
11059  ast_verbose("Peer audio RTP is at port %s\n",
11061  }
11062 
11064  /* Ensure RTCP is enabled since it may be inactive
11065  if we're coming back from a T.38 session */
11066  configure_rtcp(p, p->rtp, SIP_AUDIO_RTCP_FD, remote_rtcp_mux_audio);
11067 
11068  if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) {
11069  ast_clear_flag(&p->flags[0], SIP_DTMF);
11070  if (newnoncodeccapability & AST_RTP_DTMF) {
11071  /* XXX Would it be reasonable to drop the DSP at this point? XXX */
11073  /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */
11076  } else {
11078  }
11079  }
11080  } else if (udptlportno > 0) {
11081  if (debug)
11082  ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session.\n");
11083 
11084  /* Force media to go through us for T.38. */
11085  memset(&p->redirip, 0, sizeof(p->redirip));
11086 
11087  /* Prevent audio RTCP reads */
11088  if (p->owner) {
11090  }
11091  /* Silence RTCP while audio RTP is inactive */
11093  } else {
11095  if (debug)
11096  ast_verbose("Peer doesn't provide audio\n");
11097  }
11098  }
11099 
11100  /* Setup video address and port */
11101  if (p->vrtp) {
11102  if (vsa && vportno > 0) {
11103  set_ice_components(p, p->vrtp, remote_rtcp_mux_video);
11104  start_ice(p->vrtp, (req->method != SIP_RESPONSE) ? 0 : 1);
11105  ast_sockaddr_set_port(vsa, vportno);
11107  if (debug) {
11108  ast_verbose("Peer video RTP is at port %s\n",
11109  ast_sockaddr_stringify(vsa));
11110  }
11112  configure_rtcp(p, p->vrtp, SIP_VIDEO_RTCP_FD, remote_rtcp_mux_video);
11113  } else {
11115  if (debug)
11116  ast_verbose("Peer doesn't provide video\n");
11117  }
11118  }
11119 
11120  /* Setup text address and port */
11121  if (p->trtp) {
11122  if (tsa && tportno > 0) {
11123  start_ice(p->trtp, (req->method != SIP_RESPONSE) ? 0 : 1);
11124  ast_sockaddr_set_port(tsa, tportno);
11126  if (debug) {
11127  ast_verbose("Peer T.140 RTP is at port %s\n",
11128  ast_sockaddr_stringify(tsa));
11129  }
11131  p->red = 1;
11132  ast_rtp_red_init(p->trtp, 300, red_data_pt, 2);
11133  } else {
11134  p->red = 0;
11135  }
11137  } else {
11139  if (debug)
11140  ast_verbose("Peer doesn't provide T.140\n");
11141  }
11142  }
11143 
11144  /* Setup image address and port */
11145  if (p->udptl) {
11146  if (isa && udptlportno > 0) {
11149  if (!ast_sockaddr_isnull(isa) && debug) {
11150  ast_debug(1, "Peer T.38 UDPTL is set behind NAT and with destination, destination address now %s\n", ast_sockaddr_stringify(isa));
11151  }
11152  }
11153  ast_sockaddr_set_port(isa, udptlportno);
11154  ast_udptl_set_peer(p->udptl, isa);
11155  if (debug)
11156  ast_debug(1, "Peer T.38 UDPTL is at port %s\n", ast_sockaddr_stringify(isa));
11157 
11158  /* verify the far max ifp can be calculated. this requires far max datagram to be set. */
11160  /* setting to zero will force a default if none was provided by the SDP */
11162  }
11163 
11164  /* Remote party offers T38, we need to update state */
11165  if ((t38action == SDP_T38_ACCEPT) &&
11166  (p->t38.state == T38_LOCAL_REINVITE)) {
11168  } else if ((t38action == SDP_T38_INITIATE) &&
11169  p->owner && p->lastinvite) {
11170  change_t38_state(p, T38_PEER_REINVITE); /* T38 Offered in re-invite from remote party */
11171  /* If fax detection is enabled then send us off to the fax extension */
11173  ast_channel_lock(p->owner);
11174  if (strcmp(ast_channel_exten(p->owner), "fax")) {
11175  const char *target_context = S_OR(ast_channel_macrocontext(p->owner), ast_channel_context(p->owner));
11177  if (ast_exists_extension(p->owner, target_context, "fax", 1,
11179  ast_verb(2, "Redirecting '%s' to fax extension due to peer T.38 re-INVITE\n", ast_channel_name(p->owner));
11181  if (ast_async_goto(p->owner, target_context, "fax", 1)) {
11182  ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", ast_channel_name(p->owner), target_context);
11183  }
11184  } else {
11185  ast_log(LOG_NOTICE, "T.38 re-INVITE detected but no fax extension\n");
11186  }
11187  } else {
11189  }
11190  }
11191  }
11192  } else {
11194  ast_udptl_stop(p->udptl);
11195  if (debug)
11196  ast_debug(1, "Peer doesn't provide T.38 UDPTL\n");
11197  }
11198  }
11199 
11200  if ((portno == -1) && (p->t38.state != T38_DISABLED) && (p->t38.state != T38_REJECTED)) {
11201  ast_debug(3, "Have T.38 but no audio, accepting offer anyway\n");
11202  res = 0;
11203  goto process_sdp_cleanup;
11204  }
11205 
11206  /* Ok, we're going with this offer */
11207  ast_debug(2, "We're settling with these formats: %s\n", ast_format_cap_get_names(p->jointcaps, &codec_buf));
11208 
11209  if (!p->owner) { /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */
11210  res = 0;
11211  goto process_sdp_cleanup;
11212  }
11213 
11214  ast_debug(4, "We have an owner, now see if we need to change this call\n");
11216  struct ast_format_cap *caps;
11217  unsigned int framing;
11218 
11219  if (debug) {
11220  struct ast_str *cap_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
11221  struct ast_str *joint_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
11222 
11223  ast_debug(1, "Setting native formats after processing SDP. peer joint formats %s, old nativeformats %s\n",
11224  ast_format_cap_get_names(p->jointcaps, &joint_buf),
11226  }
11227 
11229  if (caps) {
11230  tmp_fmt = ast_format_cap_get_format(p->jointcaps, 0);
11231  framing = ast_format_cap_get_format_framing(p->jointcaps, tmp_fmt);
11232  ast_format_cap_append(caps, tmp_fmt, framing);
11233  ast_format_cap_append_from_cap(caps, vpeercapability, AST_MEDIA_TYPE_VIDEO);
11234  ast_format_cap_append_from_cap(caps, tpeercapability, AST_MEDIA_TYPE_TEXT);
11236  ao2_ref(caps, -1);
11237  ao2_ref(tmp_fmt, -1);
11238  }
11239 
11242  }
11243 
11244  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)) {
11246  ast_queue_unhold(p->owner);
11247  }
11248  /* Activate a re-invite */
11250  change_hold_state(p, req, FALSE, sendonly);
11251  } 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)) {
11254  }
11255  if (sendonly)
11257  /* RTCP needs to go ahead, even if we're on hold!!! */
11258  /* Activate a re-invite */
11260  change_hold_state(p, req, TRUE, sendonly);
11261  }
11262 
11263 process_sdp_cleanup:
11264  if (res) {
11266  }
11267  ast_rtp_codecs_payloads_destroy(&newtextrtp);
11268  ast_rtp_codecs_payloads_destroy(&newvideortp);
11269  ast_rtp_codecs_payloads_destroy(&newaudiortp);
11270  ao2_cleanup(peercapability);
11271  ao2_cleanup(vpeercapability);
11272  ao2_cleanup(tpeercapability);
11273  ao2_cleanup(newjointcapability);
11274  ao2_cleanup(newpeercapability);
11275  return res;
11276 }
void ast_rtp_codecs_payload_formats(struct ast_rtp_codecs *codecs, struct ast_format_cap *astformats, int *nonastformats)
Retrieve all formats that were found.
Definition: rtp_engine.c:1580
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
struct ast_format_cap * peercaps
Definition: sip.h:1101
static const char type[]
Definition: chan_ooh323.c:109
#define ast_channel_lock(chan)
Definition: channel.h:2945
#define T38_ENABLED
Definition: chan_ooh323.c:102
static int process_sdp_a_ice(const char *a, struct sip_pvt *p, struct ast_rtp_instance *instance, int rtcp_mux)
Definition: chan_sip.c:11432
char * str
Subscriber phone number (Malloced)
Definition: channel.h:292
int ast_rtp_red_init(struct ast_rtp_instance *instance, int buffer_time, int *payloads, int generations)
Initialize RED support on an RTP instance.
Definition: rtp_engine.c:2418
#define FALSE
Definition: app_minivm.c:521
static void set_ice_components(struct sip_pvt *p, struct ast_rtp_instance *instance, int remote_rtcp_mux)
Definition: chan_sip.c:10211
#define SIP_DTMF_INBAND
Definition: sip.h:277
struct ast_format * ast_format_t140_red
Built-in cached t140 red format.
Definition: format_cache.c:241
static int process_sdp_a_sendonly(const char *a, int *sendonly)
Definition: chan_sip.c:11412
static const char * get_sdp_iterate(int *start, struct sip_request *req, const char *name)
Lookup &#39;name&#39; in the SDP starting at the &#39;start&#39; line. Returns the matching line, and &#39;start&#39; is upda...
Definition: chan_sip.c:8444
time_t lastrtprx
Definition: sip.h:1129
enum t38state state
Definition: sip.h:917
struct ast_rtp_instance * trtp
Definition: sip.h:1176
#define ast_test_flag(p, flag)
Definition: utils.h:63
static int process_sdp_a_dtls(const char *a, struct sip_pvt *p, struct ast_rtp_instance *instance)
Definition: chan_sip.c:11505
int ast_queue_unhold(struct ast_channel *chan)
Queue an unhold frame.
Definition: channel.c:1216
#define SIP_PAGE2_PREFERRED_CODEC
Definition: sip.h:332
#define ast_set_flag(p, flag)
Definition: utils.h:70
struct ast_rtp_codecs * ast_rtp_instance_get_codecs(struct ast_rtp_instance *instance)
Get the codecs structure of an RTP instance.
Definition: rtp_engine.c:727
#define LOG_WARNING
Definition: logger.h:274
struct ast_sdp_srtp * tsrtp
Definition: sip.h:1187
Definition: sip.h:493
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:326
static int debug
Global debug status.
Definition: res_xmpp.c:435
struct ast_sockaddr redirip
Definition: sip.h:1126
unsigned int sdp_start
Definition: sip.h:835
#define SIP_DTMF_RFC2833
Definition: sip.h:276
void ast_rtp_codecs_payloads_xover(struct ast_rtp_codecs *src, struct ast_rtp_codecs *dest, struct ast_rtp_instance *instance)
Crossover copy the tx payload mapping of src to the rx payload mapping of dest.
Definition: rtp_engine.c:1257
struct ast_format_cap * jointcaps
Definition: sip.h:1100
static char get_sdp_line(int *start, int stop, struct sip_request *req, const char **value)
Fetches the next valid SDP line between the &#39;start&#39; line (inclusive) and the &#39;stop&#39; line (exclusive)...
Definition: chan_sip.c:8467
Definition of a media format.
Definition: format.c:43
size_t ast_format_cap_count(const struct ast_format_cap *cap)
Get the number of formats present within the capabilities structure.
Definition: format_cap.c:395
#define SIP_PAGE2_CALL_ONHOLD
Definition: sip.h:351
void ast_udptl_set_far_max_datagram(struct ast_udptl *udptl, unsigned int max_datagram)
sets far max datagram size. If max_datagram is = 0, the far max datagram size is set to a default val...
Definition: udptl.c:997
struct ast_flags flags[3]
Definition: sip.h:1075
char * text
Definition: app_queue.c:1508
#define ast_str_alloca(init_len)
Definition: strings.h:800
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
#define SIP_PAGE2_RFC2833_COMPENSATE
Definition: sip.h:356
void ast_rtp_codecs_set_framing(struct ast_rtp_codecs *codecs, unsigned int framing)
Set the framing used for a set of codecs.
Definition: rtp_engine.c:1558
#define AST_RTP_CODECS_NULL_INIT
Definition: rtp_engine.h:716
unsigned short novideo
Definition: sip.h:1085
#define NULL
Definition: resample.c:96
int value
Definition: syslog.c:37
Definition: sip.h:490
Socket address structure.
Definition: netsock2.h:97
int red
Definition: sip.h:1189
#define ast_verb(level,...)
Definition: logger.h:463
int jointnoncodeccapability
Definition: sip.h:1105
unsigned int ast_rtp_codecs_get_framing(struct ast_rtp_codecs *codecs)
Get the framing used for a set of codecs.
Definition: rtp_engine.c:1569
struct t38properties t38
Definition: sip.h:1113
struct ast_sdp_srtp * vsrtp
Definition: sip.h:1186
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
enum ast_format_cmp_res ast_format_cap_iscompatible_format(const struct ast_format_cap *cap, const struct ast_format *format)
Find if ast_format is within the capabilities of the ast_format_cap object.
Definition: format_cap.c:583
#define SIP_PAGE2_USE_SRTP
Definition: sip.h:368
static void configure_rtcp(struct sip_pvt *p, struct ast_rtp_instance *instance, int which, int remote_rtcp_mux)
Definition: chan_sip.c:10194
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
const ast_string_field mohsuggest
Definition: sip.h:1063
static int process_sdp_a_rtcp_mux(const char *a, struct sip_pvt *p, int *requested)
Definition: chan_sip.c:11493
struct ast_party_id id
Caller party ID.
Definition: channel.h:421
#define SIP_PAGE2_SYMMETRICRTP
Definition: sip.h:327
#define AST_LOG_NOTICE
Definition: logger.h:268
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
void ast_rtp_instance_stop(struct ast_rtp_instance *instance)
Stop an RTP instance.
Definition: rtp_engine.c:2183
static int process_sdp_a_audio(const char *a, struct sip_pvt *p, struct ast_rtp_codecs *newaudiortp, int *last_rtpmap_codec)
Definition: chan_sip.c:11557
static int process_sdp_a_video(const char *a, struct sip_pvt *p, struct ast_rtp_codecs *newvideortp, int *last_rtpmap_codec)
Definition: chan_sip.c:11637
int noncodeccapability
Definition: sip.h:1104
static void offered_media_list_destroy(struct sip_pvt *p)
Destroy SDP media offer list.
Definition: chan_sip.c:6663
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
Definition: channel.c:5849
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
struct ast_format_cap * caps
Definition: sip.h:1099
static struct ao2_container * codecs
Registered codecs.
Definition: codec.c:48
static int initialize_udptl(struct sip_pvt *p)
Definition: chan_sip.c:7862
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:85
#define AST_SRTP_CRYPTO_OFFER_OK
Definition: sdp_srtp.h:44
static void start_ice(struct ast_rtp_instance *instance, int offer)
Start ICE negotiation on an RTP instance.
Definition: chan_sip.c:13180
#define ast_format_cap_append(cap, format, framing)
Definition: format_cap.h:103
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
Sets write format on channel chan.
Definition: channel.c:5890
Definition: sip.h:492
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:4179
struct ast_udptl * udptl
Definition: sip.h:1115
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
int ast_queue_hold(struct ast_channel *chan, const char *musicclass)
Queue a hold frame.
Definition: channel.c:1191
static int process_sdp_o(const char *o, struct sip_pvt *p)
Definition: chan_sip.c:11278
const char * ast_channel_exten(const struct ast_channel *chan)
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel&#39;s frame queue.
Definition: channel.c:1139
Structure that represents the optional DTLS SRTP support within an RTP engine.
Definition: rtp_engine.h:570
void ast_format_cap_remove_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Remove all formats matching a specific format type.
Definition: format_cap.c:525
static int process_crypto(struct sip_pvt *p, struct ast_rtp_instance *rtp, struct ast_sdp_srtp **srtp, const char *a)
Definition: chan_sip.c:34339
enum media_type type
Definition: sip.h:985
Definition: sip.h:491
Structure for remembering offered media in an INVITE, to make sure we reply to all media streams...
Definition: sip.h:984
#define SIP_PAGE3_DISCARD_REMOTE_HOLD_RETRIEVAL
Definition: sip.h:392
const ast_string_field callid
Definition: sip.h:1063
#define LOG_ERROR
Definition: logger.h:285
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
#define SIP_PAGE2_UDPTL_DESTINATION
Definition: sip.h:365
struct ast_rtp_engine_dtls * ast_rtp_instance_get_dtls(struct ast_rtp_instance *instance)
Obtain a pointer to the DTLS support present on an RTP instance.
Definition: rtp_engine.c:3011
void ast_udptl_set_peer(struct ast_udptl *udptl, const struct ast_sockaddr *them)
Definition: udptl.c:1130
unsigned short notext
Definition: sip.h:1086
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:537
#define SIPBUFSIZE
Definition: sip.h:56
#define ast_rtp_instance_set_remote_address(instance, address)
Set the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.h:1080
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define T38_DISABLED
Definition: chan_ooh323.c:101
int method
Definition: sip.h:833
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
struct ast_rtp_instance * vrtp
Definition: sip.h:1175
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
unsigned int ast_format_cap_get_format_framing(const struct ast_format_cap *cap, const struct ast_format *format)
Get the framing for a format.
Definition: format_cap.c:443
#define LOG_NOTICE
Definition: logger.h:263
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition: format_cap.c:736
struct ast_control_t38_parameters their_parms
Definition: sip.h:919
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
char * decline_m_line
Definition: sip.h:986
struct ast_channel * owner
Definition: sip.h:1138
struct ast_sdp_srtp * ast_sdp_srtp_alloc(void)
allocate a ast_sdp_srtp structure
Definition: sdp_srtp.c:41
struct ast_rtp_instance * rtp
Definition: sip.h:1174
void ast_sdp_srtp_destroy(struct ast_sdp_srtp *srtp)
free a ast_sdp_srtp structure
Definition: sdp_srtp.c:51
void ast_rtp_codecs_payloads_destroy(struct ast_rtp_codecs *codecs)
Destroy the contents of an RTP codecs structure (but not the structure itself)
Definition: rtp_engine.c:974
static int sip_debug_test_pvt(struct sip_pvt *p)
Test PVT for debugging output.
Definition: chan_sip.c:3649
#define ast_clear_flag(p, flag)
Definition: utils.h:77
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition: channel.c:2431
#define SIP_PAGE2_FAX_DETECT_T38
Definition: sip.h:362
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
static void change_hold_state(struct sip_pvt *dialog, struct sip_request *req, int holdstate, int sendonly)
Change hold state for a call.
Definition: chan_sip.c:10147
struct ast_frame ast_null_frame
Definition: main/frame.c:79
void ast_rtp_codecs_payloads_copy(struct ast_rtp_codecs *src, struct ast_rtp_codecs *dest, struct ast_rtp_instance *instance)
Copy payload information from one RTP instance to another.
Definition: rtp_engine.c:1224
int(* active)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:574
static int has_media_stream(struct sip_pvt *p, enum media_type m)
Check the media stream list to see if the given type already exists.
Definition: chan_sip.c:10183
time_t lastrtptx
Definition: sip.h:1130
#define SIP_DTMF
Definition: sip.h:275
int ast_rtp_codecs_payloads_initialize(struct ast_rtp_codecs *codecs)
Initialize an RTP codecs structure.
Definition: rtp_engine.c:958
char * ast_rtp_lookup_mime_multiple2(struct ast_str *buf, struct ast_format_cap *ast_format_capability, int rtp_capability, const int asterisk_format, enum ast_rtp_options options)
Convert formats into a string and put them into a buffer.
Definition: rtp_engine.c:2045
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static void change_t38_state(struct sip_pvt *p, int state)
Change the T38 state on a SIP dialog.
Definition: chan_sip.c:5889
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
const char * ast_channel_name(const struct ast_channel *chan)
void ast_udptl_set_error_correction_scheme(struct ast_udptl *udptl, enum ast_t38_ec_modes ec)
Definition: udptl.c:945
#define TRUE
Definition: app_minivm.c:518
static int has_media_level_attribute(int start, struct sip_request *req, const char *attr)
Definition: chan_sip.c:10230
void ast_udptl_stop(struct ast_udptl *udptl)
Definition: udptl.c:1145
unsigned short session_modify
Definition: sip.h:1087
int ast_async_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Set the channel to next execute the specified dialplan location.
Definition: pbx.c:7011
uint32_t lastinvite
Definition: sip.h:1074
unsigned int ast_udptl_get_far_max_datagram(const struct ast_udptl *udptl)
Definition: udptl.c:1008
const char * ast_channel_context(const struct ast_channel *chan)
void ast_rtp_instance_set_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value)
Set the value of an RTP instance property.
Definition: rtp_engine.c:705
int ast_format_cap_append_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type)
Append the formats of provided type in src to dst.
Definition: format_cap.c:269
struct ast_format * ast_format_cap_get_format(const struct ast_format_cap *cap, int position)
Get the format at a specific index.
Definition: format_cap.c:400
struct sip_pvt::@174 offered_media
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)
Definition: chan_sip.c:11691
struct ast_sdp_srtp * srtp
Definition: sip.h:1185
static int sockaddr_is_null_or_any(const struct ast_sockaddr *addr)
Definition: chan_sip.c:10177
const char * ast_channel_macrocontext(const struct ast_channel *chan)
#define AST_RTP_DTMF
Definition: rtp_engine.h:266
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
static int process_sdp_a_image(const char *a, struct sip_pvt *p)
Definition: chan_sip.c:11741
int ast_format_cap_get_compatible(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2, struct ast_format_cap *result)
Find the compatible formats between two capabilities structures.
Definition: format_cap.c:630
#define ast_rtp_instance_get_remote_address(instance, address)
Get the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.h:1192
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:298
#define SIP_DTMF_AUTO
Definition: sip.h:279
void ast_rtp_codecs_payloads_set_m_type(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, int payload)
Record tx payload type information that was seen in an m= SDP line.
Definition: rtp_engine.c:1301
int ast_format_cap_has_type(const struct ast_format_cap *cap, enum ast_media_type type)
Find out if the capabilities structure has any formats of a specific type.
Definition: format_cap.c:615
static int process_sdp_c(const char *c, struct ast_sockaddr *addr)
Definition: chan_sip.c:11385
#define SIP_PAGE3_USE_AVPF
Definition: sip.h:389
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:343

◆ process_sdp_a_audio()

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

References ao2_ref, ao2_replace, ast_debug, ast_format_cap_set_framing(), ast_format_cmp(), AST_FORMAT_CMP_EQUAL, ast_format_g719, ast_format_parse_sdp_fmtp(), ast_log, ast_rtp_codecs_get_payload_format(), ast_rtp_codecs_payload_replace_format(), ast_rtp_codecs_payloads_set_rtpmap_type_rate(), ast_rtp_codecs_payloads_unset(), ast_rtp_codecs_set_framing(), AST_RTP_OPT_G726_NONSTANDARD, ast_test_flag, ast_verbose(), sip_pvt::autoframing, sip_pvt::caps, debug, FALSE, sip_pvt::flags, format, LOG_WARNING, NULL, SDP_MAX_RTPMAP_CODECS, sip_debug_test_pvt(), SIP_G726_NONSTANDARD, tmp(), and TRUE.

Referenced by process_sdp().

11558 {
11559  int found = FALSE;
11560  unsigned int codec;
11561  char mimeSubtype[128];
11562  char fmtp_string[256];
11563  unsigned int sample_rate;
11564  int debug = sip_debug_test_pvt(p);
11565 
11566  if (!strncasecmp(a, "ptime", 5)) {
11567  char *tmp = strrchr(a, ':');
11568  long int framing = 0;
11569  if (tmp) {
11570  tmp++;
11571  framing = strtol(tmp, NULL, 10);
11572  if (framing == LONG_MIN || framing == LONG_MAX) {
11573  framing = 0;
11574  ast_debug(1, "Can't read framing from SDP: %s\n", a);
11575  }
11576  }
11577 
11578  if (framing && p->autoframing) {
11579  ast_debug(1, "Setting framing to %ld\n", framing);
11580  ast_format_cap_set_framing(p->caps, framing);
11581  ast_rtp_codecs_set_framing(newaudiortp, framing);
11582  }
11583  found = TRUE;
11584  } else if (sscanf(a, "rtpmap: %30u %127[^/]/%30u", &codec, mimeSubtype, &sample_rate) == 3) {
11585  /* We have a rtpmap to handle */
11586  if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) {
11587  if (!(ast_rtp_codecs_payloads_set_rtpmap_type_rate(newaudiortp, NULL, codec, "audio", mimeSubtype,
11588  ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0, sample_rate))) {
11589  if (debug)
11590  ast_verbose("Found audio description format %s for ID %u\n", mimeSubtype, codec);
11591  //found_rtpmap_codecs[last_rtpmap_codec] = codec;
11592  (*last_rtpmap_codec)++;
11593  found = TRUE;
11594  } else {
11595  ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec);
11596  if (debug)
11597  ast_verbose("Found unknown media description format %s for ID %u\n", mimeSubtype, codec);
11598  }
11599  } else {
11600  if (debug)
11601  ast_verbose("Discarded description format %s for ID %u\n", mimeSubtype, codec);
11602  }
11603  } else if (sscanf(a, "fmtp: %30u %255[^\t\n]", &codec, fmtp_string) == 2) {
11604  struct ast_format *format;
11605 
11606  if ((format = ast_rtp_codecs_get_payload_format(newaudiortp, codec))) {
11607  unsigned int bit_rate;
11608  struct ast_format *format_parsed;
11609 
11610  format_parsed = ast_format_parse_sdp_fmtp(format, fmtp_string);
11611  if (format_parsed) {
11612  ast_rtp_codecs_payload_replace_format(newaudiortp, codec, format_parsed);
11613  ao2_replace(format, format_parsed);
11614  ao2_ref(format_parsed, -1);
11615  found = TRUE;
11616  } else {
11617  ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec);
11618  }
11619 
11621  if (sscanf(fmtp_string, "bitrate=%30u", &bit_rate) == 1) {
11622  if (bit_rate != 64000) {
11623  ast_log(LOG_WARNING, "Got G.719 offer at %u bps, but only 64000 bps supported; ignoring.\n", bit_rate);
11624  ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec);
11625  } else {
11626  found = TRUE;
11627  }
11628  }
11629  }
11630  ao2_ref(format, -1);
11631  }
11632  }
11633 
11634  return found;
11635 }
#define FALSE
Definition: app_minivm.c:521
int ast_rtp_codecs_payload_replace_format(struct ast_rtp_codecs *codecs, int payload, struct ast_format *format)
Update the format associated with a tx payload type in a codecs structure.
Definition: rtp_engine.c:1503
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define LOG_WARNING
Definition: logger.h:274
static int debug
Global debug status.
Definition: res_xmpp.c:435
static int tmp()
Definition: bt_open.c:389
Definition of a media format.
Definition: format.c:43
struct ast_flags flags[3]
Definition: sip.h:1075
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
void ast_rtp_codecs_set_framing(struct ast_rtp_codecs *codecs, unsigned int framing)
Set the framing used for a set of codecs.
Definition: rtp_engine.c:1558
void ast_format_cap_set_framing(struct ast_format_cap *cap, unsigned int framing)
Set the global framing.
Definition: format_cap.c:136
#define NULL
Definition: resample.c:96
struct ast_format * ast_format_g719
Built-in cached g719 format.
Definition: format_cache.c:161
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
struct ast_format * ast_rtp_codecs_get_payload_format(struct ast_rtp_codecs *codecs, int payload)
Retrieve the actual ast_format stored on the codecs structure for a specific tx payload type...
Definition: rtp_engine.c:1537
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
struct ast_format_cap * caps
Definition: sip.h:1099
#define ao2_ref(o, delta)
Definition: astobj2.h:464
unsigned short autoframing
Definition: sip.h:1089
static int sip_debug_test_pvt(struct sip_pvt *p)
Test PVT for debugging output.
Definition: chan_sip.c:3649
#define ao2_replace(dst, src)
Definition: astobj2.h:517
void ast_rtp_codecs_payloads_unset(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, int payload)
Remove tx payload type mapped information.
Definition: rtp_engine.c:1433
#define TRUE
Definition: app_minivm.c:518
int ast_rtp_codecs_payloads_set_rtpmap_type_rate(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, int pt, char *mimetype, char *mimesubtype, enum ast_rtp_options options, unsigned int sample_rate)
Set tx payload type to a known MIME media type for a codec with a specific sample rate...
Definition: rtp_engine.c:1343
#define SIP_G726_NONSTANDARD
Definition: sip.h:310
struct ast_format * ast_format_parse_sdp_fmtp(const struct ast_format *format, const char *attributes)
This function is used to have a media format aware module parse and interpret SDP attribute informati...
Definition: format.c:286
static snd_pcm_format_t format
Definition: chan_alsa.c:102
#define SDP_MAX_RTPMAP_CODECS
Definition: sip.h:122
static struct test_val a

◆ process_sdp_a_dtls()

static int process_sdp_a_dtls ( const char *  a,
struct sip_pvt p,
struct ast_rtp_instance instance 
)
static

Definition at line 11505 of file chan_sip.c.

References ast_log, AST_RTP_DTLS_HASH_SHA1, AST_RTP_DTLS_HASH_SHA256, AST_RTP_DTLS_SETUP_ACTIVE, AST_RTP_DTLS_SETUP_ACTPASS, AST_RTP_DTLS_SETUP_HOLDCONN, AST_RTP_DTLS_SETUP_PASSIVE, ast_rtp_instance_get_dtls(), sip_pvt::callid, sip_pvt::dtls_cfg, ast_rtp_dtls_cfg::enabled, FALSE, LOG_WARNING, ast_rtp_engine_dtls::reset, ast_rtp_engine_dtls::set_fingerprint, ast_rtp_engine_dtls::set_setup, TRUE, and value.

Referenced by process_sdp().

11506 {
11507  struct ast_rtp_engine_dtls *dtls;
11508  int found = FALSE;
11509  char value[256], hash[32];
11510 
11511  if (!instance || !p->dtls_cfg.enabled || !(dtls = ast_rtp_instance_get_dtls(instance))) {
11512  return found;
11513  }
11514 
11515  if (sscanf(a, "setup: %255s", value) == 1) {
11516  found = TRUE;
11517 
11518  if (!strcasecmp(value, "active")) {
11519  dtls->set_setup(instance, AST_RTP_DTLS_SETUP_ACTIVE);
11520  } else if (!strcasecmp(value, "passive")) {
11521  dtls->set_setup(instance, AST_RTP_DTLS_SETUP_PASSIVE);
11522  } else if (!strcasecmp(value, "actpass")) {
11523  dtls->set_setup(instance, AST_RTP_DTLS_SETUP_ACTPASS);
11524  } else if (!strcasecmp(value, "holdconn")) {
11525  dtls->set_setup(instance, AST_RTP_DTLS_SETUP_HOLDCONN);
11526  } else {
11527  ast_log(LOG_WARNING, "Unsupported setup attribute value '%s' received on dialog '%s'\n",
11528  value, p->callid);
11529  }
11530  } else if (sscanf(a, "connection: %255s", value) == 1) {
11531  found = TRUE;
11532 
11533  if (!strcasecmp(value, "new")) {
11534  dtls->reset(instance);
11535  } else if (!strcasecmp(value, "existing")) {
11536  /* Since they want to just use what already exists we go on as if nothing happened */
11537  } else {
11538  ast_log(LOG_WARNING, "Unsupported connection attribute value '%s' received on dialog '%s'\n",
11539  value, p->callid);
11540  }
11541  } else if (sscanf(a, "fingerprint: %31s %255s", hash, value) == 2) {
11542  found = TRUE;
11543 
11544  if (!strcasecmp(hash, "sha-1")) {
11545  dtls->set_fingerprint(instance, AST_RTP_DTLS_HASH_SHA1, value);
11546  } else if (!strcasecmp(hash, "sha-256")) {
11547  dtls->set_fingerprint(instance, AST_RTP_DTLS_HASH_SHA256, value);
11548  } else {
11549  ast_log(LOG_WARNING, "Unsupported fingerprint hash type '%s' received on dialog '%s'\n",
11550  hash, p->callid);
11551  }
11552  }
11553 
11554  return found;
11555 }
#define FALSE
Definition: app_minivm.c:521
#define LOG_WARNING
Definition: logger.h:274
int value
Definition: syslog.c:37
struct ast_rtp_dtls_cfg dtls_cfg
Definition: sip.h:1222
#define ast_log
Definition: astobj2.c:42
void(* set_fingerprint)(struct ast_rtp_instance *instance, enum ast_rtp_dtls_hash hash, const char *fingerprint)
Definition: rtp_engine.h:586
Structure that represents the optional DTLS SRTP support within an RTP engine.
Definition: rtp_engine.h:570
unsigned int enabled
Definition: rtp_engine.h:555
const ast_string_field callid
Definition: sip.h:1063
struct ast_rtp_engine_dtls * ast_rtp_instance_get_dtls(struct ast_rtp_instance *instance)
Obtain a pointer to the DTLS support present on an RTP instance.
Definition: rtp_engine.c:3011
void(* reset)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:578
void(* set_setup)(struct ast_rtp_instance *instance, enum ast_rtp_dtls_setup setup)
Definition: rtp_engine.h:584
#define TRUE
Definition: app_minivm.c:518
static struct test_val a

◆ process_sdp_a_ice()

static int process_sdp_a_ice ( const char *  a,
struct sip_pvt p,
struct ast_rtp_instance instance,
int  rtcp_mux 
)
static

Definition at line 11432 of file chan_sip.c.

References ast_rtp_engine_ice::add_remote_candidate, ast_rtp_engine_ice_candidate::address, AST_RTP_ICE_CANDIDATE_TYPE_HOST, AST_RTP_ICE_CANDIDATE_TYPE_RELAYED, AST_RTP_ICE_CANDIDATE_TYPE_SRFLX, ast_rtp_instance_get_ice(), ast_sockaddr_parse(), ast_sockaddr_set_port, ast_strlen_zero, ast_test_flag, FALSE, sip_pvt::flags, ast_rtp_engine_ice_candidate::foundation, ast_rtp_engine_ice::ice_lite, ast_rtp_engine_ice_candidate::id, NULL, PARSE_PORT_FORBID, ast_rtp_engine_ice_candidate::priority, ast_rtp_engine_ice_candidate::relay_address, ast_rtp_engine_ice::set_authentication, SIP_PAGE3_RTCP_MUX, ast_rtp_engine_ice_candidate::transport, TRUE, and ast_rtp_engine_ice_candidate::type.

Referenced by process_sdp().

11433 {
11434  struct ast_rtp_engine_ice *ice;
11435  int found = FALSE;
11436  char ufrag[256], pwd[256], foundation[33], transport[4], address[46], cand_type[6], relay_address[46] = "";
11437  struct ast_rtp_engine_ice_candidate candidate = { 0, };
11438  unsigned int port, relay_port = 0;
11439 
11440  if (!instance || !(ice = ast_rtp_instance_get_ice(instance))) {
11441  return found;
11442  }
11443 
11444  if (sscanf(a, "ice-ufrag: %255s", ufrag) == 1) {
11445  ice->set_authentication(instance, ufrag, NULL);
11446  found = TRUE;
11447  } else if (sscanf(a, "ice-pwd: %255s", pwd) == 1) {
11448  ice->set_authentication(instance, NULL, pwd);
11449  found = TRUE;
11450  } else if (sscanf(a, "candidate: %32s %30u %3s %30u %23s %30u typ %5s %*s %23s %*s %30u", foundation, &candidate.id, transport, (unsigned *)&candidate.priority,
11451  address, &port, cand_type, relay_address, &relay_port) >= 7) {
11452 
11453  if (rtcp_mux_offered && ast_test_flag(&p->flags[2], SIP_PAGE3_RTCP_MUX) && candidate.id > 1) {
11454  /* If we support RTCP-MUX and they offered it, don't consider RTCP candidates */
11455  return TRUE;
11456  }
11457 
11458  candidate.foundation = foundation;
11459  candidate.transport = transport;
11460 
11461  ast_sockaddr_parse(&candidate.address, address, PARSE_PORT_FORBID);
11462  ast_sockaddr_set_port(&candidate.address, port);
11463 
11464  if (!strcasecmp(cand_type, "host")) {
11466  } else if (!strcasecmp(cand_type, "srflx")) {
11468  } else if (!strcasecmp(cand_type, "relay")) {
11470  } else {
11471  return found;
11472  }
11473 
11474  if (!ast_strlen_zero(relay_address)) {
11475  ast_sockaddr_parse(&candidate.relay_address, relay_address, PARSE_PORT_FORBID);
11476  }
11477 
11478  if (relay_port) {
11479  ast_sockaddr_set_port(&candidate.relay_address, relay_port);
11480  }
11481 
11482  ice->add_remote_candidate(instance, &candidate);
11483 
11484  found = TRUE;
11485  } else if (!strcasecmp(a, "ice-lite")) {
11486  ice->ice_lite(instance);
11487  found = TRUE;
11488  }
11489 
11490  return found;
11491 }
#define SIP_PAGE3_RTCP_MUX
Definition: sip.h:394
#define FALSE
Definition: app_minivm.c:521
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
#define ast_test_flag(p, flag)
Definition: utils.h:63
char * address
Definition: f2c.h:59
struct ast_rtp_engine_ice * ast_rtp_instance_get_ice(struct ast_rtp_instance *instance)
Obtain a pointer to the ICE support present on an RTP instance.
Definition: rtp_engine.c:2891
void(* add_remote_candidate)(struct ast_rtp_instance *instance, const struct ast_rtp_engine_ice_candidate *candidate)
Definition: rtp_engine.h:489
struct ast_flags flags[3]
Definition: sip.h:1075
#define NULL
Definition: resample.c:96
Structure for an ICE candidate.
Definition: rtp_engine.h:474
#define ast_strlen_zero(foo)
Definition: strings.h:52
enum ast_rtp_ice_candidate_type type
Definition: rtp_engine.h:481
struct ast_sockaddr relay_address
Definition: rtp_engine.h:480
void(* set_authentication)(struct ast_rtp_instance *instance, const char *ufrag, const char *password)
Definition: rtp_engine.h:487
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:537
enum ast_rtp_ice_component_type id
Definition: rtp_engine.h:476
#define TRUE
Definition: app_minivm.c:518
Structure that represents the optional ICE support within an RTP engine.
Definition: rtp_engine.h:485
struct ast_sockaddr address
Definition: rtp_engine.h:479
static struct test_val a
void(* ice_lite)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:501

◆ process_sdp_a_image()

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

Definition at line 11741 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, ast_control_t38_parameters::fill_bit_removal, initialize_udptl(), ast_control_t38_parameters::rate, ast_control_t38_parameters::rate_management, sip_pvt::t38, sip_pvt::t38_maxdatagram, t38properties::their_parms, ast_control_t38_parameters::transcoding_jbig, ast_control_t38_parameters::transcoding_mmr, TRUE, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_REDUNDANCY, and ast_control_t38_parameters::version.

Referenced by process_sdp().

11742 {
11743  int found = FALSE;
11744  char s[256];
11745  unsigned int x;
11746  char *attrib = ast_strdupa(a);
11747  char *pos;
11748 
11749  if (initialize_udptl(p)) {
11750  return found;
11751  }
11752 
11753  /* Due to a typo in an IANA registration of one of the T.38 attributes,
11754  * RFC5347 section 2.5.2 recommends that all T.38 attributes be parsed in
11755  * a case insensitive manner. Hence, the importance of proof reading (and
11756  * code reviews).
11757  */
11758  for (pos = attrib; *pos; ++pos) {
11759  *pos = tolower(*pos);
11760  }
11761 
11762  if ((sscanf(attrib, "t38faxmaxbuffer:%30u", &x) == 1)) {
11763  ast_debug(3, "MaxBufferSize:%u\n", x);
11764  found = TRUE;
11765  } else if ((sscanf(attrib, "t38maxbitrate:%30u", &x) == 1) || (sscanf(attrib, "t38faxmaxrate:%30u", &x) == 1)) {
11766  ast_debug(3, "T38MaxBitRate: %u\n", x);
11767  switch (x) {
11768  case 14400:
11770  break;
11771  case 12000:
11773  break;
11774  case 9600:
11776  break;
11777  case 7200:
11779  break;
11780  case 4800:
11782  break;
11783  case 2400:
11785  break;
11786  }
11787  found = TRUE;
11788  } else if ((sscanf(attrib, "t38faxversion:%30u", &x) == 1)) {
11789  ast_debug(3, "FaxVersion: %u\n", x);
11790  p->t38.their_parms.version = x;
11791  found = TRUE;
11792  } else if ((sscanf(attrib, "t38faxmaxdatagram:%30u", &x) == 1) || (sscanf(attrib, "t38maxdatagram:%30u", &x) == 1)) {
11793  /* override the supplied value if the configuration requests it */
11794  if (((signed int) p->t38_maxdatagram >= 0) && ((unsigned int) p->t38_maxdatagram > x)) {
11795  ast_debug(1, "Overriding T38FaxMaxDatagram '%u' with '%d'\n", x, p->t38_maxdatagram);
11796  x = p->t38_maxdatagram;
11797  }
11798  ast_debug(3, "FaxMaxDatagram: %u\n", x);
11800  found = TRUE;
11801  } else if ((strncmp(attrib, "t38faxfillbitremoval", sizeof("t38faxfillbitremoval") - 1) == 0)) {
11802  if (sscanf(attrib, "t38faxfillbitremoval:%30u", &x) == 1) {
11803  ast_debug(3, "FillBitRemoval: %u\n", x);
11804  if (x == 1) {
11806  }
11807  } else {
11808  ast_debug(3, "FillBitRemoval\n");
11810  }
11811  found = TRUE;
11812  } else if ((strncmp(attrib, "t38faxtranscodingmmr", sizeof("t38faxtranscodingmmr") - 1) == 0)) {
11813  if (sscanf(attrib, "t38faxtranscodingmmr:%30u", &x) == 1) {
11814  ast_debug(3, "Transcoding MMR: %u\n", x);
11815  if (x == 1) {
11817  }
11818  } else {
11819  ast_debug(3, "Transcoding MMR\n");
11821  }
11822  found = TRUE;
11823  } else if ((strncmp(attrib, "t38faxtranscodingjbig", sizeof("t38faxtranscodingjbig") - 1) == 0)) {
11824  if (sscanf(attrib, "t38faxtranscodingjbig:%30u", &x) == 1) {
11825  ast_debug(3, "Transcoding JBIG: %u\n", x);
11826  if (x == 1) {
11828  }
11829  } else {
11830  ast_debug(3, "Transcoding JBIG\n");
11832  }
11833  found = TRUE;
11834  } else if ((sscanf(attrib, "t38faxratemanagement:%255s", s) == 1)) {
11835  ast_debug(3, "RateManagement: %s\n", s);
11836  if (!strcasecmp(s, "localTCF"))
11838  else if (!strcasecmp(s, "transferredTCF"))
11840  found = TRUE;
11841  } else if ((sscanf(attrib, "t38faxudpec:%255s", s) == 1)) {
11842  ast_debug(3, "UDP EC: %s\n", s);
11843  if (!strcasecmp(s, "t38UDPRedundancy")) {
11845  } else if (!strcasecmp(s, "t38UDPFEC")) {
11847  } else {
11849  }
11850  found = TRUE;
11851  }
11852 
11853  return found;
11854 }
#define FALSE
Definition: app_minivm.c:521
int t38_maxdatagram
Definition: sip.h:1107
void ast_udptl_set_far_max_datagram(struct ast_udptl *udptl, unsigned int max_datagram)
sets far max datagram size. If max_datagram is = 0, the far max datagram size is set to a default val...
Definition: udptl.c:997
struct t38properties t38
Definition: sip.h:1113
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static int initialize_udptl(struct sip_pvt *p)
Definition: chan_sip.c:7862
enum ast_control_t38_rate rate
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
struct ast_udptl * udptl
Definition: sip.h:1115
struct ast_control_t38_parameters their_parms
Definition: sip.h:919
void ast_udptl_set_error_correction_scheme(struct ast_udptl *udptl, enum ast_t38_ec_modes ec)
Definition: udptl.c:945
#define TRUE
Definition: app_minivm.c:518
enum ast_control_t38_rate_management rate_management
static struct test_val a

◆ process_sdp_a_rtcp_mux()

static int process_sdp_a_rtcp_mux ( const char *  a,
struct sip_pvt p,
int *  requested 
)
static

Definition at line 11493 of file chan_sip.c.

References FALSE, and TRUE.

Referenced by process_sdp().

11494 {
11495  int found = FALSE;
11496 
11497  if (!strncasecmp(a, "rtcp-mux", 8)) {
11498  *requested = TRUE;
11499  found = TRUE;
11500  }
11501 
11502  return found;
11503 }
#define FALSE
Definition: app_minivm.c:521
#define TRUE
Definition: app_minivm.c:518
static struct test_val a

◆ process_sdp_a_sendonly()

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

Definition at line 11412 of file chan_sip.c.

References FALSE, and TRUE.

Referenced by process_sdp().

11413 {
11414  int found = FALSE;
11415 
11416  if (!strcasecmp(a, "sendonly")) {
11417  if (*sendonly == -1)
11418  *sendonly = 1;
11419  found = TRUE;
11420  } else if (!strcasecmp(a, "inactive")) {
11421  if (*sendonly == -1)
11422  *sendonly = 2;
11423  found = TRUE;
11424  } else if (!strcasecmp(a, "sendrecv")) {
11425  if (*sendonly == -1)
11426  *sendonly = 0;
11427  found = TRUE;
11428  }
11429  return found;
11430 }
#define FALSE
Definition: app_minivm.c:521
#define TRUE
Definition: app_minivm.c:518
static struct test_val a

◆ process_sdp_a_text()

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

References AST_RED_MAX_GENERATION, ast_rtp_codecs_payloads_set_rtpmap_type_rate(), ast_verbose(), debug, FALSE, NULL, SDP_MAX_RTPMAP_CODECS, sip_debug_test_pvt(), sip_pvt::trtp, and TRUE.

Referenced by process_sdp().

11692 {
11693  int found = FALSE;
11694  unsigned int codec;
11695  char mimeSubtype[128];
11696  unsigned int sample_rate;
11697  char *red_cp;
11698  int debug = sip_debug_test_pvt(p);
11699 
11700  if (sscanf(a, "rtpmap: %30u %127[^/]/%30u", &codec, mimeSubtype, &sample_rate) == 3) {
11701  /* We have a rtpmap to handle */
11702  if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) {
11703  if (!strncasecmp(mimeSubtype, "T140", 4)) { /* Text */
11704  if (p->trtp) {
11705  /* ast_verbose("Adding t140 mimeSubtype to textrtp struct\n"); */
11706  ast_rtp_codecs_payloads_set_rtpmap_type_rate(newtextrtp, NULL, codec, "text", mimeSubtype, 0, sample_rate);
11707  found = TRUE;
11708  }
11709  } else if (!strncasecmp(mimeSubtype, "RED", 3)) { /* Text with Redudancy */
11710  if (p->trtp) {
11711  ast_rtp_codecs_payloads_set_rtpmap_type_rate(newtextrtp, NULL, codec, "text", mimeSubtype, 0, sample_rate);
11712  sprintf(red_fmtp, "fmtp:%u ", codec);
11713  if (debug)
11714  ast_verbose("RED submimetype has payload type: %u\n", codec);
11715  found = TRUE;
11716  }
11717  }
11718  } else {
11719  if (debug)
11720  ast_verbose("Discarded description format %s for ID %u\n", mimeSubtype, codec);
11721  }
11722  } else if (!strncmp(a, red_fmtp, strlen(red_fmtp))) {
11723  char *rest = NULL;
11724  /* count numbers of generations in fmtp */
11725  red_cp = &red_fmtp[strlen(red_fmtp)];
11726  strncpy(red_fmtp, a, 100);
11727 
11728  sscanf(red_cp, "%30u", (unsigned *)&red_data_pt[*red_num_gen]);
11729  red_cp = strtok_r(red_cp, "/", &rest);
11730  while (red_cp && (*red_num_gen)++ < AST_RED_MAX_GENERATION) {
11731  sscanf(red_cp, "%30u", (unsigned *)&red_data_pt[*red_num_gen]);
11732  red_cp = strtok_r(NULL, "/", &rest);
11733  }
11734  red_cp = red_fmtp;
11735  found = TRUE;
11736  }
11737 
11738  return found;
11739 }
#define FALSE
Definition: app_minivm.c:521
struct ast_rtp_instance * trtp
Definition: sip.h:1176
static int debug
Global debug status.
Definition: res_xmpp.c:435
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
#define NULL
Definition: resample.c:96
#define AST_RED_MAX_GENERATION
Definition: rtp_engine.h:98
static int sip_debug_test_pvt(struct sip_pvt *p)
Test PVT for debugging output.
Definition: chan_sip.c:3649
#define TRUE
Definition: app_minivm.c:518
int ast_rtp_codecs_payloads_set_rtpmap_type_rate(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, int pt, char *mimetype, char *mimesubtype, enum ast_rtp_options options, unsigned int sample_rate)
Set tx payload type to a known MIME media type for a codec with a specific sample rate...
Definition: rtp_engine.c:1343
#define SDP_MAX_RTPMAP_CODECS
Definition: sip.h:122
static struct test_val a

◆ process_sdp_a_video()

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

References ao2_ref, ao2_replace, ast_format_parse_sdp_fmtp(), ast_rtp_codecs_get_payload_format(), ast_rtp_codecs_payload_replace_format(), ast_rtp_codecs_payloads_set_rtpmap_type_rate(), ast_rtp_codecs_payloads_unset(), ast_verbose(), debug, FALSE, format, NULL, SDP_MAX_RTPMAP_CODECS, sip_debug_test_pvt(), and TRUE.

Referenced by process_sdp().

11638 {
11639  int found = FALSE;
11640  unsigned int codec;
11641  char mimeSubtype[128];
11642  unsigned int sample_rate;
11643  int debug = sip_debug_test_pvt(p);
11644  char fmtp_string[256];
11645 
11646  if (sscanf(a, "rtpmap: %30u %127[^/]/%30u", &codec, mimeSubtype, &sample_rate) == 3) {
11647  /* We have a rtpmap to handle */
11648  if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) {
11649  /* Note: should really look at the '#chans' params too */
11650  if (!strncasecmp(mimeSubtype, "H26", 3) || !strncasecmp(mimeSubtype, "MP4", 3)
11651  || !strncasecmp(mimeSubtype, "VP8", 3)) {
11652  if (!(ast_rtp_codecs_payloads_set_rtpmap_type_rate(newvideortp, NULL, codec, "video", mimeSubtype, 0, sample_rate))) {
11653  if (debug)
11654  ast_verbose("Found video description format %s for ID %u\n", mimeSubtype, codec);
11655  //found_rtpmap_codecs[last_rtpmap_codec] = codec;
11656  (*last_rtpmap_codec)++;
11657  found = TRUE;
11658  } else {
11659  ast_rtp_codecs_payloads_unset(newvideortp, NULL, codec);
11660  if (debug)
11661  ast_verbose("Found unknown media description format %s for ID %u\n", mimeSubtype, codec);
11662  }
11663  }
11664  } else {
11665  if (debug)
11666  ast_verbose("Discarded description format %s for ID %u\n", mimeSubtype, codec);
11667  }
11668  } else if (sscanf(a, "fmtp: %30u %255[^\t\n]", &codec, fmtp_string) == 2) {
11669  struct ast_format *format;
11670 
11671  if ((format = ast_rtp_codecs_get_payload_format(newvideortp, codec))) {
11672  struct ast_format *format_parsed;
11673 
11674  format_parsed = ast_format_parse_sdp_fmtp(format, fmtp_string);
11675 
11676  if (format_parsed) {
11677  ast_rtp_codecs_payload_replace_format(newvideortp, codec, format_parsed);
11678  ao2_replace(format, format_parsed);
11679  ao2_ref(format_parsed, -1);
11680  found = TRUE;
11681  } else {
11682  ast_rtp_codecs_payloads_unset(newvideortp, NULL, codec);
11683  }
11684  ao2_ref(format, -1);
11685  }
11686  }
11687 
11688  return found;
11689 }
#define FALSE
Definition: app_minivm.c:521
int ast_rtp_codecs_payload_replace_format(struct ast_rtp_codecs *codecs, int payload, struct ast_format *format)
Update the format associated with a tx payload type in a codecs structure.
Definition: rtp_engine.c:1503
static int debug
Global debug status.
Definition: res_xmpp.c:435
Definition of a media format.
Definition: format.c:43
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
#define NULL
Definition: resample.c:96
struct ast_format * ast_rtp_codecs_get_payload_format(struct ast_rtp_codecs *codecs, int payload)
Retrieve the actual ast_format stored on the codecs structure for a specific tx payload type...
Definition: rtp_engine.c:1537
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static int sip_debug_test_pvt(struct sip_pvt *p)
Test PVT for debugging output.
Definition: chan_sip.c:3649
#define ao2_replace(dst, src)
Definition: astobj2.h:517
void ast_rtp_codecs_payloads_unset(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, int payload)
Remove tx payload type mapped information.
Definition: rtp_engine.c:1433
#define TRUE
Definition: app_minivm.c:518
int ast_rtp_codecs_payloads_set_rtpmap_type_rate(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, int pt, char *mimetype, char *mimesubtype, enum ast_rtp_options options, unsigned int sample_rate)
Set tx payload type to a known MIME media type for a codec with a specific sample rate...
Definition: rtp_engine.c:1343
struct ast_format * ast_format_parse_sdp_fmtp(const struct ast_format *format, const char *attributes)
This function is used to have a media format aware module parse and interpret SDP attribute informati...
Definition: format.c:286
static snd_pcm_format_t format
Definition: chan_alsa.c:102
#define SDP_MAX_RTPMAP_CODECS
Definition: sip.h:122
static struct test_val a

◆ process_sdp_c()

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

Definition at line 11385 of file chan_sip.c.

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

Referenced by process_sdp().

11386 {
11387  char proto[4], host[258];
11388  int af;
11389 
11390  /* Check for Media-description-level-address */
11391  if (sscanf(c, "IN %3s %255s", proto, host) == 2) {
11392  if (!strcmp("IP4", proto)) {
11393  af = AF_INET;
11394  } else if (!strcmp("IP6", proto)) {
11395  af = AF_INET6;
11396  } else {
11397  ast_log(LOG_WARNING, "Unknown protocol '%s'.\n", proto);
11398  return FALSE;
11399  }
11400  if (ast_sockaddr_resolve_first_af(addr, host, 0, af)) {
11401  ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in c= line, '%s'\n", c);
11402  return FALSE;
11403  }
11404  return TRUE;
11405  } else {
11406  ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c);
11407  return FALSE;
11408  }
11409  return FALSE;
11410 }
#define FALSE
Definition: app_minivm.c:521
#define LOG_WARNING
Definition: logger.h:274
static struct test_val c
#define ast_log
Definition: astobj2.c:42
static char host[256]
Definition: muted.c:77
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.
Definition: netsock2.c:337
#define TRUE
Definition: app_minivm.c:518

◆ process_sdp_o()

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

Definition at line 11278 of file chan_sip.c.

References ast_copy_string(), ast_debug, ast_log, ast_strdupa, ast_string_field_set, ast_strlen_zero, ast_test_flag, ast_verbose(), sip_pvt::callid, FALSE, sip_pvt::flags, LOG_WARNING, S_OR, sip_pvt::session_modify, sip_pvt::sessionunique_remote, sip_pvt::sessionversion_remote, sip_debug_test_pvt(), SIP_PAGE2_IGNORESDPVERSION, t38properties::state, strsep(), sip_pvt::t38, T38_LOCAL_REINVITE, and TRUE.

Referenced by process_sdp().

11279 {
11280  const char *o_copy_start;
11281  char *o_copy;
11282  char *token;
11283  int offset;
11284  int64_t sess_version;
11285  char unique[128];
11286 
11287  /* Store the SDP version number of remote UA. This will allow us to
11288  distinguish between session modifications and session refreshes. If
11289  the remote UA does not send an incremented SDP version number in a
11290  subsequent RE-INVITE then that means its not changing media session.
11291  The RE-INVITE may have been sent to update connected party, remote
11292  target or to refresh the session (Session-Timers). Asterisk must not
11293  change media session and increment its own version number in answer
11294  SDP in this case. */
11295 
11296  p->session_modify = TRUE;
11297 
11298  if (ast_strlen_zero(o)) {
11299  ast_log(LOG_WARNING, "SDP syntax error. SDP without an o= line\n");
11300  return FALSE;
11301  }
11302 
11303  /* o=<username> <sess-id> <sess-version> <nettype> <addrtype>
11304  <unicast-address> */
11305 
11306  o_copy_start = o_copy = ast_strdupa(o);
11307  token = strsep(&o_copy, " "); /* Skip username */
11308  if (!o_copy) {
11309  ast_log(LOG_WARNING, "SDP syntax error in o= line username\n");
11310  return FALSE;
11311  }
11312  token = strsep(&o_copy, " "); /* sess-id */
11313  if (!o_copy) {
11314  ast_log(LOG_WARNING, "SDP syntax error in o= line sess-id\n");
11315  return FALSE;
11316  }
11317  token = strsep(&o_copy, " "); /* sess-version */
11318  if (!o_copy || !sscanf(token, "%30" SCNd64, &sess_version)) {
11319  ast_log(LOG_WARNING, "SDP syntax error in o= line sess-version\n");
11320  return FALSE;
11321  }
11322 
11323  /* Copy all after sess-version on top of sess-version into unique.
11324  * <sess-id> is a numeric string such that the tuple of <username>,
11325  * <sess-id>, <nettype>, <addrtype>, and <unicast-address> forms a
11326  * globally unique identifier for the session.
11327  * I.e. all except the <sess-version> */
11328  ast_copy_string(unique, o, sizeof(unique)); /* copy all of o= contents */
11329  offset = (o_copy - o_copy_start); /* after sess-version */
11330  if (offset < sizeof(unique)) {
11331  /* copy all after sess-version on top of sess-version */
11332  int sess_version_start = token - o_copy_start;
11333  ast_copy_string(unique + sess_version_start, o + offset, sizeof(unique) - sess_version_start);
11334  }
11335 
11336  /* We need to check the SDP version number the other end sent us;
11337  * our rules for deciding what to accept are a bit complex.
11338  *
11339  * 1) if 'ignoresdpversion' has been set for this dialog, then
11340  * we will just accept whatever they sent and assume it is
11341  * a modification of the session, even if it is not
11342  * 2) otherwise, if this is the first SDP we've seen from them
11343  * we accept it;
11344  * note that _them_ may change, in which case the
11345  * sessionunique_remote will be different
11346  * 3) otherwise, if the new SDP version number is higher than the
11347  * old one, we accept it
11348  * 4) otherwise, if this SDP is in response to us requesting a switch
11349  * to T.38, we accept the SDP, but also generate a warning message
11350  * that this peer should have the 'ignoresdpversion' option set,
11351  * because it is not following the SDP offer/answer RFC; if we did
11352  * not request a switch to T.38, then we stop parsing the SDP, as it
11353  * has not changed from the previous version
11354  */
11355  if (sip_debug_test_pvt(p)) {
11357  ast_verbose("Got SDP version %" PRId64 " and unique parts [%s]\n",
11358  sess_version, unique);
11359  } else {
11360  ast_verbose("Comparing SDP version %" PRId64 " -> %" PRId64 " and unique parts [%s] -> [%s]\n",
11361  p->sessionversion_remote, sess_version, p->sessionunique_remote, unique);
11362  }
11363  }
11364 
11366  sess_version > p->sessionversion_remote ||
11367  strcmp(unique, S_OR(p->sessionunique_remote, ""))) {
11368  p->sessionversion_remote = sess_version;
11369  ast_string_field_set(p, sessionunique_remote, unique);
11370  } else {
11371  if (p->t38.state == T38_LOCAL_REINVITE) {
11372  p->sessionversion_remote = sess_version;
11373  ast_string_field_set(p, sessionunique_remote, unique);
11374  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);
11375  } else {
11376  p->session_modify = FALSE;
11377  ast_debug(2, "Call %s responded to our reinvite without changing SDP version; ignoring SDP.\n", p->callid);
11378  return FALSE;
11379  }
11380  }
11381 
11382  return TRUE;
11383 }
#define FALSE
Definition: app_minivm.c:521
int64_t sessionversion_remote
Definition: sip.h:1123
enum t38state state
Definition: sip.h:917
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define LOG_WARNING
Definition: logger.h:274
struct ast_flags flags[3]
Definition: sip.h:1075
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
struct t38properties t38
Definition: sip.h:1113
const ast_string_field sessionunique_remote
Definition: sip.h:1063
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define SIP_PAGE2_IGNORESDPVERSION
Definition: sip.h:344
const ast_string_field callid
Definition: sip.h:1063
static int sip_debug_test_pvt(struct sip_pvt *p)
Test PVT for debugging output.
Definition: chan_sip.c:3649
char * strsep(char **str, const char *delims)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
#define TRUE
Definition: app_minivm.c:518
unsigned short session_modify
Definition: sip.h:1087
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ process_via()

static int process_via ( struct sip_pvt p,
const struct sip_request req 
)
static

Process the Via header according to RFC 3261 section 18.2.2.

Parameters
pa sip_pvt structure that will be modified according to the received header
reqa 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 address the request came from in the respprep() function).

Return values
-1error
0success

Definition at line 9117 of file chan_sip.c.

References ast_log, ast_sockaddr_is_ipv4_multicast(), ast_sockaddr_resolve_first_transport(), ast_sockaddr_set_port, free_via(), LOG_ERROR, LOG_WARNING, sip_via::maddr, PARSE_PORT_FORBID, parse_via(), sip_via::port, sip_pvt::sa, sip_get_header(), sipsock, sip_pvt::socket, STANDARD_SIP_PORT, sip_via::ttl, and sip_socket::type.

Referenced by respprep().

9118 {
9119  struct sip_via *via = parse_via(sip_get_header(req, "Via"));
9120 
9121  if (!via) {
9122  ast_log(LOG_ERROR, "error processing via header\n");
9123  return -1;
9124  }
9125 
9126  if (via->maddr) {
9128  ast_log(LOG_WARNING, "Can't find address for maddr '%s'\n", via->maddr);
9129  ast_log(LOG_ERROR, "error processing via header\n");
9130  free_via(via);
9131  return -1;
9132  }
9133 
9135  setsockopt(sipsock, IPPROTO_IP, IP_MULTICAST_TTL, &via->ttl, sizeof(via->ttl));
9136  }
9137  }
9138 
9139  ast_sockaddr_set_port(&p->sa, via->port ? via->port : STANDARD_SIP_PORT);
9140 
9141  free_via(via);
9142  return 0;
9143 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
void free_via(struct sip_via *v)
const char * maddr
Definition: sip.h:879
#define LOG_WARNING
Definition: logger.h:274
struct sip_socket socket
Definition: sip.h:1066
unsigned char ttl
Definition: sip.h:881
Structure to store Via information.
Definition: sip.h:874
struct ast_sockaddr sa
Definition: sip.h:1125
#define ast_log
Definition: astobj2.c:42
#define STANDARD_SIP_PORT
Standard SIP unsecure port for UDP and TCP from RFC 3261. DO NOT CHANGE THIS.
Definition: sip.h:176
char * via
Definition: sip.h:875
#define LOG_ERROR
Definition: logger.h:285
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:537
int ast_sockaddr_is_ipv4_multicast(const struct ast_sockaddr *addr)
Determine if an IPv4 address is a multicast address.
Definition: netsock2.c:513
static int sipsock
Main socket for UDP SIP communication.
Definition: chan_sip.c:1104
unsigned int port
Definition: sip.h:880
enum ast_transport type
Definition: sip.h:798
struct sip_via * parse_via(const char *header)
Parse a Via header.
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. ...
Definition: chan_sip.c:34479

◆ proxy_from_config()

static struct sip_proxy* proxy_from_config ( const char *  proxy,
int  sipconf_lineno,
struct sip_proxy dest 
)
static

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

References ao2_alloc, ao2_ref, ast_copy_string(), ast_log, ast_skip_blanks(), ast_strdupa, ast_strlen_zero, FALSE, sip_proxy::force, LOG_WARNING, name, sip_proxy::name, NULL, sip_proxy::port, proxy_update(), sip_parse_host(), and sip_proxy::transport.

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

3492 {
3493  char *mutable_proxy, *sep, *name;
3494  int allocated = 0;
3495 
3496  if (!dest) {
3497  dest = ao2_alloc(sizeof(struct sip_proxy), NULL);
3498  if (!dest) {
3499  ast_log(LOG_WARNING, "Unable to allocate config storage for proxy\n");
3500  return NULL;
3501  }
3502  allocated = 1;
3503  }
3504 
3505  /* Format is: [transport://]name[:port][,force] */
3506  mutable_proxy = ast_skip_blanks(ast_strdupa(proxy));
3507  sep = strchr(mutable_proxy, ',');
3508  if (sep) {
3509  *sep++ = '\0';
3510  dest->force = !strncasecmp(ast_skip_blanks(sep), "force", 5);
3511  } else {
3512  dest->force = FALSE;
3513  }
3514 
3515  sip_parse_host(mutable_proxy, sipconf_lineno, &name, &dest->port, &dest->transport);
3516 
3517  /* Check that there is a name at all */
3518  if (ast_strlen_zero(name)) {
3519  if (allocated) {
3520  ao2_ref(dest, -1);
3521  } else {
3522  dest->name[0] = '\0';
3523  }
3524  return NULL;
3525  }
3526  ast_copy_string(dest->name, name, sizeof(dest->name));
3527 
3528  /* Resolve host immediately */
3529  proxy_update(dest);
3530 
3531  return dest;
3532 }
int force
Definition: sip.h:727
#define FALSE
Definition: app_minivm.c:521
definition of a sip proxy server
Definition: sip.h:721
#define LOG_WARNING
Definition: logger.h:274
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
static int proxy_update(struct sip_proxy *proxy)
Definition: chan_sip.c:3467
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
char name[MAXHOSTNAMELEN]
Definition: sip.h:722
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
static const char name[]
Definition: cdr_mysql.c:74
int port
Definition: sip.h:724
int sip_parse_host(char *line, int lineno, char **hostname, int *portnum, enum ast_transport *transport)
parses a config line for a host with a transport
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
enum ast_transport transport
Definition: sip.h:726

◆ proxy_update()

static int proxy_update ( struct sip_proxy proxy)
static

Resolve DNS srv name or host name in a sip_proxy structure

Definition at line 3467 of file chan_sip.c.

References ast_get_ip_or_srv(), ast_log, ast_sockaddr_parse(), ast_sockaddr_set_port, AST_TRANSPORT_UDP, FALSE, get_address_family_filter(), sip_proxy::ip, sip_proxy::last_dnsupdate, LOG_WARNING, sip_proxy::name, NULL, sip_proxy::port, sip_cfg, sip_settings::srvlookup, ast_sockaddr::ss, and TRUE.

Referenced by proxy_from_config().

3468 {
3469  /* if it's actually an IP address and not a name,
3470  there's no need for a managed lookup */
3471  if (!ast_sockaddr_parse(&proxy->ip, proxy->name, 0)) {
3472  /* Ok, not an IP address, then let's check if it's a domain or host */
3473  /* XXX Todo - if we have proxy port, don't do SRV */
3474  proxy->ip.ss.ss_family = get_address_family_filter(AST_TRANSPORT_UDP); /* Filter address family */
3475  if (ast_get_ip_or_srv(&proxy->ip, proxy->name, sip_cfg.srvlookup ? "_sip._udp" : NULL) < 0) {
3476  ast_log(LOG_WARNING, "Unable to locate host '%s'\n", proxy->name);
3477  return FALSE;
3478  }
3479 
3480  }
3481 
3482  ast_sockaddr_set_port(&proxy->ip, proxy->port);
3483 
3484  proxy->last_dnsupdate = time(NULL);
3485  return TRUE;
3486 }
struct sockaddr_storage ss
Definition: netsock2.h:98
#define FALSE
Definition: app_minivm.c:521
time_t last_dnsupdate
Definition: sip.h:725
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
static int get_address_family_filter(unsigned int transport)
Helper for dns resolution to filter by address family.
Definition: chan_sip.c:29558
#define LOG_WARNING
Definition: logger.h:274
int srvlookup
Definition: sip.h:758
#define NULL
Definition: resample.c:96
struct ast_sockaddr ip
Definition: sip.h:723
#define ast_log
Definition: astobj2.c:42
char name[MAXHOSTNAMELEN]
Definition: sip.h:722
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:537
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
int port
Definition: sip.h:724
int ast_get_ip_or_srv(struct ast_sockaddr *addr, const char *hostname, const char *service)
Get the IP address given a hostname and optional service.
Definition: acl.c:897
#define TRUE
Definition: app_minivm.c:518

◆ publish_expire()

static int publish_expire ( const void *  data)
static

Definition at line 1764 of file chan_sip.c.

References ao2_ref, ao2_unlink, ast_assert, event_state_compositor::compositor, sip_esc_entry::event, get_esc(), NULL, and sip_esc_entry::sched_id.

Referenced by create_esc_entry(), handle_sip_publish_modify(), and handle_sip_publish_refresh().

1765 {
1766  struct sip_esc_entry *esc_entry = (struct sip_esc_entry *) data;
1767  struct event_state_compositor *esc = get_esc(esc_entry->event);
1768 
1769  ast_assert(esc != NULL);
1770 
1771  ao2_unlink(esc->compositor, esc_entry);
1772  esc_entry->sched_id = -1;
1773  ao2_ref(esc_entry, -1);
1774  return 0;
1775 }
int sched_id
Definition: sip.h:1750
The Event State Compositors.
Definition: chan_sip.c:996
#define ast_assert(a)
Definition: utils.h:695
#define NULL
Definition: resample.c:96
common ESC items for all event types
Definition: sip.h:1715
static struct event_state_compositor * get_esc(const char *const event_package)
Definition: chan_sip.c:1743
#define ao2_ref(o, delta)
Definition: astobj2.h:464
const char * event
Definition: sip.h:1734
#define ao2_unlink(container, obj)
Definition: astobj2.h:1598
struct ao2_container * compositor
Definition: chan_sip.c:1000

◆ publish_qualify_peer_done()

static void publish_qualify_peer_done ( const char *  id,
const char *  peer 
)
static

Definition at line 21067 of file chan_sip.c.

References ast_json_pack(), ast_json_unref(), ast_manager_publish_event(), ast_strlen_zero, EVENT_FLAG_CALL, NULL, and RAII_VAR.

Referenced by _sip_qualify_peer().

21068 {
21069  RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
21070 
21071  if (ast_strlen_zero(id)) {
21072  body = ast_json_pack("{s: s}", "Peer", peer);
21073  } else {
21074  body = ast_json_pack("{s: s, s: s}", "Peer", peer, "ActionID", id);
21075  }
21076  if (!body) {
21077  return;
21078  }
21079 
21080  ast_manager_publish_event("SIPQualifyPeerDone", EVENT_FLAG_CALL, body);
21081 }
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
#define EVENT_FLAG_CALL
Definition: manager.h:72
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
Abstract JSON element (object, array, string, int, ...).
void ast_manager_publish_event(const char *type, int class_type, struct ast_json *obj)
Publish an event to AMI.
Definition: manager.c:1903

◆ pvt_set_needdestroy()

static void pvt_set_needdestroy ( struct sip_pvt pvt,
const char *  reason 
)
inlinestatic

Definition at line 3429 of file chan_sip.c.

References ao2_t_link, append_history, sip_pvt::final_destruction_scheduled, and sip_pvt::needdestroy.

Referenced by __sip_autodestruct(), forked_invite_init(), handle_incoming(), handle_request_publish(), handle_request_refer(), handle_request_subscribe(), handle_response(), handle_response_invite(), handle_response_message(), 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().

3430 {
3431  if (pvt->final_destruction_scheduled) {
3432  return; /* This is already scheduled for final destruction, let the scheduler take care of it. */
3433  }
3434  append_history(pvt, "NeedDestroy", "Setting needdestroy because %s", reason);
3435  if (!pvt->needdestroy) {
3436  pvt->needdestroy = 1;
3437  ao2_t_link(dialogs_needdestroy, pvt, "link pvt into dialogs_needdestroy container");
3438  }
3439 }
struct ao2_container * dialogs_needdestroy
Definition: chan_sip.c:1024
unsigned short needdestroy
Definition: sip.h:1080
#define ao2_t_link(container, obj, tag)
Add an object to a container.
Definition: astobj2.h:1547
unsigned short final_destruction_scheduled
Definition: sip.h:1081
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406

◆ read_raw_content_length()

static int read_raw_content_length ( const char *  message)
static

Get the content length from an unparsed SIP message.

Parameters
messageThe unparsed SIP message headers
Returns
The value of the Content-Length header or -1 if message is invalid

Definition at line 2789 of file chan_sip.c.

References ast_free, ast_str_buffer(), ast_str_create, ast_str_set(), done, lws2sws(), sip_settings::pedanticsipchecking, sip_cfg, and strcasestr().

Referenced by check_message_integrity().

2790 {
2791  char *content_length_str;
2792  int content_length = -1;
2793 
2794  struct ast_str *msg_copy;
2795  char *msg;
2796 
2797  /* Using a ast_str because lws2sws takes one of those */
2798  if (!(msg_copy = ast_str_create(strlen(message) + 1))) {
2799  return -1;
2800  }
2801  ast_str_set(&msg_copy, 0, "%s", message);
2802 
2804  lws2sws(msg_copy);
2805  }
2806 
2807  msg = ast_str_buffer(msg_copy);
2808 
2809  /* Let's find a Content-Length header */
2810  if ((content_length_str = strcasestr(msg, "\nContent-Length:"))) {
2811  content_length_str += sizeof("\nContent-Length:") - 1;
2812  } else if ((content_length_str = strcasestr(msg, "\nl:"))) {
2813  content_length_str += sizeof("\nl:") - 1;
2814  } else {
2815  /* RFC 3261 18.3
2816  * "In the case of stream-oriented transports such as TCP, the Content-
2817  * Length header field indicates the size of the body. The Content-
2818  * Length header field MUST be used with stream oriented transports."
2819  */
2820  goto done;
2821  }
2822 
2823  /* Double-check that this is a complete header */
2824  if (!strchr(content_length_str, '\n')) {
2825  goto done;
2826  }
2827 
2828  if (sscanf(content_length_str, "%30d", &content_length) != 1) {
2829  content_length = -1;
2830  }
2831 
2832 done:
2833  ast_free(msg_copy);
2834  return content_length;
2835 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
int done
Definition: test_amihooks.c:48
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
static void lws2sws(struct ast_str *msgbuf)
Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled...
Definition: chan_sip.c:9894
int pedanticsipchecking
Definition: sip.h:756
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
char * strcasestr(const char *, const char *)
#define ast_free(a)
Definition: astmm.h:182
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ realtime_peer()

static struct sip_peer * realtime_peer ( const char *  newpeername,
struct ast_sockaddr addr,
char *  callbackexten,
int  devstate_only,
int  which_objects 
)
static

realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf Checks the "sipregs" realtime family from extconfig.conf if it's configured. This returns a pointer to a peer and because we use build_peer, we can rest assured that the refcount is bumped.

Note
This is never called with both newpeername and addr at the same time. If you do, be prepared to get a peer with a different name than newpeername.

Definition at line 5685 of file chan_sip.c.

References sip_peer::addr, 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(), sip_peer::expire, expire_register(), FINDPEERS, FINDUSERS, sip_peer::flags, ipaddr, sip_peer::is_realtime, ast_variable::name, sip_peer::name, ast_variable::next, NULL, realtime_peer_by_addr(), realtime_peer_by_name(), rpeerobjs, sip_settings::rtautoclear, sip_cfg, SIP_PAGE2_RTAUTOCLEAR, SIP_PAGE2_RTCACHEFRIENDS, sip_ref_peer, SIP_TYPE_PEER, SIP_TYPE_USER, sip_unref_peer, tmp(), TRUE, sip_peer::type, ast_variable::value, and var.

Referenced by sip_find_peer_full().

5686 {
5687  struct sip_peer *peer = NULL;
5688  struct ast_variable *var = NULL;
5689  struct ast_variable *varregs = NULL;
5690  char ipaddr[INET6_ADDRSTRLEN];
5691  int realtimeregs = ast_check_realtime("sipregs");
5692 
5693  if (addr) {
5694  ast_copy_string(ipaddr, ast_sockaddr_stringify_addr(addr), sizeof(ipaddr));
5695  } else {
5696  ipaddr[0] = '\0';
5697  }
5698 
5699  if (newpeername && realtime_peer_by_name(&newpeername, addr, ipaddr, &var, realtimeregs ? &varregs : NULL)) {
5700  ;
5701  } else if (addr && realtime_peer_by_addr(&newpeername, addr, ipaddr, callbackexten, &var, realtimeregs ? &varregs : NULL)) {
5702  ;
5703  } else {
5704  return NULL;
5705  }
5706 
5707  /* If we're looking for users, don't return peers (although this check
5708  * should probably be done in realtime_peer_by_* instead...) */
5709  if (which_objects == FINDUSERS) {
5710  struct ast_variable *tmp;
5711  for (tmp = var; tmp; tmp = tmp->next) {
5712  if (!strcasecmp(tmp->name, "type") && (!strcasecmp(tmp->value, "peer"))) {
5713  goto cleanup;
5714  }
5715  }
5716  }
5717 
5718  /* Peer found in realtime, now build it in memory */
5719  peer = build_peer(newpeername, var, varregs, TRUE, devstate_only);
5720  if (!peer) {
5721  goto cleanup;
5722  }
5723 
5724  /* Previous versions of Asterisk did not require the type field to be
5725  * set for real time peers. This statement preserves that behavior. */
5726  if (peer->type == 0) {
5727  if (which_objects == FINDUSERS) {
5728  peer->type = SIP_TYPE_USER;
5729  } else if (which_objects == FINDPEERS) {
5730  peer->type = SIP_TYPE_PEER;
5731  } else {
5732  peer->type = SIP_TYPE_PEER | SIP_TYPE_USER;
5733  }
5734  }
5735 
5736  ast_debug(3, "-REALTIME- loading peer from database to memory. Name: %s. Peer objects: %d\n", peer->name, rpeerobjs);
5737 
5738  if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && !devstate_only) {
5739  /* Cache peer */
5743  sip_unref_peer(_data, "remove registration ref"),
5744  sip_unref_peer(peer, "remove registration ref"),
5745  sip_ref_peer(peer, "add registration ref"));
5746  }
5747  ao2_t_link(peers, peer, "link peer into peers table");
5748  if (!ast_sockaddr_isnull(&peer->addr)) {
5749  ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table");
5750  }
5751  }
5752  peer->is_realtime = 1;
5753 
5754 cleanup:
5755  ast_variables_destroy(var);
5756  ast_variables_destroy(varregs);
5757  return peer;
5758 }
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:290
struct ast_variable * next
struct ast_sockaddr addr
Definition: sip.h:1352
static int expire_register(const void *data)
Expire registration of SIP peer.
Definition: chan_sip.c:16646
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
#define ast_test_flag(p, flag)
Definition: utils.h:63
static int rpeerobjs
Definition: chan_sip.c:880
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)
Definition: chan_sip.c:5509
static int tmp()
Definition: bt_open.c:389
int ast_check_realtime(const char *family)
Check if realtime engine is configured for family.
Definition: main/config.c:3363
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
Definition: sched.c:76
static int realtime_peer_by_addr(const char **name, struct ast_sockaddr *addr, const char *ipaddr, const char *callbackexten, struct ast_variable **var, struct ast_variable **varregs)
Definition: chan_sip.c:5581
#define ao2_t_link(container, obj, tag)
Add an object to a container.
Definition: astobj2.h:1547
enum sip_peer_type type
Definition: sip.h:1375
#define ast_copy_flags(dest, src, flagz)
Definition: utils.h:84
#define NULL
Definition: resample.c:96
#define sip_ref_peer(peer, tag)
Definition: sip.h:1894
char name[80]
Definition: sip.h:1274
static struct ao2_container * peers_by_ip
Definition: chan_sip.c:1053
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static char ipaddr[80]
Definition: pbx_dundi.c:210
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)
Definition: chan_sip.c:31631
int expire
Definition: sip.h:1341
#define FINDUSERS
Definition: sip.h:52
int rtautoclear
Definition: sip.h:754
static struct ast_flags global_flags[3]
Definition: chan_sip.c:884
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
#define SIP_PAGE2_RTCACHEFRIENDS
Definition: sip.h:323
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
unsigned short is_realtime
Definition: sip.h:1312
#define FINDPEERS
Definition: sip.h:53
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
static void * cleanup(void *unused)
Definition: pbx_realtime.c:124
#define AST_SCHED_REPLACE_UNREF(id, sched, when, callback, data, unrefcall, addfailcall, refcall)
Definition: sched.h:150
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
struct ast_flags flags[3]
Definition: sip.h:1335
#define TRUE
Definition: app_minivm.c:518
#define SIP_PAGE2_RTAUTOCLEAR
Definition: sip.h:324

◆ realtime_peer_by_addr()

static int realtime_peer_by_addr ( const char **  name,
struct ast_sockaddr addr,
const char *  ipaddr,
const char *  callbackexten,
struct ast_variable **  var,
struct ast_variable **  varregs 
)
static

Definition at line 5581 of file chan_sip.c.

References ast_copy_string(), ast_load_realtime(), ast_log, ast_sockaddr_stringify_port(), ast_strlen_zero, ast_variables_destroy(), get_insecure_variable_from_sippeers(), get_insecure_variable_from_sipregs(), get_name_from_variable(), LOG_WARNING, NULL, realtime_peer_get_sippeer_helper(), and SENTINEL.

Referenced by realtime_peer().

5582 {
5583  char portstring[6]; /* up to 5 digits plus null terminator */
5584  ast_copy_string(portstring, ast_sockaddr_stringify_port(addr), sizeof(portstring));
5585 
5586  /* We're not finding this peer by this name anymore. Reset it. */
5587  *name = NULL;
5588 
5589  /* First check for fixed IP hosts with matching callbackextensions, if specified */
5590  if (!ast_strlen_zero(callbackexten) && (*var = ast_load_realtime("sippeers", "host", ipaddr, "port", portstring, "callbackextension", callbackexten, SENTINEL))) {
5591  ;
5592  /* Check for fixed IP hosts */
5593  } else if ((*var = ast_load_realtime("sippeers", "host", ipaddr, "port", portstring, SENTINEL))) {
5594  ;
5595  /* Check for registered hosts (in sipregs) */
5596  } else if (varregs && (*varregs = ast_load_realtime("sipregs", "ipaddr", ipaddr, "port", portstring, SENTINEL)) &&
5597  (*var = realtime_peer_get_sippeer_helper(name, varregs))) {
5598  ;
5599  /* Check for registered hosts (in sippeers) */
5600  } else if (!varregs && (*var = ast_load_realtime("sippeers", "ipaddr", ipaddr, "port", portstring, SENTINEL))) {
5601  ;
5602  /* We couldn't match on ipaddress and port, so we need to check if port is insecure */
5603  } else if ((*var = get_insecure_variable_from_sippeers("host", ipaddr))) {
5604  ;
5605  /* Same as above, but try the IP address field (in sipregs)
5606  * Observe that it fetches the name/var at the same time, without the
5607  * realtime_peer_get_sippeer_helper. Also note that it is quite inefficient.
5608  * Avoid sipregs if possible. */
5609  } else if (varregs && (*varregs = get_insecure_variable_from_sipregs("ipaddr", ipaddr, var))) {
5610  ;
5611  /* Same as above, but try the IP address field (in sippeers) */
5612  } else if (!varregs && (*var = get_insecure_variable_from_sippeers("ipaddr", ipaddr))) {
5613  ;
5614  }
5615 
5616  /* Nothing found? */
5617  if (!*var) {
5618  return 0;
5619  }
5620 
5621  /* Check peer name. It must not be empty. There may exist a
5622  * different match that does have a name, but it's too late for
5623  * that now. */
5624  if (!*name && !(*name = get_name_from_variable(*var))) {
5625  ast_log(LOG_WARNING, "Found peer for IP %s but it has no name\n", ipaddr);
5626  ast_variables_destroy(*var);
5627  *var = NULL;
5628  if (varregs && *varregs) {
5629  ast_variables_destroy(*varregs);
5630  *varregs = NULL;
5631  }
5632  return 0;
5633  }
5634 
5635  /* Make sure varregs is populated if var is. The inverse,
5636  * ensuring that var is set when varregs is, is taken
5637  * care of by realtime_peer_get_sippeer_helper(). */
5638  if (varregs && !*varregs) {
5639  *varregs = ast_load_realtime("sipregs", "name", *name, SENTINEL);
5640  }
5641  return 1;
5642 }
struct ast_variable * ast_load_realtime(const char *family,...) attribute_sentinel
Definition: main/config.c:3339
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
static struct ast_variable * get_insecure_variable_from_sippeers(const char *column, const char *value)
Definition: chan_sip.c:5413
#define LOG_WARNING
Definition: logger.h:274
static const char * get_name_from_variable(const struct ast_variable *var)
Definition: chan_sip.c:5485
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
static char * ast_sockaddr_stringify_port(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return a port only.
Definition: netsock2.h:362
static struct ast_variable * realtime_peer_get_sippeer_helper(const char **name, struct ast_variable **varregs)
Definition: chan_sip.c:5563
#define ast_log
Definition: astobj2.c:42
#define SENTINEL
Definition: compiler.h:87
static char ipaddr[80]
Definition: pbx_dundi.c:210
static const char name[]
Definition: cdr_mysql.c:74
static struct ast_variable * get_insecure_variable_from_sipregs(const char *column, const char *value, struct ast_variable **var)
Definition: chan_sip.c:5433
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401

◆ realtime_peer_by_name()

static int realtime_peer_by_name ( const char *const *  name,
struct ast_sockaddr addr,
const char *  ipaddr,
struct ast_variable **  var,
struct ast_variable **  varregs 
)
static
Note
If this one loaded something, then we need to ensure that the host field matched. The only reason why we can't have this as a criteria is because we only have the IP address and the host field might be set as a name (and the reverse PTR might not match).

Definition at line 5509 of file chan_sip.c.

References ast_free, ast_load_realtime(), ast_sockaddr_cmp(), ast_sockaddr_resolve(), AST_TRANSPORT_UDP, ast_variables_destroy(), get_address_family_filter(), ast_variable::name, ast_variable::next, NULL, PARSE_PORT_FORBID, SENTINEL, tmp(), and ast_variable::value.

Referenced by realtime_peer().

5510 {
5511  /* Peer by name and host=dynamic */
5512  if ((*var = ast_load_realtime("sippeers", "name", *name, "host", "dynamic", SENTINEL))) {
5513  ;
5514  /* Peer by name and host=IP */
5515  } else if (addr && !(*var = ast_load_realtime("sippeers", "name", *name, "host", ipaddr, SENTINEL))) {
5516  ;
5517  /* Peer by name and host=HOSTNAME */
5518  } else if ((*var = ast_load_realtime("sippeers", "name", *name, SENTINEL))) {
5519  /*!\note
5520  * If this one loaded something, then we need to ensure that the host
5521  * field matched. The only reason why we can't have this as a criteria
5522  * is because we only have the IP address and the host field might be
5523  * set as a name (and the reverse PTR might not match).
5524  */
5525  if (addr) {
5526  struct ast_variable *tmp;
5527  for (tmp = *var; tmp; tmp = tmp->next) {
5528  if (!strcasecmp(tmp->name, "host")) {
5529  struct ast_sockaddr *addrs = NULL;
5530 
5531  if (ast_sockaddr_resolve(&addrs,
5532  tmp->value,
5535  ast_sockaddr_cmp(&addrs[0], addr)) {
5536  /* No match */
5537  ast_variables_destroy(*var);
5538  *var = NULL;
5539  }
5540  ast_free(addrs);
5541  break;
5542  }
5543  }
5544  }
5545  }
5546 
5547  /* Did we find anything? */
5548  if (*var) {
5549  if (varregs) {
5550  *varregs = ast_load_realtime("sipregs", "name", *name, SENTINEL);
5551  }
5552  return 1;
5553  }
5554  return 0;
5555 }
struct ast_variable * ast_load_realtime(const char *family,...) attribute_sentinel
Definition: main/config.c:3339
struct ast_variable * next
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
static int get_address_family_filter(unsigned int transport)
Helper for dns resolution to filter by address family.
Definition: chan_sip.c:29558
static int tmp()
Definition: bt_open.c:389
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96
int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares two ast_sockaddr structures.
Definition: netsock2.c:388
Socket address structure.
Definition: netsock2.h:97
#define SENTINEL
Definition: compiler.h:87
static char ipaddr[80]
Definition: pbx_dundi.c:210
static const char name[]
Definition: cdr_mysql.c:74
#define ast_free(a)
Definition: astmm.h:182
int ast_sockaddr_resolve(struct ast_sockaddr **addrs, const char *str, int flags, int family)
Parses a string with an IPv4 or IPv6 address and place results into an array.
Definition: netsock2.c:280

◆ realtime_peer_get_sippeer_helper()

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

Definition at line 5563 of file chan_sip.c.

References ast_load_realtime(), ast_log, ast_variables_destroy(), get_name_from_variable(), LOG_WARNING, name, NULL, SENTINEL, and var.

Referenced by realtime_peer_by_addr().

5563  {
5564  struct ast_variable *var = NULL;
5565  const char *old_name = *name;
5566  *name = get_name_from_variable(*varregs);
5567  if (!*name || !(var = ast_load_realtime("sippeers", "name", *name, SENTINEL))) {
5568  if (!*name) {
5569  ast_log(LOG_WARNING, "Found sipreg but it has no name\n");
5570  }
5571  ast_variables_destroy(*varregs);
5572  *varregs = NULL;
5573  *name = old_name;
5574  }
5575  return var;
5576 }
struct ast_variable * ast_load_realtime(const char *family,...) attribute_sentinel
Definition: main/config.c:3339
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
#define LOG_WARNING
Definition: logger.h:274
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
static const char * get_name_from_variable(const struct ast_variable *var)
Definition: chan_sip.c:5485
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
#define SENTINEL
Definition: compiler.h:87
static const char name[]
Definition: cdr_mysql.c:74

◆ realtime_update_peer()

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,
const char *  path 
)
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 5167 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, NULL, sip_settings::rtsave_path, sip_settings::rtsave_sysname, SENTINEL, and sip_cfg.

Referenced by update_peer().

5168 {
5169  char port[10];
5170  char ipaddr[INET6_ADDRSTRLEN];
5171  char regseconds[20];
5172  char *tablename = NULL;
5173  char str_lastms[20];
5174 
5175  const char *sysname = ast_config_AST_SYSTEM_NAME;
5176  char *syslabel = NULL;
5177 
5178  time_t nowtime = time(NULL) + expirey;
5179  const char *fc = fullcontact ? "fullcontact" : NULL;
5180 
5181  int realtimeregs = ast_check_realtime("sipregs");
5182 
5183  tablename = realtimeregs ? "sipregs" : "sippeers";
5184 
5185  snprintf(str_lastms, sizeof(str_lastms), "%d", lastms);
5186  snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); /* Expiration time */
5187  ast_copy_string(ipaddr, ast_sockaddr_isnull(addr) ? "" : ast_sockaddr_stringify_addr(addr), sizeof(ipaddr));
5188  ast_copy_string(port, ast_sockaddr_port(addr) ? ast_sockaddr_stringify_port(addr) : "", sizeof(port));
5189 
5190  if (ast_strlen_zero(sysname)) { /* No system name, disable this */
5191  sysname = NULL;
5192  } else if (sip_cfg.rtsave_sysname) {
5193  syslabel = "regserver";
5194  }
5195 
5196  /* XXX IMPORTANT: Anytime you add a new parameter to be updated, you
5197  * must also add it to contrib/scripts/asterisk.ldap-schema,
5198  * contrib/scripts/asterisk.ldif,
5199  * and to configs/res_ldap.conf.sample as described in
5200  * bugs 15156 and 15895
5201  */
5202 
5203  /* This is ugly, we need something better ;-) */
5204  if (sip_cfg.rtsave_path) {
5205  if (fc) {
5206  ast_update_realtime(tablename, "name", peername, "ipaddr", ipaddr,
5207  "port", port, "regseconds", regseconds,
5208  deprecated_username ? "username" : "defaultuser", defaultuser,
5209  "useragent", useragent, "lastms", str_lastms,
5210  "path", path, /* Path data can be NULL */
5211  fc, fullcontact, syslabel, sysname, SENTINEL); /* note fc and syslabel _can_ be NULL */
5212  } else {
5213  ast_update_realtime(tablename, "name", peername, "ipaddr", ipaddr,
5214  "port", port, "regseconds", regseconds,
5215  "useragent", useragent, "lastms", str_lastms,
5216  deprecated_username ? "username" : "defaultuser", defaultuser,
5217  "path", path, /* Path data can be NULL */
5218  syslabel, sysname, SENTINEL); /* note syslabel _can_ be NULL */
5219  }
5220  } else {
5221  if (fc) {
5222  ast_update_realtime(tablename, "name", peername, "ipaddr", ipaddr,
5223  "port", port, "regseconds", regseconds,
5224  deprecated_username ? "username" : "defaultuser", defaultuser,
5225  "useragent", useragent, "lastms", str_lastms,
5226  fc, fullcontact, syslabel, sysname, SENTINEL); /* note fc and syslabel _can_ be NULL */
5227  } else {
5228  ast_update_realtime(tablename, "name", peername, "ipaddr", ipaddr,
5229  "port", port, "regseconds", regseconds,
5230  "useragent", useragent, "lastms", str_lastms,
5231  deprecated_username ? "username" : "defaultuser", defaultuser,
5232  syslabel, sysname, SENTINEL); /* note syslabel _can_ be NULL */
5233  }
5234  }
5235 }
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:290
int ast_check_realtime(const char *family)
Check if realtime engine is configured for family.
Definition: main/config.c:3363
#define NULL
Definition: resample.c:96
int ast_update_realtime(const char *family, const char *keyfield, const char *lookup,...) attribute_sentinel
Update realtime configuration.
Definition: main/config.c:3489
#define ast_strlen_zero(foo)
Definition: strings.h:52
const char * ast_config_AST_SYSTEM_NAME
Definition: options.c:170
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:521
static char * ast_sockaddr_stringify_port(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return a port only.
Definition: netsock2.h:362
#define SENTINEL
Definition: compiler.h:87
static char ipaddr[80]
Definition: pbx_dundi.c:210
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
int rtsave_sysname
Definition: sip.h:751
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int rtsave_path
Definition: sip.h:752

◆ receive_message()

static void receive_message ( struct sip_pvt p,
struct sip_request req,
struct ast_sockaddr addr,
const char *  e 
)
static

Receive SIP MESSAGE method messages.

Note
We only handle messages within current calls currently Reference: RFC 3428

Definition at line 19707 of file chan_sip.c.

References sip_settings::accept_outofcall_message, ast_assert, ast_copy_string(), ast_debug, ast_escape_quoted(), AST_FRAME_TEXT, ast_log, ast_msg_alloc(), ast_msg_destroy(), ast_msg_has_destination(), ast_msg_queue(), ast_msg_set_body(), ast_msg_set_context(), ast_msg_set_endpoint(), ast_msg_set_exten(), ast_msg_set_from(), ast_msg_set_tech(), ast_msg_set_to(), ast_msg_set_var(), ast_queue_frame(), ast_sockaddr_stringify(), ast_strdupa, ast_string_field_set, ast_strlen_zero, ast_verbose(), AUTH_CHALLENGE_SENT, sip_settings::auth_message_requests, buf, sip_pvt::callid, check_user(), context, sip_pvt::context, sip_peer::context, copy_request(), ast_frame::data, ast_frame::datalen, DEFAULT_TRANS_TIMEOUT, sip_pvt::exten, FINDPEERS, ast_frame::frametype, get_calleridname(), get_content(), get_destination(), get_in_brackets(), sip_pvt::initreq, ast_frame_subclass::integer, len(), LOG_WARNING, sip_peer::md5secret, sip_settings::messagecontext, sip_pvt::messagecontext, sip_peer::messagecontext, sip_peer::name, NULL, ast_frame::offset, sip_pvt::owner, sip_pvt::peername, sip_monitor_instance::peername, ast_frame::ptr, sip_pvt::recv, REQ_OFFSET_TO_STR, sip_peer::secret, send_check_user_failure_response(), set_message_vars_from_req(), set_pvt_allowed_methods(), sip_cfg, sip_debug_test_pvt(), sip_find_peer(), SIP_GET_DEST_EXTEN_FOUND, SIP_GET_DEST_EXTEN_MATCHMORE, SIP_GET_DEST_EXTEN_NOT_FOUND, SIP_GET_DEST_INVALID_URI, SIP_GET_DEST_REFUSED, sip_get_header(), SIP_MESSAGE, sip_scheddestroy(), sip_unref_peer, SIPBUFSIZE, sip_pvt::socket, ast_frame::subclass, transmit_response(), TRUE, sip_socket::type, and XMIT_UNRELIABLE.

Referenced by handle_request_message().

19708 {
19709  char *buf;
19710  size_t len;
19711  struct ast_frame f;
19712  const char *content_type = sip_get_header(req, "Content-Type");
19713  struct ast_msg *msg;
19714  int res;
19715  char *from;
19716  char *to;
19717  char from_name[50];
19718  char stripped[SIPBUFSIZE];
19719  enum sip_get_dest_result dest_result;
19720 
19721  if (strncmp(content_type, "text/plain", strlen("text/plain"))) { /* No text/plain attachment */
19722  transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */
19723  if (!p->owner) {
19725  }
19726  return;
19727  }
19728 
19729  if (!(buf = get_content(req))) {
19730  ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid);
19731  transmit_response(p, "500 Internal Server Error", req);
19732  if (!p->owner) {
19734  }
19735  return;
19736  }
19737 
19738  /* Strip trailing line feeds from message body. (get_content may add
19739  * a trailing linefeed and we don't need any at the end) */
19740  len = strlen(buf);
19741  while (len > 0) {
19742  if (buf[--len] != '\n') {
19743  ++len;
19744  break;
19745  }
19746  }
19747  buf[len] = '\0';
19748 
19749  if (p->owner) {
19750  if (sip_debug_test_pvt(p)) {
19751  ast_verbose("SIP Text message received: '%s'\n", buf);
19752  }
19753  memset(&f, 0, sizeof(f));
19754  f.frametype = AST_FRAME_TEXT;
19755  f.subclass.integer = 0;
19756  f.offset = 0;
19757  f.data.ptr = buf;
19758  f.datalen = strlen(buf) + 1;
19759  ast_queue_frame(p->owner, &f);
19760  transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */
19761  return;
19762  }
19763 
19764  /*
19765  * At this point MESSAGE is outside of a call.
19766  *
19767  * NOTE: p->owner is NULL so no additional check is needed after
19768  * this point.
19769  */
19770 
19772  /* Message outside of a call, we do not support that */
19773  ast_debug(1, "MESSAGE outside of a call administratively disabled.\n");
19774  transmit_response(p, "405 Method Not Allowed", req);
19776  return;
19777  }
19778 
19779  copy_request(&p->initreq, req);
19780 
19782  int res;
19783 
19784  set_pvt_allowed_methods(p, req);
19785  res = check_user(p, req, SIP_MESSAGE, e, XMIT_UNRELIABLE, addr);
19786  if (res == AUTH_CHALLENGE_SENT) {
19788  return;
19789  }
19790  if (res < 0) { /* Something failed in authentication */
19793  return;
19794  }
19795  /* Auth was successful. Proceed. */
19796  } else {
19797  struct sip_peer *peer;
19798 
19799  /*
19800  * MESSAGE outside of a call, not authenticating it.
19801  * Check to see if we match a peer anyway so that we can direct
19802  * it to the right context.
19803  */
19804 
19805  peer = sip_find_peer(NULL, &p->recv, TRUE, FINDPEERS, 0, p->socket.type);
19806  if (peer) {
19807  /* Only if no auth is required. */
19808  if (ast_strlen_zero(peer->secret) && ast_strlen_zero(peer->md5secret)) {
19810  }
19811  if (!ast_strlen_zero(peer->messagecontext)) {
19813  }
19814  ast_string_field_set(p, peername, peer->name);
19815  peer = sip_unref_peer(peer, "from sip_find_peer() in receive_message");
19816  }
19817  }
19818 
19819  /* Override the context with the message context _BEFORE_
19820  * getting the destination. This way we can guarantee the correct
19821  * extension is used in the message context when it is present. */
19822  if (!ast_strlen_zero(p->messagecontext)) {
19824  } else if (!ast_strlen_zero(sip_cfg.messagecontext)) {
19826  }
19827 
19828  dest_result = get_destination(p, NULL, NULL);
19829  switch (dest_result) {
19830  case SIP_GET_DEST_REFUSED:
19831  /* Okay to send 403 since this is after auth processing */
19832  transmit_response(p, "403 Forbidden", req);
19834  return;
19836  transmit_response(p, "416 Unsupported URI Scheme", req);
19838  return;
19839  default:
19840  /* We may have something other than dialplan who wants
19841  * the message, so defer further error handling for now */
19842  break;
19843  }
19844 
19845  if (!(msg = ast_msg_alloc())) {
19846  transmit_response(p, "500 Internal Server Error", req);
19848  return;
19849  }
19850 
19851  to = ast_strdupa(REQ_OFFSET_TO_STR(req, rlpart2));
19852  from = ast_strdupa(sip_get_header(req, "From"));
19853 
19854  res = ast_msg_set_to(msg, "%s", to);
19855 
19856  /* Build "display" <uri> for from string. */
19857  from = (char *) get_calleridname(from, from_name, sizeof(from_name));
19858  from = get_in_brackets(from);
19859  if (from_name[0]) {
19860  char from_buf[128];
19861 
19862  ast_escape_quoted(from_name, from_buf, sizeof(from_buf));
19863  res |= ast_msg_set_from(msg, "\"%s\" <%s>", from_buf, from);
19864  } else {
19865  res |= ast_msg_set_from(msg, "<%s>", from);
19866  }
19867 
19868  res |= ast_msg_set_body(msg, "%s", buf);
19869  res |= ast_msg_set_context(msg, "%s", p->context);
19870 
19871  res |= ast_msg_set_var(msg, "SIP_RECVADDR", ast_sockaddr_stringify(&p->recv));
19872  res |= ast_msg_set_tech(msg, "%s", "SIP");
19873  if (!ast_strlen_zero(p->peername)) {
19874  res |= ast_msg_set_endpoint(msg, "%s", p->peername);
19875  res |= ast_msg_set_var(msg, "SIP_PEERNAME", p->peername);
19876  }
19877 
19878  ast_copy_string(stripped, sip_get_header(req, "Contact"), sizeof(stripped));
19879  res |= ast_msg_set_var(msg, "SIP_FULLCONTACT", get_in_brackets(stripped));
19880 
19881  res |= ast_msg_set_exten(msg, "%s", p->exten);
19882  res |= set_message_vars_from_req(msg, req);
19883 
19884  if (res) {
19885  ast_msg_destroy(msg);
19886  transmit_response(p, "500 Internal Server Error", req);
19888  return;
19889  }
19890 
19891  if (ast_msg_has_destination(msg)) {
19892  ast_msg_queue(msg);
19893  transmit_response(p, "202 Accepted", req);
19895  return;
19896  }
19897 
19898  /* Find a specific error cause to send */
19899  switch (dest_result) {
19902  transmit_response(p, "404 Not Found", req);
19903  break;
19905  default:
19906  /* We should have sent the message already! */
19907  ast_assert(0);
19908  transmit_response(p, "500 Internal Server Error", req);
19909  break;
19910  }
19912  ast_msg_destroy(msg);
19913 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
int ast_msg_set_tech(struct ast_msg *msg, const char *fmt,...)
Set the technology associated with this message.
Definition: message.c:509
static void send_check_user_failure_response(struct sip_pvt *p, struct sip_request *req, int res, enum xmittype reliable)
Definition: chan_sip.c:19626
char * get_in_brackets(char *tmp)
Pick out text in brackets from character string.
struct sip_peer * sip_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.
Definition: chan_sip.c:5851
int ast_msg_set_context(struct ast_msg *msg, const char *fmt,...)
Set the dialplan context for this message.
Definition: message.c:487
int ast_msg_set_body(struct ast_msg *msg, const char *fmt,...)
Set the &#39;body&#39; text of a message (in UTF-8)
Definition: message.c:476
const ast_string_field messagecontext
Definition: sip.h:1306
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
struct ast_sockaddr recv
Definition: sip.h:1135
#define DEFAULT_TRANS_TIMEOUT
Definition: sip.h:107
struct ast_msg * ast_msg_alloc(void)
Allocate a message.
Definition: message.c:418
struct sip_socket socket
Definition: sip.h:1066
const ast_string_field to
Definition: message.c:249
int auth_message_requests
Definition: sip.h:762
#define ast_assert(a)
Definition: utils.h:695
const ast_string_field context
Definition: sip.h:1063
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
sip_get_dest_result
Result from get_destination function.
Definition: sip.h:508
#define NULL
Definition: resample.c:96
static int set_message_vars_from_req(struct ast_msg *msg, struct sip_request *req)
Definition: chan_sip.c:19675
char name[80]
Definition: sip.h:1274
int ast_msg_set_to(struct ast_msg *msg, const char *fmt,...)
Set the &#39;to&#39; URI of a message.
Definition: message.c:454
#define ast_strlen_zero(foo)
Definition: strings.h:52
static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req)
Transmit response, no retransmits.
Definition: chan_sip.c:12655
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
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.
Definition: chan_sip.c:18508
struct sip_request initreq
Definition: sip.h:1151
const ast_string_field messagecontext
Definition: sip.h:1063
static void copy_request(struct sip_request *dst, const struct sip_request *src)
copy SIP request (mostly used to save request for responses)
Definition: chan_sip.c:14061
const ast_string_field exten
Definition: sip.h:1063
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
const ast_string_field md5secret
Definition: sip.h:1306
int ast_msg_set_var(struct ast_msg *msg, const char *name, const char *value)
Set a variable on the message going to the dialplan.
Definition: message.c:615
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel&#39;s frame queue.
Definition: channel.c:1139
int ast_msg_queue(struct ast_msg *msg)
Queue a message for routing through the dialplan.
Definition: message.c:958
char messagecontext[AST_MAX_CONTEXT]
Definition: sip.h:771
const ast_string_field callid
Definition: sip.h:1063
#define SIPBUFSIZE
Definition: sip.h:56
const char * get_calleridname(const char *input, char *output, size_t outputsize)
Get caller id name from SIP headers, copy into output buffer.
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
char * ast_escape_quoted(const char *string, char *outbuf, int buflen)
Escape characters found in a quoted string.
Definition: main/utils.c:635
struct ast_channel * owner
Definition: sip.h:1138
const ast_string_field from
Definition: message.c:249
#define FINDPEERS
Definition: sip.h:53
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
#define REQ_OFFSET_TO_STR(req, offset)
Definition: sip.h:858
const ast_string_field peername
Definition: sip.h:1063
int ast_msg_set_exten(struct ast_msg *msg, const char *fmt,...)
Set the dialplan extension for this message.
Definition: message.c:498
static int sip_debug_test_pvt(struct sip_pvt *p)
Test PVT for debugging output.
Definition: chan_sip.c:3649
int ast_msg_set_from(struct ast_msg *msg, const char *fmt,...)
Set the &#39;from&#39; URI of a message.
Definition: message.c:465
int ast_msg_set_endpoint(struct ast_msg *msg, const char *fmt,...)
Set the technology&#39;s endpoint associated with this message.
Definition: message.c:520
enum ast_transport type
Definition: sip.h:798
int ast_msg_has_destination(const struct ast_msg *msg)
Determine if a particular message has a destination via some handler.
Definition: message.c:937
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define TRUE
Definition: app_minivm.c:518
const ast_string_field secret
Definition: sip.h:1306
int accept_outofcall_message
Definition: sip.h:763
Data structure associated with a single frame of data.
static char * get_content(struct sip_request *req)
Get message body content.
Definition: chan_sip.c:8610
static unsigned int set_pvt_allowed_methods(struct sip_pvt *pvt, struct sip_request *req)
Definition: chan_sip.c:9880
A message.
Definition: message.c:233
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
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, that needs to be unreferenced.
Definition: chan_sip.c:19621
struct ast_msg * ast_msg_destroy(struct ast_msg *msg)
Destroy an ast_msg.
Definition: message.c:448
void sip_scheddestroy(struct sip_pvt *p, int ms)
Schedule destruction of SIP dialog.
Definition: chan_sip.c:4549
const ast_string_field context
Definition: sip.h:1306
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ ref_proxy()

static void ref_proxy ( struct sip_pvt pvt,
struct sip_proxy proxy 
)
static

maintain proper refcounts for a sip_pvt's outboundproxy

This function sets pvt's outboundproxy pointer to the one referenced by the proxy parameter. Because proxy may be a refcounted object, and because pvt's old outboundproxy may also be a refcounted object, we need to maintain the proper refcounts.

Parameters
pvtThe sip_pvt for which we wish to set the outboundproxy
proxyThe sip_proxy which we will point pvt towards.
Returns
Returns void

Definition at line 3293 of file chan_sip.c.

References ao2_ref, sip_settings::outboundproxy, sip_pvt::outboundproxy, and sip_cfg.

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

3294 {
3295  struct sip_proxy *old_obproxy = pvt->outboundproxy;
3296  /* The sip_cfg.outboundproxy is statically allocated, and so
3297  * we don't ever need to adjust refcounts for it
3298  */
3299  if (proxy && proxy != &sip_cfg.outboundproxy) {
3300  ao2_ref(proxy, +1);
3301  }
3302  pvt->outboundproxy = proxy;
3303  if (old_obproxy && old_obproxy != &sip_cfg.outboundproxy) {
3304  ao2_ref(old_obproxy, -1);
3305  }
3306 }
definition of a sip proxy server
Definition: sip.h:721
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
struct sip_proxy outboundproxy
Definition: sip.h:781
struct sip_proxy * outboundproxy
Definition: sip.h:1112

◆ referstatus2str()

static const char * referstatus2str ( enum referstatus  rstatus)
static

Convert transfer status to string.

Definition at line 3424 of file chan_sip.c.

References map_x_s().

Referenced by show_channels_cb().

3425 {
3426  return map_x_s(referstatusstrings, rstatus, "");
3427 }
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
Definition: chan_sip.c:2411
static const struct _map_x_s referstatusstrings[]
Definition: chan_sip.c:924

◆ reg_source_db()

static void reg_source_db ( struct sip_peer peer)
static

Get registration details from Asterisk DB.

Definition at line 16743 of file chan_sip.c.

References sip_peer::addr, 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, build_path(), sip_peer::expire, expire_register(), global_qualifyfreq, sip_peer::maxms, sip_peer::name, NULL, sip_settings::peer_rtupdate, sip_peer::pokeexpire, sip_peer::qualifyfreq, register_peer_exten(), sip_peer::rt_fromcontact, sip_cfg, sip_poke_peer_s(), sip_ref_peer, sip_unref_peer, SIPBUFSIZE, TRUE, and sip_peer::username.

Referenced by build_peer(), and temp_peer().

16744 {
16745  char data[256];
16746  char path[SIPBUFSIZE * 2];
16747  struct ast_sockaddr sa;
16748  int expire;
16749  char full_addr[128];
16751  AST_APP_ARG(addr);
16752  AST_APP_ARG(port);
16753  AST_APP_ARG(expiry_str);
16754  AST_APP_ARG(username);
16756  );
16757 
16758  /* If read-only RT backend, then refresh from local DB cache */
16759  if (peer->rt_fromcontact && sip_cfg.peer_rtupdate) {
16760  return;
16761  }
16762  if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) {
16763  return;
16764  }
16765 
16766  AST_NONSTANDARD_RAW_ARGS(args, data, ':');
16767 
16768  snprintf(full_addr, sizeof(full_addr), "%s:%s", args.addr, args.port);
16769 
16770  if (!ast_sockaddr_parse(&sa, full_addr, 0)) {
16771  return;
16772  }
16773 
16774  if (args.expiry_str) {
16775  expire = atoi(args.expiry_str);
16776  } else {
16777  return;
16778  }
16779 
16780  if (args.username) {
16781  ast_string_field_set(peer, username, args.username);
16782  }
16783  if (args.contact) {
16784  ast_string_field_set(peer, fullcontact, args.contact);
16785  }
16786 
16787  ast_debug(2, "SIP Seeding peer from astdb: '%s' at %s@%s for %d\n",
16788  peer->name, peer->username, ast_sockaddr_stringify_host(&sa), expire);
16789 
16790  ast_sockaddr_copy(&peer->addr, &sa);
16791  if (peer->maxms) {
16792  /* Don't poke peer immediately, just schedule it within qualifyfreq */
16794  ast_random() % ((peer->qualifyfreq) ? peer->qualifyfreq : global_qualifyfreq) + 1,
16795  sip_poke_peer_s, peer,
16796  sip_unref_peer(_data, "removing poke peer ref"),
16797  sip_unref_peer(peer, "removing poke peer ref"),
16798  sip_ref_peer(peer, "adding poke peer ref"));
16799  }
16800  AST_SCHED_REPLACE_UNREF(peer->expire, sched, (expire + 10) * 1000, expire_register, peer,
16801  sip_unref_peer(_data, "remove registration ref"),
16802  sip_unref_peer(peer, "remove registration ref"),
16803  sip_ref_peer(peer, "add registration ref"));
16804  register_peer_exten(peer, TRUE);
16805  if (!ast_db_get("SIP/RegistryPath", peer->name, path, sizeof(path))) {
16806  build_path(NULL, peer, NULL, path);
16807  }
16808 }
struct ast_sockaddr addr
Definition: sip.h:1352
int maxms
Definition: sip.h:1357
static int expire_register(const void *data)
Expire registration of SIP peer.
Definition: chan_sip.c:16646
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:171
static int build_path(struct sip_pvt *p, struct sip_peer *peer, struct sip_request *req, const char *pathbuf)
Build route list from Path header RFC 3327 requires that the Path header contains SIP URIs with lr pa...
Definition: chan_sip.c:17260
Definition: sched.c:76
unsigned short rt_fromcontact
Definition: sip.h:1313
const char * args
#define NULL
Definition: resample.c:96
#define sip_ref_peer(peer, tag)
Definition: sip.h:1894
int peer_rtupdate
Definition: sip.h:750
Socket address structure.
Definition: netsock2.h:97
char name[80]
Definition: sip.h:1274
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static int sip_poke_peer_s(const void *data)
Poke peer (send qualify to check if peer is alive and well)
Definition: chan_sip.c:16707
long int ast_random(void)
Definition: main/utils.c:2064
const ast_string_field username
Definition: sip.h:1306
#define AST_NONSTANDARD_RAW_ARGS(args, parse, sep)
int expire
Definition: sip.h:1341
#define SIPBUFSIZE
Definition: sip.h:56
static void register_peer_exten(struct sip_peer *peer, int onoff)
Automatically add peer extension to dial plan.
Definition: chan_sip.c:5238
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
int ast_db_get(const char *family, const char *key, char *value, int valuelen)
Get key value specified by family/key.
Definition: main/db.c:412
static int global_qualifyfreq
Definition: chan_sip.c:851
#define AST_SCHED_REPLACE_UNREF(id, sched, when, callback, data, unrefcall, addfailcall, refcall)
Definition: sched.h:150
#define TRUE
Definition: app_minivm.c:518
int qualifyfreq
Definition: sip.h:1358
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
int pokeexpire
Definition: sip.h:1355
static char * ast_sockaddr_stringify_host(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only, suitable for a URL (with brack...
Definition: netsock2.h:331
#define AST_APP_ARG(name)
Define an application argument.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ register_peer_exten()

static void register_peer_exten ( struct sip_peer peer,
int  onoff 
)
static

Automatically add peer extension to dial plan.

Definition at line 5238 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, sip_peer::name, NULL, pbx_find_extension(), sip_settings::regcontext, sip_peer::regexten, S_OR, sip_cfg, pbx_find_info::stacklen, and strsep().

Referenced by expire_register(), handle_response_peerpoke(), parse_register_contact(), reg_source_db(), sip_destroy_peer(), and sip_poke_noanswer().

5239 {
5240  char multi[256];
5241  char *stringp, *ext, *context;
5242  struct pbx_find_info q = { .stacklen = 0 };
5243 
5244  /* XXX note that sip_cfg.regcontext is both a global 'enable' flag and
5245  * the name of the global regexten context, if not specified
5246  * individually.
5247  */
5249  return;
5250 
5251  ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
5252  stringp = multi;
5253  while ((ext = strsep(&stringp, "&"))) {
5254  if ((context = strchr(ext, '@'))) {
5255  *context++ = '\0'; /* split ext@context */
5256  if (!ast_context_find(context)) {
5257  ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context);
5258  continue;
5259  }
5260  } else {
5261  context = sip_cfg.regcontext;
5262  }
5263  if (onoff) {
5264  if (!ast_exists_extension(NULL, context, ext, 1, NULL)) {
5265  ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop",
5266  ast_strdup(peer->name), ast_free_ptr, "SIP");
5267  }
5268  } else if (pbx_find_extension(NULL, NULL, &q, context, ext, 1, NULL, "", E_MATCH)) {
5269  ast_context_remove_extension(context, ext, 1, NULL);
5270  }
5271  }
5272 }
#define LOG_WARNING
Definition: logger.h:274
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
const char * ext
Definition: http.c:147
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1771
char name[80]
Definition: sip.h:1274
int ast_context_remove_extension(const char *context, const char *extension, int priority, const char *registrar)
Simply remove extension from context.
Definition: pbx.c:4952
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
struct ast_context * ast_context_find(const char *name)
Find a context.
Definition: extconf.c:4174
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:4179
const ast_string_field regexten
Definition: sip.h:1306
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
int stacklen
Definition: extconf.h:238
char * strsep(char **str, const char *delims)
int ast_add_extension(const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
Add and extension to an extension context.
Definition: pbx.c:6970
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
struct ast_exten * pbx_find_extension(struct ast_channel *chan, struct ast_context *bypass, struct pbx_find_info *q, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action)
Definition: ael_main.c:152
char regcontext[AST_MAX_CONTEXT]
Definition: sip.h:770

◆ register_realtime_peers_with_callbackextens()

static int register_realtime_peers_with_callbackextens ( void  )
static

Definition at line 5644 of file chan_sip.c.

References ast_category_browse(), ast_category_root(), ast_check_realtime(), ast_config_destroy(), ast_load_realtime_multientry(), ast_log, build_peer(), FALSE, sip_peer::is_realtime, LOG_NOTICE, sip_peer::name, NULL, SENTINEL, sip_unref_peer, TRUE, and var.

Referenced by reload_config().

5645 {
5646  struct ast_config *cfg;
5647  char *cat = NULL;
5648 
5649  if (!(ast_check_realtime("sippeers"))) {
5650  return 0;
5651  }
5652 
5653  /* This is hacky. We want name to be the cat, so it is the first property */
5654  if (!(cfg = ast_load_realtime_multientry("sippeers", "name LIKE", "%", "callbackextension LIKE", "%", SENTINEL))) {
5655  return -1;
5656  }
5657 
5658  while ((cat = ast_category_browse(cfg, cat))) {
5659  struct sip_peer *peer;
5660  struct ast_variable *var = ast_category_root(cfg, cat);
5661 
5662  if (!(peer = build_peer(cat, var, NULL, TRUE, FALSE))) {
5663  continue;
5664  }
5665  ast_log(LOG_NOTICE, "Created realtime peer '%s' for registration\n", peer->name);
5666 
5667  peer->is_realtime = 1;
5668  sip_unref_peer(peer, "register_realtime_peers: Done registering releasing");
5669  }
5670 
5671  ast_config_destroy(cfg);
5672 
5673  return 0;
5674 }
#define FALSE
Definition: app_minivm.c:521
int ast_check_realtime(const char *family)
Check if realtime engine is configured for family.
Definition: main/config.c:3363
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3328
#define NULL
Definition: resample.c:96
char name[80]
Definition: sip.h:1274
struct ast_variable * ast_category_root(struct ast_config *config, char *cat)
returns the root ast_variable of a config
Definition: main/config.c:1162
#define ast_log
Definition: astobj2.c:42
#define SENTINEL
Definition: compiler.h:87
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
struct ast_config * ast_load_realtime_multientry(const char *family,...) attribute_sentinel
Retrieve realtime configuration.
Definition: main/config.c:3452
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)
Definition: chan_sip.c:31631
#define LOG_NOTICE
Definition: logger.h:263
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
unsigned short is_realtime
Definition: sip.h:1312
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
#define TRUE
Definition: app_minivm.c:518

◆ register_verify()

static enum check_auth_result register_verify ( struct sip_pvt p,
struct ast_sockaddr addr,
struct sip_request req,
const char *  uri 
)
static

Verify registration of user.

  • Registration is done in several steps, first a REGISTER without auth to get a challenge (nonce) then a second one with auth
  • Registration requests are only matched with peers that are marked as "dynamic"

Definition at line 17861 of file chan_sip.c.

References sip_peer::acl, sip_peer::addr, sip_settings::alwaysauthreject, ao2_lock, ao2_t_global_obj_ref, ao2_t_link, ao2_t_ref, ao2_unlock, ast_apply_acl(), ast_copy_flags, ast_copy_string(), AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_endpoint_blob_publish(), ast_endpoint_create(), AST_ENDPOINT_ONLINE, ast_endpoint_set_state(), ast_endpoint_state_type(), ast_json_pack(), ast_json_unref(), 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, AUTH_ACL_FAILED, AUTH_BAD_TRANSPORT, AUTH_NOT_FOUND, AUTH_PEER_NOT_DYNAMIC, AUTH_SECRET_FAILED, AUTH_UNKNOWN_DOMAIN, AUTH_USERNAME_MISMATCH, sip_settings::autocreatepeer, AUTOPEERS_DISABLED, build_contact(), c, check_auth(), check_request_transport, check_sip_domain(), sip_peer::endpoint, sip_pvt::expiry, exten, extract_host_from_hostport(), FALSE, FINDPEERS, sip_pvt::flags, sip_peer::flags, sip_peer::fullcontact, get_in_brackets(), global_authfailureevents, sip_peer::host_dynamic, sip_request::ignore, sip_pvt::initreq, LOG_ERROR, LOG_NOTICE, LOG_WARNING, sip_peer::md5secret, name, sip_peer::name, NULL, parse_register_contact(), PARSE_REGISTER_DENIED, PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, parse_uri_legacy_check(), RAII_VAR, remove_uri_parameters(), sip_peer::secret, set_peer_nat(), sip_cancel_destroy(), sip_cfg, sip_find_peer(), sip_get_header(), SIP_NAT_FORCE_RPORT, SIP_PEDANTIC_DECODE, SIP_PENDINGBYE, sip_pvt_lock, sip_pvt_unlock, SIP_REGISTER, sip_send_mwi_to_peer(), sip_unref_peer, strcasestr(), temp_peer(), terminate_uri(), tmp(), transmit_fake_auth_response(), transmit_response(), transmit_response_with_date(), TRUE, update_peer(), update_peer_lastmsgssent(), and XMIT_UNRELIABLE.

Referenced by handle_request_register().

17863 {
17864  enum check_auth_result res = AUTH_NOT_FOUND;
17865  struct sip_peer *peer;
17866  char tmp[256];
17867  char *c, *name, *unused_password, *domain;
17868  char *uri2 = ast_strdupa(uri);
17869  int send_mwi = 0;
17870 
17871  terminate_uri(uri2);
17872 
17873  ast_copy_string(tmp, sip_get_header(req, "To"), sizeof(tmp));
17874 
17875  c = get_in_brackets(tmp);
17876  c = remove_uri_parameters(c);
17877 
17878  if (parse_uri_legacy_check(c, "sip:,sips:", &name, &unused_password, &domain, NULL)) {
17879  ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_sockaddr_stringify_addr(addr));
17880  return -1;
17881  }
17882 
17883  SIP_PEDANTIC_DECODE(name);
17884  SIP_PEDANTIC_DECODE(domain);
17885 
17886  extract_host_from_hostport(&domain);
17887 
17888  if (ast_strlen_zero(domain)) {
17889  /* <sip:name@[EMPTY]>, never good */
17890  transmit_response(p, "404 Not found", &p->initreq);
17891  return AUTH_UNKNOWN_DOMAIN;
17892  }
17893 
17894  if (ast_strlen_zero(name)) {
17895  /* <sip:[EMPTY][@]hostport>, unsure whether valid for
17896  * registration. RFC 3261, 10.2 states:
17897  * "The To header field and the Request-URI field typically
17898  * differ, as the former contains a user name."
17899  * But, Asterisk has always treated the domain-only uri as a
17900  * username: we allow admins to create accounts described by
17901  * domain name. */
17902  name = domain;
17903  }
17904 
17905  /* This here differs from 1.4 and 1.6: the domain matching ACLs were
17906  * skipped if it was a domain-only URI (used as username). Here we treat
17907  * <sip:hostport> as <sip:host@hostport> and won't forget to test the
17908  * domain ACLs against host. */
17909  if (!AST_LIST_EMPTY(&domain_list)) {
17910  if (!check_sip_domain(domain, NULL, 0)) {
17911  if (sip_cfg.alwaysauthreject) {
17913  } else {
17914  transmit_response(p, "404 Not found (unknown domain)", &p->initreq);
17915  }
17916  return AUTH_UNKNOWN_DOMAIN;
17917  }
17918  }
17919 
17920  ast_string_field_set(p, exten, name);
17921  build_contact(p, req, 1);
17922  if (req->ignore) {
17923  /* Expires is a special case, where we only want to load the peer if this isn't a deregistration attempt */
17924  const char *expires = sip_get_header(req, "Expires");
17925  int expire = atoi(expires);
17926 
17927  if (ast_strlen_zero(expires)) { /* No expires header; look in Contact */
17928  if ((expires = strcasestr(sip_get_header(req, "Contact"), ";expires="))) {
17929  expire = atoi(expires + 9);
17930  }
17931  }
17932  if (!ast_strlen_zero(expires) && expire == 0) {
17933  transmit_response_with_date(p, "200 OK", req);
17934  return 0;
17935  }
17936  }
17937  peer = sip_find_peer(name, NULL, TRUE, FINDPEERS, FALSE, 0);
17938 
17939  /* If we don't want username disclosure, use the bogus_peer when a user
17940  * is not found. */
17942  peer = ao2_t_global_obj_ref(g_bogus_peer, "register_verify: Get the bogus peer.");
17943  }
17944 
17945  if (!(peer && ast_apply_acl(peer->acl, addr, "SIP Peer ACL: "))) {
17946  /* Peer fails ACL check */
17947  if (peer) {
17948  sip_unref_peer(peer, "register_verify: sip_unref_peer: from sip_find_peer operation");
17949  peer = NULL;
17950  res = AUTH_ACL_FAILED;
17951  } else {
17952  res = AUTH_NOT_FOUND;
17953  }
17954  }
17955 
17956  if (peer) {
17957  ao2_lock(peer);
17958  if (!peer->host_dynamic) {
17959  ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name);
17960  res = AUTH_PEER_NOT_DYNAMIC;
17961  } else {
17962 
17963  set_peer_nat(p, peer);
17964 
17965  ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT_FORCE_RPORT);
17966 
17967  if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri2, XMIT_UNRELIABLE))) {
17968  sip_cancel_destroy(p);
17969 
17970  if (check_request_transport(peer, req)) {
17972  transmit_response_with_date(p, "403 Forbidden", req);
17973  res = AUTH_BAD_TRANSPORT;
17974  } else {
17975 
17976  /* We have a successful registration attempt with proper authentication,
17977  now, update the peer */
17978  switch (parse_register_contact(p, peer, req)) {
17979  case PARSE_REGISTER_DENIED:
17980  ast_log(LOG_WARNING, "Registration denied because of contact ACL\n");
17981  transmit_response_with_date(p, "603 Denied", req);
17982  res = 0;
17983  break;
17984  case PARSE_REGISTER_FAILED:
17985  ast_log(LOG_WARNING, "Failed to parse contact info\n");
17986  transmit_response_with_date(p, "400 Bad Request", req);
17987  res = 0;
17988  break;
17989  case PARSE_REGISTER_QUERY:
17991  transmit_response_with_date(p, "200 OK", req);
17992  res = 0;
17993  send_mwi = 1;
17994  break;
17995  case PARSE_REGISTER_UPDATE:
17997  /* If expiry is 0, peer has been unregistered already */
17998  if (p->expiry != 0) {
17999  update_peer(peer, p->expiry);
18000  }
18001  /* Say OK and ask subsystem to retransmit msg counter */
18002  transmit_response_with_date(p, "200 OK", req);
18003  send_mwi = 1;
18004  res = 0;
18005  break;
18006  }
18007  }
18008 
18009  }
18010  }
18011  ao2_unlock(peer);
18012  }
18013  if (!peer && sip_cfg.autocreatepeer != AUTOPEERS_DISABLED) {
18014  /* Create peer if we have autocreate mode enabled */
18015  peer = temp_peer(name);
18016  if (peer && !(peer->endpoint = ast_endpoint_create("SIP", name))) {
18017  ao2_t_ref(peer, -1, "failed to allocate Stasis endpoint, drop peer");
18018  peer = NULL;
18019  }
18020  if (peer) {
18021  ao2_t_link(peers, peer, "link peer into peer table");
18022  if (!ast_sockaddr_isnull(&peer->addr)) {
18023  ao2_t_link(peers_by_ip, peer, "link peer into peers-by-ip table");
18024  }
18025  ao2_lock(peer);
18026  sip_cancel_destroy(p);
18027  switch (parse_register_contact(p, peer, req)) {
18028  case PARSE_REGISTER_DENIED:
18029  ast_log(LOG_WARNING, "Registration denied because of contact ACL\n");
18030  transmit_response_with_date(p, "403 Forbidden", req);
18031  res = 0;
18032  break;
18033  case PARSE_REGISTER_FAILED:
18034  ast_log(LOG_WARNING, "Failed to parse contact info\n");
18035  transmit_response_with_date(p, "400 Bad Request", req);
18036  res = 0;
18037  break;
18038  case PARSE_REGISTER_QUERY:
18040  transmit_response_with_date(p, "200 OK", req);
18041  send_mwi = 1;
18042  res = 0;
18043  break;
18044  case PARSE_REGISTER_UPDATE:
18046  /* Say OK and ask subsystem to retransmit msg counter */
18047  transmit_response_with_date(p, "200 OK", req);
18048  if (peer->endpoint) {
18049  RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
18051  blob = ast_json_pack("{s: s, s: s}",
18052  "peer_status", "Registered",
18053  "address", ast_sockaddr_stringify(addr));
18055  }
18056  send_mwi = 1;
18057  res = 0;
18058  break;
18059  }
18060  ao2_unlock(peer);
18061  }
18062  }
18063  if (!res) {
18064  if (send_mwi) {
18065  sip_pvt_unlock(p);
18066  sip_send_mwi_to_peer(peer, 0);
18067  sip_pvt_lock(p);
18068  } else {
18069  update_peer_lastmsgssent(peer, -1, 0);
18070  }
18072  }
18073  if (res < 0) {
18074  RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
18075 
18076  switch (res) {
18077  case AUTH_SECRET_FAILED:
18078  /* Wrong password in authentication. Go away, don't try again until you fixed it */
18079  transmit_response(p, "403 Forbidden", &p->initreq);
18081  const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr));
18082  const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr));
18083 
18084  blob = ast_json_pack("{s: s, s: s, s: s, s: s}",
18085  "peer_status", "Rejected",
18086  "cause", "AUTH_SECRET_FAILED",
18087  "address", peer_addr,
18088  "port", peer_port);
18089  }
18090  break;
18092  /* Username and digest username does not match.
18093  Asterisk uses the From: username for authentication. We need the
18094  devices to use the same authentication user name until we support
18095  proper authentication by digest auth name */
18096  case AUTH_NOT_FOUND:
18097  case AUTH_PEER_NOT_DYNAMIC:
18098  case AUTH_ACL_FAILED:
18099  if (sip_cfg.alwaysauthreject) {
18102  const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr));
18103  const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr));
18104 
18105  blob = ast_json_pack("{s: s, s: s, s: s, s: s}",
18106  "peer_status", "Rejected",
18107  "cause", res == AUTH_PEER_NOT_DYNAMIC ? "AUTH_PEER_NOT_DYNAMIC" : "URI_NOT_FOUND",
18108  "address", peer_addr,
18109  "port", peer_port);
18110  }
18111  } else {
18112  /* URI not found */
18113  if (res == AUTH_PEER_NOT_DYNAMIC) {
18114  transmit_response(p, "403 Forbidden", &p->initreq);
18116  const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr));
18117  const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr));
18118 
18119  blob = ast_json_pack("{s: s, s: s, s: s, s: s}",
18120  "peer_status", "Rejected",
18121  "cause", "AUTH_PEER_NOT_DYNAMIC",
18122  "address", peer_addr,
18123  "port", peer_port);
18124  }
18125  } else {
18126  transmit_response(p, "404 Not found", &p->initreq);
18128  const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr));
18129  const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr));
18130 
18131  blob = ast_json_pack("{s: s, s: s, s: s, s: s}",
18132  "peer_status", "Rejected",
18133  "cause", (res == AUTH_USERNAME_MISMATCH) ? "AUTH_USERNAME_MISMATCH" : "URI_NOT_FOUND",
18134  "address", peer_addr,
18135  "port", peer_port);
18136  }
18137  }
18138  }
18139  break;
18140  case AUTH_BAD_TRANSPORT:
18141  default:
18142  break;
18143  }
18144 
18145  if (peer && peer->endpoint) {
18147  }
18148  }
18149  if (peer) {
18150  sip_unref_peer(peer, "register_verify: sip_unref_peer: tossing stack peer pointer at end of func");
18151  }
18152 
18153  return res;
18154 }
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:290
#define check_request_transport(peer, tmpl)
generic function for determining if a correct transport is being used to contact a peer ...
Definition: chan_sip.c:2498
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
struct ast_sockaddr addr
Definition: sip.h:1352
#define FALSE
Definition: app_minivm.c:521
char * get_in_brackets(char *tmp)
Pick out text in brackets from character string.
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
struct sip_peer * sip_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.
Definition: chan_sip.c:5851
struct ast_endpoint * ast_endpoint_create(const char *tech, const char *resource)
Create an endpoint struct.
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
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
Definition: chan_sip.c:31314
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define LOG_WARNING
Definition: logger.h:274
static int tmp()
Definition: bt_open.c:389
#define SIP_NAT_FORCE_RPORT
Definition: sip.h:283
#define ao2_t_link(container, obj, tag)
Add an object to a container.
Definition: astobj2.h:1547
check_auth_result
Authentication result from check_auth* functions.
Definition: sip.h:517
unsigned short host_dynamic
Definition: sip.h:1314
void ast_endpoint_set_state(struct ast_endpoint *endpoint, enum ast_endpoint_state state)
Updates the state of the given endpoint.
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
#define ao2_unlock(a)
Definition: astobj2.h:730
static struct test_val c
struct ast_flags flags[3]
Definition: sip.h:1075
#define ast_copy_flags(dest, src, flagz)
Definition: utils.h:84
#define NULL
Definition: resample.c:96
Domain data structure.
Definition: sip.h:888
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...
Definition: chan_sip.c:17714
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
char name[80]
Definition: sip.h:1274
static struct ao2_container * peers_by_ip
Definition: chan_sip.c:1053
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
static char * ast_sockaddr_stringify_port(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return a port only.
Definition: netsock2.h:362
static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req)
Transmit response, no retransmits.
Definition: chan_sip.c:12655
#define ast_log
Definition: astobj2.c:42
int ast_devstate_changed(enum ast_device_state state, enum ast_devstate_cache cachable, const char *fmt,...)
Tells Asterisk the State for Device is changed.
Definition: devicestate.c:510
struct ast_acl_list * acl
Definition: sip.h:1363
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
struct sip_request initreq
Definition: sip.h:1151
static char * remove_uri_parameters(char *uri)
Definition: chan_sip.c:14275
#define ao2_lock(a)
Definition: astobj2.h:718
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static int sip_send_mwi_to_peer(struct sip_peer *peer, int cache_only)
Send message waiting indication to alert peer that they&#39;ve got voicemail.
Definition: chan_sip.c:29756
int expiry
Definition: sip.h:1118
const ast_string_field md5secret
Definition: sip.h:1306
enum ast_acl_sense ast_apply_acl(struct ast_acl_list *acl_list, const struct ast_sockaddr *addr, const char *purpose)
Apply a set of rules to a given IP address.
Definition: acl.c:800
static void extract_host_from_hostport(char **hostport)
Terminate a host:port at the &#39;:&#39;.
Definition: chan_sip.c:17831
#define SIP_PEDANTIC_DECODE(str)
Definition: chan_sip.c:813
int expire
Definition: sip.h:1341
#define LOG_ERROR
Definition: logger.h:285
struct ast_endpoint * endpoint
Definition: sip.h:1379
#define ao2_t_global_obj_ref(holder, tag)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:923
const ast_string_field fullcontact
Definition: sip.h:1306
static void update_peer_lastmsgssent(struct sip_peer *peer, int value, int locked)
Definition: chan_sip.c:17841
struct stasis_message_type * ast_endpoint_state_type(void)
Message type for endpoint state changes.
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
#define LOG_NOTICE
Definition: logger.h:263
static struct sip_peer * temp_peer(const char *name)
Create temporary peer (used in autocreatepeer mode)
Definition: chan_sip.c:31550
char * strcasestr(const char *, const char *)
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
static void build_contact(struct sip_pvt *p, struct sip_request *req, int incoming)
Build contact header.
Definition: chan_sip.c:14385
static const char name[]
Definition: cdr_mysql.c:74
#define FINDPEERS
Definition: sip.h:53
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
int alwaysauthreject
Definition: sip.h:760
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)
Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers requ...
Definition: chan_sip.c:17341
void ast_endpoint_blob_publish(struct ast_endpoint *endpoint, struct stasis_message_type *type, struct ast_json *blob)
Creates and publishes a ast_endpoint_blob message.
#define SIP_PENDINGBYE
Definition: sip.h:262
void sip_cancel_destroy(struct sip_pvt *pvt)
Cancel destruction of SIP dialog.
Definition: chan_sip.c:4464
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
struct ast_flags flags[3]
Definition: sip.h:1335
static int transmit_response_with_date(struct sip_pvt *p, const char *msg, const struct sip_request *req)
Add date before transmitting response.
Definition: chan_sip.c:12724
#define TRUE
Definition: app_minivm.c:518
const ast_string_field secret
Definition: sip.h:1306
enum autocreatepeer_mode autocreatepeer
Definition: sip.h:757
char ignore
Definition: sip.h:839
static int global_authfailureevents
Definition: chan_sip.c:846
static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, struct sip_peer *p, struct sip_request *req)
Parse contact header and save registration (peer registration)
Definition: chan_sip.c:16961
Abstract JSON element (object, array, string, int, ...).
static void update_peer(struct sip_peer *p, int expire)
Update peer data in database (if used)
Definition: chan_sip.c:5382
static char * terminate_uri(char *uri)
Definition: chan_sip.c:17815
static void set_peer_nat(const struct sip_pvt *p, struct sip_peer *peer)
Set the peers nat flags if they are using auto_* settings.
Definition: chan_sip.c:19103
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
Definition: chan_sip.c:16880
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ registry_cmp_cb()

static int registry_cmp_cb ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 34672 of file chan_sip.c.

References CMP_MATCH, sip_registry::configvalue, OBJ_SEARCH_KEY, OBJ_SEARCH_MASK, and OBJ_SEARCH_OBJECT.

Referenced by load_module().

34673 {
34674  const struct sip_registry *object_left = obj;
34675  const struct sip_registry *object_right = arg;
34676  const char *right_key = arg;
34677  int cmp;
34678 
34679  switch (flags & OBJ_SEARCH_MASK) {
34680  case OBJ_SEARCH_OBJECT:
34681  right_key = object_right->configvalue;
34682  /* Fall through */
34683  case OBJ_SEARCH_KEY:
34684  cmp = strcmp(object_left->configvalue, right_key);
34685  break;
34686  default:
34687  cmp = 0;
34688  break;
34689  }
34690  if (cmp) {
34691  return 0;
34692  }
34693  return CMP_MATCH;
34694 }
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
Registrations with other SIP proxies.
Definition: sip.h:1396
The arg parameter is an object of the same type.
Definition: astobj2.h:1091
Search option field mask.
Definition: astobj2.h:1076
const ast_string_field configvalue
Definition: sip.h:1414

◆ registry_hash_cb()

static int registry_hash_cb ( const void *  obj,
const int  flags 
)
static

Definition at line 34651 of file chan_sip.c.

References ast_assert, ast_str_hash(), OBJ_SEARCH_KEY, OBJ_SEARCH_MASK, and OBJ_SEARCH_OBJECT.

Referenced by load_module().

34652 {
34653  const struct sip_registry *object;
34654  const char *key;
34655 
34656  switch (flags & OBJ_SEARCH_MASK) {
34657  case OBJ_SEARCH_KEY:
34658  key = obj;
34659  break;
34660  case OBJ_SEARCH_OBJECT:
34661  object = obj;
34662  key = object->configvalue;
34663  break;
34664  default:
34665  /* Hash can only work on something with a full key. */
34666  ast_assert(0);
34667  return 0;
34668  }
34669  return ast_str_hash(key);
34670 }
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
Registrations with other SIP proxies.
Definition: sip.h:1396
#define ast_assert(a)
Definition: utils.h:695
The arg parameter is an object of the same type.
Definition: astobj2.h:1091
Search option field mask.
Definition: astobj2.h:1076
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition: strings.h:1206

◆ regstate2str()

static const char * regstate2str ( enum sipregistrystate  regstate)
static

Convert registration state status to string.

Definition at line 15847 of file chan_sip.c.

References map_x_s().

Referenced by handle_response_register(), manager_show_registry(), sip_reg_timeout(), and sip_show_registry().

15848 {
15849  return map_x_s(regstatestrings, regstate, "Unknown");
15850 }
enum sipregistrystate regstate
Definition: sip.h:1425
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
Definition: chan_sip.c:2411
static const struct _map_x_s regstatestrings[]
Definition: chan_sip.c:15834

◆ reinvite_timeout()

static int reinvite_timeout ( const void *  data)
static

Definition at line 7158 of file chan_sip.c.

References ast_channel_unlock, ast_channel_unref, check_pendings(), dialog_unref, sip_pvt::reinviteid, sip_pvt_lock_full(), and sip_pvt_unlock.

Referenced by sip_hangup().

7159 {
7160  struct sip_pvt *dialog = (struct sip_pvt *) data;
7161  struct ast_channel *owner;
7162 
7163  owner = sip_pvt_lock_full(dialog);
7164  dialog->reinviteid = -1;
7165  check_pendings(dialog);
7166  if (owner) {
7167  ast_channel_unlock(owner);
7168  ast_channel_unref(owner);
7169  }
7170  sip_pvt_unlock(dialog);
7171  dialog_unref(dialog, "reinviteid complete");
7172  return 0;
7173 }
Main Channel structure associated with a channel.
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
int reinviteid
Definition: sip.h:1157
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
static struct ast_channel * sip_pvt_lock_full(struct sip_pvt *pvt)
Definition: chan_sip.c:9400
#define ast_channel_unlock(chan)
Definition: channel.h:2946
static void check_pendings(struct sip_pvt *p)
Check pending actions on SIP call.
Definition: chan_sip.c:23735

◆ reload()

static int reload ( void  )
static

Part of Asterisk module interface.

Definition at line 34459 of file chan_sip.c.

References AST_MODULE_LOAD_SUCCESS, NULL, and sip_reload().

Referenced by unload_module().

34460 {
34461  sip_reload(0, 0, NULL);
34462  return AST_MODULE_LOAD_SUCCESS;
34463 }
#define NULL
Definition: resample.c:96
static char * sip_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Force reload of module from cli.
Definition: chan_sip.c:34418

◆ reload_config()

static int reload_config ( enum channelreloadreason  reason)
static

Re-read SIP.conf config file.

Note
This function reloads all config data, except for active peers (with registrations). They will only change configuration data at restart, not at reload. SIP debug and recordhistory state will not change

< Don't force proxy usage, use route: headers

< Keep track of hold status for a peer

< Match auth username if available instead of From: Default off.

< Default DTMF setting: RFC2833

< Allow re-invites

< Default to nat=auto_force_rport

Definition at line 32514 of file chan_sip.c.

References ast_tcptls_session_args::accept_fd, sip_settings::accept_outofcall_message, acl_change_stasis_subscribe(), add_realm_authentication(), add_sip_domain(), sip_peer::addr, sip_settings::allow_external_domains, sip_settings::allowguest, sip_settings::allowsubscribe, sip_settings::allowtransfer, sip_settings::alwaysauthreject, ao2_t_callback, ao2_t_link, ao2_t_ref, AST_AF_INET, ast_append_acl(), 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_DEFAULT_WEBSOCKET_WRITE_TIMEOUT, ast_enable_packet_fragmentation(), ast_false(), ast_find_ourip(), AST_FLAGS_ALL, ast_format_cap_update_by_allow_disallow(), ast_free, ast_free_acl_list(), ast_free_ha(), ast_get_indication_zone(), ast_get_version(), ast_jb_read_conf(), AST_LIST_EMPTY, ast_log, AST_MAX_CONTEXT, ast_mutex_lock, ast_mutex_unlock, ast_parse_arg(), ast_rtp_dtls_cfg_free(), ast_rtp_dtls_cfg_parse(), ast_rtp_dtls_cfg_validate(), ast_set2_flag, ast_set_flag, ast_set_qos(), ast_skip_blanks(), ast_sockaddr_cmp(), ast_sockaddr_cmp_addr(), ast_sockaddr_copy(), ast_sockaddr_is_any(), ast_sockaddr_is_ipv6(), ast_sockaddr_isnull(), ast_sockaddr_parse(), ast_sockaddr_port, ast_sockaddr_resolve_first_af(), 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_tone_zone_unref(), AST_TRANSPORT_TCP, AST_TRANSPORT_TLS, AST_TRANSPORT_UDP, AST_TRANSPORT_WS, AST_TRANSPORT_WSS, ast_true(), ast_unload_realtime(), ast_variable_browse(), ast_variable_retrieve(), ast_verb, ast_websocket_add_protocol(), ast_websocket_remove_protocol(), sip_settings::auth_message_requests, sip_settings::auth_options_requests, authl_lock, authlimit, authtimeout, sip_settings::autocreatepeer, AUTOPEERS_DISABLED, AUTOPEERS_PERSIST, AUTOPEERS_VOLATILE, bindaddr, build_peer(), ast_tls_config::cafile, ast_rtp_dtls_cfg::cafile, ast_tls_config::capath, ast_rtp_dtls_cfg::capath, sip_settings::caps, ast_tls_config::certfile, ast_rtp_dtls_cfg::certfile, CHANNEL_ACL_RELOAD, CHANNEL_MODULE_LOAD, ast_tls_config::cipher, ast_rtp_dtls_cfg::cipher, cleanup_all_regs(), cleanup_stale_contexts(), clear_sip_domains(), sip_settings::compactheaders, config, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, sip_settings::contact_acl, context, DEFAULT_ACCEPT_OUTOFCALL_MESSAGE, DEFAULT_ALLOW_EXT_DOM, DEFAULT_ALLOWGUEST, DEFAULT_ALWAYSAUTHREJECT, DEFAULT_AUTH_MESSAGE, DEFAULT_AUTH_OPTIONS, DEFAULT_AUTHLIMIT, DEFAULT_AUTHTIMEOUT, DEFAULT_AUTOCREATEPEER, DEFAULT_CALLCOUNTER, DEFAULT_CALLERID, default_callerid, DEFAULT_COMPACTHEADERS, DEFAULT_CONTEXT, sip_settings::default_context, DEFAULT_COS_AUDIO, DEFAULT_COS_SIP, DEFAULT_COS_TEXT, DEFAULT_COS_VIDEO, DEFAULT_DEFAULT_EXPIRY, DEFAULT_DOMAINSASREALM, DEFAULT_ENGINE, default_engine, default_expiry, default_fromdomain, default_fromdomainport, DEFAULT_KEEPALIVE, default_keepalive, DEFAULT_KEEPALIVE_INTERVAL, default_language, DEFAULT_LEGACY_USEROPTION_PARSING, DEFAULT_MATCHEXTERNADDRLOCALLY, DEFAULT_MAX_CALL_BITRATE, DEFAULT_MAX_EXPIRY, DEFAULT_MAX_FORWARDS, sip_settings::default_max_forwards, DEFAULT_MAX_SE, default_maxcallbitrate, DEFAULT_MAXMS, DEFAULT_MIN_EXPIRY, DEFAULT_MIN_SE, DEFAULT_MOHINTERPRET, default_mohinterpret, DEFAULT_MOHSUGGEST, default_mohsuggest, DEFAULT_MWI_EXPIRY, DEFAULT_MWI_FROM, default_mwi_from, DEFAULT_NOTIFYCID, DEFAULT_NOTIFYMIME, default_notifymime, DEFAULT_NOTIFYRINGING, DEFAULT_PARKINGLOT, default_parkinglot, DEFAULT_PEDANTIC, default_primary_transport, DEFAULT_QUALIFY, default_qualify, DEFAULT_QUALIFY_GAP, DEFAULT_QUALIFY_PEERS, DEFAULT_QUALIFYFREQ, DEFAULT_REALM, DEFAULT_RECORD_FEATURE, sip_settings::default_record_off_feature, sip_settings::default_record_on_feature, DEFAULT_REGEXTENONQUALIFY, DEFAULT_REGISTRATION_TIMEOUT, DEFAULT_RTPKEEPALIVE, DEFAULT_SDPOWNER, DEFAULT_SDPSESSION, DEFAULT_SEND_DIVERSION, DEFAULT_SRVLOOKUP, DEFAULT_STORE_SIP_CAUSE, sip_settings::default_subscribecontext, DEFAULT_T1MIN, DEFAULT_TIMER_T1, DEFAULT_TOS_AUDIO, DEFAULT_TOS_SIP, DEFAULT_TOS_TEXT, DEFAULT_TOS_VIDEO, default_transports, DEFAULT_USERAGENT, DEFAULT_VMEXTEN, default_vmexten, default_zone, sip_settings::directrtpsetup, DISABLED, sip_settings::disallowed_methods, display_nat_warning(), sip_settings::domainsasrealm, dumphistory, ast_tls_config::enabled, ast_rtp_dtls_cfg::enabled, ENABLED, errno, error(), externaddr, externexpire, externhost, externrefresh, externtcpport, externtlsport, FALSE, sip_peer::flags, sip_proxy::force, gen, global_authfailureevents, global_autoframing, global_callcounter, global_cos_audio, global_cos_sip, global_cos_text, global_cos_video, global_dynamic_exclude_static, global_jbconf, global_match_auth_username, global_max_se, global_min_se, global_prematuremediafilter, global_qualify_gap, global_qualify_peers, global_qualifyfreq, global_refer_addheaders, global_reg_retry_403, global_reg_timeout, global_regattempts_max, global_relaxdtmf, global_rtpholdtimeout, global_rtpkeepalive, global_rtptimeout, global_sdpowner, global_sdpsession, global_shrinkcallerid, global_st_mode, global_st_refresher, global_store_sip_cause, global_t1, global_t1min, global_t38_maxdatagram, global_timer_b, global_tos_audio, global_tos_sip, global_tos_text, global_tos_video, global_useragent, handle_common_options(), handle_t38_options(), host, IGNORE_CONTEXT, sip_settings::ignore_regexpire, internip, sip_settings::legacy_useroption_parsing, ast_variable::lineno, ast_tcptls_session_args::local_address, LOG_ERROR, LOG_NOTICE, LOG_WARNING, mark_parsed_methods(), sip_settings::matchexternaddrlocally, max_expiry, max_subexpiry, MAXHOSTNAMELEN, media_address, sip_settings::messagecontext, min_expiry, min_subexpiry, mwi_expiry, ast_variable::name, netlock, network_change_stasis_subscribe(), network_change_stasis_unsubscribe(), ast_variable::next, notify_config, sip_settings::notifycid, sip_settings::notifyhold, sip_settings::notifyringing, NOTIFYRINGING_DISABLED, NOTIFYRINGING_ENABLED, NOTIFYRINGING_NOTINUSE, NULL, OBJ_NODATA, ourport_tcp, ourport_tls, sip_settings::outboundproxy, PARSE_ADDR, PARSE_DEFAULT, PARSE_IN_RANGE, PARSE_INT32, sip_settings::pedanticsipchecking, peer_markall_autopeers_func(), peer_markall_func(), sip_settings::peer_rtupdate, port_str2int(), proxy_from_config(), ast_tls_config::pvtfile, ast_rtp_dtls_cfg::pvtfile, sip_settings::realm, recordhistory, sip_settings::regcontext, sip_settings::regextenonqualify, register_realtime_peers_with_callbackextens(), sip_settings::rtautoclear, rtpbindaddr, sip_settings::rtsave_path, sip_settings::rtsave_sysname, S_OR, sip_settings::send_diversion, SESSION_TIMER_MODE_ACCEPT, SESSION_TIMER_REFRESHER_PARAM_UAS, sip_cfg, sip_debug_config, sip_debug_console, SIP_DIRECT_MEDIA, SIP_DOMAIN_AUTO, SIP_DOMAIN_CONFIG, SIP_DTMF_RFC2833, SIP_PAGE2_ALLOWOVERLAP_YES, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_FAX_DETECT, SIP_PAGE2_IGNORESDPVERSION, SIP_PAGE2_PREFERRED_CODEC, SIP_PAGE2_Q850_REASON, SIP_PAGE2_RTAUTOCLEAR, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_TEXTSUPPORT, SIP_PAGE2_VIDEOSUPPORT, SIP_PAGE2_VIDEOSUPPORT_ALWAYS, SIP_PAGE3_DISCARD_REMOTE_HOLD_RETRIEVAL, SIP_PAGE3_ICE_SUPPORT, SIP_PAGE3_NAT_AUTO_RPORT, SIP_PAGE3_SNOM_AOC, sip_register(), sip_set_default_format_capabilities(), sip_subscribe_mwi(), SIP_TYPE_PEER, SIP_TYPE_USER, SIP_UNKNOWN, sip_unref_peer, SIP_USEREQPHONE, sip_websocket_callback(), sipdebug, sipsock, sip_settings::srvlookup, STANDARD_SIP_PORT, STANDARD_TLS_PORT, str2stmode(), str2strefresherparam(), strsep(), sip_settings::tcp_enabled, ast_tcptls_session_args::tls_cfg, tmp(), TRANSFER_CLOSED, TRANSFER_OPENFORALL, TRUE, sip_peer::type, used_context, ast_variable::value, sip_settings::websocket_enabled, and sip_settings::websocket_write_timeout.

Referenced by load_module(), and sip_do_reload().

32515 {
32516  struct ast_config *cfg, *ucfg;
32517  struct ast_variable *v;
32518  struct sip_peer *peer;
32519  char *cat, *stringp, *context, *oldregcontext;
32520  char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT];
32521  struct ast_flags mask[3] = {{0}};
32522  struct ast_flags setflags[3] = {{0}};
32523  struct ast_flags config_flags = { (reason == CHANNEL_MODULE_LOAD || reason == CHANNEL_ACL_RELOAD) ? 0 : ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? 0 : CONFIG_FLAG_FILEUNCHANGED };
32524  int auto_sip_domains = FALSE;
32525  struct ast_sockaddr old_bindaddr = bindaddr;
32526  int registry_count = 0, peer_count = 0, timerb_set = 0, timert1_set = 0;
32527  int subscribe_network_change = 1;
32528  time_t run_start, run_end;
32529  int bindport = 0;
32530  int acl_change_subscription_needed = 0;
32531  int min_subexpiry_set = 0, max_subexpiry_set = 0;
32532  int websocket_was_enabled = sip_cfg.websocket_enabled;
32533 
32534  run_start = time(0);
32535  ast_unload_realtime("sipregs");
32536  ast_unload_realtime("sippeers");
32537  cfg = ast_config_load(config, config_flags);
32538 
32539  /* We *must* have a config file otherwise stop immediately */
32540  if (!cfg) {
32541  ast_log(LOG_NOTICE, "Unable to load config %s\n", config);
32542  return -1;
32543  } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
32544  ucfg = ast_config_load("users.conf", config_flags);
32545  if (ucfg == CONFIG_STATUS_FILEUNCHANGED) {
32546  return 1;
32547  } else if (ucfg == CONFIG_STATUS_FILEINVALID) {
32548  ast_log(LOG_ERROR, "Contents of users.conf are invalid and cannot be parsed\n");
32549  return 1;
32550  }
32551  /* Must reread both files, because one changed */
32552  ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
32553  if ((cfg = ast_config_load(config, config_flags)) == CONFIG_STATUS_FILEINVALID) {
32554  ast_log(LOG_ERROR, "Contents of %s are invalid and cannot be parsed\n", config);
32555  ast_config_destroy(ucfg);
32556  return 1;
32557  }
32558  if (!cfg) {
32559  /* should have been able to reload here */
32560  ast_log(LOG_NOTICE, "Unable to load config %s\n", config);
32561  return -1;
32562  }
32563  } else if (cfg == CONFIG_STATUS_FILEINVALID) {
32564  ast_log(LOG_ERROR, "Contents of %s are invalid and cannot be parsed\n", config);
32565  return 1;
32566  } else {
32567  ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
32568  if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) {
32569  ast_log(LOG_ERROR, "Contents of users.conf are invalid and cannot be parsed\n");
32570  ast_config_destroy(cfg);
32571  return 1;
32572  }
32573  }
32574 
32576 
32577  default_tls_cfg.enabled = FALSE; /* Default: Disable TLS */
32578  default_dtls_cfg.enabled = FALSE; /* Default: Disable DTLS too */
32579 
32580  if (reason != CHANNEL_MODULE_LOAD) {
32581  ast_debug(4, "--------------- SIP reload started\n");
32582 
32585  if (authl) {
32586  ao2_t_ref(authl, -1, "Removing old global authentication");
32587  authl = NULL;
32588  }
32590 
32591  /* Then, actually destroy users and registry */
32592  cleanup_all_regs();
32593  ast_debug(4, "--------------- Done destroying registry list\n");
32594  ao2_t_callback(peers, OBJ_NODATA, peer_markall_func, NULL, "callback to mark all peers");
32595  }
32596 
32597  /* Reset certificate handling for TLS and DTLS sessions */
32598  if (reason != CHANNEL_MODULE_LOAD) {
32605  }
32606  default_tls_cfg.certfile = ast_strdup(AST_CERTFILE); /*XXX Not sure if this is useful */
32611  /* Using the same idea fro DTLS as the code block above for TLS */
32617 
32618  /* Initialize copy of current sip_cfg.regcontext for later use in removing stale contexts */
32619  ast_copy_string(oldcontexts, sip_cfg.regcontext, sizeof(oldcontexts));
32620  oldregcontext = oldcontexts;
32621 
32622  /* Clear all flags before setting default values */
32623  /* Preserve debugging settings for console */
32628 
32629  /* Reset IP addresses */
32630  ast_sockaddr_parse(&bindaddr, "0.0.0.0:0", 0);
32631  memset(&internip, 0, sizeof(internip));
32632 
32633  /* Free memory for local network address mask */
32635  memset(&localaddr, 0, sizeof(localaddr));
32636  memset(&externaddr, 0, sizeof(externaddr));
32637  memset(&media_address, 0, sizeof(media_address));
32638  memset(&rtpbindaddr, 0, sizeof(rtpbindaddr));
32639  memset(&sip_cfg.outboundproxy, 0, sizeof(struct sip_proxy));
32640  sip_cfg.outboundproxy.force = FALSE; /*!< Don't force proxy usage, use route: headers */
32645  externtcpport = 0;
32646  externtlsport = 0;
32656 
32657  externhost[0] = '\0'; /* External host name (for behind NAT DynDNS support) */
32658  externexpire = 0; /* Expiration for DNS re-issuing */
32659  externrefresh = 10;
32660 
32661  /* Reset channel settings to default before re-configuring */
32662  sip_cfg.allow_external_domains = DEFAULT_ALLOW_EXT_DOM; /* Allow external invites */
32663  sip_cfg.regcontext[0] = '\0';
32670  sip_cfg.notifyhold = FALSE; /*!< Keep track of hold status for a peer */
32671  sip_cfg.directrtpsetup = FALSE; /* Experimental feature, disabled by default */
32675  sip_cfg.messagecontext[0] = '\0';
32679  sip_cfg.contact_acl = NULL; /* Reset the contact ACL */
32680  snprintf(global_useragent, sizeof(global_useragent), "%s %s", DEFAULT_USERAGENT, ast_get_version());
32682  snprintf(global_sdpowner, sizeof(global_sdpowner), "%s", DEFAULT_SDPOWNER);
32695  global_autoframing = 0;
32698  global_match_auth_username = FALSE; /*!< Match auth username if available instead of From: Default off. */
32699  global_rtptimeout = 0;
32702  sip_cfg.allowtransfer = TRANSFER_OPENFORALL; /* Merrily accept all transfers by default */
32703  sip_cfg.rtautoclear = 120;
32704  ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE); /* Default for all devices: TRUE */
32705  ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP_YES); /* Default for all devices: Yes */
32707  global_dynamic_exclude_static = 0; /* Exclude static peers */
32711 
32712  /* Session-Timers */
32717 
32718  /* Peer poking settings */
32721 
32722  /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for devices */
32728  default_language[0] = '\0';
32729  default_fromdomain[0] = '\0';
32733  default_zone[0] = '\0';
32738  ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */
32739  ast_set_flag(&global_flags[0], SIP_DIRECT_MEDIA); /*!< Allow re-invites */
32740  ast_set_flag(&global_flags[2], SIP_PAGE3_NAT_AUTO_RPORT); /*!< Default to nat=auto_force_rport */
32743 
32744  /* Debugging settings, always default to off */
32745  dumphistory = FALSE;
32746  recordhistory = FALSE;
32748 
32749  /* Misc settings for the channel */
32765 
32767 
32768  /* Copy the default jb config over global_jbconf */
32769  memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
32770 
32775 
32776  /* Read the [general] config section of sip.conf (or from realtime config) */
32777  for (v = ast_variable_browse(cfg, "general"); v; v = v->next) {
32778  if (handle_common_options(&setflags[0], &mask[0], v)) {
32779  continue;
32780  }
32781  if (handle_t38_options(&setflags[0], &mask[0], v, &global_t38_maxdatagram)) {
32782  continue;
32783  }
32784  /* handle jb conf */
32785  if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) {
32786  continue;
32787  }
32788 
32789  /* Load default dtls configuration */
32791 
32792  /* handle tls conf, don't allow setting of tlsverifyclient as it isn't supported by chan_sip */
32793  if (!strcasecmp(v->name, "tlsverifyclient")) {
32794  ast_log(LOG_WARNING, "Ignoring unsupported option 'tlsverifyclient'\n");
32795  continue;
32796  } else if (!ast_tls_read_conf(&default_tls_cfg, &sip_tls_desc, v->name, v->value)) {
32797  continue;
32798  }
32799 
32800  if (!strcasecmp(v->name, "context")) {
32802  } else if (!strcasecmp(v->name, "recordonfeature")) {
32804  } else if (!strcasecmp(v->name, "recordofffeature")) {
32806  } else if (!strcasecmp(v->name, "subscribecontext")) {
32808  } else if (!strcasecmp(v->name, "callcounter")) {
32809  global_callcounter = ast_true(v->value) ? 1 : 0;
32810  } else if (!strcasecmp(v->name, "allowguest")) {
32811  sip_cfg.allowguest = ast_true(v->value) ? 1 : 0;
32812  } else if (!strcasecmp(v->name, "realm")) {
32814  } else if (!strcasecmp(v->name, "domainsasrealm")) {
32816  } else if (!strcasecmp(v->name, "useragent")) {
32818  ast_debug(1, "Setting SIP channel User-Agent Name to %s\n", global_useragent);
32819  } else if (!strcasecmp(v->name, "sdpsession")) {
32821  } else if (!strcasecmp(v->name, "sdpowner")) {
32822  /* Field cannot contain spaces */
32823  if (!strstr(v->value, " ")) {
32825  } else {
32826  ast_log(LOG_WARNING, "'%s' must not contain spaces at line %d. Using default.\n", v->value, v->lineno);
32827  }
32828  } else if (!strcasecmp(v->name, "allowtransfer")) {
32830  } else if (!strcasecmp(v->name, "rtcachefriends")) {
32832  } else if (!strcasecmp(v->name, "rtsavesysname")) {
32834  } else if (!strcasecmp(v->name, "rtsavepath")) {
32836  } else if (!strcasecmp(v->name, "rtupdate")) {
32838  } else if (!strcasecmp(v->name, "ignoreregexpire")) {
32840  } else if (!strcasecmp(v->name, "timert1")) {
32841  /* Defaults to 500ms, but RFC 3261 states that it is recommended
32842  * for the value to be set higher, though a lower value is only
32843  * allowed on private networks unconnected to the Internet. */
32844  global_t1 = atoi(v->value);
32845  } else if (!strcasecmp(v->name, "timerb")) {
32846  int tmp = atoi(v->value);
32847  if (tmp < 500) {
32848  global_timer_b = global_t1 * 64;
32849  ast_log(LOG_WARNING, "Invalid value for timerb ('%s'). Setting to default ('%d').\n", v->value, global_timer_b);
32850  }
32851  timerb_set = 1;
32852  } else if (!strcasecmp(v->name, "t1min")) {
32853  global_t1min = atoi(v->value);
32854  } else if (!strcasecmp(v->name, "transport")) {
32855  char *val = ast_strdupa(v->value);
32856  char *trans;
32857 
32859  while ((trans = strsep(&val, ","))) {
32860  trans = ast_skip_blanks(trans);
32861 
32862  if (!strncasecmp(trans, "udp", 3)) {
32864  } else if (!strncasecmp(trans, "tcp", 3)) {
32866  } else if (!strncasecmp(trans, "tls", 3)) {
32868  } else if (!strncasecmp(trans, "wss", 3)) {
32870  } else if (!strncasecmp(trans, "ws", 2)) {
32872  } else {
32873  ast_log(LOG_NOTICE, "'%s' is not a valid transport type. if no other is specified, udp will be used.\n", trans);
32874  }
32875  if (default_primary_transport == 0) {
32877  }
32878  }
32879  } else if (!strcasecmp(v->name, "tcpenable")) {
32880  if (!ast_false(v->value)) {
32881  ast_debug(2, "Enabling TCP socket for listening\n");
32883  }
32884  } else if (!strcasecmp(v->name, "tcpbindaddr")) {
32885  if (ast_parse_arg(v->value, PARSE_ADDR,
32887  ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n",
32888  v->name, v->value, v->lineno, config);
32889  }
32890  ast_debug(2, "Setting TCP socket address to %s\n",
32892  } else if (!strcasecmp(v->name, "dynamic_exclude_static") || !strcasecmp(v->name, "dynamic_excludes_static")) {
32894  } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny") || !strcasecmp(v->name, "contactacl")) {
32895  int ha_error = 0;
32896  ast_append_acl(v->name + 7, v->value, &sip_cfg.contact_acl, &ha_error, &acl_change_subscription_needed);
32897  if (ha_error) {
32898  ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s. Failing to load chan_sip.so\n", v->lineno, v->value);
32899  return -1;
32900  }
32901  } else if (!strcasecmp(v->name, "rtautoclear")) {
32902  int i = atoi(v->value);
32903  if (i > 0) {
32904  sip_cfg.rtautoclear = i;
32905  } else {
32906  i = 0;
32907  }
32909  } else if (!strcasecmp(v->name, "usereqphone")) {
32911  } else if (!strcasecmp(v->name, "prematuremedia")) {
32913  } else if (!strcasecmp(v->name, "relaxdtmf")) {
32915  } else if (!strcasecmp(v->name, "vmexten")) {
32917  } else if (!strcasecmp(v->name, "rtptimeout")) {
32918  if ((sscanf(v->value, "%30d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) {
32919  ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno);
32920  global_rtptimeout = 0;
32921  }
32922  } else if (!strcasecmp(v->name, "rtpholdtimeout")) {
32923  if ((sscanf(v->value, "%30d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) {
32924  ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno);
32926  }
32927  } else if (!strcasecmp(v->name, "rtpkeepalive")) {
32928  if ((sscanf(v->value, "%30d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) {
32929  ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno);
32931  }
32932  } else if (!strcasecmp(v->name, "compactheaders")) {
32934  } else if (!strcasecmp(v->name, "notifymimetype")) {
32936  } else if (!strcasecmp(v->name, "directrtpsetup")) {
32938  } else if (!strcasecmp(v->name, "notifyringing")) {
32939  if (!strcasecmp(v->value, "notinuse")) {
32941  } else {
32943  }
32944  } else if (!strcasecmp(v->name, "notifyhold")) {
32946  } else if (!strcasecmp(v->name, "notifycid")) {
32947  if (!strcasecmp(v->value, "ignore-context")) {
32949  } else {
32951  }
32952  } else if (!strcasecmp(v->name, "alwaysauthreject")) {
32954  } else if (!strcasecmp(v->name, "auth_options_requests")) {
32955  if (ast_true(v->value)) {
32957  }
32958  } else if (!strcasecmp(v->name, "auth_message_requests")) {
32960  } else if (!strcasecmp(v->name, "accept_outofcall_message")) {
32962  } else if (!strcasecmp(v->name, "outofcall_message_context")) {
32964  } else if (!strcasecmp(v->name, "mohinterpret")) {
32966  } else if (!strcasecmp(v->name, "mohsuggest")) {
32968  } else if (!strcasecmp(v->name, "tonezone")) {
32969  struct ast_tone_zone *new_zone;
32970  if (!(new_zone = ast_get_indication_zone(v->value))) {
32971  ast_log(LOG_ERROR, "Unknown country code '%s' for tonezone in [general] at line %d. Check indications.conf for available country codes.\n", v->value, v->lineno);
32972  } else {
32973  ast_tone_zone_unref(new_zone);
32975  }
32976  } else if (!strcasecmp(v->name, "language")) {
32978  } else if (!strcasecmp(v->name, "regcontext")) {
32979  ast_copy_string(newcontexts, v->value, sizeof(newcontexts));
32980  stringp = newcontexts;
32981  /* Let's remove any contexts that are no longer defined in regcontext */
32982  cleanup_stale_contexts(stringp, oldregcontext);
32983  /* Create contexts if they don't exist already */
32984  while ((context = strsep(&stringp, "&"))) {
32985  ast_copy_string(used_context, context, sizeof(used_context));
32986  ast_context_find_or_create(NULL, NULL, context, "SIP");
32987  }
32989  } else if (!strcasecmp(v->name, "regextenonqualify")) {
32991  } else if (!strcasecmp(v->name, "legacy_useroption_parsing")) {
32993  } else if (!strcasecmp(v->name, "send_diversion")) {
32995  } else if (!strcasecmp(v->name, "callerid")) {
32997  } else if (!strcasecmp(v->name, "mwi_from")) {
32999  } else if (!strcasecmp(v->name, "fromdomain")) {
33000  char *fromdomainport;
33002  if ((fromdomainport = strchr(default_fromdomain, ':'))) {
33003  *fromdomainport++ = '\0';
33004  if (!(default_fromdomainport = port_str2int(fromdomainport, 0))) {
33005  ast_log(LOG_NOTICE, "'%s' is not a valid port number for fromdomain.\n",fromdomainport);
33006  }
33007  } else {
33009  }
33010  } else if (!strcasecmp(v->name, "outboundproxy")) {
33011  struct sip_proxy *proxy;
33012  if (ast_strlen_zero(v->value)) {
33013  ast_log(LOG_WARNING, "no value given for outbound proxy on line %d of sip.conf\n", v->lineno);
33014  continue;
33015  }
33017  if (!proxy) {
33018  ast_log(LOG_WARNING, "failure parsing the outbound proxy on line %d of sip.conf.\n", v->lineno);
33019  continue;
33020  }
33021  } else if (!strcasecmp(v->name, "autocreatepeer")) {
33022  if (!strcasecmp(v->value, "persist")) {
33024  } else {
33026  }
33027  } else if (!strcasecmp(v->name, "match_auth_username")) {
33029  } else if (!strcasecmp(v->name, "srvlookup")) {
33031  } else if (!strcasecmp(v->name, "pedantic")) {
33033  } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) {
33034  max_expiry = atoi(v->value);
33035  if (max_expiry < 1) {
33037  }
33038  } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) {
33039  min_expiry = atoi(v->value);
33040  if (min_expiry < 1) {
33042  }
33043  } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) {
33044  default_expiry = atoi(v->value);
33045  if (default_expiry < 1) {
33047  }
33048  } else if (!strcasecmp(v->name, "submaxexpirey") || !strcasecmp(v->name, "submaxexpiry")) {
33049  max_subexpiry = atoi(v->value);
33050  if (max_subexpiry < 1) {
33052  }
33053  max_subexpiry_set = 1;
33054  } else if (!strcasecmp(v->name, "subminexpirey") || !strcasecmp(v->name, "subminexpiry")) {
33055  min_subexpiry = atoi(v->value);
33056  if (min_subexpiry < 1) {
33058  }
33059  min_subexpiry_set = 1;
33060  } else if (!strcasecmp(v->name, "mwiexpiry") || !strcasecmp(v->name, "mwiexpirey")) {
33061  mwi_expiry = atoi(v->value);
33062  if (mwi_expiry < 1) {
33064  }
33065  } else if (!strcasecmp(v->name, "tcpauthtimeout")) {
33067  &authtimeout, DEFAULT_AUTHTIMEOUT, 1, INT_MAX)) {
33068  ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n",
33069  v->name, v->value, v->lineno, config);
33070  }
33071  } else if (!strcasecmp(v->name, "tcpauthlimit")) {
33073  &authlimit, DEFAULT_AUTHLIMIT, 1, INT_MAX)) {
33074  ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n",
33075  v->name, v->value, v->lineno, config);
33076  }
33077  } else if (!strcasecmp(v->name, "sipdebug")) {
33078  if (ast_true(v->value))
33080  } else if (!strcasecmp(v->name, "dumphistory")) {
33081  dumphistory = ast_true(v->value);
33082  } else if (!strcasecmp(v->name, "recordhistory")) {
33084  } else if (!strcasecmp(v->name, "registertimeout")) {
33085  global_reg_timeout = atoi(v->value);
33086  if (global_reg_timeout < 1) {
33088  }
33089  } else if (!strcasecmp(v->name, "registerattempts")) {
33090  global_regattempts_max = atoi(v->value);
33091  } else if (!strcasecmp(v->name, "register_retry_403")) {
33093  } else if (!strcasecmp(v->name, "bindaddr") || !strcasecmp(v->name, "udpbindaddr")) {
33094  if (ast_parse_arg(v->value, PARSE_ADDR, &bindaddr)) {
33095  ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
33096  }
33097  } else if (!strcasecmp(v->name, "localnet")) {
33098  struct ast_ha *na;
33099  int ha_error = 0;
33100 
33101  if (!(na = ast_append_ha("d", v->value, localaddr, &ha_error))) {
33102  ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value);
33103  } else {
33104  localaddr = na;
33105  }
33106  if (ha_error) {
33107  ast_log(LOG_ERROR, "Bad localnet configuration value line %d : %s\n", v->lineno, v->value);
33108  }
33109  } else if (!strcasecmp(v->name, "media_address")) {
33111  ast_log(LOG_WARNING, "Invalid address for media_address keyword: %s\n", v->value);
33112  } else if (!strcasecmp(v->name, "rtpbindaddr")) {
33114  ast_log(LOG_WARNING, "Invalid address for rtpbindaddr keyword: %s\n", v->value);
33115  }
33116  } else if (!strcasecmp(v->name, "externaddr") || !strcasecmp(v->name, "externip")) {
33119  "Invalid address for externaddr keyword: %s\n",
33120  v->value);
33121  }
33122  externexpire = 0;
33123  } else if (!strcasecmp(v->name, "externhost")) {
33126  ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost);
33127  }
33128  externexpire = time(NULL);
33129  } else if (!strcasecmp(v->name, "externrefresh")) {
33130  if (sscanf(v->value, "%30d", &externrefresh) != 1) {
33131  ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno);
33132  externrefresh = 10;
33133  }
33134  } else if (!strcasecmp(v->name, "externtcpport")) {
33135  if (!(externtcpport = port_str2int(v->value, 0))) {
33136  ast_log(LOG_WARNING, "Invalid externtcpport value, must be a positive integer between 1 and 65535 at line %d\n", v->lineno);
33137  }
33138  } else if (!strcasecmp(v->name, "externtlsport")) {
33139  if (!(externtlsport = port_str2int(v->value, 0))) {
33140  ast_log(LOG_WARNING, "Invalid externtlsport value, must be a positive integer between 1 and 65535 at line %d\n", v->lineno);
33141  }
33142  } else if (!strcasecmp(v->name, "allow")) {
33144  if (error) {
33145  ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value);
33146  }
33147  } else if (!strcasecmp(v->name, "disallow")) {
33149  if (error) {
33150  ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value);
33151  }
33152  } else if (!strcasecmp(v->name, "preferred_codec_only")) {
33154  } else if (!strcasecmp(v->name, "autoframing")) {
33156  } else if (!strcasecmp(v->name, "allowexternaldomains")) {
33158  } else if (!strcasecmp(v->name, "autodomain")) {
33159  auto_sip_domains = ast_true(v->value);
33160  } else if (!strcasecmp(v->name, "domain")) {
33161  char *domain = ast_strdupa(v->value);
33162  char *cntx = strchr(domain, ',');
33163 
33164  if (cntx) {
33165  *cntx++ = '\0';
33166  }
33167 
33168  if (ast_strlen_zero(cntx)) {
33169  ast_debug(1, "No context specified at line %d for domain '%s'\n", v->lineno, domain);
33170  }
33171  if (ast_strlen_zero(domain)) {
33172  ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno);
33173  } else {
33174  add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, cntx ? ast_strip(cntx) : "");
33175  }
33176  } else if (!strcasecmp(v->name, "register")) {
33177  if (sip_register(v->value, v->lineno) == 0) {
33178  registry_count++;
33179  }
33180  } else if (!strcasecmp(v->name, "mwi")) {
33181  sip_subscribe_mwi(v->value, v->lineno);
33182  } else if (!strcasecmp(v->name, "tos_sip")) {
33183  if (ast_str2tos(v->value, &global_tos_sip)) {
33184  ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, refer to QoS documentation\n", v->lineno);
33185  }
33186  } else if (!strcasecmp(v->name, "tos_audio")) {
33187  if (ast_str2tos(v->value, &global_tos_audio)) {
33188  ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, refer to QoS documentation\n", v->lineno);
33189  }
33190  } else if (!strcasecmp(v->name, "tos_video")) {
33191  if (ast_str2tos(v->value, &global_tos_video)) {
33192  ast_log(LOG_WARNING, "Invalid tos_video value at line %d, refer to QoS documentation\n", v->lineno);
33193  }
33194  } else if (!strcasecmp(v->name, "tos_text")) {
33195  if (ast_str2tos(v->value, &global_tos_text)) {
33196  ast_log(LOG_WARNING, "Invalid tos_text value at line %d, refer to QoS documentation\n", v->lineno);
33197  }
33198  } else if (!strcasecmp(v->name, "cos_sip")) {
33199  if (ast_str2cos(v->value, &global_cos_sip)) {
33200  ast_log(LOG_WARNING, "Invalid cos_sip value at line %d, refer to QoS documentation\n", v->lineno);
33201  }
33202  } else if (!strcasecmp(v->name, "cos_audio")) {
33203  if (ast_str2cos(v->value, &global_cos_audio)) {
33204  ast_log(LOG_WARNING, "Invalid cos_audio value at line %d, refer to QoS documentation\n", v->lineno);
33205  }
33206  } else if (!strcasecmp(v->name, "cos_video")) {
33207  if (ast_str2cos(v->value, &global_cos_video)) {
33208  ast_log(LOG_WARNING, "Invalid cos_video value at line %d, refer to QoS documentation\n", v->lineno);
33209  }
33210  } else if (!strcasecmp(v->name, "cos_text")) {
33211  if (ast_str2cos(v->value, &global_cos_text)) {
33212  ast_log(LOG_WARNING, "Invalid cos_text value at line %d, refer to QoS documentation\n", v->lineno);
33213  }
33214  } else if (!strcasecmp(v->name, "bindport")) {
33215  if (sscanf(v->value, "%5d", &bindport) != 1) {
33216  ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config);
33217  }
33218  } else if (!strcasecmp(v->name, "qualify")) {
33219  if (!strcasecmp(v->value, "no")) {
33220  default_qualify = 0;
33221  } else if (!strcasecmp(v->value, "yes")) {
33223  } else if (sscanf(v->value, "%30d", &default_qualify) != 1) {
33224  ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno);
33225  default_qualify = 0;
33226  }
33227  } else if (!strcasecmp(v->name, "keepalive")) {
33228  if (!strcasecmp(v->value, "no")) {
33229  default_keepalive = 0;
33230  } else if (!strcasecmp(v->value, "yes")) {
33232  } else if (sscanf(v->value, "%30d", &default_keepalive) != 1) {
33233  ast_log(LOG_WARNING, "Keep alive default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno);
33234  default_keepalive = 0;
33235  }
33236  } else if (!strcasecmp(v->name, "qualifyfreq")) {
33237  int i;
33238  if (sscanf(v->value, "%30d", &i) == 1) {
33239  global_qualifyfreq = i * 1000;
33240  } else {
33241  ast_log(LOG_WARNING, "Invalid qualifyfreq number '%s' at line %d of %s\n", v->value, v->lineno, config);
33243  }
33244  } else if (!strcasecmp(v->name, "authfailureevents")) {
33246  } else if (!strcasecmp(v->name, "maxcallbitrate")) {
33247  default_maxcallbitrate = atoi(v->value);
33248  if (default_maxcallbitrate < 0) {
33250  }
33251  } else if (!strcasecmp(v->name, "matchexternaddrlocally") || !strcasecmp(v->name, "matchexterniplocally")) {
33253  } else if (!strcasecmp(v->name, "session-timers")) {
33254  int i = (int) str2stmode(v->value);
33255  if (i < 0) {
33256  ast_log(LOG_WARNING, "Invalid session-timers '%s' at line %d of %s\n", v->value, v->lineno, config);
33258  } else {
33259  global_st_mode = i;
33260  }
33261  } else if (!strcasecmp(v->name, "session-expires")) {
33262  if (sscanf(v->value, "%30d", &global_max_se) != 1) {
33263  ast_log(LOG_WARNING, "Invalid session-expires '%s' at line %d of %s\n", v->value, v->lineno, config);
33265  }
33266  } else if (!strcasecmp(v->name, "session-minse")) {
33267  if (sscanf(v->value, "%30d", &global_min_se) != 1) {
33268  ast_log(LOG_WARNING, "Invalid session-minse '%s' at line %d of %s\n", v->value, v->lineno, config);
33270  }
33271  if (global_min_se < DEFAULT_MIN_SE) {
33272  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);
33274  }
33275  } else if (!strcasecmp(v->name, "session-refresher")) {
33276  int i = (int) str2strefresherparam(v->value);
33277  if (i < 0) {
33278  ast_log(LOG_WARNING, "Invalid session-refresher '%s' at line %d of %s\n", v->value, v->lineno, config);
33280  } else {
33281  global_st_refresher = i;
33282  }
33283  } else if (!strcasecmp(v->name, "storesipcause")) {
33285  if (global_store_sip_cause) {
33286  ast_log(LOG_WARNING, "Usage of SIP_CAUSE is deprecated. Please use HANGUPCAUSE instead.\n");
33287  }
33288  } else if (!strcasecmp(v->name, "qualifygap")) {
33289  if (sscanf(v->value, "%30d", &global_qualify_gap) != 1
33290  || global_qualify_gap < 0) {
33291  ast_log(LOG_WARNING, "Invalid qualifygap '%s' at line %d of %s\n", v->value, v->lineno, config);
33293  }
33294  } else if (!strcasecmp(v->name, "qualifypeers")) {
33295  if (sscanf(v->value, "%30d", &global_qualify_peers) != 1) {
33296  ast_log(LOG_WARNING, "Invalid pokepeers '%s' at line %d of %s\n", v->value, v->lineno, config);
33298  }
33299  } else if (!strcasecmp(v->name, "disallowed_methods")) {
33300  char *disallow = ast_strdupa(v->value);
33302  } else if (!strcasecmp(v->name, "shrinkcallerid")) {
33303  if (ast_true(v->value)) {
33305  } else if (ast_false(v->value)) {
33307  } else {
33308  ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno);
33309  }
33310  } else if (!strcasecmp(v->name, "use_q850_reason")) {
33312  } else if (!strcasecmp(v->name, "maxforwards")) {
33313  if (sscanf(v->value, "%30d", &sip_cfg.default_max_forwards) != 1
33315  ast_log(LOG_WARNING, "'%s' is not a valid maxforwards value at line %d. Using default.\n", v->value, v->lineno);
33317  }
33318  } else if (!strcasecmp(v->name, "subscribe_network_change_event")) {
33319  if (ast_true(v->value)) {
33320  subscribe_network_change = 1;
33321  } else if (ast_false(v->value)) {
33322  subscribe_network_change = 0;
33323  } else {
33324  ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno);
33325  }
33326  } else if (!strcasecmp(v->name, "snom_aoc_enabled")) {
33328  } else if (!strcasecmp(v->name, "icesupport")) {
33330  } else if (!strcasecmp(v->name, "discard_remote_hold_retrieval")) {
33332  } else if (!strcasecmp(v->name, "parkinglot")) {
33334  } else if (!strcasecmp(v->name, "refer_addheaders")) {
33336  } else if (!strcasecmp(v->name, "websocket_write_timeout")) {
33337  if (sscanf(v->value, "%30d", &sip_cfg.websocket_write_timeout) != 1
33339  ast_log(LOG_WARNING, "'%s' is not a valid websocket_write_timeout value at line %d. Using default '%d'.\n", v->value, v->lineno, AST_DEFAULT_WEBSOCKET_WRITE_TIMEOUT);
33341  }
33342  } else if (!strcasecmp(v->name, "websocket_enabled")) {
33344  }
33345  }
33346 
33347  /* Validate DTLS configuration */
33349  return -1;
33350  }
33351 
33352  /* Override global defaults if setting found in general section */
33353  ast_copy_flags(&global_flags[0], &setflags[0], mask[0].flags);
33354  ast_copy_flags(&global_flags[1], &setflags[1], mask[1].flags);
33355  ast_copy_flags(&global_flags[2], &setflags[2], mask[2].flags);
33356 
33357  /* For backwards compatibility the corresponding registration timer value is used if subscription timer value isn't set by configuration */
33358  if (!min_subexpiry_set) {
33360  }
33361  if (!max_subexpiry_set) {
33363  }
33364 
33366  ao2_t_callback(peers, OBJ_NODATA, peer_markall_autopeers_func, NULL, "callback to mark autopeers for destruction");
33367  }
33368 
33369  if (subscribe_network_change) {
33371  } else {
33373  }
33374 
33375  if (global_t1 < global_t1min) {
33376  ast_log(LOG_WARNING, "'t1min' (%d) cannot be greater than 't1timer' (%d). Resetting 't1timer' to the value of 't1min'\n", global_t1min, global_t1);
33378  }
33379 
33380  if (global_timer_b < global_t1 * 64) {
33381  if (timerb_set && timert1_set) {
33382  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);
33383  } else if (timerb_set) {
33384  if ((global_t1 = global_timer_b / 64) < global_t1min) {
33385  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);
33387  global_timer_b = global_t1 * 64;
33388  }
33389  } else {
33390  global_timer_b = global_t1 * 64;
33391  }
33392  }
33394  ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n");
33396  }
33397  /* If not or badly configured, set default transports */
33399  ast_log(LOG_WARNING, "Cannot use 'tcp' transport with tcpenable=no. Removing from available transports.\n");
33400  default_primary_transport &= ~AST_TRANSPORT_TCP;
33401  default_transports &= ~AST_TRANSPORT_TCP;
33402  }
33404  ast_log(LOG_WARNING, "Cannot use 'tls' transport with tlsenable=no. Removing from available transports.\n");
33405  default_primary_transport &= ~AST_TRANSPORT_TLS;
33406  default_transports &= ~AST_TRANSPORT_TLS;
33407  }
33408  if (!default_transports) {
33409  ast_log(LOG_WARNING, "No valid transports available, falling back to 'udp'.\n");
33411  } else if (!default_primary_transport) {
33412  ast_log(LOG_WARNING, "No valid default transport. Selecting 'udp' as default.\n");
33414  }
33415 
33416  /* Build list of authentication to various SIP realms, i.e. service providers */
33417  for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) {
33418  /* Format for authentication is auth = username:password@realm */
33419  if (!strcasecmp(v->name, "auth")) {
33421  }
33422  }
33423 
33424  if (bindport) {
33425  if (ast_sockaddr_port(&bindaddr)) {
33426  ast_log(LOG_WARNING, "bindport is also specified in bindaddr. "
33427  "Using %d.\n", bindport);
33428  }
33429  ast_sockaddr_set_port(&bindaddr, bindport);
33430  }
33431 
33432  if (!ast_sockaddr_port(&bindaddr)) {
33434  }
33435 
33436  /* Set UDP address and open socket */
33438  if (ast_find_ourip(&internip, &bindaddr, 0)) {
33439  ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n");
33440  ast_config_destroy(cfg);
33441  return 0;
33442  }
33443 
33445  if ((sipsock > -1) && (ast_sockaddr_cmp(&old_bindaddr, &bindaddr))) {
33446  close(sipsock);
33447  sipsock = -1;
33448  }
33449  if (sipsock < 0) {
33451  AF_INET6 : AF_INET, SOCK_DGRAM, 0);
33452  if (sipsock < 0) {
33453  ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno));
33454  ast_config_destroy(cfg);
33456  return -1;
33457  } else {
33458  /* Allow SIP clients on the same host to access us: */
33459  const int reuseFlag = 1;
33460 
33461  setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR,
33462  (const char*)&reuseFlag,
33463  sizeof reuseFlag);
33464 
33466 
33467  if (ast_bind(sipsock, &bindaddr) < 0) {
33468  ast_log(LOG_WARNING, "Failed to bind to %s: %s\n",
33469  ast_sockaddr_stringify(&bindaddr), strerror(errno));
33470  close(sipsock);
33471  sipsock = -1;
33472  } else {
33473  ast_verb(2, "SIP Listening on %s\n", ast_sockaddr_stringify(&bindaddr));
33475  }
33476  }
33477  } else {
33479  }
33481 
33482  /* Start TCP server */
33483  if (sip_cfg.tcp_enabled) {
33486  }
33489  }
33490  } else {
33492  }
33494  if (sip_cfg.tcp_enabled && sip_tcp_desc.accept_fd == -1) {
33495  /* TCP server start failed. Tell the admin */
33496  ast_log(LOG_ERROR, "SIP TCP Server start failed. Not listening on TCP socket.\n");
33497  } else {
33498  ast_debug(2, "SIP TCP server started\n");
33499  if (sip_tcp_desc.accept_fd >= 0) {
33500  int flags = 1;
33501  if (setsockopt(sip_tcp_desc.accept_fd, SOL_SOCKET, SO_KEEPALIVE, &flags, sizeof(flags))) {
33502  ast_log(LOG_ERROR, "Error enabling TCP keep-alive on sip socket: %s\n", strerror(errno));
33503  }
33505  }
33506  }
33507 
33508  /* Start TLS server if needed */
33510 
33516  }
33520  }
33523  ast_log(LOG_ERROR, "TLS Server start failed. Not listening on TLS socket.\n");
33525  }
33526  if (sip_tls_desc.accept_fd >= 0) {
33527  int flags = 1;
33528  if (setsockopt(sip_tls_desc.accept_fd, SOL_SOCKET, SO_KEEPALIVE, &flags, sizeof(flags))) {
33529  ast_log(LOG_ERROR, "Error enabling TCP keep-alive on sip socket: %s\n", strerror(errno));
33531  }
33533  }
33534  } else if (sip_tls_desc.tls_cfg->enabled) {
33536  ast_log(LOG_WARNING, "SIP TLS server did not load because of errors.\n");
33537  }
33538 
33539  if (ucfg) {
33540  struct ast_variable *gen;
33541  int genhassip, genregistersip;
33542  const char *hassip, *registersip;
33543 
33544  genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip"));
33545  genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip"));
33546  gen = ast_variable_browse(ucfg, "general");
33547  cat = ast_category_browse(ucfg, NULL);
33548  while (cat) {
33549  if (strcasecmp(cat, "general")) {
33550  hassip = ast_variable_retrieve(ucfg, cat, "hassip");
33551  registersip = ast_variable_retrieve(ucfg, cat, "registersip");
33552  if (ast_true(hassip) || (!hassip && genhassip)) {
33553  peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0, 0);
33554  if (peer) {
33555  /* user.conf entries are always of type friend */
33556  peer->type = SIP_TYPE_USER | SIP_TYPE_PEER;
33557  ao2_t_link(peers, peer, "link peer into peer table");
33558  if ((peer->type & SIP_TYPE_PEER) && !ast_sockaddr_isnull(&peer->addr)) {
33559  ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table");
33560  }
33561 
33562  sip_unref_peer(peer, "sip_unref_peer: from reload_config");
33563  peer_count++;
33564  }
33565  }
33566  if (ast_true(registersip) || (!registersip && genregistersip)) {
33567  char tmp[256];
33568  const char *host = ast_variable_retrieve(ucfg, cat, "host");
33569  const char *username = ast_variable_retrieve(ucfg, cat, "username");
33570  const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
33571  const char *contact = ast_variable_retrieve(ucfg, cat, "contact");
33572  const char *authuser = ast_variable_retrieve(ucfg, cat, "authuser");
33573  if (!host) {
33574  host = ast_variable_retrieve(ucfg, "general", "host");
33575  }
33576  if (!username) {
33577  username = ast_variable_retrieve(ucfg, "general", "username");
33578  }
33579  if (!secret) {
33580  secret = ast_variable_retrieve(ucfg, "general", "secret");
33581  }
33582  if (!contact) {
33583  contact = "s";
33584  }
33585  if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
33586  if (!ast_strlen_zero(secret)) {
33587  if (!ast_strlen_zero(authuser)) {
33588  snprintf(tmp, sizeof(tmp), "%s?%s:%s:%s@%s/%s", cat, username, secret, authuser, host, contact);
33589  } else {
33590  snprintf(tmp, sizeof(tmp), "%s?%s:%s@%s/%s", cat, username, secret, host, contact);
33591  }
33592  } else if (!ast_strlen_zero(authuser)) {
33593  snprintf(tmp, sizeof(tmp), "%s?%s::%s@%s/%s", cat, username, authuser, host, contact);
33594  } else {
33595  snprintf(tmp, sizeof(tmp), "%s?%s@%s/%s", cat, username, host, contact);
33596  }
33597  if (sip_register(tmp, 0) == 0) {
33598  registry_count++;
33599  }
33600  }
33601  }
33602  }
33603  cat = ast_category_browse(ucfg, cat);
33604  }
33605  ast_config_destroy(ucfg);
33606  }
33607 
33608  /* Load peers, users and friends */
33609  cat = NULL;
33610  while ( (cat = ast_category_browse(cfg, cat)) ) {
33611  const char *utype;
33612  if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication"))
33613  continue;
33614  utype = ast_variable_retrieve(cfg, cat, "type");
33615  if (!utype) {
33616  ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
33617  continue;
33618  } else {
33619  if (!strcasecmp(utype, "user")) {
33620  ;
33621  } else if (!strcasecmp(utype, "friend")) {
33622  ;
33623  } else if (!strcasecmp(utype, "peer")) {
33624  ;
33625  } else {
33626  ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf");
33627  continue;
33628  }
33629  peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0, 0);
33630  if (peer) {
33631  display_nat_warning(cat, reason, &peer->flags[0]);
33632  ao2_t_link(peers, peer, "link peer into peers table");
33633  if ((peer->type & SIP_TYPE_PEER) && !ast_sockaddr_isnull(&peer->addr)) {
33634  ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table");
33635  }
33636  sip_unref_peer(peer, "unref the result of the build_peer call. Now, the links from the tables are the only ones left.");
33637  peer_count++;
33638  }
33639  }
33640  }
33641 
33642  /* Add default domains - host name, IP address and IP:port
33643  * Only do this if user added any sip domain with "localdomains"
33644  * In order to *not* break backwards compatibility
33645  * Some phones address us at IP only, some with additional port number
33646  */
33647  if (auto_sip_domains) {
33648  char temp[MAXHOSTNAMELEN];
33649 
33650  /* First our default IP address */
33655  /* Our internal IP address, if configured */
33658  } else {
33659  ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n");
33660  }
33661 
33662  /* If TCP is running on a different IP than UDP, then add it too */
33667  }
33668 
33669  /* If TLS is running on a different IP than UDP and TCP, then add that too */
33676  }
33677 
33678  /* Our extern IP address, if configured */
33682  }
33683 
33684  /* Extern host name (NAT traversal support) */
33685  if (!ast_strlen_zero(externhost)) {
33687  }
33688 
33689  /* Our host name */
33690  if (!gethostname(temp, sizeof(temp))) {
33692  }
33693  }
33694 
33695  /* Release configuration from memory */
33696  ast_config_destroy(cfg);
33697 
33699 
33700  /* Load the list of manual NOTIFY types to support */
33701  if (notify_types) {
33703  }
33705  ast_log(LOG_ERROR, "Contents of %s are invalid and cannot be parsed.\n", notify_config);
33706  notify_types = NULL;
33707  }
33708 
33709  /* If the module is loading it's not time to enable websockets yet. */
33710  if (reason != CHANNEL_MODULE_LOAD && websocket_was_enabled != sip_cfg.websocket_enabled) {
33711  if (sip_cfg.websocket_enabled) {
33713  } else {
33715  }
33716  }
33717 
33718  run_end = time(0);
33719  ast_debug(4, "SIP reload_config done...Runtime= %d sec\n", (int)(run_end-run_start));
33720 
33721  /* If an ACL change subscription is needed and doesn't exist, we need one. */
33722  if (acl_change_subscription_needed) {
33724  }
33725 
33726  return 0;
33727 }
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:290
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
static struct ast_tcptls_session_args sip_tls_desc
The TCP/TLS server definition.
Definition: chan_sip.c:2394
#define SIP_PAGE3_ICE_SUPPORT
Definition: sip.h:390
#define DEFAULT_RECORD_FEATURE
Definition: sip.h:198
struct ast_variable * next
static unsigned int global_cos_video
Definition: chan_sip.c:839
#define DEFAULT_MAX_CALL_BITRATE
Definition: sip.h:237
static int global_shrinkcallerid
Definition: chan_sip.c:829
static unsigned int global_tos_text
Definition: chan_sip.c:836
#define SIP_DIRECT_MEDIA
Definition: sip.h:289
char * pvtfile
Definition: tcptls.h:90
int ast_rtp_dtls_cfg_parse(struct ast_rtp_dtls_cfg *dtls_cfg, const char *name, const char *value)
Parse DTLS related configuration options.
Definition: rtp_engine.c:3020
#define AST_CERTFILE
Definition: tcptls.h:62
static uint16_t externtcpport
Definition: chan_sip.c:1138
#define DEFAULT_PARKINGLOT
The default parking lot.
Definition: parking.h:40
#define DEFAULT_COS_SIP
Definition: sip.h:214
int force
Definition: sip.h:727
void ast_enable_packet_fragmentation(int sock)
Disable PMTU discovery on a socket.
Definition: main/utils.c:2221
#define SIP_PAGE2_ALLOWSUBSCRIBE
Definition: sip.h:335
struct ast_sockaddr addr
Definition: sip.h:1352
static struct ast_ha * localaddr
List of local networks We store "localnet" addresses from the config file into an access list...
Definition: chan_sip.c:1147
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&#39;d proxy. If dest is non-NULL, no allocation is performed a...
Definition: chan_sip.c:3491
#define FALSE
Definition: app_minivm.c:521
static int ourport_tcp
Definition: chan_sip.c:1149
static void sip_set_default_format_capabilities(struct ast_format_cap *cap)
Definition: chan_sip.c:32437
#define DEFAULT_MAX_FORWARDS
Definition: sip.h:67
static struct ast_tls_config default_tls_cfg
Default TLS connection configuration.
Definition: chan_sip.c:2377
static int max_expiry
Definition: chan_sip.c:668
enum notifycid_setting notifycid
Definition: sip.h:775
int matchexternaddrlocally
Definition: sip.h:769
static struct ast_tone_zone * ast_tone_zone_unref(struct ast_tone_zone *tz)
Release a reference to an ast_tone_zone.
Definition: indications.h:205
static int default_keepalive
Definition: chan_sip.c:798
void ast_tcptls_server_start(struct ast_tcptls_session_args *desc)
This is a generic (re)start routine for a TCP server, which does the socket/bind/listen and starts a ...
Definition: tcptls.c:685
static unsigned int global_cos_text
Definition: chan_sip.c:840
static int global_qualify_gap
Definition: chan_sip.c:852
int directrtpsetup
Definition: sip.h:755
static unsigned int global_tos_audio
Definition: chan_sip.c:834
Definition: ast_expr2.c:325
int ast_ssl_setup(struct ast_tls_config *cfg)
Set up an SSL server.
Definition: tcptls.c:570
static unsigned int dumphistory
Definition: chan_sip.c:842
static struct ast_sockaddr rtpbindaddr
Definition: chan_sip.c:1133
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
int ast_find_ourip(struct ast_sockaddr *ourip, const struct ast_sockaddr *bindaddr, int family)
Find our IP address.
Definition: acl.c:1052
definition of a sip proxy server
Definition: sip.h:721
#define ast_set2_flag(p, value, flag)
Definition: utils.h:94
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.
Definition: chan_sip.c:31284
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1216
int domainsasrealm
Definition: sip.h:780
int tcp_enabled
Definition: sip.h:788
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:171
#define DEFAULT_MWI_EXPIRY
Definition: sip.h:65
static int global_t1min
Definition: chan_sip.c:848
const char * ast_get_version(void)
Retrieve the Asterisk version string.
Definition: version.c:16
#define DEFAULT_TOS_VIDEO
Definition: sip.h:212
#define SIP_PAGE2_FAX_DETECT
Definition: sip.h:360
static int global_dynamic_exclude_static
Definition: chan_sip.c:862
#define SIP_PAGE2_PREFERRED_CODEC
Definition: sip.h:332
static void network_change_stasis_unsubscribe(void)
Definition: chan_sip.c:17557
#define ast_set_flag(p, flag)
Definition: utils.h:70
static struct sip_auth_container * authl
Authentication container for realm authentication.
Definition: chan_sip.c:1079
#define LOG_WARNING
Definition: logger.h:274
static char global_useragent[AST_MAX_EXTENSION]
Definition: chan_sip.c:843
#define DEFAULT_MIN_EXPIRY
Definition: sip.h:63
#define DEFAULT_PEDANTIC
Definition: sip.h:223
int ast_jb_read_conf(struct ast_jb_conf *conf, const char *varname, const char *value)
Sets jitterbuffer configuration property.
Definition: abstract_jb.c:545
int ast_unload_realtime(const char *family)
Release any resources cached for a realtime family.
Definition: main/config.c:3406
#define CONFIG_STATUS_FILEINVALID
static int global_rtptimeout
Definition: chan_sip.c:823
#define DEFAULT_QUALIFYFREQ
Definition: sip.h:97
unsigned int disallowed_methods
Definition: sip.h:772
static int tmp()
Definition: bt_open.c:389
Structure for variables, used for configurations and for channel variables.
#define SIP_DTMF_RFC2833
Definition: sip.h:276
static unsigned int global_tos_video
Definition: chan_sip.c:835
#define DEFAULT_REGISTRATION_TIMEOUT
Definition: sip.h:66
#define DEFAULT_COMPACTHEADERS
Definition: sip.h:209
static int peer_markall_func(void *device, void *arg, int flags)
Definition: chan_sip.c:32415
int auth_message_requests
Definition: sip.h:762
static struct ast_config * notify_types
Definition: chan_sip.c:1153
static char default_language[MAX_LANGUAGE]
Definition: chan_sip.c:790
#define ao2_t_link(container, obj, tag)
Add an object to a container.
Definition: astobj2.h:1547
static struct ast_tcptls_session_args sip_tcp_desc
The TCP server definition.
Definition: chan_sip.c:2383
static struct ast_sockaddr internip
our (internal) default address/port to put in SIP/SDP messages internip is initialized picking a suit...
Definition: chan_sip.c:1114
#define DEFAULT_STORE_SIP_CAUSE
Definition: sip.h:243
static const char notify_config[]
Definition: chan_sip.c:691
#define DEFAULT_TOS_TEXT
Definition: sip.h:213
static char default_fromdomain[AST_MAX_EXTENSION]
Definition: chan_sip.c:793
#define DEFAULT_AUTH_OPTIONS
Definition: sip.h:230
#define DEFAULT_MOHINTERPRET
Definition: sip.h:199
#define DEFAULT_LEGACY_USEROPTION_PARSING
Definition: sip.h:234
int srvlookup
Definition: sip.h:758
static void sip_websocket_callback(struct ast_websocket *session, struct ast_variable *parameters, struct ast_variable *headers)
SIP WebSocket connection handler.
Definition: chan_sip.c:2678
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
#define ast_mutex_lock(a)
Definition: lock.h:187
enum sip_peer_type type
Definition: sip.h:1375
#define ast_copy_flags(dest, src, flagz)
Definition: utils.h:84
#define MAXHOSTNAMELEN
Definition: network.h:69
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
static unsigned int global_t38_maxdatagram
Definition: chan_sip.c:885
static char default_callerid[AST_MAX_EXTENSION]
Definition: chan_sip.c:791
Definition: sip.h:642
int ast_str2tos(const char *value, unsigned int *tos)
Convert a string to the appropriate TOS value.
Definition: acl.c:967
#define DEFAULT_TOS_AUDIO
Definition: sip.h:211
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3328
static ast_mutex_t authl_lock
Global authentication container protection while adjusting the references.
Definition: chan_sip.c:1081
#define NULL
Definition: resample.c:96
int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares two ast_sockaddr structures.
Definition: netsock2.c:388
Domain data structure.
Definition: sip.h:888
#define DEFAULT_MWI_FROM
Definition: sip.h:203
static int default_maxcallbitrate
Definition: chan_sip.c:804
int peer_rtupdate
Definition: sip.h:750
int websocket_enabled
Definition: sip.h:791
static int peer_markall_autopeers_func(void *device, void *arg, int flags)
Definition: chan_sip.c:32424
#define DEFAULT_ALLOWGUEST
Definition: sip.h:205
int allowsubscribe
Definition: sip.h:777
#define DEFAULT_COS_TEXT
Definition: sip.h:217
Socket address structure.
Definition: netsock2.h:97
static unsigned int default_transports
Definition: chan_sip.c:806
#define SIP_PAGE3_SNOM_AOC
Definition: sip.h:384
int ast_bind(int sockfd, const struct ast_sockaddr *addr)
Wrapper around bind(2) that uses struct ast_sockaddr.
Definition: netsock2.c:590
#define ast_verb(level,...)
Definition: logger.h:463
int ast_sockaddr_cmp_addr(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares the addresses of two ast_sockaddr structures.
Definition: netsock2.c:413
#define DEFAULT_REGEXTENONQUALIFY
Definition: sip.h:233
static struct ao2_container * peers_by_ip
Definition: chan_sip.c:1053
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
Definition: netsock2.h:140
enum transfermodes allowtransfer
Definition: sip.h:776
static struct ast_jb_conf default_jbconf
Global jitterbuffer configuration - by default, jb is disabled.
Definition: chan_sip.c:680
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define DEFAULT_AUTH_MESSAGE
Definition: sip.h:231
#define DEFAULT_NOTIFYCID
Definition: sip.h:222
#define DEFAULT_MATCHEXTERNADDRLOCALLY
Definition: sip.h:225
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&#39;...
Definition: chan_sip.c:20651
int AST_OPTIONAL_API_NAME() ast_websocket_add_protocol(const char *name, ast_websocket_callback callback)
int ast_format_cap_update_by_allow_disallow(struct ast_format_cap *cap, const char *list, int allowing)
Parse an "allow" or "deny" list and modify a format capabilities structure accordingly.
Definition: format_cap.c:320
const char * ast_config_AST_SYSTEM_NAME
Definition: options.c:170
char default_record_off_feature[AST_FEATURE_MAX_LEN]
Definition: sip.h:785
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
static char used_context[AST_MAX_CONTEXT]
Definition: chan_sip.c:891
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:521
#define DEFAULT_AUTHLIMIT
Definition: sip.h:69
internal representation of ACL entries In principle user applications would have no need for this...
Definition: acl.h:51
#define DEFAULT_VMEXTEN
Definition: sip.h:201
#define DEFAULT_SDPOWNER
Definition: sip.h:241
#define DEFAULT_AUTHTIMEOUT
Definition: sip.h:70
char default_subscribecontext[AST_MAX_CONTEXT]
Definition: sip.h:783
static struct ast_sockaddr media_address
Definition: chan_sip.c:1132
int notifyhold
Definition: sip.h:774
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define STANDARD_TLS_PORT
Standard SIP TLS port from RFC 3261. DO NOT CHANGE THIS.
Definition: sip.h:178
int ast_sockaddr_is_any(const struct ast_sockaddr *addr)
Determine if the address type is unspecified, or "any" address.
Definition: netsock2.c:534
static unsigned char global_refer_addheaders
Definition: chan_sip.c:863
#define ast_config_load(filename, flags)
Load a config file.
static char host[256]
Definition: muted.c:77
#define DEFAULT_DOMAINSASREALM
Definition: sip.h:220
#define STANDARD_SIP_PORT
Standard SIP unsecure port for UDP and TCP from RFC 3261. DO NOT CHANGE THIS.
Definition: sip.h:176
#define DEFAULT_CONTEXT
Definition: chan_ooh323.c:83
#define DEFAULT_MOHSUGGEST
Definition: sip.h:200
static enum st_mode str2stmode(const char *s)
Definition: chan_sip.c:19995
static int global_store_sip_cause
Definition: chan_sip.c:860
static void network_change_stasis_subscribe(void)
Definition: chan_sip.c:17547
A set of tones for a given locale.
Definition: indications.h:74
Definition: sip.h:641
#define DEFAULT_ALLOW_EXT_DOM
Definition: sip.h:218
static struct ast_generator gen
int compactheaders
Definition: sip.h:764
int allow_external_domains
Definition: sip.h:765
static int min_subexpiry
Definition: chan_sip.c:670
static char default_zone[MAX_TONEZONE_COUNTRY]
Definition: chan_sip.c:805
#define DEFAULT_SEND_DIVERSION
Definition: sip.h:235
static uint16_t externtlsport
Definition: chan_sip.c:1139
static char externhost[MAXHOSTNAMELEN]
Definition: chan_sip.c:1135
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:219
static ast_mutex_t netlock
Definition: chan_sip.c:893
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static void add_realm_authentication(struct sip_auth_container **credentials, const char *configuration, int lineno)
Definition: chan_sip.c:31375
#define DEFAULT_MIN_SE
Definition: sip.h:120
static int register_realtime_peers_with_callbackextens(void)
Definition: chan_sip.c:5644
#define DEFAULT_RTPKEEPALIVE
Definition: sip.h:206
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.
Definition: netsock2.c:337
static int authlimit
Definition: chan_sip.c:675
static struct ast_sockaddr externaddr
our external IP address/port for SIP sessions. externaddr.sin_addr is only set when we know we might ...
Definition: chan_sip.c:1131
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.
Definition: chan_sip.c:31075
#define SIP_PAGE2_VIDEOSUPPORT_ALWAYS
Definition: sip.h:366
static time_t externexpire
Definition: chan_sip.c:1136
int default_max_forwards
Definition: sip.h:789
static void mark_parsed_methods(unsigned int *methods, char *methods_str)
Definition: chan_sip.c:9811
int AST_OPTIONAL_API_NAME() ast_websocket_remove_protocol(const char *name, ast_websocket_callback callback)
int pedanticsipchecking
Definition: sip.h:756
static int ourport_tls
Definition: chan_sip.c:1150
#define DEFAULT_COS_AUDIO
Definition: sip.h:215
static char global_sdpowner[AST_MAX_EXTENSION]
Definition: chan_sip.c:845
#define DEFAULT_MAX_EXPIRY
Definition: sip.h:64
#define SIP_PAGE2_IGNORESDPVERSION
Definition: sip.h:344
static int default_expiry
Definition: chan_sip.c:669
#define CONFIG_STATUS_FILEUNCHANGED
char messagecontext[AST_MAX_CONTEXT]
Definition: sip.h:771
#define SIP_PAGE3_DISCARD_REMOTE_HOLD_RETRIEVAL
Definition: sip.h:392
#define SIP_PAGE2_ALLOWOVERLAP_YES
Definition: sip.h:339
static int default_qualify
Definition: chan_sip.c:797
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)
Definition: chan_sip.c:31631
unsigned int enabled
Definition: rtp_engine.h:555
#define AST_DEFAULT_WEBSOCKET_WRITE_TIMEOUT
Default websocket write timeout, in ms.
static int global_callcounter
Definition: chan_sip.c:830
#define LOG_ERROR
Definition: logger.h:285
static unsigned int recordhistory
Definition: chan_sip.c:841
#define SIP_PAGE2_Q850_REASON
Definition: sip.h:326
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: main/utils.c:1951
int legacy_useroption_parsing
Definition: sip.h:767
static int global_reg_retry_403
Definition: chan_sip.c:828
#define DEFAULT_KEEPALIVE
Definition: sip.h:227
static char default_parkinglot[AST_MAX_CONTEXT]
Definition: chan_sip.c:802
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:537
struct ast_sockaddr bindaddr
Definition: chan_sip.c:1106
int rtautoclear
Definition: sip.h:754
static int sip_register(const char *value, int lineno)
create sip_registry object from register=> line in sip.conf and link into reg container ...
Definition: chan_sip.c:9679
int ast_set_qos(int sockfd, int tos, int cos, const char *desc)
Set type of service.
Definition: netsock2.c:621
struct ast_acl_list * ast_free_acl_list(struct ast_acl_list *acl)
Free a list of ACLs.
Definition: acl.c:233
struct ast_tone_zone * ast_get_indication_zone(const char *country)
locate ast_tone_zone
Definition: indications.c:433
int errno
#define ao2_t_callback(c, flags, cb_fn, arg, tag)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.
Definition: astobj2.h:1714
#define DEFAULT_QUALIFY
Definition: sip.h:226
static int global_reg_timeout
Definition: chan_sip.c:826
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
static struct ast_flags global_flags[3]
Definition: chan_sip.c:884
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
static struct ast_jb_conf global_jbconf
Definition: chan_sip.c:688
static int externrefresh
Definition: chan_sip.c:1137
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
#define LOG_NOTICE
Definition: logger.h:263
#define DEFAULT_NOTIFYMIME
Definition: sip.h:204
char * cafile
Definition: tcptls.h:92
#define SIP_PAGE2_RTCACHEFRIENDS
Definition: sip.h:323
#define SIP_PAGE3_NAT_AUTO_RPORT
Definition: sip.h:386
static char default_mohsuggest[MAX_MUSICCLASS]
Definition: chan_sip.c:800
static void clear_sip_domains(void)
Clear our domain list (at reload)
Definition: chan_sip.c:31337
int ast_rtp_dtls_cfg_validate(struct ast_rtp_dtls_cfg *dtls_cfg)
Validates DTLS related configuration options.
Definition: rtp_engine.c:3094
static int global_timer_b
Definition: chan_sip.c:849
static int sipsock
Main socket for UDP SIP communication.
Definition: chan_sip.c:1104
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
#define DEFAULT_MAXMS
Definition: chan_iax2.c:390
#define AST_MAX_CONTEXT
Definition: channel.h:136
#define ast_free(a)
Definition: astmm.h:182
static enum st_refresher_param str2strefresherparam(const char *s)
Definition: chan_sip.c:20020
static char global_sdpsession[AST_MAX_EXTENSION]
Definition: chan_sip.c:844
static int global_max_se
Definition: chan_sip.c:858
#define AST_FLAGS_ALL
Definition: utils.h:196
int ast_str2cos(const char *value, unsigned int *cos)
Convert a string to the appropriate COS value.
Definition: acl.c:953
#define DEFAULT_MAX_SE
Definition: sip.h:119
#define DEFAULT_USERAGENT
Definition: sip.h:239
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
#define DEFAULT_ALWAYSAUTHREJECT
Definition: sip.h:229
int ast_parse_arg(const char *arg, enum ast_parse_flags flags, void *result,...)
The argument parsing routine.
Definition: main/config.c:3657
static unsigned int global_autoframing
Definition: chan_sip.c:850
#define DEFAULT_QUALIFY_PEERS
Definition: sip.h:91
int alwaysauthreject
Definition: sip.h:760
#define DEFAULT_NOTIFYRINGING
Definition: sip.h:221
static char default_engine[256]
Definition: chan_sip.c:803
static int global_qualifyfreq
Definition: chan_sip.c:851
int notifyringing
Definition: sip.h:773
Structure used to handle boolean flags.
Definition: utils.h:199
static int max_subexpiry
Definition: chan_sip.c:671
#define DEFAULT_TIMER_T1
Definition: sip.h:101
char * certfile
Definition: tcptls.h:89
struct ast_format_cap * caps
Global list of addresses dynamic peers are not allowed to use.
Definition: sip.h:787
#define ast_clear_flag(p, flag)
Definition: utils.h:77
static enum st_refresher_param global_st_refresher
Definition: chan_sip.c:856
static int authtimeout
Definition: chan_sip.c:676
#define SIP_PAGE2_TEXTSUPPORT
Definition: sip.h:334
#define DEFAULT_KEEPALIVE_INTERVAL
Definition: sip.h:228
#define SIP_PAGE2_VIDEOSUPPORT
Definition: sip.h:333
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.
Definition: chan_sip.c:31120
void ast_free_ha(struct ast_ha *ha)
Free a list of HAs.
Definition: acl.c:222
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
Definition: main/config.c:694
#define DEFAULT_REALM
Definition: sip.h:219
#define DEFAULT_AUTOCREATEPEER
Definition: sip.h:224
char * strsep(char **str, const char *delims)
static void cleanup_all_regs(void)
Definition: chan_sip.c:32502
int rtsave_sysname
Definition: sip.h:751
static enum st_mode global_st_mode
Definition: chan_sip.c:855
static char default_mohinterpret[MAX_MUSICCLASS]
Definition: chan_sip.c:799
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
void ast_append_acl(const char *sense, const char *stuff, struct ast_acl_list **path, int *error, int *named_acl_flag)
Add a rule to an ACL struct.
Definition: acl.c:430
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
struct ast_flags flags[3]
Definition: sip.h:1335
void ast_rtp_dtls_cfg_free(struct ast_rtp_dtls_cfg *dtls_cfg)
Free contents of a DTLS configuration structure.
Definition: rtp_engine.c:3131
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"...
Definition: main/utils.c:1968
static int default_fromdomainport
Definition: chan_sip.c:794
static char default_mwi_from[80]
Definition: chan_sip.c:792
#define TRUE
Definition: app_minivm.c:518
static int global_match_auth_username
Definition: chan_sip.c:819
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 bein...
Definition: chan_sip.c:3538
static int global_regattempts_max
Definition: chan_sip.c:827
static int global_t1
Definition: chan_sip.c:847
enum autocreatepeer_mode autocreatepeer
Definition: sip.h:757
static void acl_change_stasis_subscribe(void)
Definition: chan_sip.c:17562
int accept_outofcall_message
Definition: sip.h:763
char default_record_on_feature[AST_FEATURE_MAX_LEN]
Definition: sip.h:784
static int global_authfailureevents
Definition: chan_sip.c:846
int ast_tls_read_conf(struct ast_tls_config *tls_cfg, struct ast_tcptls_session_args *tls_desc, const char *varname, const char *value)
Used to parse conf files containing tls/ssl options.
Definition: tcptls.c:875
#define DEFAULT_T1MIN
Definition: sip.h:236
#define DEFAULT_SRVLOOKUP
Definition: sip.h:208
#define DEFAULT_QUALIFY_GAP
Definition: sip.h:90
int allowguest
Definition: sip.h:759
struct ast_ha * ast_append_ha(const char *sense, const char *stuff, struct ast_ha *path, int *error)
Add a new rule to a list of HAs.
Definition: acl.c:713
int error(const char *format,...)
Definition: utils/frame.c:999
static int global_rtpholdtimeout
Definition: chan_sip.c:824
char * capath
Definition: tcptls.h:93
static char default_vmexten[AST_MAX_EXTENSION]
Definition: chan_sip.c:796
#define SIP_PAGE2_RTAUTOCLEAR
Definition: sip.h:324
struct ast_tls_config * tls_cfg
Definition: tcptls.h:134
static char default_notifymime[AST_MAX_EXTENSION]
Definition: chan_sip.c:795
static int sip_subscribe_mwi(const char *value, int lineno)
Parse mwi=> line in sip.conf and add to list.
Definition: chan_sip.c:9720
struct ast_acl_list * contact_acl
Definition: sip.h:786
static unsigned int global_cos_audio
Definition: chan_sip.c:838
int auth_options_requests
Definition: sip.h:761
struct ast_sockaddr local_address
Definition: tcptls.h:130
#define DEFAULT_ACCEPT_OUTOFCALL_MESSAGE
Definition: sip.h:232
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
struct ast_context * ast_context_find_or_create(struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *name, const char *registrar)
Register a new context or find an existing one.
Definition: pbx.c:6198
struct sip_proxy outboundproxy
Definition: sip.h:781
static unsigned int global_cos_sip
Definition: chan_sip.c:837
static struct ast_rtp_dtls_cfg default_dtls_cfg
Default DTLS connection configuration.
Definition: chan_sip.c:2380
static unsigned int global_tos_sip
Definition: chan_sip.c:833
char default_context[AST_MAX_CONTEXT]
Definition: sip.h:782
static unsigned int default_primary_transport
Definition: chan_sip.c:807
int rtsave_path
Definition: sip.h:752
static int global_rtpkeepalive
Definition: chan_sip.c:825
char realm[MAXHOSTNAMELEN]
Definition: sip.h:779
#define DEFAULT_DEFAULT_EXPIRY
Definition: sip.h:62
#define DEFAULT_TOS_SIP
Definition: sip.h:210
#define DEFAULT_CALLCOUNTER
Definition: sip.h:207
#define DEFAULT_COS_VIDEO
Definition: sip.h:216
char regcontext[AST_MAX_CONTEXT]
Definition: sip.h:770
static int global_relaxdtmf
Definition: chan_sip.c:821
General jitterbuffer configuration.
Definition: abstract_jb.h:69
#define SIP_USEREQPHONE
Definition: sip.h:271
static int mwi_expiry
Definition: chan_sip.c:672
char * cipher
Definition: tcptls.h:91
int websocket_write_timeout
Definition: sip.h:790
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
Definition: netsock2.c:524
static const char config[]
Definition: chan_sip.c:690
#define DEFAULT_SDPSESSION
Definition: sip.h:240
#define DEFAULT_CALLERID
Definition: sip.h:202
static int global_qualify_peers
Definition: chan_sip.c:853
static int global_prematuremediafilter
Definition: chan_sip.c:822
static int global_min_se
Definition: chan_sip.c:857
int ignore_regexpire
Definition: sip.h:753
#define ast_mutex_unlock(a)
Definition: lock.h:188
int send_diversion
Definition: sip.h:768
static int min_expiry
Definition: chan_sip.c:667
#define DEFAULT_ENGINE
Definition: sip.h:242
int regextenonqualify
Definition: sip.h:766
static void display_nat_warning(const char *cat, int reason, struct ast_flags *flags)
Definition: chan_sip.c:32446
int enabled
Definition: tcptls.h:88

◆ remove_uri_parameters()

static char * remove_uri_parameters ( char *  uri)
static

Definition at line 14275 of file chan_sip.c.

Referenced by extract_uri(), parse_moved_contact(), register_verify(), reqprep(), and transmit_state_notify().

14276 {
14277  char *atsign;
14278  atsign = strchr(uri, '@'); /* First, locate the at sign */
14279  if (!atsign) {
14280  atsign = uri; /* Ok hostname only, let's stick with the rest */
14281  }
14282  atsign = strchr(atsign, ';'); /* Locate semi colon */
14283  if (atsign)
14284  *atsign = '\0'; /* Kill at the semi colon */
14285  return uri;
14286 }

◆ reply_digest()

static int reply_digest ( struct sip_pvt p,
struct sip_request req,
char *  header,
int  sipmethod,
char *  digest,
int  digest_len 
)
static

reply to authentication for outbound registrations

Returns
Returns -1 if we have no auth
Note
This is used for register= servers in sip.conf, SIP proxies we register with for receiving calls from.

Definition at line 23062 of file chan_sip.c.

References __get_header(), ast_copy_string(), ast_log, ast_skip_blanks(), ast_string_field_ptr_set, ast_string_field_set, ast_strlen_zero, build_reply_digest(), c, sip_pvt::domain, LOG_WARNING, sip_pvt::nonce, sip_registry::nonce, sip_pvt::noncecount, sip_registry::noncecount, NULL, sip_pvt::opaque, sip_pvt::qop, sip_pvt::realm, sip_pvt::registry, strcasestr(), strsep(), and tmp().

Referenced by do_message_auth(), do_proxy_auth(), and do_register_auth().

23063 {
23064  char tmp[512];
23065  char *c;
23066  char oldnonce[256];
23067  int start = 0;
23068 
23069  /* table of recognised keywords, and places where they should be copied */
23070  const struct x {
23071  const char *key;
23072  const ast_string_field *field;
23073  } *i, keys[] = {
23074  { "realm=", &p->realm },
23075  { "nonce=", &p->nonce },
23076  { "opaque=", &p->opaque },
23077  { "qop=", &p->qop },
23078  { "domain=", &p->domain },
23079  { NULL, 0 },
23080  };
23081 
23082  do {
23083  ast_copy_string(tmp, __get_header(req, header, &start), sizeof(tmp));
23084  if (ast_strlen_zero(tmp))
23085  return -1;
23086  } while (strcasestr(tmp, "algorithm=") && !strcasestr(tmp, "algorithm=MD5"));
23087  if (strncasecmp(tmp, "Digest ", strlen("Digest "))) {
23088  ast_log(LOG_WARNING, "missing Digest.\n");
23089  return -1;
23090  }
23091  c = tmp + strlen("Digest ");
23092  ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce));
23093  while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */
23094  for (i = keys; i->key != NULL; i++) {
23095  char *src, *separator;
23096  if (strncasecmp(c, i->key, strlen(i->key)) != 0)
23097  continue;
23098  /* Found. Skip keyword, take text in quotes or up to the separator. */
23099  c += strlen(i->key);
23100  if (*c == '"') {
23101  src = ++c;
23102  separator = "\"";
23103  } else {
23104  src = c;
23105  separator = ",";
23106  }
23107  strsep(&c, separator); /* clear separator and move ptr */
23108  ast_string_field_ptr_set(p, i->field, src);
23109  break;
23110  }
23111  if (i->key == NULL) /* not found, try ',' */
23112  strsep(&c, ",");
23113  }
23114  /* Reset nonce count */
23115  if (strcmp(p->nonce, oldnonce))
23116  p->noncecount = 0;
23117 
23118  /* Save auth data for following registrations */
23119  if (p->registry) {
23120  struct sip_registry *r = p->registry;
23121 
23122  if (strcmp(r->nonce, p->nonce)) {
23127  ast_string_field_set(r, qop, p->qop);
23128  r->noncecount = 0;
23129  }
23130  }
23131  return build_reply_digest(p, sipmethod, digest, digest_len);
23132 }
#define ast_string_field_ptr_set(x, ptr, data)
Set a field to a simple string value.
Definition: stringfields.h:470
const ast_string_field realm
Definition: sip.h:1063
#define LOG_WARNING
Definition: logger.h:274
static int tmp()
Definition: bt_open.c:389
int noncecount
Definition: sip.h:1142
const ast_string_field opaque
Definition: sip.h:1063
Registrations with other SIP proxies.
Definition: sip.h:1396
const char * ast_string_field
Definition: stringfields.h:190
static struct test_val c
#define NULL
Definition: resample.c:96
const ast_string_field nonce
Definition: sip.h:1063
const ast_string_field qop
Definition: sip.h:1063
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
struct sip_registry * registry
Definition: sip.h:1173
const ast_string_field nonce
Definition: sip.h:1414
static int build_reply_digest(struct sip_pvt *p, int method, char *digest, int digest_len)
Build reply digest.
Definition: chan_sip.c:23139
sipmethod
SIP Request methods known by Asterisk.
Definition: sip.h:612
static const char * __get_header(const struct sip_request *req, const char *name, int *start)
Definition: chan_sip.c:8562
int noncecount
Definition: sip.h:1431
const ast_string_field domain
Definition: sip.h:1063
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
char * strcasestr(const char *, const char *)
const ast_string_field opaque
Definition: sip.h:1414
const ast_string_field authdomain
Definition: sip.h:1414
const ast_string_field realm
Definition: sip.h:1414
char * strsep(char **str, const char *delims)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
const ast_string_field qop
Definition: sip.h:1414
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ reqprep()

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

References add_header(), add_max_forwards(), add_route(), ast_copy_string(), ast_debug, ast_random(), ast_string_field_set, ast_strlen_zero, ast_test_flag, AST_TRANSPORT_UDP, sip_pvt::branch, build_via(), c, sip_pvt::callid, copy_header(), FALSE, sip_pvt::flags, get_in_brackets(), global_useragent, init_req(), sip_pvt::initreq, INV_CANCELLED, INV_COMPLETED, INV_EARLY_MEDIA, INV_PROCEEDING, sip_pvt::invite_branch, sip_pvt::invitestate, sip_pvt::lastmsg, NULL, sip_pvt::ocseq, sip_pvt::okcontacturi, sip_pvt::our_contact, remove_uri_parameters(), REQ_OFFSET_TO_STR, sip_pvt::route, SESSION_TIMER_REFRESHER_US, set_destination(), SIP_ACK, SIP_BYE, SIP_CANCEL, sip_get_header(), SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NAT_FORCE_RPORT, SIP_OUTGOING, sip_route_empty, sip_route_first_uri(), sip_route_is_strict(), SIP_UPDATE, sipdebug, sip_pvt::socket, sip_st_dlg::st_active, sip_st_dlg::st_active_peer_ua, st_get_se(), sip_st_dlg::st_interval, sip_st_dlg::st_ref, sip_pvt::stimer, strcasestr(), sip_pvt::tag, sip_socket::tcptls_session, cfsip_methods::text, text, sip_pvt::theirtag, tmp(), TRUE, sip_socket::type, sip_pvt::uri, url, sip_pvt::url, and sip_pvt::via.

Referenced by sipinfo_send(), transmit_cc_notify(), transmit_info_with_aoc(), transmit_info_with_digit(), transmit_info_with_vidupdate(), transmit_invite(), transmit_message(), transmit_notify_with_sipfrag(), transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), transmit_state_notify(), and update_connectedline().

12362 {
12363  struct sip_request *orig = &p->initreq;
12364  char stripped[80];
12365  char tmp[80];
12366  char newto[256];
12367  const char *c;
12368  const char *ot, *of;
12369  int is_strict = FALSE; /*!< Strict routing flag */
12370  int is_outbound = ast_test_flag(&p->flags[0], SIP_OUTGOING); /* Session direction */
12371 
12372  snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text);
12373 
12374  if (!seqno) {
12375  p->ocseq++;
12376  seqno = p->ocseq;
12377  }
12378 
12379  /* A CANCEL must have the same branch as the INVITE that it is canceling. */
12380  if (sipmethod == SIP_CANCEL) {
12381  p->branch = p->invite_branch;
12382  build_via(p);
12383  } else if (newbranch && (sipmethod == SIP_INVITE)) {
12384  p->branch ^= ast_random();
12385  p->invite_branch = p->branch;
12386  build_via(p);
12387  } else if (newbranch) {
12388  p->branch ^= ast_random();
12389  build_via(p);
12390  }
12391 
12392  /* Check for strict or loose router */
12393  if (sip_route_is_strict(&p->route)) {
12394  is_strict = TRUE;
12395  if (sipdebug)
12396  ast_debug(1, "Strict routing enforced for session %s\n", p->callid);
12397  }
12398 
12399  if (sipmethod == SIP_CANCEL) {
12400  c = REQ_OFFSET_TO_STR(&p->initreq, rlpart2); /* Use original URI */
12401  } else if (sipmethod == SIP_ACK) {
12402  /* Use URI from Contact: in 200 OK (if INVITE)
12403  (we only have the contacturi on INVITEs) */
12404  if (!ast_strlen_zero(p->okcontacturi)) {
12405  c = is_strict ? sip_route_first_uri(&p->route) : p->okcontacturi;
12406  } else {
12407  c = REQ_OFFSET_TO_STR(&p->initreq, rlpart2);
12408  }
12409  } else if (!ast_strlen_zero(p->okcontacturi)) {
12410  /* Use for BYE or REINVITE */
12411  c = is_strict ? sip_route_first_uri(&p->route) : p->okcontacturi;
12412  } else if (!ast_strlen_zero(p->uri)) {
12413  c = p->uri;
12414  } else {
12415  char *n;
12416  /* We have no URI, use To: or From: header as URI (depending on direction) */
12417  ast_copy_string(stripped, sip_get_header(orig, is_outbound ? "To" : "From"),
12418  sizeof(stripped));
12419  n = get_in_brackets(stripped);
12420  c = remove_uri_parameters(n);
12421  }
12422  init_req(req, sipmethod, c);
12423 
12424  snprintf(tmp, sizeof(tmp), "%u %s", seqno, sip_methods[sipmethod].text);
12425 
12426  add_header(req, "Via", p->via);
12427  /*
12428  * Use the learned route set unless this is a CANCEL or an ACK for a non-2xx
12429  * final response. For a CANCEL or ACK, we have to send to the same destination
12430  * as the original INVITE.
12431  * Send UPDATE to the same destination as CANCEL, if call is not in final state.
12432  */
12433  if (!sip_route_empty(&p->route) &&
12434  !(sipmethod == SIP_CANCEL ||
12438  /* For TCP/TLS sockets that are connected we won't need
12439  * to do any hostname/IP lookups */
12440  } else if (ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT)) {
12441  /* For NATed traffic, we ignore the contact/route and
12442  * simply send to the received-from address. No need
12443  * for lookups. */
12444  } else {
12446  }
12447  add_route(req, &p->route, is_strict ? 1 : 0);
12448  }
12449  add_max_forwards(p, req);
12450 
12451  ot = sip_get_header(orig, "To");
12452  of = sip_get_header(orig, "From");
12453 
12454  /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly
12455  as our original request, including tag (or presumably lack thereof) */
12456  if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) {
12457  /* Add the proper tag if we don't have it already. If they have specified
12458  their tag, use it. Otherwise, use our own tag */
12459  if (is_outbound && !ast_strlen_zero(p->theirtag))
12460  snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
12461  else if (!is_outbound)
12462  snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
12463  else
12464  snprintf(newto, sizeof(newto), "%s", ot);
12465  ot = newto;
12466  }
12467 
12468  if (is_outbound) {
12469  add_header(req, "From", of);
12470  add_header(req, "To", ot);
12471  } else {
12472  add_header(req, "From", ot);
12473  add_header(req, "To", of);
12474  }
12475  /* Do not add Contact for MESSAGE, BYE and Cancel requests */
12477  add_header(req, "Contact", p->our_contact);
12478 
12479  copy_header(req, orig, "Call-ID");
12480  add_header(req, "CSeq", tmp);
12481 
12483  add_header(req, "User-Agent", global_useragent);
12484 
12485  if (!ast_strlen_zero(p->url)) {
12486  add_header(req, "Access-URL", p->url);
12488  }
12489 
12490  /* Add Session-Timers related headers if the feature is active for this session.
12491  An exception to this behavior is the ACK request. Since Asterisk never requires
12492  session-timers support from a remote end-point (UAS) in an INVITE, it must
12493  not send 'Require: timer' header in the ACK request.
12494  This should only be added in the INVITE transactions, not MESSAGE or REFER or other
12495  in-dialog messages.
12496  */
12497  if (p->stimer && p->stimer->st_active == TRUE && p->stimer->st_active_peer_ua == TRUE
12498  && sipmethod == SIP_INVITE) {
12499  char se_hdr[256];
12500  snprintf(se_hdr, sizeof(se_hdr), "%d;refresher=%s", p->stimer->st_interval,
12501  p->stimer->st_ref == SESSION_TIMER_REFRESHER_US ? "uac" : "uas");
12502  add_header(req, "Session-Expires", se_hdr);
12503  snprintf(se_hdr, sizeof(se_hdr), "%d", st_get_se(p, FALSE));
12504  add_header(req, "Min-SE", se_hdr);
12505  }
12506 
12507  return 0;
12508 }
enum st_refresher st_ref
Definition: sip.h:962
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
#define FALSE
Definition: app_minivm.c:521
char * get_in_brackets(char *tmp)
Pick out text in brackets from character string.
static void build_via(struct sip_pvt *p)
Build a Via header for a request.
Definition: chan_sip.c:3847
int st_active_peer_ua
Definition: sip.h:964
char lastmsg[256]
Definition: sip.h:1145
char via[128]
Definition: sip.h:1063
#define ast_test_flag(p, flag)
Definition: utils.h:63
Definition: sip.h:619
static const struct cfsip_methods sip_methods[]
static void add_route(struct sip_request *req, struct sip_route *route, int skip)
Add route header into request per learned route.
Definition: chan_sip.c:12042
static char global_useragent[AST_MAX_EXTENSION]
Definition: chan_sip.c:843
struct sip_socket socket
Definition: sip.h:1066
static int tmp()
Definition: bt_open.c:389
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.
Definition: chan_sip.c:11943
#define SIP_NAT_FORCE_RPORT
Definition: sip.h:283
static int init_req(struct sip_request *req, int sipmethod, const char *recip)
Initialize SIP request.
Definition: chan_sip.c:12173
static struct test_val c
struct ast_flags flags[3]
Definition: sip.h:1075
char * text
Definition: app_queue.c:1508
int st_active
Definition: sip.h:960
Definition: sip.h:621
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
int st_interval
Definition: sip.h:961
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define sip_route_empty(route)
Check if route has no URI&#39;s.
Definition: route.h:118
static void set_destination(struct sip_pvt *p, const char *uri)
Set destination from SIP URI.
Definition: chan_sip.c:12067
static int add_max_forwards(struct sip_pvt *dialog, struct sip_request *req)
Add &#39;Max-Forwards&#39; header to SIP message.
Definition: chan_sip.c:11901
struct sip_request initreq
Definition: sip.h:1151
static char * remove_uri_parameters(char *uri)
Definition: chan_sip.c:14275
long branch
Definition: sip.h:1121
long int ast_random(void)
Definition: main/utils.c:2064
const ast_string_field theirtag
Definition: sip.h:1063
sipmethod
SIP Request methods known by Asterisk.
Definition: sip.h:612
struct ast_tcptls_session_instance * tcptls_session
Definition: sip.h:801
struct sip_route route
Definition: sip.h:1139
const ast_string_field callid
Definition: sip.h:1063
struct sip_st_dlg * stimer
Definition: sip.h:1184
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
uint32_t ocseq
Definition: sip.h:1067
char * strcasestr(const char *, const char *)
#define REQ_OFFSET_TO_STR(req, offset)
Definition: sip.h:858
enum invitestates invitestate
Definition: sip.h:1007
char *const text
Definition: chan_sip.c:737
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
int sip_route_is_strict(struct sip_route *route)
Check if the route is strict.
Definition: route.c:183
enum ast_transport type
Definition: sip.h:798
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define TRUE
Definition: app_minivm.c:518
const ast_string_field tag
Definition: sip.h:1063
#define SIP_OUTGOING
Definition: sip.h:257
static char url[512]
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873
const ast_string_field url
Definition: sip.h:1063
const char * sip_route_first_uri(const struct sip_route *route)
Get the URI of the route&#39;s first hop.
Definition: route.c:199
static int st_get_se(struct sip_pvt *, int max)
Get Max or Min SE (session timer expiry)
Definition: chan_sip.c:30393
long invite_branch
Definition: sip.h:1122
const ast_string_field uri
Definition: sip.h:1063
ptrdiff_t rlpart2
Definition: sip.h:831
const ast_string_field okcontacturi
Definition: sip.h:1063
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514
const ast_string_field our_contact
Definition: sip.h:1063

◆ resp_needs_contact()

static int resp_needs_contact ( const char *  msg,
enum sipmethod  method 
)
inlinestatic

Test if this response needs a contact header.

Definition at line 12209 of file chan_sip.c.

References SIP_ACK, SIP_BYE, SIP_CANCEL, SIP_INFO, SIP_INVITE, SIP_MESSAGE, SIP_NOTIFY, SIP_OPTIONS, SIP_PING, SIP_PRACK, SIP_PUBLISH, SIP_REFER, SIP_REGISTER, SIP_SUBSCRIBE, and SIP_UPDATE.

Referenced by respprep().

12209  {
12210  /* Requirements for Contact header inclusion in responses generated
12211  * from the header tables found in the following RFCs. Where the
12212  * Contact header was marked mandatory (m) or optional (o) this
12213  * function returns 1.
12214  *
12215  * - RFC 3261 (ACK, BYE, CANCEL, INVITE, OPTIONS, REGISTER)
12216  * - RFC 2976 (INFO)
12217  * - RFC 3262 (PRACK)
12218  * - RFC 3265 (SUBSCRIBE, NOTIFY)
12219  * - RFC 3311 (UPDATE)
12220  * - RFC 3428 (MESSAGE)
12221  * - RFC 3515 (REFER)
12222  * - RFC 3903 (PUBLISH)
12223  */
12224 
12225  switch (method) {
12226  /* 1xx, 2xx, 3xx, 485 */
12227  case SIP_INVITE:
12228  case SIP_UPDATE:
12229  case SIP_SUBSCRIBE:
12230  case SIP_NOTIFY:
12231  if ((msg[0] >= '1' && msg[0] <= '3') || !strncmp(msg, "485", 3))
12232  return 1;
12233  break;
12234 
12235  /* 2xx, 3xx, 485 */
12236  case SIP_REGISTER:
12237  case SIP_OPTIONS:
12238  if (msg[0] == '2' || msg[0] == '3' || !strncmp(msg, "485", 3))
12239  return 1;
12240  break;
12241 
12242  /* 3xx, 485 */
12243  case SIP_BYE:
12244  case SIP_PRACK:
12245  case SIP_MESSAGE:
12246  case SIP_PUBLISH:
12247  if (msg[0] == '3' || !strncmp(msg, "485", 3))
12248  return 1;
12249  break;
12250 
12251  /* 2xx, 3xx, 4xx, 5xx, 6xx */
12252  case SIP_REFER:
12253  if (msg[0] >= '2' && msg[0] <= '6')
12254  return 1;
12255  break;
12256 
12257  /* contact will not be included for everything else */
12258  case SIP_ACK:
12259  case SIP_CANCEL:
12260  case SIP_INFO:
12261  case SIP_PING:
12262  default:
12263  return 0;
12264  }
12265  return 0;
12266 }
Definition: sip.h:626
Definition: sip.h:619
Definition: sip.h:629
Definition: sip.h:621
const char * method
Definition: res_pjsip.c:4335
Definition: sip.h:620
Definition: sip.h:622

◆ respprep()

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

References add_expires(), add_header(), add_supported(), ALLOWED_METHODS, ast_copy_string(), ast_log, ast_string_field_set, ast_strlen_zero, ast_test_flag, copy_all_header(), copy_header(), copy_via_headers(), sip_pvt::expiry, sip_pvt::flags, sip_pvt::fullcontact, global_useragent, init_resp(), LOG_WARNING, sip_pvt::method, NULL, sip_pvt::our_contact, process_via(), sip_pvt::recv, sip_request::reqsipoptions, resp_needs_contact(), sip_pvt::sa, SESSION_TIMER_REFRESHER_THEM, SESSION_TIMER_REFRESHER_US, sip_get_header(), SIP_INVITE, SIP_OPT_TIMER, SIP_OUTGOING, SIP_PUBLISH, SIP_REGISTER, SIP_SUBSCRIBE, SIP_USEPATH, SIPBUFSIZE, sip_st_dlg::st_active, sip_st_dlg::st_active_peer_ua, sip_st_dlg::st_interval, sip_st_dlg::st_ref, sip_pvt::stimer, strcasestr(), sip_pvt::tag, sip_pvt::theirtag, TRUE, url, and sip_pvt::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().

12270 {
12271  char newto[256];
12272  const char *ot;
12273 
12274  init_resp(resp, msg);
12275  copy_via_headers(p, resp, req, "Via");
12276  if (msg[0] == '1' || msg[0] == '2')
12277  copy_all_header(resp, req, "Record-Route");
12278  copy_header(resp, req, "From");
12279  ot = sip_get_header(req, "To");
12280  if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) {
12281  /* Add the proper tag if we don't have it already. If they have specified
12282  their tag, use it. Otherwise, use our own tag */
12284  snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
12285  else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING))
12286  snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
12287  else
12288  ast_copy_string(newto, ot, sizeof(newto));
12289  ot = newto;
12290  }
12291  add_header(resp, "To", ot);
12292  copy_header(resp, req, "Call-ID");
12293  copy_header(resp, req, "CSeq");
12295  add_header(resp, "Server", global_useragent);
12296  add_header(resp, "Allow", ALLOWED_METHODS);
12297  add_supported(p, resp);
12298 
12299  /* If this is an invite, add Session-Timers related headers if the feature is active for this session */
12300  if (p->method == SIP_INVITE && p->stimer && p->stimer->st_active == TRUE) {
12301  char se_hdr[256];
12302  snprintf(se_hdr, sizeof(se_hdr), "%d;refresher=%s", p->stimer->st_interval,
12303  p->stimer->st_ref == SESSION_TIMER_REFRESHER_US ? "uas" : "uac");
12304  add_header(resp, "Session-Expires", se_hdr);
12305  /* RFC 2048, Section 9
12306  * If the refresher parameter in the Session-Expires header field in the
12307  * 2xx response has a value of 'uac', the UAS MUST place a Require
12308  * header field into the response with the value 'timer'.
12309  * ...
12310  * If the refresher parameter in
12311  * the 2xx response has a value of 'uas' and the Supported header field
12312  * in the request contained the value 'timer', the UAS SHOULD place a
12313  * Require header field into the response with the value 'timer'
12314  */
12317  p->stimer->st_active_peer_ua == TRUE)) {
12318  resp->reqsipoptions |= SIP_OPT_TIMER;
12319  }
12320  }
12321 
12322  if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_PUBLISH)) {
12323  /* For registration responses, we also need expiry and
12324  contact info */
12325  add_expires(resp, p->expiry);
12326  if (p->expiry) { /* Only add contact if we have an expiry time */
12327  char contact[SIPBUFSIZE];
12328  const char *contact_uri = p->method == SIP_SUBSCRIBE ? p->our_contact : p->fullcontact;
12329  char *brackets = strchr(contact_uri, '<');
12330  snprintf(contact, sizeof(contact), "%s%s%s;expires=%d", brackets ? "" : "<", contact_uri, brackets ? "" : ">", p->expiry);
12331  add_header(resp, "Contact", contact); /* Not when we unregister */
12332  }
12333  if (p->method == SIP_REGISTER && ast_test_flag(&p->flags[0], SIP_USEPATH)) {
12334  copy_header(resp, req, "Path");
12335  }
12336  } else if (!ast_strlen_zero(p->our_contact) && resp_needs_contact(msg, p->method)) {
12337  add_header(resp, "Contact", p->our_contact);
12338  }
12339 
12340  if (!ast_strlen_zero(p->url)) {
12341  add_header(resp, "Access-URL", p->url);
12343  }
12344 
12345  /* default to routing the response to the address where the request
12346  * came from. Since we don't have a transport layer, we do this here.
12347  * The process_via() function will update the port to either the port
12348  * specified in the via header or the default port later on (per RFC
12349  * 3261 section 18.2.2).
12350  */
12351  p->sa = p->recv;
12352 
12353  if (process_via(p, req)) {
12354  ast_log(LOG_WARNING, "error processing via header, will send response to originating address\n");
12355  }
12356 
12357  return 0;
12358 }
enum st_refresher st_ref
Definition: sip.h:962
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
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.
Definition: chan_sip.c:11978
int st_active_peer_ua
Definition: sip.h:964
#define SIP_USEPATH
Definition: sip.h:305
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define LOG_WARNING
Definition: logger.h:274
static char global_useragent[AST_MAX_EXTENSION]
Definition: chan_sip.c:843
struct ast_sockaddr recv
Definition: sip.h:1135
static void add_expires(struct sip_request *req, int expires)
Add Expires header to SIP message.
Definition: chan_sip.c:12706
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.
Definition: chan_sip.c:11943
static int add_supported(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.
Definition: chan_sip.c:11859
unsigned int reqsipoptions
Definition: sip.h:848
#define SIP_OPT_TIMER
Definition: sip.h:148
struct ast_flags flags[3]
Definition: sip.h:1075
int st_active
Definition: sip.h:960
#define NULL
Definition: resample.c:96
const ast_string_field fullcontact
Definition: sip.h:1063
static int resp_needs_contact(const char *msg, enum sipmethod method)
Test if this response needs a contact header.
Definition: chan_sip.c:12209
#define ast_strlen_zero(foo)
Definition: strings.h:52
int st_interval
Definition: sip.h:961
struct ast_sockaddr sa
Definition: sip.h:1125
#define ast_log
Definition: astobj2.c:42
static int init_resp(struct sip_request *resp, const char *msg)
Initialize SIP response, based on SIP request.
Definition: chan_sip.c:12151
const ast_string_field theirtag
Definition: sip.h:1063
int expiry
Definition: sip.h:1118
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.
Definition: chan_sip.c:11954
struct sip_st_dlg * stimer
Definition: sip.h:1184
#define SIPBUFSIZE
Definition: sip.h:56
int method
Definition: sip.h:1009
#define ALLOWED_METHODS
SIP Methods we support.
Definition: sip.h:173
char * strcasestr(const char *, const char *)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define TRUE
Definition: app_minivm.c:518
const ast_string_field tag
Definition: sip.h:1063
#define SIP_OUTGOING
Definition: sip.h:257
static char url[512]
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873
const ast_string_field url
Definition: sip.h:1063
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.
Definition: chan_sip.c:9117
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514
const ast_string_field our_contact
Definition: sip.h:1063

◆ restart_monitor()

static int restart_monitor ( void  )
static

Start the channel monitor thread.

Definition at line 30078 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, LOG_WARNING, monitor_thread, monlock, and NULL.

Referenced by acl_change_stasis_cb(), load_module(), sip_reload(), and sip_request_call().

30079 {
30080  /* If we're supposed to be stopped -- stay stopped */
30082  return 0;
30084  if (monitor_thread == pthread_self()) {
30086  ast_log(LOG_WARNING, "Cannot kill myself\n");
30087  return -1;
30088  }
30090  /* Wake up the thread */
30091  pthread_kill(monitor_thread, SIGURG);
30092  } else {
30093  /* Start a new monitor */
30096  ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
30097  return -1;
30098  }
30099  }
30101  return 0;
30102 }
static ast_mutex_t monlock
Protect the monitoring thread, so only one process can kill or start it, and not when it&#39;s doing some...
Definition: chan_sip.c:897
#define LOG_WARNING
Definition: logger.h:274
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:567
#define ast_log
Definition: astobj2.c:42
#define AST_PTHREADT_NULL
Definition: lock.h:66
static void * do_monitor(void *data)
The SIP monitoring thread.
Definition: chan_sip.c:29997
#define LOG_ERROR
Definition: logger.h:285
#define AST_PTHREADT_STOP
Definition: lock.h:67
static pthread_t monitor_thread
This is the thread for the monitor which checks for input on the channels which are not currently in ...
Definition: chan_sip.c:903
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ restart_session_timer()

static void restart_session_timer ( struct sip_pvt p)
static

Session-Timers: Restart session timer.

Definition at line 30278 of file chan_sip.c.

References sip_st_dlg::st_active, start_session_timer(), sip_pvt::stimer, and TRUE.

Referenced by handle_request_invite(), and sip_answer().

30279 {
30280  if (p->stimer->st_active == TRUE) {
30282  }
30283 }
int st_active
Definition: sip.h:960
struct sip_st_dlg * stimer
Definition: sip.h:1184
static void start_session_timer(struct sip_pvt *p)
Session-Timers: Start session timer.
Definition: chan_sip.c:30265
#define TRUE
Definition: app_minivm.c:518

◆ retrans_pkt()

static int retrans_pkt ( const void *  data)
static

Retransmit SIP message if no answer.

Note
Run by the sched thread.

Definition at line 4041 of file chan_sip.c.

References __sip_xmit(), ao2_t_ref, append_history, AST_CAUSE_NO_USER_RESPONSE, ast_channel_hangupcause(), ast_channel_hangupcause_set(), ast_channel_unlock, ast_channel_unref, ast_debug, ast_log, ast_queue_hangup_with_cause(), ast_sockaddr_stringify(), ast_str_buffer(), ast_test_flag, ast_tvdiff_ms(), ast_tvnow(), ast_verbose(), sip_pvt::callid, check_pendings(), sip_pkt::data, DEFAULT_RETRANS, sip_pvt::flags, INV_TERMINATED, sip_pvt::invitestate, sip_pkt::is_fatal, sip_pkt::is_resp, LOG_WARNING, sip_pkt::method, sip_pkt::next, NULL, sip_pkt::owner, sip_pvt::packets, sip_pvt::pendinginvite, pvt_set_needdestroy(), sip_pkt::response_code, sip_pkt::retrans, sip_pkt::retrans_stop, sip_pkt::retrans_stop_time, sip_pkt::retransid, sip_pkt::seqno, sip_alreadygone(), SIP_BYE, sip_debug_test_pvt(), SIP_INVITE, sip_methods, sip_nat_mode(), SIP_OPTIONS, SIP_PAGE2_DIALOG_ESTABLISHED, sip_pvt_lock, sip_pvt_lock_full(), sip_pvt_unlock, sip_real_dst(), SIP_REGISTER, sipdebug, cfsip_methods::text, sip_pkt::time_sent, sip_pkt::timer_a, sip_pkt::timer_t1, UNLINK, and XMIT_ERROR.

Referenced by __sip_reliable_xmit(), and sip_show_sched().

4042 {
4043  struct sip_pkt *pkt = (struct sip_pkt *) data;
4044  struct sip_pkt *prev;
4045  struct sip_pkt *cur;
4046  struct ast_channel *owner_chan;
4047  int reschedule = DEFAULT_RETRANS;
4048  int xmitres = 0;
4049  /* how many ms until retrans timeout is reached */
4050  int64_t diff = pkt->retrans_stop_time - ast_tvdiff_ms(ast_tvnow(), pkt->time_sent);
4051 
4052  /* Do not retransmit if time out is reached. This will be negative if the time between
4053  * the first transmission and now is larger than our timeout period. This is a fail safe
4054  * check in case the scheduler gets behind or the clock is changed. */
4055  if ((diff <= 0) || (diff > pkt->retrans_stop_time)) {
4056  pkt->retrans_stop = 1;
4057  }
4058 
4059  /* Lock channel PVT */
4060  sip_pvt_lock(pkt->owner);
4061 
4062  if (!pkt->retrans_stop) {
4063  pkt->retrans++;
4064  if (!pkt->timer_t1) { /* Re-schedule using timer_a and timer_t1 */
4065  if (sipdebug) {
4066  ast_debug(4, "SIP TIMER: Not rescheduling id #%d:%s (Method %d) (No timer T1)\n",
4067  pkt->retransid,
4068  sip_methods[pkt->method].text,
4069  pkt->method);
4070  }
4071  } else {
4072  int siptimer_a;
4073 
4074  if (sipdebug) {
4075  ast_debug(4, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n",
4076  pkt->retransid,
4077  pkt->retrans,
4078  sip_methods[pkt->method].text,
4079  pkt->method);
4080  }
4081  if (!pkt->timer_a) {
4082  pkt->timer_a = 2 ;
4083  } else {
4084  pkt->timer_a = 2 * pkt->timer_a;
4085  }
4086 
4087  /* For non-invites, a maximum of 4 secs */
4088  if (INT_MAX / pkt->timer_a < pkt->timer_t1) {
4089  /*
4090  * Uh Oh, we will have an integer overflow.
4091  * Recalculate previous timeout time instead.
4092  */
4093  pkt->timer_a = pkt->timer_a / 2;
4094  }
4095  siptimer_a = pkt->timer_t1 * pkt->timer_a; /* Double each time */
4096  if (pkt->method != SIP_INVITE && siptimer_a > 4000) {
4097  siptimer_a = 4000;
4098  }
4099 
4100  /* Reschedule re-transmit */
4101  reschedule = siptimer_a;
4102  ast_debug(4, "** SIP timers: Rescheduling retransmission %d to %d ms (t1 %d ms (Retrans id #%d)) \n",
4103  pkt->retrans + 1,
4104  siptimer_a,
4105  pkt->timer_t1,
4106  pkt->retransid);
4107  }
4108 
4109  if (sip_debug_test_pvt(pkt->owner)) {
4110  const struct ast_sockaddr *dst = sip_real_dst(pkt->owner);
4111 
4112  ast_verbose("Retransmitting #%d (%s) to %s:\n%s\n---\n",
4113  pkt->retrans, sip_nat_mode(pkt->owner),
4115  ast_str_buffer(pkt->data));
4116  }
4117 
4118  append_history(pkt->owner, "ReTx", "%d %s", reschedule, ast_str_buffer(pkt->data));
4119  xmitres = __sip_xmit(pkt->owner, pkt->data);
4120 
4121  /* If there was no error during the network transmission, schedule the next retransmission,
4122  * but if the next retransmission is going to be beyond our timeout period, mark the packet's
4123  * stop_retrans value and set the next retransmit to be the exact time of timeout. This will
4124  * allow any responses to the packet to be processed before the packet is destroyed on the next
4125  * call to this function by the scheduler. */
4126  if (xmitres != XMIT_ERROR) {
4127  if (reschedule >= diff) {
4128  pkt->retrans_stop = 1;
4129  reschedule = diff;
4130  }
4131  sip_pvt_unlock(pkt->owner);
4132  return reschedule;
4133  }
4134  }
4135 
4136  /* At this point, either the packet's retransmission timed out, or there was a
4137  * transmission error, either way destroy the scheduler item and this packet. */
4138 
4139  pkt->retransid = -1; /* Kill this scheduler item */
4140 
4141  if (pkt->method != SIP_OPTIONS && xmitres == 0) {
4142  if (pkt->is_fatal || sipdebug) { /* Tell us if it's critical or if we're debugging */
4143  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"
4144  "Packet timed out after %dms with no response\n",
4145  pkt->owner->callid,
4146  pkt->seqno,
4147  pkt->is_fatal ? "Critical" : "Non-critical",
4148  pkt->is_resp ? "Response" : "Request",
4149  (int) ast_tvdiff_ms(ast_tvnow(), pkt->time_sent));
4150  }
4151  } else if (pkt->method == SIP_OPTIONS && sipdebug) {
4152  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);
4153  }
4154 
4155  if (xmitres == XMIT_ERROR) {
4156  ast_log(LOG_WARNING, "Transmit error :: Cancelling transmission on Call ID %s\n", pkt->owner->callid);
4157  append_history(pkt->owner, "XmitErr", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)");
4158  } else {
4159  append_history(pkt->owner, "MaxRetries", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)");
4160  }
4161 
4162  sip_pvt_unlock(pkt->owner); /* SIP_PVT, not channel */
4163  owner_chan = sip_pvt_lock_full(pkt->owner);
4164 
4165  if (pkt->is_fatal) {
4166  if (owner_chan) {
4167  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);
4168 
4169  if (pkt->is_resp &&
4170  (pkt->response_code >= 200) &&
4171  (pkt->response_code < 300) &&
4172  pkt->owner->pendinginvite &&
4174  /* This is a timeout of the 2XX response to a pending INVITE. In this case terminate the INVITE
4175  * transaction just as if we received the ACK, but immediately hangup with a BYE (sip_hangup
4176  * will send the BYE as long as the dialog is not set as "alreadygone")
4177  * RFC 3261 section 13.3.1.4.
4178  * "If the server retransmits the 2xx response for 64*T1 seconds without receiving
4179  * an ACK, the dialog is confirmed, but the session SHOULD be terminated. This is
4180  * accomplished with a BYE, as described in Section 15." */
4182  pkt->owner->pendinginvite = 0;
4183  } else {
4184  /* there is nothing left to do, mark the dialog as gone */
4185  sip_alreadygone(pkt->owner);
4186  }
4187  if (!ast_channel_hangupcause(owner_chan)) {
4189  }
4191  } else {
4192  /* If no channel owner, destroy now */
4193 
4194  /* Let the peerpoke system expire packets when the timer expires for poke_noanswer */
4195  if (pkt->method != SIP_OPTIONS && pkt->method != SIP_REGISTER) {
4196  pvt_set_needdestroy(pkt->owner, "no response to critical packet");
4197  sip_alreadygone(pkt->owner);
4198  append_history(pkt->owner, "DialogKill", "Killing this failed dialog immediately");
4199  }
4200  }
4201  } else if (pkt->owner->pendinginvite == pkt->seqno) {
4202  ast_log(LOG_WARNING, "Timeout on %s on non-critical invite transaction.\n", pkt->owner->callid);
4204  pkt->owner->pendinginvite = 0;
4205  check_pendings(pkt->owner);
4206  }
4207 
4208  if (owner_chan) {
4209  ast_channel_unlock(owner_chan);
4210  ast_channel_unref(owner_chan);
4211  }
4212 
4213  if (pkt->method == SIP_BYE) {
4214  /* We're not getting answers on SIP BYE's. Tear down the call anyway. */
4215  sip_alreadygone(pkt->owner);
4216  append_history(pkt->owner, "ByeFailure", "Remote peer doesn't respond to bye. Destroying call anyway.");
4217  pvt_set_needdestroy(pkt->owner, "no response to BYE");
4218  }
4219 
4220  /* Unlink and destroy the packet object. */
4221  for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) {
4222  if (cur == pkt) {
4223  /* Unlink the node from the list. */
4224  UNLINK(cur, pkt->owner->packets, prev);
4225  ao2_t_ref(pkt, -1, "Packet retransmission list (retransmission complete)");
4226  break;
4227  }
4228  }
4229 
4230  /*
4231  * If the object was not in the list then we were in the process of
4232  * stopping retransmisions while we were sending this retransmission.
4233  */
4234 
4235  sip_pvt_unlock(pkt->owner);
4236  ao2_t_ref(pkt, -1, "Scheduled packet retransmission complete");
4237  return 0;
4238 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
sip packet - raw format for outbound packets that are sent or scheduled for transmission Packets are ...
Definition: sip.h:1231
Main Channel structure associated with a channel.
struct sip_pvt * owner
Definition: sip.h:1239
int method
Definition: sip.h:1234
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
#define ast_test_flag(p, flag)
Definition: utils.h:63
static const struct cfsip_methods sip_methods[]
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
int response_code
Definition: sip.h:1238
#define LOG_WARNING
Definition: logger.h:274
uint32_t pendinginvite
Definition: sip.h:1147
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
uint32_t seqno
Definition: sip.h:1235
static void sip_alreadygone(struct sip_pvt *dialog)
Encapsulate setting of SIP_ALREADYGONE to be able to trace it with debugging.
Definition: chan_sip.c:3460
int retransid
Definition: sip.h:1240
int timer_t1
Definition: sip.h:1242
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
struct ast_flags flags[3]
Definition: sip.h:1075
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
Definition: sip.h:621
#define NULL
Definition: resample.c:96
#define AST_CAUSE_NO_USER_RESPONSE
Definition: causes.h:107
Socket address structure.
Definition: netsock2.h:97
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
Queue a hangup frame with hangupcause set.
Definition: channel.c:1166
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static const struct ast_sockaddr * sip_real_dst(const struct sip_pvt *p)
The real destination address for a write.
Definition: chan_sip.c:3633
static int __sip_xmit(struct sip_pvt *p, struct ast_str *data)
Definition: chan_sip.c:3801
struct ast_str * data
Definition: sip.h:1246
int timer_a
Definition: sip.h:1241
int64_t retrans_stop_time
Definition: sip.h:1244
#define XMIT_ERROR
Definition: sip.h:58
const ast_string_field callid
Definition: sip.h:1063
static void pvt_set_needdestroy(struct sip_pvt *pvt, const char *reason)
Definition: chan_sip.c:3429
#define DEFAULT_RETRANS
Definition: chan_mgcp.c:126
char is_resp
Definition: sip.h:1236
int retrans_stop
Definition: sip.h:1245
struct timeval time_sent
Definition: sip.h:1243
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
struct sip_pkt * next
Definition: sip.h:1232
static struct ast_channel * sip_pvt_lock_full(struct sip_pvt *pvt)
Definition: chan_sip.c:9400
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct sip_pkt * packets
Definition: sip.h:1177
enum invitestates invitestate
Definition: sip.h:1007
static int sip_debug_test_pvt(struct sip_pvt *p)
Test PVT for debugging output.
Definition: chan_sip.c:3649
char *const text
Definition: chan_sip.c:737
static void check_pendings(struct sip_pvt *p)
Check pending actions on SIP call.
Definition: chan_sip.c:23735
#define UNLINK(element, head, prev)
Definition: chan_sip.c:1157
int ast_channel_hangupcause(const struct ast_channel *chan)
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406
char is_fatal
Definition: sip.h:1237
int retrans
Definition: sip.h:1233
#define SIP_PAGE2_DIALOG_ESTABLISHED
Definition: sip.h:358
static const char * sip_nat_mode(const struct sip_pvt *p)
Display SIP nat mode.
Definition: chan_sip.c:3643

◆ sched_check_pendings()

static void sched_check_pendings ( struct sip_pvt pvt)
static

Definition at line 23802 of file chan_sip.c.

References __sched_check_pendings(), ast_sched_add(), dialog_ref, and dialog_unref.

Referenced by handle_incoming(), and handle_response_invite().

23803 {
23804  dialog_ref(pvt, "Check pending actions action");
23805  if (ast_sched_add(sched, 0, __sched_check_pendings, pvt) < 0) {
23806  /* Uh Oh. Expect bad behavior. */
23807  dialog_unref(pvt, "Failed to schedule check pending actions action");
23808  }
23809 }
Definition: sched.c:76
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
#define dialog_ref(dialog, tag)
when we create or delete references, make sure to use these functions so we keep track of the refcoun...
Definition: dialog.h:32
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565
static int __sched_check_pendings(const void *data)
Definition: chan_sip.c:23785

◆ send_check_user_failure_response()

static void send_check_user_failure_response ( struct sip_pvt p,
struct sip_request req,
int  res,
enum xmittype  reliable 
)
static

Definition at line 19626 of file chan_sip.c.

References ast_log, AUTH_ACL_FAILED, AUTH_BAD_TRANSPORT, AUTH_CHALLENGE_SENT, AUTH_NOT_FOUND, AUTH_PEER_NOT_DYNAMIC, AUTH_RTP_FAILED, AUTH_SECRET_FAILED, AUTH_SESSION_LIMIT, AUTH_SUCCESSFUL, AUTH_UNKNOWN_DOMAIN, AUTH_USERNAME_MISMATCH, LOG_NOTICE, sip_pvt::method, sip_get_header(), sip_methods, cfsip_methods::text, transmit_response(), transmit_response_reliable(), XMIT_RELIABLE, and XMIT_UNRELIABLE.

Referenced by handle_request_invite(), handle_request_options(), handle_request_publish(), handle_request_subscribe(), and receive_message().

19627 {
19628  const char *response;
19629 
19630  switch (res) {
19631  case AUTH_SECRET_FAILED:
19633  case AUTH_NOT_FOUND:
19634  case AUTH_UNKNOWN_DOMAIN:
19635  case AUTH_PEER_NOT_DYNAMIC:
19636  case AUTH_BAD_TRANSPORT:
19637  case AUTH_ACL_FAILED:
19638  ast_log(LOG_NOTICE, "Failed to authenticate device %s for %s, code = %d\n",
19639  sip_get_header(req, "From"), sip_methods[p->method].text, res);
19640  response = "403 Forbidden";
19641  break;
19642  case AUTH_SESSION_LIMIT:
19643  /* Unexpected here, actually. As it's handled elsewhere. */
19644  ast_log(LOG_NOTICE, "Call limit reached for device %s for %s, code = %d\n",
19645  sip_get_header(req, "From"), sip_methods[p->method].text, res);
19646  response = "480 Temporarily Unavailable";
19647  break;
19648  case AUTH_RTP_FAILED:
19649  /* We don't want to send a 403 in the RTP_FAILED case.
19650  * The cause could be any one of:
19651  * - out of memory or rtp ports
19652  * - dtls/srtp requested but not loaded/invalid
19653  * Neither of them warrant a 403. A 503 makes more
19654  * sense, as this node is broken/overloaded. */
19655  ast_log(LOG_NOTICE, "RTP init failure for device %s for %s, code = %d\n",
19656  sip_get_header(req, "From"), sip_methods[p->method].text, res);
19657  response = "503 Service Unavailable";
19658  break;
19659  case AUTH_SUCCESSFUL:
19660  case AUTH_CHALLENGE_SENT:
19661  /* These should have been handled elsewhere. */
19662  default:
19663  ast_log(LOG_NOTICE, "Unexpected error for device %s for %s, code = %d\n",
19664  sip_get_header(req, "From"), sip_methods[p->method].text, res);
19665  response = "503 Service Unavailable";
19666  }
19667 
19668  if (reliable == XMIT_RELIABLE) {
19669  transmit_response_reliable(p, response, req);
19670  } else if (reliable == XMIT_UNRELIABLE) {
19671  transmit_response(p, response, req);
19672  }
19673 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
static const struct cfsip_methods sip_methods[]
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.
Definition: chan_sip.c:12688
static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req)
Transmit response, no retransmits.
Definition: chan_sip.c:12655
#define ast_log
Definition: astobj2.c:42
int method
Definition: sip.h:1009
#define LOG_NOTICE
Definition: logger.h:263
char *const text
Definition: chan_sip.c:737

◆ send_manager_peer_status()

static void send_manager_peer_status ( struct mansession s,
struct sip_peer peer,
const char *  idText 
)
static

Definition at line 20981 of file chan_sip.c.

References astman_append(), sip_peer::lastms, sip_peer::maxms, sip_peer::name, and status.

Referenced by manager_sip_peer_status().

20982 {
20983  char time[128] = "";
20984  char status[128] = "";
20985  if (peer->maxms) {
20986  if (peer->lastms < 0) {
20987  snprintf(status, sizeof(status), "PeerStatus: Unreachable\r\n");
20988  } else if (peer->lastms > peer->maxms) {
20989  snprintf(status, sizeof(status), "PeerStatus: Lagged\r\n");
20990  snprintf(time, sizeof(time), "Time: %d\r\n", peer->lastms);
20991  } else if (peer->lastms) {
20992  snprintf(status, sizeof(status), "PeerStatus: Reachable\r\n");
20993  snprintf(time, sizeof(time), "Time: %d\r\n", peer->lastms);
20994  } else {
20995  snprintf(status, sizeof(status), "PeerStatus: Unknown\r\n");
20996  }
20997  } else {
20998  snprintf(status, sizeof(status), "PeerStatus: Unmonitored\r\n");
20999  }
21000 
21001  astman_append(s,
21002  "Event: PeerStatus\r\n"
21003  "Privilege: System\r\n"
21004  "ChannelType: SIP\r\n"
21005  "Peer: SIP/%s\r\n"
21006  "%s"
21007  "%s"
21008  "%s"
21009  "\r\n",
21010  peer->name, status, time, idText);
21011 }
int maxms
Definition: sip.h:1357
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3080
char name[80]
Definition: sip.h:1274
int lastms
Definition: sip.h:1356
jack_status_t status
Definition: app_jack.c:146

◆ send_provisional_keepalive()

static int send_provisional_keepalive ( const void *  data)
static

Definition at line 4708 of file chan_sip.c.

References send_provisional_keepalive_full().

Referenced by __update_provisional_keepalive_full().

4709 {
4710  struct sip_pvt *pvt = (struct sip_pvt *) data;
4711 
4712  return send_provisional_keepalive_full(pvt, 0);
4713 }
static int send_provisional_keepalive_full(struct sip_pvt *pvt, int with_sdp)
Definition: chan_sip.c:4672
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005

◆ send_provisional_keepalive_full()

static int send_provisional_keepalive_full ( struct sip_pvt pvt,
int  with_sdp 
)
static

Definition at line 4672 of file chan_sip.c.

References ast_channel_unlock, ast_channel_unref, dialog_unref, FALSE, sip_pvt::initreq, INV_COMPLETED, sip_pvt::invitestate, sip_pvt::last_provisional, NULL, PROVIS_KEEPALIVE_TIMEOUT, sip_pvt::provisional_keepalive_sched_id, S_OR, sip_pvt_lock_full(), sip_pvt_unlock, transmit_response(), transmit_response_with_sdp(), and XMIT_UNRELIABLE.

Referenced by send_provisional_keepalive(), and send_provisional_keepalive_with_sdp().

4673 {
4674  const char *msg = NULL;
4675  struct ast_channel *chan;
4676  int res = 0;
4677 
4678  chan = sip_pvt_lock_full(pvt);
4679 
4680  if (!pvt->last_provisional || !strncasecmp(pvt->last_provisional, "100", 3)) {
4681  msg = "183 Session Progress";
4682  }
4683 
4684  if (pvt->invitestate < INV_COMPLETED) {
4685  if (with_sdp) {
4687  } else {
4688  transmit_response(pvt, S_OR(msg, pvt->last_provisional), &pvt->initreq);
4689  }
4691  } else {
4693  }
4694 
4695  sip_pvt_unlock(pvt);
4696  if (chan) {
4697  ast_channel_unlock(chan);
4698  ast_channel_unref(chan);
4699  }
4700 
4701  if (!res) {
4702  dialog_unref(pvt, "Schedule provisional keepalive complete");
4703  }
4704  return res;
4705 }
const char * last_provisional
Definition: sip.h:1110
Main Channel structure associated with a channel.
#define FALSE
Definition: app_minivm.c:521
#define PROVIS_KEEPALIVE_TIMEOUT
Definition: sip.h:108
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
#define NULL
Definition: resample.c:96
int provisional_keepalive_sched_id
Definition: sip.h:1109
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req)
Transmit response, no retransmits.
Definition: chan_sip.c:12655
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.
Definition: chan_sip.c:14125
struct sip_request initreq
Definition: sip.h:1151
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
static struct ast_channel * sip_pvt_lock_full(struct sip_pvt *pvt)
Definition: chan_sip.c:9400
#define ast_channel_unlock(chan)
Definition: channel.h:2946
enum invitestates invitestate
Definition: sip.h:1007
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79

◆ send_provisional_keepalive_with_sdp()

static int send_provisional_keepalive_with_sdp ( const void *  data)
static

Definition at line 4716 of file chan_sip.c.

References send_provisional_keepalive_full().

Referenced by __update_provisional_keepalive_full().

4717 {
4718  struct sip_pvt *pvt = (void *) data;
4719 
4720  return send_provisional_keepalive_full(pvt, 1);
4721 }
static int send_provisional_keepalive_full(struct sip_pvt *pvt, int with_sdp)
Definition: chan_sip.c:4672
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005

◆ send_request()

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

Definition at line 4863 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(), sip_request::data, deinit_req(), sip_pvt::do_history, finalize_content(), sip_pvt::flags, sip_proxy::ip, sip_request::method, sip_pvt::outboundproxy, parse_copy(), sip_pvt::recv, sip_pvt::sa, sip_debug_test_pvt(), sip_get_header(), sip_methods, SIP_NAT_FORCE_RPORT, cfsip_methods::text, tmp(), and XMIT_CRITICAL.

Referenced by sipinfo_send(), transmit_cc_notify(), transmit_info_with_aoc(), transmit_info_with_digit(), transmit_info_with_vidupdate(), transmit_invite(), transmit_message(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), transmit_state_notify(), and update_connectedline().

4864 {
4865  int res;
4866 
4867  /* If we have an outbound proxy, reset peer address
4868  Only do this once.
4869  */
4870  if (p->outboundproxy) {
4871  p->sa = p->outboundproxy->ip;
4872  }
4873 
4874  finalize_content(req);
4875  add_blank(req);
4876  if (sip_debug_test_pvt(p)) {
4877  if (ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT)) {
4878  ast_verbose("%sTransmitting (NAT) to %s:\n%s\n---\n", reliable ? "Reliably " : "", ast_sockaddr_stringify(&p->recv), ast_str_buffer(req->data));
4879  } else {
4880  ast_verbose("%sTransmitting (no NAT) to %s:\n%s\n---\n", reliable ? "Reliably " : "", ast_sockaddr_stringify(&p->sa), ast_str_buffer(req->data));
4881  }
4882  }
4883  if (p->do_history) {
4884  struct sip_request tmp = { .rlpart1 = 0, };
4885  parse_copy(&tmp, req);
4886  append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", ast_str_buffer(tmp.data), sip_get_header(&tmp, "CSeq"), sip_methods[tmp.method].text);
4887  deinit_req(&tmp);
4888  }
4889  res = (reliable) ?
4890  __sip_reliable_xmit(p, seqno, 0, req->data, (reliable == XMIT_CRITICAL), req->method) :
4891  __sip_xmit(p, req->data);
4892  deinit_req(req);
4893  return res;
4894 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
#define ast_test_flag(p, flag)
Definition: utils.h:63
static const struct cfsip_methods sip_methods[]
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
static int __sip_reliable_xmit(struct sip_pvt *p, uint32_t seqno, int resp, struct ast_str *data, int fatal, int sipmethod)
Definition: chan_sip.c:4275
struct ast_sockaddr recv
Definition: sip.h:1135
static int tmp()
Definition: bt_open.c:389
#define SIP_NAT_FORCE_RPORT
Definition: sip.h:283
struct ast_flags flags[3]
Definition: sip.h:1075
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
static void deinit_req(struct sip_request *req)
Deinitialize SIP response/request.
Definition: chan_sip.c:12195
struct ast_sockaddr sa
Definition: sip.h:1125
struct ast_sockaddr ip
Definition: sip.h:723
static int __sip_xmit(struct sip_pvt *p, struct ast_str *data)
Definition: chan_sip.c:3801
struct ast_str * data
Definition: sip.h:843
int method
Definition: sip.h:833
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
unsigned short do_history
Definition: sip.h:1078
static void parse_copy(struct sip_request *dst, const struct sip_request *src)
Copy SIP request, parse it.
Definition: chan_sip.c:4656
static int finalize_content(struct sip_request *req)
Add &#39;Content-Length&#39; header and content to SIP message.
Definition: chan_sip.c:11911
static int sip_debug_test_pvt(struct sip_pvt *p)
Test PVT for debugging output.
Definition: chan_sip.c:3649
char *const text
Definition: chan_sip.c:737
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406
static void add_blank(struct sip_request *req)
add a blank line if no body
Definition: chan_sip.c:4663
struct sip_proxy * outboundproxy
Definition: sip.h:1112

◆ send_response()

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

References __sip_reliable_xmit(), __sip_xmit(), add_blank(), append_history, ast_sockaddr_stringify(), ast_str_buffer(), ast_verbose(), sip_request::data, deinit_req(), sip_pvt::do_history, finalize_content(), sip_pvt::initreq, sip_request::method, parse_copy(), REQ_OFFSET_TO_STR, sip_debug_test_pvt(), sip_get_header(), SIP_INVITE, sip_methods, sip_nat_mode(), sip_real_dst(), SIP_RESPONSE, SIP_UNKNOWN, stop_provisional_keepalive(), cfsip_methods::text, tmp(), and XMIT_CRITICAL.

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

4822 {
4823  int res;
4824 
4825  finalize_content(req);
4826  add_blank(req);
4827  if (sip_debug_test_pvt(p)) {
4828  const struct ast_sockaddr *dst = sip_real_dst(p);
4829 
4830  ast_verbose("\n<--- %sTransmitting (%s) to %s --->\n%s\n<------------>\n",
4831  reliable ? "Reliably " : "", sip_nat_mode(p),
4833  ast_str_buffer(req->data));
4834  }
4835  if (p->do_history) {
4836  struct sip_request tmp = { .rlpart1 = 0, };
4837  parse_copy(&tmp, req);
4838  append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", ast_str_buffer(tmp.data), sip_get_header(&tmp, "CSeq"),
4840  deinit_req(&tmp);
4841  }
4842 
4843  /* If we are sending a final response to an INVITE, stop retransmitting provisional responses */
4844  if (p->initreq.method == SIP_INVITE && reliable == XMIT_CRITICAL) {
4846  }
4847 
4848  res = (reliable) ?
4849  __sip_reliable_xmit(p, seqno, 1, req->data, (reliable == XMIT_CRITICAL), req->method) :
4850  __sip_xmit(p, req->data);
4851  deinit_req(req);
4852  if (res > 0) {
4853  return 0;
4854  }
4855  return res;
4856 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
static const struct cfsip_methods sip_methods[]
static void stop_provisional_keepalive(struct sip_pvt *pvt)
Definition: chan_sip.c:4783
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
static int __sip_reliable_xmit(struct sip_pvt *p, uint32_t seqno, int resp, struct ast_str *data, int fatal, int sipmethod)
Definition: chan_sip.c:4275
static int tmp()
Definition: bt_open.c:389
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
Socket address structure.
Definition: netsock2.h:97
static void deinit_req(struct sip_request *req)
Deinitialize SIP response/request.
Definition: chan_sip.c:12195
struct sip_request initreq
Definition: sip.h:1151
static const struct ast_sockaddr * sip_real_dst(const struct sip_pvt *p)
The real destination address for a write.
Definition: chan_sip.c:3633
static int __sip_xmit(struct sip_pvt *p, struct ast_str *data)
Definition: chan_sip.c:3801
struct ast_str * data
Definition: sip.h:843
int method
Definition: sip.h:833
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
unsigned short do_history
Definition: sip.h:1078
#define REQ_OFFSET_TO_STR(req, offset)
Definition: sip.h:858
static void parse_copy(struct sip_request *dst, const struct sip_request *src)
Copy SIP request, parse it.
Definition: chan_sip.c:4656
static int finalize_content(struct sip_request *req)
Add &#39;Content-Length&#39; header and content to SIP message.
Definition: chan_sip.c:11911
static int sip_debug_test_pvt(struct sip_pvt *p)
Test PVT for debugging output.
Definition: chan_sip.c:3649
char *const text
Definition: chan_sip.c:737
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406
static void add_blank(struct sip_request *req)
add a blank line if no body
Definition: chan_sip.c:4663
static const char * sip_nat_mode(const struct sip_pvt *p)
Display SIP nat mode.
Definition: chan_sip.c:3643
ptrdiff_t rlpart2
Definition: sip.h:831

◆ send_session_timeout()

static void send_session_timeout ( struct ast_channel chan,
const char *  source 
)
static

Sends a session timeout channel blob used to produce SessionTimeout AMI messages.

Definition at line 29879 of file chan_sip.c.

References ast_assert, ast_channel_publish_blob(), ast_json_pack(), ast_json_unref(), NULL, and RAII_VAR.

Referenced by check_rtp_timeout(), and proc_session_timer().

29880 {
29881  RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
29882 
29883  ast_assert(chan != NULL);
29884  ast_assert(source != NULL);
29885 
29886  blob = ast_json_pack("{s: s}", "source", source);
29887  if (!blob) {
29888  return;
29889  }
29890 
29891  ast_channel_publish_blob(chan, session_timeout_type(), blob);
29892 }
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
#define ast_assert(a)
Definition: utils.h:695
#define NULL
Definition: resample.c:96
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
Abstract JSON element (object, array, string, int, ...).
void ast_channel_publish_blob(struct ast_channel *chan, struct stasis_message_type *type, struct ast_json *blob)
Publish a channel blob message.

◆ service_string_to_service_type()

static enum ast_cc_service_type service_string_to_service_type ( const char *const  service_string)
static

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

1710 {
1712  for (service = AST_CC_CCBS; service <= AST_CC_CCNL; ++service) {
1713  if (!strcasecmp(service_string, sip_cc_service_map[service].service_string)) {
1714  return service;
1715  }
1716  }
1717  return AST_CC_NONE;
1718 }
const char * service_string
Definition: chan_sip.c:950
enum ast_cc_service_type service
Definition: chan_sip.c:949
static const struct @130 sip_cc_service_map[]
ast_cc_service_type
Definition: ccss.h:32

◆ session_timeout_to_ami()

static struct ast_manager_event_blob * session_timeout_to_ami ( struct stasis_message msg)
static

Definition at line 29861 of file chan_sip.c.

References ast_free, ast_json_object_get(), ast_json_string_get(), ast_manager_build_channel_state_string(), ast_manager_event_blob_create(), ast_str_buffer(), ast_channel_blob::blob, EVENT_FLAG_CALL, NULL, RAII_VAR, ast_channel_blob::snapshot, and stasis_message_data().

29862 {
29863  RAII_VAR(struct ast_str *, channel_string, NULL, ast_free);
29864  struct ast_channel_blob *obj = stasis_message_data(msg);
29865  const char *source = ast_json_string_get(ast_json_object_get(obj->blob, "source"));
29866 
29867  channel_string = ast_manager_build_channel_state_string(obj->snapshot);
29868  if (!channel_string) {
29869  return NULL;
29870  }
29871 
29872  return ast_manager_event_blob_create(EVENT_FLAG_CALL, "SessionTimeout",
29873  "%s"
29874  "Source: %s\r\n",
29875  ast_str_buffer(channel_string), source);
29876 }
struct ast_json * blob
struct ast_channel_snapshot * snapshot
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define EVENT_FLAG_CALL
Definition: manager.h:72
#define NULL
Definition: resample.c:96
struct ast_manager_event_blob * ast_manager_event_blob_create(int event_flags, const char *manager_event, const char *extra_fields_fmt,...)
Construct a ast_manager_event_blob.
Definition: manager.c:9727
Blob of data associated with a channel.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
Definition: json.c:273
struct ast_str * ast_manager_build_channel_state_string(const struct ast_channel_snapshot *snapshot)
Generate the AMI message body from a channel snapshot.
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
#define ast_free(a)
Definition: astmm.h:182
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:397

◆ set_address_from_contact()

static int set_address_from_contact ( struct sip_pvt pvt)
static

Change the other partys IP address based on given contact.

Todo:
We need to save the TRANSPORT here too

Definition at line 16947 of file chan_sip.c.

References __set_address_from_contact(), ast_test_flag, AST_TRANSPORT_TLS, sip_pvt::flags, sip_pvt::fullcontact, sip_pvt::recv, sip_pvt::sa, SIP_NAT_FORCE_RPORT, sip_pvt::socket, and sip_socket::type.

Referenced by handle_response_invite().

16948 {
16949  if (ast_test_flag(&pvt->flags[0], SIP_NAT_FORCE_RPORT)) {
16950  /* NAT: Don't trust the contact field. Just use what they came to us
16951  with. */
16952  /*! \todo We need to save the TRANSPORT here too */
16953  pvt->sa = pvt->recv;
16954  return 0;
16955  }
16956 
16957  return __set_address_from_contact(pvt->fullcontact, &pvt->sa, pvt->socket.type == AST_TRANSPORT_TLS ? 1 : 0);
16958 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_sockaddr recv
Definition: sip.h:1135
struct sip_socket socket
Definition: sip.h:1066
#define SIP_NAT_FORCE_RPORT
Definition: sip.h:283
struct ast_flags flags[3]
Definition: sip.h:1075
const ast_string_field fullcontact
Definition: sip.h:1063
struct ast_sockaddr sa
Definition: sip.h:1125
static int __set_address_from_contact(const char *fullcontact, struct ast_sockaddr *addr, int tcp)
Definition: chan_sip.c:16892
enum ast_transport type
Definition: sip.h:798

◆ set_destination()

static void set_destination ( struct sip_pvt p,
const 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]@host[:port][;...] 

If there's a port given, turn NAPTR/SRV off. NAPTR might indicate SIPS preference even for SIP: uri's

If there's a sips: uri scheme, TLS will be required.

Todo:
XXX If we have sip_cfg.srvlookup on, then look for NAPTR/SRV, otherwise, just look for A records
Todo:
XXX If we have sip_cfg.srvlookup on, then look for NAPTR/SRV, otherwise, just look for A records

Definition at line 12067 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(), debug, FALSE, hostname, LOG_WARNING, PARSE_PORT_FORBID, sip_pvt::sa, sip_debug_test_pvt(), sip_pvt::socket, STANDARD_SIP_PORT, STANDARD_TLS_PORT, strcasestr(), TRUE, and sip_socket::type.

Referenced by reqprep().

12068 {
12069  char *trans, *maddr, hostname[256];
12070  const char *h;
12071  int hn;
12072  int debug=sip_debug_test_pvt(p);
12073  int tls_on = FALSE;
12074 
12075  if (debug)
12076  ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri);
12077 
12078  if ((trans = strcasestr(uri, ";transport="))) {
12079  trans += strlen(";transport=");
12080 
12081  if (!strncasecmp(trans, "ws", 2)) {
12082  if (debug)
12083  ast_verbose("set_destination: URI is for WebSocket, we can't set destination\n");
12084  return;
12085  }
12086  }
12087 
12088  /* Find and parse hostname */
12089  h = strchr(uri, '@');
12090  if (h)
12091  ++h;
12092  else {
12093  h = uri;
12094  if (!strncasecmp(h, "sip:", 4)) {
12095  h += 4;
12096  } else if (!strncasecmp(h, "sips:", 5)) {
12097  h += 5;
12098  tls_on = TRUE;
12099  }
12100  }
12101  hn = strcspn(h, ";>") + 1;
12102  if (hn > sizeof(hostname))
12103  hn = sizeof(hostname);
12104  ast_copy_string(hostname, h, hn);
12105  /* XXX bug here if string has been trimmed to sizeof(hostname) */
12106  h += hn - 1;
12107 
12108  /*! \todo XXX If we have sip_cfg.srvlookup on, then look for NAPTR/SRV,
12109  * otherwise, just look for A records */
12110  if (ast_sockaddr_resolve_first_transport(&p->sa, hostname, 0, p->socket.type)) {
12111  ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname);
12112  return;
12113  }
12114 
12115  /* Got the hostname - but maybe there's a "maddr=" to override address? */
12116  maddr = strstr(h, "maddr=");
12117  if (maddr) {
12118  int port;
12119 
12120  maddr += 6;
12121  hn = strspn(maddr, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
12122  "0123456789-.:[]") + 1;
12123  if (hn > sizeof(hostname))
12124  hn = sizeof(hostname);
12125  ast_copy_string(hostname, maddr, hn);
12126 
12127  port = ast_sockaddr_port(&p->sa);
12128 
12129  /*! \todo XXX If we have sip_cfg.srvlookup on, then look for
12130  * NAPTR/SRV, otherwise, just look for A records */
12132  ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname);
12133  return;
12134  }
12135 
12136  ast_sockaddr_set_port(&p->sa, port);
12137  }
12138 
12139  if (!ast_sockaddr_port(&p->sa)) {
12140  ast_sockaddr_set_port(&p->sa, tls_on ?
12142  }
12143 
12144  if (debug) {
12145  ast_verbose("set_destination: set destination to %s\n",
12146  ast_sockaddr_stringify(&p->sa));
12147  }
12148 }
#define FALSE
Definition: app_minivm.c:521
#define LOG_WARNING
Definition: logger.h:274
static int debug
Global debug status.
Definition: res_xmpp.c:435
struct sip_socket socket
Definition: sip.h:1066
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:521
struct ast_sockaddr sa
Definition: sip.h:1125
#define ast_log
Definition: astobj2.c:42
#define STANDARD_TLS_PORT
Standard SIP TLS port from RFC 3261. DO NOT CHANGE THIS.
Definition: sip.h:178
#define STANDARD_SIP_PORT
Standard SIP unsecure port for UDP and TCP from RFC 3261. DO NOT CHANGE THIS.
Definition: sip.h:176
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:537
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
char * strcasestr(const char *, const char *)
static int sip_debug_test_pvt(struct sip_pvt *p)
Test PVT for debugging output.
Definition: chan_sip.c:3649
enum ast_transport type
Definition: sip.h:798
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define TRUE
Definition: app_minivm.c:518
static struct ast_str * hostname
Definition: cdr_mysql.c:77
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. ...
Definition: chan_sip.c:34479

◆ set_ice_components()

static void set_ice_components ( struct sip_pvt p,
struct ast_rtp_instance instance,
int  remote_rtcp_mux 
)
static

Definition at line 10211 of file chan_sip.c.

References ast_rtp_instance_get_ice(), ast_test_flag, ast_rtp_engine_ice::change_components, sip_pvt::flags, and SIP_PAGE3_RTCP_MUX.

Referenced by process_sdp().

10212 {
10213  struct ast_rtp_engine_ice *ice;
10214  int local_rtcp_mux = ast_test_flag(&p->flags[2], SIP_PAGE3_RTCP_MUX);
10215 
10216  ice = ast_rtp_instance_get_ice(instance);
10217  if (!ice) {
10218  return;
10219  }
10220 
10221  if (local_rtcp_mux && remote_rtcp_mux) {
10222  /* We both support RTCP mux. Only one ICE component necessary */
10223  ice->change_components(instance, 1);
10224  } else {
10225  /* They either don't support RTCP mux or we don't know if they do yet. */
10226  ice->change_components(instance, 2);
10227  }
10228 }
#define SIP_PAGE3_RTCP_MUX
Definition: sip.h:394
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_rtp_engine_ice * ast_rtp_instance_get_ice(struct ast_rtp_instance *instance)
Obtain a pointer to the ICE support present on an RTP instance.
Definition: rtp_engine.c:2891
void(* change_components)(struct ast_rtp_instance *instance, int num_components)
Definition: rtp_engine.h:509
struct ast_flags flags[3]
Definition: sip.h:1075
Structure that represents the optional ICE support within an RTP engine.
Definition: rtp_engine.h:485

◆ set_insecure_flags()

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

References ast_copy_string(), ast_false(), ast_log, ast_set_flag, ast_strlen_zero, buf, LOG_WARNING, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, and strsep().

Referenced by get_insecure_variable_from_config(), get_insecure_variable_from_sipregs(), and handle_common_options().

31050 {
31051  if (ast_strlen_zero(value))
31052  return;
31053 
31054  if (!ast_false(value)) {
31055  char buf[64];
31056  char *word, *next;
31057 
31058  ast_copy_string(buf, value, sizeof(buf));
31059  next = buf;
31060  while ((word = strsep(&next, ","))) {
31061  if (!strcasecmp(word, "port"))
31062  ast_set_flag(&flags[0], SIP_INSECURE_PORT);
31063  else if (!strcasecmp(word, "invite"))
31064  ast_set_flag(&flags[0], SIP_INSECURE_INVITE);
31065  else
31066  ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno);
31067  }
31068  }
31069 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define LOG_WARNING
Definition: logger.h:274
int value
Definition: syslog.c:37
#define SIP_INSECURE_PORT
Definition: sip.h:296
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
char * strsep(char **str, const char *delims)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"...
Definition: main/utils.c:1968
#define SIP_INSECURE_INVITE
Definition: sip.h:297
short word

◆ set_message_vars_from_req()

static int set_message_vars_from_req ( struct ast_msg msg,
struct sip_request req 
)
static

Definition at line 19675 of file chan_sip.c.

References ast_copy_string(), ast_msg_set_var(), ast_skip_blanks(), ast_trim_blanks(), c, find_full_alias(), sip_request::headers, MIN, name, and REQ_OFFSET_TO_STR.

Referenced by receive_message().

19676 {
19677  size_t x;
19678  char name_buf[1024];
19679  char val_buf[1024];
19680  const char *name;
19681  char *c;
19682  int res = 0;
19683 
19684  for (x = 0; x < req->headers; x++) {
19685  const char *header = REQ_OFFSET_TO_STR(req, header[x]);
19686 
19687  if ((c = strchr(header, ':'))) {
19688  ast_copy_string(name_buf, header, MIN((c - header + 1), sizeof(name_buf)));
19689  ast_copy_string(val_buf, ast_skip_blanks(c + 1), sizeof(val_buf));
19690  ast_trim_blanks(name_buf);
19691 
19692  /* Convert header name to full name alias. */
19693  name = find_full_alias(name_buf, name_buf);
19694 
19695  res = ast_msg_set_var(msg, name, val_buf);
19696  if (res) {
19697  break;
19698  }
19699  }
19700  }
19701  return res;
19702 }
static const char * find_full_alias(const char *name, const char *_default)
Find full SIP alias.
Definition: chan_sip.c:8547
static struct test_val c
#define MIN(a, b)
Definition: utils.h:226
int ast_msg_set_var(struct ast_msg *msg, const char *name, const char *value)
Set a variable on the message going to the dialplan.
Definition: message.c:615
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
int headers
Definition: sip.h:832
char * ast_trim_blanks(char *str)
Trims trailing whitespace characters from a string.
Definition: strings.h:182
static const char name[]
Definition: cdr_mysql.c:74
#define REQ_OFFSET_TO_STR(req, offset)
Definition: sip.h:858
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401

◆ set_peer_defaults()

static void set_peer_defaults ( struct sip_peer peer)
static

Set peer defaults before configuring specific configurations.

Definition at line 31482 of file chan_sip.c.

References sip_peer::addr, sip_settings::allowtransfer, sip_peer::allowtransfer, ao2_ref, ast_copy_flags, ast_format_cap_append_from_cap(), AST_MEDIA_TYPE_UNKNOWN, ast_sockaddr_setnull(), ast_string_field_set, AST_TRANSPORT_UDP, sip_peer::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_settings::caps, sip_peer::caps, cid_name, cid_num, clear_peer_mailboxes(), context, sip_peer::defaddr, sip_settings::default_context, default_engine, default_keepalive, default_language, default_maxcallbitrate, default_mohinterpret, default_mohsuggest, sip_peer::default_outbound_transport, default_primary_transport, default_qualify, sip_settings::default_record_off_feature, sip_settings::default_record_on_feature, sip_settings::default_subscribecontext, default_transports, default_vmexten, default_zone, sip_settings::disallowed_methods, sip_peer::disallowed_methods, sip_peer::expire, sip_peer::flags, global_autoframing, global_callcounter, global_max_se, global_min_se, global_qualifyfreq, global_rtpholdtimeout, global_rtpkeepalive, global_rtptimeout, global_st_mode, global_st_refresher, global_t1, global_t38_maxdatagram, global_timer_b, sip_peer::keepalive, language, sip_peer::maxcallbitrate, sip_peer::maxms, sip_settings::messagecontext, mohinterpret, mohsuggest, NULL, sip_peer::outboundproxy, peer_sched_cleanup(), sip_peer::pickupgroup, sip_peer::qualifyfreq, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_peer::rtptimeout, set_socket_transport(), sip_cfg, SIP_FLAGS_TO_COPY, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE3_FLAGS_TO_COPY, SIP_TYPE_PEER, sip_peer::socket, sip_st_cfg::st_max_se, sip_st_cfg::st_min_se, sip_st_cfg::st_mode_oper, sip_st_cfg::st_ref, sip_peer::stimer, sip_peer::t38_maxdatagram, sip_peer::timer_b, sip_peer::timer_t1, sip_peer::transports, sip_peer::type, and vmexten.

Referenced by build_peer(), and temp_peer().

31483 {
31484  if (peer->expire < 0) {
31485  /* Don't reset expire or port time during reload
31486  if we have an active registration
31487  */
31488  peer_sched_cleanup(peer);
31490  }
31491  peer->type = SIP_TYPE_PEER;
31496  ast_string_field_set(peer, record_on_feature, sip_cfg.default_record_on_feature);
31497  ast_string_field_set(peer, record_off_feature, sip_cfg.default_record_off_feature);
31498  ast_string_field_set(peer, messagecontext, sip_cfg.messagecontext);
31499  ast_string_field_set(peer, subscribecontext, sip_cfg.default_subscribecontext);
31503  ast_string_field_set(peer, engine, default_engine);
31504  ast_sockaddr_setnull(&peer->addr);
31505  ast_sockaddr_setnull(&peer->defaddr);
31508  peer->rtptimeout = global_rtptimeout;
31515  if (global_callcounter)
31516  peer->call_limit=INT_MAX;
31518  ast_string_field_set(peer, secret, "");
31519  ast_string_field_set(peer, description, "");
31520  ast_string_field_set(peer, remotesecret, "");
31521  ast_string_field_set(peer, md5secret, "");
31522  ast_string_field_set(peer, cid_num, "");
31523  ast_string_field_set(peer, cid_name, "");
31524  ast_string_field_set(peer, cid_tag, "");
31525  ast_string_field_set(peer, fromdomain, "");
31526  ast_string_field_set(peer, fromuser, "");
31527  ast_string_field_set(peer, regexten, "");
31528  peer->callgroup = 0;
31529  peer->pickupgroup = 0;
31530  peer->maxms = default_qualify;
31531  peer->keepalive = default_keepalive;
31532  ast_string_field_set(peer, zone, default_zone);
31533  peer->stimer.st_mode_oper = global_st_mode; /* Session-Timers */
31535  peer->stimer.st_min_se = global_min_se;
31536  peer->stimer.st_max_se = global_max_se;
31537  peer->timer_t1 = global_t1;
31538  peer->timer_b = global_timer_b;
31539  clear_peer_mailboxes(peer);
31543  if (peer->outboundproxy) {
31544  ao2_ref(peer->outboundproxy, -1);
31545  peer->outboundproxy = NULL;
31546  }
31547 }
int st_min_se
Definition: sip.h:978
int keepalive
Definition: sip.h:1360
static char mohinterpret[MAX_MUSICCLASS]
Definition: chan_alsa.c:119
struct ast_sockaddr addr
Definition: sip.h:1352
int maxms
Definition: sip.h:1357
int timer_t1
Definition: sip.h:1369
static int default_keepalive
Definition: chan_sip.c:798
int rtpholdtimeout
Definition: sip.h:1344
static int global_rtptimeout
Definition: chan_sip.c:823
unsigned int disallowed_methods
Definition: sip.h:772
struct ast_sockaddr defaddr
Definition: sip.h:1362
static char default_language[MAX_LANGUAGE]
Definition: chan_sip.c:790
enum sip_peer_type type
Definition: sip.h:1375
#define ast_copy_flags(dest, src, flagz)
Definition: utils.h:84
static unsigned int global_t38_maxdatagram
Definition: chan_sip.c:885
#define NULL
Definition: resample.c:96
static int default_maxcallbitrate
Definition: chan_sip.c:804
int st_max_se
Definition: sip.h:979
static char cid_num[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:164
static unsigned int default_transports
Definition: chan_sip.c:806
unsigned short transports
Definition: sip.h:1311
struct sip_proxy * outboundproxy
Definition: sip.h:1350
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
Definition: netsock2.h:140
enum transfermodes allowtransfer
Definition: sip.h:776
int rtptimeout
Definition: sip.h:1343
char default_record_off_feature[AST_FEATURE_MAX_LEN]
Definition: sip.h:785
enum transfermodes allowtransfer
Definition: sip.h:1332
char default_subscribecontext[AST_MAX_CONTEXT]
Definition: sip.h:783
static char default_zone[MAX_TONEZONE_COUNTRY]
Definition: chan_sip.c:805
static char mohsuggest[MAX_MUSICCLASS]
Definition: chan_iax2.c:430
int call_limit
Definition: sip.h:1328
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define SIP_PAGE3_FLAGS_TO_COPY
Definition: sip.h:396
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
int maxcallbitrate
Definition: sip.h:1340
int timer_b
Definition: sip.h:1370
unsigned int t38_maxdatagram
Definition: sip.h:1329
#define SIP_PAGE2_FLAGS_TO_COPY
Definition: sip.h:375
char messagecontext[AST_MAX_CONTEXT]
Definition: sip.h:771
static int default_qualify
Definition: chan_sip.c:797
int expire
Definition: sip.h:1341
static int global_callcounter
Definition: chan_sip.c:830
struct ast_format_cap * caps
Definition: sip.h:1342
static struct ast_flags global_flags[3]
Definition: chan_sip.c:884
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
static char default_mohsuggest[MAX_MUSICCLASS]
Definition: chan_sip.c:800
static int global_timer_b
Definition: chan_sip.c:849
static void peer_sched_cleanup(struct sip_peer *peer)
Definition: chan_sip.c:3209
#define SIP_FLAGS_TO_COPY
Flags to copy from peer/user to dialog.
Definition: sip.h:313
static int global_max_se
Definition: chan_sip.c:858
int rtpkeepalive
Definition: sip.h:1345
static unsigned int global_autoframing
Definition: chan_sip.c:850
static char default_engine[256]
Definition: chan_sip.c:803
static int global_qualifyfreq
Definition: chan_sip.c:851
enum st_mode st_mode_oper
Definition: sip.h:976
unsigned short autoframing
Definition: sip.h:1317
struct ast_format_cap * caps
Global list of addresses dynamic peers are not allowed to use.
Definition: sip.h:787
static enum st_refresher_param global_st_refresher
Definition: chan_sip.c:856
static char cid_name[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:165
ast_group_t callgroup
Definition: sip.h:1346
static enum st_mode global_st_mode
Definition: chan_sip.c:855
static char default_mohinterpret[MAX_MUSICCLASS]
Definition: chan_sip.c:799
struct ast_flags flags[3]
Definition: sip.h:1335
static int global_t1
Definition: chan_sip.c:847
char default_record_on_feature[AST_FEATURE_MAX_LEN]
Definition: sip.h:784
enum ast_transport default_outbound_transport
Definition: sip.h:1308
static void clear_peer_mailboxes(struct sip_peer *peer)
Definition: chan_sip.c:5293
static int global_rtpholdtimeout
Definition: chan_sip.c:824
static char default_vmexten[AST_MAX_EXTENSION]
Definition: chan_sip.c:796
int qualifyfreq
Definition: sip.h:1358
int ast_format_cap_append_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type)
Append the formats of provided type in src to dst.
Definition: format_cap.c:269
static void set_socket_transport(struct sip_socket *socket, int transport)
Definition: chan_sip.c:16629
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
struct sip_st_cfg stimer
Definition: sip.h:1368
char default_context[AST_MAX_CONTEXT]
Definition: sip.h:782
static unsigned int default_primary_transport
Definition: chan_sip.c:807
enum st_refresher_param st_ref
Definition: sip.h:977
static int global_rtpkeepalive
Definition: chan_sip.c:825
struct sip_socket socket
Definition: sip.h:1307
static char vmexten[AST_MAX_EXTENSION]
Definition: chan_skinny.c:206
static int global_min_se
Definition: chan_sip.c:857
ast_group_t pickupgroup
Definition: sip.h:1347
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514
unsigned int disallowed_methods
Definition: sip.h:1376

◆ set_peer_nat()

static void set_peer_nat ( const struct sip_pvt p,
struct sip_peer peer 
)
static

Set the peers nat flags if they are using auto_* settings.

Definition at line 19103 of file chan_sip.c.

References ast_clear_flag, ast_set_flag, ast_test_flag, sip_peer::flags, sip_pvt::natdetected, SIP_NAT_FORCE_RPORT, SIP_PAGE2_SYMMETRICRTP, SIP_PAGE3_NAT_AUTO_COMEDIA, and SIP_PAGE3_NAT_AUTO_RPORT.

Referenced by check_peer_ok(), register_verify(), and sip_request_call().

19104 {
19105 
19106  if (!p || !peer) {
19107  return;
19108  }
19109 
19110  if (ast_test_flag(&peer->flags[2], SIP_PAGE3_NAT_AUTO_RPORT)) {
19111  if (p->natdetected) {
19113  } else {
19115  }
19116  }
19117 
19119  if (p->natdetected) {
19121  } else {
19123  }
19124  }
19125 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define SIP_NAT_FORCE_RPORT
Definition: sip.h:283
#define SIP_PAGE2_SYMMETRICRTP
Definition: sip.h:327
#define SIP_PAGE3_NAT_AUTO_RPORT
Definition: sip.h:386
#define ast_clear_flag(p, flag)
Definition: utils.h:77
#define SIP_PAGE3_NAT_AUTO_COMEDIA
Definition: sip.h:387
struct ast_flags flags[3]
Definition: sip.h:1335
unsigned short natdetected
Definition: sip.h:1094

◆ set_pvt_allowed_methods()

static unsigned int set_pvt_allowed_methods ( struct sip_pvt pvt,
struct sip_request req 
)
static

A wrapper for parse_allowed_methods geared toward sip_pvts

This function, in addition to setting the allowed methods for a sip_pvt also will take into account the setting of the SIP_PAGE2_RPID_UPDATE flag.

Parameters
pvtThe sip_pvt we are setting the allowed_methods for
reqThe request which we are parsing
Return values
Themethods alloweded by the sip_pvt

Definition at line 9880 of file chan_sip.c.

References sip_pvt::allowed_methods, ast_test_flag, sip_pvt::disallowed_methods, sip_pvt::flags, mark_method_allowed(), parse_allowed_methods(), SIP_PAGE2_RPID_UPDATE, and SIP_UPDATE.

Referenced by check_peer_ok(), handle_request_invite(), handle_request_options(), handle_request_subscribe(), handle_response_invite(), handle_response_subscribe(), and receive_message().

9881 {
9883 
9884  if (ast_test_flag(&pvt->flags[1], SIP_PAGE2_RPID_UPDATE)) {
9886  }
9887  pvt->allowed_methods &= ~(pvt->disallowed_methods);
9888 
9889  return pvt->allowed_methods;
9890 }
unsigned int allowed_methods
Definition: sip.h:1196
#define ast_test_flag(p, flag)
Definition: utils.h:63
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...
Definition: chan_sip.c:9838
struct ast_flags flags[3]
Definition: sip.h:1075
unsigned int disallowed_methods
Definition: sip.h:1201
static void mark_method_allowed(unsigned int *allowed_methods, enum sipmethod method)
Definition: chan_sip.c:9795
#define SIP_PAGE2_RPID_UPDATE
Definition: sip.h:325

◆ set_socket_transport()

static void set_socket_transport ( struct sip_socket socket,
int  transport 
)
static

Definition at line 16629 of file chan_sip.c.

References ao2_ref, ast_websocket_unref(), sip_socket::fd, NULL, sip_socket::tcptls_session, sip_socket::type, and sip_socket::ws_session.

Referenced by __sip_alloc(), __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_request_call(), sip_send_mwi_to_peer(), sip_websocket_callback(), sipsock_read(), and transmit_register().

16630 {
16631  /* if the transport type changes, clear all socket data */
16632  if (socket->type != transport) {
16633  socket->fd = -1;
16634  socket->type = transport;
16635  if (socket->tcptls_session) {
16636  ao2_ref(socket->tcptls_session, -1);
16637  socket->tcptls_session = NULL;
16638  } else if (socket->ws_session) {
16640  socket->ws_session = NULL;
16641  }
16642  }
16643 }
#define NULL
Definition: resample.c:96
int fd
Definition: sip.h:799
struct ast_websocket * ws_session
Definition: sip.h:802
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_tcptls_session_instance * tcptls_session
Definition: sip.h:801
enum ast_transport type
Definition: sip.h:798
void AST_OPTIONAL_API_NAME() ast_websocket_unref(struct ast_websocket *session)

◆ set_t38_capabilities()

static void set_t38_capabilities ( struct sip_pvt p)
static

Set the global T38 capabilities on a SIP dialog structure.

Definition at line 5939 of file chan_sip.c.

References ast_test_flag, ast_udptl_set_error_correction_scheme(), sip_pvt::flags, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_T38SUPPORT_UDPTL_FEC, SIP_PAGE2_T38SUPPORT_UDPTL_REDUNDANCY, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, and UDPTL_ERROR_CORRECTION_REDUNDANCY.

Referenced by check_peer_ok(), and initialize_udptl().

5940 {
5941  if (p->udptl) {
5948  }
5949  }
5950 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_flags flags[3]
Definition: sip.h:1075
#define SIP_PAGE2_T38SUPPORT_UDPTL_FEC
Definition: sip.h:348
struct ast_udptl * udptl
Definition: sip.h:1115
#define SIP_PAGE2_T38SUPPORT
Definition: sip.h:346
void ast_udptl_set_error_correction_scheme(struct ast_udptl *udptl, enum ast_t38_ec_modes ec)
Definition: udptl.c:945
#define SIP_PAGE2_T38SUPPORT_UDPTL
Definition: sip.h:347
#define SIP_PAGE2_T38SUPPORT_UDPTL_REDUNDANCY
Definition: sip.h:349

◆ show_channels_cb()

static int show_channels_cb ( struct sip_pvt cur,
struct __show_chan_arg arg 
)
static

callback for show channel|subscription

Definition at line 22155 of file chan_sip.c.

References ast_channel_nativeformats(), ast_cli(), AST_CLI_YESNO, ast_extension_state2str(), ast_format_cap_get_names(), AST_FORMAT_CAP_NAMES_LEN, ast_sockaddr_stringify_addr(), ast_str_alloca, ast_str_buffer(), ast_test_flag, sip_pvt::callid, sip_pvt::cid_num, sip_pvt::expiry, __show_chan_arg::fd, sip_pvt::flags, FORMAT, FORMAT4, sip_pvt::lastmsg, sip_pvt::laststate, MWI_NOTIFICATION, sip_peer::name, sip_pvt::needdestroy, NONE, __show_chan_arg::numchans, sip_pvt::owner, peer_mailboxes_to_str(), sip_pvt::refer, referstatus2str(), sip_pvt::relatedpeer, S_OR, SIP_PAGE2_CALL_ONHOLD, sip_pvt_lock, sip_pvt_unlock, sip_real_dst(), sip_refer::status, sip_pvt::subscribed, sip_pvt::subscribeuri, subscription_type2str(), __show_chan_arg::subscriptions, and sip_pvt::username.

Referenced by sip_show_channels().

22156 {
22157  const struct ast_sockaddr *dst;
22158 
22159  sip_pvt_lock(cur);
22160  dst = sip_real_dst(cur);
22161 
22162  /* XXX indentation preserved to reduce diff. Will be fixed later */
22163  if (cur->subscribed == NONE && !arg->subscriptions) {
22164  /* set if SIP transfer in progress */
22165  const char *referstatus = cur->refer ? referstatus2str(cur->refer->status) : "";
22166  struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
22167 
22169  S_OR(cur->username, S_OR(cur->cid_num, "(None)")),
22170  cur->callid,
22171  cur->owner ? ast_format_cap_get_names(ast_channel_nativeformats(cur->owner), &codec_buf) : "(nothing)",
22173  cur->needdestroy ? "(d)" : "",
22174  cur->lastmsg ,
22175  referstatus,
22176  cur->relatedpeer ? cur->relatedpeer->name : "<guest>"
22177  );
22178  arg->numchans++;
22179  }
22180  if (cur->subscribed != NONE && arg->subscriptions) {
22181  struct ast_str *mailbox_str = ast_str_alloca(512);
22182  if (cur->subscribed == MWI_NOTIFICATION && cur->relatedpeer)
22183  peer_mailboxes_to_str(&mailbox_str, cur->relatedpeer);
22185  S_OR(cur->username, S_OR(cur->cid_num, "(None)")),
22186  cur->callid,
22187  /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */
22188  cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri,
22189  cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate),
22191  cur->subscribed == MWI_NOTIFICATION ? S_OR(ast_str_buffer(mailbox_str), "<none>") : "<none>",
22192  cur->expiry
22193  );
22194  arg->numchans++;
22195  }
22196  sip_pvt_unlock(cur);
22197  return 0; /* don't care, we scan all channels */
22198 }
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:290
enum subscriptiontype subscribed
Definition: sip.h:1161
#define FORMAT4
Definition: chan_sip.c:22149
char lastmsg[256]
Definition: sip.h:1145
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define NONE
Definition: misdn_config.c:45
struct sip_peer * relatedpeer
Definition: sip.h:1171
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:326
enum referstatus status
Definition: sip.h:947
unsigned short needdestroy
Definition: sip.h:1080
const ast_string_field username
Definition: sip.h:1063
int subscriptions
Definition: sip.h:734
#define SIP_PAGE2_CALL_ONHOLD
Definition: sip.h:351
struct ast_flags flags[3]
Definition: sip.h:1075
#define ast_str_alloca(init_len)
Definition: strings.h:800
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
Socket address structure.
Definition: netsock2.h:97
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
char name[80]
Definition: sip.h:1274
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
const char * ast_extension_state2str(int extension_state)
Return string representation of the state of an extension.
Definition: pbx.c:3126
static const struct ast_sockaddr * sip_real_dst(const struct sip_pvt *p)
The real destination address for a write.
Definition: chan_sip.c:3633
int expiry
Definition: sip.h:1118
const ast_string_field callid
Definition: sip.h:1063
static const char * referstatus2str(enum referstatus rstatus) attribute_pure
Convert transfer status to string.
Definition: chan_sip.c:3424
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
const ast_string_field cid_num
Definition: sip.h:1063
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition: format_cap.c:736
struct ast_channel * owner
Definition: sip.h:1138
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
struct sip_refer * refer
Definition: sip.h:1160
referstatus
Parameters to know status of transfer.
Definition: sip.h:674
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
#define FORMAT
Definition: chan_sip.c:22152
int laststate
Definition: sip.h:1163
int numchans
Definition: sip.h:735
#define AST_CLI_YESNO(x)
Return Yes or No depending on the argument.
Definition: cli.h:71
const ast_string_field subscribeuri
Definition: sip.h:1063
static const char * subscription_type2str(enum subscriptiontype subtype) attribute_pure
Show subscription type in string format.
Definition: chan_sip.c:22117
static void peer_mailboxes_to_str(struct ast_str **mailbox_str, struct sip_peer *peer)
list peer mailboxes to CLI
Definition: chan_sip.c:21157

◆ show_chanstats_cb()

static int show_chanstats_cb ( struct sip_pvt cur,
struct __show_chan_arg arg 
)
static

Callback for show_chanstats.

Definition at line 21742 of file chan_sip.c.

References ast_channel_get_duration(), ast_cli(), ast_format_duration_hh_mm_ss(), ast_log, ast_rtp_instance_get_stats(), AST_RTP_INSTANCE_STAT_ALL, ast_sockaddr_stringify_addr(), c, sip_pvt::callid, invstate2stringtable::desc, __show_chan_arg::fd, FORMAT, sip_pvt::invitestate, invitestate2string, LOG_WARNING, NONE, __show_chan_arg::numchans, sip_pvt::owner, sip_pvt::rtp, ast_rtp_instance_stats::rxcount, ast_rtp_instance_stats::rxjitter, ast_rtp_instance_stats::rxploss, sip_pvt::sa, sip_pvt_lock, sip_pvt_unlock, sipdebug, sip_pvt::subscribed, ast_rtp_instance_stats::txcount, ast_rtp_instance_stats::txjitter, and ast_rtp_instance_stats::txploss.

Referenced by sip_show_channelstats().

21743 {
21744 #define FORMAT2 "%-15.15s %-11.11s %-8.8s %-10.10s %-10.10s ( %%) %-6.6s %-10.10s %-10.10s ( %%) %-6.6s\n"
21745 #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"
21746  struct ast_rtp_instance_stats stats;
21747  char durbuf[10];
21748  struct ast_channel *c;
21749  int fd = arg->fd;
21750 
21751  sip_pvt_lock(cur);
21752  c = cur->owner;
21753 
21754  if (cur->subscribed != NONE) {
21755  /* Subscriptions */
21756  sip_pvt_unlock(cur);
21757  return 0; /* don't care, we scan all channels */
21758  }
21759 
21760  if (!cur->rtp) {
21761  if (sipdebug) {
21762  ast_cli(fd, "%-15.15s %-11.11s (inv state: %s) -- %s\n",
21763  ast_sockaddr_stringify_addr(&cur->sa), cur->callid,
21765  "-- No RTP active");
21766  }
21767  sip_pvt_unlock(cur);
21768  return 0; /* don't care, we scan all channels */
21769  }
21770 
21772  sip_pvt_unlock(cur);
21773  ast_log(LOG_WARNING, "Could not get RTP stats.\n");
21774  return 0;
21775  }
21776 
21777  if (c) {
21778  ast_format_duration_hh_mm_ss(ast_channel_get_duration(c), durbuf, sizeof(durbuf));
21779  } else {
21780  durbuf[0] = '\0';
21781  }
21782 
21783  ast_cli(fd, FORMAT,
21785  cur->callid,
21786  durbuf,
21787  stats.rxcount > (unsigned int) 100000 ? (unsigned int) (stats.rxcount)/(unsigned int) 1000 : stats.rxcount,
21788  stats.rxcount > (unsigned int) 100000 ? "K":" ",
21789  stats.rxploss,
21790  (stats.rxcount + stats.rxploss) > 0 ? (double) stats.rxploss / (stats.rxcount + stats.rxploss) * 100 : 0,
21791  stats.rxjitter,
21792  stats.txcount > (unsigned int) 100000 ? (unsigned int) (stats.txcount)/(unsigned int) 1000 : stats.txcount,
21793  stats.txcount > (unsigned int) 100000 ? "K":" ",
21794  stats.txploss,
21795  stats.txcount > 0 ? (double) stats.txploss / stats.txcount * 100 : 0,
21796  stats.txjitter
21797  );
21798  arg->numchans++;
21799  sip_pvt_unlock(cur);
21800 
21801  return 0; /* don't care, we scan all channels */
21802 }
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:290
Main Channel structure associated with a channel.
const char * desc
Definition: chan_sip.c:697
enum subscriptiontype subscribed
Definition: sip.h:1161
int ast_rtp_instance_get_stats(struct ast_rtp_instance *instance, struct ast_rtp_instance_stats *stats, enum ast_rtp_instance_stat stat)
Retrieve statistics about an RTP instance.
Definition: rtp_engine.c:2446
#define NONE
Definition: misdn_config.c:45
#define LOG_WARNING
Definition: logger.h:274
static struct test_val c
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
struct ast_sockaddr sa
Definition: sip.h:1125
#define ast_log
Definition: astobj2.c:42
static const struct invstate2stringtable invitestate2string[]
const ast_string_field callid
Definition: sip.h:1063
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
int ast_channel_get_duration(struct ast_channel *chan)
Obtain how long the channel since the channel was created.
Definition: channel.c:2839
struct ast_channel * owner
Definition: sip.h:1138
struct ast_rtp_instance * rtp
Definition: sip.h:1174
enum invitestates invitestate
Definition: sip.h:1007
#define FORMAT
Definition: chan_sip.c:22152
int numchans
Definition: sip.h:735
void ast_format_duration_hh_mm_ss(int duration, char *buf, size_t length)
Formats a duration into HH:MM:SS.
Definition: main/utils.c:2049

◆ shutdown_mwi_subscription()

static void shutdown_mwi_subscription ( struct sip_subscription_mwi mwi)
static

Definition at line 14952 of file chan_sip.c.

References __shutdown_mwi_subscription(), ao2_t_ref, and ast_sched_add().

Referenced by unload_module().

14953 {
14954  ao2_t_ref(mwi, +1, "Shutdown MWI subscription action");
14955  if (ast_sched_add(sched, 0, __shutdown_mwi_subscription, mwi) < 0) {
14956  /* Uh Oh. Expect bad behavior. */
14957  ao2_t_ref(mwi, -1, "Failed to schedule shutdown MWI subscription action");
14958  }
14959 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
Definition: sched.c:76
static int __shutdown_mwi_subscription(const void *data)
Definition: chan_sip.c:14935
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565

◆ sip_addheader()

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

Add a SIP header to an outbound INVITE.

Definition at line 34078 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, NULL, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), sipdebug, and TRUE.

Referenced by load_module().

34079 {
34080  int no = 0;
34081  int ok = FALSE;
34082  char varbuf[30];
34083  const char *inbuf = data;
34084  char *subbuf;
34085 
34086  if (ast_strlen_zero(inbuf)) {
34087  ast_log(LOG_WARNING, "This application requires the argument: Header\n");
34088  return 0;
34089  }
34090  ast_channel_lock(chan);
34091 
34092  /* Check for headers */
34093  while (!ok && no <= 50) {
34094  no++;
34095  snprintf(varbuf, sizeof(varbuf), "__SIPADDHEADER%.2d", no);
34096 
34097  /* Compare without the leading underscores */
34098  if ((pbx_builtin_getvar_helper(chan, (const char *) varbuf + 2) == (const char *) NULL)) {
34099  ok = TRUE;
34100  }
34101  }
34102  if (ok) {
34103  size_t len = strlen(inbuf);
34104  subbuf = ast_alloca(len + 1);
34105  ast_get_encoded_str(inbuf, subbuf, len + 1);
34106  pbx_builtin_setvar_helper(chan, varbuf, subbuf);
34107  if (sipdebug) {
34108  ast_debug(1, "SIP Header added \"%s\" as %s\n", inbuf, varbuf);
34109  }
34110  } else {
34111  ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n");
34112  }
34113  ast_channel_unlock(chan);
34114  return 0;
34115 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
#define FALSE
Definition: app_minivm.c:521
char * ast_get_encoded_str(const char *stream, char *result, size_t result_len)
Decode a stream of encoded control or extended ASCII characters.
Definition: main/app.c:3002
#define LOG_WARNING
Definition: logger.h:274
#define NULL
Definition: resample.c:96
const char * data
static int inbuf(struct baseio *bio, FILE *fi)
utility used by inchar(), for base_encode()
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
#define ast_channel_unlock(chan)
Definition: channel.h:2946
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
#define TRUE
Definition: app_minivm.c:518

◆ sip_allow_anyrtp_remote()

static int sip_allow_anyrtp_remote ( struct ast_channel chan1,
struct ast_rtp_instance instance,
const char *  rtptype 
)
static

Definition at line 33729 of file chan_sip.c.

References ast_apply_acl(), ast_channel_tech_pvt(), ast_debug, ast_duplicate_acl_list(), ast_free_acl_list(), ast_rtp_instance_get_local_address(), ast_rtp_instance_get_requested_target_address(), AST_SENSE_DENY, ast_sockaddr_stringify(), ast_strdupa, ast_test_flag, sip_peer::directmediaacl, sip_pvt::flags, NULL, sip_pvt::relatedpeer, SIP_DIRECT_MEDIA, sip_pvt_lock, and sip_pvt_unlock.

Referenced by sip_allow_rtp_remote(), and sip_allow_vrtp_remote().

33730 {
33731  struct sip_pvt *p;
33732  struct ast_acl_list *acl = NULL;
33733  int res = 1;
33734 
33735  if (!(p = ast_channel_tech_pvt(chan1))) {
33736  return 0;
33737  }
33738 
33739  sip_pvt_lock(p);
33740  if (p->relatedpeer && p->relatedpeer->directmediaacl) {
33742  }
33743  sip_pvt_unlock(p);
33744 
33745  if (!acl) {
33746  return res;
33747  }
33748 
33749  if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) {
33750  struct ast_sockaddr us = { { 0, }, }, them = { { 0, }, };
33751 
33753  ast_rtp_instance_get_local_address(instance, &us);
33754 
33755  if (ast_apply_acl(acl, &them, "SIP Direct Media ACL: ") == AST_SENSE_DENY) {
33756  const char *us_addr = ast_strdupa(ast_sockaddr_stringify(&us));
33757  const char *them_addr = ast_strdupa(ast_sockaddr_stringify(&them));
33758 
33759  ast_debug(3, "Reinvite %s to %s denied by directmedia ACL on %s\n",
33760  rtptype, them_addr, us_addr);
33761 
33762  res = 0;
33763  }
33764  }
33765 
33766  ast_free_acl_list(acl);
33767 
33768  return res;
33769 }
#define SIP_DIRECT_MEDIA
Definition: sip.h:289
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct sip_peer * relatedpeer
Definition: sip.h:1171
Wrapper for an ast_acl linked list.
Definition: acl.h:76
struct ast_flags flags[3]
Definition: sip.h:1075
#define NULL
Definition: resample.c:96
Socket address structure.
Definition: netsock2.h:97
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct ast_acl_list * ast_duplicate_acl_list(struct ast_acl_list *original)
Duplicates the contests of a list of lists of host access rules.
Definition: acl.c:316
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
enum ast_acl_sense ast_apply_acl(struct ast_acl_list *acl_list, const struct ast_sockaddr *addr, const char *purpose)
Apply a set of rules to a given IP address.
Definition: acl.c:800
struct ast_acl_list * directmediaacl
Definition: sip.h:1365
struct ast_acl_list * ast_free_acl_list(struct ast_acl_list *acl)
Free a list of ACLs.
Definition: acl.c:233
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
Definition: test_acl.c:111
void ast_rtp_instance_get_local_address(struct ast_rtp_instance *instance, struct ast_sockaddr *address)
Get the local address that we are expecting RTP on.
Definition: rtp_engine.c:643
void ast_rtp_instance_get_requested_target_address(struct ast_rtp_instance *instance, struct ast_sockaddr *address)
Get the requested target address of the remote endpoint.
Definition: rtp_engine.c:673

◆ sip_allow_rtp_remote()

static int sip_allow_rtp_remote ( struct ast_channel chan1,
struct ast_rtp_instance instance 
)
static

Definition at line 33771 of file chan_sip.c.

References sip_allow_anyrtp_remote().

33772 {
33773  return sip_allow_anyrtp_remote(chan1, instance, "audio");
33774 }
static int sip_allow_anyrtp_remote(struct ast_channel *chan1, struct ast_rtp_instance *instance, const char *rtptype)
Definition: chan_sip.c:33729

◆ sip_allow_vrtp_remote()

static int sip_allow_vrtp_remote ( struct ast_channel chan1,
struct ast_rtp_instance instance 
)
static

Definition at line 33776 of file chan_sip.c.

References sip_allow_anyrtp_remote().

33777 {
33778  return sip_allow_anyrtp_remote(chan1, instance, "video");
33779 }
static int sip_allow_anyrtp_remote(struct ast_channel *chan1, struct ast_rtp_instance *instance, const char *rtptype)
Definition: chan_sip.c:33729

◆ sip_alreadygone()

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

References sip_pvt::alreadygone, ast_debug, and sip_pvt::callid.

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

3461 {
3462  ast_debug(3, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid);
3463  dialog->alreadygone = 1;
3464 }
unsigned short alreadygone
Definition: sip.h:1079
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
const ast_string_field callid
Definition: sip.h:1063

◆ sip_answer()

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

References ast_channel_name(), ast_channel_tech_pvt(), ast_debug, ast_rtp_instance_update_source(), ast_set_flag, ast_setstate(), AST_STATE_UP, ast_test_flag, FALSE, sip_pvt::flags, sip_pvt::initreq, restart_session_timer(), sip_pvt::rtp, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PROGRESS_SENT, sip_pvt_lock, sip_pvt_unlock, sip_pvt::stimer, transmit_response_with_sdp(), TRUE, try_suggested_sip_codec(), and XMIT_CRITICAL.

7477 {
7478  int res = 0;
7479  struct sip_pvt *p = ast_channel_tech_pvt(ast);
7480  int oldsdp = FALSE;
7481 
7482  if (!p) {
7483  ast_debug(1, "Asked to answer channel %s without tech pvt; ignoring\n",
7484  ast_channel_name(ast));
7485  return res;
7486  }
7487  sip_pvt_lock(p);
7488  if (ast_channel_state(ast) != AST_STATE_UP) {
7490 
7491  if (ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT)) {
7492  oldsdp = TRUE;
7493  }
7494 
7495  ast_setstate(ast, AST_STATE_UP);
7496  ast_debug(1, "SIP answering channel: %s\n", ast_channel_name(ast));
7498  res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL, oldsdp, TRUE);
7500  /* RFC says the session timer starts counting on 200,
7501  * not on INVITE. */
7502  if (p->stimer) {
7504  }
7505  }
7506  sip_pvt_unlock(p);
7507  return res;
7508 }
#define FALSE
Definition: app_minivm.c:521
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ast_set_flag(p, flag)
Definition: utils.h:70
ast_channel_state
ast_channel states
Definition: channelstate.h:35
struct ast_flags flags[3]
Definition: sip.h:1075
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
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.
Definition: chan_sip.c:14125
struct sip_request initreq
Definition: sip.h:1151
static void restart_session_timer(struct sip_pvt *p)
Session-Timers: Restart session timer.
Definition: chan_sip.c:30278
struct sip_st_dlg * stimer
Definition: sip.h:1184
static void try_suggested_sip_codec(struct sip_pvt *p)
Try setting the codecs suggested by the SIP_CODEC channel variable.
Definition: chan_sip.c:7405
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
struct ast_rtp_instance * rtp
Definition: sip.h:1174
const char * ast_channel_name(const struct ast_channel *chan)
#define TRUE
Definition: app_minivm.c:518
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7486
void ast_rtp_instance_update_source(struct ast_rtp_instance *instance)
Indicate that the RTP marker bit should be set on an RTP stream.
Definition: rtp_engine.c:2151
#define SIP_PAGE2_DIALOG_ESTABLISHED
Definition: sip.h:358
#define SIP_PROGRESS_SENT
Definition: sip.h:260

◆ sip_auth_headers()

void sip_auth_headers ( enum sip_auth_type  code,
char **  header,
char **  respheader 
)

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

Definition at line 16549 of file chan_sip.c.

References ast_verbose(), PROXY_AUTH, and WWW_AUTH.

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

16550 {
16551  if (code == WWW_AUTH) { /* 401 */
16552  *header = "WWW-Authenticate";
16553  *respheader = "Authorization";
16554  } else if (code == PROXY_AUTH) { /* 407 */
16555  *header = "Proxy-Authenticate";
16556  *respheader = "Proxy-Authorization";
16557  } else {
16558  ast_verbose("-- wrong response code %u\n", code);
16559  *header = *respheader = "Invalid";
16560  }
16561 }
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
Definition: sip.h:504

◆ sip_call()

static int sip_call ( struct ast_channel ast,
const char *  dest,
int  timeout 
)
static

Initiate SIP call from PBX used from the dial() application.

Definition at line 6445 of file chan_sip.c.

References sip_invite_param::addsipheaders, 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_caller(), ast_channel_get_device_name(), ast_channel_hangupcause_set(), AST_CHANNEL_NAME, ast_channel_name(), ast_channel_queue_connected_line_update(), ast_channel_tech_pvt(), ast_channel_varshead(), ast_clear_flag, AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER, ast_copy_string(), ast_debug, ast_format_cap_empty(), ast_format_cap_has_type(), AST_LIST_TRAVERSE, ast_log, AST_MEDIA_TYPE_AUDIO, 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_sdp_srtp_alloc(), ast_set_flag, ast_set_party_id_all(), AST_STATE_DOWN, AST_STATE_RESERVED, ast_string_field_set, ast_strlen_zero, ast_test_flag, AST_TRANSPORT_TLS, ast_var_name(), ast_var_value(), auto_congest(), buf, sip_pvt::callingpres, sip_pvt::caps, cid_name, sip_pvt::cid_name, sip_pvt::cid_num, sip_pvt::cid_tag, connected, sip_monitor_instance::device_name, dialog_ref, dialog_unref, sip_pvt::flags, ast_party_connected_line::id, ast_set_party_connected_line::id, INC_CALL_RINGING, sip_pvt::initid, INV_CALLING, sip_pvt::invitestate, sip_pvt::jointcaps, sip_pvt::jointnoncodeccapability, LOG_WARNING, sip_pvt::maxforwards, ast_party_id::name, ast_set_party_id::name, sip_pvt::noncodeccapability, sip_monitor_instance::notify_uri, NULL, ast_party_id::number, ast_set_party_id::number, sip_pvt::options, sip_pvt::prefcaps, ast_party_name::presentation, ast_party_number::presentation, ast_set_party_connected_line::priv, ast_cc_monitor::private_data, sip_invite_param::replaces, sip_pvt::req_secure_signaling, sip_pvt::rtp, SIP_INVITE, SIP_OUTGOING, SIP_PAGE2_FAX_DETECT_T38, SIP_PAGE2_USE_SRTP, sip_pvt_lock, sip_pvt_unlock, SIP_REINVITE, SIPBUFSIZE, sipdebug, sip_pvt::socket, ast_party_connected_line::source, sip_pvt::srtp, ast_party_name::str, ast_party_number::str, ast_party_id::tag, sip_pvt::timer_b, sip_invite_param::transfer, transmit_invite(), sip_pvt::trtp, sip_pvt::tsrtp, sip_socket::type, update_call_counter(), sip_invite_param::uri_options, sip_pvt::username, ast_party_name::valid, ast_party_number::valid, sip_pvt::vrtp, sip_pvt::vsrtp, sip_invite_param::vxml_url, and XMIT_ERROR.

6446 {
6447  int res;
6448  struct sip_pvt *p = ast_channel_tech_pvt(ast); /* chan is locked, so the reference cannot go away */
6449  struct varshead *headp;
6450  struct ast_var_t *current;
6451  const char *referer = NULL; /* SIP referrer */
6452  int cc_core_id;
6453  char uri[SIPBUFSIZE] = "";
6454 
6456  ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast_channel_name(ast));
6457  return -1;
6458  }
6459 
6460  if (ast_cc_is_recall(ast, &cc_core_id, "SIP")) {
6461  char device_name[AST_CHANNEL_NAME];
6462  struct ast_cc_monitor *recall_monitor;
6463  struct sip_monitor_instance *monitor_instance;
6464  ast_channel_get_device_name(ast, device_name, sizeof(device_name));
6465  if ((recall_monitor = ast_cc_get_monitor_by_recall_core_id(cc_core_id, device_name))) {
6466  monitor_instance = recall_monitor->private_data;
6467  ast_copy_string(uri, monitor_instance->notify_uri, sizeof(uri));
6468  ao2_t_ref(recall_monitor, -1, "Got the URI we need so unreffing monitor");
6469  }
6470  }
6471 
6472  /* Check whether there is vxml_url, distinctive ring variables */
6473  headp = ast_channel_varshead(ast);
6474  AST_LIST_TRAVERSE(headp, current, entries) {
6475  /* Check whether there is a VXML_URL variable */
6476  if (!p->options->vxml_url && !strcmp(ast_var_name(current), "VXML_URL")) {
6477  p->options->vxml_url = ast_var_value(current);
6478  } else if (!p->options->uri_options && !strcmp(ast_var_name(current), "SIP_URI_OPTIONS")) {
6479  p->options->uri_options = ast_var_value(current);
6480  } else if (!p->options->addsipheaders && !strncmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) {
6481  /* Check whether there is a variable with a name starting with SIPADDHEADER */
6482  p->options->addsipheaders = 1;
6483  } else if (!strcmp(ast_var_name(current), "SIPFROMDOMAIN")) {
6484  ast_string_field_set(p, fromdomain, ast_var_value(current));
6485  } else if (!strcmp(ast_var_name(current), "SIPTRANSFER")) {
6486  /* This is a transferred call */
6487  p->options->transfer = 1;
6488  } else if (!strcmp(ast_var_name(current), "SIPTRANSFER_REFERER")) {
6489  /* This is the referrer */
6490  referer = ast_var_value(current);
6491  } else if (!strcmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) {
6492  /* We're replacing a call. */
6493  p->options->replaces = ast_var_value(current);
6494  } else if (!strcmp(ast_var_name(current), "SIP_MAX_FORWARDS")) {
6495  if (sscanf(ast_var_value(current), "%30d", &(p->maxforwards)) != 1) {
6496  ast_log(LOG_WARNING, "The SIP_MAX_FORWARDS channel variable is not a valid integer.\n");
6497  }
6498  }
6499  }
6500 
6501  /* Check to see if we should try to force encryption */
6503  ast_log(LOG_WARNING, "Encrypted signaling is required\n");
6505  return -1;
6506  }
6507 
6508  if (ast_test_flag(&p->flags[1], SIP_PAGE2_USE_SRTP)) {
6509  if (ast_test_flag(&p->flags[0], SIP_REINVITE)) {
6510  ast_debug(1, "Direct media not possible when using SRTP, ignoring canreinvite setting\n");
6512  }
6513 
6514  if (p->rtp && !p->srtp && !(p->srtp = ast_sdp_srtp_alloc())) {
6515  ast_log(LOG_WARNING, "SRTP audio setup failed\n");
6516  return -1;
6517  }
6518 
6519  if (p->vrtp && !p->vsrtp && !(p->vsrtp = ast_sdp_srtp_alloc())) {
6520  ast_log(LOG_WARNING, "SRTP video setup failed\n");
6521  return -1;
6522  }
6523 
6524  if (p->trtp && !p->tsrtp && !(p->tsrtp = ast_sdp_srtp_alloc())) {
6525  ast_log(LOG_WARNING, "SRTP text setup failed\n");
6526  return -1;
6527  }
6528  }
6529 
6530  res = 0;
6531  ast_set_flag(&p->flags[0], SIP_OUTGOING);
6532 
6533  /* T.38 re-INVITE FAX detection should never be done for outgoing calls,
6534  * so ensure it is disabled.
6535  */
6537 
6538  if (p->options->transfer) {
6539  char buf[SIPBUFSIZE / 2];
6540 
6541  if (referer) {
6542  if (sipdebug)
6543  ast_debug(3, "Call for %s transferred by %s\n", p->username, referer);
6544  snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer);
6545  } else
6546  snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name);
6547  ast_string_field_set(p, cid_name, buf);
6548  }
6549  ast_debug(1, "Outgoing Call for %s\n", p->username);
6550 
6552 
6553  if (res == -1) {
6555  return res;
6556  }
6560 
6561  /* If there are no formats left to offer, punt */
6562  if (ast_format_cap_empty(p->jointcaps)) {
6563  ast_log(LOG_WARNING, "No format found to offer. Cancelling call to %s\n", p->username);
6564  res = -1;
6565  /* If audio was requested (prefcaps) and the [peer] section contains
6566  * audio (caps) the user expects audio. In that case, if jointcaps
6567  * contain no audio, punt. Furthermore, this check allows the [peer]
6568  * section to have no audio. In that case, the user expects no audio
6569  * and we can pass. Finally, this check allows the requester not to
6570  * offer any audio. In that case, the call is expected to have no audio
6571  * and we can pass, as well.
6572  */
6576  ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username);
6577  res = -1;
6578  } else {
6579  int xmitres;
6581  struct ast_set_party_connected_line update_connected;
6582 
6583  sip_pvt_lock(p);
6584 
6585  /* Supply initial connected line information if available. */
6586  memset(&update_connected, 0, sizeof(update_connected));
6588  if (!ast_strlen_zero(p->cid_num)
6590  update_connected.id.number = 1;
6591  connected.id.number.valid = 1;
6592  connected.id.number.str = (char *) p->cid_num;
6593  connected.id.number.presentation = p->callingpres;
6594  }
6595  if (!ast_strlen_zero(p->cid_name)
6597  update_connected.id.name = 1;
6598  connected.id.name.valid = 1;
6599  connected.id.name.str = (char *) p->cid_name;
6600  connected.id.name.presentation = p->callingpres;
6601  }
6602  if (update_connected.id.number || update_connected.id.name) {
6603  /* Invalidate any earlier private connected id representation */
6604  ast_set_party_id_all(&update_connected.priv);
6605 
6606  connected.id.tag = (char *) p->cid_tag;
6608  ast_channel_queue_connected_line_update(ast, &connected, &update_connected);
6609  }
6610 
6611  xmitres = transmit_invite(p, SIP_INVITE, 1, 2, uri);
6612  if (xmitres == XMIT_ERROR) {
6613  sip_pvt_unlock(p);
6614  return -1;
6615  }
6616  p->invitestate = INV_CALLING;
6617 
6618  /* Initialize auto-congest time */
6620  dialog_unref(_data, "dialog ptr dec when SCHED_REPLACE del op succeeded"),
6621  dialog_unref(p, "dialog ptr dec when SCHED_REPLACE add failed"),
6622  dialog_ref(p, "dialog ptr inc when SCHED_REPLACE add succeeded") );
6623  sip_pvt_unlock(p);
6624  }
6625  return res;
6626 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
Definition: channel.c:2022
struct ast_format_cap * prefcaps
Definition: sip.h:1103
void ast_rtp_instance_available_formats(struct ast_rtp_instance *instance, struct ast_format_cap *to_endpoint, struct ast_format_cap *to_asterisk, struct ast_format_cap *result)
Request the formats that can be transcoded.
Definition: rtp_engine.c:2633
void * ast_channel_tech_pvt(const struct ast_channel *chan)
struct ast_rtp_instance * trtp
Definition: sip.h:1176
#define ast_test_flag(p, flag)
Definition: utils.h:63
const char * ast_var_value(const struct ast_var_t *var)
Definition: chanvars.c:80
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
const char * ast_var_name(const struct ast_var_t *var)
Definition: chanvars.c:60
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define LOG_WARNING
Definition: logger.h:274
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.
Definition: chan_sip.c:14755
struct ast_sdp_srtp * tsrtp
Definition: sip.h:1187
int ast_party_id_presentation(const struct ast_party_id *id)
Determine the overall presentation value for the given party.
Definition: channel.c:1821
int initid
Definition: sip.h:1155
struct sip_socket socket
Definition: sip.h:1066
int addsipheaders
Definition: sip.h:862
const ast_string_field username
Definition: sip.h:1063
Definition: sched.c:76
static int auto_congest(const void *arg)
Scheduled congestion on a call. Only called by the scheduler, must return the reference when done...
Definition: chan_sip.c:6420
ast_channel_state
ast_channel states
Definition: channelstate.h:35
const ast_string_field notify_uri
Definition: sip.h:1819
struct ast_format_cap * jointcaps
Definition: sip.h:1100
struct ast_flags flags[3]
Definition: sip.h:1075
struct varshead * ast_channel_varshead(struct ast_channel *chan)
#define NULL
Definition: resample.c:96
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
int ast_cc_is_recall(struct ast_channel *chan, int *core_id, const char *const monitor_type)
Decide if a call to a particular channel is a CC recall.
Definition: ccss.c:3438
int jointnoncodeccapability
Definition: sip.h:1105
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 th...
Definition: chan_sip.c:6844
struct sip_invite_param * options
Definition: sip.h:1183
struct ast_sdp_srtp * vsrtp
Definition: sip.h:1186
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
#define SIP_PAGE2_USE_SRTP
Definition: sip.h:368
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
const char * vxml_url
Definition: sip.h:864
int noncodeccapability
Definition: sip.h:1104
void ast_channel_queue_connected_line_update(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Queue a connected line update frame on a channel.
Definition: channel.c:9202
struct ast_format_cap * caps
Definition: sip.h:1099
#define SIP_REINVITE
Definition: sip.h:287
int maxforwards
Definition: sip.h:1065
unsigned short req_secure_signaling
Definition: sip.h:1093
int callingpres
Definition: sip.h:1117
int transfer
Definition: sip.h:869
#define XMIT_ERROR
Definition: sip.h:58
const char * replaces
Definition: sip.h:868
const ast_string_field cid_num
Definition: sip.h:1063
const char * uri_options
Definition: sip.h:863
#define SIPBUFSIZE
Definition: sip.h:56
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
Connected Line/Party information.
Definition: channel.h:457
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
struct ast_rtp_instance * vrtp
Definition: sip.h:1175
int timer_b
Definition: sip.h:1096
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define AST_CHANNEL_NAME
Definition: channel.h:172
#define dialog_ref(dialog, tag)
when we create or delete references, make sure to use these functions so we keep track of the refcoun...
Definition: dialog.h:32
struct ast_sdp_srtp * ast_sdp_srtp_alloc(void)
allocate a ast_sdp_srtp structure
Definition: sdp_srtp.c:41
#define INC_CALL_RINGING
Definition: sip.h:130
struct ast_rtp_instance * rtp
Definition: sip.h:1174
enum invitestates invitestate
Definition: sip.h:1007
#define ast_clear_flag(p, flag)
Definition: utils.h:77
#define SIP_PAGE2_FAX_DETECT_T38
Definition: sip.h:362
static char cid_name[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:165
Indicate what information in ast_party_connected_line should be set.
Definition: channel.h:490
#define AST_PRES_RESTRICTION
Definition: callerid.h:323
const ast_string_field cid_name
Definition: sip.h:1063
#define AST_SCHED_REPLACE_UNREF(id, sched, when, callback, data, unrefcall, addfailcall, refcall)
Definition: sched.h:150
enum ast_transport type
Definition: sip.h:798
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
const char * ast_channel_name(const struct ast_channel *chan)
#define AST_CAUSE_USER_BUSY
Definition: causes.h:106
const ast_string_field cid_tag
Definition: sip.h:1063
#define AST_PRES_ALLOWED
Definition: callerid.h:324
int ast_channel_get_device_name(struct ast_channel *chan, char *device_name, size_t name_buffer_length)
Get a device name given its channel structure.
Definition: channel.c:10697
void * private_data
Data that is private to a monitor technology.
Definition: ccss.h:561
int ast_format_cap_empty(const struct ast_format_cap *cap)
Determine if a format cap has no formats in it.
Definition: format_cap.c:746
#define SIP_OUTGOING
Definition: sip.h:257
struct ast_sdp_srtp * srtp
Definition: sip.h:1185
void ast_set_party_id_all(struct ast_set_party_id *update_id)
Set the update marker to update all information of a corresponding party id.
Definition: channel.c:1750
#define AST_CAUSE_BEARERCAPABILITY_NOTAVAIL
Definition: causes.h:129
struct ast_cc_monitor * ast_cc_get_monitor_by_recall_core_id(const int core_id, const char *const device_name)
Get the associated monitor given the device name and core_id.
Definition: ccss.c:3519
char connected
Definition: eagi_proxy.c:82
int ast_format_cap_has_type(const struct ast_format_cap *cap, enum ast_media_type type)
Find out if the capabilities structure has any formats of a specific type.
Definition: format_cap.c:615
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ sip_cancel_destroy()

void sip_cancel_destroy ( struct sip_pvt pvt)

Cancel destruction of SIP dialog.

Definition at line 4464 of file chan_sip.c.

References __sip_cancel_destroy(), ast_log, ast_sched_add(), dialog_ref, dialog_unref, sip_pvt::final_destruction_scheduled, and LOG_WARNING.

Referenced by handle_request_invite(), handle_request_subscribe(), handle_response(), handle_response_invite(), register_verify(), and sip_hangup().

4465 {
4466  if (pvt->final_destruction_scheduled) {
4467  return;
4468  }
4469 
4470  dialog_ref(pvt, "Cancel destroy action");
4471  if (ast_sched_add(sched, 0, __sip_cancel_destroy, pvt) < 0) {
4472  /* Uh Oh. Expect bad behavior. */
4473  dialog_unref(pvt, "Failed to schedule cancel destroy action");
4474  ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n");
4475  }
4476 }
#define LOG_WARNING
Definition: logger.h:274
Definition: sched.c:76
#define ast_log
Definition: astobj2.c:42
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
unsigned short final_destruction_scheduled
Definition: sip.h:1081
#define dialog_ref(dialog, tag)
when we create or delete references, make sure to use these functions so we keep track of the refcoun...
Definition: dialog.h:32
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565
static int __sip_cancel_destroy(const void *data)
Definition: chan_sip.c:4453

◆ sip_cc_agent_destructor()

static void sip_cc_agent_destructor ( struct ast_cc_agent agent)
static

Definition at line 1997 of file chan_sip.c.

References ast_free, ast_test_flag, dialog_unref, sip_pvt::flags, sip_pvt::initreq, ast_cc_agent::private_data, sip_cc_agent_stop_offer_timer(), SIP_PAGE2_DIALOG_ESTABLISHED, sip_pvt_lock, sip_pvt_unlock, sip_cc_agent_pvt::subscribe_pvt, and transmit_response().

1998 {
1999  struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
2000 
2001  if (!agent_pvt) {
2002  /* The agent constructor probably failed. */
2003  return;
2004  }
2005 
2007  if (agent_pvt->subscribe_pvt) {
2008  sip_pvt_lock(agent_pvt->subscribe_pvt);
2010  /* If we haven't sent a 200 OK for the SUBSCRIBE dialog yet, then we need to send a response letting
2011  * the subscriber know something went wrong
2012  */
2013  transmit_response(agent_pvt->subscribe_pvt, "500 Internal Server Error", &agent_pvt->subscribe_pvt->initreq);
2014  }
2015  sip_pvt_unlock(agent_pvt->subscribe_pvt);
2016  agent_pvt->subscribe_pvt = dialog_unref(agent_pvt->subscribe_pvt, "SIP CC agent destructor: Remove ref to subscription");
2017  }
2018  ast_free(agent_pvt);
2019 }
void * private_data
Definition: ccss.h:871
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_flags flags[3]
Definition: sip.h:1075
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req)
Transmit response, no retransmits.
Definition: chan_sip.c:12655
struct sip_request initreq
Definition: sip.h:1151
Structure representing an agent.
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
static int sip_cc_agent_stop_offer_timer(struct ast_cc_agent *agent)
Definition: chan_sip.c:1925
#define ast_free(a)
Definition: astmm.h:182
struct sip_pvt * subscribe_pvt
Definition: sip.h:1796
#define SIP_PAGE2_DIALOG_ESTABLISHED
Definition: sip.h:358

◆ sip_cc_agent_init()

static int sip_cc_agent_init ( struct ast_cc_agent agent,
struct ast_channel chan 
)
static

Definition at line 1884 of file chan_sip.c.

References ast_assert, ast_calloc, ast_channel_tech(), ast_channel_tech_pvt(), ast_copy_string(), ast_set_flag, sip_pvt::callid, sip_pvt::exten, sip_pvt::flags, sip_cc_agent_pvt::offer_timer_id, sip_cc_agent_pvt::original_callid, sip_cc_agent_pvt::original_exten, ast_cc_agent::private_data, SIP_OFFER_CC, sip_pvt_lock, sip_pvt_unlock, and type.

1885 {
1886  struct sip_cc_agent_pvt *agent_pvt = ast_calloc(1, sizeof(*agent_pvt));
1887  struct sip_pvt *call_pvt = ast_channel_tech_pvt(chan);
1888 
1889  if (!agent_pvt) {
1890  return -1;
1891  }
1892 
1893  ast_assert(!strcmp(ast_channel_tech(chan)->type, "SIP"));
1894 
1895  ast_copy_string(agent_pvt->original_callid, call_pvt->callid, sizeof(agent_pvt->original_callid));
1896  ast_copy_string(agent_pvt->original_exten, call_pvt->exten, sizeof(agent_pvt->original_exten));
1897  agent_pvt->offer_timer_id = -1;
1898  agent->private_data = agent_pvt;
1899  sip_pvt_lock(call_pvt);
1900  ast_set_flag(&call_pvt->flags[0], SIP_OFFER_CC);
1901  sip_pvt_unlock(call_pvt);
1902  return 0;
1903 }
static const char type[]
Definition: chan_ooh323.c:109
char original_callid[SIPBUFSIZE]
Definition: sip.h:1784
void * private_data
Definition: ccss.h:871
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define ast_assert(a)
Definition: utils.h:695
struct ast_flags flags[3]
Definition: sip.h:1075
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
int offer_timer_id
Definition: sip.h:1779
const ast_string_field exten
Definition: sip.h:1063
const ast_string_field callid
Definition: sip.h:1063
Structure representing an agent.
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
char original_exten[SIPBUFSIZE]
Definition: sip.h:1791
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
#define SIP_OFFER_CC
Definition: sip.h:258

◆ sip_cc_agent_recall()

static int sip_cc_agent_recall ( struct ast_cc_agent agent)
static

Definition at line 1977 of file chan_sip.c.

References ast_cc_agent_caller_busy(), CC_READY, ast_cc_agent::core_id, ast_cc_agent::device_name, sip_cc_agent_pvt::is_available, ast_cc_agent::private_data, sip_pvt_lock, sip_pvt_unlock, sip_cc_agent_pvt::subscribe_pvt, and transmit_cc_notify().

1978 {
1979  struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
1980  /* If we have received a PUBLISH beforehand stating that the caller in question
1981  * is not available, we can save ourself a bit of effort here and just report
1982  * the caller as busy
1983  */
1984  if (!agent_pvt->is_available) {
1985  return ast_cc_agent_caller_busy(agent->core_id, "Caller %s is busy, reporting to the core",
1986  agent->device_name);
1987  }
1988  /* Otherwise, we transmit a NOTIFY to the caller and await either
1989  * a PUBLISH or an INVITE
1990  */
1991  sip_pvt_lock(agent_pvt->subscribe_pvt);
1992  transmit_cc_notify(agent, agent_pvt->subscribe_pvt, CC_READY);
1993  sip_pvt_unlock(agent_pvt->subscribe_pvt);
1994  return 0;
1995 }
Definition: sip.h:1556
void * private_data
Definition: ccss.h:871
char is_available
Definition: sip.h:1810
int ast_cc_agent_caller_busy(int core_id, const char *const debug,...)
Indicate that the caller is busy.
Definition: ccss.c:3809
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
Structure representing an agent.
unsigned int core_id
Definition: ccss.h:849
struct sip_pvt * subscribe_pvt
Definition: sip.h:1796
char device_name[1]
Definition: ccss.h:875
static int transmit_cc_notify(struct ast_cc_agent *agent, struct sip_pvt *subscription, enum sip_cc_notify_state state)
Definition: chan_sip.c:15446

◆ sip_cc_agent_respond()

static void sip_cc_agent_respond ( struct ast_cc_agent agent,
enum ast_cc_agent_response_reason  reason 
)
static

Definition at line 1933 of file chan_sip.c.

References AST_CC_AGENT_RESPONSE_SUCCESS, ast_set_flag, ast_strlen_zero, CC_QUEUED, sip_pvt::flags, sip_pvt::initreq, sip_cc_agent_pvt::is_available, sip_cc_agent_pvt::notify_uri, ast_cc_agent::private_data, SIP_PAGE2_DIALOG_ESTABLISHED, sip_pvt_lock, sip_pvt_unlock, sip_cc_agent_pvt::subscribe_pvt, transmit_cc_notify(), transmit_response(), and TRUE.

1934 {
1935  struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
1936 
1937  sip_pvt_lock(agent_pvt->subscribe_pvt);
1939  if (reason == AST_CC_AGENT_RESPONSE_SUCCESS || !ast_strlen_zero(agent_pvt->notify_uri)) {
1940  /* The second half of this if statement may be a bit hard to grasp,
1941  * so here's an explanation. When a subscription comes into
1942  * chan_sip, as long as it is not malformed, it will be passed
1943  * to the CC core. If the core senses an out-of-order state transition,
1944  * then the core will call this callback with the "reason" set to a
1945  * failure condition.
1946  * However, an out-of-order state transition will occur during a resubscription
1947  * for CC. In such a case, we can see that we have already generated a notify_uri
1948  * and so we can detect that this isn't a *real* failure. Rather, it is just
1949  * something the core doesn't recognize as a legitimate SIP state transition.
1950  * Thus we respond with happiness and flowers.
1951  */
1952  transmit_response(agent_pvt->subscribe_pvt, "200 OK", &agent_pvt->subscribe_pvt->initreq);
1953  transmit_cc_notify(agent, agent_pvt->subscribe_pvt, CC_QUEUED);
1954  } else {
1955  transmit_response(agent_pvt->subscribe_pvt, "500 Internal Error", &agent_pvt->subscribe_pvt->initreq);
1956  }
1957  sip_pvt_unlock(agent_pvt->subscribe_pvt);
1958  agent_pvt->is_available = TRUE;
1959 }
void * private_data
Definition: ccss.h:871
#define ast_set_flag(p, flag)
Definition: utils.h:70
char is_available
Definition: sip.h:1810
struct ast_flags flags[3]
Definition: sip.h:1075
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req)
Transmit response, no retransmits.
Definition: chan_sip.c:12655
struct sip_request initreq
Definition: sip.h:1151
Structure representing an agent.
char notify_uri[SIPBUFSIZE]
Definition: sip.h:1802
struct sip_pvt * subscribe_pvt
Definition: sip.h:1796
static int transmit_cc_notify(struct ast_cc_agent *agent, struct sip_pvt *subscription, enum sip_cc_notify_state state)
Definition: chan_sip.c:15446
#define TRUE
Definition: app_minivm.c:518
#define SIP_PAGE2_DIALOG_ESTABLISHED
Definition: sip.h:358

◆ sip_cc_agent_start_monitoring()

static int sip_cc_agent_start_monitoring ( struct ast_cc_agent agent)
static

Definition at line 1968 of file chan_sip.c.

1969 {
1970  /* To start monitoring just means to wait for an incoming PUBLISH
1971  * to tell us that the caller has become available again. No special
1972  * action is needed
1973  */
1974  return 0;
1975 }

◆ sip_cc_agent_start_offer_timer()

static int sip_cc_agent_start_offer_timer ( struct ast_cc_agent agent)
static

Definition at line 1915 of file chan_sip.c.

References ast_get_cc_offer_timer(), ast_sched_add(), ast_cc_agent::cc_params, sip_cc_agent_pvt::offer_timer_id, ast_cc_agent::private_data, and sip_offer_timer_expire().

1916 {
1917  struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
1918  int when;
1919 
1920  when = ast_get_cc_offer_timer(agent->cc_params) * 1000;
1921  agent_pvt->offer_timer_id = ast_sched_add(sched, when, sip_offer_timer_expire, agent);
1922  return 0;
1923 }
void * private_data
Definition: ccss.h:871
struct ast_cc_config_params * cc_params
Definition: ccss.h:859
Definition: sched.c:76
static int sip_offer_timer_expire(const void *data)
Definition: chan_sip.c:1905
int offer_timer_id
Definition: sip.h:1779
Structure representing an agent.
unsigned int ast_get_cc_offer_timer(struct ast_cc_config_params *config)
Get the cc_offer_timer.
Definition: ccss.c:900
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565

◆ sip_cc_agent_status_request()

static int sip_cc_agent_status_request ( struct ast_cc_agent agent)
static

Definition at line 1961 of file chan_sip.c.

References ast_cc_agent_status_response(), AST_DEVICE_INUSE, AST_DEVICE_NOT_INUSE, ast_cc_agent::core_id, sip_cc_agent_pvt::is_available, and ast_cc_agent::private_data.

1962 {
1963  struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
1965  return ast_cc_agent_status_response(agent->core_id, state);
1966 }
ast_device_state
Device States.
Definition: devicestate.h:52
void * private_data
Definition: ccss.h:871
char is_available
Definition: sip.h:1810
int ast_cc_agent_status_response(int core_id, enum ast_device_state devstate)
Response with a caller&#39;s current status.
Definition: ccss.c:4093
Structure representing an agent.
unsigned int core_id
Definition: ccss.h:849

◆ sip_cc_agent_stop_offer_timer()

static int sip_cc_agent_stop_offer_timer ( struct ast_cc_agent agent)
static

Definition at line 1925 of file chan_sip.c.

References AST_SCHED_DEL, sip_cc_agent_pvt::offer_timer_id, and ast_cc_agent::private_data.

Referenced by sip_cc_agent_destructor().

1926 {
1927  struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
1928 
1929  AST_SCHED_DEL(sched, agent_pvt->offer_timer_id);
1930  return 0;
1931 }
void * private_data
Definition: ccss.h:871
Definition: sched.c:76
int offer_timer_id
Definition: sip.h:1779
#define AST_SCHED_DEL(sched, id)
Remove a scheduler entry.
Definition: sched.h:46
Structure representing an agent.

◆ sip_cc_monitor_cancel_available_timer()

static int sip_cc_monitor_cancel_available_timer ( struct ast_cc_monitor monitor,
int *  sched_id 
)
static

Definition at line 2235 of file chan_sip.c.

References ao2_t_ref, and AST_SCHED_DEL.

Referenced by find_sip_monitor_instance_by_suspension_entry().

2236 {
2237  if (*sched_id != -1) {
2239  ao2_t_ref(monitor, -1, "Removing scheduler's reference to the monitor");
2240  }
2241  return 0;
2242 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
Definition: sched.c:76
Scheduler ID holder.
Definition: sched.c:70
#define AST_SCHED_DEL(sched, id)
Remove a scheduler entry.
Definition: sched.h:46

◆ sip_cc_monitor_destructor()

static void sip_cc_monitor_destructor ( void *  private_data)
static

Definition at line 2244 of file chan_sip.c.

References ao2_unlink, ast_module_unref, and ast_module_info::self.

Referenced by find_sip_monitor_instance_by_suspension_entry().

2245 {
2246  struct sip_monitor_instance *monitor_instance = private_data;
2247  ao2_unlink(sip_monitor_instances, monitor_instance);
2249 }
struct ao2_container * sip_monitor_instances
Definition: chan_sip.c:1164
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:469
struct ast_module * self
Definition: module.h:342
#define ao2_unlink(container, obj)
Definition: astobj2.h:1598

◆ sip_cc_monitor_request_cc()

static int sip_cc_monitor_request_cc ( struct ast_cc_monitor monitor,
int *  available_timer_id 
)
static

Definition at line 2102 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(), CALL_COMPLETION, ast_cc_interface::config_params, create_addr(), sip_pvt::expiry, FALSE, sip_pvt::flags, ast_cc_monitor::interface, NULL, sip_pvt::ourip, sip_monitor_instance::peername, ast_cc_monitor::private_data, sip_pvt::sa, service, ast_cc_monitor::service_offered, sip_alloc, SIP_OUTGOING, sip_pvt_lock, sip_pvt_unlock, SIP_SUBSCRIBE, sip_monitor_instance::subscribe_uri, sip_pvt::subscribed, sip_monitor_instance::subscription_pvt, and transmit_invite().

Referenced by find_sip_monitor_instance_by_suspension_entry().

2103 {
2104  struct sip_monitor_instance *monitor_instance = monitor->private_data;
2106  int when;
2107 
2108  if (!monitor_instance) {
2109  return -1;
2110  }
2111 
2112  if (!(monitor_instance->subscription_pvt = sip_alloc(NULL, NULL, 0, SIP_SUBSCRIBE, NULL, 0))) {
2113  return -1;
2114  }
2115 
2116  when = service == AST_CC_CCBS ? ast_get_ccbs_available_timer(monitor->interface->config_params) :
2117  ast_get_ccnr_available_timer(monitor->interface->config_params);
2118 
2119  sip_pvt_lock(monitor_instance->subscription_pvt);
2120  ast_set_flag(&monitor_instance->subscription_pvt->flags[0], SIP_OUTGOING);
2121  create_addr(monitor_instance->subscription_pvt, monitor_instance->peername, 0, 1);
2122  ast_sip_ouraddrfor(&monitor_instance->subscription_pvt->sa, &monitor_instance->subscription_pvt->ourip, monitor_instance->subscription_pvt);
2123  monitor_instance->subscription_pvt->subscribed = CALL_COMPLETION;
2124  monitor_instance->subscription_pvt->expiry = when;
2125 
2126  transmit_invite(monitor_instance->subscription_pvt, SIP_SUBSCRIBE, FALSE, 2, monitor_instance->subscribe_uri);
2127  sip_pvt_unlock(monitor_instance->subscription_pvt);
2128 
2129  ao2_t_ref(monitor, +1, "Adding a ref to the monitor for the scheduler");
2130  *available_timer_id = ast_sched_add(sched, when * 1000, ast_cc_available_timer_expire, monitor);
2131  return 0;
2132 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
enum subscriptiontype subscribed
Definition: sip.h:1161
#define FALSE
Definition: app_minivm.c:521
#define ast_set_flag(p, flag)
Definition: utils.h:70
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.
Definition: chan_sip.c:14755
const ast_string_field peername
Definition: sip.h:1819
enum ast_cc_service_type service
Definition: chan_sip.c:949
Definition: sched.c:76
int ast_cc_available_timer_expire(const void *data)
Scheduler callback for available timer expiration.
Definition: ccss.c:1509
struct ast_sockaddr ourip
Definition: sip.h:1136
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?
Definition: chan_sip.c:3866
struct ast_flags flags[3]
Definition: sip.h:1075
#define NULL
Definition: resample.c:96
ast_cc_service_type
Definition: ccss.h:32
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
unsigned int ast_get_ccbs_available_timer(struct ast_cc_config_params *config)
Get the ccbs_available_timer.
Definition: ccss.c:945
struct ast_sockaddr sa
Definition: sip.h:1125
const ast_string_field subscribe_uri
Definition: sip.h:1819
unsigned int ast_get_ccnr_available_timer(struct ast_cc_config_params *config)
Get the ccnr_available_timer.
Definition: ccss.c:915
#define sip_alloc(callid, addr, useglobal_nat, intended_method, req, logger_callid)
Definition: dialog.h:39
int expiry
Definition: sip.h:1118
struct ast_cc_config_params * config_params
Definition: ccss.h:834
struct ast_cc_interface * interface
Definition: ccss.h:514
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565
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 TR...
Definition: chan_sip.c:6317
struct sip_pvt * subscription_pvt
Definition: sip.h:1821
void * private_data
Data that is private to a monitor technology.
Definition: ccss.h:561
#define SIP_OUTGOING
Definition: sip.h:257
enum ast_cc_service_type service_offered
Definition: ccss.h:532

◆ sip_cc_monitor_suspend()

static int sip_cc_monitor_suspend ( struct ast_cc_monitor monitor)
static

Definition at line 2160 of file chan_sip.c.

References ao2_ref, ast_calloc, ast_log, ast_strlen_zero, sip_epa_entry::body, CC_CLOSED, construct_pidf_body(), ast_cc_monitor::core_id, cc_epa_entry::core_id, create_epa_entry(), cc_epa_entry::current_state, sip_epa_entry::instance_data, LOG_WARNING, sip_monitor_instance::notify_uri, sip_monitor_instance::peername, ast_cc_monitor::private_data, SIP_PUBLISH_INITIAL, SIP_PUBLISH_MODIFY, sip_monitor_instance::suspension_entry, and transmit_publish().

Referenced by find_sip_monitor_instance_by_suspension_entry().

2161 {
2162  struct sip_monitor_instance *monitor_instance = monitor->private_data;
2163  enum sip_publish_type publish_type;
2164  struct cc_epa_entry *cc_entry;
2165 
2166  if (!monitor_instance) {
2167  return -1;
2168  }
2169 
2170  if (!monitor_instance->suspension_entry) {
2171  /* We haven't yet allocated the suspension entry, so let's give it a shot */
2172  if (!(monitor_instance->suspension_entry = create_epa_entry("call-completion", monitor_instance->peername))) {
2173  ast_log(LOG_WARNING, "Unable to allocate sip EPA entry for call-completion\n");
2174  ao2_ref(monitor_instance, -1);
2175  return -1;
2176  }
2177  if (!(cc_entry = ast_calloc(1, sizeof(*cc_entry)))) {
2178  ast_log(LOG_WARNING, "Unable to allocate space for instance data of EPA entry for call-completion\n");
2179  ao2_ref(monitor_instance, -1);
2180  return -1;
2181  }
2182  cc_entry->core_id = monitor->core_id;
2183  monitor_instance->suspension_entry->instance_data = cc_entry;
2184  publish_type = SIP_PUBLISH_INITIAL;
2185  } else {
2186  publish_type = SIP_PUBLISH_MODIFY;
2187  cc_entry = monitor_instance->suspension_entry->instance_data;
2188  }
2189 
2190  cc_entry->current_state = CC_CLOSED;
2191 
2192  if (ast_strlen_zero(monitor_instance->notify_uri)) {
2193  /* If we have no set notify_uri, then what this means is that we have
2194  * not received a NOTIFY from this destination stating that he is
2195  * currently available.
2196  *
2197  * This situation can arise when the core calls the suspend callbacks
2198  * of multiple destinations. If one of the other destinations aside
2199  * from this one notified Asterisk that he is available, then there
2200  * is no reason to take any suspension action on this device. Rather,
2201  * we should return now and if we receive a NOTIFY while monitoring
2202  * is still "suspended" then we can immediately respond with the
2203  * proper PUBLISH to let this endpoint know what is going on.
2204  */
2205  return 0;
2206  }
2207  construct_pidf_body(CC_CLOSED, monitor_instance->suspension_entry->body, sizeof(monitor_instance->suspension_entry->body), monitor_instance->peername);
2208  return transmit_publish(monitor_instance->suspension_entry, publish_type, monitor_instance->notify_uri);
2209 }
static int construct_pidf_body(enum sip_cc_publish_state state, char *pidf_body, size_t size, const char *presentity)
Definition: chan_sip.c:2134
static int transmit_publish(struct sip_epa_entry *epa_entry, enum sip_publish_type publish_type, const char *const explicit_uri)
Definition: chan_sip.c:14711
#define LOG_WARNING
Definition: logger.h:274
const ast_string_field peername
Definition: sip.h:1819
const ast_string_field notify_uri
Definition: sip.h:1819
#define ast_strlen_zero(foo)
Definition: strings.h:52
enum sip_cc_publish_state current_state
Definition: sip.h:1704
void * instance_data
Definition: sip.h:1680
#define ast_log
Definition: astobj2.c:42
int core_id
Definition: ccss.h:528
#define ao2_ref(o, delta)
Definition: astobj2.h:464
int core_id
Definition: sip.h:1694
Modify.
Definition: sip.h:1599
static struct sip_epa_entry * create_epa_entry(const char *const event_package, const char *const destination)
Definition: chan_sip.c:1692
struct sip_epa_entry * suspension_entry
Definition: sip.h:1822
Instance data for a Call completion EPA entry.
Definition: sip.h:1686
char body[SIPBUFSIZE]
Definition: sip.h:1668
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
sip_publish_type
The types of PUBLISH messages defined in RFC 3903.
Definition: sip.h:1562
void * private_data
Data that is private to a monitor technology.
Definition: ccss.h:561
Initial.
Definition: sip.h:1581

◆ sip_cc_monitor_unsuspend()

static int sip_cc_monitor_unsuspend ( struct ast_cc_monitor monitor)
static

Definition at line 2211 of file chan_sip.c.

References ast_assert, ast_strlen_zero, sip_epa_entry::body, CC_OPEN, construct_pidf_body(), cc_epa_entry::current_state, sip_epa_entry::instance_data, sip_monitor_instance::notify_uri, NULL, sip_monitor_instance::peername, ast_cc_monitor::private_data, SIP_PUBLISH_MODIFY, sip_monitor_instance::suspension_entry, and transmit_publish().

Referenced by find_sip_monitor_instance_by_suspension_entry().

2212 {
2213  struct sip_monitor_instance *monitor_instance = monitor->private_data;
2214  struct cc_epa_entry *cc_entry;
2215 
2216  if (!monitor_instance) {
2217  return -1;
2218  }
2219 
2220  ast_assert(monitor_instance->suspension_entry != NULL);
2221 
2222  cc_entry = monitor_instance->suspension_entry->instance_data;
2223  cc_entry->current_state = CC_OPEN;
2224  if (ast_strlen_zero(monitor_instance->notify_uri)) {
2225  /* This means we are being asked to unsuspend a call leg we never
2226  * sent a PUBLISH on. As such, there is no reason to send another
2227  * PUBLISH at this point either. We can just return instead.
2228  */
2229  return 0;
2230  }
2231  construct_pidf_body(CC_OPEN, monitor_instance->suspension_entry->body, sizeof(monitor_instance->suspension_entry->body), monitor_instance->peername);
2232  return transmit_publish(monitor_instance->suspension_entry, SIP_PUBLISH_MODIFY, monitor_instance->notify_uri);
2233 }
static int construct_pidf_body(enum sip_cc_publish_state state, char *pidf_body, size_t size, const char *presentity)
Definition: chan_sip.c:2134
static int transmit_publish(struct sip_epa_entry *epa_entry, enum sip_publish_type publish_type, const char *const explicit_uri)
Definition: chan_sip.c:14711
const ast_string_field peername
Definition: sip.h:1819
const ast_string_field notify_uri
Definition: sip.h:1819
#define ast_assert(a)
Definition: utils.h:695
#define NULL
Definition: resample.c:96
Definition: sip.h:1546
#define ast_strlen_zero(foo)
Definition: strings.h:52
enum sip_cc_publish_state current_state
Definition: sip.h:1704
void * instance_data
Definition: sip.h:1680
Modify.
Definition: sip.h:1599
struct sip_epa_entry * suspension_entry
Definition: sip.h:1822
Instance data for a Call completion EPA entry.
Definition: sip.h:1686
char body[SIPBUFSIZE]
Definition: sip.h:1668
void * private_data
Data that is private to a monitor technology.
Definition: ccss.h:561

◆ sip_check_authtimeout()

static int sip_check_authtimeout ( time_t  start)
static

Check if the authtimeout has expired.

Parameters
startthe time when the session started
Return values
0the timeout has expired
-1error
Returns
the number of milliseconds until the timeout will expire

Definition at line 2740 of file chan_sip.c.

References ast_log, authtimeout, errno, LOG_ERROR, and timeout.

Referenced by _sip_tcp_helper_thread(), and sip_tcptls_read().

2741 {
2742  int timeout;
2743  time_t now;
2744  if(time(&now) == -1) {
2745  ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
2746  return -1;
2747  }
2748 
2749  timeout = (authtimeout - (now - start)) * 1000;
2750  if (timeout < 0) {
2751  /* we have timed out */
2752  return 0;
2753  }
2754 
2755  return timeout;
2756 }
static int timeout
Definition: cdr_mysql.c:86
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
int errno
static int authtimeout
Definition: chan_sip.c:676

◆ sip_cli_notify()

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 22894 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, buf, build_via(), change_callid_pvt(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sip_notify(), sip_notify::content, create_addr(), dialog_unlink_all(), dialog_unref, ast_cli_args::fd, sip_pvt::flags, sip_notify::headers, ast_cli_args::line, LOG_WARNING, ast_cli_args::n, ast_variable::name, ast_variable::next, sip_pvt::notify, notify_config, NULL, sip_pvt::ourip, ast_cli_args::pos, sip_pvt::sa, sip_alloc, SIP_NOTIFY, sip_notify_alloc(), SIP_OUTGOING, sip_scheddestroy(), SIP_TRANS_TIMEOUT, transmit_invite(), ast_cli_entry::usage, ast_variable::value, var, and ast_cli_args::word.

22895 {
22896  struct ast_variable *varlist;
22897  int i;
22898 
22899  switch (cmd) {
22900  case CLI_INIT:
22901  e->command = "sip notify";
22902  e->usage =
22903  "Usage: sip notify <type> <peer> [<peer>...]\n"
22904  " Send a NOTIFY message to a SIP peer or peers\n"
22905  " Message types are defined in sip_notify.conf\n";
22906  return NULL;
22907  case CLI_GENERATE:
22908  return complete_sip_notify(a->line, a->word, a->pos, a->n);
22909  }
22910 
22911  if (a->argc < 4)
22912  return CLI_SHOWUSAGE;
22913 
22914  if (!notify_types) {
22915  ast_cli(a->fd, "No %s file found, or no types listed there\n", notify_config);
22916  return CLI_FAILURE;
22917  }
22918 
22919  varlist = ast_variable_browse(notify_types, a->argv[2]);
22920 
22921  if (!varlist) {
22922  ast_cli(a->fd, "Unable to find notify type '%s'\n", a->argv[2]);
22923  return CLI_FAILURE;
22924  }
22925 
22926  for (i = 3; i < a->argc; i++) {
22927  struct sip_pvt *p;
22928  char buf[512];
22929  struct ast_variable *header, *var;
22930 
22931  if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL, 0))) {
22932  ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n");
22933  return CLI_FAILURE;
22934  }
22935 
22936  if (create_addr(p, a->argv[i], NULL, 1)) {
22937  /* Maybe they're not registered, etc. */
22938  dialog_unlink_all(p);
22939  dialog_unref(p, "unref dialog inside for loop" );
22940  /* sip_destroy(p); */
22941  ast_cli(a->fd, "Could not create address for '%s'\n", a->argv[i]);
22942  continue;
22943  }
22944 
22945  /* Notify is outgoing call */
22946  ast_set_flag(&p->flags[0], SIP_OUTGOING);
22947  sip_notify_alloc(p);
22948  p->notify->headers = header = ast_variable_new("Subscription-State", "terminated", "");
22949 
22950  for (var = varlist; var; var = var->next) {
22951  ast_copy_string(buf, var->value, sizeof(buf));
22953 
22954  if (!strcasecmp(var->name, "Content")) {
22955  if (ast_str_strlen(p->notify->content))
22956  ast_str_append(&p->notify->content, 0, "\r\n");
22957  ast_str_append(&p->notify->content, 0, "%s", buf);
22958  } else if (!strcasecmp(var->name, "Content-Length")) {
22959  ast_log(LOG_WARNING, "it is not necessary to specify Content-Length in sip_notify.conf, ignoring\n");
22960  } else {
22961  header->next = ast_variable_new(var->name, buf, "");
22962  header = header->next;
22963  }
22964  }
22965 
22966  /* Now that we have the peer's address, set our ip and change callid */
22967  ast_sip_ouraddrfor(&p->sa, &p->ourip, p);
22968  build_via(p);
22969 
22970  change_callid_pvt(p, NULL);
22971 
22972  ast_cli(a->fd, "Sending NOTIFY of type '%s' to '%s'\n", a->argv[2], a->argv[i]);
22974  transmit_invite(p, SIP_NOTIFY, 0, 2, NULL);
22975  dialog_unref(p, "bump down the count of p since we're done with it.");
22976  }
22977 
22978  return CLI_SUCCESS;
22979 }
struct ast_variable * next
static void build_via(struct sip_pvt *p)
Build a Via header for a request.
Definition: chan_sip.c:3847
struct ast_str * content
Definition: sip.h:953
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1216
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define ast_set_flag(p, flag)
Definition: utils.h:70
const int argc
Definition: cli.h:160
#define LOG_WARNING
Definition: logger.h:274
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.
Definition: chan_sip.c:14755
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
Definition: cli.h:152
static struct ast_config * notify_types
Definition: chan_sip.c:1153
struct ast_sockaddr ourip
Definition: sip.h:1136
static const char notify_config[]
Definition: chan_sip.c:691
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
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?
Definition: chan_sip.c:3866
struct ast_flags flags[3]
Definition: sip.h:1075
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const char * line
Definition: cli.h:162
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 stor...
Definition: chan_sip.c:3367
struct ast_sockaddr sa
Definition: sip.h:1125
#define ast_log
Definition: astobj2.c:42
const int fd
Definition: cli.h:159
const int n
Definition: cli.h:165
static int sip_notify_alloc(struct sip_pvt *p)
Allocate SIP refer structure.
Definition: chan_sip.c:16388
#define sip_alloc(callid, addr, useglobal_nat, intended_method, req, logger_callid)
Definition: dialog.h:39
#define ast_variable_new(name, value, filename)
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
static void change_callid_pvt(struct sip_pvt *pvt, const char *callid)
Definition: chan_sip.c:8860
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
static char * complete_sip_notify(const char *line, const char *word, int pos, int state)
Support routine for &#39;sip notify&#39; CLI.
Definition: chan_sip.c:22359
#define CLI_FAILURE
Definition: cli.h:46
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
char * ast_unescape_semicolon(char *s)
Strip backslash for "escaped" semicolons, the string to be stripped (will be modified).
Definition: main/utils.c:1716
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
struct ast_variable * headers
Definition: sip.h:952
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
#define SIP_TRANS_TIMEOUT
Definition: sip.h:102
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
const int pos
Definition: cli.h:164
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 TR...
Definition: chan_sip.c:6317
#define SIP_OUTGOING
Definition: sip.h:257
void sip_scheddestroy(struct sip_pvt *p, int ms)
Schedule destruction of SIP dialog.
Definition: chan_sip.c:4549
struct sip_notify * notify
Definition: sip.h:1140

◆ sip_debug_test_addr()

static int sip_debug_test_addr ( const struct ast_sockaddr addr)
inlinestatic

See if we pass debug IP filter.

Definition at line 3610 of file chan_sip.c.

References ast_sockaddr_cmp(), ast_sockaddr_cmp_addr(), ast_sockaddr_isnull(), ast_sockaddr_port, debugaddr, and sipdebug.

Referenced by check_peer_ok(), handle_request_do(), and sip_debug_test_pvt().

3611 {
3612  /* Can't debug if sipdebug is not enabled */
3613  if (!sipdebug) {
3614  return 0;
3615  }
3616 
3617  /* A null debug_addr means we'll debug any address */
3619  return 1;
3620  }
3621 
3622  /* If no port was specified for a debug address, just compare the
3623  * addresses, otherwise compare the address and port
3624  */
3625  if (ast_sockaddr_port(&debugaddr)) {
3626  return !ast_sockaddr_cmp(&debugaddr, addr);
3627  } else {
3628  return !ast_sockaddr_cmp_addr(&debugaddr, addr);
3629  }
3630 }
static struct ast_sockaddr debugaddr
Definition: chan_sip.c:1151
int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares two ast_sockaddr structures.
Definition: netsock2.c:388
int ast_sockaddr_cmp_addr(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares the addresses of two ast_sockaddr structures.
Definition: netsock2.c:413
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:521
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916

◆ sip_debug_test_pvt()

static int sip_debug_test_pvt ( struct sip_pvt p)
inlinestatic

Test PVT for debugging output.

Definition at line 3649 of file chan_sip.c.

References sip_debug_test_addr(), sip_real_dst(), and sipdebug.

Referenced by add_sdp(), build_path(), build_route(), check_via(), do_register_auth(), get_also_info(), get_destination(), get_rdnis(), get_refer_info(), process_sdp(), process_sdp_a_audio(), process_sdp_a_text(), process_sdp_a_video(), process_sdp_o(), receive_message(), retrans_pkt(), send_request(), send_response(), set_destination(), sip_pvt_dtor(), sip_scheddestroy_full(), sip_sendhtml(), sip_sendtext(), and transmit_register().

3650 {
3651  if (!sipdebug) {
3652  return 0;
3653  }
3654  return sip_debug_test_addr(sip_real_dst(p));
3655 }
static int sip_debug_test_addr(const struct ast_sockaddr *addr)
See if we pass debug IP filter.
Definition: chan_sip.c:3610
static const struct ast_sockaddr * sip_real_dst(const struct sip_pvt *p)
The real destination address for a write.
Definition: chan_sip.c:3633
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916

◆ sip_destroy_peer()

static void sip_destroy_peer ( struct sip_peer peer)
static

Destroy peer object from memory.

Definition at line 5309 of file chan_sip.c.

References sip_peer::acl, ao2_cleanup, ao2_ref, ao2_t_ref, apeerobjs, ast_atomic_fetchadd_int(), ast_cc_config_params_destroy(), ast_debug, ast_endpoint_shutdown(), ast_free_acl_list(), ast_rtp_dtls_cfg_free(), ast_string_field_free_memory, ast_test_flag, ast_unref_namedgroups(), ast_variables_destroy(), ast_websocket_unref(), sip_peer::auth, sip_peer::call, sip_peer::caps, sip_peer::cc_params, sip_peer::chanvars, clear_peer_mailboxes(), sip_peer::contactacl, dialog_unlink_all(), dialog_unref, sip_peer::directmediaacl, sip_peer::dtls_cfg, sip_peer::endpoint, FALSE, sip_peer::is_realtime, sip_peer::mwipvt, sip_peer::name, sip_peer::named_callgroups, sip_peer::named_pickupgroups, NULL, sip_peer::outboundproxy, sip_peer::path, register_peer_exten(), rpeerobjs, sip_peer::selfdestruct, SIP_PAGE2_RTCACHEFRIENDS, sip_route_clear(), sip_peer::socket, speerobjs, sip_socket::tcptls_session, and sip_socket::ws_session.

Referenced by sip_destroy_peer_fn().

5310 {
5311  ast_debug(3, "Destroying SIP peer %s\n", peer->name);
5312 
5313  /*
5314  * Remove any mailbox event subscriptions for this peer before
5315  * we destroy anything. An event subscription callback may be
5316  * happening right now.
5317  */
5318  clear_peer_mailboxes(peer);
5319 
5320  if (peer->outboundproxy) {
5321  ao2_ref(peer->outboundproxy, -1);
5322  peer->outboundproxy = NULL;
5323  }
5324 
5325  /* Delete it, it needs to disappear */
5326  if (peer->call) {
5327  dialog_unlink_all(peer->call);
5328  peer->call = dialog_unref(peer->call, "peer->call is being unset");
5329  }
5330 
5331  if (peer->mwipvt) { /* We have an active subscription, delete it */
5332  dialog_unlink_all(peer->mwipvt);
5333  peer->mwipvt = dialog_unref(peer->mwipvt, "unreffing peer->mwipvt");
5334  }
5335 
5336  if (peer->chanvars) {
5338  peer->chanvars = NULL;
5339  }
5340  sip_route_clear(&peer->path);
5341 
5342  register_peer_exten(peer, FALSE);
5343  ast_free_acl_list(peer->acl);
5346  if (peer->selfdestruct)
5350  ast_debug(3, "-REALTIME- peer Destroyed. Name: %s. Realtime Peer objects: %d\n", peer->name, rpeerobjs);
5351  } else
5353  if (peer->auth) {
5354  ao2_t_ref(peer->auth, -1, "Removing peer authentication");
5355  peer->auth = NULL;
5356  }
5357 
5358  if (peer->socket.tcptls_session) {
5359  ao2_ref(peer->socket.tcptls_session, -1);
5360  peer->socket.tcptls_session = NULL;
5361  } else if (peer->socket.ws_session) {
5363  peer->socket.ws_session = NULL;
5364  }
5365 
5368 
5370 
5372 
5373  ao2_cleanup(peer->caps);
5374 
5376 
5378  peer->endpoint = NULL;
5379 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
static int speerobjs
Definition: chan_sip.c:879
struct ast_namedgroups * named_pickupgroups
Definition: sip.h:1349
#define FALSE
Definition: app_minivm.c:521
void ast_cc_config_params_destroy(struct ast_cc_config_params *params)
Free memory from CCSS configuration params.
Definition: ccss.c:693
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
struct ast_rtp_dtls_cfg dtls_cfg
Definition: sip.h:1381
#define ast_test_flag(p, flag)
Definition: utils.h:63
static int rpeerobjs
Definition: chan_sip.c:880
struct sip_route path
Definition: sip.h:1372
#define NULL
Definition: resample.c:96
void sip_route_clear(struct sip_route *route)
Free all routes in the list.
Definition: route.c:132
struct sip_proxy * outboundproxy
Definition: sip.h:1350
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:755
char name[80]
Definition: sip.h:1274
struct ast_variable * chanvars
Definition: sip.h:1366
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 stor...
Definition: chan_sip.c:3367
struct ast_websocket * ws_session
Definition: sip.h:802
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct ast_namedgroups * named_callgroups
Definition: sip.h:1348
struct ast_acl_list * acl
Definition: sip.h:1363
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_tcptls_session_instance * tcptls_session
Definition: sip.h:801
struct ast_acl_list * directmediaacl
Definition: sip.h:1365
struct ast_cc_config_params * cc_params
Definition: sip.h:1377
struct ast_format_cap * caps
Definition: sip.h:1342
struct ast_endpoint * endpoint
Definition: sip.h:1379
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
struct ast_acl_list * ast_free_acl_list(struct ast_acl_list *acl)
Free a list of ACLs.
Definition: acl.c:233
static struct ast_flags global_flags[3]
Definition: chan_sip.c:884
static void register_peer_exten(struct sip_peer *peer, int onoff)
Automatically add peer extension to dial plan.
Definition: chan_sip.c:5238
#define SIP_PAGE2_RTCACHEFRIENDS
Definition: sip.h:323
static int apeerobjs
Definition: chan_sip.c:881
unsigned short is_realtime
Definition: sip.h:1312
unsigned short selfdestruct
Definition: sip.h:1315
struct ast_acl_list * contactacl
Definition: sip.h:1364
struct sip_pvt * call
Definition: sip.h:1354
struct sip_auth_container * auth
Definition: sip.h:1322
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct sip_pvt * mwipvt
Definition: sip.h:1367
void ast_rtp_dtls_cfg_free(struct ast_rtp_dtls_cfg *dtls_cfg)
Free contents of a DTLS configuration structure.
Definition: rtp_engine.c:3131
static void clear_peer_mailboxes(struct sip_peer *peer)
Definition: chan_sip.c:5293
struct ast_namedgroups * ast_unref_namedgroups(struct ast_namedgroups *groups)
Definition: channel.c:7832
void AST_OPTIONAL_API_NAME() ast_websocket_unref(struct ast_websocket *session)
void ast_endpoint_shutdown(struct ast_endpoint *endpoint)
Shutsdown an ast_endpoint.
struct sip_socket socket
Definition: sip.h:1307
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:368

◆ sip_destroy_peer_fn()

static void sip_destroy_peer_fn ( void *  peer)
static

Definition at line 5303 of file chan_sip.c.

References sip_destroy_peer().

Referenced by build_peer(), and temp_peer().

5304 {
5305  sip_destroy_peer(peer);
5306 }
static void sip_destroy_peer(struct sip_peer *peer)
Destroy peer object from memory.
Definition: chan_sip.c:5309

◆ sip_devicestate()

static int sip_devicestate ( const char *  data)
static

Part of PBX channel interface.

Note
Return values:—

If we have qualify on and the device is not reachable, regardless of registration state we return AST_DEVICE_UNAVAILABLE

For peers with call limit:

  • not registered AST_DEVICE_UNAVAILABLE
  • registered, no call AST_DEVICE_NOT_INUSE
  • registered, active calls AST_DEVICE_INUSE
  • registered, call limit reached AST_DEVICE_BUSY
  • registered, onhold AST_DEVICE_ONHOLD
  • registered, ringing AST_DEVICE_RINGING

For peers without call limit:

  • not registered AST_DEVICE_UNAVAILABLE
  • registered AST_DEVICE_NOT_INUSE
  • fixed IP (!dynamic) AST_DEVICE_NOT_INUSE

Peers that does not have a known call and can't be reached by OPTIONS

  • unreachable AST_DEVICE_UNAVAILABLE

If we return AST_DEVICE_UNKNOWN, the device state engine will try to find out a state by walking the channel list.

The queue system (app_queue.c) treats a member as "active" if devicestate is != AST_DEVICE_UNAVAILBALE && != AST_DEVICE_INVALID

When placing a call to the queue member, queue system sets a member to busy if != AST_DEVICE_NOT_INUSE and != AST_DEVICE_UNKNOWN

Definition at line 30710 of file chan_sip.c.

References sip_peer::addr, 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, sip_peer::busy_level, sip_peer::call_limit, sip_peer::defaddr, FALSE, FINDALLDEVICES, host, sip_peer::inuse, sip_peer::lastms, sip_peer::maxms, NULL, sip_peer::onhold, sip_peer::ringing, sip_find_peer(), sip_unref_peer, tmp(), and TRUE.

30711 {
30712  char *host;
30713  char *tmp;
30714  struct sip_peer *p;
30715 
30716  int res = AST_DEVICE_INVALID;
30717 
30718  /* make sure data is not null. Maybe unnecessary, but better be safe */
30719  host = ast_strdupa(data ? data : "");
30720  if ((tmp = strchr(host, '@')))
30721  host = tmp + 1;
30722 
30723  ast_debug(3, "Checking device state for peer %s\n", host);
30724 
30725  /* If sip_find_peer asks for a realtime peer, then this breaks rtautoclear. This
30726  * is because when a peer tries to autoexpire, the last thing it does is to
30727  * queue up an event telling the system that the devicestate has changed
30728  * (presumably to unavailable). If we ask for a realtime peer here, this would
30729  * load it BACK into memory, thus defeating the point of trying to clear dead
30730  * hosts out of memory.
30731  */
30732  if ((p = sip_find_peer(host, NULL, FALSE, FINDALLDEVICES, TRUE, 0))) {
30733  if (!(ast_sockaddr_isnull(&p->addr) && ast_sockaddr_isnull(&p->defaddr))) {
30734  /* we have an address for the peer */
30735 
30736  /* Check status in this order
30737  - Hold
30738  - Ringing
30739  - Busy (enforced only by call limit)
30740  - Inuse (we have a call)
30741  - Unreachable (qualify)
30742  If we don't find any of these state, report AST_DEVICE_NOT_INUSE
30743  for registered devices */
30744 
30745  if (p->onhold)
30746  /* First check for hold or ring states */
30747  res = AST_DEVICE_ONHOLD;
30748  else if (p->ringing) {
30749  if (p->ringing == p->inuse)
30750  res = AST_DEVICE_RINGING;
30751  else
30752  res = AST_DEVICE_RINGINUSE;
30753  } else if (p->call_limit && (p->inuse == p->call_limit))
30754  /* check call limit */
30755  res = AST_DEVICE_BUSY;
30756  else if (p->call_limit && p->busy_level && p->inuse >= p->busy_level)
30757  /* We're forcing busy before we've reached the call limit */
30758  res = AST_DEVICE_BUSY;
30759  else if (p->call_limit && p->inuse)
30760  /* Not busy, but we do have a call */
30761  res = AST_DEVICE_INUSE;
30762  else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0)))
30763  /* We don't have a call. Are we reachable at all? Requires qualify= */
30764  res = AST_DEVICE_UNAVAILABLE;
30765  else /* Default reply if we're registered and have no other data */
30766  res = AST_DEVICE_NOT_INUSE;
30767  } else {
30768  /* there is no address, it's unavailable */
30769  res = AST_DEVICE_UNAVAILABLE;
30770  }
30771  sip_unref_peer(p, "sip_unref_peer, from sip_devicestate, release ref from sip_find_peer");
30772  }
30773 
30774  return res;
30775 }
struct ast_sockaddr addr
Definition: sip.h:1352
int maxms
Definition: sip.h:1357
#define FALSE
Definition: app_minivm.c:521
struct sip_peer * sip_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.
Definition: chan_sip.c:5851
static int tmp()
Definition: bt_open.c:389
struct ast_sockaddr defaddr
Definition: sip.h:1362
#define NULL
Definition: resample.c:96
int ringing
Definition: sip.h:1326
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
int lastms
Definition: sip.h:1356
static char host[256]
Definition: muted.c:77
int call_limit
Definition: sip.h:1328
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
#define FINDALLDEVICES
Definition: sip.h:54
int onhold
Definition: sip.h:1327
#define TRUE
Definition: app_minivm.c:518
int inuse
Definition: sip.h:1325
int busy_level
Definition: sip.h:1330

◆ sip_digest_parser()

void sip_digest_parser ( char *  c,
struct digestkeys keys 
)

Takes the digest response and parses it.

Definition at line 17309 of file chan_sip.c.

References ast_skip_blanks(), c, digestkeys::key, NULL, digestkeys::s, and strsep().

Referenced by check_auth(), and sip_report_security_event().

17310 {
17311  struct digestkeys *i = i;
17312 
17313  while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */
17314  for (i = keys; i->key != NULL; i++) {
17315  const char *separator = ","; /* default */
17316 
17317  if (strncasecmp(c, i->key, strlen(i->key)) != 0) {
17318  continue;
17319  }
17320  /* Found. Skip keyword, take text in quotes or up to the separator. */
17321  c += strlen(i->key);
17322  if (*c == '"') { /* in quotes. Skip first and look for last */
17323  c++;
17324  separator = "\"";
17325  }
17326  i->s = c;
17327  strsep(&c, separator);
17328  break;
17329  }
17330  if (i->key == NULL) { /* not found, jump after space or comma */
17331  strsep(&c, " ,");
17332  }
17333  }
17334 }
const char * key
Definition: sip.h:1879
static struct test_val c
#define NULL
Definition: resample.c:96
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
const char * s
Definition: sip.h:1880
char * strsep(char **str, const char *delims)

◆ sip_do_debug()

static char * sip_do_debug ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Turn on SIP debugging (CLI command)

Note
this can be a special debug command - "sip debug text" or something

Definition at line 22846 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, NULL, ast_cli_args::pos, sip_debug_console, sip_debug_none, sip_do_debug_ip(), sip_do_debug_peer(), sipdebug, sipdebug_text, ast_cli_entry::usage, and ast_cli_args::word.

22847 {
22848  int oldsipdebug = sipdebug & sip_debug_console;
22849  const char *what;
22850 
22851  if (cmd == CLI_INIT) {
22852  e->command = "sip set debug {on|off|ip|peer}";
22853  e->usage =
22854  "Usage: sip set debug {off|on|ip addr[:port]|peer peername}\n"
22855  " Globally disables dumping of SIP packets,\n"
22856  " or enables it either globally or for a (single)\n"
22857  " IP address or registered peer.\n";
22858  return NULL;
22859  } else if (cmd == CLI_GENERATE) {
22860  if (a->pos == 4 && !strcasecmp(a->argv[3], "peer"))
22861  return complete_sip_peer(a->word, a->n, 0);
22862  return NULL;
22863  }
22864 
22865  what = a->argv[e->args-1]; /* guaranteed to exist */
22866  if (a->argc == e->args) { /* on/off */
22867  if (!strcasecmp(what, "on")) {
22869  sipdebug_text = 1; /*! \note this can be a special debug command - "sip debug text" or something */
22870  memset(&debugaddr, 0, sizeof(debugaddr));
22871  ast_cli(a->fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : "");
22872  return CLI_SUCCESS;
22873  } else if (!strcasecmp(what, "off")) {
22874  sipdebug &= ~sip_debug_console;
22875  sipdebug_text = 0;
22876  if (sipdebug == sip_debug_none) {
22877  ast_cli(a->fd, "SIP Debugging Disabled\n");
22878  } else {
22879  ast_cli(a->fd, "SIP Debugging still enabled due to configuration.\n");
22880  ast_cli(a->fd, "Set sipdebug=no in sip.conf and reload to actually disable.\n");
22881  }
22882  return CLI_SUCCESS;
22883  }
22884  } else if (a->argc == e->args + 1) { /* ip/peer */
22885  if (!strcasecmp(what, "ip"))
22886  return sip_do_debug_ip(a->fd, a->argv[e->args]);
22887  else if (!strcasecmp(what, "peer"))
22888  return sip_do_debug_peer(a->fd, a->argv[e->args]);
22889  }
22890  return CLI_SHOWUSAGE; /* default, failure */
22891 }
static char * sip_do_debug_peer(int fd, const char *arg)
Turn on SIP debugging for a given peer.
Definition: chan_sip.c:22827
static struct ast_sockaddr debugaddr
Definition: chan_sip.c:1151
const int argc
Definition: cli.h:160
static char * sip_do_debug_ip(int fd, const char *arg)
Enable SIP Debugging for a single IP.
Definition: chan_sip.c:22814
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
int args
This gets set in ast_cli_register()
Definition: cli.h:185
const int fd
Definition: cli.h:159
const int n
Definition: cli.h:165
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
static int sipdebug_text
extra debugging for &#39;text&#39; related events. At the moment this is set together with sip_debug_console...
Definition: chan_sip.c:922
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
const int pos
Definition: cli.h:164
static char * complete_sip_peer(const char *word, int state, int flags2)
Do completion on peer name.
Definition: chan_sip.c:22282

◆ sip_do_debug_ip()

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

Enable SIP Debugging for a single IP.

Definition at line 22814 of file chan_sip.c.

References ast_cli(), ast_sockaddr_resolve_first_af(), ast_sockaddr_stringify_addr(), CLI_SHOWUSAGE, CLI_SUCCESS, debugaddr, sip_debug_console, and sipdebug.

Referenced by sip_do_debug().

22815 {
22816  if (ast_sockaddr_resolve_first_af(&debugaddr, arg, 0, 0)) {
22817  return CLI_SHOWUSAGE;
22818  }
22819 
22820  ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_sockaddr_stringify_addr(&debugaddr));
22822 
22823  return CLI_SUCCESS;
22824 }
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:290
static struct ast_sockaddr debugaddr
Definition: chan_sip.c:1151
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
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.
Definition: netsock2.c:337
#define CLI_SHOWUSAGE
Definition: cli.h:45
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
#define CLI_SUCCESS
Definition: cli.h:44

◆ sip_do_debug_peer()

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

Turn on SIP debugging for a given peer.

Definition at line 22827 of file chan_sip.c.

References sip_peer::addr, ast_cli(), ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_stringify_addr(), CLI_SUCCESS, debugaddr, FALSE, FINDPEERS, NULL, sip_debug_console, sip_find_peer(), sip_unref_peer, sipdebug, and TRUE.

Referenced by sip_do_debug().

22828 {
22829  struct sip_peer *peer = sip_find_peer(arg, NULL, TRUE, FINDPEERS, FALSE, 0);
22830  if (!peer) {
22831  ast_cli(fd, "No such peer '%s'\n", arg);
22832  } else if (ast_sockaddr_isnull(&peer->addr)) {
22833  ast_cli(fd, "Unable to get IP address of peer '%s'\n", arg);
22834  } else {
22835  ast_sockaddr_copy(&debugaddr, &peer->addr);
22836  ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_sockaddr_stringify_addr(&debugaddr));
22838  }
22839  if (peer) {
22840  sip_unref_peer(peer, "sip_do_debug_peer: sip_unref_peer, from sip_find_peer call");
22841  }
22842  return CLI_SUCCESS;
22843 }
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:290
struct ast_sockaddr addr
Definition: sip.h:1352
#define FALSE
Definition: app_minivm.c:521
struct sip_peer * sip_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.
Definition: chan_sip.c:5851
static struct ast_sockaddr debugaddr
Definition: chan_sip.c:1151
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:171
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
#define FINDPEERS
Definition: sip.h:53
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
#define CLI_SUCCESS
Definition: cli.h:44
#define TRUE
Definition: app_minivm.c:518

◆ sip_do_reload()

static int sip_do_reload ( enum channelreloadreason  reason)
static

Reload module.

Definition at line 34384 of file chan_sip.c.

References ast_debug, ast_sched_dump(), reload_config(), sip_keepalive_all_peers(), sip_poke_all_peers(), sip_send_all_mwi_subscriptions(), sip_send_all_registers(), and unlink_marked_peers_from_tables().

Referenced by do_monitor().

34385 {
34386  time_t start_poke, end_poke;
34387 
34388  reload_config(reason);
34390 
34391  start_poke = time(0);
34392  /* Prune peers who still are supposed to be deleted */
34394 
34395  ast_debug(4, "--------------- Done destroying pruned peers\n");
34396 
34397  /* Send qualify (OPTIONS) to all peers */
34399 
34400  /* Send keepalive to all peers */
34402 
34403  /* Register with all services */
34405 
34407 
34408  end_poke = time(0);
34409 
34410  ast_debug(4, "do_reload finished. peer poke/prune reg contact time = %d sec.\n", (int)(end_poke-start_poke));
34411 
34412  ast_debug(4, "--------------- SIP reload done\n");
34413 
34414  return 0;
34415 }
Definition: sched.c:76
static int reload_config(enum channelreloadreason reason)
Re-read SIP.conf config file.
Definition: chan_sip.c:32514
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static void sip_send_all_mwi_subscriptions(void)
Send all MWI subscriptions.
Definition: chan_sip.c:34326
static void sip_poke_all_peers(void)
Send a poke to all known peers.
Definition: chan_sip.c:34242
void ast_sched_dump(struct ast_sched_context *con)
Dumps the scheduler contents.
Definition: sched.c:712
static void sip_send_all_registers(void)
Send all known registrations.
Definition: chan_sip.c:34298
static void unlink_marked_peers_from_tables(void)
Definition: chan_sip.c:3272
static void sip_keepalive_all_peers(void)
Send a keepalive to all known peers.
Definition: chan_sip.c:34275

◆ sip_dtmfmode()

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

Set the DTMFmode for an outbound SIP call (application)

Definition at line 34024 of file chan_sip.c.

References ast_channel_lock, ast_channel_tech(), ast_channel_tech_pvt(), 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(), sip_pvt::flags, IS_SIP_TECH, sip_pvt::jointnoncodeccapability, LOG_WARNING, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, SIP_DTMF_SHORTINFO, sip_pvt_lock, and sip_pvt_unlock.

Referenced by load_module().

34025 {
34026  struct sip_pvt *p;
34027  const char *mode = data;
34028 
34029  if (!data) {
34030  ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n");
34031  return 0;
34032  }
34033  ast_channel_lock(chan);
34034  if (!IS_SIP_TECH(ast_channel_tech(chan))) {
34035  ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n");
34036  ast_channel_unlock(chan);
34037  return 0;
34038  }
34039  p = ast_channel_tech_pvt(chan);
34040  if (!p) {
34041  ast_channel_unlock(chan);
34042  return 0;
34043  }
34044  sip_pvt_lock(p);
34045  if (!strcasecmp(mode, "info")) {
34046  ast_clear_flag(&p->flags[0], SIP_DTMF);
34047  ast_set_flag(&p->flags[0], SIP_DTMF_INFO);
34049  } else if (!strcasecmp(mode, "shortinfo")) {
34050  ast_clear_flag(&p->flags[0], SIP_DTMF);
34053  } else if (!strcasecmp(mode, "rfc2833")) {
34054  ast_clear_flag(&p->flags[0], SIP_DTMF);
34057  } else if (!strcasecmp(mode, "inband")) {
34058  ast_clear_flag(&p->flags[0], SIP_DTMF);
34061  } else {
34062  ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n", mode);
34063  }
34064  if (p->rtp)
34066  if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) ||
34067  (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) {
34068  enable_dsp_detect(p);
34069  } else {
34070  disable_dsp_detect(p);
34071  }
34072  sip_pvt_unlock(p);
34073  ast_channel_unlock(chan);
34074  return 0;
34075 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
#define SIP_DTMF_INBAND
Definition: sip.h:277
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define LOG_WARNING
Definition: logger.h:274
#define SIP_DTMF_RFC2833
Definition: sip.h:276
static void enable_dsp_detect(struct sip_pvt *p)
Definition: chan_sip.c:4896
struct ast_flags flags[3]
Definition: sip.h:1075
static void disable_dsp_detect(struct sip_pvt *p)
Definition: chan_sip.c:4930
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
int jointnoncodeccapability
Definition: sip.h:1105
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
#define ast_log
Definition: astobj2.c:42
#define IS_SIP_TECH(t)
Definition: sip_utils.h:26
#define SIP_DTMF_SHORTINFO
Definition: sip.h:280
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_rtp_instance * rtp
Definition: sip.h:1174
#define ast_clear_flag(p, flag)
Definition: utils.h:77
#define SIP_DTMF
Definition: sip.h:275
void ast_rtp_instance_set_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value)
Set the value of an RTP instance property.
Definition: rtp_engine.c:705
#define SIP_DTMF_INFO
Definition: sip.h:278
#define AST_RTP_DTMF
Definition: rtp_engine.h:266
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
#define SIP_DTMF_AUTO
Definition: sip.h:279

◆ sip_dump_history()

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

References AST_LIST_TRAVERSE, ast_log, sip_pvt::callid, DEBUG_ATLEAST, sip_history::event, sip_pvt::history, LOG_DEBUG, LOG_NOTICE, sipdebug, and sip_pvt::subscribed.

Referenced by sip_pvt_dtor().

22587 {
22588  int x = 0;
22589  struct sip_history *hist;
22590  static int errmsg = 0;
22591 
22592  if (!dialog) {
22593  return;
22594  }
22595 
22596  if (!sipdebug && !DEBUG_ATLEAST(1)) {
22597  if (!errmsg) {
22598  ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n");
22599  errmsg = 1;
22600  }
22601  return;
22602  }
22603 
22604  ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid);
22605  if (dialog->subscribed) {
22606  ast_log(LOG_DEBUG, " * Subscription\n");
22607  } else {
22608  ast_log(LOG_DEBUG, " * SIP Call\n");
22609  }
22610  if (dialog->history) {
22611  AST_LIST_TRAVERSE(dialog->history, hist, list)
22612  ast_log(LOG_DEBUG, " %-3.3d. %s\n", ++x, hist->event);
22613  }
22614  if (!x) {
22615  ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid);
22616  }
22617  ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid);
22618 }
enum subscriptiontype subscribed
Definition: sip.h:1161
#define LOG_DEBUG
Definition: logger.h:241
char event[0]
Definition: sip.h:898
#define ast_log
Definition: astobj2.c:42
struct sip_history_head * history
Definition: sip.h:1178
const ast_string_field callid
Definition: sip.h:1063
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
#define LOG_NOTICE
Definition: logger.h:263
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define DEBUG_ATLEAST(level)
Definition: logger.h:441
struct sip_history::@168 list
sip_history: Structure for saving transactions within a SIP dialog
Definition: sip.h:896

◆ sip_epa_register()

static int sip_epa_register ( const struct epa_static_data static_data)
static

Definition at line 1635 of file chan_sip.c.

References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, epa_backend::next, and epa_backend::static_data.

Referenced by load_module().

1636 {
1637  struct epa_backend *backend = ast_calloc(1, sizeof(*backend));
1638 
1639  if (!backend) {
1640  return -1;
1641  }
1642 
1643  backend->static_data = static_data;
1644 
1648  return 0;
1649 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
const struct epa_static_data * static_data
Definition: sip.h:1640
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
struct epa_backend * next
Definition: sip.h:1641
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
backend for an event publication agent
Definition: sip.h:1639
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204

◆ sip_epa_unregister_all()

static void sip_epa_unregister_all ( void  )
static

Definition at line 1651 of file chan_sip.c.

References ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, cc_handle_publish_error(), and epa_backend::next.

Referenced by unload_module().

1652 {
1653  struct epa_backend *backend;
1654 
1656  while ((backend = AST_LIST_REMOVE_HEAD(&epa_static_data_list, next))) {
1657  ast_free(backend);
1658  }
1660 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
struct epa_backend * next
Definition: sip.h:1641
backend for an event publication agent
Definition: sip.h:1639
#define ast_free(a)
Definition: astmm.h:182

◆ sip_find_peer()

struct sip_peer* sip_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.

Parameters
peer,addr,realtime,devstate_only,transport
which_objectsDefine which objects should be matched when doing a lookup by name. Valid options are FINDUSERS, FINDPEERS, or FINDALLDEVICES. Note that this option is not used at all when doing a lookup by IP.

This is used on find matching device on name or ip/port. If the device was declared as type=peer, we don't match on peer name on incoming INVITEs.

Note
Avoid using this function in new functions if there is a way to avoid it, since it might cause a database lookup.

Definition at line 5851 of file chan_sip.c.

References NULL, and sip_find_peer_full().

Referenced by _sip_qualify_peer(), _sip_show_peer(), check_peer_ok(), create_addr(), function_sippeer(), handle_request_notify(), manager_sip_peer_status(), receive_message(), register_verify(), sip_devicestate(), sip_do_debug_peer(), sip_msg_send(), sip_report_security_event(), sip_show_user(), sip_unregister(), and transmit_register().

5852 {
5853  return sip_find_peer_full(peer, addr, NULL, realtime, which_objects, devstate_only, transport);
5854 }
#define NULL
Definition: resample.c:96
static struct sip_peer * sip_find_peer_full(const char *peer, struct ast_sockaddr *addr, char *callbackexten, int realtime, int which_objects, int devstate_only, int transport)
Definition: chan_sip.c:5789

◆ sip_find_peer_by_ip_and_exten()

static struct sip_peer* sip_find_peer_by_ip_and_exten ( struct ast_sockaddr addr,
char *  callbackexten,
int  transport 
)
static

Definition at line 5856 of file chan_sip.c.

References FALSE, FINDPEERS, NULL, sip_find_peer_full(), and TRUE.

Referenced by check_peer_ok().

5857 {
5858  return sip_find_peer_full(NULL, addr, callbackexten, TRUE, FINDPEERS, FALSE, transport);
5859 }
#define FALSE
Definition: app_minivm.c:521
#define NULL
Definition: resample.c:96
#define FINDPEERS
Definition: sip.h:53
static struct sip_peer * sip_find_peer_full(const char *peer, struct ast_sockaddr *addr, char *callbackexten, int realtime, int which_objects, int devstate_only, int transport)
Definition: chan_sip.c:5789
#define TRUE
Definition: app_minivm.c:518

◆ sip_find_peer_full()

static struct sip_peer* sip_find_peer_full ( const char *  peer,
struct ast_sockaddr addr,
char *  callbackexten,
int  realtime,
int  which_objects,
int  devstate_only,
int  transport 
)
static

Definition at line 5789 of file chan_sip.c.

References sip_peer::addr, ao2_t_callback_data, ast_copy_string(), ast_set_flag, ast_sockaddr_copy(), find_by_name(), FINDALLDEVICES, FINDPEERS, FINDUSERS, ast_flags::flags, sip_peer::flags, sip_peer::name, NULL, OBJ_POINTER, peer_ipcmp_cb_full(), realtime_peer(), SIP_INSECURE_PORT, SIP_TYPE_PEER, SIP_TYPE_USER, sip_unref_peer, sip_peer::transports, and sip_peer::type.

Referenced by sip_find_peer(), and sip_find_peer_by_ip_and_exten().

5790 {
5791  struct sip_peer *p = NULL;
5792  struct sip_peer tmp_peer;
5793 
5794  if (peer) {
5795  ast_copy_string(tmp_peer.name, peer, sizeof(tmp_peer.name));
5796  p = ao2_t_callback_data(peers, OBJ_POINTER, find_by_name, &tmp_peer, &which_objects, "ao2_find in peers table");
5797  } else if (addr) { /* search by addr? */
5798  ast_sockaddr_copy(&tmp_peer.addr, addr);
5799  tmp_peer.flags[0].flags = 0;
5800  tmp_peer.transports = transport;
5801  p = ao2_t_callback_data(peers_by_ip, OBJ_POINTER, peer_ipcmp_cb_full, &tmp_peer, callbackexten, "ao2_find in peers_by_ip table");
5802  if (!p) {
5803  ast_set_flag(&tmp_peer.flags[0], SIP_INSECURE_PORT);
5804  p = ao2_t_callback_data(peers_by_ip, OBJ_POINTER, peer_ipcmp_cb_full, &tmp_peer, callbackexten, "ao2_find in peers_by_ip table 2");
5805  if (p) {
5806  return p;
5807  }
5808  }
5809  }
5810 
5811  if (!p && (realtime || devstate_only)) {
5812  /* realtime_peer will return a peer with matching callbackexten if possible, otherwise one matching
5813  * without the callbackexten */
5814  p = realtime_peer(peer, addr, callbackexten, devstate_only, which_objects);
5815  if (p) {
5816  switch (which_objects) {
5817  case FINDUSERS:
5818  if (!(p->type & SIP_TYPE_USER)) {
5819  sip_unref_peer(p, "Wrong type of realtime SIP endpoint");
5820  return NULL;
5821  }
5822  break;
5823  case FINDPEERS:
5824  if (!(p->type & SIP_TYPE_PEER)) {
5825  sip_unref_peer(p, "Wrong type of realtime SIP endpoint");
5826  return NULL;
5827  }
5828  break;
5829  case FINDALLDEVICES:
5830  break;
5831  }
5832  }
5833  }
5834 
5835  return p;
5836 }
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:171
#define OBJ_POINTER
Definition: astobj2.h:1154
#define ast_set_flag(p, flag)
Definition: utils.h:70
enum sip_peer_type type
Definition: sip.h:1375
static int find_by_name(void *obj, void *arg, void *data, int flags)
Definition: chan_sip.c:5761
#define NULL
Definition: resample.c:96
static struct ao2_container * peers_by_ip
Definition: chan_sip.c:1053
#define SIP_INSECURE_PORT
Definition: sip.h:296
#define FINDUSERS
Definition: sip.h:52
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
#define FINDPEERS
Definition: sip.h:53
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
#define FINDALLDEVICES
Definition: sip.h:54
static struct sip_peer * realtime_peer(const char *peername, struct ast_sockaddr *sin, char *callbackexten, int devstate_only, int which_objects)
realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig...
Definition: chan_sip.c:5685
#define ao2_t_callback_data(container, flags, cb_fn, arg, data, tag)
ao2_callback_data() is a generic function that applies cb_fn() to all objects in a container...
Definition: astobj2.h:1741
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static int peer_ipcmp_cb_full(void *obj, void *arg, void *data, int flags)
Definition: chan_sip.c:34543

◆ sip_fixup()

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

References append_history, ast_channel_flags(), ast_channel_name(), ast_channel_tech_pvt(), ast_debug, AST_FLAG_ZOMBIE, ast_log, ast_test_flag, sip_pvt::callid, LOG_WARNING, NULL, sip_pvt::owner, sip_pvt_lock, sip_pvt_unlock, sip_set_owner(), and sip_set_rtp_peer().

7629 {
7630  int ret = -1;
7631  struct sip_pvt *p;
7632 
7633  if (newchan && ast_test_flag(ast_channel_flags(newchan), AST_FLAG_ZOMBIE))
7634  ast_debug(1, "New channel is zombie\n");
7635  if (oldchan && ast_test_flag(ast_channel_flags(oldchan), AST_FLAG_ZOMBIE))
7636  ast_debug(1, "Old channel is zombie\n");
7637 
7638  if (!newchan || !ast_channel_tech_pvt(newchan)) {
7639  if (!newchan)
7640  ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", ast_channel_name(oldchan));
7641  else
7642  ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", ast_channel_name(oldchan));
7643  return -1;
7644  }
7645  p = ast_channel_tech_pvt(newchan);
7646 
7647  sip_pvt_lock(p);
7648  append_history(p, "Masq", "Old channel: %s\n", ast_channel_name(oldchan));
7649  append_history(p, "Masq (cont)", "...new owner: %s\n", ast_channel_name(newchan));
7650  if (p->owner != oldchan)
7651  ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner);
7652  else {
7653  sip_set_owner(p, newchan);
7654  /* Re-invite RTP back to Asterisk. Needed if channel is masqueraded out of a native
7655  RTP bridge (i.e., RTP not going through Asterisk): RTP bridge code might not be
7656  able to do this if the masquerade happens before the bridge breaks (e.g., AMI
7657  redirect of both channels). Note that a channel can not be masqueraded *into*
7658  a native bridge. So there is no danger that this breaks a native bridge that
7659  should stay up. */
7660  sip_set_rtp_peer(newchan, NULL, NULL, NULL, NULL, 0);
7661  ret = 0;
7662  }
7663  ast_debug(3, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, ast_channel_name(p->owner), ast_channel_name(oldchan));
7664 
7665  sip_pvt_unlock(p);
7666  return ret;
7667 }
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define LOG_WARNING
Definition: logger.h:274
static void sip_set_owner(struct sip_pvt *p, struct ast_channel *chan)
Set the owning channel on the sip_pvt object.
Definition: chan_sip.c:9450
#define NULL
Definition: resample.c:96
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
const ast_string_field callid
Definition: sip.h:1063
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
struct ast_channel * owner
Definition: sip.h:1138
const char * ast_channel_name(const struct ast_channel *chan)
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
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, const struct ast_format_cap *cap, int nat_active)
Definition: chan_sip.c:33883

◆ sip_get_callid()

static const char * sip_get_callid ( struct ast_channel chan)
static

Deliver SIP call ID for the call.

Definition at line 5120 of file chan_sip.c.

References ast_channel_tech_pvt().

5121 {
5122  return ast_channel_tech_pvt(chan) ? ((struct sip_pvt *) ast_channel_tech_pvt(chan))->callid : "";
5123 }
void * ast_channel_tech_pvt(const struct ast_channel *chan)
const ast_string_field callid
Definition: sip.h:1063
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005

◆ sip_get_cc_information()

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

References AST_CC_NONE, ast_copy_string(), ast_strdupa, ast_strlen_zero, get_in_brackets(), service_string_to_service_type(), sip_get_header(), and strsep().

Referenced by sip_handle_cc().

2252 {
2253  char *call_info = ast_strdupa(sip_get_header(req, "Call-Info"));
2254  char *uri;
2255  char *purpose;
2256  char *service_str;
2257  static const char cc_purpose[] = "purpose=call-completion";
2258  static const int cc_purpose_len = sizeof(cc_purpose) - 1;
2259 
2260  if (ast_strlen_zero(call_info)) {
2261  /* No Call-Info present. Definitely no CC offer */
2262  return -1;
2263  }
2264 
2265  uri = strsep(&call_info, ";");
2266 
2267  while ((purpose = strsep(&call_info, ";"))) {
2268  if (!strncmp(purpose, cc_purpose, cc_purpose_len)) {
2269  break;
2270  }
2271  }
2272  if (!purpose) {
2273  /* We didn't find the appropriate purpose= parameter. Oh well */
2274  return -1;
2275  }
2276 
2277  /* Okay, call-completion has been offered. Let's figure out what type of service this is */
2278  while ((service_str = strsep(&call_info, ";"))) {
2279  if (!strncmp(service_str, "m=", 2)) {
2280  break;
2281  }
2282  }
2283  if (!service_str) {
2284  /* So they didn't offer a particular service, We'll just go with CCBS since it really
2285  * doesn't matter anyway
2286  */
2287  service_str = "BS";
2288  } else {
2289  /* We already determined that there is an "m=" so no need to check
2290  * the result of this strsep
2291  */
2292  strsep(&service_str, "=");
2293  }
2294 
2295  if ((*service = service_string_to_service_type(service_str)) == AST_CC_NONE) {
2296  /* Invalid service offered */
2297  return -1;
2298  }
2299 
2300  ast_copy_string(subscribe_uri, get_in_brackets(uri), size);
2301 
2302  return 0;
2303 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
char * get_in_brackets(char *tmp)
Pick out text in brackets from character string.
enum ast_cc_service_type service
Definition: chan_sip.c:949
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static enum ast_cc_service_type service_string_to_service_type(const char *const service_string)
Definition: chan_sip.c:1709
char * strsep(char **str, const char *delims)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
const ast_string_field uri
Definition: sip.h:1063

◆ sip_get_codec()

static void sip_get_codec ( struct ast_channel chan,
struct ast_format_cap result 
)
static

Definition at line 34000 of file chan_sip.c.

References ast_channel_nativeformats(), ast_format_cap_append_from_cap(), and AST_MEDIA_TYPE_UNKNOWN.

34001 {
34003 }
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
int ast_format_cap_append_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type)
Append the formats of provided type in src to dst.
Definition: format_cap.c:269

◆ sip_get_header()

const char* sip_get_header ( const struct sip_request req,
const char *  name 
)

Get header from SIP request.

Returns
Always return something, so don't check for NULL because it won't happen :-)

Definition at line 8600 of file chan_sip.c.

References __get_header().

Referenced by __find_call(), __sip_alloc(), __transmit_response(), build_route(), cc_handle_publish_error(), change_redirecting_information(), check_auth(), check_user_full(), check_via(), copy_header(), extract_uri(), 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_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_oli(), parse_register_contact(), proc_422_rsp(), process_via(), receive_message(), register_verify(), reqprep(), respprep(), send_check_user_failure_response(), send_request(), send_response(), sip_get_cc_information(), sip_pidf_validate(), sip_report_security_event(), sip_sipredirect(), transmit_fake_auth_response(), transmit_invite(), transmit_refer(), transmit_response_with_auth(), transmit_response_with_sdp(), transmit_response_with_t38_sdp(), transmit_state_notify(), uac_sips_contact(), uas_sips_contact(), and use_reason_header().

8601 {
8602  int start = 0;
8603  return __get_header(req, name, &start);
8604 }
static const char * __get_header(const struct sip_request *req, const char *name, int *start)
Definition: chan_sip.c:8562
static const char name[]
Definition: cdr_mysql.c:74

◆ sip_get_rtp_peer()

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

Definition at line 33781 of file chan_sip.c.

References ao2_ref, ast_channel_tech_pvt(), AST_JB_FORCED, AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_LOCAL, AST_RTP_GLUE_RESULT_REMOTE, ast_test_flag, sip_pvt::flags, global_jbconf, NULL, sip_pvt::rtp, SIP_DIRECT_MEDIA, SIP_DIRECT_MEDIA_NAT, SIP_PAGE2_T38SUPPORT, sip_pvt_lock, sip_pvt_unlock, sip_pvt::srtp, t38properties::state, sip_pvt::t38, T38_ENABLED, T38_LOCAL_REINVITE, T38_PEER_REINVITE, and T38_REJECTED.

33782 {
33783  struct sip_pvt *p = NULL;
33785 
33786  if (!(p = ast_channel_tech_pvt(chan))) {
33788  }
33789 
33790  sip_pvt_lock(p);
33791  if (!(p->rtp)) {
33792  sip_pvt_unlock(p);
33794  }
33795 
33796  ao2_ref(p->rtp, +1);
33797  *instance = p->rtp;
33798 
33799  if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) {
33801  } else if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA_NAT)) {
33803  } else if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) {
33805  }
33806 
33807  if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) {
33808  switch (p->t38.state) {
33809  case T38_LOCAL_REINVITE:
33810  case T38_PEER_REINVITE:
33811  case T38_ENABLED:
33813  break;
33814  case T38_REJECTED:
33815  default:
33816  break;
33817  }
33818  }
33819 
33820  if (p->srtp) {
33822  }
33823 
33824  sip_pvt_unlock(p);
33825 
33826  return res;
33827 }
#define SIP_DIRECT_MEDIA
Definition: sip.h:289
#define T38_ENABLED
Definition: chan_ooh323.c:102
enum t38state state
Definition: sip.h:917
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_flags flags[3]
Definition: sip.h:1075
#define NULL
Definition: resample.c:96
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
struct t38properties t38
Definition: sip.h:1113
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
#define ao2_ref(o, delta)
Definition: astobj2.h:464
ast_rtp_glue_result
Definition: rtp_engine.h:158
#define SIP_DIRECT_MEDIA_NAT
Definition: sip.h:290
static struct ast_jb_conf global_jbconf
Definition: chan_sip.c:688
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
struct ast_rtp_instance * rtp
Definition: sip.h:1174
#define SIP_PAGE2_T38SUPPORT
Definition: sip.h:346
struct ast_sdp_srtp * srtp
Definition: sip.h:1185

◆ sip_get_transport()

const char* sip_get_transport ( enum ast_transport  t)

Return transport as string.

Definition at line 3725 of file chan_sip.c.

References AST_TRANSPORT_TCP, AST_TRANSPORT_TLS, AST_TRANSPORT_UDP, AST_TRANSPORT_WS, and AST_TRANSPORT_WSS.

Referenced by _sip_show_peer(), ast_sip_ouraddrfor(), build_contact(), get_transport_pvt(), handle_request_do(), parse_moved_contact(), sip_report_security_event(), sip_show_settings(), sip_show_tcp(), and transmit_notify_with_mwi().

3726 {
3727  switch (t) {
3728  case AST_TRANSPORT_UDP:
3729  return "UDP";
3730  case AST_TRANSPORT_TCP:
3731  return "TCP";
3732  case AST_TRANSPORT_TLS:
3733  return "TLS";
3734  case AST_TRANSPORT_WS:
3735  case AST_TRANSPORT_WSS:
3736  return "WS";
3737  }
3738 
3739  return "UNKNOWN";
3740 }

◆ sip_get_trtp_peer()

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

Definition at line 33856 of file chan_sip.c.

References ao2_ref, ast_channel_tech_pvt(), AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_REMOTE, ast_test_flag, sip_pvt::flags, NULL, SIP_DIRECT_MEDIA, sip_pvt_lock, sip_pvt_unlock, and sip_pvt::trtp.

33857 {
33858  struct sip_pvt *p = NULL;
33860 
33861  if (!(p = ast_channel_tech_pvt(chan))) {
33863  }
33864 
33865  sip_pvt_lock(p);
33866  if (!(p->trtp)) {
33867  sip_pvt_unlock(p);
33869  }
33870 
33871  ao2_ref(p->trtp, +1);
33872  *instance = p->trtp;
33873 
33874  if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) {
33876  }
33877 
33878  sip_pvt_unlock(p);
33879 
33880  return res;
33881 }
#define SIP_DIRECT_MEDIA
Definition: sip.h:289
void * ast_channel_tech_pvt(const struct ast_channel *chan)
struct ast_rtp_instance * trtp
Definition: sip.h:1176
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_flags flags[3]
Definition: sip.h:1075
#define NULL
Definition: resample.c:96
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
#define ao2_ref(o, delta)
Definition: astobj2.h:464
ast_rtp_glue_result
Definition: rtp_engine.h:158
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005

◆ sip_get_vrtp_peer()

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

Definition at line 33829 of file chan_sip.c.

References ao2_ref, ast_channel_tech_pvt(), AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_REMOTE, ast_test_flag, sip_pvt::flags, NULL, SIP_DIRECT_MEDIA, sip_pvt_lock, sip_pvt_unlock, and sip_pvt::vrtp.

33830 {
33831  struct sip_pvt *p = NULL;
33833 
33834  if (!(p = ast_channel_tech_pvt(chan))) {
33836  }
33837 
33838  sip_pvt_lock(p);
33839  if (!(p->vrtp)) {
33840  sip_pvt_unlock(p);
33842  }
33843 
33844  ao2_ref(p->vrtp, +1);
33845  *instance = p->vrtp;
33846 
33847  if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) {
33849  }
33850 
33851  sip_pvt_unlock(p);
33852 
33853  return res;
33854 }
#define SIP_DIRECT_MEDIA
Definition: sip.h:289
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_flags flags[3]
Definition: sip.h:1075
#define NULL
Definition: resample.c:96
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
#define ao2_ref(o, delta)
Definition: astobj2.h:464
ast_rtp_glue_result
Definition: rtp_engine.h:158
struct ast_rtp_instance * vrtp
Definition: sip.h:1175
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005

◆ sip_handle_cc()

static void sip_handle_cc ( struct sip_pvt pvt,
struct sip_request req,
enum ast_cc_service_type  service 
)
static

Definition at line 2322 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_pvt::cc_params, sip_monitor_instance::core_id, sip_monitor_instance::device_name, sip_pvt::dialstring, NULL, sip_pvt::owner, sip_pvt::peername, ast_module_info::self, sip_get_cc_information(), sip_monitor_instance_init(), SIPBUFSIZE, and sip_monitor_instance::subscribe_uri.

Referenced by handle_response(), and handle_response_invite().

2323 {
2324  enum ast_cc_monitor_policies monitor_policy = ast_get_cc_monitor_policy(pvt->cc_params);
2325  int core_id;
2326  char interface_name[AST_CHANNEL_NAME];
2327 
2328  if (monitor_policy == AST_CC_MONITOR_NEVER) {
2329  /* Don't bother, just return */
2330  return;
2331  }
2332 
2333  if ((core_id = ast_cc_get_current_core_id(pvt->owner)) == -1) {
2334  /* For some reason, CC is invalid, so don't try it! */
2335  return;
2336  }
2337 
2338  ast_channel_get_device_name(pvt->owner, interface_name, sizeof(interface_name));
2339 
2340  if (monitor_policy == AST_CC_MONITOR_ALWAYS || monitor_policy == AST_CC_MONITOR_NATIVE) {
2341  char subscribe_uri[SIPBUFSIZE];
2342  char device_name[AST_CHANNEL_NAME];
2343  enum ast_cc_service_type offered_service;
2344  struct sip_monitor_instance *monitor_instance;
2345  if (sip_get_cc_information(req, subscribe_uri, sizeof(subscribe_uri), &offered_service)) {
2346  /* If CC isn't being offered to us, or for some reason the CC offer is
2347  * not formatted correctly, then it may still be possible to use generic
2348  * call completion since the monitor policy may be "always"
2349  */
2350  goto generic;
2351  }
2352  ast_channel_get_device_name(pvt->owner, device_name, sizeof(device_name));
2353  if (!(monitor_instance = sip_monitor_instance_init(core_id, subscribe_uri, pvt->peername, device_name))) {
2354  /* Same deal. We can try using generic still */
2355  goto generic;
2356  }
2357  /* We bump the refcount of chan_sip because once we queue this frame, the CC core
2358  * will have a reference to callbacks in this module. We decrement the module
2359  * refcount once the monitor destructor is called
2360  */
2362  ast_queue_cc_frame(pvt->owner, "SIP", pvt->dialstring, offered_service, monitor_instance);
2363  ao2_ref(monitor_instance, -1);
2364  return;
2365  }
2366 
2367 generic:
2368  if (monitor_policy == AST_CC_MONITOR_GENERIC || monitor_policy == AST_CC_MONITOR_ALWAYS) {
2370  }
2371 }
struct ast_cc_config_params * cc_params
Definition: sip.h:1218
int ast_cc_get_current_core_id(struct ast_channel *chan)
Get the core id for the current call.
Definition: ccss.c:2487
enum ast_cc_service_type service
Definition: chan_sip.c:949
int ast_queue_cc_frame(struct ast_channel *chan, const char *const monitor_type, const char *const dialstring, enum ast_cc_service_type service, void *private_data)
Queue an AST_CONTROL_CC frame.
Definition: ccss.c:4149
#define NULL
Definition: resample.c:96
ast_cc_service_type
Definition: ccss.h:32
ast_cc_monitor_policies
The various possibilities for cc_monitor_policy values.
Definition: ccss.h:74
const ast_string_field dialstring
Definition: sip.h:1063
enum ast_cc_monitor_policies ast_get_cc_monitor_policy(struct ast_cc_config_params *config)
Get the cc_monitor_policy.
Definition: ccss.c:883
static int sip_get_cc_information(struct sip_request *req, char *subscribe_uri, size_t size, enum ast_cc_service_type *service)
Definition: chan_sip.c:2251
struct ast_module * self
Definition: module.h:342
#define ao2_ref(o, delta)
Definition: astobj2.h:464
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)
Definition: chan_sip.c:2054
#define AST_CC_GENERIC_MONITOR_TYPE
Definition: ccss.h:489
#define SIPBUFSIZE
Definition: sip.h:56
#define AST_CHANNEL_NAME
Definition: channel.h:172
struct ast_channel * owner
Definition: sip.h:1138
const ast_string_field peername
Definition: sip.h:1063
int ast_channel_get_device_name(struct ast_channel *chan, char *device_name, size_t name_buffer_length)
Get a device name given its channel structure.
Definition: channel.c:10697
#define ast_module_ref(mod)
Hold a reference to the module.
Definition: module.h:443

◆ sip_hangup()

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

References __sip_semi_ack(), sip_pvt::alreadygone, sip_pvt::answered_elsewhere, ao2_ref, append_history, ast_cause2str(), AST_CAUSE_ANSWERED_ELSEWHERE, ast_channel_hangupcause(), ast_channel_lock, ast_channel_name(), ast_channel_stage_snapshot(), ast_channel_stage_snapshot_done(), ast_channel_tech_pvt(), ast_channel_tech_pvt_set(), ast_channel_unlock, ast_clear_flag, ast_debug, 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_set_flag, ast_state2str(), AST_STATE_UP, ast_str_buffer(), ast_str_strlen(), ast_test_flag, sip_pvt::callid, sip_request::data, sip_pkt::data, DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, dialog_ref, dialog_unref, disable_dsp_detect(), sip_pvt::do_history, FALSE, find_sip_method(), sip_pvt::flags, hangup_cause2sip(), sip_pvt::hangupcause, sip_pvt::initreq, INV_CALLING, INV_CANCELLED, INV_COMPLETED, INV_TERMINATED, sip_pvt::invitestate, sip_pkt::is_resp, sip_pvt::lastinvite, LOG_WARNING, sip_pkt::method, sip_pkt::next, NULL, sip_pvt::ongoing_reinvite, sip_pvt::owner, sip_pvt::packets, pbx_builtin_setvar_helper(), sip_pvt::pendinginvite, pvt_set_needdestroy(), quality, reinvite_timeout(), sip_pvt::reinviteid, sip_pvt::rtp, ast_module_info::self, sip_pkt::seqno, SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_DEFER_BYE_ON_TRANSFER, SIP_INC_COUNT, SIP_NEEDREINVITE, SIP_OUTGOING, SIP_PAGE2_CALL_ONHOLD, SIP_PENDINGBYE, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), sip_set_owner(), sipdebug, sip_pvt::stimer, stop_media_flows(), stop_provisional_keepalive(), stop_reinvite_retry(), stop_session_timer(), sip_pvt::timer_t1, transmit_request(), transmit_request_with_auth(), transmit_response_reliable(), sip_pvt::trtp, TRUE, update_call_counter(), sip_pvt::username, sip_pvt::vrtp, and XMIT_RELIABLE.

7198 {
7199  struct sip_pvt *p = ast_channel_tech_pvt(ast);
7200  int needcancel = FALSE;
7201  int needdestroy = 0;
7202  struct ast_channel *oldowner = ast;
7203 
7204  if (!p) {
7205  ast_debug(1, "Asked to hangup channel that was not connected\n");
7206  return 0;
7207  }
7209  ast_debug(1, "This call was answered elsewhere\n");
7210  append_history(p, "Cancel", "Call answered elsewhere");
7211  p->answered_elsewhere = TRUE;
7212  }
7213 
7214  /* Store hangupcause locally in PVT so we still have it before disconnect */
7215  if (p->owner)
7217 
7220  if (sipdebug)
7221  ast_debug(1, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username);
7223  }
7224  ast_debug(4, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid);
7226  ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */
7227  if (p->owner) {
7228  sip_pvt_lock(p);
7229  oldowner = p->owner;
7230  sip_set_owner(p, NULL); /* Owner will be gone after we return, so take it away */
7231  sip_pvt_unlock(p);
7232  ast_channel_tech_pvt_set(oldowner, dialog_unref(ast_channel_tech_pvt(oldowner), "unref oldowner->tech_pvt"));
7233  }
7235  return 0;
7236  }
7237 
7238  ast_debug(1, "Hangup call %s, SIP callid %s\n", ast_channel_name(ast), p->callid);
7239 
7240  sip_pvt_lock(p);
7242  if (sipdebug)
7243  ast_debug(1, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username);
7245  }
7246 
7247  /* Determine how to disconnect */
7248  if (p->owner != ast) {
7249  ast_log(LOG_WARNING, "Huh? We aren't the owner? Can't hangup call.\n");
7250  sip_pvt_unlock(p);
7251  return 0;
7252  }
7253  /* If the call is not UP, we need to send CANCEL instead of BYE */
7254  /* In case of re-invites, the call might be UP even though we have an incomplete invite transaction */
7256  needcancel = TRUE;
7257  ast_debug(4, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast_channel_state(ast)));
7258  }
7259 
7260  stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
7261 
7262  append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", ast_cause2str(p->hangupcause));
7263 
7264  /* Disconnect */
7265  disable_dsp_detect(p);
7266 
7267  sip_set_owner(p, NULL);
7269 
7271  /* Do not destroy this pvt until we have timeout or
7272  get an answer to the BYE or INVITE/CANCEL
7273  If we get no answer during retransmit period, drop the call anyway.
7274  (Sorry, mother-in-law, you can't deny a hangup by sending
7275  603 declined to BYE...)
7276  */
7277  if (p->alreadygone)
7278  needdestroy = 1; /* Set destroy flag at end of this function */
7279  else if (p->invitestate != INV_CALLING)
7281 
7282  /* Start the process if it's not already started */
7283  if (!p->alreadygone && p->initreq.data && ast_str_strlen(p->initreq.data)) {
7284  if (needcancel) { /* Outgoing call, not up */
7285  if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
7286  /* if we can't send right now, mark it pending */
7287  if (p->invitestate == INV_CALLING) {
7288  /* We can't send anything in CALLING state */
7290  /* 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. */
7292  append_history(p, "DELAY", "Not sending cancel, waiting for timeout");
7293  } else {
7294  struct sip_pkt *cur;
7295 
7296  for (cur = p->packets; cur; cur = cur->next) {
7297  __sip_semi_ack(p, cur->seqno, cur->is_resp, cur->method ? cur->method : find_sip_method(ast_str_buffer(cur->data)));
7298  }
7300  /* Send a new request: CANCEL */
7302  /* Actually don't destroy us yet, wait for the 487 on our original
7303  INVITE, but do set an autodestruct just in case we never get it. */
7304  needdestroy = 0;
7306  }
7307  } else { /* Incoming call, not up */
7308  const char *res;
7309 
7311  if (p->hangupcause && (res = hangup_cause2sip(p->hangupcause)))
7312  transmit_response_reliable(p, res, &p->initreq);
7313  else
7314  transmit_response_reliable(p, "603 Declined", &p->initreq);
7316  }
7317  } else { /* Call is in UP state, send BYE */
7318  if (p->stimer) {
7319  stop_session_timer(p);
7320  }
7321 
7322  if (!p->pendinginvite) {
7323  char *quality;
7324  char quality_buf[AST_MAX_USER_FIELD];
7325 
7326  if (p->rtp) {
7327  struct ast_rtp_instance *p_rtp;
7328 
7329  p_rtp = p->rtp;
7330  ao2_ref(p_rtp, +1);
7331  ast_channel_unlock(oldowner);
7332  sip_pvt_unlock(p);
7333  ast_rtp_instance_set_stats_vars(oldowner, p_rtp);
7334  ao2_ref(p_rtp, -1);
7335  ast_channel_lock(oldowner);
7336  sip_pvt_lock(p);
7337  }
7338 
7339  /*
7340  * The channel variables are set below just to get the AMI
7341  * VarSet event because the channel is being hungup.
7342  */
7343  if (p->rtp || p->vrtp || p->trtp) {
7344  ast_channel_stage_snapshot(oldowner);
7345  }
7346  if (p->rtp && (quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) {
7347  if (p->do_history) {
7348  append_history(p, "RTCPaudio", "Quality:%s", quality);
7349  }
7350  pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", quality);
7351  }
7352  if (p->vrtp && (quality = ast_rtp_instance_get_quality(p->vrtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) {
7353  if (p->do_history) {
7354  append_history(p, "RTCPvideo", "Quality:%s", quality);
7355  }
7356  pbx_builtin_setvar_helper(oldowner, "RTPVIDEOQOS", quality);
7357  }
7358  if (p->trtp && (quality = ast_rtp_instance_get_quality(p->trtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) {
7359  if (p->do_history) {
7360  append_history(p, "RTCPtext", "Quality:%s", quality);
7361  }
7362  pbx_builtin_setvar_helper(oldowner, "RTPTEXTQOS", quality);
7363  }
7364  if (p->rtp || p->vrtp || p->trtp) {
7366  }
7367 
7368  /* Send a hangup */
7369  if (ast_channel_state(oldowner) == AST_STATE_UP) {
7371  }
7372 
7373  } else {
7374  /* Note we will need a BYE when this all settles out
7375  but we can't send one while we have "INVITE" outstanding. */
7379  sip_cancel_destroy(p);
7380 
7381  /* If we have an ongoing reinvite, there is a chance that we have gotten a provisional
7382  * response, but something weird has happened and we will never receive a final response.
7383  * So, just in case, check for pending actions after a bit of time to trigger the pending
7384  * bye that we are setting above */
7385  if (p->ongoing_reinvite && p->reinviteid < 0) {
7386  p->reinviteid = ast_sched_add(sched, 32 * p->timer_t1,
7387  reinvite_timeout, dialog_ref(p, "Schedule reinviteid"));
7388  if (p->reinviteid < 0) {
7389  /* Uh Oh. Expect bad behavior. */
7390  dialog_unref(p, "Failed to schedule reinviteid");
7391  }
7392  }
7393  }
7394  }
7395  }
7396  if (needdestroy) {
7397  pvt_set_needdestroy(p, "hangup");
7398  }
7399  sip_pvt_unlock(p);
7400  dialog_unref(p, "unref ast->tech_pvt");
7401  return 0;
7402 }
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.
Definition: chan_sip.c:16564
sip packet - raw format for outbound packets that are sent or scheduled for transmission Packets are ...
Definition: sip.h:1231
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
#define FALSE
Definition: app_minivm.c:521
int method
Definition: sip.h:1234
static int quality
Definition: codec_speex.c:62
int hangupcause
Definition: sip.h:1190
void * ast_channel_tech_pvt(const struct ast_channel *chan)
struct ast_rtp_instance * trtp
Definition: sip.h:1176
#define ast_test_flag(p, flag)
Definition: utils.h:63
static void stop_reinvite_retry(struct sip_pvt *pvt)
Definition: chan_sip.c:23846
static void stop_provisional_keepalive(struct sip_pvt *pvt)
Definition: chan_sip.c:4783
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define LOG_WARNING
Definition: logger.h:274
uint32_t pendinginvite
Definition: sip.h:1147
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
int reinviteid
Definition: sip.h:1157
#define DEFAULT_TRANS_TIMEOUT
Definition: sip.h:107
#define SIP_DEFER_BYE_ON_TRANSFER
Definition: sip.h:267
uint32_t seqno
Definition: sip.h:1235
unsigned short needdestroy
Definition: sip.h:1080
const ast_string_field username
Definition: sip.h:1063
Definition: sched.c:76
ast_channel_state
ast_channel states
Definition: channelstate.h:35
#define DEC_CALL_LIMIT
Definition: sip.h:127
unsigned int ongoing_reinvite
Definition: sip.h:1144
static void sip_set_owner(struct sip_pvt *p, struct ast_channel *chan)
Set the owning channel on the sip_pvt object.
Definition: chan_sip.c:9450
#define SIP_PAGE2_CALL_ONHOLD
Definition: sip.h:351
struct ast_flags flags[3]
Definition: sip.h:1075
const char * ast_state2str(enum ast_channel_state)
Gives the string form of a given channel state.
Definition: channel.c:642
Definition: sip.h:621
#define NULL
Definition: resample.c:96
static void disable_dsp_detect(struct sip_pvt *p)
Definition: chan_sip.c:4930
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
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 th...
Definition: chan_sip.c:6844
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:469
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
static void stop_session_timer(struct sip_pvt *p)
Session-Timers: Stop session timer.
Definition: chan_sip.c:30213
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.
Definition: chan_sip.c:12688
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: chan_sip.c:4632
unsigned short alreadygone
Definition: sip.h:1079
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define SIP_INC_COUNT
Definition: sip.h:265
#define ast_log
Definition: astobj2.c:42
struct ast_module * self
Definition: module.h:342
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
struct sip_request initreq
Definition: sip.h:1151
#define AST_CAUSE_ANSWERED_ELSEWHERE
Definition: causes.h:113
#define ao2_ref(o, delta)
Definition: astobj2.h:464
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&#39;t retry...
Definition: chan_sip.c:16532
char * ast_rtp_instance_get_quality(struct ast_rtp_instance *instance, enum ast_rtp_instance_stat_field field, char *buf, size_t size)
Retrieve quality statistics about an RTP instance.
Definition: rtp_engine.c:2460
struct ast_str * data
Definition: sip.h:1246
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
const char * hangup_cause2sip(int cause)
Convert Asterisk hangup causes to SIP codes.
Definition: chan_sip.c:7108
const ast_string_field callid
Definition: sip.h:1063
static void pvt_set_needdestroy(struct sip_pvt *pvt, const char *reason)
Definition: chan_sip.c:3429
struct sip_st_dlg * stimer
Definition: sip.h:1184
struct ast_str * data
Definition: sip.h:843
char is_resp
Definition: sip.h:1236
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
struct ast_rtp_instance * vrtp
Definition: sip.h:1175
struct sip_pkt * next
Definition: sip.h:1232
static void stop_media_flows(struct sip_pvt *p)
Immediately stop RTP, VRTP and UDPTL as applicable.
Definition: chan_sip.c:25156
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
#define ast_channel_unlock(chan)
Definition: channel.h:2946
const char * ast_cause2str(int state) attribute_pure
Gives the string form of a given cause code.
Definition: channel.c:612
unsigned short do_history
Definition: sip.h:1078
struct ast_channel * owner
Definition: sip.h:1138
int timer_t1
Definition: sip.h:1095
#define dialog_ref(dialog, tag)
when we create or delete references, make sure to use these functions so we keep track of the refcoun...
Definition: dialog.h:32
struct sip_pkt * packets
Definition: sip.h:1177
struct ast_rtp_instance * rtp
Definition: sip.h:1174
static int find_sip_method(const char *msg)
find_sip_method: Find SIP method from header
Definition: chan_sip.c:3594
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565
enum invitestates invitestate
Definition: sip.h:1007
#define ast_clear_flag(p, flag)
Definition: utils.h:77
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
#define SIP_PENDINGBYE
Definition: sip.h:262
void sip_cancel_destroy(struct sip_pvt *pvt)
Cancel destruction of SIP dialog.
Definition: chan_sip.c:4464
int ast_channel_hangupcause(const struct ast_channel *chan)
const char * ast_channel_name(const struct ast_channel *chan)
#define TRUE
Definition: app_minivm.c:518
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406
uint32_t lastinvite
Definition: sip.h:1074
unsigned short answered_elsewhere
Definition: sip.h:1084
void ast_rtp_instance_set_stats_vars(struct ast_channel *chan, struct ast_rtp_instance *instance)
Set standard statistics from an RTP instance on a channel.
Definition: rtp_engine.c:2500
#define SIP_NEEDREINVITE
Definition: sip.h:261
static int reinvite_timeout(const void *data)
Definition: chan_sip.c:7158
#define SIP_OUTGOING
Definition: sip.h:257
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)
void sip_scheddestroy(struct sip_pvt *p, int ms)
Schedule destruction of SIP dialog.
Definition: chan_sip.c:4549
#define AST_MAX_USER_FIELD
Definition: channel.h:175

◆ sip_indicate()

static int sip_indicate ( struct ast_channel ast,
int  condition,
const void *  data,
size_t  datalen 
)
static

Play indication to user With SIP a lot of indications is sent as messages, letting the device play the indication - busy signal, congestion etc.

Returns
-1 to force ast_indicate to send indication in audio, 0 if SIP can handle the indication by sending a message

Definition at line 7948 of file chan_sip.c.

References 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_channel_name(), ast_channel_nativeformats(), ast_channel_tech_pvt(), AST_CONTROL_AOC, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_FLASH, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_MASQUERADE_NOTIFY, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_PVT_CAUSE_CODE, 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_format_cap_iscompatible_format(), AST_FORMAT_CMP_NOT_EQUAL, ast_format_vp8, AST_FRAME_CONTROL, ast_log, ast_moh_start(), ast_moh_stop(), ast_rtp_instance_change_source(), ast_rtp_instance_update_source(), ast_rtp_instance_write(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_UP, ast_test_flag, sip_pvt::flags, ast_frame::frametype, initialize_udptl(), sip_pvt::initreq, ast_frame_subclass::integer, interpret_t38_parameters(), INV_COMPLETED, INV_EARLY_MEDIA, INV_PROCEEDING, sip_pvt::invitestate, LOG_ERROR, LOG_WARNING, sip_pvt::mohinterpret, sip_pvt::novideo, sip_pvt::owner, sip_pvt::rtp, sip_alreadygone(), SIP_OUTGOING, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWOVERLAP_DTMF, SIP_PAGE2_ALLOWOVERLAP_YES, SIP_PAGE3_SNOM_AOC, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_YES, SIP_PROGRESS_SENT, sip_pvt_lock, sip_pvt_unlock, SIP_RINGING, ast_frame::subclass, transmit_info_with_aoc(), transmit_info_with_vidupdate(), transmit_provisional_response(), transmit_response(), transmit_response_reliable(), TRUE, update_connectedline(), update_redirecting(), and sip_pvt::vrtp.

7949 {
7950  struct sip_pvt *p = ast_channel_tech_pvt(ast);
7951  int res = 0;
7952 
7953  if (!p) {
7954  ast_debug(1, "Asked to indicate condition on channel %s with no pvt; ignoring\n",
7955  ast_channel_name(ast));
7956  return res;
7957  }
7958 
7959  sip_pvt_lock(p);
7960  switch(condition) {
7961  case AST_CONTROL_RINGING:
7962  if (ast_channel_state(ast) == AST_STATE_RING) {
7964  if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) ||
7966  /* Send 180 ringing if out-of-band seems reasonable */
7967  transmit_provisional_response(p, "180 Ringing", &p->initreq, 0);
7968  ast_set_flag(&p->flags[0], SIP_RINGING);
7970  break;
7971  } else {
7972  /* Well, if it's not reasonable, just send in-band */
7973  }
7974  }
7975  res = -1;
7976  break;
7977  case AST_CONTROL_BUSY:
7978  if (ast_channel_state(ast) != AST_STATE_UP) {
7979  transmit_response_reliable(p, "486 Busy Here", &p->initreq);
7981  sip_alreadygone(p);
7983  break;
7984  }
7985  res = -1;
7986  break;
7988  if (ast_channel_state(ast) != AST_STATE_UP) {
7989  transmit_response_reliable(p, "503 Service Unavailable", &p->initreq);
7991  sip_alreadygone(p);
7993  break;
7994  }
7995  res = -1;
7996  break;
7998  if (ast_channel_state(ast) != AST_STATE_UP) {
7999  switch (ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) {
8001  transmit_response_reliable(p, "484 Address Incomplete", &p->initreq);
8003  sip_alreadygone(p);
8005  break;
8007  /* Just wait for inband DTMF digits */
8008  break;
8009  default:
8010  /* it actually means no support for overlap */
8011  transmit_response_reliable(p, "404 Not Found", &p->initreq);
8013  sip_alreadygone(p);
8015  break;
8016  }
8017  }
8018  break;
8020  if ((ast_channel_state(ast) != AST_STATE_UP) &&
8022  !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
8023  transmit_response(p, "100 Trying", &p->initreq);
8025  break;
8026  }
8027  res = -1;
8028  break;
8029  case AST_CONTROL_PROGRESS:
8030  if ((ast_channel_state(ast) != AST_STATE_UP) &&
8032  !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
8034  /* SIP_PROG_INBAND_NEVER means sending 180 ringing in place of a 183 */
8036  transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE);
8038  } else if (ast_channel_state(ast) == AST_STATE_RING && !ast_test_flag(&p->flags[0], SIP_RINGING)) {
8039  transmit_provisional_response(p, "180 Ringing", &p->initreq, 0);
8040  ast_set_flag(&p->flags[0], SIP_RINGING);
8041  }
8042  break;
8043  }
8044  res = -1;
8045  break;
8046  case AST_CONTROL_HOLD:
8048  ast_moh_start(ast, data, p->mohinterpret);
8049  break;
8050  case AST_CONTROL_UNHOLD:
8052  ast_moh_stop(ast);
8053  break;
8054  case AST_CONTROL_VIDUPDATE: /* Request a video frame update */
8055  if (p->vrtp && !p->novideo) {
8056  /* FIXME: Only use this for VP8. Additional work would have to be done to
8057  * fully support other video codecs */
8059  /* FIXME Fake RTP write, this will be sent as an RTCP packet. Ideally the
8060  * RTP engine would provide a way to externally write/schedule RTCP
8061  * packets */
8062  struct ast_frame fr;
8064  fr.subclass.integer = AST_CONTROL_VIDUPDATE;
8065  res = ast_rtp_instance_write(p->vrtp, &fr);
8066  } else {
8068  }
8069  } else {
8070  res = -1;
8071  }
8072  break;
8074  res = -1;
8075  if (datalen != sizeof(struct ast_control_t38_parameters)) {
8076  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);
8077  } else {
8078  const struct ast_control_t38_parameters *parameters = data;
8079  if (!initialize_udptl(p)) {
8080  res = interpret_t38_parameters(p, parameters);
8081  }
8082  }
8083  break;
8084  case AST_CONTROL_SRCUPDATE:
8086  break;
8087  case AST_CONTROL_SRCCHANGE:
8089  break;
8091  update_connectedline(p, data, datalen);
8092  break;
8094  update_redirecting(p, data, datalen);
8095  break;
8096  case AST_CONTROL_AOC:
8097  {
8098  struct ast_aoc_decoded *decoded = ast_aoc_decode((struct ast_aoc_encoded *) data, datalen, ast);
8099  if (!decoded) {
8100  ast_log(LOG_ERROR, "Error decoding indicated AOC data\n");
8101  res = -1;
8102  break;
8103  }
8104  switch (ast_aoc_get_msg_type(decoded)) {
8105  case AST_AOC_REQUEST:
8106  if (ast_aoc_get_termination_request(decoded)) {
8107  /* TODO, once there is a way to get AOC-E on hangup, attempt that here
8108  * before hanging up the channel.*/
8109 
8110  /* The other side has already initiated the hangup. This frame
8111  * just says they are waiting to get AOC-E before completely tearing
8112  * the call down. Since SIP does not support this at the moment go
8113  * ahead and terminate the call here to avoid an unnecessary timeout. */
8114  ast_debug(1, "AOC-E termination request received on %s. This is not yet supported on sip. Continue with hangup \n", ast_channel_name(p->owner));
8116  }
8117  break;
8118  case AST_AOC_D:
8119  case AST_AOC_E:
8120  if (ast_test_flag(&p->flags[2], SIP_PAGE3_SNOM_AOC)) {
8121  transmit_info_with_aoc(p, decoded);
8122  }
8123  break;
8124  case AST_AOC_S: /* S not supported yet */
8125  default:
8126  break;
8127  }
8128  ast_aoc_destroy_decoded(decoded);
8129  }
8130  break;
8131  case AST_CONTROL_UPDATE_RTP_PEER: /* Absorb this since it is handled by the bridge */
8132  break;
8133  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. */
8134  res = -1;
8135  break;
8136  case AST_CONTROL_PVT_CAUSE_CODE: /* these should be handled by the code in channel.c */
8138  case -1:
8139  res = -1;
8140  break;
8141  default:
8142  ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition);
8143  res = -1;
8144  break;
8145  }
8146  sip_pvt_unlock(p);
8147  return res;
8148 }
struct ast_format * ast_format_vp8
Built-in cached vp8 format.
Definition: format_cache.c:196
void ast_rtp_instance_change_source(struct ast_rtp_instance *instance)
Indicate a new source of audio has dropped in and the ssrc should change.
Definition: rtp_engine.c:2160
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define LOG_WARNING
Definition: logger.h:274
const ast_string_field mohinterpret
Definition: sip.h:1063
static void sip_alreadygone(struct sip_pvt *dialog)
Encapsulate setting of SIP_ALREADYGONE to be able to trace it with debugging.
Definition: chan_sip.c:3460
int ast_rtp_instance_write(struct ast_rtp_instance *instance, struct ast_frame *frame)
Send a frame out over RTP.
Definition: rtp_engine.c:568
void * ast_aoc_destroy_decoded(struct ast_aoc_decoded *decoded)
free an ast_aoc_decoded object
Definition: aoc.c:307
ast_channel_state
ast_channel states
Definition: channelstate.h:35
struct ast_flags flags[3]
Definition: sip.h:1075
#define SIP_RINGING
Definition: sip.h:259
unsigned short novideo
Definition: sip.h:1085
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7876
#define SIP_PAGE3_SNOM_AOC
Definition: sip.h:384
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
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.
Definition: chan_sip.c:12688
enum ast_format_cmp_res ast_format_cap_iscompatible_format(const struct ast_format_cap *cap, const struct ast_format *format)
Find if ast_format is within the capabilities of the ast_format_cap object.
Definition: format_cap.c:583
#define SIP_PROG_INBAND
Definition: sip.h:300
static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req)
Transmit response, no retransmits.
Definition: chan_sip.c:12655
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define SIP_PROG_INBAND_YES
Definition: sip.h:303
static int transmit_info_with_aoc(struct sip_pvt *p, struct ast_aoc_decoded *decoded)
Send SIP INFO advice of charge message.
Definition: chan_sip.c:16462
struct ast_aoc_decoded * ast_aoc_decode(struct ast_aoc_encoded *encoded, size_t size, struct ast_channel *chan)
decodes an encoded aoc payload.
Definition: aoc.c:449
struct sip_request initreq
Definition: sip.h:1151
static int initialize_udptl(struct sip_pvt *p)
Definition: chan_sip.c:7862
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.
Definition: chan_sip.c:7753
#define SIP_PAGE2_ALLOWOVERLAP
Definition: sip.h:337
#define SIP_PAGE2_ALLOWOVERLAP_YES
Definition: sip.h:339
#define LOG_ERROR
Definition: logger.h:285
#define SIP_PROG_INBAND_NEVER
Definition: sip.h:302
#define SIP_PAGE2_ALLOWOVERLAP_DTMF
Definition: sip.h:340
struct ast_rtp_instance * vrtp
Definition: sip.h:1175
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
Definition: channel.c:7866
int ast_aoc_get_termination_request(struct ast_aoc_decoded *decoded)
get whether or not the AST_AOC_REQUEST message as a termination request.
Definition: aoc.c:1079
int ast_softhangup_nolock(struct ast_channel *chan, int reason)
Softly hangup up a channel (no channel lock)
Definition: channel.c:2463
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
struct ast_channel * owner
Definition: sip.h:1138
static int transmit_provisional_response(struct sip_pvt *p, const char *msg, const struct sip_request *req, int with_sdp)
Definition: chan_sip.c:12867
static void update_connectedline(struct sip_pvt *p, const void *data, size_t datalen)
Notify peer that the connected line has changed.
Definition: chan_sip.c:15769
struct ast_rtp_instance * rtp
Definition: sip.h:1174
enum invitestates invitestate
Definition: sip.h:1007
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
const char * ast_channel_name(const struct ast_channel *chan)
#define TRUE
Definition: app_minivm.c:518
Data structure associated with a single frame of data.
Definition: aoc.h:64
Definition: aoc.h:66
enum ast_aoc_type ast_aoc_get_msg_type(struct ast_aoc_decoded *decoded)
get the message type, AOC-D, AOC-E, or AOC Request
Definition: aoc.c:892
enum ast_frame_type frametype
#define SIP_OUTGOING
Definition: sip.h:257
static void update_redirecting(struct sip_pvt *p, const void *data, size_t datalen)
Send a provisional response indicating that a call was redirected.
Definition: chan_sip.c:15755
void ast_rtp_instance_update_source(struct ast_rtp_instance *instance)
Indicate that the RTP marker bit should be set on an RTP stream.
Definition: rtp_engine.c:2151
#define SIP_PROGRESS_SENT
Definition: sip.h:260
Definition: aoc.h:65
static int transmit_info_with_vidupdate(struct sip_pvt *p)
Send SIP INFO with video update request.
Definition: chan_sip.c:16520

◆ sip_is_token()

static int sip_is_token ( const char *  str)
static

Definition at line 2449 of file chan_sip.c.

References ast_strlen_zero.

Referenced by add_diversion().

2450 {
2451  int is_token;
2452 
2453  if (ast_strlen_zero(str)) {
2454  /* An empty string is not a token. */
2455  return 0;
2456  }
2457 
2458  is_token = 1;
2459  do {
2460  if (!isalnum(*str)
2461  && !strchr("-.!%*_+`'~", *str)) {
2462  /* The character is not allowed in a token. */
2463  is_token = 0;
2464  break;
2465  }
2466  } while (*++str);
2467 
2468  return is_token;
2469 }
const char * str
Definition: app_jack.c:147
#define ast_strlen_zero(foo)
Definition: strings.h:52

◆ sip_is_xml_parsable()

static int sip_is_xml_parsable ( void  )
static

Definition at line 34232 of file chan_sip.c.

References FALSE, and TRUE.

Referenced by load_module().

34233 {
34234 #ifdef HAVE_LIBXML2
34235  return TRUE;
34236 #else
34237  return FALSE;
34238 #endif
34239 }
#define FALSE
Definition: app_minivm.c:521
#define TRUE
Definition: app_minivm.c:518

◆ sip_keepalive_all_peers()

static void sip_keepalive_all_peers ( void  )
static

Send a keepalive to all known peers.

Definition at line 34275 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_iterator_next, ao2_unlock, AST_SCHED_REPLACE_UNREF, sip_peer::keepalivesend, sip_ref_peer, sip_send_keepalive(), sip_unref_peer, and speerobjs.

Referenced by load_module(), and sip_do_reload().

34276 {
34277  struct ao2_iterator i;
34278  struct sip_peer *peer;
34279 
34280  if (!speerobjs) { /* No peers, just give up */
34281  return;
34282  }
34283 
34284  i = ao2_iterator_init(peers, 0);
34285  while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) {
34286  ao2_lock(peer);
34288  sip_unref_peer(_data, "removing poke peer ref"),
34289  sip_unref_peer(peer, "removing poke peer ref"),
34290  sip_ref_peer(peer, "adding poke peer ref"));
34291  ao2_unlock(peer);
34292  sip_unref_peer(peer, "toss iterator peer ptr");
34293  }
34295 }
static int speerobjs
Definition: chan_sip.c:879
int keepalivesend
Definition: sip.h:1361
Definition: sched.c:76
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_unlock(a)
Definition: astobj2.h:730
#define sip_ref_peer(peer, tag)
Definition: sip.h:1894
#define ao2_lock(a)
Definition: astobj2.h:718
static int sip_send_keepalive(const void *data)
Send keep alive packet to peer.
Definition: chan_sip.c:30469
#define ao2_t_iterator_next(iter, tag)
Definition: astobj2.h:1931
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
#define AST_SCHED_REPLACE_UNREF(id, sched, when, callback, data, unrefcall, addfailcall, refcall)
Definition: sched.h:150
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

◆ sip_monitor_instance_cmp_fn()

static int sip_monitor_instance_cmp_fn ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 2028 of file chan_sip.c.

References CMP_MATCH, CMP_STOP, and sip_monitor_instance::core_id.

Referenced by load_module().

2029 {
2030  struct sip_monitor_instance *monitor_instance1 = obj;
2031  struct sip_monitor_instance *monitor_instance2 = arg;
2032 
2033  return monitor_instance1->core_id == monitor_instance2->core_id ? CMP_MATCH | CMP_STOP : 0;
2034 }

◆ sip_monitor_instance_destructor()

static void sip_monitor_instance_destructor ( void *  data)
static

Definition at line 2036 of file chan_sip.c.

References ao2_t_ref, ast_string_field_free_memory, sip_epa_entry::body, dialog_unref, sip_pvt::expiry, FALSE, sip_monitor_instance::notify_uri, SIP_PUBLISH_REMOVE, sip_pvt_lock, sip_pvt_unlock, SIP_SUBSCRIBE, sip_monitor_instance::subscribe_uri, sip_monitor_instance::subscription_pvt, sip_monitor_instance::suspension_entry, transmit_invite(), and transmit_publish().

Referenced by sip_monitor_instance_init().

2037 {
2038  struct sip_monitor_instance *monitor_instance = data;
2039  if (monitor_instance->subscription_pvt) {
2040  sip_pvt_lock(monitor_instance->subscription_pvt);
2041  monitor_instance->subscription_pvt->expiry = 0;
2042  transmit_invite(monitor_instance->subscription_pvt, SIP_SUBSCRIBE, FALSE, 0, monitor_instance->subscribe_uri);
2043  sip_pvt_unlock(monitor_instance->subscription_pvt);
2044  dialog_unref(monitor_instance->subscription_pvt, "Unref monitor instance ref of subscription pvt");
2045  }
2046  if (monitor_instance->suspension_entry) {
2047  monitor_instance->suspension_entry->body[0] = '\0';
2048  transmit_publish(monitor_instance->suspension_entry, SIP_PUBLISH_REMOVE ,monitor_instance->notify_uri);
2049  ao2_t_ref(monitor_instance->suspension_entry, -1, "Decrementing suspension entry refcount in sip_monitor_instance_destructor");
2050  }
2051  ast_string_field_free_memory(monitor_instance);
2052 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
#define FALSE
Definition: app_minivm.c:521
static int transmit_publish(struct sip_epa_entry *epa_entry, enum sip_publish_type publish_type, const char *const explicit_uri)
Definition: chan_sip.c:14711
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.
Definition: chan_sip.c:14755
const ast_string_field notify_uri
Definition: sip.h:1819
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
Remove.
Definition: sip.h:1607
const ast_string_field subscribe_uri
Definition: sip.h:1819
int expiry
Definition: sip.h:1118
struct sip_epa_entry * suspension_entry
Definition: sip.h:1822
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
char body[SIPBUFSIZE]
Definition: sip.h:1668
struct sip_pvt * subscription_pvt
Definition: sip.h:1821
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:368

◆ sip_monitor_instance_hash_fn()

static int sip_monitor_instance_hash_fn ( const void *  obj,
const int  flags 
)
static

Definition at line 2022 of file chan_sip.c.

References sip_monitor_instance::core_id.

Referenced by load_module().

2023 {
2024  const struct sip_monitor_instance *monitor_instance = obj;
2025  return monitor_instance->core_id;
2026 }

◆ sip_monitor_instance_init()

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

Definition at line 2054 of file chan_sip.c.

References ao2_alloc, ao2_link, ao2_ref, ast_string_field_init, ast_string_field_set, sip_monitor_instance::core_id, NULL, and sip_monitor_instance_destructor().

Referenced by sip_handle_cc().

2055 {
2056  struct sip_monitor_instance *monitor_instance = ao2_alloc(sizeof(*monitor_instance), sip_monitor_instance_destructor);
2057 
2058  if (!monitor_instance) {
2059  return NULL;
2060  }
2061 
2062  if (ast_string_field_init(monitor_instance, 256)) {
2063  ao2_ref(monitor_instance, -1);
2064  return NULL;
2065  }
2066 
2067  ast_string_field_set(monitor_instance, subscribe_uri, subscribe_uri);
2068  ast_string_field_set(monitor_instance, peername, peername);
2069  ast_string_field_set(monitor_instance, device_name, device_name);
2070  monitor_instance->core_id = core_id;
2071  ao2_link(sip_monitor_instances, monitor_instance);
2072  return monitor_instance;
2073 }
const ast_string_field peername
Definition: sip.h:1819
struct ao2_container * sip_monitor_instances
Definition: chan_sip.c:1164
#define NULL
Definition: resample.c:96
const ast_string_field subscribe_uri
Definition: sip.h:1819
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:353
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
static void sip_monitor_instance_destructor(void *data)
Definition: chan_sip.c:2036
const ast_string_field device_name
Definition: sip.h:1819
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514
#define ao2_link(container, obj)
Definition: astobj2.h:1549

◆ sip_msg_send()

static int sip_msg_send ( const struct ast_msg msg,
const char *  to,
const char *  from 
)
static

Definition at line 27879 of file chan_sip.c.

References add_msg_header(), ast_callerid_parse(), ast_log, ast_msg_get_body(), ast_msg_var_iterator_destroy(), ast_msg_var_iterator_init(), ast_msg_var_iterator_next(), ast_msg_var_unref_current(), ast_set_flag, ast_sip_ouraddrfor(), ast_strdupa, ast_string_field_set, ast_strlen_zero, block_msg_header(), build_via(), sip_peer::cid_name, sip_peer::cid_num, create_addr(), DEFAULT_TRANS_TIMEOUT, dialog_unlink_all(), dialog_unref, extract_host_from_hostport(), sip_pvt::flags, get_in_brackets(), LOG_NOTICE, LOG_WARNING, sip_pvt::maxforwards, name, sip_peer::name, NULL, sip_pvt::ourip, parse_uri(), S_OR, sip_pvt::sa, sip_alloc, sip_find_peer(), SIP_MESSAGE, SIP_OUTGOING, SIP_PEDANTIC_DECODE, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), sip_unref_peer, transmit_message(), TRUE, and var.

Referenced by handle_request_message().

27880 {
27881  struct sip_pvt *pvt;
27882  int res;
27883  char *to_uri;
27884  char *to_host;
27885  char *to_user;
27886  const char *var;
27887  const char *val;
27888  struct ast_msg_var_iterator *iter;
27889  struct sip_peer *peer_ptr;
27890 
27891  if (!(pvt = sip_alloc(NULL, NULL, 0, SIP_MESSAGE, NULL, 0))) {
27892  return -1;
27893  }
27894 
27895  for (iter = ast_msg_var_iterator_init(msg);
27896  ast_msg_var_iterator_next(msg, iter, &var, &val);
27897  ast_msg_var_unref_current(iter)) {
27898  if (!strcasecmp(var, "Request-URI")) {
27899  ast_string_field_set(pvt, fullcontact, val);
27900  break;
27901  }
27902  }
27904 
27905  to_uri = ast_strdupa(to);
27906  to_uri = get_in_brackets(to_uri);
27907  parse_uri(to_uri, "sip:,sips:", &to_user, NULL, &to_host, NULL);
27908 
27909  if (ast_strlen_zero(to_host)) {
27910  ast_log(LOG_WARNING, "MESSAGE(to) is invalid for SIP - '%s'\n", to);
27911  dialog_unlink_all(pvt);
27912  dialog_unref(pvt, "MESSAGE(to) is invalid for SIP");
27913  return -1;
27914  }
27915 
27916  if (!ast_strlen_zero(from)) {
27917  if ((peer_ptr = sip_find_peer(from, NULL, 0, 1, 0, 0))) {
27918  ast_string_field_set(pvt, fromname, S_OR(peer_ptr->cid_name, peer_ptr->name));
27919  ast_string_field_set(pvt, fromuser, S_OR(peer_ptr->cid_num, peer_ptr->name));
27920  sip_unref_peer(peer_ptr, "sip_unref_peer, from sip_msg_send, sip_find_peer");
27921  } else if (strchr(from, '<')) { /* from is callerid-style */
27922  char *sender;
27923  char *name = NULL, *location = NULL, *user = NULL, *domain = NULL;
27924 
27925  sender = ast_strdupa(from);
27926  ast_callerid_parse(sender, &name, &location);
27927  if (ast_strlen_zero(location)) {
27928  /* This can occur if either
27929  * 1) A name-addr style From header does not close the angle brackets
27930  * properly.
27931  * 2) The From header is not in name-addr style and the content of the
27932  * From contains characters other than 0-9, *, #, or +.
27933  *
27934  * In both cases, ast_callerid_parse() should have parsed the From header
27935  * as a name rather than a number. So we just need to set the location
27936  * to what was parsed as a name, and set the name NULL since there was
27937  * no name present.
27938  */
27939  location = name;
27940  name = NULL;
27941  }
27942  ast_string_field_set(pvt, fromname, name);
27943  if (strchr(location, ':')) { /* Must be a URI */
27944  parse_uri(location, "sip:,sips:", &user, NULL, &domain, NULL);
27945  SIP_PEDANTIC_DECODE(user);
27946  SIP_PEDANTIC_DECODE(domain);
27947  extract_host_from_hostport(&domain);
27948  ast_string_field_set(pvt, fromuser, user);
27949  ast_string_field_set(pvt, fromdomain, domain);
27950  } else { /* Treat it as an exten/user */
27951  ast_string_field_set(pvt, fromuser, location);
27952  }
27953  } else { /* assume we just have the name, use defaults for the rest */
27954  ast_string_field_set(pvt, fromname, from);
27955  }
27956  }
27957 
27958  sip_pvt_lock(pvt);
27959 
27960  /* Look up the host to contact */
27961  if (create_addr(pvt, to_host, NULL, TRUE)) {
27962  sip_pvt_unlock(pvt);
27963  dialog_unlink_all(pvt);
27964  dialog_unref(pvt, "create_addr failed sending a MESSAGE");
27965  return -1;
27966  }
27967 
27968  if (!ast_strlen_zero(to_user)) {
27969  ast_string_field_set(pvt, username, to_user);
27970  }
27971  ast_sip_ouraddrfor(&pvt->sa, &pvt->ourip, pvt);
27972  build_via(pvt);
27973  ast_set_flag(&pvt->flags[0], SIP_OUTGOING);
27974 
27975  /* XXX Does pvt->expiry need to be set? */
27976 
27977  /* Save additional MESSAGE headers in case of authentication request. */
27978  for (iter = ast_msg_var_iterator_init(msg);
27979  ast_msg_var_iterator_next(msg, iter, &var, &val);
27980  ast_msg_var_unref_current(iter)) {
27981  if (!strcasecmp(var, "Max-Forwards")) {
27982  /* Decrement Max-Forwards for SIP loop prevention. */
27983  if (sscanf(val, "%30d", &pvt->maxforwards) != 1 || pvt->maxforwards < 1) {
27985  sip_pvt_unlock(pvt);
27986  dialog_unlink_all(pvt);
27987  dialog_unref(pvt, "MESSAGE(Max-Forwards) reached zero.");
27989  "MESSAGE(Max-Forwards) reached zero. MESSAGE not sent.\n");
27990  return -1;
27991  }
27992  --pvt->maxforwards;
27993  continue;
27994  }
27995  if (block_msg_header(var)) {
27996  /* Block addition of this header. */
27997  continue;
27998  }
27999  add_msg_header(pvt, var, val);
28000  }
28002 
28003  ast_string_field_set(pvt, msg_body, ast_msg_get_body(msg));
28004  res = transmit_message(pvt, 1, 0);
28005 
28006  sip_pvt_unlock(pvt);
28008  dialog_unref(pvt, "sent a MESSAGE");
28009 
28010  return res;
28011 }
char * get_in_brackets(char *tmp)
Pick out text in brackets from character string.
struct sip_peer * sip_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.
Definition: chan_sip.c:5851
struct ao2_iterator iter
Definition: message.c:640
static void build_via(struct sip_pvt *p)
Build a Via header for a request.
Definition: chan_sip.c:3847
Definition: ast_expr2.c:325
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define LOG_WARNING
Definition: logger.h:274
#define DEFAULT_TRANS_TIMEOUT
Definition: sip.h:107
int ast_msg_var_iterator_next(const struct ast_msg *msg, struct ast_msg_var_iterator *iter, const char **name, const char **value)
Get the next variable name and value that is set for sending outbound.
Definition: message.c:689
#define var
Definition: ast_expr2f.c:614
struct ast_sockaddr ourip
Definition: sip.h:1136
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?
Definition: chan_sip.c:3866
struct ast_flags flags[3]
Definition: sip.h:1075
#define NULL
Definition: resample.c:96
Domain data structure.
Definition: sip.h:888
const char * ast_msg_get_body(const struct ast_msg *msg)
Get the body of a message.
Definition: message.c:531
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
void ast_msg_var_iterator_destroy(struct ast_msg_var_iterator *iter)
Destroy a message variable iterator.
Definition: message.c:706
char name[80]
Definition: sip.h:1274
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
static void add_msg_header(struct sip_pvt *pvt, const char *hdr_name, const char *hdr_value)
Definition: chan_sip.c:12906
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 stor...
Definition: chan_sip.c:3367
struct ast_sockaddr sa
Definition: sip.h:1125
#define ast_log
Definition: astobj2.c:42
void ast_msg_var_unref_current(struct ast_msg_var_iterator *iter)
Unref a message var from inside an iterator loop.
Definition: message.c:700
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define sip_alloc(callid, addr, useglobal_nat, intended_method, req, logger_callid)
Definition: dialog.h:39
const ast_string_field username
Definition: sip.h:1306
int maxforwards
Definition: sip.h:1065
static void extract_host_from_hostport(char **hostport)
Terminate a host:port at the &#39;:&#39;.
Definition: chan_sip.c:17831
static int transmit_message(struct sip_pvt *p, int init, int auth)
Transmit with SIP MESSAGE method.
Definition: chan_sip.c:16351
#define SIP_PEDANTIC_DECODE(str)
Definition: chan_sip.c:813
const ast_string_field fromdomain
Definition: sip.h:1306
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
int parse_uri(char *uri, const char *scheme, char **ret_name, char **pass, char **hostport, char **transport)
parses a URI in its components.
const ast_string_field fullcontact
Definition: sip.h:1306
#define LOG_NOTICE
Definition: logger.h:263
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
static const char name[]
Definition: cdr_mysql.c:74
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
structure to hold users read from users.conf
const ast_string_field cid_name
Definition: sip.h:1306
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
#define TRUE
Definition: app_minivm.c:518
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 TR...
Definition: chan_sip.c:6317
const ast_string_field cid_num
Definition: sip.h:1306
const ast_string_field fromuser
Definition: sip.h:1306
#define SIP_OUTGOING
Definition: sip.h:257
void sip_scheddestroy(struct sip_pvt *p, int ms)
Schedule destruction of SIP dialog.
Definition: chan_sip.c:4549
int ast_callerid_parse(char *instr, char **name, char **location)
Destructively parse inbuf into name and location (or number)
Definition: callerid.c:1008
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514
static int block_msg_header(const char *header_name)
Definition: chan_sip.c:27849
struct ast_msg_var_iterator * ast_msg_var_iterator_init(const struct ast_msg *msg)
Create a new message variable iterator.
Definition: message.c:644

◆ sip_nat_mode()

static const char * sip_nat_mode ( const struct sip_pvt p)
static

Display SIP nat mode.

Definition at line 3643 of file chan_sip.c.

References ast_test_flag, sip_pvt::flags, and SIP_NAT_FORCE_RPORT.

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

3644 {
3645  return ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT) ? "NAT" : "no NAT";
3646 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define SIP_NAT_FORCE_RPORT
Definition: sip.h:283
struct ast_flags flags[3]
Definition: sip.h:1075

◆ sip_new()

static struct ast_channel* sip_new ( struct sip_pvt i,
int  state,
const char *  title,
const struct ast_assigned_ids assignedids,
const struct ast_channel requestor,
ast_callid  callid 
)
static

Initiate a call in the SIP channel.

Note
called from sip_request_call (calls from the pbx ) for outbound channels and from handle_request_invite for inbound channels
Precondition
i is locked
Returns
New ast_channel locked.

Definition at line 8161 of file chan_sip.c.

References sip_pvt::accountcode, sip_pvt::amaflags, ast_party_caller::ani, ao2_ref, append_history, AST_ADSI_UNAVAILABLE, ast_atomic_fetchadd_int(), ast_channel_adsicpe_set(), ast_channel_alloc, ast_channel_alloc_with_endpoint, ast_channel_amaflags_set(), ast_channel_caller(), ast_channel_callgroup_set(), ast_channel_callid_set(), ast_channel_cc_params_init(), ast_channel_context_set(), ast_channel_dialed(), ast_channel_exten_set(), ast_channel_flags(), ast_channel_lock, ast_channel_name(), ast_channel_named_callgroups_set(), ast_channel_named_pickupgroups_set(), ast_channel_nativeformats(), ast_channel_nativeformats_set(), ast_channel_pickupgroup_set(), ast_channel_priority_set(), ast_channel_redirecting(), ast_channel_rings_set(), ast_channel_set_fd(), ast_channel_set_rawreadformat(), ast_channel_set_rawwriteformat(), ast_channel_set_readformat(), ast_channel_set_writeformat(), ast_channel_stage_snapshot(), ast_channel_stage_snapshot_done(), ast_channel_tech_pvt_set(), ast_channel_tech_set(), ast_channel_unlock, ast_channel_zone_set(), ast_debug, ast_exists_extension(), AST_FLAG_DISABLE_DEVSTATE_CACHE, ast_format_cap_alloc, ast_format_cap_append, ast_format_cap_append_from_cap(), ast_format_cap_count(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_get_best_by_type(), ast_format_cap_get_format(), ast_format_cap_get_format_framing(), ast_format_cap_get_names(), ast_format_cap_has_type(), AST_FORMAT_CAP_NAMES_LEN, ast_format_cap_remove_by_type(), ast_format_get_name(), ast_get_encoded_str(), ast_get_indication_zone(), ast_hangup(), ast_jb_configure(), ast_log, AST_MEDIA_TYPE_AUDIO, AST_MEDIA_TYPE_TEXT, AST_MEDIA_TYPE_UNKNOWN, AST_MEDIA_TYPE_VIDEO, ast_module_ref, AST_RTP_DTMF_MODE_INBAND, AST_RTP_DTMF_MODE_RFC2833, ast_rtp_instance_destroy(), ast_rtp_instance_dtmf_mode_set(), ast_rtp_instance_fd(), ast_rtp_instance_set_read_format(), ast_rtp_instance_set_write_format(), ast_set_flag, AST_STATE_RING, ast_str_alloca, ast_strdup, ast_strdupa, ast_strlen_zero, ast_test_flag, ast_udptl_fd(), ast_uri_decode(), ast_uri_sip_user, sip_pvt::callgroup, sip_pvt::callid, sip_pvt::callingpres, sip_settings::caps, sip_pvt::caps, sip_pvt::cc_params, chan_idx, sip_pvt::chanvars, sip_pvt::cid_name, sip_pvt::cid_num, sip_pvt::cid_tag, sip_pvt::context, dialog_ref, sip_pvt::do_history, sip_pvt::domain, enable_dsp_detect(), sip_peer::endpoint, exten, sip_pvt::exten, sip_pvt::flags, ast_party_redirecting::from, sip_pvt::fromdomain, global_jbconf, ast_party_caller::id, sip_pvt::jointcaps, sip_pvt::language, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_party_id::name, sip_pvt::named_callgroups, sip_pvt::named_pickupgroups, ast_variable::next, NULL, ast_party_id::number, ast_party_dialed::number, sip_pvt::parkinglot, pbx_builtin_setvar_helper(), sip_pvt::pickupgroup, sip_pvt::prefcaps, ast_party_name::presentation, ast_party_number::presentation, sip_pvt::rdnis, sip_pvt::relatedpeer, sip_pvt::rtp, ast_module_info::self, SIP_AUDIO_RTCP_FD, SIP_AUDIO_RTP_FD, sip_cfg, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, SIP_DTMF_SHORTINFO, SIP_PAGE2_VIDEOSUPPORT_ALWAYS, SIP_PAGE3_RTCP_MUX, sip_pvt_lock, sip_pvt_unlock, sip_set_owner(), sip_tech_info, SIP_TEXT_RTP_FD, SIP_UDPTL_FD, SIP_VIDEO_RTCP_FD, SIP_VIDEO_RTP_FD, ast_party_number::str, ast_party_dialed::str, ast_party_id::tag, sip_pvt::tel_phone_context, tmp(), sip_pvt::trtp, sip_pvt::udptl, sip_pvt::uri, ast_party_number::valid, ast_variable::value, sip_pvt::vrtp, and sip_pvt::zone.

Referenced by handle_request_invite(), and sip_request_call().

8162 {
8163  struct ast_format_cap *caps;
8164  struct ast_channel *tmp;
8165  struct ast_variable *v = NULL;
8166  struct ast_format *fmt;
8167  struct ast_format_cap *what = NULL; /* SHALLOW COPY DO NOT DESTROY! */
8168  struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
8169  int needvideo = 0;
8170  int needtext = 0;
8171  char *exten;
8172 
8174  if (!caps) {
8175  return NULL;
8176  }
8177 
8178  {
8179  const char *my_name; /* pick a good name */
8180 
8181  if (title) {
8182  my_name = title;
8183  } else {
8184  my_name = ast_strdupa(i->fromdomain);
8185  }
8186 
8187  /* Don't hold a sip pvt lock while we allocate a channel */
8188  sip_pvt_unlock(i);
8189 
8190  if (i->relatedpeer && i->relatedpeer->endpoint) {
8191  tmp = ast_channel_alloc_with_endpoint(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, assignedids, requestor, i->amaflags, i->relatedpeer->endpoint, "SIP/%s-%08x", my_name, (unsigned)ast_atomic_fetchadd_int((int *)&chan_idx, +1));
8192  } else {
8193  tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, assignedids, requestor, i->amaflags, "SIP/%s-%08x", my_name, (unsigned)ast_atomic_fetchadd_int((int *)&chan_idx, +1));
8194  }
8195  }
8196  if (!tmp) {
8197  ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n");
8198  ao2_ref(caps, -1);
8199  sip_pvt_lock(i);
8200  return NULL;
8201  }
8202 
8204 
8205  /* If we sent in a callid, bind it to the channel. */
8206  if (callid) {
8207  ast_channel_callid_set(tmp, callid);
8208  }
8209 
8210  sip_pvt_lock(i);
8213 
8215 
8216  /* Select our native format based on codec preference until we receive
8217  something from another device to the contrary. */
8218  if (ast_format_cap_count(i->jointcaps)) { /* The joint capabilities of us and peer */
8219  what = i->jointcaps;
8220  } else if (ast_format_cap_count(i->caps)) { /* Our configured capability for this peer */
8221  what = i->caps;
8222  } else {
8223  what = sip_cfg.caps;
8224  }
8225 
8226  /* Set the native formats */
8228  /* Use only the preferred audio format, which is stored at the '0' index */
8229  fmt = ast_format_cap_get_best_by_type(what, AST_MEDIA_TYPE_AUDIO); /* get the best audio format */
8230  if (fmt) {
8231  int framing;
8232 
8233  ast_format_cap_remove_by_type(caps, AST_MEDIA_TYPE_AUDIO); /* remove only the other audio formats */
8234  framing = ast_format_cap_get_format_framing(what, fmt);
8235  ast_format_cap_append(caps, fmt, framing); /* add our best choice back */
8236  } else {
8237  /* If we don't have an audio format, try to get something */
8238  fmt = ast_format_cap_get_format(caps, 0);
8239  if (!fmt) {
8240  ast_log(LOG_WARNING, "No compatible formats could be found for %s\n", ast_channel_name(tmp));
8241  ao2_ref(caps, -1);
8243  ast_channel_unlock(tmp);
8244  ast_hangup(tmp);
8245  return NULL;
8246  }
8247  }
8248  ast_channel_nativeformats_set(tmp, caps);
8249  ao2_ref(caps, -1);
8250 
8251  ast_debug(3, "*** Our native formats are %s \n", ast_format_cap_get_names(ast_channel_nativeformats(tmp), &codec_buf));
8252  ast_debug(3, "*** Joint capabilities are %s \n", ast_format_cap_get_names(i->jointcaps, &codec_buf));
8253  ast_debug(3, "*** Our capabilities are %s \n", ast_format_cap_get_names(i->caps, &codec_buf));
8254  ast_debug(3, "*** AST_CODEC_CHOOSE formats are %s \n", ast_format_get_name(fmt));
8255  if (ast_format_cap_count(i->prefcaps)) {
8256  ast_debug(3, "*** Our preferred formats from the incoming channel are %s \n", ast_format_cap_get_names(i->prefcaps, &codec_buf));
8257  }
8258 
8259  /* If we have a prefcodec setting, we have an inbound channel that set a
8260  preferred format for this call. Otherwise, we check the jointcapability
8261  We also check for vrtp. If it's not there, we are not allowed do any video anyway.
8262  */
8263  if (i->vrtp) {
8265  needvideo = 1;
8266  else if (ast_format_cap_count(i->prefcaps))
8267  needvideo = ast_format_cap_has_type(i->prefcaps, AST_MEDIA_TYPE_VIDEO); /* Outbound call */
8268  else
8269  needvideo = ast_format_cap_has_type(i->jointcaps, AST_MEDIA_TYPE_VIDEO); /* Inbound call */
8270 
8271  if (!needvideo) {
8273  i->vrtp = NULL;
8274  }
8275  }
8276 
8277  if (i->trtp) {
8279  needtext = ast_format_cap_has_type(i->prefcaps, AST_MEDIA_TYPE_TEXT); /* Outbound call */
8280  else
8281  needtext = ast_format_cap_has_type(i->jointcaps, AST_MEDIA_TYPE_TEXT); /* Inbound call */
8282  }
8283 
8284  if (needvideo) {
8285  ast_debug(3, "This channel can handle video! HOLLYWOOD next!\n");
8286  } else {
8287  ast_debug(3, "This channel will not be able to handle video.\n");
8288  }
8289 
8290  enable_dsp_detect(i);
8291 
8292  if ((ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) ||
8293  (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) {
8294  if (i->rtp) {
8296  }
8297  } else if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) {
8298  if (i->rtp) {
8300  }
8301  }
8302 
8303  /* Set file descriptors for audio, video, and realtime text. Since
8304  * UDPTL is created as needed in the lifetime of a dialog, its file
8305  * descriptor is set in initialize_udptl */
8306  if (i->rtp) {
8308  if (ast_test_flag(&i->flags[2], SIP_PAGE3_RTCP_MUX)) {
8310  } else {
8312  }
8315  }
8316  if (needvideo && i->vrtp) {
8318  if (ast_test_flag(&i->flags[2], SIP_PAGE3_RTCP_MUX)) {
8320  } else {
8322  }
8323  }
8324  if (needtext && i->trtp) {
8326  }
8327  if (i->udptl) {
8329  }
8330 
8331  if (state == AST_STATE_RING) {
8332  ast_channel_rings_set(tmp, 1);
8333  }
8335 
8336  ast_channel_set_writeformat(tmp, fmt);
8338 
8339  ast_channel_set_readformat(tmp, fmt);
8341 
8342  ao2_ref(fmt, -1);
8343 
8344  ast_channel_tech_pvt_set(tmp, dialog_ref(i, "sip_new: set chan->tech_pvt to i"));
8345 
8348 
8351 
8354  if (!ast_strlen_zero(i->parkinglot)) {
8355  ast_channel_parkinglot_set(tmp, i->parkinglot);
8356  }
8357  if (!ast_strlen_zero(i->accountcode)) {
8358  ast_channel_accountcode_set(tmp, i->accountcode);
8359  }
8360  if (i->amaflags) {
8362  }
8363  if (!ast_strlen_zero(i->language)) {
8364  ast_channel_language_set(tmp, i->language);
8365  }
8366  if (!ast_strlen_zero(i->zone)) {
8367  struct ast_tone_zone *zone;
8368  if (!(zone = ast_get_indication_zone(i->zone))) {
8369  ast_log(LOG_ERROR, "Unknown country code '%s' for tonezone. Check indications.conf for available country codes.\n", i->zone);
8370  }
8371  ast_channel_zone_set(tmp, zone);
8372  }
8373  sip_set_owner(i, tmp);
8376  /*Since it is valid to have extensions in the dialplan that have unescaped characters in them
8377  * we should decode the uri before storing it in the channel, but leave it encoded in the sip_pvt
8378  * structure so that there aren't issues when forming URI's
8379  */
8380  exten = ast_strdupa(i->exten);
8381  sip_pvt_unlock(i);
8382  ast_channel_unlock(tmp);
8383  if (!ast_exists_extension(NULL, i->context, i->exten, 1, i->cid_num)) {
8385  }
8386  ast_channel_lock(tmp);
8387  sip_pvt_lock(i);
8388  ast_channel_exten_set(tmp, exten);
8389 
8390  /* Don't use ast_set_callerid() here because it will
8391  * generate an unnecessary NewCallerID event */
8392  if (!ast_strlen_zero(i->cid_num)) {
8393  ast_channel_caller(tmp)->ani.number.valid = 1;
8395  }
8396  if (!ast_strlen_zero(i->rdnis)) {
8399  }
8400 
8401  if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) {
8403  }
8404 
8405  ast_channel_priority_set(tmp, 1);
8406  if (!ast_strlen_zero(i->uri)) {
8407  pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri);
8408  }
8409  if (!ast_strlen_zero(i->domain)) {
8410  pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain);
8411  }
8413  pbx_builtin_setvar_helper(tmp, "SIPURIPHONECONTEXT", i->tel_phone_context);
8414  }
8415  if (!ast_strlen_zero(i->callid)) {
8416  pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid);
8417  }
8418  if (i->rtp) {
8420  }
8421 
8422  if (!i->relatedpeer) {
8424  }
8425  /* Set channel variables for this call from configuration */
8426  for (v = i->chanvars ; v ; v = v->next) {
8427  char valuebuf[1024];
8428  pbx_builtin_setvar_helper(tmp, v->name, ast_get_encoded_str(v->value, valuebuf, sizeof(valuebuf)));
8429  }
8430 
8431  if (i->do_history) {
8432  append_history(i, "NewChan", "Channel %s - from %s", ast_channel_name(tmp), i->callid);
8433  }
8434 
8436 
8437  return tmp;
8438 }
void ast_uri_decode(char *s, struct ast_flags spec)
Decode URI, URN, URL (overwrite string)
Definition: main/utils.c:616
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
struct ast_variable * next
#define SIP_PAGE3_RTCP_MUX
Definition: sip.h:394
int presentation
Q.931 encoded presentation-indicator encoded field.
Definition: channel.h:278
void ast_channel_pickupgroup_set(struct ast_channel *chan, ast_group_t value)
struct ast_cc_config_params * cc_params
Definition: sip.h:1218
#define ast_channel_lock(chan)
Definition: channel.h:2945
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
Main Channel structure associated with a channel.
struct ast_party_dialed::@246 number
Dialed/Called number.
char * str
Subscriber phone number (Malloced)
Definition: channel.h:292
const ast_string_field tel_phone_context
Definition: sip.h:1063
struct ast_format_cap * prefcaps
Definition: sip.h:1103
char * str
Subscriber phone number (Malloced)
Definition: channel.h:387
#define SIP_DTMF_INBAND
Definition: sip.h:277
ast_group_t callgroup
Definition: sip.h:1070
#define ast_channel_alloc_with_endpoint(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag, endpoint,...)
Definition: channel.h:1263
char * ast_get_encoded_str(const char *stream, char *result, size_t result_len)
Decode a stream of encoded control or extended ASCII characters.
Definition: main/app.c:3002
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
Definition: channel.h:296
int ast_rtp_instance_dtmf_mode_set(struct ast_rtp_instance *instance, enum ast_rtp_dtmf_mode dtmf_mode)
Set the DTMF mode that should be used.
Definition: rtp_engine.c:2123
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
struct ast_rtp_instance * trtp
Definition: sip.h:1176
#define ast_test_flag(p, flag)
Definition: utils.h:63
int amaflags
Definition: sip.h:1146
const ast_string_field parkinglot
Definition: sip.h:1063
struct sip_peer * relatedpeer
Definition: sip.h:1171
struct ast_party_name name
Subscriber name.
Definition: channel.h:341
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: channel.h:528
void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define LOG_WARNING
Definition: logger.h:274
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:326
struct ast_namedgroups * named_pickupgroups
Definition: sip.h:1073
static int tmp()
Definition: bt_open.c:389
Structure for variables, used for configurations and for channel variables.
#define SIP_DTMF_RFC2833
Definition: sip.h:276
static void enable_dsp_detect(struct sip_pvt *p)
Definition: chan_sip.c:4896
struct ast_namedgroups * named_callgroups
Definition: sip.h:1072
void ast_channel_callgroup_set(struct ast_channel *chan, ast_group_t value)
struct ast_format_cap * jointcaps
Definition: sip.h:1100
Definition of a media format.
Definition: format.c:43
void ast_channel_named_pickupgroups_set(struct ast_channel *chan, struct ast_namedgroups *value)
static void sip_set_owner(struct sip_pvt *p, struct ast_channel *chan)
Set the owning channel on the sip_pvt object.
Definition: chan_sip.c:9450
size_t ast_format_cap_count(const struct ast_format_cap *cap)
Get the number of formats present within the capabilities structure.
Definition: format_cap.c:395
struct ast_format * ast_format_cap_get_best_by_type(const struct ast_format_cap *cap, enum ast_media_type type)
Get the most preferred format for a particular media type.
Definition: format_cap.c:417
struct ast_flags flags[3]
Definition: sip.h:1075
const ast_string_field context
Definition: sip.h:1063
#define ast_str_alloca(init_len)
Definition: strings.h:800
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
void ast_channel_zone_set(struct ast_channel *chan, struct ast_tone_zone *value)
const ast_string_field language
Definition: sip.h:1063
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:755
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
static unsigned int chan_idx
Definition: chan_sip.c:818
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
char zone[MAX_TONEZONE_COUNTRY]
Definition: sip.h:1116
struct ast_party_id id
Caller party ID.
Definition: channel.h:421
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
struct ast_module * self
Definition: module.h:342
struct ast_party_id ani
Automatic Number Identification (ANI)
Definition: channel.h:428
void ast_channel_rings_set(struct ast_channel *chan, int value)
A set of tones for a given locale.
Definition: indications.h:74
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
struct ast_format_cap * caps
Definition: sip.h:1099
#define ao2_ref(o, delta)
Definition: astobj2.h:464
void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
const ast_string_field fromdomain
Definition: sip.h:1063
const ast_string_field exten
Definition: sip.h:1063
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define ast_format_cap_append(cap, format, framing)
Definition: format_cap.h:103
void ast_channel_amaflags_set(struct ast_channel *chan, enum ama_flags value)
#define SIP_PAGE2_VIDEOSUPPORT_ALWAYS
Definition: sip.h:366
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:4179
struct ast_udptl * udptl
Definition: sip.h:1115
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
int callingpres
Definition: sip.h:1117
void ast_channel_adsicpe_set(struct ast_channel *chan, enum ast_channel_adsicpe value)
int ast_channel_cc_params_init(struct ast_channel *chan, const struct ast_cc_config_params *base_params)
Set up datastore with CCSS parameters for a channel.
Definition: channel.c:10652
void ast_format_cap_remove_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Remove all formats matching a specific format type.
Definition: format_cap.c:525
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
const ast_string_field callid
Definition: sip.h:1063
#define LOG_ERROR
Definition: logger.h:285
#define SIP_DTMF_SHORTINFO
Definition: sip.h:280
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
struct ast_endpoint * endpoint
Definition: sip.h:1379
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
const ast_string_field cid_num
Definition: sip.h:1063
void ast_channel_named_callgroups_set(struct ast_channel *chan, struct ast_namedgroups *value)
const ast_string_field domain
Definition: sip.h:1063
struct ast_tone_zone * ast_get_indication_zone(const char *country)
locate ast_tone_zone
Definition: indications.c:433
struct ast_party_dialed * ast_channel_dialed(struct ast_channel *chan)
struct ast_rtp_instance * vrtp
Definition: sip.h:1175
static struct ast_jb_conf global_jbconf
Definition: chan_sip.c:688
unsigned int ast_format_cap_get_format_framing(const struct ast_format_cap *cap, const struct ast_format *format)
Get the framing for a format.
Definition: format_cap.c:443
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition: format_cap.c:736
int ast_rtp_instance_set_read_format(struct ast_rtp_instance *instance, struct ast_format *format)
Request that the underlying RTP engine provide audio frames in a specific format. ...
Definition: rtp_engine.c:2560
#define ast_channel_unlock(chan)
Definition: channel.h:2946
unsigned short do_history
Definition: sip.h:1078
#define dialog_ref(dialog, tag)
when we create or delete references, make sure to use these functions so we keep track of the refcoun...
Definition: dialog.h:32
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
int ast_udptl_fd(const struct ast_udptl *udptl)
Definition: udptl.c:730
int ast_rtp_instance_fd(struct ast_rtp_instance *instance, int rtcp)
Get the file descriptor for an RTP session (or RTCP)
Definition: rtp_engine.c:2192
struct ast_rtp_instance * rtp
Definition: sip.h:1174
int ast_rtp_instance_destroy(struct ast_rtp_instance *instance)
Destroy an RTP instance.
Definition: rtp_engine.c:458
struct ast_format_cap * caps
Global list of addresses dynamic peers are not allowed to use.
Definition: sip.h:787
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition: channel.c:2431
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
void ast_channel_callid_set(struct ast_channel *chan, ast_callid value)
void ast_jb_configure(struct ast_channel *chan, const struct ast_jb_conf *conf)
Configures a jitterbuffer on a channel.
Definition: abstract_jb.c:593
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
const ast_string_field cid_name
Definition: sip.h:1063
char * tag
User-set "tag".
Definition: channel.h:355
int ast_rtp_instance_set_write_format(struct ast_rtp_instance *instance, struct ast_format *format)
Tell underlying RTP engine that audio frames will be provided in a specific format.
Definition: rtp_engine.c:2574
#define SIP_DTMF
Definition: sip.h:275
void ast_channel_context_set(struct ast_channel *chan, const char *value)
const char * ast_channel_name(const struct ast_channel *chan)
const ast_string_field cid_tag
Definition: sip.h:1063
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406
const struct ast_flags ast_uri_sip_user
Definition: main/utils.c:575
const ast_string_field accountcode
Definition: sip.h:1063
#define SIP_DTMF_INFO
Definition: sip.h:278
int ast_format_cap_append_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type)
Append the formats of provided type in src to dst.
Definition: format_cap.c:269
struct ast_channel_tech sip_tech
Definition of this channel for PBX channel registration.
Definition: chan_sip.c:1573
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
struct ast_format * ast_format_cap_get_format(const struct ast_format_cap *cap, int position)
Get the format at a specific index.
Definition: format_cap.c:400
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...
Definition: chan_sip.c:1606
void ast_channel_priority_set(struct ast_channel *chan, int value)
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Definition: channel.h:1259
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:298
#define SIP_DTMF_AUTO
Definition: sip.h:279
struct ast_variable * chanvars
Definition: sip.h:1180
int ast_format_cap_has_type(const struct ast_format_cap *cap, enum ast_media_type type)
Find out if the capabilities structure has any formats of a specific type.
Definition: format_cap.c:615
const ast_string_field uri
Definition: sip.h:1063
ast_group_t pickupgroup
Definition: sip.h:1071
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:343
const ast_string_field rdnis
Definition: sip.h:1063
#define ast_module_ref(mod)
Hold a reference to the module.
Definition: module.h:443

◆ sip_notify_alloc()

static int sip_notify_alloc ( struct sip_pvt p)
static

Allocate SIP refer structure.

Definition at line 16388 of file chan_sip.c.

References ast_calloc, ast_str_create, sip_notify::content, and sip_pvt::notify.

Referenced by manager_sipnotify(), and sip_cli_notify().

16389 {
16390  p->notify = ast_calloc(1, sizeof(struct sip_notify));
16391  if (p->notify) {
16392  p->notify->content = ast_str_create(128);
16393  }
16394  return p->notify ? 1 : 0;
16395 }
struct ast_str * content
Definition: sip.h:953
Struct to handle custom SIP notify requests. Dynamically allocated when needed.
Definition: sip.h:951
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
struct sip_notify * notify
Definition: sip.h:1140
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ sip_offer_timer_expire()

static int sip_offer_timer_expire ( const void *  data)
static

Definition at line 1905 of file chan_sip.c.

References ast_cc_failed(), ast_cc_agent::core_id, ast_cc_agent::device_name, sip_cc_agent_pvt::offer_timer_id, and ast_cc_agent::private_data.

Referenced by sip_cc_agent_start_offer_timer().

1906 {
1907  struct ast_cc_agent *agent = (struct ast_cc_agent *) data;
1908  struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
1909 
1910  agent_pvt->offer_timer_id = -1;
1911 
1912  return ast_cc_failed(agent->core_id, "SIP agent %s's offer timer expired", agent->device_name);
1913 }
int ast_cc_failed(int core_id, const char *const debug,...)
Indicate failure has occurred.
Definition: ccss.c:3879
void * private_data
Definition: ccss.h:871
int offer_timer_id
Definition: sip.h:1779
Structure representing an agent.
unsigned int core_id
Definition: ccss.h:849
char device_name[1]
Definition: ccss.h:875

◆ sip_peer_hold()

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

References ast_atomic_fetchadd_int(), ast_channel_flags(), AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), AST_DEVSTATE_NOT_CACHABLE, AST_FLAG_DISABLE_DEVSTATE_CACHE, ast_test_flag, sip_peer::name, sip_peer::onhold, sip_pvt::owner, and sip_pvt::relatedpeer.

Referenced by change_hold_state(), and update_call_counter().

17512 {
17513  if (!p->relatedpeer) {
17514  return;
17515  }
17516 
17517  /* If they put someone on hold, increment the value... otherwise decrement it */
17518  ast_atomic_fetchadd_int(&p->relatedpeer->onhold, (hold ? +1 : -1));
17519 
17520  /* Request device state update */
17522  "SIP/%s", p->relatedpeer->name);
17523 
17524  return;
17525 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct sip_peer * relatedpeer
Definition: sip.h:1171
static void hold(struct ast_channel *chan)
Helper method to place a channel in a bridge on hold.
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:755
char name[80]
Definition: sip.h:1274
int ast_devstate_changed(enum ast_device_state state, enum ast_devstate_cache cachable, const char *fmt,...)
Tells Asterisk the State for Device is changed.
Definition: devicestate.c:510
struct ast_channel * owner
Definition: sip.h:1138
int onhold
Definition: sip.h:1327
struct ast_flags * ast_channel_flags(struct ast_channel *chan)

◆ sip_pickup()

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

References ast_channel_name(), ast_channel_ref, ast_channel_unref, ast_debug, ast_pthread_create_detached_background, NULL, and sip_pickup_thread().

Referenced by handle_request_invite().

25635 {
25636  pthread_t threadid;
25637 
25638  ast_channel_ref(chan);
25639 
25641  ast_debug(1, "Unable to start Group pickup thread on channel %s\n", ast_channel_name(chan));
25642  ast_channel_unref(chan);
25643  return -1;
25644  }
25645  ast_debug(1, "Started Group pickup thread on channel %s\n", ast_channel_name(chan));
25646  return 0;
25647 }
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
#define NULL
Definition: resample.c:96
#define ast_pthread_create_detached_background(a, b, c, d)
Definition: utils.h:572
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2970
const char * ast_channel_name(const struct ast_channel *chan)
static void * sip_pickup_thread(void *stuff)
SIP pickup support function Starts in a new thread, then pickup the call.
Definition: chan_sip.c:25616

◆ sip_pickup_thread()

static void * sip_pickup_thread ( void *  stuff)
static

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

Definition at line 25616 of file chan_sip.c.

References AST_CAUSE_CALL_REJECTED, AST_CAUSE_NORMAL_CLEARING, ast_channel_hangupcause_set(), ast_channel_unref, ast_hangup(), ast_pickup_call(), and NULL.

Referenced by sip_pickup().

25617 {
25618  struct ast_channel *chan;
25619  chan = stuff;
25620 
25622  if (ast_pickup_call(chan)) {
25624  }
25625  ast_hangup(chan);
25626  ast_channel_unref(chan);
25627  chan = NULL;
25628  return NULL;
25629 }
Main Channel structure associated with a channel.
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
#define NULL
Definition: resample.c:96
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
int ast_pickup_call(struct ast_channel *chan)
Pickup a call.
Definition: pickup.c:200
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
#define AST_CAUSE_CALL_REJECTED
Definition: causes.h:110

◆ sip_pidf_validate()

static int sip_pidf_validate ( struct sip_request req,
struct ast_xml_doc **  pidf_doc 
)
static

Makes sure that body is properly formatted PIDF.

Specifically, we check that the document has a "presence" element at the root and that within that, there is at least one "tuple" element that contains a "status" element.

XXX This function currently assumes a default namespace is used. Of course if you're not using a default namespace, you're probably a stupid jerk anyway.

Parameters
reqThe SIP request to check
[out]pidf_docThe validated PIDF doc.
Return values
FALSEThe XML was malformed or the basic PIDF structure was marred
TRUEThe PIDF document is of a valid format

Definition at line 28170 of file chan_sip.c.

References ast_log, ast_strlen_zero, ast_xml_close(), ast_xml_read_memory(), FALSE, get_content(), LOG_WARNING, pidf_validate_presence(), sip_get_header(), and TRUE.

Referenced by cc_esc_publish_handler().

28171 {
28172  struct ast_xml_doc *doc;
28173  const char *content_type = sip_get_header(req, "Content-Type");
28174  char *pidf_body;
28175  int res;
28176 
28177  if (ast_strlen_zero(content_type) || strcmp(content_type, "application/pidf+xml")) {
28178  ast_log(LOG_WARNING, "Content type is not PIDF\n");
28179  return FALSE;
28180  }
28181 
28182  if (!(pidf_body = get_content(req))) {
28183  ast_log(LOG_WARNING, "Unable to get PIDF body\n");
28184  return FALSE;
28185  }
28186 
28187  if (!(doc = ast_xml_read_memory(pidf_body, strlen(pidf_body)))) {
28188  ast_log(LOG_WARNING, "Unable to open XML PIDF document. Is it malformed?\n");
28189  return FALSE;
28190  }
28191 
28192  res = pidf_validate_presence(doc);
28193  if (res == TRUE) {
28194  *pidf_doc = doc;
28195  } else {
28196  ast_xml_close(doc);
28197  }
28198  return res;
28199 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
#define FALSE
Definition: app_minivm.c:521
#define LOG_WARNING
Definition: logger.h:274
static int pidf_validate_presence(struct ast_xml_doc *doc)
Definition: chan_sip.c:28084
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
void ast_xml_close(struct ast_xml_doc *doc)
Close an already open document and free the used structure.
Definition: xml.c:180
#define TRUE
Definition: app_minivm.c:518
static char * get_content(struct sip_request *req)
Get message body content.
Definition: chan_sip.c:8610
struct ast_xml_doc * ast_xml_read_memory(char *buffer, size_t size)
Open an XML document that resides in memory.
Definition: xml.c:161

◆ sip_pkt_dtor()

static void sip_pkt_dtor ( void *  vdoomed)
static

Definition at line 4260 of file chan_sip.c.

References ast_free, sip_pkt::data, dialog_unref, and sip_pkt::owner.

Referenced by __sip_reliable_xmit().

4261 {
4262  struct sip_pkt *pkt = (void *) vdoomed;
4263 
4264  if (pkt->owner) {
4265  dialog_unref(pkt->owner, "Retransmission packet is being destroyed");
4266  }
4267  ast_free(pkt->data);
4268 }
sip packet - raw format for outbound packets that are sent or scheduled for transmission Packets are ...
Definition: sip.h:1231
struct sip_pvt * owner
Definition: sip.h:1239
struct ast_str * data
Definition: sip.h:1246
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
#define ast_free(a)
Definition: astmm.h:182

◆ sip_poke_all_peers()

static void sip_poke_all_peers ( void  )
static

Send a poke to all known peers.

Definition at line 34242 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_iterator_next, ao2_unlock, AST_SCHED_REPLACE_UNREF, global_qualify_gap, global_qualify_peers, sip_peer::maxms, sip_peer::pokeexpire, sip_poke_peer_s(), sip_ref_peer, sip_unref_peer, and speerobjs.

Referenced by load_module(), and sip_do_reload().

34243 {
34244  int ms = 0, num = 0;
34245  struct ao2_iterator i;
34246  struct sip_peer *peer;
34247 
34248  if (!speerobjs) { /* No peers, just give up */
34249  return;
34250  }
34251 
34252  i = ao2_iterator_init(peers, 0);
34253  while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) {
34254  ao2_lock(peer);
34255  /* Don't schedule poking on a peer without qualify */
34256  if (peer->maxms) {
34257  if (num == global_qualify_peers) {
34258  ms += global_qualify_gap;
34259  num = 0;
34260  } else {
34261  num++;
34262  }
34264  sip_unref_peer(_data, "removing poke peer ref"),
34265  sip_unref_peer(peer, "removing poke peer ref"),
34266  sip_ref_peer(peer, "adding poke peer ref"));
34267  }
34268  ao2_unlock(peer);
34269  sip_unref_peer(peer, "toss iterator peer ptr");
34270  }
34272 }
static int speerobjs
Definition: chan_sip.c:879
int maxms
Definition: sip.h:1357
static int global_qualify_gap
Definition: chan_sip.c:852
Definition: sched.c:76
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_unlock(a)
Definition: astobj2.h:730
#define sip_ref_peer(peer, tag)
Definition: sip.h:1894
static int sip_poke_peer_s(const void *data)
Poke peer (send qualify to check if peer is alive and well)
Definition: chan_sip.c:16707
#define ao2_lock(a)
Definition: astobj2.h:718
#define ao2_t_iterator_next(iter, tag)
Definition: astobj2.h:1931
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
#define AST_SCHED_REPLACE_UNREF(id, sched, when, callback, data, unrefcall, addfailcall, refcall)
Definition: sched.h:150
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
int pokeexpire
Definition: sip.h:1355
static int global_qualify_peers
Definition: chan_sip.c:853

◆ sip_poke_noanswer()

static int sip_poke_noanswer ( const void *  data)
static

React to lack of answer to Qualify poke.

Definition at line 30523 of file chan_sip.c.

References ast_check_realtime(), AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_endpoint_blob_publish(), AST_ENDPOINT_OFFLINE, ast_endpoint_set_state(), ast_endpoint_state_type(), ast_json_pack(), ast_json_unref(), ast_log, AST_SCHED_REPLACE_UNREF, ast_update_realtime(), sip_peer::call, DEFAULT_FREQ_NOTOK, dialog_unlink_all(), dialog_unref, sip_peer::endpoint, FALSE, sip_peer::lastms, LOG_NOTICE, sip_peer::name, NULL, sip_settings::peer_rtupdate, sip_peer::pokeexpire, RAII_VAR, sip_settings::regextenonqualify, register_peer_exten(), SENTINEL, sip_cfg, sip_poke_peer_s(), sip_ref_peer, and sip_unref_peer.

Referenced by sip_poke_peer(), and sip_show_sched().

30524 {
30525  struct sip_peer *peer = (struct sip_peer *)data;
30526 
30527  peer->pokeexpire = -1;
30528 
30529  if (peer->lastms > -1) {
30530 
30531  ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms);
30532  if (sip_cfg.peer_rtupdate) {
30533  ast_update_realtime(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", "name", peer->name, "lastms", "-1", SENTINEL);
30534  }
30535 
30536  if (peer->endpoint) {
30537  RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
30539  blob = ast_json_pack("{s: s, s: s}",
30540  "peer_status", "Unreachable",
30541  "time", "-1");
30543  }
30544 
30545  if (sip_cfg.regextenonqualify) {
30546  register_peer_exten(peer, FALSE);
30547  }
30548  }
30549 
30550  if (peer->call) {
30551  dialog_unlink_all(peer->call);
30552  peer->call = dialog_unref(peer->call, "unref dialog peer->call");
30553  /* peer->call = sip_destroy(peer->call);*/
30554  }
30555 
30556  /* Don't send a devstate change if nothing changed. */
30557  if (peer->lastms > -1) {
30558  peer->lastms = -1;
30560  }
30561 
30562  /* Try again quickly */
30565  sip_unref_peer(_data, "removing poke peer ref"),
30566  sip_unref_peer(peer, "removing poke peer ref"),
30567  sip_ref_peer(peer, "adding poke peer ref"));
30568 
30569  /* Release the ref held by the running scheduler entry */
30570  sip_unref_peer(peer, "release peer poke noanswer ref");
30571 
30572  return 0;
30573 }
#define FALSE
Definition: app_minivm.c:521
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
int ast_check_realtime(const char *family)
Check if realtime engine is configured for family.
Definition: main/config.c:3363
Definition: sched.c:76
void ast_endpoint_set_state(struct ast_endpoint *endpoint, enum ast_endpoint_state state)
Updates the state of the given endpoint.
#define NULL
Definition: resample.c:96
#define sip_ref_peer(peer, tag)
Definition: sip.h:1894
int peer_rtupdate
Definition: sip.h:750
int ast_update_realtime(const char *family, const char *keyfield, const char *lookup,...) attribute_sentinel
Update realtime configuration.
Definition: main/config.c:3489
char name[80]
Definition: sip.h:1274
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 stor...
Definition: chan_sip.c:3367
#define ast_log
Definition: astobj2.c:42
int lastms
Definition: sip.h:1356
#define SENTINEL
Definition: compiler.h:87
int ast_devstate_changed(enum ast_device_state state, enum ast_devstate_cache cachable, const char *fmt,...)
Tells Asterisk the State for Device is changed.
Definition: devicestate.c:510
static int sip_poke_peer_s(const void *data)
Poke peer (send qualify to check if peer is alive and well)
Definition: chan_sip.c:16707
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
struct ast_endpoint * endpoint
Definition: sip.h:1379
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
struct stasis_message_type * ast_endpoint_state_type(void)
Message type for endpoint state changes.
static void register_peer_exten(struct sip_peer *peer, int onoff)
Automatically add peer extension to dial plan.
Definition: chan_sip.c:5238
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
#define LOG_NOTICE
Definition: logger.h:263
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
struct sip_pvt * call
Definition: sip.h:1354
void ast_endpoint_blob_publish(struct ast_endpoint *endpoint, struct stasis_message_type *type, struct ast_json *blob)
Creates and publishes a ast_endpoint_blob message.
#define AST_SCHED_REPLACE_UNREF(id, sched, when, callback, data, unrefcall, addfailcall, refcall)
Definition: sched.h:150
Abstract JSON element (object, array, string, int, ...).
int pokeexpire
Definition: sip.h:1355
#define DEFAULT_FREQ_NOTOK
Definition: chan_iax2.c:392
int regextenonqualify
Definition: sip.h:766

◆ sip_poke_peer()

static int sip_poke_peer ( struct sip_peer peer,
int  force 
)
static

Check availability of peer, also keep NAT open.

Note
This is done with 60 seconds between each ping, unless forced by cli or manager. If peer is unreachable, we check every 10th second by default.
Do not hold a pvt lock while calling this function. This function calls sip_alloc, which can cause a deadlock if another sip_pvt is held.

Definition at line 30583 of file chan_sip.c.

References __set_address_from_contact(), sip_peer::addr, 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_TRANSPORT_TLS, ast_tvnow(), build_via(), sip_peer::call, change_callid_pvt(), copy_socket_data(), dialog_ref, dialog_unlink_all(), dialog_unref, sip_pvt::flags, sip_peer::flags, sip_peer::fromuser, sip_peer::fullcontact, sip_peer::lastms, LOG_NOTICE, sip_peer::maxms, NULL, obproxy_get(), sip_pvt::ourip, sip_peer::path, sip_peer::pokeexpire, sip_peer::ps, sip_pvt::recv, ref_proxy(), sip_pvt::relatedpeer, sip_pvt::route, sip_pvt::sa, sip_alloc, SIP_FLAGS_TO_COPY, SIP_INVITE, SIP_OPTIONS, SIP_OUTGOING, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE3_FLAGS_TO_COPY, sip_poke_noanswer(), sip_ref_peer, sip_route_copy(), sip_route_empty, sip_route_first_uri(), sip_unref_peer, sipdebug, sip_pvt::socket, sip_peer::socket, sip_peer::tohost, transmit_invite(), sip_socket::type, sip_pvt::username, and XMIT_ERROR.

Referenced by _sip_qualify_peer(), parse_register_contact(), sip_poke_peer_now(), and sip_poke_peer_s().

30584 {
30585  struct sip_pvt *p;
30586  int xmitres = 0;
30587 
30588  if ((!peer->maxms && !force) || ast_sockaddr_isnull(&peer->addr)) {
30589  /* IF we have no IP, or this isn't to be monitored, return
30590  immediately after clearing things out */
30592  sip_unref_peer(peer, "removing poke peer ref"));
30593 
30594  peer->lastms = 0;
30595  if (peer->call) {
30596  peer->call = dialog_unref(peer->call, "unref dialog peer->call");
30597  }
30598  return 0;
30599  }
30600  if (peer->call) {
30601  if (sipdebug) {
30602  ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n");
30603  }
30604  dialog_unlink_all(peer->call);
30605  peer->call = dialog_unref(peer->call, "unref dialog peer->call");
30606  /* peer->call = sip_destroy(peer->call); */
30607  }
30608  if (!(p = sip_alloc(NULL, NULL, 0, SIP_OPTIONS, NULL, 0))) {
30609  return -1;
30610  }
30611  peer->call = dialog_ref(p, "copy sip alloc from p to peer->call");
30612 
30613  p->sa = peer->addr;
30614  p->recv = peer->addr;
30615  copy_socket_data(&p->socket, &peer->socket);
30616  ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
30617  ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
30618  ast_copy_flags(&p->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY);
30619  sip_route_copy(&p->route, &peer->path);
30620  if (!sip_route_empty(&p->route)) {
30621  /* Parse SIP URI of first route-set hop and use it as target address */
30623  }
30624 
30625  /* Get the outbound proxy information */
30626  ref_proxy(p, obproxy_get(p, peer));
30627 
30628  /* Send OPTIONs to peer's fullcontact */
30629  if (!ast_strlen_zero(peer->fullcontact)) {
30631  }
30632 
30633  if (!ast_strlen_zero(peer->fromuser)) {
30635  }
30636 
30637  if (!ast_strlen_zero(peer->tohost)) {
30638  ast_string_field_set(p, tohost, peer->tohost);
30639  } else {
30641  }
30642 
30643  /* Recalculate our side, and recalculate Call ID */
30644  ast_sip_ouraddrfor(&p->sa, &p->ourip, p);
30645  build_via(p);
30646 
30647  /* Change the dialog callid. */
30648  change_callid_pvt(p, NULL);
30649 
30651  sip_unref_peer(peer, "removing poke peer ref"));
30652 
30653  if (p->relatedpeer)
30654  p->relatedpeer = sip_unref_peer(p->relatedpeer,"unsetting the relatedpeer field in the dialog, before it is set to something else.");
30655  p->relatedpeer = sip_ref_peer(peer, "setting the relatedpeer field in the dialog");
30656  ast_set_flag(&p->flags[0], SIP_OUTGOING);
30657 #ifdef VOCAL_DATA_HACK
30658  ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username));
30659  xmitres = transmit_invite(p, SIP_INVITE, 0, 2, NULL); /* sinks the p refcount */
30660 #else
30661  xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2, NULL); /* sinks the p refcount */
30662 #endif
30663  peer->ps = ast_tvnow();
30664  if (xmitres == XMIT_ERROR) {
30665  /* Immediately unreachable, network problems */
30666  sip_poke_noanswer(sip_ref_peer(peer, "add ref for peerexpire (fake, for sip_poke_noanswer to remove)"));
30667  } else if (!force) {
30669  sip_unref_peer(_data, "removing poke peer ref"),
30670  sip_unref_peer(peer, "removing poke peer ref"),
30671  sip_ref_peer(peer, "adding poke peer ref"));
30672  }
30673  dialog_unref(p, "unref dialog at end of sip_poke_peer, obtained from sip_alloc, just before it goes out of scope");
30674  return 0;
30675 }
struct ast_sockaddr addr
Definition: sip.h:1352
int maxms
Definition: sip.h:1357
void sip_route_copy(struct sip_route *dst, const struct sip_route *src)
copy route-set
Definition: route.c:115
static void build_via(struct sip_pvt *p)
Build a Via header for a request.
Definition: chan_sip.c:3847
struct sip_peer * relatedpeer
Definition: sip.h:1171
#define ast_set_flag(p, flag)
Definition: utils.h:70
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.
Definition: chan_sip.c:14755
struct ast_sockaddr recv
Definition: sip.h:1135
struct sip_socket socket
Definition: sip.h:1066
const ast_string_field username
Definition: sip.h:1063
Definition: sched.c:76
struct ast_sockaddr ourip
Definition: sip.h:1136
#define AST_SCHED_DEL_UNREF(sched, id, refcall)
schedule task to get deleted and call unref function
Definition: sched.h:80
static int sip_poke_noanswer(const void *data)
React to lack of answer to Qualify poke.
Definition: chan_sip.c:30523
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
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?
Definition: chan_sip.c:3866
struct ast_flags flags[3]
Definition: sip.h:1075
struct sip_route path
Definition: sip.h:1372
#define ast_copy_flags(dest, src, flagz)
Definition: utils.h:84
#define NULL
Definition: resample.c:96
#define sip_ref_peer(peer, tag)
Definition: sip.h:1894
const ast_string_field fullcontact
Definition: sip.h:1063
const ast_string_field fromuser
Definition: sip.h:1063
#define ast_strlen_zero(foo)
Definition: strings.h:52
const ast_string_field tohost
Definition: sip.h:1306
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
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 stor...
Definition: chan_sip.c:3367
struct ast_sockaddr sa
Definition: sip.h:1125
#define ast_log
Definition: astobj2.c:42
int lastms
Definition: sip.h:1356
#define sip_route_empty(route)
Check if route has no URI&#39;s.
Definition: route.h:118
static struct sip_proxy * obproxy_get(struct sip_pvt *dialog, struct sip_peer *peer)
Get default outbound proxy or global proxy.
Definition: chan_sip.c:3549
#define sip_alloc(callid, addr, useglobal_nat, intended_method, req, logger_callid)
Definition: dialog.h:39
#define SIP_PAGE3_FLAGS_TO_COPY
Definition: sip.h:396
static void copy_socket_data(struct sip_socket *to_sock, const struct sip_socket *from_sock)
Definition: chan_sip.c:5952
#define SIP_PAGE2_FLAGS_TO_COPY
Definition: sip.h:375
struct sip_route route
Definition: sip.h:1139
#define XMIT_ERROR
Definition: sip.h:58
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
const ast_string_field fullcontact
Definition: sip.h:1306
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
static void change_callid_pvt(struct sip_pvt *pvt, const char *callid)
Definition: chan_sip.c:8860
#define LOG_NOTICE
Definition: logger.h:263
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
static int __set_address_from_contact(const char *fullcontact, struct ast_sockaddr *addr, int tcp)
Definition: chan_sip.c:16892
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
static char * ast_sockaddr_stringify_host_remote(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only, suitable for a URL (with brack...
Definition: netsock2.h:349
#define SIP_FLAGS_TO_COPY
Flags to copy from peer/user to dialog.
Definition: sip.h:313
#define dialog_ref(dialog, tag)
when we create or delete references, make sure to use these functions so we keep track of the refcoun...
Definition: dialog.h:32
static void ref_proxy(struct sip_pvt *pvt, struct sip_proxy *proxy)
maintain proper refcounts for a sip_pvt&#39;s outboundproxy
Definition: chan_sip.c:3293
struct sip_pvt * call
Definition: sip.h:1354
#define AST_SCHED_REPLACE_UNREF(id, sched, when, callback, data, unrefcall, addfailcall, refcall)
Definition: sched.h:150
struct timeval ps
Definition: sip.h:1359
enum ast_transport type
Definition: sip.h:798
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
struct ast_flags flags[3]
Definition: sip.h:1335
const ast_string_field tohost
Definition: sip.h:1063
const ast_string_field fromuser
Definition: sip.h:1306
#define SIP_OUTGOING
Definition: sip.h:257
struct sip_socket socket
Definition: sip.h:1307
const char * sip_route_first_uri(const struct sip_route *route)
Get the URI of the route&#39;s first hop.
Definition: route.c:199
int pokeexpire
Definition: sip.h:1355
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ sip_poke_peer_now()

static int sip_poke_peer_now ( const void *  data)
static

Definition at line 16731 of file chan_sip.c.

References sip_peer::pokeexpire, sip_poke_peer(), and sip_unref_peer.

Referenced by build_peer(), and sip_show_sched().

16732 {
16733  struct sip_peer *peer = (struct sip_peer *) data;
16734 
16735  peer->pokeexpire = -1;
16736  sip_poke_peer(peer, 0);
16737  sip_unref_peer(peer, "removing poke peer ref");
16738 
16739  return 0;
16740 }
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
static int sip_poke_peer(struct sip_peer *peer, int force)
Check availability of peer, also keep NAT open.
Definition: chan_sip.c:30583
int pokeexpire
Definition: sip.h:1355

◆ sip_poke_peer_s()

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

References ao2_find, sip_peer::name, OBJ_POINTER, sip_peer::pokeexpire, sip_poke_peer(), and sip_unref_peer.

Referenced by handle_response_peerpoke(), reg_source_db(), sip_poke_all_peers(), sip_poke_noanswer(), and sip_show_sched().

16708 {
16709  struct sip_peer *peer = (struct sip_peer *)data;
16710  struct sip_peer *foundpeer;
16711 
16712  peer->pokeexpire = -1;
16713 
16714  foundpeer = ao2_find(peers, peer, OBJ_POINTER);
16715  if (!foundpeer) {
16716  sip_unref_peer(peer, "removing poke peer ref");
16717  return 0;
16718  } else if (foundpeer->name != peer->name) {
16719  sip_unref_peer(foundpeer, "removing above peer ref");
16720  sip_unref_peer(peer, "removing poke peer ref");
16721  return 0;
16722  }
16723 
16724  sip_unref_peer(foundpeer, "removing above peer ref");
16725  sip_poke_peer(peer, 0);
16726  sip_unref_peer(peer, "removing poke peer ref");
16727 
16728  return 0;
16729 }
#define OBJ_POINTER
Definition: astobj2.h:1154
char name[80]
Definition: sip.h:1274
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
static int sip_poke_peer(struct sip_peer *peer, int force)
Check availability of peer, also keep NAT open.
Definition: chan_sip.c:30583
int pokeexpire
Definition: sip.h:1355

◆ sip_prepare_socket()

static int sip_prepare_socket ( struct sip_pvt p)
static
Todo:
Get socket for dialog, prepare if needed, and return file handle
Todo:
Check this... This might be wrong, depending on the proxy configuration If proxy is in "force" mode its correct.

Definition at line 29578 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_iostream_get_fd(), ast_pthread_create_detached_background, ast_set_qos(), ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_set_port, ast_strdup, ast_strlen_zero, ast_tcptls_client_create(), ast_tcptls_close_session_file(), AST_TRANSPORT_TCP, AST_TRANSPORT_TLS, AST_TRANSPORT_UDP, AST_TRANSPORT_WS, AST_TRANSPORT_WSS, ast_websocket_fd(), ast_tls_config::cafile, ast_tls_config::capath, ast_tls_config::certfile, ast_tls_config::cipher, sip_socket::fd, global_cos_sip, global_tos_sip, ast_tcptls_session_args::hostname, ast_tcptls_session_args::local_address, name, ast_tcptls_session_args::name, NULL, sip_pvt::outboundproxy, 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(), sipsock, sip_pvt::socket, ast_tcptls_session_instance::stream, sip_socket::tcptls_session, ast_tcptls_session_args::tls_cfg, sip_pvt::tohost, sip_proxy::transport, sip_socket::type, and sip_socket::ws_session.

Referenced by __sip_xmit().

29579 {
29580  struct sip_socket *s = &p->socket;
29581  static const char name[] = "SIP socket";
29582  struct sip_threadinfo *th = NULL;
29583  struct ast_tcptls_session_instance *tcptls_session;
29584  struct ast_tcptls_session_args *ca;
29585  struct ast_sockaddr sa_tmp;
29586  pthread_t launched;
29587 
29588  /* check to see if a socket is already active */
29589  if ((s->fd != -1) && (s->type == AST_TRANSPORT_UDP)) {
29590  return s->fd;
29591  }
29592  if ((s->type & (AST_TRANSPORT_TCP | AST_TRANSPORT_TLS)) &&
29593  s->tcptls_session && s->tcptls_session->stream) {
29595  }
29596  if ((s->type & (AST_TRANSPORT_WS | AST_TRANSPORT_WSS))) {
29597  return s->ws_session ? ast_websocket_fd(s->ws_session) : -1;
29598  }
29599 
29600  /*! \todo Check this... This might be wrong, depending on the proxy configuration
29601  If proxy is in "force" mode its correct.
29602  */
29603  if (p->outboundproxy && p->outboundproxy->transport) {
29604  s->type = p->outboundproxy->transport;
29605  }
29606 
29607  if (s->type == AST_TRANSPORT_UDP) {
29608  s->fd = sipsock;
29609  return s->fd;
29610  }
29611 
29612  /* At this point we are dealing with a TCP/TLS connection
29613  * 1. We need to check to see if a connection thread exists
29614  * for this address, if so use that.
29615  * 2. If a thread does not exist for this address, but the tcptls_session
29616  * exists on the socket, the connection was closed.
29617  * 3. If no tcptls_session thread exists for the address, and no tcptls_session
29618  * already exists on the socket, create a new one and launch a new thread.
29619  */
29620 
29621  /* 1. check for existing threads */
29622  ast_sockaddr_copy(&sa_tmp, sip_real_dst(p));
29623  if ((tcptls_session = sip_tcp_locate(&sa_tmp))) {
29624  s->fd = ast_iostream_get_fd(tcptls_session->stream);
29625  if (s->tcptls_session) {
29626  ao2_ref(s->tcptls_session, -1);
29627  s->tcptls_session = NULL;
29628  }
29629  s->tcptls_session = tcptls_session;
29630  return s->fd;
29631  /* 2. Thread not found, if tcptls_session already exists, it once had a thread and is now terminated */
29632  } else if (s->tcptls_session) {
29633  return s->fd; /* XXX whether reconnection is ever necessary here needs to be investigated further */
29634  }
29635 
29636  /* 3. Create a new TCP/TLS client connection */
29637  /* create new session arguments for the client connection */
29638  if (!(ca = ao2_alloc(sizeof(*ca), sip_tcptls_client_args_destructor)) ||
29639  !(ca->name = ast_strdup(name))) {
29640  goto create_tcptls_session_fail;
29641  }
29642  ca->accept_fd = -1;
29644  /* if type is TLS, we need to create a tls cfg for this session arg */
29645  if (s->type == AST_TRANSPORT_TLS) {
29646  if (!(ca->tls_cfg = ast_calloc(1, sizeof(*ca->tls_cfg)))) {
29647  goto create_tcptls_session_fail;
29648  }
29649  memcpy(ca->tls_cfg, &default_tls_cfg, sizeof(*ca->tls_cfg));
29650 
29656 
29657  goto create_tcptls_session_fail;
29658  }
29659 
29660  /* this host is used as the common name in ssl/tls */
29661  if (!ast_strlen_zero(p->tohost)) {
29662  ast_copy_string(ca->hostname, p->tohost, sizeof(ca->hostname));
29663  }
29664  }
29665 
29666  /* If a bind address has been specified, use it */
29669  }
29672  }
29673  /* Reset tcp source port to zero to let system pick a random one */
29674  if (!ast_sockaddr_isnull(&ca->local_address)) {
29676  }
29677  /* Create a client connection for address, this does not start the connection, just sets it up. */
29678  if (!(s->tcptls_session = ast_tcptls_client_create(ca))) {
29679  goto create_tcptls_session_fail;
29680  }
29681 
29683 
29684  /* client connections need to have the sip_threadinfo object created before
29685  * the thread is detached. This ensures the alert_pipe is up before it will
29686  * be used. Note that this function links the new threadinfo object into the
29687  * threadt container. */
29688  if (!(th = sip_threadinfo_create(s->tcptls_session, s->type))) {
29689  goto create_tcptls_session_fail;
29690  }
29691 
29692  /* Give the new thread a reference to the tcptls_session */
29693  ao2_ref(s->tcptls_session, +1);
29694 
29696  ast_debug(1, "Unable to launch '%s'.", ca->name);
29697  ao2_ref(s->tcptls_session, -1); /* take away the thread ref we just gave it */
29698  goto create_tcptls_session_fail;
29699  }
29700 
29702 
29703  return s->fd;
29704 
29705 create_tcptls_session_fail:
29706  if (ca) {
29707  ao2_t_ref(ca, -1, "failed to create client, getting rid of client tcptls_session arguments");
29708  }
29709  if (s->tcptls_session) {
29711  s->fd = -1;
29712  ao2_ref(s->tcptls_session, -1);
29713  s->tcptls_session = NULL;
29714  }
29715  if (th) {
29716  ao2_t_unlink(threadt, th, "Removing tcptls thread info object, thread failed to open");
29717  }
29718 
29719  return -1;
29720 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
static struct ao2_container * threadt
The table of TCP threads.
Definition: chan_sip.c:1049
static struct ast_tcptls_session_args sip_tls_desc
The TCP/TLS server definition.
Definition: chan_sip.c:2394
char * pvtfile
Definition: tcptls.h:90
static struct ast_tls_config default_tls_cfg
Default TLS connection configuration.
Definition: chan_sip.c:2377
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:171
struct sip_socket socket
Definition: sip.h:1066
static struct ast_tcptls_session_args sip_tcp_desc
The TCP server definition.
Definition: chan_sip.c:2383
#define ao2_t_unlink(container, obj, tag)
Remove an object from a container.
Definition: astobj2.h:1596
int ast_iostream_get_fd(struct ast_iostream *stream)
Get an iostream&#39;s file descriptor.
Definition: iostream.c:84
arguments for the accepting thread
Definition: tcptls.h:129
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
int fd
Definition: sip.h:799
Socket address structure.
Definition: netsock2.h:97
#define ast_pthread_create_detached_background(a, b, c, d)
Definition: utils.h:572
#define ast_strlen_zero(foo)
Definition: strings.h:52
int AST_OPTIONAL_API_NAME() ast_websocket_fd(struct ast_websocket *session)
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
struct ast_websocket * ws_session
Definition: sip.h:802
Definition of a thread that handles a socket.
Definition: sip.h:1441
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct ast_sockaddr remote_address
Definition: tcptls.h:132
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static const struct ast_sockaddr * sip_real_dst(const struct sip_pvt *p)
The real destination address for a write.
Definition: chan_sip.c:3633
struct ast_tcptls_session_instance * tcptls_session
Definition: sip.h:801
describes a server instance
Definition: tcptls.h:149
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:537
int ast_set_qos(int sockfd, int tos, int cos, const char *desc)
Set type of service.
Definition: netsock2.c:621
static void sip_tcptls_client_args_destructor(void *obj)
Definition: chan_sip.c:2545
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
char * cafile
Definition: tcptls.h:92
static int sipsock
Main socket for UDP SIP communication.
Definition: chan_sip.c:1104
static const char name[]
Definition: cdr_mysql.c:74
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
static struct ast_tcptls_session_instance * sip_tcp_locate(struct ast_sockaddr *s)
Find thread for TCP/TLS session (based on IP/Port.
Definition: chan_sip.c:29540
char * certfile
Definition: tcptls.h:89
const char * name
Definition: tcptls.h:142
struct ast_iostream * stream
Definition: tcptls.h:160
static void * sip_tcp_worker_fn(void *)
SIP TCP connection handler.
Definition: chan_sip.c:2670
enum ast_transport type
Definition: sip.h:798
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
void ast_tcptls_close_session_file(struct ast_tcptls_session_instance *tcptls_session)
Closes a tcptls session instance&#39;s file and/or file descriptor. The tcptls_session will be set to NUL...
Definition: tcptls.c:839
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.
Definition: chan_sip.c:2584
struct ast_tcptls_session_instance * ast_tcptls_client_create(struct ast_tcptls_session_args *desc)
Definition: tcptls.c:615
const ast_string_field tohost
Definition: sip.h:1063
char * capath
Definition: tcptls.h:93
enum ast_transport transport
Definition: sip.h:726
struct ast_tls_config * tls_cfg
Definition: tcptls.h:134
struct ast_sockaddr local_address
Definition: tcptls.h:130
static unsigned int global_cos_sip
Definition: chan_sip.c:837
static unsigned int global_tos_sip
Definition: chan_sip.c:833
The SIP socket definition.
Definition: sip.h:797
char * cipher
Definition: tcptls.h:91
struct sip_proxy * outboundproxy
Definition: sip.h:1112
char hostname[MAXHOSTNAMELEN]
Definition: tcptls.h:133

◆ sip_prune_realtime()

static char * sip_prune_realtime ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Remove temporary realtime objects from memory (CLI)

Todo:
XXXX Propably needs an overhaul after removal of the devices

Definition at line 20753 of file chan_sip.c.

References sip_peer::addr, 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, sip_peer::flags, ast_cli_args::n, name, sip_peer::name, NULL, OBJ_POINTER, OBJ_UNLINK, ast_cli_args::pos, SIP_PAGE2_RTCACHEFRIENDS, sip_unref_peer, sip_peer::the_mark, tmp(), TRUE, unlink_marked_peers_from_tables(), ast_cli_entry::usage, and ast_cli_args::word.

20754 {
20755  struct sip_peer *peer, *pi;
20756  int prunepeer = FALSE;
20757  int multi = FALSE;
20758  const char *name = NULL;
20759  regex_t regexbuf;
20760  int havepattern = 0;
20761  struct ao2_iterator i;
20762  static const char * const choices[] = { "all", "like", NULL };
20763  char *cmplt;
20764 
20765  if (cmd == CLI_INIT) {
20766  e->command = "sip prune realtime [peer|all]";
20767  e->usage =
20768  "Usage: sip prune realtime [peer [<name>|all|like <pattern>]|all]\n"
20769  " Prunes object(s) from the cache.\n"
20770  " Optional regular expression pattern is used to filter the objects.\n";
20771  return NULL;
20772  } else if (cmd == CLI_GENERATE) {
20773  if (a->pos == 4 && !strcasecmp(a->argv[3], "peer")) {
20774  cmplt = ast_cli_complete(a->word, choices, a->n);
20775  if (!cmplt)
20776  cmplt = complete_sip_peer(a->word, a->n - sizeof(choices), SIP_PAGE2_RTCACHEFRIENDS);
20777  return cmplt;
20778  }
20779  if (a->pos == 5 && !strcasecmp(a->argv[4], "like"))
20781  return NULL;
20782  }
20783  switch (a->argc) {
20784  case 4:
20785  name = a->argv[3];
20786  /* we accept a name in position 3, but keywords are not good. */
20787  if (!strcasecmp(name, "peer") || !strcasecmp(name, "like"))
20788  return CLI_SHOWUSAGE;
20789  prunepeer = TRUE;
20790  if (!strcasecmp(name, "all")) {
20791  multi = TRUE;
20792  name = NULL;
20793  }
20794  /* else a single name, already set */
20795  break;
20796  case 5:
20797  /* sip prune realtime {peer|like} name */
20798  name = a->argv[4];
20799  if (!strcasecmp(a->argv[3], "peer"))
20800  prunepeer = TRUE;
20801  else if (!strcasecmp(a->argv[3], "like")) {
20802  prunepeer = TRUE;
20803  multi = TRUE;
20804  } else
20805  return CLI_SHOWUSAGE;
20806  if (!strcasecmp(name, "like"))
20807  return CLI_SHOWUSAGE;
20808  if (!multi && !strcasecmp(name, "all")) {
20809  multi = TRUE;
20810  name = NULL;
20811  }
20812  break;
20813  case 6:
20814  name = a->argv[5];
20815  multi = TRUE;
20816  /* sip prune realtime {peer} like name */
20817  if (strcasecmp(a->argv[4], "like"))
20818  return CLI_SHOWUSAGE;
20819  if (!strcasecmp(a->argv[3], "peer")) {
20820  prunepeer = TRUE;
20821  } else
20822  return CLI_SHOWUSAGE;
20823  break;
20824  default:
20825  return CLI_SHOWUSAGE;
20826  }
20827 
20828  if (multi && name) {
20829  if (regcomp(&regexbuf, name, REG_EXTENDED | REG_NOSUB)) {
20830  return CLI_SHOWUSAGE;
20831  }
20832  havepattern = 1;
20833  }
20834 
20835  if (multi) {
20836  if (prunepeer) {
20837  int pruned = 0;
20838 
20839  i = ao2_iterator_init(peers, 0);
20840  while ((pi = ao2_t_iterator_next(&i, "iterate thru peers table"))) {
20841  ao2_lock(pi);
20842  if (name && regexec(&regexbuf, pi->name, 0, NULL, 0)) {
20843  ao2_unlock(pi);
20844  sip_unref_peer(pi, "toss iterator peer ptr before continue");
20845  continue;
20846  };
20848  pi->the_mark = 1;
20849  pruned++;
20850  }
20851  ao2_unlock(pi);
20852  sip_unref_peer(pi, "toss iterator peer ptr");
20853  }
20855  if (pruned) {
20857  ast_cli(a->fd, "%d peers pruned.\n", pruned);
20858  } else
20859  ast_cli(a->fd, "No peers found to prune.\n");
20860  }
20861  } else {
20862  if (prunepeer) {
20863  struct sip_peer tmp;
20864  ast_copy_string(tmp.name, name, sizeof(tmp.name));
20865  if ((peer = ao2_t_find(peers, &tmp, OBJ_POINTER | OBJ_UNLINK, "finding to unlink from peers"))) {
20866  if (!ast_sockaddr_isnull(&peer->addr)) {
20867  ao2_t_unlink(peers_by_ip, peer, "unlinking peer from peers_by_ip also");
20868  }
20869  if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
20870  ast_cli(a->fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name);
20871  /* put it back! */
20872  ao2_t_link(peers, peer, "link peer into peer table");
20873  if (!ast_sockaddr_isnull(&peer->addr)) {
20874  ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table");
20875  }
20876  } else
20877  ast_cli(a->fd, "Peer '%s' pruned.\n", name);
20878  sip_unref_peer(peer, "sip_prune_realtime: sip_unref_peer: tossing temp peer ptr");
20879  } else
20880  ast_cli(a->fd, "Peer '%s' not found.\n", name);
20881  }
20882  }
20883 
20884  if (havepattern) {
20885  regfree(&regexbuf);
20886  }
20887 
20888  return CLI_SUCCESS;
20889 }
struct ast_sockaddr addr
Definition: sip.h:1352
#define FALSE
Definition: app_minivm.c:521
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define OBJ_POINTER
Definition: astobj2.h:1154
const int argc
Definition: cli.h:160
static int tmp()
Definition: bt_open.c:389
Definition: cli.h:152
#define ao2_t_link(container, obj, tag)
Add an object to a container.
Definition: astobj2.h:1547
#define ao2_t_unlink(container, obj, tag)
Remove an object from a container.
Definition: astobj2.h:1596
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
char name[80]
Definition: sip.h:1274
static struct ao2_container * peers_by_ip
Definition: chan_sip.c:1053
char * ast_cli_complete(const char *word, const char *const choices[], int pos)
Definition: main/cli.c:1811
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
const int fd
Definition: cli.h:159
const int n
Definition: cli.h:165
#define ao2_lock(a)
Definition: astobj2.h:718
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define ao2_t_iterator_next(iter, tag)
Definition: astobj2.h:1931
unsigned short the_mark
Definition: sip.h:1316
#define SIP_PAGE2_RTCACHEFRIENDS
Definition: sip.h:323
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
static const char name[]
Definition: cdr_mysql.c:74
char * command
Definition: cli.h:186
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
const char * word
Definition: cli.h:163
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
struct ast_flags flags[3]
Definition: sip.h:1335
const int pos
Definition: cli.h:164
#define TRUE
Definition: app_minivm.c:518
#define ao2_t_find(container, arg, flags, tag)
Definition: astobj2.h:1754
static char * complete_sip_peer(const char *word, int state, int flags2)
Do completion on peer name.
Definition: chan_sip.c:22282
static void unlink_marked_peers_from_tables(void)
Definition: chan_sip.c:3272
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

◆ sip_publish_registry()

static void sip_publish_registry ( const char *  username,
const char *  domain,
const char *  status 
)
static

Definition at line 15852 of file chan_sip.c.

References ast_system_publish_registry(), and NULL.

Referenced by handle_response_register(), and sip_reg_timeout().

15853 {
15855 }
#define NULL
Definition: resample.c:96
Domain data structure.
Definition: sip.h:888
const ast_string_field username
Definition: sip.h:1306
void ast_system_publish_registry(const char *channeltype, const char *username, const char *domain, const char *status, const char *cause)
Publish a channel driver outgoing registration message.
jack_status_t status
Definition: app_jack.c:146

◆ sip_pvt_callid_set()

static void sip_pvt_callid_set ( struct sip_pvt pvt,
ast_callid  callid 
)
static

Definition at line 8933 of file chan_sip.c.

References sip_pvt::logger_callid.

Referenced by __sip_alloc().

8934 {
8935  pvt->logger_callid = callid;
8936 }
ast_callid logger_callid
Definition: sip.h:1008

◆ sip_pvt_dtor()

static void sip_pvt_dtor ( void *  vdoomed)
static

ao2 destructor for SIP dialog structure

Definition at line 6673 of file chan_sip.c.

References ao2_cleanup, ao2_ref, ao2_t_ref, ao2_t_replace, ast_cc_config_params_destroy(), ast_channel_lock, ast_channel_name(), ast_channel_softhangup_internal_flag_add(), ast_channel_tech_pvt_set(), ast_channel_unlock, ast_debug, ast_free, ast_free_acl_list(), AST_LIST_REMOVE_HEAD, ast_rtp_dtls_cfg_free(), ast_sdp_srtp_destroy(), AST_SOFTHANGUP_DEV, ast_string_field_free_memory, ast_test_flag, ast_udptl_destroy(), ast_unref_namedgroups(), ast_variables_destroy(), ast_verbose(), ast_websocket_unref(), sip_peer::call, sip_registry::call, sip_subscription_mwi::call, sip_pvt::callid, sip_pvt::caps, sip_pvt::cc_params, sip_pvt::chanvars, sip_notify::content, DEC_CALL_LIMIT, deinit_req(), destroy_msg_headers(), dialog_clean_rtp(), dialog_unref, sip_pvt::directmediaacl, sip_pvt::dtls_cfg, dumphistory, sip_pvt::epa_entry, sip_pvt::flags, sip_notify::headers, sip_pvt::history, sip_pvt::history_entries, sip_pvt::initreq, sip_pvt::jointcaps, sip_pvt::last_device_state_info, sip_pvt::method, sip_pvt::mwi, sip_peer::mwipvt, sip_pvt::named_callgroups, sip_pvt::named_pickupgroups, sip_pvt::notify, NULL, offered_media_list_destroy(), sip_pvt::options, sip_invite_param::outboundproxy, sip_pvt::outboundproxy, sip_pvt::owner, sip_pvt::peerauth, sip_pvt::peercaps, sip_pvt::prefcaps, sip_pvt::redircaps, ref_proxy(), sip_pvt::registry, sip_pvt::relatedpeer, sip_pvt::request_queue, sip_pvt::route, sip_debug_test_pvt(), sip_dump_history(), SIP_INC_COUNT, sip_methods, SIP_PAGE2_CALL_ONHOLD, sip_refer_destroy(), sip_route_clear(), sip_unref_peer, sip_pvt::socket, sip_pvt::stimer, sip_socket::tcptls_session, cfsip_methods::text, sip_pvt::udptl, update_call_counter(), sip_pvt::vsrtp, and sip_socket::ws_session.

Referenced by __sip_alloc().

6674 {
6675  struct sip_pvt *p = vdoomed;
6676  struct sip_request *req;
6677 
6678  ast_debug(3, "Destroying SIP dialog %s\n", p->callid);
6679 
6680  /* Destroy Session-Timers if allocated */
6681  ast_free(p->stimer);
6682  p->stimer = NULL;
6683 
6684  if (sip_debug_test_pvt(p))
6685  ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text);
6686 
6689  ast_debug(2, "This call did not properly clean up call limits. Call ID %s\n", p->callid);
6690  }
6691 
6692  /* Unlink us from the owner if we have one */
6693  if (p->owner) {
6694  ast_channel_lock(p->owner);
6695  ast_debug(1, "Detaching from %s\n", ast_channel_name(p->owner));
6697  /* Make sure that the channel knows its backend is going away */
6700  /* Give the channel a chance to react before deallocation */
6701  usleep(1);
6702  }
6703 
6704  /* Remove link from peer to subscription of MWI */
6705  if (p->relatedpeer && p->relatedpeer->mwipvt == p)
6706  p->relatedpeer->mwipvt = dialog_unref(p->relatedpeer->mwipvt, "delete ->relatedpeer->mwipvt");
6707  if (p->relatedpeer && p->relatedpeer->call == p)
6708  p->relatedpeer->call = dialog_unref(p->relatedpeer->call, "unset the relatedpeer->call field in tandem with relatedpeer field itself");
6709 
6710  if (p->relatedpeer)
6711  p->relatedpeer = sip_unref_peer(p->relatedpeer,"unsetting a dialog relatedpeer field in sip_destroy");
6712 
6713  if (p->registry) {
6714  if (p->registry->call == p)
6715  p->registry->call = dialog_unref(p->registry->call, "nulling out the registry's call dialog field in unlink_all");
6716  ao2_t_replace(p->registry, NULL, "delete p->registry");
6717  }
6718 
6719  if (p->mwi) {
6720  p->mwi->call = NULL;
6721  p->mwi = NULL;
6722  }
6723 
6724  if (dumphistory)
6725  sip_dump_history(p);
6726 
6727  if (p->options) {
6728  if (p->options->outboundproxy) {
6729  ao2_ref(p->options->outboundproxy, -1);
6730  }
6731  ast_free(p->options);
6732  p->options = NULL;
6733  }
6734 
6735  if (p->outboundproxy) {
6736  ref_proxy(p, NULL);
6737  }
6738 
6739  if (p->notify) {
6741  ast_free(p->notify->content);
6742  ast_free(p->notify);
6743  p->notify = NULL;
6744  }
6745 
6746  /* Free RTP and SRTP instances */
6747  dialog_clean_rtp(p);
6748 
6749  if (p->udptl) {
6751  p->udptl = NULL;
6752  }
6753  sip_refer_destroy(p);
6754  sip_route_clear(&p->route);
6755  deinit_req(&p->initreq);
6756 
6757  /* Clear history */
6758  if (p->history) {
6759  struct sip_history *hist;
6760  while ( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) {
6761  ast_free(hist);
6762  p->history_entries--;
6763  }
6764  ast_free(p->history);
6765  p->history = NULL;
6766  }
6767 
6768  while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) {
6769  ast_free(req);
6770  }
6771 
6773 
6774  if (p->chanvars) {
6776  p->chanvars = NULL;
6777  }
6778 
6780 
6781  if (p->vsrtp) {
6783  p->vsrtp = NULL;
6784  }
6785 
6786  if (p->directmediaacl) {
6788  }
6789 
6791 
6793  p->cc_params = NULL;
6794 
6795  if (p->epa_entry) {
6796  ao2_ref(p->epa_entry, -1);
6797  p->epa_entry = NULL;
6798  }
6799 
6800  if (p->socket.tcptls_session) {
6801  ao2_ref(p->socket.tcptls_session, -1);
6802  p->socket.tcptls_session = NULL;
6803  } else if (p->socket.ws_session) {
6805  p->socket.ws_session = NULL;
6806  }
6807 
6808  if (p->peerauth) {
6809  ao2_t_ref(p->peerauth, -1, "Removing active peer authentication");
6810  p->peerauth = NULL;
6811  }
6812 
6815 
6816  ao2_cleanup(p->caps);
6817  ao2_cleanup(p->jointcaps);
6818  ao2_cleanup(p->peercaps);
6819  ao2_cleanup(p->redircaps);
6820  ao2_cleanup(p->prefcaps);
6821 
6823 
6824  if (p->last_device_state_info) {
6827  }
6828 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
struct ast_format_cap * peercaps
Definition: sip.h:1101
struct ast_cc_config_params * cc_params
Definition: sip.h:1218
#define ast_channel_lock(chan)
Definition: channel.h:2945
static void destroy_msg_headers(struct sip_pvt *pvt)
Definition: chan_sip.c:12887
struct ast_format_cap * prefcaps
Definition: sip.h:1103
static void dialog_clean_rtp(struct sip_pvt *p)
Definition: chan_sip.c:5975
struct sip_proxy * outboundproxy
Definition: sip.h:870
void ast_cc_config_params_destroy(struct ast_cc_config_params *params)
Free memory from CCSS configuration params.
Definition: ccss.c:693
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
struct ast_str * content
Definition: sip.h:953
static unsigned int dumphistory
Definition: chan_sip.c:842
#define ast_test_flag(p, flag)
Definition: utils.h:63
static const struct cfsip_methods sip_methods[]
struct sip_peer * relatedpeer
Definition: sip.h:1171
struct sip_pvt * call
Definition: sip.h:1424
struct sip_socket socket
Definition: sip.h:1066
struct ast_namedgroups * named_pickupgroups
Definition: sip.h:1073
static void sip_dump_history(struct sip_pvt *dialog)
Dump SIP history to debug log file at end of lifespan for SIP dialog.
Definition: chan_sip.c:22586
size_t history_entries
Definition: sip.h:1179
struct ast_namedgroups * named_callgroups
Definition: sip.h:1072
#define ao2_t_replace(dst, src, tag)
Replace one object reference with another cleaning up the original.
Definition: astobj2.h:503
struct ast_acl_list * directmediaacl
Definition: sip.h:1134
struct ast_format_cap * jointcaps
Definition: sip.h:1100
#define DEC_CALL_LIMIT
Definition: sip.h:127
static void sip_refer_destroy(struct sip_pvt *p)
Destroy SIP refer structure.
Definition: chan_sip.c:16378
#define SIP_PAGE2_CALL_ONHOLD
Definition: sip.h:351
struct ast_flags flags[3]
Definition: sip.h:1075
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
#define NULL
Definition: resample.c:96
void ast_udptl_destroy(struct ast_udptl *udptl)
Definition: udptl.c:1150
void sip_route_clear(struct sip_route *route)
Free all routes in the list.
Definition: route.c:132
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 th...
Definition: chan_sip.c:6844
struct sip_invite_param * options
Definition: sip.h:1183
struct ast_sdp_srtp * vsrtp
Definition: sip.h:1186
static void deinit_req(struct sip_request *req)
Deinitialize SIP response/request.
Definition: chan_sip.c:12195
struct ast_rtp_dtls_cfg dtls_cfg
Definition: sip.h:1222
struct ast_websocket * ws_session
Definition: sip.h:802
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define SIP_INC_COUNT
Definition: sip.h:265
struct sip_registry * registry
Definition: sip.h:1173
struct sip_subscription_mwi * mwi
Definition: sip.h:1192
static void offered_media_list_destroy(struct sip_pvt *p)
Destroy SDP media offer list.
Definition: chan_sip.c:6663
struct sip_history_head * history
Definition: sip.h:1178
struct ast_format_cap * caps
Definition: sip.h:1099
struct sip_request initreq
Definition: sip.h:1151
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct sip_epa_entry * epa_entry
Definition: sip.h:1219
struct sip_history * next
Definition: sip.h:897
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
struct ast_udptl * udptl
Definition: sip.h:1115
struct ast_tcptls_session_instance * tcptls_session
Definition: sip.h:801
struct sip_route route
Definition: sip.h:1139
struct sip_pvt * call
Definition: sip.h:1466
const ast_string_field callid
Definition: sip.h:1063
struct ast_format_cap * redircaps
Definition: sip.h:1102
struct sip_st_dlg * stimer
Definition: sip.h:1184
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
struct ast_acl_list * ast_free_acl_list(struct ast_acl_list *acl)
Free a list of ACLs.
Definition: acl.c:233
int method
Definition: sip.h:1009
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
#define ast_free(a)
Definition: astmm.h:182
struct ast_channel * owner
Definition: sip.h:1138
struct ao2_container * last_device_state_info
Definition: sip.h:1164
void ast_sdp_srtp_destroy(struct ast_sdp_srtp *srtp)
free a ast_sdp_srtp structure
Definition: sdp_srtp.c:51
static void ref_proxy(struct sip_pvt *pvt, struct sip_proxy *proxy)
maintain proper refcounts for a sip_pvt&#39;s outboundproxy
Definition: chan_sip.c:3293
static int sip_debug_test_pvt(struct sip_pvt *p)
Test PVT for debugging output.
Definition: chan_sip.c:3649
char *const text
Definition: chan_sip.c:737
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
struct sip_pvt * call
Definition: sip.h:1354
struct sip_pvt::request_queue request_queue
struct ast_variable * headers
Definition: sip.h:952
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct sip_pvt * mwipvt
Definition: sip.h:1367
const char * ast_channel_name(const struct ast_channel *chan)
void ast_rtp_dtls_cfg_free(struct ast_rtp_dtls_cfg *dtls_cfg)
Free contents of a DTLS configuration structure.
Definition: rtp_engine.c:3131
void ast_channel_softhangup_internal_flag_add(struct ast_channel *chan, int value)
struct ast_namedgroups * ast_unref_namedgroups(struct ast_namedgroups *groups)
Definition: channel.c:7832
void AST_OPTIONAL_API_NAME() ast_websocket_unref(struct ast_websocket *session)
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)
struct sip_history::@168 list
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:368
struct ast_variable * chanvars
Definition: sip.h:1180
struct sip_proxy * outboundproxy
Definition: sip.h:1112
sip_history: Structure for saving transactions within a SIP dialog
Definition: sip.h:896
struct sip_notify * notify
Definition: sip.h:1140
struct sip_auth_container * peerauth
Definition: sip.h:1141

◆ sip_pvt_lock_full()

static struct ast_channel * sip_pvt_lock_full ( struct sip_pvt pvt)
static

Definition at line 9400 of file chan_sip.c.

References ast_channel_lock, ast_channel_ref, ast_channel_unlock, ast_channel_unref, NULL, sip_pvt::owner, sip_pvt_lock, and sip_pvt_unlock.

Referenced by __sched_check_pendings(), __sip_autodestruct(), dialog_unlink_all(), get_refer_info(), handle_request_bye(), handle_request_do(), proc_session_timer(), reinvite_timeout(), retrans_pkt(), send_provisional_keepalive_full(), sip_queue_hangup_cause(), sip_reinvite_retry(), and sip_t38_abort().

9401 {
9402  struct ast_channel *chan;
9403 
9404  /* Locking is simple when it is done right. If you see a deadlock resulting
9405  * in this function, it is not this function's fault, Your problem exists elsewhere.
9406  * This function is perfect... seriously. */
9407  for (;;) {
9408  /* First, get the channel and grab a reference to it */
9409  sip_pvt_lock(pvt);
9410  chan = pvt->owner;
9411  if (chan) {
9412  /* The channel can not go away while we hold the pvt lock.
9413  * Give the channel a ref so it will not go away after we let
9414  * the pvt lock go. */
9415  ast_channel_ref(chan);
9416  } else {
9417  /* no channel, return pvt locked */
9418  return NULL;
9419  }
9420 
9421  /* We had to hold the pvt lock while getting a ref to the owner channel
9422  * but now we have to let this lock go in order to preserve proper
9423  * locking order when grabbing the channel lock */
9424  sip_pvt_unlock(pvt);
9425 
9426  /* Look, no deadlock avoidance, hooray! */
9427  ast_channel_lock(chan);
9428  sip_pvt_lock(pvt);
9429 
9430  if (pvt->owner == chan) {
9431  /* done */
9432  break;
9433  }
9434 
9435  /* If the owner changed while everything was unlocked, no problem,
9436  * just start over and everthing will work. This is rare, do not be
9437  * confused by this loop and think this it is an expensive operation.
9438  * The majority of the calls to this function will never involve multiple
9439  * executions of this loop. */
9440  ast_channel_unlock(chan);
9441  ast_channel_unref(chan);
9442  sip_pvt_unlock(pvt);
9443  }
9444 
9445  /* If owner exists, it is locked and reffed */
9446  return pvt->owner;
9447 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
#define NULL
Definition: resample.c:96
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_channel * owner
Definition: sip.h:1138
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2970

◆ sip_qualify_peer()

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

References _sip_qualify_peer(), ast_cli_args::argc, ast_cli_args::argv, ast_cli_complete(), CLI_GENERATE, CLI_INIT, ast_cli_entry::command, complete_sip_show_peer(), ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, NULL, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

21136 {
21137  switch (cmd) {
21138  case CLI_INIT:
21139  e->command = "sip qualify peer";
21140  e->usage =
21141  "Usage: sip qualify peer <name> [load]\n"
21142  " Requests a response from one SIP peer and the current status.\n"
21143  " Option \"load\" forces lookup of peer in realtime storage.\n";
21144  return NULL;
21145  case CLI_GENERATE:
21146  if (a->pos == 4) {
21147  static const char * const completions[] = { "load", NULL };
21148  return ast_cli_complete(a->word, completions, a->n);
21149  } else {
21150  return complete_sip_show_peer(a->line, a->word, a->pos, a->n);
21151  }
21152  }
21153  return _sip_qualify_peer(0, a->fd, NULL, NULL, a->argc, (const char **) a->argv);
21154 }
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
const char * line
Definition: cli.h:162
char * ast_cli_complete(const char *word, const char *const choices[], int pos)
Definition: main/cli.c:1811
const int fd
Definition: cli.h:159
const int n
Definition: cli.h:165
const char *const * argv
Definition: cli.h:161
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.
Definition: chan_sip.c:21084
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
const char * usage
Definition: cli.h:177
static char * complete_sip_show_peer(const char *line, const char *word, int pos, int state)
Support routine for &#39;sip show peer&#39; CLI.
Definition: chan_sip.c:22340
const int pos
Definition: cli.h:164

◆ sip_queryoption()

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

References ast_channel_name(), ast_channel_tech_pvt(), 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, sip_pvt::dialstring, sip_pvt::dsp, sip_pvt::flags, LOG_ERROR, sip_pvt::outgoing_call, sip_pvt::req_secure_signaling, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_USE_SRTP, sip_pvt_lock, sip_pvt_unlock, t38properties::state, invstate2stringtable::state, sip_pvt::t38, T38_ENABLED, T38_LOCAL_REINVITE, T38_PEER_REINVITE, T38_REJECTED, T38_STATE_NEGOTIATED, T38_STATE_NEGOTIATING, T38_STATE_REJECTED, T38_STATE_UNAVAILABLE, and T38_STATE_UNKNOWN.

4995 {
4996  int res = -1;
4998  struct sip_pvt *p = (struct sip_pvt *) ast_channel_tech_pvt(chan);
4999  char *cp;
5000 
5001  if (!p) {
5002  ast_debug(1, "Attempt to Ref a null pointer. Sip private structure is gone!\n");
5003  return -1;
5004  }
5005 
5006  sip_pvt_lock(p);
5007 
5008  switch (option) {
5009  case AST_OPTION_T38_STATE:
5010  /* Make sure we got an ast_t38_state enum passed in */
5011  if (*datalen != sizeof(enum ast_t38_state)) {
5012  ast_log(LOG_ERROR, "Invalid datalen for AST_OPTION_T38_STATE option. Expected %d, got %d\n", (int)sizeof(enum ast_t38_state), *datalen);
5013  break;
5014  }
5015 
5016  /* 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 */
5017  if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) {
5018  switch (p->t38.state) {
5019  case T38_LOCAL_REINVITE:
5020  case T38_PEER_REINVITE:
5021  state = T38_STATE_NEGOTIATING;
5022  break;
5023  case T38_ENABLED:
5024  state = T38_STATE_NEGOTIATED;
5025  break;
5026  case T38_REJECTED:
5027  state = T38_STATE_REJECTED;
5028  break;
5029  default:
5030  state = T38_STATE_UNKNOWN;
5031  }
5032  }
5033 
5034  *((enum ast_t38_state *) data) = state;
5035  res = 0;
5036 
5037  break;
5039  cp = (char *) data;
5040  *cp = p->dsp ? 1 : 0;
5041  ast_debug(1, "Reporting digit detection %sabled on %s\n", *cp ? "en" : "dis", ast_channel_name(chan));
5042  break;
5044  *((unsigned int *) data) = p->req_secure_signaling;
5045  res = 0;
5046  break;
5048  *((unsigned int *) data) = ast_test_flag(&p->flags[1], SIP_PAGE2_USE_SRTP) ? 1 : 0;
5049  res = 0;
5050  break;
5052  if (p && p->outgoing_call) {
5053  cp = (char *) data;
5054  ast_copy_string(cp, p->dialstring, *datalen);
5055  res = 0;
5056  }
5057  /* We purposely break with a return of -1 in the
5058  * implied else case here
5059  */
5060  break;
5061  default:
5062  break;
5063  }
5064 
5065  sip_pvt_unlock(p);
5066 
5067  return res;
5068 }
enum sip_cc_notify_state state
Definition: chan_sip.c:959
#define T38_ENABLED
Definition: chan_ooh323.c:102
enum t38state state
Definition: sip.h:917
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define AST_OPTION_DEVICE_NAME
unsigned short outgoing_call
Definition: sip.h:1083
ast_t38_state
Possible T38 states on channels.
Definition: channel.h:879
#define AST_OPTION_SECURE_MEDIA
struct ast_flags flags[3]
Definition: sip.h:1075
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
struct t38properties t38
Definition: sip.h:1113
const ast_string_field dialstring
Definition: sip.h:1063
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
#define SIP_PAGE2_USE_SRTP
Definition: sip.h:368
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
unsigned short req_secure_signaling
Definition: sip.h:1093
struct ast_dsp * dsp
Definition: sip.h:1169
#define AST_OPTION_DIGIT_DETECT
#define LOG_ERROR
Definition: logger.h:285
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
#define AST_OPTION_SECURE_SIGNALING
#define SIP_PAGE2_T38SUPPORT
Definition: sip.h:346
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
const char * ast_channel_name(const struct ast_channel *chan)
#define AST_OPTION_T38_STATE

◆ sip_queue_hangup_cause()

static void sip_queue_hangup_cause ( struct sip_pvt p,
int  cause 
)
static

Definition at line 23981 of file chan_sip.c.

References ast_channel_name(), 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::owner, sip_pvt_lock_full(), and sip_pvt_unlock.

Referenced by handle_request_bye(), handle_request_cancel(), and handle_response_invite().

23982 {
23983  struct ast_channel *owner = p->owner;
23984  const char *name = ast_strdupa(ast_channel_name(owner));
23985 
23986  /* Cannot hold any channel/private locks when calling. */
23987  ast_channel_ref(owner);
23988  ast_channel_unlock(owner);
23989  sip_pvt_unlock(p);
23990  ast_set_hangupsource(owner, name, 0);
23991  if (cause) {
23992  ast_queue_hangup_with_cause(owner, cause);
23993  } else {
23994  ast_queue_hangup(owner);
23995  }
23996  ast_channel_unref(owner);
23997 
23998  /* Relock things. */
23999  owner = sip_pvt_lock_full(p);
24000  if (owner) {
24001  ast_channel_unref(owner);
24002  }
24003 }
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
Definition: channel.c:1150
Main Channel structure associated with a channel.
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
Queue a hangup frame with hangupcause set.
Definition: channel.c:1166
void ast_set_hangupsource(struct ast_channel *chan, const char *source, int force)
Set the source of the hangup in this channel and it&#39;s bridge.
Definition: channel.c:2504
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static struct ast_channel * sip_pvt_lock_full(struct sip_pvt *pvt)
Definition: chan_sip.c:9400
#define ast_channel_unlock(chan)
Definition: channel.h:2946
static const char name[]
Definition: cdr_mysql.c:74
struct ast_channel * owner
Definition: sip.h:1138
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2970
const char * ast_channel_name(const struct ast_channel *chan)

◆ sip_read()

static struct ast_frame * sip_read ( struct ast_channel ast)
static

Read SIP RTP from channel.

Definition at line 8742 of file chan_sip.c.

References ast_async_goto(), ast_channel_caller(), ast_channel_context(), ast_channel_exten(), ast_channel_lock, ast_channel_macrocontext(), ast_channel_name(), ast_channel_tech_pvt(), ast_channel_unlock, ast_exists_extension(), AST_FRAME_VOICE, ast_frfree, ast_log, ast_null_frame, AST_STATE_UP, ast_test_flag, ast_verb, FALSE, sip_pvt::flags, ast_frame::frametype, INV_EARLY_MEDIA, sip_pvt::invitestate, sip_pvt::lastrtprx, LOG_NOTICE, NULL, pbx_builtin_setvar_helper(), S_COR, S_OR, SIP_PAGE2_FAX_DETECT_CNG, sip_pvt_lock, sip_pvt_unlock, and sip_rtp_read().

8743 {
8744  struct ast_frame *fr;
8745  struct sip_pvt *p = ast_channel_tech_pvt(ast);
8746  int faxdetected = FALSE;
8747 
8748  sip_pvt_lock(p);
8749  fr = sip_rtp_read(ast, p, &faxdetected);
8750  p->lastrtprx = time(NULL);
8751 
8752  /* If we detect a CNG tone and fax detection is enabled then send us off to the fax extension */
8753  if (faxdetected && ast_test_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_CNG)) {
8754  if (strcmp(ast_channel_exten(ast), "fax")) {
8755  const char *target_context = S_OR(ast_channel_macrocontext(ast), ast_channel_context(ast));
8756  /*
8757  * We need to unlock 'ast' here because
8758  * ast_exists_extension has the potential to start and
8759  * stop an autoservice on the channel. Such action is
8760  * prone to deadlock if the channel is locked.
8761  *
8762  * ast_async_goto() has its own restriction on not holding
8763  * the channel lock.
8764  */
8765  sip_pvt_unlock(p);
8766  ast_channel_unlock(ast);
8767  ast_frfree(fr);
8768  fr = &ast_null_frame;
8769  if (ast_exists_extension(ast, target_context, "fax", 1,
8770  S_COR(ast_channel_caller(ast)->id.number.valid, ast_channel_caller(ast)->id.number.str, NULL))) {
8771  ast_verb(2, "Redirecting '%s' to fax extension due to CNG detection\n", ast_channel_name(ast));
8772  pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast_channel_exten(ast));
8773  if (ast_async_goto(ast, target_context, "fax", 1)) {
8774  ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", ast_channel_name(ast), target_context);
8775  }
8776  } else {
8777  ast_log(LOG_NOTICE, "FAX CNG detected but no fax extension\n");
8778  }
8779  ast_channel_lock(ast);
8780  sip_pvt_lock(p);
8781  }
8782  }
8783 
8784  /* Only allow audio through if they sent progress with SDP, or if the channel is actually answered */
8785  if (fr && fr->frametype == AST_FRAME_VOICE && p->invitestate != INV_EARLY_MEDIA && ast_channel_state(ast) != AST_STATE_UP) {
8786  ast_frfree(fr);
8787  fr = &ast_null_frame;
8788  }
8789 
8790  sip_pvt_unlock(p);
8791 
8792  return fr;
8793 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
#define SIP_PAGE2_FAX_DETECT_CNG
Definition: sip.h:361
#define ast_channel_lock(chan)
Definition: channel.h:2945
#define FALSE
Definition: app_minivm.c:521
static struct ast_frame * sip_rtp_read(struct ast_channel *ast, struct sip_pvt *p, int *faxdetect)
Read RTP from network.
Definition: chan_sip.c:8631
time_t lastrtprx
Definition: sip.h:1129
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_test_flag(p, flag)
Definition: utils.h:63
ast_channel_state
ast_channel states
Definition: channelstate.h:35
struct ast_flags flags[3]
Definition: sip.h:1075
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:463
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
Number structure.
Definition: app_followme.c:154
#define ast_log
Definition: astobj2.c:42
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:85
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:4179
const char * ast_channel_exten(const struct ast_channel *chan)
#define LOG_NOTICE
Definition: logger.h:263
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
#define ast_channel_unlock(chan)
Definition: channel.h:2946
enum invitestates invitestate
Definition: sip.h:1007
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
struct ast_frame ast_null_frame
Definition: main/frame.c:79
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
const char * ast_channel_name(const struct ast_channel *chan)
int ast_async_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Set the channel to next execute the specified dialplan location.
Definition: pbx.c:7011
#define ast_frfree(fr)
Data structure associated with a single frame of data.
const char * ast_channel_context(const struct ast_channel *chan)
enum ast_frame_type frametype
const char * ast_channel_macrocontext(const struct ast_channel *chan)

◆ sip_real_dst()

static const struct ast_sockaddr * sip_real_dst ( const struct sip_pvt p)
static

The real destination address for a write.

Definition at line 3633 of file chan_sip.c.

References ast_test_flag, sip_pvt::flags, sip_proxy::ip, sip_pvt::outboundproxy, sip_pvt::recv, sip_pvt::sa, SIP_NAT_FORCE_RPORT, and SIP_NAT_RPORT_PRESENT.

Referenced by __sip_xmit(), check_via(), retrans_pkt(), send_response(), show_channels_cb(), sip_debug_test_pvt(), and sip_prepare_socket().

3634 {
3635  if (p->outboundproxy) {
3636  return &p->outboundproxy->ip;
3637  }
3638 
3639  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;
3640 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_sockaddr recv
Definition: sip.h:1135
#define SIP_NAT_FORCE_RPORT
Definition: sip.h:283
struct ast_flags flags[3]
Definition: sip.h:1075
struct ast_sockaddr sa
Definition: sip.h:1125
struct ast_sockaddr ip
Definition: sip.h:723
#define SIP_NAT_RPORT_PRESENT
Definition: sip.h:284
struct sip_proxy * outboundproxy
Definition: sip.h:1112

◆ sip_reason_code_to_str()

static const char* sip_reason_code_to_str ( struct ast_party_redirecting_reason reason)
static

Definition at line 2471 of file chan_sip.c.

References ARRAY_LEN, ast_strlen_zero, ast_party_redirecting_reason::code, sip_reason_table, ast_party_redirecting_reason::str, and sip_reasons::text.

Referenced by add_diversion(), and change_redirecting_information().

2472 {
2473  int idx;
2474  int code;
2475 
2476  /* use specific string if given */
2477  if (!ast_strlen_zero(reason->str)) {
2478  return reason->str;
2479  }
2480 
2481  code = reason->code;
2482  for (idx = 0; idx < ARRAY_LEN(sip_reason_table); ++idx) {
2483  if (code == sip_reason_table[idx].code) {
2484  return sip_reason_table[idx].text;
2485  }
2486  }
2487 
2488  return "unknown";
2489 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static const struct sip_reasons sip_reason_table[]
int code
enum AST_REDIRECTING_REASON value for redirection
Definition: channel.h:511
#define ast_strlen_zero(foo)
Definition: strings.h:52
char * str
a string value for the redirecting reason
Definition: channel.h:508
const char * text
Definition: chan_sip.c:768

◆ sip_refer_alloc()

static int sip_refer_alloc ( struct sip_pvt p)
static

Allocate SIP refer structure.

Definition at line 16370 of file chan_sip.c.

References ast_calloc_with_stringfields, sip_pvt::refer, and sip_refer_destroy().

Referenced by get_also_info(), handle_request_invite(), handle_request_refer(), and transmit_refer().

16371 {
16372  sip_refer_destroy(p);
16373  p->refer = ast_calloc_with_stringfields(1, struct sip_refer, 512);
16374  return p->refer ? 1 : 0;
16375 }
#define ast_calloc_with_stringfields(n, type, size)
Allocate a structure with embedded stringfields in a single allocation.
Definition: stringfields.h:426
static void sip_refer_destroy(struct sip_pvt *p)
Destroy SIP refer structure.
Definition: chan_sip.c:16378
struct sip_refer * refer
Definition: sip.h:1160
Structure to handle SIP transfers. Dynamically allocated when needed.
Definition: sip.h:933

◆ sip_refer_destroy()

static void sip_refer_destroy ( struct sip_pvt p)
static

Destroy SIP refer structure.

Definition at line 16378 of file chan_sip.c.

References ast_free, ast_string_field_free_memory, NULL, and sip_pvt::refer.

Referenced by sip_pvt_dtor(), and sip_refer_alloc().

16379 {
16380  if (p->refer) {
16382  ast_free(p->refer);
16383  p->refer = NULL;
16384  }
16385 }
#define NULL
Definition: resample.c:96
#define ast_free(a)
Definition: astmm.h:182
struct sip_refer * refer
Definition: sip.h:1160
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:368

◆ sip_reg_timeout()

static int sip_reg_timeout ( const void *  data)
static

Registration request timeout, register again.

Registered as a timeout handler during transmit_register(), to retransmit the packet if a reply does not come back.

Note
This is called by the scheduler so the event is not pending anymore when we are called.
Run by the sched thread.

Definition at line 15976 of file chan_sip.c.

References __sip_pretend_ack(), ao2_t_ref, ao2_t_replace, ast_dnsmgr_refresh(), ast_log, sip_registry::call, dialog_unref, sip_registry::dnsmgr, global_regattempts_max, sip_registry::hostname, LOG_NOTICE, NULL, pvt_set_needdestroy(), REG_STATE_AUTHSENT, REG_STATE_FAILED, REG_STATE_REGSENT, REG_STATE_TIMEOUT, REG_STATE_UNREGISTERED, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, regstate2str(), sip_publish_registry(), sip_pvt_lock, sip_pvt_unlock, SIP_REGISTER, sip_registry::timeout, transmit_register(), and sip_registry::username.

Referenced by __start_register_timeout(), and sip_show_sched().

15977 {
15978  struct sip_registry *r = (struct sip_registry *)data; /* the ref count should have been bumped when the sched item was added */
15979  struct sip_pvt *p;
15980 
15981  switch (r->regstate) {
15983  case REG_STATE_REGSENT:
15984  case REG_STATE_AUTHSENT:
15985  case REG_STATE_TIMEOUT:
15986  break;
15987  default:
15988  /*
15989  * Registration completed because we got a request response
15990  * and we couldn't stop the scheduled entry in time.
15991  */
15992  r->timeout = -1;
15993  ao2_t_ref(r, -1, "Scheduled register timeout completed early");
15994  return 0;
15995  }
15996 
15997  if (r->dnsmgr) {
15998  /* If the registration has timed out, maybe the IP changed. Force a refresh. */
16000  }
16001 
16002  /* If the initial tranmission failed, we may not have an existing dialog,
16003  * so it is possible that r->call == NULL.
16004  * Otherwise destroy it, as we have a timeout so we don't want it.
16005  */
16006  if (r->call) {
16007  /* Unlink us, destroy old call. Locking is not relevant here because all this happens
16008  in the single SIP manager thread. */
16009  p = r->call;
16010  sip_pvt_lock(p);
16011  pvt_set_needdestroy(p, "registration timeout");
16012  /* Pretend to ACK anything just in case */
16013  __sip_pretend_ack(p);
16014  sip_pvt_unlock(p);
16015 
16016  /* decouple the two objects */
16017  /* p->registry == r, so r has 2 refs, and the unref won't take the object away */
16018  ao2_t_replace(p->registry, NULL, "p->registry unreffed");
16019  r->call = dialog_unref(r->call, "unrefing r->call");
16020  }
16021  /* If we have a limit, stop registration and give up */
16022  r->timeout = -1;
16024  /* Ok, enough is enough. Don't try any more */
16025  /* We could add an external notification here...
16026  steal it from app_voicemail :-) */
16027  ast_log(LOG_NOTICE, " -- Last Registration Attempt #%d failed, Giving up forever trying to register '%s@%s'\n", r->regattempts, r->username, r->hostname);
16029  } else {
16032  ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts);
16033  }
16035  ao2_t_ref(r, -1, "Scheduled register timeout complete");
16036  return 0;
16037 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
void __sip_pretend_ack(struct sip_pvt *p)
Pretend to ack all packets called with p locked.
Definition: chan_sip.c:4615
const ast_string_field hostname
Definition: sip.h:1414
const ast_string_field username
Definition: sip.h:1414
enum sipregistrystate regstate
Definition: sip.h:1425
struct sip_pvt * call
Definition: sip.h:1424
#define ao2_t_replace(dst, src, tag)
Replace one object reference with another cleaning up the original.
Definition: astobj2.h:503
Registrations with other SIP proxies.
Definition: sip.h:1396
#define NULL
Definition: resample.c:96
int ast_dnsmgr_refresh(struct ast_dnsmgr_entry *entry)
Force a refresh of a dnsmgr entry.
Definition: dnsmgr.c:239
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
struct ast_dnsmgr_entry * dnsmgr
Definition: sip.h:1429
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
#define ast_log
Definition: astobj2.c:42
struct sip_registry * registry
Definition: sip.h:1173
int regattempts
Definition: sip.h:1421
static void sip_publish_registry(const char *username, const char *domain, const char *status)
Definition: chan_sip.c:15852
static void pvt_set_needdestroy(struct sip_pvt *pvt, const char *reason)
Definition: chan_sip.c:3429
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
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()) ...
Definition: chan_sip.c:16106
static const char * regstate2str(enum sipregistrystate regstate) attribute_const
Convert registration state status to string.
Definition: chan_sip.c:15847
#define LOG_NOTICE
Definition: logger.h:263
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
static int global_regattempts_max
Definition: chan_sip.c:827
int timeout
Definition: sip.h:1422

◆ sip_register()

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

References ao2_t_alloc, ao2_t_find, ao2_t_link, ao2_t_ref, ast_log, ast_string_field_init, ast_string_field_set, sip_registry::configured_expiry, default_expiry, sip_registry::expire, sip_registry::expiry, LOG_ERROR, OBJ_SEARCH_KEY, sip_registry::refresh, sip_parse_register_line(), sip_registry_destroy(), and sip_registry::timeout.

Referenced by build_peer(), and reload_config().

9680 {
9681  struct sip_registry *reg;
9682 
9683  reg = ao2_t_find(registry_list, value, OBJ_SEARCH_KEY, "check for existing registry");
9684  if (reg) {
9685  ao2_t_ref(reg, -1, "throw away found registry");
9686  return 0;
9687  }
9688 
9689  if (!(reg = ao2_t_alloc(sizeof(*reg), sip_registry_destroy, "allocate a registry struct"))) {
9690  ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n");
9691  return -1;
9692  }
9693 
9694  reg->expire = -1;
9695  reg->timeout = -1;
9696 
9697  if (ast_string_field_init(reg, 256)) {
9698  ao2_t_ref(reg, -1, "failed to string_field_init, drop reg");
9699  return -1;
9700  }
9701 
9703  if (sip_parse_register_line(reg, default_expiry, value, lineno)) {
9704  ao2_t_ref(reg, -1, "failure to parse, unref the reg pointer");
9705  return -1;
9706  }
9707 
9708  /* set default expiry if necessary */
9709  if (reg->refresh && !reg->expiry && !reg->configured_expiry) {
9710  reg->refresh = reg->expiry = reg->configured_expiry = default_expiry;
9711  }
9712 
9713  ao2_t_link(registry_list, reg, "link reg to registry_list");
9714  ao2_t_ref(reg, -1, "unref the reg pointer");
9715 
9716  return 0;
9717 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
int expire
Definition: sip.h:1418
#define ao2_t_alloc(data_size, destructor_fn, debug_msg)
Definition: astobj2.h:409
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
int sip_parse_register_line(struct sip_registry *reg, int default_expiry, const char *value, int lineno)
Parse register=> line in sip.conf.
Definition: config_parser.c:37
int configured_expiry
Definition: sip.h:1419
Registrations with other SIP proxies.
Definition: sip.h:1396
#define ao2_t_link(container, obj, tag)
Add an object to a container.
Definition: astobj2.h:1547
int value
Definition: syslog.c:37
static struct ao2_container * registry_list
The register list: Other SIP proxies we register with and receive calls from.
Definition: chan_sip.c:1061
#define ast_log
Definition: astobj2.c:42
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:353
static int default_expiry
Definition: chan_sip.c:669
static void sip_registry_destroy(void *reg)
Destroy registry object Objects created with the register= statement in static configuration.
Definition: chan_sip.c:6630
#define LOG_ERROR
Definition: logger.h:285
int expiry
Definition: sip.h:1420
int timeout
Definition: sip.h:1422
#define ao2_t_find(container, arg, flags, tag)
Definition: astobj2.h:1754
int refresh
Definition: sip.h:1423
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514
const ast_string_field configvalue
Definition: sip.h:1414

◆ sip_register_tests()

static void sip_register_tests ( void  )
static

SIP test registration.

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

34726 {
34730 }
void sip_dialplan_function_register_tests(void)
SIP test registration.
void sip_request_parser_register_tests(void)
register request parsing tests
void sip_config_parser_register_tests(void)
SIP test registration.

◆ sip_registry_destroy()

static void sip_registry_destroy ( void *  reg)
static

Destroy registry object Objects created with the register= statement in static configuration.

Definition at line 6630 of file chan_sip.c.

References ao2_t_replace, ast_debug, ast_string_field_free_memory, sip_registry::call, dialog_unlink_all(), dialog_unref, sip_registry::hostname, NULL, sip_pvt::registry, and sip_registry::username.

Referenced by sip_register().

6631 {
6632  struct sip_registry *reg = obj;
6633  /* Really delete */
6634  ast_debug(3, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname);
6635 
6636  if (reg->call) {
6637  /* Clear registry before destroying to ensure
6638  we don't get reentered trying to grab the registry lock */
6639  ao2_t_replace(reg->call->registry, NULL, "destroy reg->call->registry");
6640  ast_debug(3, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname);
6641  dialog_unlink_all(reg->call);
6642  reg->call = dialog_unref(reg->call, "unref reg->call");
6643  /* reg->call = sip_destroy(reg->call); */
6644  }
6645 
6647 }
const ast_string_field hostname
Definition: sip.h:1414
const ast_string_field username
Definition: sip.h:1414
struct sip_pvt * call
Definition: sip.h:1424
#define ao2_t_replace(dst, src, tag)
Replace one object reference with another cleaning up the original.
Definition: astobj2.h:503
Registrations with other SIP proxies.
Definition: sip.h:1396
#define NULL
Definition: resample.c:96
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 stor...
Definition: chan_sip.c:3367
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct sip_registry * registry
Definition: sip.h:1173
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:368

◆ sip_reinvite_retry()

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.

Note
Run by the sched thread.

Definition at line 23817 of file chan_sip.c.

References ast_channel_unlock, ast_channel_unref, ast_set_flag, check_pendings(), dialog_unref, sip_pvt::flags, SIP_NEEDREINVITE, sip_pvt_lock_full(), sip_pvt_unlock, and sip_pvt::waitid.

Referenced by handle_response_invite(), and sip_show_sched().

23818 {
23819  struct sip_pvt *p = (struct sip_pvt *) data;
23820  struct ast_channel *owner;
23821 
23822  owner = sip_pvt_lock_full(p);
23824  p->waitid = -1;
23825  check_pendings(p);
23826  sip_pvt_unlock(p);
23827  if (owner) {
23828  ast_channel_unlock(owner);
23829  ast_channel_unref(owner);
23830  }
23831  dialog_unref(p, "Schedule waitid complete");
23832  return 0;
23833 }
Main Channel structure associated with a channel.
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
#define ast_set_flag(p, flag)
Definition: utils.h:70
struct ast_flags flags[3]
Definition: sip.h:1075
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
int waitid
Definition: sip.h:1156
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
static struct ast_channel * sip_pvt_lock_full(struct sip_pvt *pvt)
Definition: chan_sip.c:9400
#define ast_channel_unlock(chan)
Definition: channel.h:2946
static void check_pendings(struct sip_pvt *p)
Check pending actions on SIP call.
Definition: chan_sip.c:23735
#define SIP_NEEDREINVITE
Definition: sip.h:261

◆ sip_reload()

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

References ao2_t_global_obj_replace_unref, 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, sip_peer::flags, LOG_ERROR, NULL, restart_monitor(), SIP_INSECURE, sip_reload_lock, sip_reloading, sip_reloadreason, temp_peer(), TRUE, and ast_cli_entry::usage.

Referenced by reload().

34419 {
34420  static struct sip_peer *new_peer;
34421 
34422  switch (cmd) {
34423  case CLI_INIT:
34424  e->command = "sip reload";
34425  e->usage =
34426  "Usage: sip reload\n"
34427  " Reloads SIP configuration from sip.conf\n";
34428  return NULL;
34429  case CLI_GENERATE:
34430  return NULL;
34431  }
34432 
34434  if (sip_reloading) {
34435  ast_verbose("Previous SIP reload not yet done\n");
34436  } else {
34437  sip_reloading = TRUE;
34439  }
34441  restart_monitor();
34442 
34443  /* Create new bogus peer possibly with new global settings. */
34444  if ((new_peer = temp_peer("(bogus_peer)"))) {
34446  ast_clear_flag(&new_peer->flags[0], SIP_INSECURE);
34447  ao2_t_global_obj_replace_unref(g_bogus_peer, new_peer,
34448  "Replacing the old bogus peer during reload.");
34449  ao2_t_ref(new_peer, -1, "done with new_peer");
34450  } else {
34451  ast_log(LOG_ERROR, "Could not update the fake authentication peer.\n");
34452  /* You probably have bigger (memory?) issues to worry about though.. */
34453  }
34454 
34455  return CLI_SUCCESS;
34456 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
static int sip_reloading
Definition: chan_sip.c:905
#define ao2_t_global_obj_replace_unref(holder, obj, tag)
Replace an ao2 object in the global holder, throwing away any old object.
Definition: astobj2.h:906
static enum channelreloadreason sip_reloadreason
Definition: chan_sip.c:906
#define BOGUS_PEER_MD5SECRET
We can recognize the bogus peer by this invalid MD5 hash.
Definition: chan_sip.c:1058
Definition: cli.h:152
#define ast_mutex_lock(a)
Definition: lock.h:187
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
const int fd
Definition: cli.h:159
const ast_string_field md5secret
Definition: sip.h:1306
static ast_mutex_t sip_reload_lock
Definition: chan_sip.c:899
#define SIP_INSECURE
Definition: sip.h:294
#define LOG_ERROR
Definition: logger.h:285
static struct sip_peer * temp_peer(const char *name)
Create temporary peer (used in autocreatepeer mode)
Definition: chan_sip.c:31550
char * command
Definition: cli.h:186
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
#define ast_clear_flag(p, flag)
Definition: utils.h:77
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
struct ast_flags flags[3]
Definition: sip.h:1335
#define TRUE
Definition: app_minivm.c:518
static int restart_monitor(void)
Start the channel monitor thread.
Definition: chan_sip.c:30078
#define ast_mutex_unlock(a)
Definition: lock.h:188
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ sip_removeheader()

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

Remove SIP headers added previously with SipAddHeader application.

Definition at line 34118 of file chan_sip.c.

References ast_channel_lock, ast_channel_unlock, ast_channel_varshead(), 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 sipdebug.

Referenced by load_module().

34119 {
34120  struct ast_var_t *newvariable;
34121  struct varshead *headp;
34122  int removeall = 0;
34123  char *inbuf = (char *) data;
34124 
34125  if (ast_strlen_zero(inbuf)) {
34126  removeall = 1;
34127  }
34128  ast_channel_lock(chan);
34129 
34130  headp=ast_channel_varshead(chan);
34131  AST_LIST_TRAVERSE_SAFE_BEGIN (headp, newvariable, entries) {
34132  if (strncmp(ast_var_name(newvariable), "SIPADDHEADER", strlen("SIPADDHEADER")) == 0) {
34133  if (removeall || (!strncasecmp(ast_var_value(newvariable),inbuf,strlen(inbuf)))) {
34134  if (sipdebug) {
34135  ast_debug(1,"removing SIP Header \"%s\" as %s\n",
34136  ast_var_value(newvariable),
34137  ast_var_name(newvariable));
34138  }
34139  AST_LIST_REMOVE_CURRENT(entries);
34140  ast_var_delete(newvariable);
34141  }
34142  }
34143  }
34145 
34146  ast_channel_unlock(chan);
34147  return 0;
34148 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
const char * ast_var_value(const struct ast_var_t *var)
Definition: chanvars.c:80
const char * ast_var_name(const struct ast_var_t *var)
Definition: chanvars.c:60
struct varshead * ast_channel_varshead(struct ast_channel *chan)
static int inbuf(struct baseio *bio, FILE *fi)
utility used by inchar(), for base_encode()
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
void ast_var_delete(struct ast_var_t *var)
Definition: extconf.c:2473
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528

◆ sip_request_call()

static struct ast_channel * sip_request_call ( const char *  type,
struct ast_format_cap cap,
const struct ast_assigned_ids assignedids,
const struct ast_channel requestor,
const char *  dest,
int *  cause 
)
static

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. And after that, a [![fromuser][@fromdomain]] argument.
*  Leave those blank to use the defaults.
* 

Definition at line 30793 of file chan_sip.c.

References __set_address_from_contact(), args, AST_APP_ARG, ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_CHANNEL_UNACCEPTABLE, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNREGISTERED, ast_channel_unlock, ast_copy_string(), ast_debug, AST_DECLARE_APP_ARGS, ast_format_cap_append_from_cap(), ast_format_cap_empty(), ast_format_cap_get_compatible(), ast_format_cap_get_names(), AST_FORMAT_CAP_NAMES_LEN, ast_log, AST_MEDIA_TYPE_UNKNOWN, AST_NONSTANDARD_APP_ARGS, ast_read_threadstorage_callid(), ast_sip_ouraddrfor(), AST_STATE_DOWN, ast_str_alloca, ast_string_field_set, ast_strlen_zero, ast_test_flag, AST_TRANSPORT_TCP, AST_TRANSPORT_TLS, AST_TRANSPORT_UDP, ast_update_use_count(), build_via(), sip_pvt::caps, change_callid_pvt(), check_for_nat(), create_addr(), dialog_unlink_all(), dialog_unref, do_setnat(), ext, exten, sip_pvt::flags, sip_peer::fullcontact, host, sip_pvt::jointcaps, LOG_ERROR, LOG_NOTICE, LOG_WARNING, sip_pvt::natdetected, NULL, sip_pvt::options, sip_pvt::ourip, sip_invite_param::outboundproxy, sip_pvt::outgoing_call, sip_pvt::peername, sip_monitor_instance::peername, sip_pvt::prefcaps, proxy_from_config(), sip_pvt::relatedpeer, restart_monitor(), sip_pvt::sa, set_peer_nat(), set_socket_transport(), sip_alloc, SIP_INVITE, SIP_NAT_FORCE_RPORT, sip_new(), SIP_PAGE2_SYMMETRICRTP, SIP_PAGE3_NAT_AUTO_COMEDIA, SIP_PAGE3_NAT_AUTO_RPORT, sip_pvt_lock, sip_pvt_unlock, sip_pvt::socket, tmp(), and TRUE.

30794 {
30795  struct sip_pvt *p;
30796  struct ast_channel *tmpc = NULL;
30797  char *ext = NULL, *host;
30798  char tmp[256];
30799  struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
30800  char *dnid;
30801  char *secret = NULL;
30802  char *md5secret = NULL;
30803  char *authname = NULL;
30804  char *trans = NULL;
30805  char dialstring[256];
30806  char *remote_address;
30807  enum ast_transport transport = 0;
30808  ast_callid callid;
30810  AST_APP_ARG(peerorhost);
30811  AST_APP_ARG(exten);
30812  AST_APP_ARG(remote_address);
30813  );
30814 
30815  if (ast_format_cap_empty(cap)) {
30816  ast_log(LOG_NOTICE, "Asked to get a channel without offering any format\n");
30817  *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; /* Can't find codec to connect to host */
30818  return NULL;
30819  }
30820  ast_debug(1, "Asked to create a SIP channel with formats: %s\n", ast_format_cap_get_names(cap, &codec_buf));
30821 
30822  if (ast_strlen_zero(dest)) {
30823  ast_log(LOG_ERROR, "Unable to create channel with empty destination.\n");
30825  return NULL;
30826  }
30827 
30828  callid = ast_read_threadstorage_callid();
30829  if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE, NULL, callid))) {
30830  ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", dest);
30831  *cause = AST_CAUSE_SWITCH_CONGESTION;
30832  return NULL;
30833  }
30834 
30835  p->outgoing_call = TRUE;
30836 
30837  snprintf(dialstring, sizeof(dialstring), "%s/%s", type, dest);
30838  ast_string_field_set(p, dialstring, dialstring);
30839 
30840  if (!(p->options = ast_calloc(1, sizeof(*p->options)))) {
30841  dialog_unlink_all(p);
30842  dialog_unref(p, "unref dialog p from mem fail");
30843  /* sip_destroy(p); */
30844  ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n");
30845  *cause = AST_CAUSE_SWITCH_CONGESTION;
30846  return NULL;
30847  }
30848 
30849  /* Save the destination, the SIP dial string */
30850  ast_copy_string(tmp, dest, sizeof(tmp));
30851 
30852  /* Find optional DNID (SIP to-uri) and From-CLI (SIP from-uri)
30853  * and strip it from the dial string:
30854  * [!touser[@todomain][![fromuser][@fromdomain]]]
30855  * For historical reasons, the touser@todomain is passed as dnid
30856  * while fromuser@fromdomain are split immediately. Passing a
30857  * todomain without touser will create an invalid SIP message. */
30858  dnid = strchr(tmp, '!');
30859  if (dnid != NULL) {
30860  char *fromuser_and_domain;
30861 
30862  *dnid++ = '\0';
30863  if ((fromuser_and_domain = strchr(dnid, '!'))) {
30864  char *forward_compat;
30865  char *fromdomain;
30866 
30867  *fromuser_and_domain++ = '\0';
30868 
30869  /* Cut it at a trailing NUL or trailing '!' for
30870  * forward compatibility with extra arguments
30871  * in the future. */
30872  if ((forward_compat = strchr(fromuser_and_domain, '!'))) {
30873  /* Ignore the rest.. */
30874  *forward_compat = '\0';
30875  }
30876 
30877  if ((fromdomain = strchr(fromuser_and_domain, '@'))) {
30878  *fromdomain++ = '\0';
30879  /* Set fromdomain. */
30880  if (!ast_strlen_zero(fromdomain)) {
30881  ast_string_field_set(p, fromdomain, fromdomain);
30882  }
30883  }
30884 
30885  /* Set fromuser. */
30886  if (!ast_strlen_zero(fromuser_and_domain)) {
30887  ast_string_field_set(p, fromuser, fromuser_and_domain);
30888  }
30889  }
30890 
30891  /* Set DNID (touser/todomain). */
30892  if (!ast_strlen_zero(dnid)) {
30893  ast_string_field_set(p, todnid, dnid);
30894  }
30895  }
30896 
30897  /* If stripping the DNID left us with nothing, bail out */
30898  if (ast_strlen_zero(tmp)) {
30899  dialog_unlink_all(p);
30900  dialog_unref(p, "unref dialog p from bad destination");
30902  return NULL;
30903  }
30904 
30905  /* Divvy up the items separated by slashes */
30906  AST_NONSTANDARD_APP_ARGS(args, tmp, '/');
30907 
30908  /* Find at sign - @ */
30909  host = strchr(args.peerorhost, '@');
30910  if (host) {
30911  *host++ = '\0';
30912  ext = args.peerorhost;
30913  secret = strchr(ext, ':');
30914  }
30915  if (secret) {
30916  *secret++ = '\0';
30917  md5secret = strchr(secret, ':');
30918  }
30919  if (md5secret) {
30920  *md5secret++ = '\0';
30921  authname = strchr(md5secret, ':');
30922  }
30923  if (authname) {
30924  *authname++ = '\0';
30925  trans = strchr(authname, ':');
30926  }
30927  if (trans) {
30928  *trans++ = '\0';
30929  if (!strcasecmp(trans, "tcp"))
30930  transport = AST_TRANSPORT_TCP;
30931  else if (!strcasecmp(trans, "tls"))
30932  transport = AST_TRANSPORT_TLS;
30933  else {
30934  if (strcasecmp(trans, "udp"))
30935  ast_log(LOG_WARNING, "'%s' is not a valid transport option to Dial() for SIP calls, using udp by default.\n", trans);
30936  transport = AST_TRANSPORT_UDP;
30937  }
30938  } else { /* use default */
30939  transport = AST_TRANSPORT_UDP;
30940  }
30941 
30942  if (!host) {
30943  ext = args.exten;
30944  host = args.peerorhost;
30945  remote_address = args.remote_address;
30946  } else {
30947  remote_address = args.remote_address;
30948  if (!ast_strlen_zero(args.exten)) {
30949  ast_log(LOG_NOTICE, "Conflicting extension values given. Using '%s' and not '%s'\n", ext, args.exten);
30950  }
30951  }
30952 
30953  if (!ast_strlen_zero(remote_address)) {
30954  p->options->outboundproxy = proxy_from_config(remote_address, 0, NULL);
30955  if (!p->options->outboundproxy) {
30956  ast_log(LOG_WARNING, "Unable to parse outboundproxy %s. We will not use this remote IP address\n", remote_address);
30957  }
30958  }
30959 
30960  set_socket_transport(&p->socket, transport);
30961 
30962  /* We now have
30963  host = peer name, DNS host name or DNS domain (for SRV)
30964  ext = extension (user part of URI)
30965  dnid = destination of the call (applies to the To: header)
30966  */
30967  if (create_addr(p, host, NULL, 1)) {
30968  *cause = AST_CAUSE_UNREGISTERED;
30969  ast_debug(3, "Cant create SIP call - target device not registered\n");
30970  dialog_unlink_all(p);
30971  dialog_unref(p, "unref dialog p UNREGISTERED");
30972  /* sip_destroy(p); */
30973  return NULL;
30974  }
30975  if (ast_strlen_zero(p->peername) && ext)
30976  ast_string_field_set(p, peername, ext);
30977  /* Recalculate our side, and recalculate Call ID */
30978  ast_sip_ouraddrfor(&p->sa, &p->ourip, p);
30979  /* When chan_sip is first loaded or reloaded, we need to check for NAT and set the appropiate flags
30980  now that we have the auto_* settings. */
30981  check_for_nat(&p->sa, p);
30982  /* If there is a peer related to this outgoing call and it hasn't re-registered after
30983  a reload, we need to set the peer's NAT flags accordingly. */
30984  if (p->relatedpeer) {
30985 
30989  /* We need to make an attempt to determine if a peer is behind NAT
30990  if the peer has the flags auto_force_rport or auto_comedia set. */
30991  struct ast_sockaddr tmpaddr;
30992 
30994 
30995  check_for_nat(&tmpaddr, p);
30996  }
30997 
30998  set_peer_nat(p, p->relatedpeer);
30999  }
31000 
31001  do_setnat(p);
31002 
31003  build_via(p);
31004 
31005  /* Change the dialog callid. */
31006  change_callid_pvt(p, NULL);
31007 
31008  /* We have an extension to call, don't use the full contact here */
31009  /* This to enable dialing registered peers with extension dialling,
31010  like SIP/peername/extension
31011  SIP/peername will still use the full contact
31012  */
31013  if (ext) {
31014  ast_string_field_set(p, username, ext);
31015  ast_string_field_set(p, fullcontact, NULL);
31016  }
31017  if (secret && !ast_strlen_zero(secret))
31018  ast_string_field_set(p, peersecret, secret);
31019 
31020  if (md5secret && !ast_strlen_zero(md5secret))
31021  ast_string_field_set(p, peermd5secret, md5secret);
31022 
31023  if (authname && !ast_strlen_zero(authname))
31024  ast_string_field_set(p, authname, authname);
31025 #if 0
31026  printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host);
31027 #endif
31030 
31031  sip_pvt_lock(p);
31032 
31033  tmpc = sip_new(p, AST_STATE_DOWN, host, assignedids, requestor, callid); /* Place the call */
31034 
31035  sip_pvt_unlock(p);
31036  if (!tmpc) {
31037  dialog_unlink_all(p);
31038  /* sip_destroy(p); */
31039  } else {
31040  ast_channel_unlock(tmpc);
31041  }
31042  dialog_unref(p, "toss pvt ptr at end of sip_request_call");
31044  restart_monitor();
31045  return tmpc;
31046 }
static const char type[]
Definition: chan_ooh323.c:109
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
Main Channel structure associated with a channel.
struct ast_format_cap * prefcaps
Definition: sip.h:1103
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&#39;d proxy. If dest is non-NULL, no allocation is performed a...
Definition: chan_sip.c:3491
struct sip_proxy * outboundproxy
Definition: sip.h:870
static void build_via(struct sip_pvt *p)
Build a Via header for a request.
Definition: chan_sip.c:3847
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define AST_CAUSE_SWITCH_CONGESTION
Definition: causes.h:122
struct sip_peer * relatedpeer
Definition: sip.h:1171
ast_transport
Definition: netsock2.h:59
#define LOG_WARNING
Definition: logger.h:274
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:326
struct sip_socket socket
Definition: sip.h:1066
static int tmp()
Definition: bt_open.c:389
unsigned short outgoing_call
Definition: sip.h:1083
struct ast_sockaddr ourip
Definition: sip.h:1136
#define SIP_NAT_FORCE_RPORT
Definition: sip.h:283
struct ast_format_cap * jointcaps
Definition: sip.h:1100
unsigned int ast_callid
Definition: logger.h:87
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?
Definition: chan_sip.c:3866
struct ast_flags flags[3]
Definition: sip.h:1075
#define ast_str_alloca(init_len)
Definition: strings.h:800
const char * args
#define NULL
Definition: resample.c:96
void ast_update_use_count(void)
Notify when usecount has been changed.
Definition: loader.c:2528
const char * ext
Definition: http.c:147
Socket address structure.
Definition: netsock2.h:97
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
struct sip_invite_param * options
Definition: sip.h:1183
ast_callid ast_read_threadstorage_callid(void)
extracts the callerid from the thread
Definition: logger.c:1962
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
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 stor...
Definition: chan_sip.c:3367
struct ast_sockaddr sa
Definition: sip.h:1125
#define SIP_PAGE2_SYMMETRICRTP
Definition: sip.h:327
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static char host[256]
Definition: muted.c:77
struct ast_format_cap * caps
Definition: sip.h:1099
#define sip_alloc(callid, addr, useglobal_nat, intended_method, req, logger_callid)
Definition: dialog.h:39
static struct ast_channel * sip_new(struct sip_pvt *i, int state, const char *title, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, ast_callid callid)
Initiate a call in the SIP channel.
Definition: chan_sip.c:8161
#define AST_CAUSE_DESTINATION_OUT_OF_ORDER
Definition: causes.h:114
#define LOG_ERROR
Definition: logger.h:285
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
#define AST_CAUSE_CHANNEL_UNACCEPTABLE
Definition: causes.h:101
const ast_string_field fullcontact
Definition: sip.h:1306
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the &#39;nonstandard&#39; argument separation process for an application.
static void change_callid_pvt(struct sip_pvt *pvt, const char *callid)
Definition: chan_sip.c:8860
#define LOG_NOTICE
Definition: logger.h:263
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition: format_cap.c:736
#define SIP_PAGE3_NAT_AUTO_RPORT
Definition: sip.h:386
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
static int __set_address_from_contact(const char *fullcontact, struct ast_sockaddr *addr, int tcp)
Definition: chan_sip.c:16892
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define AST_CAUSE_UNREGISTERED
Definition: causes.h:153
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
const ast_string_field peername
Definition: sip.h:1063
static void do_setnat(struct sip_pvt *p)
Set nat mode on the various data sockets.
Definition: chan_sip.c:5862
#define SIP_PAGE3_NAT_AUTO_COMEDIA
Definition: sip.h:387
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define TRUE
Definition: app_minivm.c:518
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 TR...
Definition: chan_sip.c:6317
static int restart_monitor(void)
Start the channel monitor thread.
Definition: chan_sip.c:30078
int ast_format_cap_empty(const struct ast_format_cap *cap)
Determine if a format cap has no formats in it.
Definition: format_cap.c:746
int ast_format_cap_append_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type)
Append the formats of provided type in src to dst.
Definition: format_cap.c:269
static void check_for_nat(const struct ast_sockaddr *them, struct sip_pvt *p)
Check and see if the requesting UA is likely to be behind a NAT.
Definition: chan_sip.c:19134
static void set_socket_transport(struct sip_socket *socket, int transport)
Definition: chan_sip.c:16629
#define AST_CAUSE_BEARERCAPABILITY_NOTAVAIL
Definition: causes.h:129
int ast_format_cap_get_compatible(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2, struct ast_format_cap *result)
Find the compatible formats between two capabilities structures.
Definition: format_cap.c:630
static void set_peer_nat(const struct sip_pvt *p, struct sip_peer *peer)
Set the peers nat flags if they are using auto_* settings.
Definition: chan_sip.c:19103
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
unsigned short natdetected
Definition: sip.h:1094
#define AST_APP_ARG(name)
Define an application argument.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ sip_reregister()

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.

Note
Run by the sched thread.

Definition at line 15868 of file chan_sip.c.

References __sip_do_register(), ao2_t_ref, append_history, ast_log, sip_registry::call, sip_registry::configured_expiry, sip_pvt::do_history, sip_registry::expire, sip_registry::expiry, sip_registry::hostname, LOG_NOTICE, REG_STATE_AUTHSENT, REG_STATE_FAILED, REG_STATE_NOAUTH, REG_STATE_REGISTERED, REG_STATE_REGSENT, REG_STATE_REJECTED, REG_STATE_TIMEOUT, REG_STATE_UNREGISTERED, sip_registry::regstate, sipdebug, and sip_registry::username.

Referenced by __start_reregister_timeout(), and sip_show_sched().

15869 {
15870  /* if we are here, we know that we need to reregister. */
15871  struct sip_registry *r = (struct sip_registry *) data;
15872 
15873  if (r->call && r->call->do_history) {
15874  append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname);
15875  }
15876  /* Since registry's are only added/removed by the monitor thread, this
15877  may be overkill to reference/dereference at all here */
15878  if (sipdebug) {
15879  ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname);
15880  }
15881 
15882  r->expire = -1;
15883  r->expiry = r->configured_expiry;
15884  switch (r->regstate) {
15886  case REG_STATE_REGSENT:
15887  case REG_STATE_AUTHSENT:
15888  break;
15889  case REG_STATE_REJECTED:
15890  case REG_STATE_NOAUTH:
15891  case REG_STATE_FAILED:
15892  /* Restarting registration as unregistered */
15894  break;
15895  case REG_STATE_TIMEOUT:
15896  case REG_STATE_REGISTERED:
15897  /* Registration needs to be renewed. */
15899  break;
15900  }
15901  __sip_do_register(r);
15902  ao2_t_ref(r, -1, "Scheduled reregister timeout complete");
15903  return 0;
15904 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
const ast_string_field hostname
Definition: sip.h:1414
int expire
Definition: sip.h:1418
const ast_string_field username
Definition: sip.h:1414
enum sipregistrystate regstate
Definition: sip.h:1425
struct sip_pvt * call
Definition: sip.h:1424
int configured_expiry
Definition: sip.h:1419
Registrations with other SIP proxies.
Definition: sip.h:1396
static int __sip_do_register(struct sip_registry *r)
Register with SIP proxy.
Definition: chan_sip.c:15909
#define ast_log
Definition: astobj2.c:42
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
#define LOG_NOTICE
Definition: logger.h:263
unsigned short do_history
Definition: sip.h:1078
int expiry
Definition: sip.h:1420
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406

◆ sip_rtp_read()

static struct ast_frame* sip_rtp_read ( struct ast_channel ast,
struct sip_pvt p,
int *  faxdetect 
)
static

Read RTP from network.

Definition at line 8631 of file chan_sip.c.

References ao2_ref, ast_channel_fdno(), ast_channel_name(), ast_channel_nativeformats(), ast_channel_nativeformats_set(), ast_channel_readformat(), ast_channel_writeformat(), ast_debug, ast_dsp_free(), ast_dsp_process(), ast_dsp_set_features(), ast_format_cap_alloc, ast_format_cap_append, ast_format_cap_append_from_cap(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_iscompatible_format(), ast_format_cap_remove_by_type(), AST_FORMAT_CMP_NOT_EQUAL, ast_format_get_name(), AST_FRAME_DTMF, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_VOICE, ast_free, ast_frfree, AST_MEDIA_TYPE_AUDIO, AST_MEDIA_TYPE_UNKNOWN, ast_null_frame, ast_rtp_instance_read(), ast_set_read_format(), ast_set_write_format(), ast_str_append(), ast_str_buffer(), ast_str_create, ast_test_flag, ast_udptl_read(), ast_verb, ast_frame::data, ast_frame::datalen, sip_pvt::dsp, DSP_FEATURE_DIGIT_DETECT, sip_pvt::flags, ast_frame_subclass::format, ast_frame::frametype, ast_frame_subclass::integer, sip_pvt::jointcaps, NULL, out, sip_pvt::owner, ast_frame::ptr, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, sipdebug_text, ast_frame::subclass, sip_pvt::trtp, sip_pvt::udptl, and sip_pvt::vrtp.

Referenced by sip_read().

8632 {
8633  /* Retrieve audio/etc from channel. Assumes p->lock is already held. */
8634  struct ast_frame *f;
8635 
8636  if (!p->rtp) {
8637  /* We have no RTP allocated for this channel */
8638  return &ast_null_frame;
8639  }
8640 
8641  switch(ast_channel_fdno(ast)) {
8642  case 0:
8643  f = ast_rtp_instance_read(p->rtp, 0); /* RTP Audio */
8644  break;
8645  case 1:
8646  f = ast_rtp_instance_read(p->rtp, 1); /* RTCP Control Channel */
8647  break;
8648  case 2:
8649  f = ast_rtp_instance_read(p->vrtp, 0); /* RTP Video */
8650  break;
8651  case 3:
8652  f = ast_rtp_instance_read(p->vrtp, 1); /* RTCP Control Channel for video */
8653  break;
8654  case 4:
8655  f = ast_rtp_instance_read(p->trtp, 0); /* RTP Text */
8656  if (sipdebug_text) {
8657  struct ast_str *out = ast_str_create(f->datalen * 4 + 6);
8658  int i;
8659  unsigned char* arr = f->data.ptr;
8660  do {
8661  if (!out) {
8662  break;
8663  }
8664  for (i = 0; i < f->datalen; i++) {
8665  ast_str_append(&out, 0, "%c", (arr[i] > ' ' && arr[i] < '}') ? arr[i] : '.');
8666  }
8667  ast_str_append(&out, 0, " -> ");
8668  for (i = 0; i < f->datalen; i++) {
8669  ast_str_append(&out, 0, "%02hhX ", arr[i]);
8670  }
8671  ast_verb(0, "%s\n", ast_str_buffer(out));
8672  ast_free(out);
8673  } while (0);
8674  }
8675  break;
8676  case 5:
8677  f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */
8678  break;
8679  default:
8680  f = &ast_null_frame;
8681  }
8682  /* Don't forward RFC2833 if we're not supposed to */
8683  if (f && (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END) &&
8684  (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833)) {
8685  ast_debug(1, "Ignoring DTMF (%c) RTP frame because dtmfmode is not RFC2833\n", f->subclass.integer);
8686  ast_frfree(f);
8687  return &ast_null_frame;
8688  }
8689 
8690  /* We already hold the channel lock */
8691  if (!p->owner || (f && f->frametype != AST_FRAME_VOICE)) {
8692  return f;
8693  }
8694 
8696  struct ast_format_cap *caps;
8697 
8699  ast_debug(1, "Bogus frame of format '%s' received from '%s'!\n",
8701  ast_frfree(f);
8702  return &ast_null_frame;
8703  }
8704  ast_debug(1, "Oooh, format changed to %s\n",
8706 
8708  if (caps) {
8711  ast_format_cap_append(caps, f->subclass.format, 0);
8713  ao2_ref(caps, -1);
8714  }
8717  }
8718 
8719  if (f && p->dsp) {
8720  f = ast_dsp_process(p->owner, p->dsp, f);
8721  if (f && f->frametype == AST_FRAME_DTMF) {
8722  if (f->subclass.integer == 'f') {
8723  ast_debug(1, "Fax CNG detected on %s\n", ast_channel_name(ast));
8724  *faxdetect = 1;
8725  /* If we only needed this DSP for fax detection purposes we can just drop it now */
8726  if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) {
8728  } else {
8729  ast_dsp_free(p->dsp);
8730  p->dsp = NULL;
8731  }
8732  } else {
8733  ast_debug(1, "* Detected inband DTMF '%c'\n", f->subclass.integer);
8734  }
8735  }
8736  }
8737 
8738  return f;
8739 }
struct ast_frame * ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *inf)
Return AST_FRAME_NULL frames when there is silence, AST_FRAME_BUSY on busies, and call progress...
Definition: dsp.c:1494
#define SIP_DTMF_INBAND
Definition: sip.h:277
struct ast_rtp_instance * trtp
Definition: sip.h:1176
#define ast_test_flag(p, flag)
Definition: utils.h:63
void ast_dsp_free(struct ast_dsp *dsp)
Definition: dsp.c:1770
#define DSP_FEATURE_DIGIT_DETECT
Definition: dsp.h:28
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define SIP_DTMF_RFC2833
Definition: sip.h:276
struct ast_format_cap * jointcaps
Definition: sip.h:1100
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
struct ast_flags flags[3]
Definition: sip.h:1075
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
#define NULL
Definition: resample.c:96
#define AST_FRAME_DTMF
#define ast_verb(level,...)
Definition: logger.h:463
struct ast_frame_subclass subclass
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
enum ast_format_cmp_res ast_format_cap_iscompatible_format(const struct ast_format_cap *cap, const struct ast_format *format)
Find if ast_format is within the capabilities of the ast_format_cap object.
Definition: format_cap.c:583
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
Definition: channel.c:5849
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_format_cap_append(cap, format, framing)
Definition: format_cap.h:103
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
Sets write format on channel chan.
Definition: channel.c:5890
struct ast_dsp * dsp
Definition: sip.h:1169
struct ast_udptl * udptl
Definition: sip.h:1115
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
void ast_format_cap_remove_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Remove all formats matching a specific format type.
Definition: format_cap.c:525
int ast_channel_fdno(const struct ast_channel *chan)
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
struct ast_rtp_instance * vrtp
Definition: sip.h:1175
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1755
#define ast_free(a)
Definition: astmm.h:182
struct ast_channel * owner
Definition: sip.h:1138
struct ast_rtp_instance * rtp
Definition: sip.h:1174
static int sipdebug_text
extra debugging for &#39;text&#39; related events. At the moment this is set together with sip_debug_console...
Definition: chan_sip.c:922
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
struct ast_frame * ast_udptl_read(struct ast_udptl *udptl)
Definition: udptl.c:762
struct ast_frame ast_null_frame
Definition: main/frame.c:79
FILE * out
Definition: utils/frame.c:33
#define SIP_DTMF
Definition: sip.h:275
const char * ast_channel_name(const struct ast_channel *chan)
#define ast_frfree(fr)
Data structure associated with a single frame of data.
union ast_frame::@263 data
enum ast_frame_type frametype
int ast_format_cap_append_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type)
Append the formats of provided type in src to dst.
Definition: format_cap.c:269
struct ast_format * format
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
struct ast_frame * ast_rtp_instance_read(struct ast_rtp_instance *instance, int rtcp)
Receive a frame over RTP.
Definition: rtp_engine.c:578
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ sip_sanitized_host()

static const char* sip_sanitized_host ( const char *  host)
static

Definition at line 16089 of file chan_sip.c.

References ast_sockaddr_parse(), ast_sockaddr_stringify_host_remote(), host, and PARSE_PORT_FORBID.

Referenced by transmit_register().

16090 {
16091  struct ast_sockaddr addr;
16092 
16093  /* peer/sip_pvt->tohost and sip_registry->hostname should never have a port
16094  * in them, so we use PARSE_PORT_FORBID here. If this lookup fails, we return
16095  * the original host which is most likely a host name and not an IP. */
16096  memset(&addr, 0, sizeof(addr));
16097  if (!ast_sockaddr_parse(&addr, host, PARSE_PORT_FORBID)) {
16098  return host;
16099  }
16100  return ast_sockaddr_stringify_host_remote(&addr);
16101 }
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
Socket address structure.
Definition: netsock2.h:97
static char host[256]
Definition: muted.c:77
static char * ast_sockaddr_stringify_host_remote(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only, suitable for a URL (with brack...
Definition: netsock2.h:349

◆ sip_scheddestroy()

void sip_scheddestroy ( struct sip_pvt p,
int  ms 
)

◆ sip_scheddestroy_final()

void sip_scheddestroy_final ( struct sip_pvt p,
int  ms 
)

Schedule final destruction of SIP dialog.

Note
This cannot 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 4557 of file chan_sip.c.

References sip_pvt::final_destruction_scheduled, and sip_scheddestroy_full().

Referenced by handle_request_bye().

4558 {
4559  if (p->final_destruction_scheduled) {
4560  return; /* already set final destruction */
4561  }
4562 
4563  if (!sip_scheddestroy_full(p, ms)) {
4565  }
4566 }
unsigned short final_destruction_scheduled
Definition: sip.h:1081
static int sip_scheddestroy_full(struct sip_pvt *p, int ms)
Definition: chan_sip.c:4514

◆ sip_scheddestroy_full()

static int sip_scheddestroy_full ( struct sip_pvt p,
int  ms 
)
static

Definition at line 4514 of file chan_sip.c.

References __sip_scheddestroy(), ast_free, ast_malloc, ast_sched_add(), ast_verbose(), sip_pvt::callid, dialog_ref, dialog_unref, global_t1, global_timer_b, sip_pvt::method, sip_scheddestroy_data::ms, sip_scheddestroy_data::pvt, sip_debug_test_pvt(), sip_methods, cfsip_methods::text, sip_pvt::timer_b, and sip_pvt::timer_t1.

Referenced by sip_scheddestroy(), and sip_scheddestroy_final().

4515 {
4516  struct sip_scheddestroy_data *sched_data;
4517 
4518  if (ms < 0) {
4519  if (p->timer_t1 == 0) {
4520  p->timer_t1 = global_t1; /* Set timer T1 if not set (RFC 3261) */
4521  }
4522  if (p->timer_b == 0) {
4523  p->timer_b = global_timer_b; /* Set timer B if not set (RFC 3261) */
4524  }
4525  ms = p->timer_t1 * 64;
4526  }
4527  if (sip_debug_test_pvt(p)) {
4528  ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n",
4529  p->callid, ms, sip_methods[p->method].text);
4530  }
4531 
4532  sched_data = ast_malloc(sizeof(*sched_data));
4533  if (!sched_data) {
4534  /* Uh Oh. Expect bad behavior. */
4535  return -1;
4536  }
4537  sched_data->pvt = p;
4538  sched_data->ms = ms;
4539  dialog_ref(p, "Destroy action");
4540  if (ast_sched_add(sched, 0, __sip_scheddestroy, sched_data) < 0) {
4541  /* Uh Oh. Expect bad behavior. */
4542  dialog_unref(p, "Failed to schedule destroy action");
4543  ast_free(sched_data);
4544  return -1;
4545  }
4546  return 0;
4547 }
static const struct cfsip_methods sip_methods[]
Definition: sched.c:76
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
static int __sip_scheddestroy(const void *data)
Definition: chan_sip.c:4484
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
const ast_string_field callid
Definition: sip.h:1063
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
int method
Definition: sip.h:1009
int timer_b
Definition: sip.h:1096
static int global_timer_b
Definition: chan_sip.c:849
#define ast_free(a)
Definition: astmm.h:182
int timer_t1
Definition: sip.h:1095
#define dialog_ref(dialog, tag)
when we create or delete references, make sure to use these functions so we keep track of the refcoun...
Definition: dialog.h:32
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565
static int sip_debug_test_pvt(struct sip_pvt *p)
Test PVT for debugging output.
Definition: chan_sip.c:3649
char *const text
Definition: chan_sip.c:737
static int global_t1
Definition: chan_sip.c:847
struct sip_pvt * pvt
Definition: chan_sip.c:4479

◆ sip_send_all_mwi_subscriptions()

static void sip_send_all_mwi_subscriptions ( void  )
static

Send all MWI subscriptions.

Definition at line 34326 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ao2_t_ref, and start_mwi_subscription().

Referenced by load_module(), network_change_sched_cb(), and sip_do_reload().

34327 {
34328  struct ao2_iterator iter;
34329  struct sip_subscription_mwi *mwi;
34330 
34332  while ((mwi = ao2_t_iterator_next(&iter, "sip_send_all_mwi_subscriptions iter"))) {
34333  start_mwi_subscription(mwi, 1);
34334  ao2_t_ref(mwi, -1, "sip_send_all_mwi_subscriptions iter");
34335  }
34336  ao2_iterator_destroy(&iter);
34337 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_t_iterator_next(iter, tag)
Definition: astobj2.h:1931
Definition of an MWI subscription to another server.
Definition: sip.h:1454
static struct ao2_container * subscription_mwi_list
The MWI subscription list.
Definition: chan_sip.c:1064
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
static void start_mwi_subscription(struct sip_subscription_mwi *mwi, int ms)
Definition: chan_sip.c:14989
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

◆ sip_send_all_registers()

static void sip_send_all_registers ( void  )
static

Send all known registrations.

Definition at line 34298 of file chan_sip.c.

References ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_iterator_next, ao2_t_ref, ao2_unlock, default_expiry, and start_reregister_timeout().

Referenced by load_module(), network_change_sched_cb(), and sip_do_reload().

34299 {
34300  int ms;
34301  int regspacing;
34302  struct ao2_iterator iter;
34303  struct sip_registry *iterator;
34304 
34306  return;
34307  }
34308  regspacing = default_expiry * 1000 / ao2_container_count(registry_list);
34309  if (regspacing > 100) {
34310  regspacing = 100;
34311  }
34312  ms = regspacing;
34313 
34314  iter = ao2_iterator_init(registry_list, 0);
34315  while ((iterator = ao2_t_iterator_next(&iter, "sip_send_all_registers iter"))) {
34316  ao2_lock(iterator);
34317  ms += regspacing;
34318  start_reregister_timeout(iterator, ms);
34319  ao2_unlock(iterator);
34320  ao2_t_ref(iterator, -1, "sip_send_all_registers iter");
34321  }
34322  ao2_iterator_destroy(&iter);
34323 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
Registrations with other SIP proxies.
Definition: sip.h:1396
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_unlock(a)
Definition: astobj2.h:730
static struct ao2_container * registry_list
The register list: Other SIP proxies we register with and receive calls from.
Definition: chan_sip.c:1061
#define ao2_lock(a)
Definition: astobj2.h:718
static int default_expiry
Definition: chan_sip.c:669
static void start_reregister_timeout(struct sip_registry *reg, int ms)
Definition: chan_sip.c:15945
#define ao2_t_iterator_next(iter, tag)
Definition: astobj2.h:1931
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

◆ sip_send_keepalive()

static int sip_send_keepalive ( const void *  data)
static

Send keep alive packet to peer.

Definition at line 30469 of file chan_sip.c.

References sip_peer::addr, ast_log, AST_SCHED_REPLACE_UNREF, ast_sendto(), ast_sockaddr_isnull(), ast_sockaddr_stringify(), AST_TRANSPORT_TCP, AST_TRANSPORT_TLS, AST_TRANSPORT_UDP, errno, sip_socket::fd, keepalive, sip_peer::keepalive, sip_peer::keepalivesend, LOG_WARNING, sip_ref_peer, sip_tcptls_write(), sip_unref_peer, sipsock, sip_peer::socket, sip_socket::tcptls_session, sip_socket::type, and XMIT_ERROR.

Referenced by sip_keepalive_all_peers().

30470 {
30471  struct sip_peer *peer = (struct sip_peer*) data;
30472  int res = 0;
30473  const char keepalive[] = "\r\n";
30474  size_t count = sizeof(keepalive) - 1;
30475 
30476  peer->keepalivesend = -1;
30477 
30478  if (!peer->keepalive || ast_sockaddr_isnull(&peer->addr)) {
30479  sip_unref_peer(peer, "release keepalive peer ref");
30480  return 0;
30481  }
30482 
30483  /* Send the packet out using the proper method for this peer */
30484  if ((peer->socket.fd != -1) && (peer->socket.type == AST_TRANSPORT_UDP)) {
30485  res = ast_sendto(peer->socket.fd, keepalive, count, 0, &peer->addr);
30486  } else if ((peer->socket.type & (AST_TRANSPORT_TCP | AST_TRANSPORT_TLS)) &&
30487  peer->socket.tcptls_session) {
30488  res = sip_tcptls_write(peer->socket.tcptls_session, keepalive, count);
30489  if (res < -1) {
30490  return 0;
30491  }
30492  } else if (peer->socket.type == AST_TRANSPORT_UDP) {
30493  res = ast_sendto(sipsock, keepalive, count, 0, &peer->addr);
30494  }
30495 
30496  if (res == -1) {
30497  switch (errno) {
30498  case EBADF: /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */
30499  case EHOSTUNREACH: /* Host can't be reached */
30500  case ENETDOWN: /* Interface down */
30501  case ENETUNREACH: /* Network failure */
30502  case ECONNREFUSED: /* ICMP port unreachable */
30503  res = XMIT_ERROR; /* Don't bother with trying to transmit again */
30504  }
30505  }
30506 
30507  if (res != count) {
30508  ast_log(LOG_WARNING, "sip_send_keepalive to %s returned %d: %s\n", ast_sockaddr_stringify(&peer->addr), res, strerror(errno));
30509  }
30510 
30512  peer->keepalive * 1000, sip_send_keepalive, peer,
30513  sip_unref_peer(_data, "removing keepalive peer ref"),
30514  sip_unref_peer(peer, "removing keepalive peer ref"),
30515  sip_ref_peer(peer, "adding keepalive peer ref"));
30516 
30517  sip_unref_peer(peer, "release keepalive peer ref");
30518 
30519  return 0;
30520 }
int keepalive
Definition: sip.h:1360
ssize_t ast_sendto(int sockfd, const void *buf, size_t len, int flags, const struct ast_sockaddr *dest_addr)
Wrapper around sendto(2) that uses ast_sockaddr.
Definition: netsock2.c:614
struct ast_sockaddr addr
Definition: sip.h:1352
int keepalivesend
Definition: sip.h:1361
static uint32_t keepalive
Definition: res_pktccops.c:160
#define LOG_WARNING
Definition: logger.h:274
Definition: sched.c:76
#define sip_ref_peer(peer, tag)
Definition: sip.h:1894
int fd
Definition: sip.h:799
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
#define ast_log
Definition: astobj2.c:42
struct ast_tcptls_session_instance * tcptls_session
Definition: sip.h:801
static int sip_send_keepalive(const void *data)
Send keep alive packet to peer.
Definition: chan_sip.c:30469
#define XMIT_ERROR
Definition: sip.h:58
int errno
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
static int sipsock
Main socket for UDP SIP communication.
Definition: chan_sip.c:1104
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
#define AST_SCHED_REPLACE_UNREF(id, sched, when, callback, data, unrefcall, addfailcall, refcall)
Definition: sched.h:150
enum ast_transport type
Definition: sip.h:798
struct sip_socket socket
Definition: sip.h:1307
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
Definition: chan_sip.c:2608

◆ sip_send_mwi_to_peer()

static int sip_send_mwi_to_peer ( struct sip_peer peer,
int  cache_only 
)
static

Send message waiting indication to alert peer that they've got voicemail.

Note
Both peer and associated sip_pvt must be unlocked prior to calling this function. It's possible that this function will get called during peer destruction as final messages are processed. The peer will still be valid however.
Returns
-1 on failure, 0 on success

Definition at line 29756 of file chan_sip.c.

References sip_peer::addr, 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(), sip_peer::defaddr, default_mwi_from, DEFAULT_TRANS_TIMEOUT, dialog_ref, dialog_unlink_all(), dialog_unref, sip_pvt::flags, sip_peer::flags, get_cached_mwi(), sip_peer::mwi_from, sip_peer::mwipvt, NULL, sip_pvt::ourip, peer_mailboxes_to_str(), sip_pvt::sa, set_socket_transport(), sip_alloc, SIP_NOTIFY, SIP_OUTGOING, SIP_PAGE2_SUBSCRIBEMWIONLY, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), sip_pvt::socket, transmit_notify_with_mwi(), update_peer_lastmsgssent(), vmexten, and sip_peer::vmexten.

Referenced by build_peer(), handle_request_subscribe(), mwi_event_cb(), and register_verify().

29757 {
29758  /* Called with peer lock, but releases it */
29759  struct sip_pvt *p;
29760  int newmsgs = 0, oldmsgs = 0;
29761  const char *vmexten = NULL;
29762 
29763  ao2_lock(peer);
29764 
29765  if (peer->vmexten) {
29766  vmexten = ast_strdupa(peer->vmexten);
29767  }
29768 
29769  if (ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY) && !peer->mwipvt) {
29770  update_peer_lastmsgssent(peer, -1, 1);
29771  ao2_unlock(peer);
29772  return -1;
29773  }
29774 
29775  /* Do we have an IP address? If not, skip this peer */
29776  if (ast_sockaddr_isnull(&peer->addr) && ast_sockaddr_isnull(&peer->defaddr)) {
29777  update_peer_lastmsgssent(peer, -1, 1);
29778  ao2_unlock(peer);
29779  return -1;
29780  }
29781 
29782  /* Attempt to use cached mwi to get message counts. */
29783  if (!get_cached_mwi(peer, &newmsgs, &oldmsgs) && !cache_only) {
29784  /* Fall back to manually checking the mailbox if not cache_only and get_cached_mwi failed */
29785  struct ast_str *mailbox_str = ast_str_alloca(512);
29786  peer_mailboxes_to_str(&mailbox_str, peer);
29787  /* if there is no mailbox do nothing */
29788  if (!ast_str_strlen(mailbox_str)) {
29789  ao2_unlock(peer);
29790  return -1;
29791  }
29792  ao2_unlock(peer);
29793  /* If there is no mailbox do nothing */
29794  if (!ast_str_strlen(mailbox_str)) {
29795  update_peer_lastmsgssent(peer, -1, 0);
29796  return 0;
29797  }
29798  ast_app_inboxcount(ast_str_buffer(mailbox_str), &newmsgs, &oldmsgs);
29799  ao2_lock(peer);
29800  }
29801 
29802  if (peer->mwipvt) {
29803  /* Base message on subscription */
29804  p = dialog_ref(peer->mwipvt, "sip_send_mwi_to_peer: Setting dialog ptr p from peer->mwipvt");
29805  ao2_unlock(peer);
29806  } else {
29807  ao2_unlock(peer);
29808  /* Build temporary dialog for this message */
29809  if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL, 0))) {
29810  update_peer_lastmsgssent(peer, -1, 0);
29811  return -1;
29812  }
29813 
29814  /* If we don't set the socket type to 0, then create_addr_from_peer will fail immediately if the peer
29815  * uses any transport other than UDP. We set the type to 0 here and then let create_addr_from_peer copy
29816  * the peer's socket information to the sip_pvt we just allocated
29817  */
29818  set_socket_transport(&p->socket, 0);
29819  if (create_addr_from_peer(p, peer)) {
29820  /* Maybe they're not registered, etc. */
29821  dialog_unlink_all(p);
29822  dialog_unref(p, "unref dialog p just created via sip_alloc");
29823  update_peer_lastmsgssent(peer, -1, 0);
29824  return -1;
29825  }
29826  /* Recalculate our side, and recalculate Call ID */
29827  ast_sip_ouraddrfor(&p->sa, &p->ourip, p);
29828  build_via(p);
29829 
29830  ao2_lock(peer);
29831  if (!ast_strlen_zero(peer->mwi_from)) {
29832  ast_string_field_set(p, mwi_from, peer->mwi_from);
29833  } else if (!ast_strlen_zero(default_mwi_from)) {
29834  ast_string_field_set(p, mwi_from, default_mwi_from);
29835  }
29836  ao2_unlock(peer);
29837 
29838  /* Change the dialog callid. */
29839  change_callid_pvt(p, NULL);
29840 
29841  /* Destroy this session after 32 secs */
29843  }
29844 
29845  /* 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,
29846  we really need to have a lock on it */
29847  sip_pvt_lock(p);
29848 
29849  /* Send MWI */
29850  ast_set_flag(&p->flags[0], SIP_OUTGOING);
29851  /* the following will decrement the refcount on p as it finishes */
29852  transmit_notify_with_mwi(p, newmsgs, oldmsgs, vmexten);
29853  sip_pvt_unlock(p);
29854  dialog_unref(p, "unref dialog ptr p just before it goes out of scope at the end of sip_send_mwi_to_peer.");
29855 
29856  update_peer_lastmsgssent(peer, ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)), 0);
29857 
29858  return 0;
29859 }
struct ast_sockaddr addr
Definition: sip.h:1352
static void build_via(struct sip_pvt *p)
Build a Via header for a request.
Definition: chan_sip.c:3847
const ast_string_field mwi_from
Definition: sip.h:1306
#define ast_test_flag(p, flag)
Definition: utils.h:63
static int get_cached_mwi(struct sip_peer *peer, int *new, int *old)
Get cached MWI info.
Definition: chan_sip.c:29726
#define ast_set_flag(p, flag)
Definition: utils.h:70
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define DEFAULT_TRANS_TIMEOUT
Definition: sip.h:107
struct sip_socket socket
Definition: sip.h:1066
struct ast_sockaddr defaddr
Definition: sip.h:1362
struct ast_sockaddr ourip
Definition: sip.h:1136
#define SIP_PAGE2_SUBSCRIBEMWIONLY
Definition: sip.h:343
#define ao2_unlock(a)
Definition: astobj2.h:730
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?
Definition: chan_sip.c:3866
struct ast_flags flags[3]
Definition: sip.h:1075
#define ast_str_alloca(init_len)
Definition: strings.h:800
#define NULL
Definition: resample.c:96
const ast_string_field vmexten
Definition: sip.h:1306
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
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 stor...
Definition: chan_sip.c:3367
struct ast_sockaddr sa
Definition: sip.h:1125
#define ao2_lock(a)
Definition: astobj2.h:718
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define sip_alloc(callid, addr, useglobal_nat, intended_method, req, logger_callid)
Definition: dialog.h:39
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
static void update_peer_lastmsgssent(struct sip_peer *peer, int value, int locked)
Definition: chan_sip.c:17841
static void change_callid_pvt(struct sip_pvt *pvt, const char *callid)
Definition: chan_sip.c:8860
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
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)
Definition: chan_sip.c:15584
#define dialog_ref(dialog, tag)
when we create or delete references, make sure to use these functions so we keep track of the refcoun...
Definition: dialog.h:32
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
struct sip_pvt * mwipvt
Definition: sip.h:1367
struct ast_flags flags[3]
Definition: sip.h:1335
static char default_mwi_from[80]
Definition: chan_sip.c:792
static int create_addr_from_peer(struct sip_pvt *r, struct sip_peer *peer)
Create address structure from peer reference. This function copies data from peer to the dialog...
Definition: chan_sip.c:6136
#define SIP_OUTGOING
Definition: sip.h:257
static void set_socket_transport(struct sip_socket *socket, int transport)
Definition: chan_sip.c:16629
void sip_scheddestroy(struct sip_pvt *p, int ms)
Schedule destruction of SIP dialog.
Definition: chan_sip.c:4549
static char vmexten[AST_MAX_EXTENSION]
Definition: chan_skinny.c:206
int ast_app_inboxcount(const char *mailboxes, int *newmsgs, int *oldmsgs)
Determine number of new/old messages in a mailbox.
Definition: main/app.c:677
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514
static void peer_mailboxes_to_str(struct ast_str **mailbox_str, struct sip_peer *peer)
list peer mailboxes to CLI
Definition: chan_sip.c:21157

◆ sip_sendcustominfo()

static int sip_sendcustominfo ( struct ast_channel chan,
const char *  data 
)
static

Send a custom INFO message via AST_CONTROL_CUSTOM indication.

Definition at line 34152 of file chan_sip.c.

References ast_log, ast_sipinfo_send(), ast_strdupa, ast_strlen_zero, LOG_WARNING, NULL, and strsep().

Referenced by load_module().

34153 {
34154  char *info_data, *useragent;
34155 
34156  if (ast_strlen_zero(data)) {
34157  ast_log(LOG_WARNING, "You must provide data to be sent\n");
34158  return 0;
34159  }
34160 
34161  useragent = ast_strdupa(data);
34162  info_data = strsep(&useragent, ",");
34163 
34164  if (ast_sipinfo_send(chan, NULL, "text/plain", info_data, useragent)) {
34165  ast_log(LOG_WARNING, "Failed to create payload for custom SIP INFO\n");
34166  return 0;
34167  }
34168  return 0;
34169 }
int ast_sipinfo_send(struct ast_channel *chan, struct ast_variable *headers, const char *content_type, const char *content, const char *useragent_filter)
Send a customized SIP INFO request.
Definition: sip_api.c:25
#define LOG_WARNING
Definition: logger.h:274
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
char * strsep(char **str, const char *delims)

◆ sip_senddigit_begin()

static int sip_senddigit_begin ( struct ast_channel ast,
char  digit 
)
static

Definition at line 7669 of file chan_sip.c.

References ast_channel_name(), ast_channel_tech_pvt(), ast_debug, ast_rtp_instance_dtmf_begin(), ast_test_flag, sip_pvt::flags, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, sip_pvt_lock, and sip_pvt_unlock.

7670 {
7671  struct sip_pvt *p = ast_channel_tech_pvt(ast);
7672  int res = 0;
7673 
7674  if (!p) {
7675  ast_debug(1, "Asked to begin DTMF digit on channel %s with no pvt; ignoring\n",
7676  ast_channel_name(ast));
7677  return res;
7678  }
7679 
7680  sip_pvt_lock(p);
7681  switch (ast_test_flag(&p->flags[0], SIP_DTMF)) {
7682  case SIP_DTMF_INBAND:
7683  res = -1; /* Tell Asterisk to generate inband indications */
7684  break;
7685  case SIP_DTMF_RFC2833:
7686  if (p->rtp)
7688  break;
7689  default:
7690  break;
7691  }
7692  sip_pvt_unlock(p);
7693 
7694  return res;
7695 }
char digit
#define SIP_DTMF_INBAND
Definition: sip.h:277
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define SIP_DTMF_RFC2833
Definition: sip.h:276
struct ast_flags flags[3]
Definition: sip.h:1075
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
int ast_rtp_instance_dtmf_begin(struct ast_rtp_instance *instance, char digit)
Begin sending a DTMF digit.
Definition: rtp_engine.c:2081
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
struct ast_rtp_instance * rtp
Definition: sip.h:1174
#define SIP_DTMF
Definition: sip.h:275
const char * ast_channel_name(const struct ast_channel *chan)

◆ sip_senddigit_end()

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

References ast_channel_name(), ast_channel_tech_pvt(), ast_debug, ast_rtp_instance_dtmf_end_with_duration(), ast_test_flag, sip_pvt::flags, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, SIP_DTMF_SHORTINFO, sip_pvt_lock, sip_pvt_unlock, and transmit_info_with_digit().

7700 {
7701  struct sip_pvt *p = ast_channel_tech_pvt(ast);
7702  int res = 0;
7703 
7704  if (!p) {
7705  ast_debug(1, "Asked to end DTMF digit on channel %s with no pvt; ignoring\n",
7706  ast_channel_name(ast));
7707  return res;
7708  }
7709 
7710  sip_pvt_lock(p);
7711  switch (ast_test_flag(&p->flags[0], SIP_DTMF)) {
7712  case SIP_DTMF_INFO:
7713  case SIP_DTMF_SHORTINFO:
7714  transmit_info_with_digit(p, digit, duration);
7715  break;
7716  case SIP_DTMF_RFC2833:
7717  if (p->rtp)
7719  break;
7720  case SIP_DTMF_INBAND:
7721  res = -1; /* Tell Asterisk to stop inband indications */
7722  break;
7723  }
7724  sip_pvt_unlock(p);
7725 
7726  return res;
7727 }
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.
Definition: chan_sip.c:16510
char digit
#define SIP_DTMF_INBAND
Definition: sip.h:277
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define SIP_DTMF_RFC2833
Definition: sip.h:276
struct ast_flags flags[3]
Definition: sip.h:1075
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define SIP_DTMF_SHORTINFO
Definition: sip.h:280
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
struct ast_rtp_instance * rtp
Definition: sip.h:1174
#define SIP_DTMF
Definition: sip.h:275
const char * ast_channel_name(const struct ast_channel *chan)
#define SIP_DTMF_INFO
Definition: sip.h:278
int ast_rtp_instance_dtmf_end_with_duration(struct ast_rtp_instance *instance, char digit, unsigned int duration)
Definition: rtp_engine.c:2109

◆ sip_sendhtml()

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

References ast_channel_tech_pvt(), 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, sip_pvt::flags, sip_pvt::initreq, LOG_WARNING, sip_pvt::pendinginvite, sip_debug_test_pvt(), SIP_NEEDREINVITE, SIP_PENDINGBYE, transmit_reinvite_with_sdp(), transmit_response(), and url.

5087 {
5088  struct sip_pvt *p = ast_channel_tech_pvt(chan);
5089 
5090  if (subclass != AST_HTML_URL)
5091  return -1;
5092 
5093  ast_string_field_build(p, url, "<%s>;mode=active", data);
5094 
5095  if (sip_debug_test_pvt(p))
5096  ast_debug(1, "Send URL %s, state = %u!\n", data, ast_channel_state(chan));
5097 
5098  switch (ast_channel_state(chan)) {
5099  case AST_STATE_RING:
5100  transmit_response(p, "100 Trying", &p->initreq);
5101  break;
5102  case AST_STATE_RINGING:
5103  transmit_response(p, "180 Ringing", &p->initreq);
5104  break;
5105  case AST_STATE_UP:
5106  if (!p->pendinginvite) { /* We are up, and have no outstanding invite */
5108  } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
5110  }
5111  break;
5112  default:
5113  ast_log(LOG_WARNING, "Don't know how to send URI when state is %u!\n", ast_channel_state(chan));
5114  }
5115 
5116  return 0;
5117 }
#define FALSE
Definition: app_minivm.c:521
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define LOG_WARNING
Definition: logger.h:274
uint32_t pendinginvite
Definition: sip.h:1147
ast_channel_state
ast_channel states
Definition: channelstate.h:35
struct ast_flags flags[3]
Definition: sip.h:1075
static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req)
Transmit response, no retransmits.
Definition: chan_sip.c:12655
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
struct sip_request initreq
Definition: sip.h:1151
static int transmit_reinvite_with_sdp(struct sip_pvt *p, int t38version, int oldsdp)
Transmit reinvite with SDP.
Definition: chan_sip.c:14212
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
#define AST_HTML_URL
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
Definition: stringfields.h:550
static int sip_debug_test_pvt(struct sip_pvt *p)
Test PVT for debugging output.
Definition: chan_sip.c:3649
#define SIP_PENDINGBYE
Definition: sip.h:262
#define SIP_NEEDREINVITE
Definition: sip.h:261
static char url[512]

◆ sip_sendtext()

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

Definition at line 5130 of file chan_sip.c.

References sip_pvt::allowed_methods, ast_channel_name(), ast_channel_tech_pvt(), ast_debug, ast_string_field_set, ast_verbose(), debug, destroy_msg_headers(), is_method_allowed(), sip_debug_test_pvt(), SIP_MESSAGE, sip_pvt_lock, sip_pvt_unlock, and transmit_message().

5131 {
5132  struct sip_pvt *dialog = ast_channel_tech_pvt(ast);
5133  int debug;
5134 
5135  if (!dialog) {
5136  return -1;
5137  }
5138  /* NOT ast_strlen_zero, because a zero-length message is specifically
5139  * allowed by RFC 3428 (See section 10, Examples) */
5140  if (!text) {
5141  return 0;
5142  }
5144  ast_debug(2, "Trying to send MESSAGE to device that does not support it.\n");
5145  return 0;
5146  }
5147 
5148  debug = sip_debug_test_pvt(dialog);
5149  if (debug) {
5150  ast_verbose("Sending text %s on %s\n", text, ast_channel_name(ast));
5151  }
5152 
5153  /* Setup to send text message */
5154  sip_pvt_lock(dialog);
5155  destroy_msg_headers(dialog);
5157  transmit_message(dialog, 0, 0);
5158  sip_pvt_unlock(dialog);
5159  return 0;
5160 }
static void destroy_msg_headers(struct sip_pvt *pvt)
Definition: chan_sip.c:12887
unsigned int allowed_methods
Definition: sip.h:1196
void * ast_channel_tech_pvt(const struct ast_channel *chan)
static int debug
Global debug status.
Definition: res_xmpp.c:435
char * text
Definition: app_queue.c:1508
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static int transmit_message(struct sip_pvt *p, int init, int auth)
Transmit with SIP MESSAGE method.
Definition: chan_sip.c:16351
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
static int sip_debug_test_pvt(struct sip_pvt *p)
Test PVT for debugging output.
Definition: chan_sip.c:3649
static int is_method_allowed(unsigned int *allowed_methods, enum sipmethod method)
Check if method is allowed for a device or a dialog.
Definition: chan_sip.c:9806
const ast_string_field msg_body
Definition: sip.h:1063
const char * ast_channel_name(const struct ast_channel *chan)
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ sip_set_default_format_capabilities()

static void sip_set_default_format_capabilities ( struct ast_format_cap cap)
static

Definition at line 32437 of file chan_sip.c.

References ast_format_alaw, ast_format_cap_append, ast_format_cap_remove_by_type(), ast_format_gsm, ast_format_h263, ast_format_ulaw, and AST_MEDIA_TYPE_UNKNOWN.

Referenced by reload_config().

32438 {
32444 }
struct ast_format * ast_format_ulaw
Built-in cached ulaw format.
Definition: format_cache.c:86
struct ast_format * ast_format_gsm
Built-in cached gsm format.
Definition: format_cache.c:101
#define ast_format_cap_append(cap, format, framing)
Definition: format_cap.h:103
void ast_format_cap_remove_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Remove all formats matching a specific format type.
Definition: format_cap.c:525
struct ast_format * ast_format_alaw
Built-in cached alaw format.
Definition: format_cache.c:91
struct ast_format * ast_format_h263
Built-in cached h263 format.
Definition: format_cache.c:171

◆ sip_set_history()

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 22982 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, NULL, recordhistory, TRUE, and ast_cli_entry::usage.

22983 {
22984  switch (cmd) {
22985  case CLI_INIT:
22986  e->command = "sip set history {on|off}";
22987  e->usage =
22988  "Usage: sip set history {on|off}\n"
22989  " Enables/Disables recording of SIP dialog history for debugging purposes.\n"
22990  " Use 'sip show history' to view the history of a call number.\n";
22991  return NULL;
22992  case CLI_GENERATE:
22993  return NULL;
22994  }
22995 
22996  if (a->argc != e->args)
22997  return CLI_SHOWUSAGE;
22998 
22999  if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
23000  recordhistory = TRUE;
23001  ast_cli(a->fd, "SIP History Recording Enabled (use 'sip show history')\n");
23002  } else if (!strncasecmp(a->argv[e->args - 1], "off", 3)) {
23003  recordhistory = FALSE;
23004  ast_cli(a->fd, "SIP History Recording Disabled\n");
23005  } else {
23006  return CLI_SHOWUSAGE;
23007  }
23008  return CLI_SUCCESS;
23009 }
#define FALSE
Definition: app_minivm.c:521
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
int args
This gets set in ast_cli_register()
Definition: cli.h:185
const int fd
Definition: cli.h:159
const char *const * argv
Definition: cli.h:161
static unsigned int recordhistory
Definition: chan_sip.c:841
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
#define TRUE
Definition: app_minivm.c:518

◆ sip_set_owner()

static void sip_set_owner ( struct sip_pvt p,
struct ast_channel chan 
)
static

Set the owning channel on the sip_pvt object.

Definition at line 9450 of file chan_sip.c.

References ast_channel_uniqueid(), ast_rtp_instance_set_channel_id(), sip_pvt::owner, sip_pvt::rtp, sip_pvt::trtp, and sip_pvt::vrtp.

Referenced by dialog_unlink_all(), sip_fixup(), sip_hangup(), and sip_new().

9451 {
9452  p->owner = chan;
9453  if (p->rtp) {
9455  }
9456  if (p->vrtp) {
9458  }
9459  if (p->trtp) {
9461  }
9462 }
void ast_rtp_instance_set_channel_id(struct ast_rtp_instance *instance, const char *uniqueid)
Set the channel that owns this RTP instance.
Definition: rtp_engine.c:553
struct ast_rtp_instance * trtp
Definition: sip.h:1176
const char * ast_channel_uniqueid(const struct ast_channel *chan)
struct ast_rtp_instance * vrtp
Definition: sip.h:1175
struct ast_channel * owner
Definition: sip.h:1138
struct ast_rtp_instance * rtp
Definition: sip.h:1174

◆ sip_set_redirstr()

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

Translate referring cause.

Definition at line 18157 of file chan_sip.c.

References ast_string_field_set.

Referenced by get_rdnis().

18157  {
18158 
18159  if (!strcmp(reason, "unknown")) {
18160  ast_string_field_set(p, redircause, "UNKNOWN");
18161  } else if (!strcmp(reason, "user-busy")) {
18162  ast_string_field_set(p, redircause, "BUSY");
18163  } else if (!strcmp(reason, "no-answer")) {
18164  ast_string_field_set(p, redircause, "NOANSWER");
18165  } else if (!strcmp(reason, "unavailable")) {
18166  ast_string_field_set(p, redircause, "UNREACHABLE");
18167  } else if (!strcmp(reason, "unconditional")) {
18168  ast_string_field_set(p, redircause, "UNCONDITIONAL");
18169  } else if (!strcmp(reason, "time-of-day")) {
18170  ast_string_field_set(p, redircause, "UNKNOWN");
18171  } else if (!strcmp(reason, "do-not-disturb")) {
18172  ast_string_field_set(p, redircause, "UNKNOWN");
18173  } else if (!strcmp(reason, "deflection")) {
18174  ast_string_field_set(p, redircause, "UNKNOWN");
18175  } else if (!strcmp(reason, "follow-me")) {
18176  ast_string_field_set(p, redircause, "UNKNOWN");
18177  } else if (!strcmp(reason, "out-of-service")) {
18178  ast_string_field_set(p, redircause, "UNREACHABLE");
18179  } else if (!strcmp(reason, "away")) {
18180  ast_string_field_set(p, redircause, "UNREACHABLE");
18181  } else {
18182  ast_string_field_set(p, redircause, "UNKNOWN");
18183  }
18184 }
const ast_string_field redircause
Definition: sip.h:1063
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ sip_set_rtp_peer()

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,
const struct ast_format_cap cap,
int  nat_active 
)
static

Definition at line 33883 of file chan_sip.c.

References sip_pvt::alreadygone, append_history, ast_channel_is_bridged(), ast_channel_name(), ast_channel_set_fd(), ast_channel_tech_pvt(), ast_clear_flag, ast_debug, ast_format_cap_append_from_cap(), ast_format_cap_count(), ast_format_cap_identical(), ast_format_cap_remove_by_type(), AST_MEDIA_TYPE_UNKNOWN, ast_rtp_instance_fd(), ast_rtp_instance_get_and_cmp_remote_address, AST_RTP_INSTANCE_RTCP_DISABLED, AST_RTP_INSTANCE_RTCP_STANDARD, ast_rtp_instance_set_prop(), AST_RTP_PROPERTY_RTCP, ast_set_flag, ast_sockaddr_isnull(), ast_sockaddr_stringify(), AST_STATE_UP, ast_test_flag, sip_pvt::callid, sip_settings::directrtpsetup, sip_pvt::do_history, FALSE, sip_pvt::flags, sip_pvt::lastrtprx, sip_pvt::lastrtptx, NULL, sip_pvt::ourip, sip_pvt::outgoing_call, sip_pvt::owner, sip_pvt::pendinginvite, sip_pvt::redircaps, sip_pvt::redirip, sip_pvt::rtp, SIP_AUDIO_RTCP_FD, sip_cfg, SIP_DEFER_BYE_ON_TRANSFER, SIP_DIRECT_MEDIA_NAT, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PAGE3_DIRECT_MEDIA_OUTGOING, SIP_PENDINGBYE, sip_pvt_lock, sip_pvt_unlock, SIP_VIDEO_RTCP_FD, transmit_reinvite_with_sdp(), sip_pvt::tredirip, sip_pvt::vredirip, and sip_pvt::vrtp.

Referenced by sip_fixup().

33884 {
33885  struct sip_pvt *p;
33886  int changed = 0;
33887 
33888  p = ast_channel_tech_pvt(chan);
33889  if (!p) {
33890  return -1;
33891  }
33892  sip_pvt_lock(p);
33893  if (p->owner != chan) {
33894  /* I suppose it could be argued that if this happens it is a bug. */
33895  ast_debug(1, "The private is not owned by channel %s anymore.\n", ast_channel_name(chan));
33896  sip_pvt_unlock(p);
33897  return 0;
33898  }
33899 
33900  /* Disable early RTP bridge */
33901  if ((instance || vinstance || tinstance) &&
33902  !ast_channel_is_bridged(chan) &&
33904  sip_pvt_unlock(p);
33905  return 0;
33906  }
33907 
33908  if (p->alreadygone) {
33909  /* If we're destroyed, don't bother */
33910  sip_pvt_unlock(p);
33911  return 0;
33912  }
33913 
33914  /* if this peer cannot handle reinvites of the media stream to devices
33915  that are known to be behind a NAT, then stop the process now
33916  */
33917  if (nat_active && !ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA_NAT)) {
33918  sip_pvt_unlock(p);
33919  return 0;
33920  }
33921 
33922  if (instance) {
33923  changed |= ast_rtp_instance_get_and_cmp_remote_address(instance, &p->redirip);
33924 
33925  if (p->rtp) {
33926  /* Prevent audio RTCP reads */
33928  /* Silence RTCP while audio RTP is inactive */
33930  }
33931  } else if (!ast_sockaddr_isnull(&p->redirip)) {
33932  memset(&p->redirip, 0, sizeof(p->redirip));
33933  changed = 1;
33934  }
33935 
33936  if (vinstance) {
33937  changed |= ast_rtp_instance_get_and_cmp_remote_address(vinstance, &p->vredirip);
33938 
33939  if (p->vrtp) {
33940  /* Prevent video RTCP reads */
33942  /* Silence RTCP while video RTP is inactive */
33944  }
33945  } else if (!ast_sockaddr_isnull(&p->vredirip)) {
33946  memset(&p->vredirip, 0, sizeof(p->vredirip));
33947  changed = 1;
33948 
33949  if (p->vrtp) {
33950  /* Enable RTCP since it will be inactive if we're coming back
33951  * from a reinvite */
33953  /* Enable video RTCP reads */
33955  }
33956  }
33957 
33958  if (tinstance) {
33959  changed |= ast_rtp_instance_get_and_cmp_remote_address(tinstance, &p->tredirip);
33960  } else if (!ast_sockaddr_isnull(&p->tredirip)) {
33961  memset(&p->tredirip, 0, sizeof(p->tredirip));
33962  changed = 1;
33963  }
33964  if (cap && ast_format_cap_count(cap) && !ast_format_cap_identical(cap, p->redircaps)) {
33967  changed = 1;
33968  }
33969 
33971  /* We only wish to withhold sending the initial direct media reinvite on the incoming dialog.
33972  * Further direct media reinvites beyond the initial should be sent. In order to allow further
33973  * direct media reinvites to be sent, we clear this flag.
33974  */
33976  sip_pvt_unlock(p);
33977  return 0;
33978  }
33979 
33980  if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) {
33981  if (ast_channel_state(chan) != AST_STATE_UP) { /* We are in early state */
33982  if (p->do_history)
33983  append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal.");
33984  ast_debug(1, "Early remote bridge setting SIP '%s' - Sending media to %s\n", p->callid, ast_sockaddr_stringify(instance ? &p->redirip : &p->ourip));
33985  } else if (!p->pendinginvite) { /* We are up, and have no outstanding invite */
33986  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));
33988  } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
33989  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));
33990  /* We have a pending Invite. Send re-invite when we're done with the invite */
33992  }
33993  }
33994  /* Reset lastrtprx timer */
33995  p->lastrtprx = p->lastrtptx = time(NULL);
33996  sip_pvt_unlock(p);
33997  return 0;
33998 }
#define FALSE
Definition: app_minivm.c:521
int directrtpsetup
Definition: sip.h:755
time_t lastrtprx
Definition: sip.h:1129
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ast_set_flag(p, flag)
Definition: utils.h:70
uint32_t pendinginvite
Definition: sip.h:1147
#define SIP_DEFER_BYE_ON_TRANSFER
Definition: sip.h:267
struct ast_sockaddr redirip
Definition: sip.h:1126
unsigned short outgoing_call
Definition: sip.h:1083
#define SIP_PAGE3_DIRECT_MEDIA_OUTGOING
Definition: sip.h:388
struct ast_sockaddr ourip
Definition: sip.h:1136
ast_channel_state
ast_channel states
Definition: channelstate.h:35
size_t ast_format_cap_count(const struct ast_format_cap *cap)
Get the number of formats present within the capabilities structure.
Definition: format_cap.c:395
struct ast_flags flags[3]
Definition: sip.h:1075
#define NULL
Definition: resample.c:96
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
unsigned short alreadygone
Definition: sip.h:1079
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
void ast_format_cap_remove_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Remove all formats matching a specific format type.
Definition: format_cap.c:525
#define SIP_GOTREFER
Definition: sip.h:263
static int transmit_reinvite_with_sdp(struct sip_pvt *p, int t38version, int oldsdp)
Transmit reinvite with SDP.
Definition: chan_sip.c:14212
const ast_string_field callid
Definition: sip.h:1063
struct ast_format_cap * redircaps
Definition: sip.h:1102
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
struct ast_rtp_instance * vrtp
Definition: sip.h:1175
#define SIP_DIRECT_MEDIA_NAT
Definition: sip.h:290
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
Definition: channel.c:10746
struct ast_sockaddr tredirip
Definition: sip.h:1128
unsigned short do_history
Definition: sip.h:1078
struct ast_channel * owner
Definition: sip.h:1138
int ast_format_cap_identical(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2)
Determine if two capabilities structures are identical.
Definition: format_cap.c:689
int ast_rtp_instance_fd(struct ast_rtp_instance *instance, int rtcp)
Get the file descriptor for an RTP session (or RTCP)
Definition: rtp_engine.c:2192
struct ast_rtp_instance * rtp
Definition: sip.h:1174
#define ast_clear_flag(p, flag)
Definition: utils.h:77
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition: channel.c:2431
struct ast_sockaddr vredirip
Definition: sip.h:1127
#define SIP_PENDINGBYE
Definition: sip.h:262
time_t lastrtptx
Definition: sip.h:1130
const char * ast_channel_name(const struct ast_channel *chan)
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406
#define SIP_NEEDREINVITE
Definition: sip.h:261
void ast_rtp_instance_set_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value)
Set the value of an RTP instance property.
Definition: rtp_engine.c:705
int ast_format_cap_append_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type)
Append the formats of provided type in src to dst.
Definition: format_cap.c:269
#define ast_rtp_instance_get_and_cmp_remote_address(instance, address)
Get the address of the remote endpoint that we are sending RTP to, comparing its address to another...
Definition: rtp_engine.h:1228

◆ sip_setoption()

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

References ast_channel_name(), ast_channel_tech_pvt(), ast_debug, ast_log, AST_OPTION_DIGIT_DETECT, AST_OPTION_FORMAT_READ, AST_OPTION_FORMAT_WRITE, AST_OPTION_SECURE_MEDIA, AST_OPTION_SECURE_SIGNALING, ast_rtp_instance_set_read_format(), ast_rtp_instance_set_write_format(), ast_set2_flag, ast_test_flag, disable_dsp_detect(), enable_dsp_detect(), sip_pvt::flags, LOG_ERROR, sip_pvt::req_secure_signaling, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_PAGE2_USE_SRTP, sip_pvt_lock, and sip_pvt_unlock.

4940 {
4941  int res = -1;
4942  struct sip_pvt *p = ast_channel_tech_pvt(chan);
4943 
4944  if (!p) {
4945  ast_log(LOG_ERROR, "Attempt to Ref a null pointer. sip private structure is gone!\n");
4946  return -1;
4947  }
4948 
4949  sip_pvt_lock(p);
4950 
4951  switch (option) {
4953  if (p->rtp) {
4954  res = ast_rtp_instance_set_read_format(p->rtp, *(struct ast_format **) data);
4955  }
4956  break;
4958  if (p->rtp) {
4959  res = ast_rtp_instance_set_write_format(p->rtp, *(struct ast_format **) data);
4960  }
4961  break;
4963  if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) ||
4964  (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) {
4965  char *cp = (char *) data;
4966 
4967  ast_debug(1, "%sabling digit detection on %s\n", *cp ? "En" : "Dis", ast_channel_name(chan));
4968  if (*cp) {
4969  enable_dsp_detect(p);
4970  } else {
4971  disable_dsp_detect(p);
4972  }
4973  res = 0;
4974  }
4975  break;
4977  p->req_secure_signaling = *(unsigned int *) data;
4978  res = 0;
4979  break;
4981  ast_set2_flag(&p->flags[1], *(unsigned int *) data, SIP_PAGE2_USE_SRTP);
4982  res = 0;
4983  break;
4984  default:
4985  break;
4986  }
4987 
4988  sip_pvt_unlock(p);
4989 
4990  return res;
4991 }
#define SIP_DTMF_INBAND
Definition: sip.h:277
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_set2_flag(p, value, flag)
Definition: utils.h:94
#define ast_test_flag(p, flag)
Definition: utils.h:63
static void enable_dsp_detect(struct sip_pvt *p)
Definition: chan_sip.c:4896
Definition of a media format.
Definition: format.c:43
#define AST_OPTION_SECURE_MEDIA
struct ast_flags flags[3]
Definition: sip.h:1075
static void disable_dsp_detect(struct sip_pvt *p)
Definition: chan_sip.c:4930
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define AST_OPTION_FORMAT_WRITE
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
#define SIP_PAGE2_USE_SRTP
Definition: sip.h:368
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
unsigned short req_secure_signaling
Definition: sip.h:1093
#define AST_OPTION_DIGIT_DETECT
#define LOG_ERROR
Definition: logger.h:285
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
int ast_rtp_instance_set_read_format(struct ast_rtp_instance *instance, struct ast_format *format)
Request that the underlying RTP engine provide audio frames in a specific format. ...
Definition: rtp_engine.c:2560
#define AST_OPTION_SECURE_SIGNALING
struct ast_rtp_instance * rtp
Definition: sip.h:1174
int ast_rtp_instance_set_write_format(struct ast_rtp_instance *instance, struct ast_format *format)
Tell underlying RTP engine that audio frames will be provided in a specific format.
Definition: rtp_engine.c:2574
#define SIP_DTMF
Definition: sip.h:275
const char * ast_channel_name(const struct ast_channel *chan)
#define AST_OPTION_FORMAT_READ
#define SIP_DTMF_AUTO
Definition: sip.h:279

◆ sip_show_channel()

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

References sip_pvt::allowtransfer, ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ao2_t_ref, ast_cli_args::argc, ast_cli_args::argv, ARRAY_LEN, ast_channel_name(), ast_channel_nativeformats(), ast_cli(), AST_CLI_YESNO, ast_format_cap_get_names(), AST_FORMAT_CAP_NAMES_LEN, ast_free, ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_str_alloca, ast_str_buffer(), ast_strlen_zero, ast_test_flag, ast_transport2str(), sip_pvt::callid, sip_pvt::caps, sip_pvt::cid_num, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sipch(), dtmfmode2str(), ast_cli_args::fd, sip_pvt::flags, force_rport_string(), cfsip_options::id, sip_pvt::jointcaps, sip_pvt::lastmsg, len(), ast_cli_args::line, sip_pvt::maxcallbitrate, ast_cli_args::n, sip_pvt::needdestroy, sip_pvt::noncodeccapability, NONE, NULL, sip_pvt::ourip, sip_pvt::owner, sip_pvt::peercaps, sip_pvt::peername, ast_cli_args::pos, sip_pvt::recv, sip_pvt::redirip, sip_pvt::route, sip_pvt::rtp, sip_pvt::sa, SIP_DTMF, sip_options, SIP_OUTGOING, SIP_PROMISCREDIR, sip_pvt_lock, sip_pvt_unlock, sip_route_list(), sip_pvt::sipoptions, sip_pvt::socket, sip_pvt::srtp, sip_st_dlg::st_active, sip_st_dlg::st_active_peer_ua, sip_st_dlg::st_cached_max_se, sip_st_dlg::st_cached_min_se, sip_st_dlg::st_cached_mode, sip_st_dlg::st_cached_ref, sip_st_dlg::st_interval, sip_st_dlg::st_ref, sip_st_dlg::st_schedid, sip_pvt::stimer, stmode2str(), strefresher2str(), sip_pvt::subscribed, subscription_type2str(), sip_pvt::tag, cfsip_options::text, sip_pvt::theirtag, transfermode2str(), TRUE, sip_socket::type, sip_pvt::udptl, sip_pvt::uri, ast_cli_entry::usage, sip_pvt::useragent, sip_pvt::username, sip_pvt::vrtp, and ast_cli_args::word.

22390 {
22391  struct sip_pvt *cur;
22392  size_t len;
22393  int found = 0;
22394  struct ao2_iterator i;
22395 
22396  switch (cmd) {
22397  case CLI_INIT:
22398  e->command = "sip show channel";
22399  e->usage =
22400  "Usage: sip show channel <call-id>\n"
22401  " Provides detailed status on a given SIP dialog (identified by SIP call-id).\n";
22402  return NULL;
22403  case CLI_GENERATE:
22404  return complete_sipch(a->line, a->word, a->pos, a->n);
22405  }
22406 
22407  if (a->argc != 4)
22408  return CLI_SHOWUSAGE;
22409  len = strlen(a->argv[3]);
22410 
22411  i = ao2_iterator_init(dialogs, 0);
22412  while ((cur = ao2_t_iterator_next(&i, "iterate thru dialogs"))) {
22413  sip_pvt_lock(cur);
22414 
22415  if (!strncasecmp(cur->callid, a->argv[3], len)) {
22416  struct ast_str *strbuf;
22417  struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
22418 
22419  ast_cli(a->fd, "\n");
22420  if (cur->subscribed != NONE) {
22421  ast_cli(a->fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed));
22422  } else {
22423  ast_cli(a->fd, " * SIP Call\n");
22424  }
22425  ast_cli(a->fd, " Curr. trans. direction: %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming");
22426  ast_cli(a->fd, " Call-ID: %s\n", cur->callid);
22427  ast_cli(a->fd, " Owner channel ID: %s\n", cur->owner ? ast_channel_name(cur->owner) : "<none>");
22428  ast_cli(a->fd, " Our Codec Capability: %s\n", ast_format_cap_get_names(cur->caps, &codec_buf));
22429  ast_cli(a->fd, " Non-Codec Capability (DTMF): %d\n", cur->noncodeccapability);
22430  ast_cli(a->fd, " Their Codec Capability: %s\n", ast_format_cap_get_names(cur->peercaps, &codec_buf));
22431  ast_cli(a->fd, " Joint Codec Capability: %s\n", ast_format_cap_get_names(cur->jointcaps, &codec_buf));
22432  ast_cli(a->fd, " Format: %s\n", cur->owner ? ast_format_cap_get_names(ast_channel_nativeformats(cur->owner), &codec_buf) : "(nothing)" );
22433  ast_cli(a->fd, " T.38 support %s\n", AST_CLI_YESNO(cur->udptl != NULL));
22434  ast_cli(a->fd, " Video support %s\n", AST_CLI_YESNO(cur->vrtp != NULL));
22435  ast_cli(a->fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate);
22436  ast_cli(a->fd, " Theoretical Address: %s\n", ast_sockaddr_stringify(&cur->sa));
22437  ast_cli(a->fd, " Received Address: %s\n", ast_sockaddr_stringify(&cur->recv));
22438  ast_cli(a->fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer));
22439  ast_cli(a->fd, " Force rport: %s\n", force_rport_string(cur->flags));
22440  if (ast_sockaddr_isnull(&cur->redirip)) {
22441  ast_cli(a->fd,
22442  " Audio IP: %s (local)\n",
22444  } else {
22445  ast_cli(a->fd,
22446  " Audio IP: %s (Outside bridge)\n",
22448  }
22449  ast_cli(a->fd, " Our Tag: %s\n", cur->tag);
22450  ast_cli(a->fd, " Their Tag: %s\n", cur->theirtag);
22451  ast_cli(a->fd, " SIP User agent: %s\n", cur->useragent);
22452  if (!ast_strlen_zero(cur->username)) {
22453  ast_cli(a->fd, " Username: %s\n", cur->username);
22454  }
22455  if (!ast_strlen_zero(cur->peername)) {
22456  ast_cli(a->fd, " Peername: %s\n", cur->peername);
22457  }
22458  if (!ast_strlen_zero(cur->uri)) {
22459  ast_cli(a->fd, " Original uri: %s\n", cur->uri);
22460  }
22461  if (!ast_strlen_zero(cur->cid_num)) {
22462  ast_cli(a->fd, " Caller-ID: %s\n", cur->cid_num);
22463  }
22464  ast_cli(a->fd, " Need Destroy: %s\n", AST_CLI_YESNO(cur->needdestroy));
22465  ast_cli(a->fd, " Last Message: %s\n", cur->lastmsg);
22466  ast_cli(a->fd, " Promiscuous Redir: %s\n", AST_CLI_YESNO(ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR)));
22467  if ((strbuf = sip_route_list(&cur->route, 1, 0))) {
22468  ast_cli(a->fd, " Route: %s\n", ast_str_buffer(strbuf));
22469  ast_free(strbuf);
22470  }
22471  ast_cli(a->fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF)));
22472  ast_cli(a->fd, " SIP Options: ");
22473  if (cur->sipoptions) {
22474  int x;
22475  for (x = 0 ; x < ARRAY_LEN(sip_options); x++) {
22476  if (cur->sipoptions & sip_options[x].id)
22477  ast_cli(a->fd, "%s ", sip_options[x].text);
22478  }
22479  ast_cli(a->fd, "\n");
22480  } else {
22481  ast_cli(a->fd, "(none)\n");
22482  }
22483 
22484  if (!cur->stimer) {
22485  ast_cli(a->fd, " Session-Timer: Uninitiallized\n");
22486  } else {
22487  ast_cli(a->fd, " Session-Timer: %s\n", cur->stimer->st_active ? "Active" : "Inactive");
22488  if (cur->stimer->st_active == TRUE) {
22489  ast_cli(a->fd, " S-Timer Interval: %d\n", cur->stimer->st_interval);
22490  ast_cli(a->fd, " S-Timer Refresher: %s\n", strefresher2str(cur->stimer->st_ref));
22491  ast_cli(a->fd, " S-Timer Sched Id: %d\n", cur->stimer->st_schedid);
22492  ast_cli(a->fd, " S-Timer Peer Sts: %s\n", cur->stimer->st_active_peer_ua ? "Active" : "Inactive");
22493  ast_cli(a->fd, " S-Timer Cached Min-SE: %d\n", cur->stimer->st_cached_min_se);
22494  ast_cli(a->fd, " S-Timer Cached SE: %d\n", cur->stimer->st_cached_max_se);
22495  ast_cli(a->fd, " S-Timer Cached Ref: %s\n", strefresher2str(cur->stimer->st_cached_ref));
22496  ast_cli(a->fd, " S-Timer Cached Mode: %s\n", stmode2str(cur->stimer->st_cached_mode));
22497  }
22498  }
22499 
22500  /* add transport and media types */
22501  ast_cli(a->fd, " Transport: %s\n", ast_transport2str(cur->socket.type));
22502  ast_cli(a->fd, " Media: %s\n", cur->srtp ? "SRTP" : cur->rtp ? "RTP" : "None");
22503 
22504  ast_cli(a->fd, "\n\n");
22505 
22506  found++;
22507  }
22508 
22509  sip_pvt_unlock(cur);
22510 
22511  ao2_t_ref(cur, -1, "toss dialog ptr set by iterator_next");
22512  }
22514 
22515  if (!found) {
22516  ast_cli(a->fd, "No such SIP Call ID starting with '%s'\n", a->argv[3]);
22517  }
22518 
22519  return CLI_SUCCESS;
22520 }
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:290
static struct ao2_container * dialogs
Definition: chan_sip.c:1043
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
enum st_refresher st_ref
Definition: sip.h:962
struct ast_format_cap * peercaps
Definition: sip.h:1101
enum subscriptiontype subscribed
Definition: sip.h:1161
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int st_active_peer_ua
Definition: sip.h:964
int st_schedid
Definition: sip.h:963
int maxcallbitrate
Definition: sip.h:1106
char lastmsg[256]
Definition: sip.h:1145
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define NONE
Definition: misdn_config.c:45
const int argc
Definition: cli.h:160
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:326
struct ast_sockaddr recv
Definition: sip.h:1135
struct sip_socket socket
Definition: sip.h:1066
unsigned short needdestroy
Definition: sip.h:1080
struct ast_sockaddr redirip
Definition: sip.h:1126
const ast_string_field username
Definition: sip.h:1063
Definition: cli.h:152
struct ast_sockaddr ourip
Definition: sip.h:1136
struct ast_format_cap * jointcaps
Definition: sip.h:1100
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
enum st_mode st_cached_mode
Definition: sip.h:967
struct ast_flags flags[3]
Definition: sip.h:1075
#define ast_str_alloca(init_len)
Definition: strings.h:800
int st_active
Definition: sip.h:960
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
const char * line
Definition: cli.h:162
char *const text
Definition: sip.h:1830
static const char * stmode2str(enum st_mode m)
Definition: chan_sip.c:19990
static char * transfermode2str(enum transfermodes mode) attribute_const
Convert transfer mode to text string.
Definition: chan_sip.c:19968
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
int st_cached_max_se
Definition: sip.h:966
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
int st_interval
Definition: sip.h:961
struct ast_str * sip_route_list(const struct sip_route *route, int formatcli, int skip)
Make the comma separated list of route hops.
Definition: route.c:155
struct ast_sockaddr sa
Definition: sip.h:1125
const char * ast_transport2str(enum ast_transport transport)
Returns a string representation of an ast_transport.
Definition: netsock2.c:566
int noncodeccapability
Definition: sip.h:1104
const int fd
Definition: cli.h:159
struct ast_format_cap * caps
Definition: sip.h:1099
const int n
Definition: cli.h:165
enum st_refresher st_cached_ref
Definition: sip.h:968
int id
Definition: sip.h:1828
const ast_string_field theirtag
Definition: sip.h:1063
struct ast_udptl * udptl
Definition: sip.h:1115
struct sip_route route
Definition: sip.h:1139
const char *const * argv
Definition: cli.h:161
const ast_string_field callid
Definition: sip.h:1063
const ast_string_field useragent
Definition: sip.h:1063
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
const ast_string_field cid_num
Definition: sip.h:1063
struct sip_st_dlg * stimer
Definition: sip.h:1184
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define ao2_t_iterator_next(iter, tag)
Definition: astobj2.h:1931
int st_cached_min_se
Definition: sip.h:965
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
struct ast_rtp_instance * vrtp
Definition: sip.h:1175
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition: format_cap.c:736
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
const char * force_rport_string(struct ast_flags *flags)
Return a string describing the force_rport value for the given flags.
static const struct cfsip_options sip_options[]
#define ast_free(a)
Definition: astmm.h:182
char * command
Definition: cli.h:186
struct ast_channel * owner
Definition: sip.h:1138
const char * word
Definition: cli.h:163
struct ast_rtp_instance * rtp
Definition: sip.h:1174
const ast_string_field peername
Definition: sip.h:1063
const char * usage
Definition: cli.h:177
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
#define CLI_SUCCESS
Definition: cli.h:44
static char * complete_sipch(const char *line, const char *word, int pos, int state)
Support routine for &#39;sip show channel&#39; and &#39;sip show history&#39; CLI This is in charge of generating all...
Definition: chan_sip.c:22252
enum transfermodes allowtransfer
Definition: sip.h:1137
#define SIP_DTMF
Definition: sip.h:275
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
enum ast_transport type
Definition: sip.h:798
const char * ast_channel_name(const struct ast_channel *chan)
const int pos
Definition: cli.h:164
#define TRUE
Definition: app_minivm.c:518
const ast_string_field tag
Definition: sip.h:1063
#define SIP_PROMISCREDIR
Definition: sip.h:269
#define SIP_OUTGOING
Definition: sip.h:257
#define AST_CLI_YESNO(x)
Return Yes or No depending on the argument.
Definition: cli.h:71
struct ast_sdp_srtp * srtp
Definition: sip.h:1185
unsigned int sipoptions
Definition: sip.h:1097
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
static const char * subscription_type2str(enum subscriptiontype subtype) attribute_pure
Show subscription type in string format.
Definition: chan_sip.c:22117
static const char * dtmfmode2str(int mode) attribute_const
Convert DTMF mode to printable string.
Definition: chan_sip.c:20598
const ast_string_field uri
Definition: sip.h:1063
static const char * strefresher2str(enum st_refresher r)
Definition: chan_sip.c:20033

◆ sip_show_channels()

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

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, 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, __show_chan_arg::fd, FORMAT2, FORMAT3, NULL, __show_chan_arg::numchans, show_channels_cb(), __show_chan_arg::subscriptions, and ast_cli_entry::usage.

22206 {
22207  struct __show_chan_arg arg = { .fd = a->fd, .numchans = 0 };
22208  struct sip_pvt *cur;
22209  struct ao2_iterator i;
22210 
22211  if (cmd == CLI_INIT) {
22212  e->command = "sip show {channels|subscriptions}";
22213  e->usage =
22214  "Usage: sip show channels\n"
22215  " Lists all currently active SIP calls (dialogs).\n"
22216  "Usage: sip show subscriptions\n"
22217  " Lists active SIP subscriptions.\n";
22218  return NULL;
22219  } else if (cmd == CLI_GENERATE)
22220  return NULL;
22221 
22222  if (a->argc != e->args)
22223  return CLI_SHOWUSAGE;
22224  arg.subscriptions = !strcasecmp(a->argv[e->args - 1], "subscriptions");
22225  if (!arg.subscriptions)
22226  ast_cli(arg.fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Format", "Hold", "Last Message", "Expiry", "Peer");
22227  else
22228  ast_cli(arg.fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox", "Expiry");
22229 
22230  /* iterate on the container and invoke the callback on each item */
22231  i = ao2_iterator_init(dialogs, 0);
22232  for (; (cur = ao2_iterator_next(&i)); ao2_ref(cur, -1)) {
22233  show_channels_cb(cur, &arg);
22234  }
22236 
22237  /* print summary information */
22238  ast_cli(arg.fd, "%d active SIP %s%s\n", arg.numchans,
22239  (arg.subscriptions ? "subscription" : "dialog"),
22240  ESS(arg.numchans)); /* ESS(n) returns an "s" if n>1 */
22241  return CLI_SUCCESS;
22242 #undef FORMAT
22243 #undef FORMAT2
22244 #undef FORMAT3
22245 }
static struct ao2_container * dialogs
Definition: chan_sip.c:1043
const int argc
Definition: cli.h:160
Definition: cli.h:152
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
int subscriptions
Definition: sip.h:734
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
#define FORMAT2
Definition: chan_sip.c:22151
int args
This gets set in ast_cli_register()
Definition: cli.h:185
const int fd
Definition: cli.h:159
#define ao2_ref(o, delta)
Definition: astobj2.h:464
const char *const * argv
Definition: cli.h:161
argument for the &#39;show channels|subscriptions&#39; callback.
Definition: sip.h:732
static int show_channels_cb(struct sip_pvt *cur, struct __show_chan_arg *arg)
callback for show channel|subscription
Definition: chan_sip.c:22155
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
#define ESS(x)
Definition: cli.h:59
char * command
Definition: cli.h:186
#define FORMAT3
Definition: chan_sip.c:22150
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
int numchans
Definition: sip.h:735
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

◆ sip_show_channelstats()

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

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_cli_args::argc, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, __show_chan_arg::fd, FORMAT2, NULL, __show_chan_arg::numchans, show_chanstats_cb(), and ast_cli_entry::usage.

21806 {
21807  struct __show_chan_arg arg = { .fd = a->fd, .numchans = 0 };
21808  struct sip_pvt *cur;
21809  struct ao2_iterator i;
21810 
21811  switch (cmd) {
21812  case CLI_INIT:
21813  e->command = "sip show channelstats";
21814  e->usage =
21815  "Usage: sip show channelstats\n"
21816  " Lists all currently active SIP channel's RTCP statistics.\n"
21817  " Note that calls in the much optimized RTP P2P bridge mode will not show any packets here.";
21818  return NULL;
21819  case CLI_GENERATE:
21820  return NULL;
21821  }
21822 
21823  if (a->argc != 3)
21824  return CLI_SHOWUSAGE;
21825 
21826  ast_cli(a->fd, FORMAT2, "Peer", "Call ID", "Duration", "Recv: Pack", "Lost", "Jitter", "Send: Pack", "Lost", "Jitter");
21827 
21828  /* iterate on the container and invoke the callback on each item */
21829  i = ao2_iterator_init(dialogs, 0);
21830  for (; (cur = ao2_iterator_next(&i)); ao2_ref(cur, -1)) {
21831  show_chanstats_cb(cur, &arg);
21832  }
21834 
21835  ast_cli(a->fd, "%d active SIP channel%s\n", arg.numchans, (arg.numchans != 1) ? "s" : "");
21836  return CLI_SUCCESS;
21837 }
static struct ao2_container * dialogs
Definition: chan_sip.c:1043
const int argc
Definition: cli.h:160
Definition: cli.h:152
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
static int show_chanstats_cb(struct sip_pvt *cur, struct __show_chan_arg *arg)
Callback for show_chanstats.
Definition: chan_sip.c:21742
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
#define FORMAT2
Definition: chan_sip.c:22151
const int fd
Definition: cli.h:159
#define ao2_ref(o, delta)
Definition: astobj2.h:464
argument for the &#39;show channels|subscriptions&#39; callback.
Definition: sip.h:732
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
int numchans
Definition: sip.h:735
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

◆ sip_show_domains()

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 20905 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::context, d, domain::domain, domain_mode_to_text(), ast_cli_args::fd, FORMAT, domain::mode, NULL, S_OR, and ast_cli_entry::usage.

20906 {
20907  struct domain *d;
20908 #define FORMAT "%-40.40s %-20.20s %-16.16s\n"
20909 
20910  switch (cmd) {
20911  case CLI_INIT:
20912  e->command = "sip show domains";
20913  e->usage =
20914  "Usage: sip show domains\n"
20915  " Lists all configured SIP local domains.\n"
20916  " Asterisk only responds to SIP messages to local domains.\n";
20917  return NULL;
20918  case CLI_GENERATE:
20919  return NULL;
20920  }
20921 
20922  if (AST_LIST_EMPTY(&domain_list)) {
20923  ast_cli(a->fd, "SIP Domain support not enabled.\n\n");
20924  return CLI_SUCCESS;
20925  } else {
20926  ast_cli(a->fd, FORMAT, "Our local SIP domains:", "Context", "Set by");
20929  ast_cli(a->fd, FORMAT, d->domain, S_OR(d->context, "(default)"),
20932  ast_cli(a->fd, "\n");
20933  return CLI_SUCCESS;
20934  }
20935 }
struct domain::@167 list
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
static struct test_val d
Definition: cli.h:152
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
#define NULL
Definition: resample.c:96
Domain data structure.
Definition: sip.h:888
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
enum domain_mode mode
Definition: sip.h:891
const int fd
Definition: cli.h:159
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
static const char * domain_mode_to_text(const enum domain_mode mode)
Print domain mode to cli.
Definition: chan_sip.c:20892
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
#define FORMAT
Definition: chan_sip.c:22152
char domain[MAXHOSTNAMELEN]
Definition: sip.h:889
char context[AST_MAX_EXTENSION]
Definition: sip.h:890

◆ sip_show_history()

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 22523 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, sip_pvt::callid, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sip_show_history(), sip_history::event, ast_cli_args::fd, sip_pvt::history, len(), ast_cli_args::line, ast_cli_args::n, NONE, NULL, ast_cli_args::pos, recordhistory, sip_pvt_lock, sip_pvt_unlock, sip_pvt::subscribed, ast_cli_entry::usage, and ast_cli_args::word.

22524 {
22525  struct sip_pvt *cur;
22526  size_t len;
22527  int found = 0;
22528  struct ao2_iterator i;
22529 
22530  switch (cmd) {
22531  case CLI_INIT:
22532  e->command = "sip show history";
22533  e->usage =
22534  "Usage: sip show history <call-id>\n"
22535  " Provides detailed dialog history on a given SIP call (specified by call-id).\n";
22536  return NULL;
22537  case CLI_GENERATE:
22538  return complete_sip_show_history(a->line, a->word, a->pos, a->n);
22539  }
22540 
22541  if (a->argc != 4) {
22542  return CLI_SHOWUSAGE;
22543  }
22544 
22545  if (!recordhistory) {
22546  ast_cli(a->fd, "\n***Note: History recording is currently DISABLED. Use 'sip set history on' to ENABLE.\n");
22547  }
22548 
22549  len = strlen(a->argv[3]);
22550 
22551  i = ao2_iterator_init(dialogs, 0);
22552  while ((cur = ao2_t_iterator_next(&i, "iterate thru dialogs"))) {
22553  sip_pvt_lock(cur);
22554  if (!strncasecmp(cur->callid, a->argv[3], len)) {
22555  struct sip_history *hist;
22556  int x = 0;
22557 
22558  ast_cli(a->fd, "\n");
22559  if (cur->subscribed != NONE) {
22560  ast_cli(a->fd, " * Subscription\n");
22561  } else {
22562  ast_cli(a->fd, " * SIP Call\n");
22563  }
22564  if (cur->history) {
22565  AST_LIST_TRAVERSE(cur->history, hist, list)
22566  ast_cli(a->fd, "%d. %s\n", ++x, hist->event);
22567  }
22568  if (x == 0) {
22569  ast_cli(a->fd, "Call '%s' has no history\n", cur->callid);
22570  }
22571  found++;
22572  }
22573  sip_pvt_unlock(cur);
22574  ao2_t_ref(cur, -1, "toss dialog ptr from iterator_next");
22575  }
22577 
22578  if (!found) {
22579  ast_cli(a->fd, "No such SIP Call ID starting with '%s'\n", a->argv[3]);
22580  }
22581 
22582  return CLI_SUCCESS;
22583 }
static struct ao2_container * dialogs
Definition: chan_sip.c:1043
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
enum subscriptiontype subscribed
Definition: sip.h:1161
#define NONE
Definition: misdn_config.c:45
const int argc
Definition: cli.h:160
Definition: cli.h:152
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
const char * line
Definition: cli.h:162
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
char event[0]
Definition: sip.h:898
struct sip_history_head * history
Definition: sip.h:1178
const int fd
Definition: cli.h:159
const int n
Definition: cli.h:165
const char *const * argv
Definition: cli.h:161
const ast_string_field callid
Definition: sip.h:1063
static unsigned int recordhistory
Definition: chan_sip.c:841
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define ao2_t_iterator_next(iter, tag)
Definition: astobj2.h:1931
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
char * command
Definition: cli.h:186
static char * complete_sip_show_history(const char *line, const char *word, int pos, int state)
Support routine for &#39;sip show history&#39; CLI.
Definition: chan_sip.c:22331
const char * word
Definition: cli.h:163
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
const int pos
Definition: cli.h:164
struct sip_history::@168 list
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
sip_history: Structure for saving transactions within a SIP dialog
Definition: sip.h:896

◆ sip_show_inuse()

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 19916 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(), sip_peer::call_limit, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, FALSE, ast_cli_args::fd, FORMAT, FORMAT2, sip_peer::inuse, sip_peer::name, NULL, sip_peer::onhold, sip_peer::ringing, sip_unref_peer, TRUE, and ast_cli_entry::usage.

19917 {
19918 #define FORMAT "%-25.25s %-15.15s %-15.15s \n"
19919 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n"
19920  char ilimits[40];
19921  char iused[40];
19922  int showall = FALSE;
19923  struct ao2_iterator i;
19924  struct sip_peer *peer;
19925 
19926  switch (cmd) {
19927  case CLI_INIT:
19928  e->command = "sip show inuse [all]";
19929  e->usage =
19930  "Usage: sip show inuse [all]\n"
19931  " List all SIP devices usage counters and limits.\n"
19932  " Add option \"all\" to show all devices, not only those with a limit.\n";
19933  return NULL;
19934  case CLI_GENERATE:
19935  return NULL;
19936  }
19937 
19938  if (a->argc < 3)
19939  return CLI_SHOWUSAGE;
19940 
19941  if (a->argc == 4 && !strcmp(a->argv[3], "all"))
19942  showall = TRUE;
19943 
19944  ast_cli(a->fd, FORMAT, "* Peer name", "In use", "Limit");
19945 
19946  i = ao2_iterator_init(peers, 0);
19947  while ((peer = ao2_t_iterator_next(&i, "iterate thru peer table"))) {
19948  ao2_lock(peer);
19949  if (peer->call_limit)
19950  snprintf(ilimits, sizeof(ilimits), "%d", peer->call_limit);
19951  else
19952  ast_copy_string(ilimits, "N/A", sizeof(ilimits));
19953  snprintf(iused, sizeof(iused), "%d/%d/%d", peer->inuse, peer->ringing, peer->onhold);
19954  if (showall || peer->call_limit)
19955  ast_cli(a->fd, FORMAT2, peer->name, iused, ilimits);
19956  ao2_unlock(peer);
19957  sip_unref_peer(peer, "toss iterator pointer");
19958  }
19960 
19961  return CLI_SUCCESS;
19962 #undef FORMAT
19963 #undef FORMAT2
19964 }
#define FALSE
Definition: app_minivm.c:521
const int argc
Definition: cli.h:160
Definition: cli.h:152
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
#define FORMAT2
Definition: chan_sip.c:22151
int ringing
Definition: sip.h:1326
char name[80]
Definition: sip.h:1274
const int fd
Definition: cli.h:159
int call_limit
Definition: sip.h:1328
#define ao2_lock(a)
Definition: astobj2.h:718
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define ao2_t_iterator_next(iter, tag)
Definition: astobj2.h:1931
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
char * command
Definition: cli.h:186
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
int onhold
Definition: sip.h:1327
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define TRUE
Definition: app_minivm.c:518
#define FORMAT
Definition: chan_sip.c:22152
int inuse
Definition: sip.h:1325
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

◆ sip_show_mwi()

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

Definition at line 22081 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_iterator_next, ao2_t_ref, ao2_unlock, ast_cli(), AST_CLI_YESNO, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, FORMAT, host, sip_subscription_mwi::hostname, sip_subscription_mwi::mailbox, NULL, sip_subscription_mwi::portno, STANDARD_SIP_PORT, sip_subscription_mwi::subscribed, ast_cli_entry::usage, and sip_subscription_mwi::username.

22082 {
22083 #define FORMAT "%-30.30s %-12.12s %-10.10s %-10.10s\n"
22084  char host[80];
22085  struct ao2_iterator iter;
22086  struct sip_subscription_mwi *iterator;
22087 
22088  switch (cmd) {
22089  case CLI_INIT:
22090  e->command = "sip show mwi";
22091  e->usage =
22092  "Usage: sip show mwi\n"
22093  " Provides a list of MWI subscriptions and status.\n";
22094  return NULL;
22095  case CLI_GENERATE:
22096  return NULL;
22097  }
22098 
22099  ast_cli(a->fd, FORMAT, "Host", "Username", "Mailbox", "Subscribed");
22100 
22102  while ((iterator = ao2_t_iterator_next(&iter, "sip_show_mwi iter"))) {
22103  ao2_lock(iterator);
22104  snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT);
22105  ast_cli(a->fd, FORMAT, host, iterator->username, iterator->mailbox, AST_CLI_YESNO(iterator->subscribed));
22106  ao2_unlock(iterator);
22107  ao2_t_ref(iterator, -1, "sip_show_mwi iter");
22108  }
22109  ao2_iterator_destroy(&iter);
22110 
22111  return CLI_SUCCESS;
22112 #undef FORMAT
22113 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
unsigned int subscribed
Definition: sip.h:1465
const ast_string_field hostname
Definition: sip.h:1461
Definition: cli.h:152
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_unlock(a)
Definition: astobj2.h:730
const ast_string_field mailbox
Definition: sip.h:1461
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const ast_string_field username
Definition: sip.h:1461
static char host[256]
Definition: muted.c:77
#define STANDARD_SIP_PORT
Standard SIP unsecure port for UDP and TCP from RFC 3261. DO NOT CHANGE THIS.
Definition: sip.h:176
const int fd
Definition: cli.h:159
#define ao2_lock(a)
Definition: astobj2.h:718
#define ao2_t_iterator_next(iter, tag)
Definition: astobj2.h:1931
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
Definition of an MWI subscription to another server.
Definition: sip.h:1454
#define CLI_SUCCESS
Definition: cli.h:44
static struct ao2_container * subscription_mwi_list
The MWI subscription list.
Definition: chan_sip.c:1064
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
#define FORMAT
Definition: chan_sip.c:22152
#define AST_CLI_YESNO(x)
Return Yes or No depending on the argument.
Definition: cli.h:71
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

◆ sip_show_objects()

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

References ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_callback, ao2_t_iterator_next, ao2_t_ref, ao2_unlock, apeerobjs, ast_cli_args::argc, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, sip_registry::configvalue, dialog_dump_func(), ast_cli_args::fd, NULL, OBJ_NODATA, peer_dump_func(), rpeerobjs, speerobjs, and ast_cli_entry::usage.

20534 {
20535  struct sip_registry *reg;
20536  struct ao2_iterator iter;
20537 
20538  switch (cmd) {
20539  case CLI_INIT:
20540  e->command = "sip show objects";
20541  e->usage =
20542  "Usage: sip show objects\n"
20543  " Lists status of known SIP objects\n";
20544  return NULL;
20545  case CLI_GENERATE:
20546  return NULL;
20547  }
20548 
20549  if (a->argc != 3)
20550  return CLI_SHOWUSAGE;
20551  ast_cli(a->fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs);
20552  ao2_t_callback(peers, OBJ_NODATA, peer_dump_func, a, "initiate ao2_callback to dump peers");
20553  ast_cli(a->fd, "-= Peer objects by IP =-\n\n");
20554  ao2_t_callback(peers_by_ip, OBJ_NODATA, peer_dump_func, a, "initiate ao2_callback to dump peers_by_ip");
20555 
20556  iter = ao2_iterator_init(registry_list, 0);
20557  ast_cli(a->fd, "-= Registry objects: %d =-\n\n", ao2_container_count(registry_list));
20558  while ((reg = ao2_t_iterator_next(&iter, "sip_show_objects iter"))) {
20559  ao2_lock(reg);
20560  ast_cli(a->fd, "name: %s\n", reg->configvalue);
20561  ao2_unlock(reg);
20562  ao2_t_ref(reg, -1, "sip_show_objects iter");
20563  }
20564  ao2_iterator_destroy(&iter);
20565 
20566  ast_cli(a->fd, "-= Dialog objects:\n\n");
20567  ao2_t_callback(dialogs, OBJ_NODATA, dialog_dump_func, a, "initiate ao2_callback to dump dialogs");
20568  return CLI_SUCCESS;
20569 }
static struct ao2_container * dialogs
Definition: chan_sip.c:1043
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
static int speerobjs
Definition: chan_sip.c:879
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
const int argc
Definition: cli.h:160
static int rpeerobjs
Definition: chan_sip.c:880
Definition: cli.h:152
Registrations with other SIP proxies.
Definition: sip.h:1396
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
static int peer_dump_func(void *userobj, void *arg, int flags)
Definition: chan_sip.c:20509
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
static struct ao2_container * registry_list
The register list: Other SIP proxies we register with and receive calls from.
Definition: chan_sip.c:1061
static struct ao2_container * peers_by_ip
Definition: chan_sip.c:1053
const int fd
Definition: cli.h:159
#define ao2_lock(a)
Definition: astobj2.h:718
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define ao2_t_iterator_next(iter, tag)
Definition: astobj2.h:1931
#define ao2_t_callback(c, flags, cb_fn, arg, tag)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.
Definition: astobj2.h:1714
static int apeerobjs
Definition: chan_sip.c:881
static int dialog_dump_func(void *userobj, void *arg, int flags)
Definition: chan_sip.c:20520
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
const ast_string_field configvalue
Definition: sip.h:1414

◆ sip_show_peer()

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

References _sip_show_peer(), ast_cli_args::argc, ast_cli_args::argv, ast_cli_complete(), CLI_GENERATE, CLI_INIT, ast_cli_entry::command, complete_sip_show_peer(), ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, NULL, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

20961 {
20962  switch (cmd) {
20963  case CLI_INIT:
20964  e->command = "sip show peer";
20965  e->usage =
20966  "Usage: sip show peer <name> [load]\n"
20967  " Shows all details on one SIP peer and the current status.\n"
20968  " Option \"load\" forces lookup of peer in realtime storage.\n";
20969  return NULL;
20970  case CLI_GENERATE:
20971  if (a->pos == 4) {
20972  static const char * const completions[] = { "load", NULL };
20973  return ast_cli_complete(a->word, completions, a->n);
20974  } else {
20975  return complete_sip_show_peer(a->line, a->word, a->pos, a->n);
20976  }
20977  }
20978  return _sip_show_peer(0, a->fd, NULL, NULL, a->argc, (const char **) a->argv);
20979 }
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
const char * line
Definition: cli.h:162
char * ast_cli_complete(const char *word, const char *const choices[], int pos)
Definition: main/cli.c:1811
const int fd
Definition: cli.h:159
const int n
Definition: cli.h:165
const char *const * argv
Definition: cli.h:161
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
const char * usage
Definition: cli.h:177
static char * complete_sip_show_peer(const char *line, const char *word, int pos, int state)
Support routine for &#39;sip show peer&#39; CLI.
Definition: chan_sip.c:22340
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)
Definition: chan_sip.c:21181
const int pos
Definition: cli.h:164

◆ sip_show_peers()

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

References _sip_show_peers(), a, ast_cli_args::argc, ast_cli_args::argv, b, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, ast_cli_args::fd, NULL, peercomparefunc(), and ast_cli_entry::usage.

20254 {
20255  switch (cmd) {
20256  case CLI_INIT:
20257  e->command = "sip show peers [like]";
20258  e->usage =
20259  "Usage: sip show peers [like <pattern>]\n"
20260  " Lists all known SIP peers.\n"
20261  " Optional regular expression pattern is used to filter the peer list.\n";
20262  return NULL;
20263  case CLI_GENERATE:
20264  return NULL;
20265  }
20266 
20267  return _sip_show_peers(a->fd, NULL, NULL, NULL, a->argc, (const char **) a->argv);
20268 }
const int argc
Definition: cli.h:160
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.
Definition: chan_sip.c:20295
Definition: cli.h:152
#define NULL
Definition: resample.c:96
const int fd
Definition: cli.h:159
const char *const * argv
Definition: cli.h:161
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177

◆ sip_show_registry()

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

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_iterator_next, ao2_t_ref, ao2_unlock, ast_cli_args::argc, ast_cli(), ast_localtime(), ast_strftime(), ast_strlen_zero, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, sip_registry::dnsmgr, ast_cli_args::fd, FORMAT, FORMAT2, host, sip_registry::hostname, NULL, sip_registry::portno, sip_registry::refresh, sip_registry::regdomain, sip_registry::regdomainport, sip_registry::regstate, regstate2str(), sip_registry::regtime, STANDARD_SIP_PORT, ast_cli_entry::usage, and sip_registry::username.

21644 {
21645 #define FORMAT2 "%-39.39s %-6.6s %-12.12s %8.8s %-20.20s %-25.25s\n"
21646 #define FORMAT "%-39.39s %-6.6s %-12.12s %8d %-20.20s %-25.25s\n"
21647  char host[80];
21648  char user[80];
21649  char tmpdat[256];
21650  struct ast_tm tm;
21651  int counter = 0;
21652  struct ao2_iterator iter;
21653  struct sip_registry *iterator;
21654 
21655  switch (cmd) {
21656  case CLI_INIT:
21657  e->command = "sip show registry";
21658  e->usage =
21659  "Usage: sip show registry\n"
21660  " Lists all registration requests and status.\n";
21661  return NULL;
21662  case CLI_GENERATE:
21663  return NULL;
21664  }
21665 
21666  if (a->argc != 3)
21667  return CLI_SHOWUSAGE;
21668  ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Refresh", "State", "Reg.Time");
21669 
21670  iter = ao2_iterator_init(registry_list, 0);
21671  while ((iterator = ao2_t_iterator_next(&iter, "sip_show_registry iter"))) {
21672  ao2_lock(iterator);
21673 
21674  snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT);
21675  snprintf(user, sizeof(user), "%s", iterator->username);
21676  if (!ast_strlen_zero(iterator->regdomain)) {
21677  snprintf(tmpdat, sizeof(tmpdat), "%s", user);
21678  snprintf(user, sizeof(user), "%s@%s", tmpdat, iterator->regdomain);}
21679  if (iterator->regdomainport) {
21680  snprintf(tmpdat, sizeof(tmpdat), "%s", user);
21681  snprintf(user, sizeof(user), "%s:%d", tmpdat, iterator->regdomainport);}
21682  if (iterator->regtime.tv_sec) {
21683  ast_localtime(&iterator->regtime, &tm, NULL);
21684  ast_strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm);
21685  } else
21686  tmpdat[0] = '\0';
21687  ast_cli(a->fd, FORMAT, host, (iterator->dnsmgr) ? "Y" : "N", user, iterator->refresh, regstate2str(iterator->regstate), tmpdat);
21688 
21689  ao2_unlock(iterator);
21690  ao2_t_ref(iterator, -1, "sip_show_registry iter");
21691  counter++;
21692  }
21693  ao2_iterator_destroy(&iter);
21694 
21695  ast_cli(a->fd, "%d SIP registrations.\n", counter);
21696  return CLI_SUCCESS;
21697 #undef FORMAT
21698 #undef FORMAT2
21699 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
const ast_string_field hostname
Definition: sip.h:1414
const ast_string_field username
Definition: sip.h:1414
enum sipregistrystate regstate
Definition: sip.h:1425
int portno
Definition: sip.h:1416
const int argc
Definition: cli.h:160
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
Definition: cli.h:152
Registrations with other SIP proxies.
Definition: sip.h:1396
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
#define FORMAT2
Definition: chan_sip.c:22151
struct ast_dnsmgr_entry * dnsmgr
Definition: sip.h:1429
static struct ao2_container * registry_list
The register list: Other SIP proxies we register with and receive calls from.
Definition: chan_sip.c:1061
#define ast_strlen_zero(foo)
Definition: strings.h:52
int regdomainport
Definition: sip.h:1417
static char host[256]
Definition: muted.c:77
#define STANDARD_SIP_PORT
Standard SIP unsecure port for UDP and TCP from RFC 3261. DO NOT CHANGE THIS.
Definition: sip.h:176
const int fd
Definition: cli.h:159
#define ao2_lock(a)
Definition: astobj2.h:718
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define ao2_t_iterator_next(iter, tag)
Definition: astobj2.h:1931
static const char * regstate2str(enum sipregistrystate regstate) attribute_const
Convert registration state status to string.
Definition: chan_sip.c:15847
char * command
Definition: cli.h:186
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition: localtime.c:2524
structure to hold users read from users.conf
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
#define FORMAT
Definition: chan_sip.c:22152
const ast_string_field regdomain
Definition: sip.h:1414
int refresh
Definition: sip.h:1423
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
struct timeval regtime
Definition: sip.h:1426

◆ sip_show_sched()

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

Definition at line 21591 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, NULL, retrans_pkt(), sip_poke_noanswer(), sip_poke_peer_now(), sip_poke_peer_s(), sip_reg_timeout(), sip_reinvite_retry(), sip_reregister(), and ast_cli_entry::usage.

21592 {
21593  struct ast_str *cbuf;
21594  struct ast_cb_names cbnames = {
21595  10,
21596  {
21597  "retrans_pkt",
21598  "__sip_autodestruct",
21599  "expire_register",
21600  "auto_congest",
21601  "sip_reg_timeout",
21602  "sip_poke_peer_s",
21603  "sip_poke_peer_now",
21604  "sip_poke_noanswer",
21605  "sip_reregister",
21606  "sip_reinvite_retry"
21607  },
21608  {
21609  retrans_pkt,
21612  auto_congest,
21619  }
21620  };
21621 
21622  switch (cmd) {
21623  case CLI_INIT:
21624  e->command = "sip show sched";
21625  e->usage =
21626  "Usage: sip show sched\n"
21627  " Shows stats on what's in the sched queue at the moment\n";
21628  return NULL;
21629  case CLI_GENERATE:
21630  return NULL;
21631  }
21632 
21633  cbuf = ast_str_alloca(2048);
21634 
21635  ast_cli(a->fd, "\n");
21636  ast_sched_report(sched, &cbuf, &cbnames);
21637  ast_cli(a->fd, "%s", ast_str_buffer(cbuf));
21638 
21639  return CLI_SUCCESS;
21640 }
static int expire_register(const void *data)
Expire registration of SIP peer.
Definition: chan_sip.c:16646
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
Definition: sched.c:76
Definition: cli.h:152
static int auto_congest(const void *arg)
Scheduled congestion on a call. Only called by the scheduler, must return the reference when done...
Definition: chan_sip.c:6420
static int sip_reg_timeout(const void *data)
Registration request timeout, register again.
Definition: chan_sip.c:15976
static int sip_poke_noanswer(const void *data)
React to lack of answer to Qualify poke.
Definition: chan_sip.c:30523
#define ast_str_alloca(init_len)
Definition: strings.h:800
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
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 bet...
Definition: chan_sip.c:23817
static int retrans_pkt(const void *data)
Retransmit SIP message if no answer.
Definition: chan_sip.c:4041
static int sip_poke_peer_s(const void *data)
Poke peer (send qualify to check if peer is alive and well)
Definition: chan_sip.c:16707
const int fd
Definition: cli.h:159
static int sip_poke_peer_now(const void *data)
Definition: chan_sip.c:16731
void ast_sched_report(struct ast_sched_context *con, struct ast_str **buf, struct ast_cb_names *cbnames)
Show statics on what it is in the schedule queue.
Definition: sched.c:674
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
static int sip_reregister(const void *data)
Update registration with SIP Proxy.
Definition: chan_sip.c:15868
#define CLI_SUCCESS
Definition: cli.h:44
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-...
Definition: chan_sip.c:4369

◆ sip_show_settings()

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

References ast_ha::addr, sip_settings::allow_external_domains, sip_settings::allowguest, allowoverlap2str(), sip_settings::allowtransfer, sip_settings::alwaysauthreject, ao2_t_ref, ast_cli_args::argc, ast_check_realtime(), ast_cli(), AST_CLI_ONOFF, AST_CLI_YESNO, ast_format_cap_get_names(), AST_FORMAT_CAP_NAMES_LEN, 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_str_alloca, ast_strdupa, ast_strlen_zero, ast_test_flag, ast_tos2str(), authl, authl_lock, sip_settings::autocreatepeer, autocreatepeer2str(), bindaddr, sip_settings::caps, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, comedia_string(), ast_cli_entry::command, sip_settings::compactheaders, d, default_callerid, sip_settings::default_context, default_expiry, default_fromdomain, default_fromdomainport, default_keepalive, default_language, sip_settings::default_max_forwards, default_maxcallbitrate, default_mohinterpret, default_mohsuggest, default_notifymime, default_primary_transport, default_qualify, sip_settings::default_record_off_feature, sip_settings::default_record_on_feature, default_transports, default_vmexten, default_zone, sip_settings::directrtpsetup, sip_settings::domainsasrealm, dtmfmode2str(), ast_tls_config::enabled, externaddr, externhost, externrefresh, FALSE, faxec2str(), ast_cli_args::fd, sip_proxy::force, force_rport_string(), get_transport_list(), global_authfailureevents, global_autoframing, global_callcounter, global_cos_audio, global_cos_sip, global_cos_text, global_cos_video, global_jbconf, global_match_auth_username, global_max_se, global_min_se, global_prematuremediafilter, global_qualifyfreq, global_reg_retry_403, global_reg_timeout, global_regattempts_max, global_relaxdtmf, global_rtpholdtimeout, global_rtpkeepalive, global_rtptimeout, global_sdpowner, global_sdpsession, global_st_mode, global_st_refresher, global_store_sip_cause, global_t1, global_t1min, global_t38_maxdatagram, global_timer_b, global_tos_audio, global_tos_sip, global_tos_text, global_tos_video, global_useragent, IGNORE_CONTEXT, sip_settings::ignore_regexpire, ast_jb_conf::impl, sip_settings::legacy_useroption_parsing, sip_auth_container::list, ast_tcptls_session_args::local_address, max_expiry, ast_jb_conf::max_size, max_subexpiry, sip_auth::md5secret, min_expiry, min_subexpiry, sip_proxy::name, ast_ha::netmask, ast_ha::next, sip_settings::notifycid, sip_settings::notifyhold, sip_settings::notifyringing, NOTIFYRINGING_NOTINUSE, NULL, sip_settings::outboundproxy, sip_settings::pedanticsipchecking, sip_settings::peer_rtupdate, prefix, sip_settings::realm, sip_auth::realm, recordhistory, sip_settings::regcontext, sip_settings::regextenonqualify, ast_jb_conf::resync_threshold, sip_settings::rtautoclear, rtpbindaddr, sip_settings::rtsave_path, sip_settings::rtsave_sysname, S_OR, sip_auth::secret, sip_settings::send_diversion, sip_cfg, SIP_DTMF, sip_get_transport(), SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_IGNORESDPVERSION, SIP_PAGE2_Q850_REASON, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_RTAUTOCLEAR, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_TEXTSUPPORT, SIP_PAGE2_VIDEOSUPPORT, SIP_PAGE3_RTCP_MUX, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_NO, SIP_PROMISCREDIR, SIP_SENDRPID, SIP_TRUSTRPID, SIP_USECLIENTCODE, SIP_USEPATH, SIP_USEREQPHONE, sip_settings::srvlookup, STANDARD_SIP_PORT, stmode2str(), strefresherparam2str(), ast_jb_conf::target_extra, sip_settings::tcp_enabled, transfermode2str(), ast_cli_entry::usage, and sip_auth::username.

21843 {
21844  int realtimepeers;
21845  int realtimeregs;
21846  struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
21847  const char *msg; /* temporary msg pointer */
21848  struct sip_auth_container *credentials;
21849 
21850  switch (cmd) {
21851  case CLI_INIT:
21852  e->command = "sip show settings";
21853  e->usage =
21854  "Usage: sip show settings\n"
21855  " Provides detailed list of the configuration of the SIP channel.\n";
21856  return NULL;
21857  case CLI_GENERATE:
21858  return NULL;
21859  }
21860 
21861  if (a->argc != 3)
21862  return CLI_SHOWUSAGE;
21863 
21864  realtimepeers = ast_check_realtime("sippeers");
21865  realtimeregs = ast_check_realtime("sipregs");
21866 
21868  credentials = authl;
21869  if (credentials) {
21870  ao2_t_ref(credentials, +1, "Ref global auth for show");
21871  }
21873 
21874  ast_cli(a->fd, "\n\nGlobal Settings:\n");
21875  ast_cli(a->fd, "----------------\n");
21876  ast_cli(a->fd, " UDP Bindaddress: %s\n", ast_sockaddr_stringify(&bindaddr));
21878  ast_cli(a->fd, " ** Additional Info:\n");
21879  ast_cli(a->fd, " [::] may include IPv4 in addition to IPv6, if such a feature is enabled in the OS.\n");
21880  }
21881  ast_cli(a->fd, " TCP SIP Bindaddress: %s\n",
21884  "Disabled");
21885  ast_cli(a->fd, " TLS SIP Bindaddress: %s\n",
21888  "Disabled");
21889  ast_cli(a->fd, " RTP Bindaddress: %s\n",
21892  "Disabled");
21893  ast_cli(a->fd, " Videosupport: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT)));
21894  ast_cli(a->fd, " Textsupport: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_TEXTSUPPORT)));
21895  ast_cli(a->fd, " Ignore SDP sess. ver.: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_IGNORESDPVERSION)));
21896  ast_cli(a->fd, " AutoCreate Peer: %s\n", autocreatepeer2str(sip_cfg.autocreatepeer));
21897  ast_cli(a->fd, " Match Auth Username: %s\n", AST_CLI_YESNO(global_match_auth_username));
21898  ast_cli(a->fd, " Allow unknown access: %s\n", AST_CLI_YESNO(sip_cfg.allowguest));
21899  ast_cli(a->fd, " Allow subscriptions: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)));
21900  ast_cli(a->fd, " Allow overlap dialing: %s\n", allowoverlap2str(ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP)));
21901  ast_cli(a->fd, " Allow promisc. redir: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_PROMISCREDIR)));
21902  ast_cli(a->fd, " Enable call counters: %s\n", AST_CLI_YESNO(global_callcounter));
21903  ast_cli(a->fd, " SIP domain support: %s\n", AST_CLI_YESNO(!AST_LIST_EMPTY(&domain_list)));
21904  ast_cli(a->fd, " Path support : %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_USEPATH)));
21905  ast_cli(a->fd, " Realm. auth: %s\n", AST_CLI_YESNO(credentials != NULL));
21906  if (credentials) {
21907  struct sip_auth *auth;
21908 
21909  AST_LIST_TRAVERSE(&credentials->list, auth, node) {
21910  ast_cli(a->fd, " Realm. auth entry: Realm %-15.15s User %-10.20s %s\n",
21911  auth->realm,
21912  auth->username,
21913  !ast_strlen_zero(auth->secret)
21914  ? "<Secret set>"
21915  : (!ast_strlen_zero(auth->md5secret)
21916  ? "<MD5secret set>" : "<Not set>"));
21917  }
21918  ao2_t_ref(credentials, -1, "Unref global auth for show");
21919  }
21920  ast_cli(a->fd, " Our auth realm %s\n", sip_cfg.realm);
21921  ast_cli(a->fd, " Use domains as realms: %s\n", AST_CLI_YESNO(sip_cfg.domainsasrealm));
21922  ast_cli(a->fd, " Call to non-local dom.: %s\n", AST_CLI_YESNO(sip_cfg.allow_external_domains));
21923  ast_cli(a->fd, " URI user is phone no: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_USEREQPHONE)));
21924  ast_cli(a->fd, " Always auth rejects: %s\n", AST_CLI_YESNO(sip_cfg.alwaysauthreject));
21925  ast_cli(a->fd, " Direct RTP setup: %s\n", AST_CLI_YESNO(sip_cfg.directrtpsetup));
21926  ast_cli(a->fd, " User Agent: %s\n", global_useragent);
21927  ast_cli(a->fd, " SDP Session Name: %s\n", ast_strlen_zero(global_sdpsession) ? "-" : global_sdpsession);
21928  ast_cli(a->fd, " SDP Owner Name: %s\n", ast_strlen_zero(global_sdpowner) ? "-" : global_sdpowner);
21929  ast_cli(a->fd, " Reg. context: %s\n", S_OR(sip_cfg.regcontext, "(not set)"));
21930  ast_cli(a->fd, " Regexten on Qualify: %s\n", AST_CLI_YESNO(sip_cfg.regextenonqualify));
21931  ast_cli(a->fd, " Trust RPID: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_TRUSTRPID)));
21932  ast_cli(a->fd, " Send RPID: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_SENDRPID)));
21933  ast_cli(a->fd, " Legacy userfield parse: %s\n", AST_CLI_YESNO(sip_cfg.legacy_useroption_parsing));
21934  ast_cli(a->fd, " Send Diversion: %s\n", AST_CLI_YESNO(sip_cfg.send_diversion));
21935  ast_cli(a->fd, " Caller ID: %s\n", default_callerid);
21937  ast_cli(a->fd, " From: Domain: %s:%d\n", default_fromdomain, default_fromdomainport);
21938  } else {
21939  ast_cli(a->fd, " From: Domain: %s\n", default_fromdomain);
21940  }
21941  ast_cli(a->fd, " Record SIP history: %s\n", AST_CLI_ONOFF(recordhistory));
21942  ast_cli(a->fd, " Auth. Failure Events: %s\n", AST_CLI_ONOFF(global_authfailureevents));
21943 
21944  ast_cli(a->fd, " T.38 support: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT)));
21945  ast_cli(a->fd, " T.38 EC mode: %s\n", faxec2str(ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT)));
21946  ast_cli(a->fd, " T.38 MaxDtgrm: %u\n", global_t38_maxdatagram);
21947  if (!realtimepeers && !realtimeregs)
21948  ast_cli(a->fd, " SIP realtime: Disabled\n" );
21949  else
21950  ast_cli(a->fd, " SIP realtime: Enabled\n" );
21951  ast_cli(a->fd, " Qualify Freq : %d ms\n", global_qualifyfreq);
21952  ast_cli(a->fd, " Q.850 Reason header: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_Q850_REASON)));
21953  ast_cli(a->fd, " Store SIP_CAUSE: %s\n", AST_CLI_YESNO(global_store_sip_cause));
21954  ast_cli(a->fd, "\nNetwork QoS Settings:\n");
21955  ast_cli(a->fd, "---------------------------\n");
21956  ast_cli(a->fd, " IP ToS SIP: %s\n", ast_tos2str(global_tos_sip));
21957  ast_cli(a->fd, " IP ToS RTP audio: %s\n", ast_tos2str(global_tos_audio));
21958  ast_cli(a->fd, " IP ToS RTP video: %s\n", ast_tos2str(global_tos_video));
21959  ast_cli(a->fd, " IP ToS RTP text: %s\n", ast_tos2str(global_tos_text));
21960  ast_cli(a->fd, " 802.1p CoS SIP: %u\n", global_cos_sip);
21961  ast_cli(a->fd, " 802.1p CoS RTP audio: %u\n", global_cos_audio);
21962  ast_cli(a->fd, " 802.1p CoS RTP video: %u\n", global_cos_video);
21963  ast_cli(a->fd, " 802.1p CoS RTP text: %u\n", global_cos_text);
21964  ast_cli(a->fd, " Jitterbuffer enabled: %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_ENABLED)));
21966  ast_cli(a->fd, " Jitterbuffer forced: %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_FORCED)));
21967  ast_cli(a->fd, " Jitterbuffer max size: %ld\n", global_jbconf.max_size);
21968  ast_cli(a->fd, " Jitterbuffer resync: %ld\n", global_jbconf.resync_threshold);
21969  ast_cli(a->fd, " Jitterbuffer impl: %s\n", global_jbconf.impl);
21970  if (!strcasecmp(global_jbconf.impl, "adaptive")) {
21971  ast_cli(a->fd, " Jitterbuffer tgt extra: %ld\n", global_jbconf.target_extra);
21972  }
21973  ast_cli(a->fd, " Jitterbuffer log: %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_LOG)));
21974  }
21975 
21976  ast_cli(a->fd, "\nNetwork Settings:\n");
21977  ast_cli(a->fd, "---------------------------\n");
21978  /* determine if/how SIP address can be remapped */
21979  if (localaddr == NULL)
21980  msg = "Disabled, no localnet list";
21981  else if (ast_sockaddr_isnull(&externaddr))
21982  msg = "Disabled";
21983  else if (!ast_strlen_zero(externhost))
21984  msg = "Enabled using externhost";
21985  else
21986  msg = "Enabled using externaddr";
21987  ast_cli(a->fd, " SIP address remapping: %s\n", msg);
21988  ast_cli(a->fd, " Externhost: %s\n", S_OR(externhost, "<none>"));
21989  ast_cli(a->fd, " Externaddr: %s\n", ast_sockaddr_stringify(&externaddr));
21990  ast_cli(a->fd, " Externrefresh: %d\n", externrefresh);
21991  {
21992  struct ast_ha *d;
21993  const char *prefix = "Localnet:";
21994 
21995  for (d = localaddr; d ; prefix = "", d = d->next) {
21996  const char *addr = ast_strdupa(ast_sockaddr_stringify_addr(&d->addr));
21997  const char *mask = ast_strdupa(ast_sockaddr_stringify_addr(&d->netmask));
21998  ast_cli(a->fd, " %-24s%s/%s\n", prefix, addr, mask);
21999  }
22000  }
22001  ast_cli(a->fd, "\nGlobal Signalling Settings:\n");
22002  ast_cli(a->fd, "---------------------------\n");
22003  ast_cli(a->fd, " Codecs: %s\n", ast_format_cap_get_names(sip_cfg.caps, &codec_buf));
22004  ast_cli(a->fd, " Relax DTMF: %s\n", AST_CLI_YESNO(global_relaxdtmf));
22005  ast_cli(a->fd, " RFC2833 Compensation: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE)));
22006  ast_cli(a->fd, " Symmetric RTP: %s\n", comedia_string(global_flags));
22007  ast_cli(a->fd, " Compact SIP headers: %s\n", AST_CLI_YESNO(sip_cfg.compactheaders));
22008  ast_cli(a->fd, " RTP Keepalive: %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" );
22009  ast_cli(a->fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" );
22010  ast_cli(a->fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)");
22011  ast_cli(a->fd, " MWI NOTIFY mime type: %s\n", default_notifymime);
22012  ast_cli(a->fd, " DNS SRV lookup: %s\n", AST_CLI_YESNO(sip_cfg.srvlookup));
22013  ast_cli(a->fd, " Pedantic SIP support: %s\n", AST_CLI_YESNO(sip_cfg.pedanticsipchecking));
22014  ast_cli(a->fd, " Reg. min duration %d secs\n", min_expiry);
22015  ast_cli(a->fd, " Reg. max duration: %d secs\n", max_expiry);
22016  ast_cli(a->fd, " Reg. default duration: %d secs\n", default_expiry);
22017  ast_cli(a->fd, " Sub. min duration %d secs\n", min_subexpiry);
22018  ast_cli(a->fd, " Sub. max duration: %d secs\n", max_subexpiry);
22019  ast_cli(a->fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout);
22020  ast_cli(a->fd, " Outbound reg. attempts: %d\n", global_regattempts_max);
22021  ast_cli(a->fd, " Outbound reg. retry 403:%s\n", AST_CLI_YESNO(global_reg_retry_403));
22022  ast_cli(a->fd, " Notify ringing state: %s%s\n", AST_CLI_YESNO(sip_cfg.notifyringing), sip_cfg.notifyringing == NOTIFYRINGING_NOTINUSE ? " (when not in use)" : "");
22023  if (sip_cfg.notifyringing) {
22024  ast_cli(a->fd, " Include CID: %s%s\n",
22026  sip_cfg.notifycid == IGNORE_CONTEXT ? " (Ignoring context)" : "");
22027  }
22028  ast_cli(a->fd, " Notify hold state: %s\n", AST_CLI_YESNO(sip_cfg.notifyhold));
22029  ast_cli(a->fd, " SIP Transfer mode: %s\n", transfermode2str(sip_cfg.allowtransfer));
22030  ast_cli(a->fd, " Max Call Bitrate: %d kbps\n", default_maxcallbitrate);
22031  ast_cli(a->fd, " Auto-Framing: %s\n", AST_CLI_YESNO(global_autoframing));
22032  ast_cli(a->fd, " Outb. proxy: %s %s\n", ast_strlen_zero(sip_cfg.outboundproxy.name) ? "<not set>" : sip_cfg.outboundproxy.name,
22033  sip_cfg.outboundproxy.force ? "(forced)" : "");
22034  ast_cli(a->fd, " Session Timers: %s\n", stmode2str(global_st_mode));
22035  ast_cli(a->fd, " Session Refresher: %s\n", strefresherparam2str(global_st_refresher));
22036  ast_cli(a->fd, " Session Expires: %d secs\n", global_max_se);
22037  ast_cli(a->fd, " Session Min-SE: %d secs\n", global_min_se);
22038  ast_cli(a->fd, " Timer T1: %d\n", global_t1);
22039  ast_cli(a->fd, " Timer T1 minimum: %d\n", global_t1min);
22040  ast_cli(a->fd, " Timer B: %d\n", global_timer_b);
22041  ast_cli(a->fd, " No premature media: %s\n", AST_CLI_YESNO(global_prematuremediafilter));
22042  ast_cli(a->fd, " Max forwards: %d\n", sip_cfg.default_max_forwards);
22043 
22044  ast_cli(a->fd, "\nDefault Settings:\n");
22045  ast_cli(a->fd, "-----------------\n");
22046  ast_cli(a->fd, " Allowed transports: %s\n", get_transport_list(default_transports));
22047  ast_cli(a->fd, " Outbound transport: %s\n", sip_get_transport(default_primary_transport));
22048  ast_cli(a->fd, " Context: %s\n", sip_cfg.default_context);
22049  ast_cli(a->fd, " Record on feature: %s\n", sip_cfg.default_record_on_feature);
22050  ast_cli(a->fd, " Record off feature: %s\n", sip_cfg.default_record_off_feature);
22051  ast_cli(a->fd, " Force rport: %s\n", force_rport_string(global_flags));
22052  ast_cli(a->fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF)));
22053  ast_cli(a->fd, " Qualify: %d\n", default_qualify);
22054  ast_cli(a->fd, " Keepalive: %d\n", default_keepalive);
22055  ast_cli(a->fd, " Use ClientCode: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_USECLIENTCODE)));
22057  ast_cli(a->fd, " Language: %s\n", default_language);
22058  ast_cli(a->fd, " Tone zone: %s\n", default_zone[0] != '\0' ? default_zone : "<Not set>");
22059  ast_cli(a->fd, " MOH Interpret: %s\n", default_mohinterpret);
22060  ast_cli(a->fd, " MOH Suggest: %s\n", default_mohsuggest);
22061  ast_cli(a->fd, " Voice Mail Extension: %s\n", default_vmexten);
22062  ast_cli(a->fd, " RTCP Multiplexing: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[2], SIP_PAGE3_RTCP_MUX)));
22063 
22064 
22065  if (realtimepeers || realtimeregs) {
22066  ast_cli(a->fd, "\nRealtime SIP Settings:\n");
22067  ast_cli(a->fd, "----------------------\n");
22068  ast_cli(a->fd, " Realtime Peers: %s\n", AST_CLI_YESNO(realtimepeers));
22069  ast_cli(a->fd, " Realtime Regs: %s\n", AST_CLI_YESNO(realtimeregs));
22070  ast_cli(a->fd, " Cache Friends: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)));
22071  ast_cli(a->fd, " Update: %s\n", AST_CLI_YESNO(sip_cfg.peer_rtupdate));
22072  ast_cli(a->fd, " Ignore Reg. Expire: %s\n", AST_CLI_YESNO(sip_cfg.ignore_regexpire));
22073  ast_cli(a->fd, " Save sys. name: %s\n", AST_CLI_YESNO(sip_cfg.rtsave_sysname));
22074  ast_cli(a->fd, " Save path header: %s\n", AST_CLI_YESNO(sip_cfg.rtsave_path));
22075  ast_cli(a->fd, " Auto Clear: %d (%s)\n", sip_cfg.rtautoclear, ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR) ? "Enabled" : "Disabled");
22076  }
22077  ast_cli(a->fd, "\n----\n");
22078  return CLI_SUCCESS;
22079 }
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:290
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
static struct ast_tcptls_session_args sip_tls_desc
The TCP/TLS server definition.
Definition: chan_sip.c:2394
struct ast_ha * next
Definition: acl.h:56
static unsigned int global_cos_video
Definition: chan_sip.c:839
#define SIP_PAGE3_RTCP_MUX
Definition: sip.h:394
static unsigned int global_tos_text
Definition: chan_sip.c:836
Definition: test_heap.c:38
int force
Definition: sip.h:727
#define SIP_PAGE2_ALLOWSUBSCRIBE
Definition: sip.h:335
static struct ast_ha * localaddr
List of local networks We store "localnet" addresses from the config file into an access list...
Definition: chan_sip.c:1147
#define FALSE
Definition: app_minivm.c:521
static struct ast_tls_config default_tls_cfg
Default TLS connection configuration.
Definition: chan_sip.c:2377
static int max_expiry
Definition: chan_sip.c:668
enum notifycid_setting notifycid
Definition: sip.h:775
static int default_keepalive
Definition: chan_sip.c:798
static unsigned int global_cos_text
Definition: chan_sip.c:840
int directrtpsetup
Definition: sip.h:755
static unsigned int global_tos_audio
Definition: chan_sip.c:834
#define SIP_USEPATH
Definition: sip.h:305
static struct ast_sockaddr rtpbindaddr
Definition: chan_sip.c:1133
#define ast_test_flag(p, flag)
Definition: utils.h:63
int domainsasrealm
Definition: sip.h:780
struct ast_sockaddr addr
Definition: acl.h:53
int tcp_enabled
Definition: sip.h:788
static int global_t1min
Definition: chan_sip.c:848
static struct sip_auth_container * authl
Authentication container for realm authentication.
Definition: chan_sip.c:1079
const int argc
Definition: cli.h:160
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:326
static char global_useragent[AST_MAX_EXTENSION]
Definition: chan_sip.c:843
static struct test_val d
static int global_rtptimeout
Definition: chan_sip.c:823
int ast_check_realtime(const char *family)
Check if realtime engine is configured for family.
Definition: main/config.c:3363
#define SIP_TRUSTRPID
Definition: sip.h:270
static unsigned int global_tos_video
Definition: chan_sip.c:835
const char * sip_get_transport(enum ast_transport t)
Return transport as string.
Definition: chan_sip.c:3725
Definition: cli.h:152
static char default_language[MAX_LANGUAGE]
Definition: chan_sip.c:790
static struct ast_tcptls_session_args sip_tcp_desc
The TCP server definition.
Definition: chan_sip.c:2383
static char default_fromdomain[AST_MAX_EXTENSION]
Definition: chan_sip.c:793
int srvlookup
Definition: sip.h:758
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
#define ast_mutex_lock(a)
Definition: lock.h:187
#define ast_str_alloca(init_len)
Definition: strings.h:800
#define SIP_PAGE2_RFC2833_COMPENSATE
Definition: sip.h:356
static unsigned int global_t38_maxdatagram
Definition: chan_sip.c:885
static char default_callerid[AST_MAX_EXTENSION]
Definition: chan_sip.c:791
static ast_mutex_t authl_lock
Global authentication container protection while adjusting the references.
Definition: chan_sip.c:1081
#define NULL
Definition: resample.c:96
static int default_maxcallbitrate
Definition: chan_sip.c:804
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
int peer_rtupdate
Definition: sip.h:750
static unsigned int default_transports
Definition: chan_sip.c:806
#define AST_CLI_ONOFF(x)
return On or Off depending on the argument. This is used in many places in CLI command, having a function to generate this helps maintaining a consistent output (and possibly emitting the output in other languages, at some point).
Definition: cli.h:78
static const char * stmode2str(enum st_mode m)
Definition: chan_sip.c:19990
static const char * allowoverlap2str(int mode) attribute_const
Convert AllowOverlap setting to printable string.
Definition: chan_sip.c:20631
static char * transfermode2str(enum transfermodes mode) attribute_const
Convert transfer mode to text string.
Definition: chan_sip.c:19968
enum transfermodes allowtransfer
Definition: sip.h:776
const char * comedia_string(struct ast_flags *flags)
Return a string describing the comedia value for the given flags.
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define SIP_PROG_INBAND
Definition: sip.h:300
static const char * strefresherparam2str(enum st_refresher_param r)
Definition: chan_sip.c:20015
char default_record_off_feature[AST_FEATURE_MAX_LEN]
Definition: sip.h:785
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
long resync_threshold
Resynchronization threshold of the jitterbuffer implementation.
Definition: abstract_jb.h:76
internal representation of ACL entries In principle user applications would have no need for this...
Definition: acl.h:51
int notifyhold
Definition: sip.h:774
int ast_sockaddr_is_any(const struct ast_sockaddr *addr)
Determine if the address type is unspecified, or "any" address.
Definition: netsock2.c:534
#define STANDARD_SIP_PORT
Standard SIP unsecure port for UDP and TCP from RFC 3261. DO NOT CHANGE THIS.
Definition: sip.h:176
struct ast_sockaddr netmask
Definition: acl.h:54
static int global_store_sip_cause
Definition: chan_sip.c:860
const int fd
Definition: cli.h:159
int compactheaders
Definition: sip.h:764
#define SIP_PROG_INBAND_NO
Definition: sip.h:301
int allow_external_domains
Definition: sip.h:765
static int min_subexpiry
Definition: chan_sip.c:670
static char default_zone[MAX_TONEZONE_COUNTRY]
Definition: chan_sip.c:805
static char externhost[MAXHOSTNAMELEN]
Definition: chan_sip.c:1135
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
long target_extra
amount of additional jitterbuffer adjustment
Definition: abstract_jb.h:80
static struct ast_sockaddr externaddr
our external IP address/port for SIP sessions. externaddr.sin_addr is only set when we know we might ...
Definition: chan_sip.c:1131
int default_max_forwards
Definition: sip.h:789
char impl[AST_JB_IMPL_NAME_SIZE]
Name of the jitterbuffer implementation to be used.
Definition: abstract_jb.h:78
int pedanticsipchecking
Definition: sip.h:756
static char global_sdpowner[AST_MAX_EXTENSION]
Definition: chan_sip.c:845
#define SIP_PAGE2_IGNORESDPVERSION
Definition: sip.h:344
static int default_expiry
Definition: chan_sip.c:669
struct sip_auth_container::@170 list
static const char * autocreatepeer2str(enum autocreatepeer_mode r)
Definition: chan_sip.c:20038
#define SIP_PAGE2_ALLOWOVERLAP
Definition: sip.h:337
static int default_qualify
Definition: chan_sip.c:797
static int global_callcounter
Definition: chan_sip.c:830
static unsigned int recordhistory
Definition: chan_sip.c:841
#define SIP_PAGE2_Q850_REASON
Definition: sip.h:326
char name[MAXHOSTNAMELEN]
Definition: sip.h:722
int legacy_useroption_parsing
Definition: sip.h:767
static int global_reg_retry_403
Definition: chan_sip.c:828
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
#define CLI_SHOWUSAGE
Definition: cli.h:45
struct ast_sockaddr bindaddr
Definition: chan_sip.c:1106
int rtautoclear
Definition: sip.h:754
#define SIP_PROG_INBAND_NEVER
Definition: sip.h:302
static int global_reg_timeout
Definition: chan_sip.c:826
static struct ast_flags global_flags[3]
Definition: chan_sip.c:884
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
static struct ast_jb_conf global_jbconf
Definition: chan_sip.c:688
static int externrefresh
Definition: chan_sip.c:1137
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition: format_cap.c:736
#define SIP_PAGE2_RTCACHEFRIENDS
Definition: sip.h:323
static char default_mohsuggest[MAX_MUSICCLASS]
Definition: chan_sip.c:800
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static int global_timer_b
Definition: chan_sip.c:849
const char * force_rport_string(struct ast_flags *flags)
Return a string describing the force_rport value for the given flags.
char * command
Definition: cli.h:186
static char global_sdpsession[AST_MAX_EXTENSION]
Definition: chan_sip.c:844
static int global_max_se
Definition: chan_sip.c:858
static unsigned int global_autoframing
Definition: chan_sip.c:850
int alwaysauthreject
Definition: sip.h:760
static int global_qualifyfreq
Definition: chan_sip.c:851
int notifyringing
Definition: sip.h:773
static int max_subexpiry
Definition: chan_sip.c:671
struct ast_format_cap * caps
Global list of addresses dynamic peers are not allowed to use.
Definition: sip.h:787
static enum st_refresher_param global_st_refresher
Definition: chan_sip.c:856
const char * usage
Definition: cli.h:177
char username[256]
Definition: sip.h:905
#define SIP_PAGE2_TEXTSUPPORT
Definition: sip.h:334
#define SIP_PAGE2_VIDEOSUPPORT
Definition: sip.h:333
#define CLI_SUCCESS
Definition: cli.h:44
#define SIP_PAGE2_T38SUPPORT
Definition: sip.h:346
int rtsave_sysname
Definition: sip.h:751
static enum st_mode global_st_mode
Definition: chan_sip.c:855
#define SIP_DTMF
Definition: sip.h:275
static char default_mohinterpret[MAX_MUSICCLASS]
Definition: chan_sip.c:799
static const char * faxec2str(int faxec)
Definition: chan_sip.c:21175
#define SIP_USECLIENTCODE
Definition: sip.h:272
char realm[AST_MAX_EXTENSION]
Definition: sip.h:904
char secret[256]
Definition: sip.h:906
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
static int default_fromdomainport
Definition: chan_sip.c:794
static const char * get_transport_list(unsigned int transports)
Return configuration of transports for a device.
Definition: chan_sip.c:3686
static int global_match_auth_username
Definition: chan_sip.c:819
static int global_regattempts_max
Definition: chan_sip.c:827
static int global_t1
Definition: chan_sip.c:847
enum autocreatepeer_mode autocreatepeer
Definition: sip.h:757
char default_record_on_feature[AST_FEATURE_MAX_LEN]
Definition: sip.h:784
static int global_authfailureevents
Definition: chan_sip.c:846
sip_auth: Credentials for authentication to other SIP services
Definition: sip.h:902
int allowguest
Definition: sip.h:759
static int global_rtpholdtimeout
Definition: chan_sip.c:824
static char default_vmexten[AST_MAX_EXTENSION]
Definition: chan_sip.c:796
char md5secret[256]
Definition: sip.h:907
#define SIP_PAGE2_RTAUTOCLEAR
Definition: sip.h:324
static char default_notifymime[AST_MAX_EXTENSION]
Definition: chan_sip.c:795
#define SIP_PROMISCREDIR
Definition: sip.h:269
static unsigned int global_cos_audio
Definition: chan_sip.c:838
#define AST_CLI_YESNO(x)
Return Yes or No depending on the argument.
Definition: cli.h:71
struct ast_sockaddr local_address
Definition: tcptls.h:130
struct sip_proxy outboundproxy
Definition: sip.h:781
static unsigned int global_cos_sip
Definition: chan_sip.c:837
static unsigned int global_tos_sip
Definition: chan_sip.c:833
char default_context[AST_MAX_CONTEXT]
Definition: sip.h:782
static unsigned int default_primary_transport
Definition: chan_sip.c:807
int rtsave_path
Definition: sip.h:752
static int global_rtpkeepalive
Definition: chan_sip.c:825
long max_size
Max size of the jitterbuffer implementation.
Definition: abstract_jb.h:74
const char * ast_tos2str(unsigned int tos)
Convert a TOS value into its string representation.
Definition: acl.c:987
char realm[MAXHOSTNAMELEN]
Definition: sip.h:779
char regcontext[AST_MAX_CONTEXT]
Definition: sip.h:770
Container of SIP authentication credentials.
Definition: sip.h:911
static int global_relaxdtmf
Definition: chan_sip.c:821
#define SIP_USEREQPHONE
Definition: sip.h:271
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
Definition: netsock2.c:524
static const char * dtmfmode2str(int mode) attribute_const
Convert DTMF mode to printable string.
Definition: chan_sip.c:20598
static int global_prematuremediafilter
Definition: chan_sip.c:822
static int global_min_se
Definition: chan_sip.c:857
int ignore_regexpire
Definition: sip.h:753
#define ast_mutex_unlock(a)
Definition: lock.h:188
int send_diversion
Definition: sip.h:768
#define SIP_SENDRPID
Definition: sip.h:306
static char prefix[MAX_PREFIX]
Definition: http.c:141
static int min_expiry
Definition: chan_sip.c:667
int regextenonqualify
Definition: sip.h:766
int enabled
Definition: tcptls.h:88

◆ sip_show_tcp()

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 20067 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_tcptls_session_instance::client, ast_cli_entry::command, ast_cli_args::fd, FORMAT, FORMAT2, NULL, ast_tcptls_session_instance::remote_address, sip_get_transport(), sip_threadinfo::tcptls_session, sip_threadinfo::type, and ast_cli_entry::usage.

20068 {
20069  struct sip_threadinfo *th;
20070  struct ao2_iterator i;
20071 
20072 #define FORMAT2 "%-47.47s %9.9s %6.6s\n"
20073 #define FORMAT "%-47.47s %-9.9s %-6.6s\n"
20074 
20075  switch (cmd) {
20076  case CLI_INIT:
20077  e->command = "sip show tcp";
20078  e->usage =
20079  "Usage: sip show tcp\n"
20080  " Lists all active TCP/TLS sessions.\n";
20081  return NULL;
20082  case CLI_GENERATE:
20083  return NULL;
20084  }
20085 
20086  if (a->argc != 3)
20087  return CLI_SHOWUSAGE;
20088 
20089  ast_cli(a->fd, FORMAT2, "Address", "Transport", "Type");
20090 
20091  i = ao2_iterator_init(threadt, 0);
20092  while ((th = ao2_t_iterator_next(&i, "iterate through tcp threads for 'sip show tcp'"))) {
20093  ast_cli(a->fd, FORMAT,
20095  sip_get_transport(th->type),
20096  (th->tcptls_session->client ? "Client" : "Server"));
20097  ao2_t_ref(th, -1, "decrement ref from iterator");
20098  }
20100 
20101  return CLI_SUCCESS;
20102 #undef FORMAT
20103 #undef FORMAT2
20104 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
static struct ao2_container * threadt
The table of TCP threads.
Definition: chan_sip.c:1049
const int argc
Definition: cli.h:160
const char * sip_get_transport(enum ast_transport t)
Return transport as string.
Definition: chan_sip.c:3725
Definition: cli.h:152
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
#define FORMAT2
Definition: chan_sip.c:22151
Definition of a thread that handles a socket.
Definition: sip.h:1441
const int fd
Definition: cli.h:159
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define ao2_t_iterator_next(iter, tag)
Definition: astobj2.h:1931
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
enum ast_transport type
Definition: sip.h:1447
#define FORMAT
Definition: chan_sip.c:22152
struct ast_tcptls_session_instance * tcptls_session
Definition: sip.h:1446
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
struct ast_sockaddr remote_address
Definition: tcptls.h:151

◆ sip_show_user()

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

References sip_peer::accountcode, sip_peer::acl, sip_peer::allowtransfer, sip_peer::amaflags, ao2_lock, ao2_unlock, ast_cli_args::argc, ast_cli_args::argv, ast_acl_list_is_empty(), ast_callerid_merge(), ast_channel_amaflags2string(), ast_cli(), ast_cli_complete(), AST_CLI_YESNO, ast_describe_caller_presentation(), ast_strlen_zero, sip_peer::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sip_show_user(), sip_peer::context, sip_peer::engine, FALSE, ast_cli_args::fd, FINDUSERS, sip_peer::language, ast_cli_args::line, sip_peer::maxcallbitrate, sip_peer::md5secret, ast_cli_args::n, ast_variable::name, sip_peer::name, sip_peer::named_callgroups, sip_peer::named_pickupgroups, ast_variable::next, NULL, sip_peer::pickupgroup, ast_cli_args::pos, print_group(), print_named_groups(), sip_peer::secret, sip_find_peer(), sip_unref_peer, sip_st_cfg::st_max_se, sip_st_cfg::st_min_se, sip_st_cfg::st_mode_oper, sip_st_cfg::st_ref, sip_peer::stimer, stmode2str(), strefresherparam2str(), transfermode2str(), TRUE, ast_cli_entry::usage, user, ast_variable::value, ast_cli_args::word, and sip_peer::zone.

21510 {
21511  char cbuf[256];
21512  struct sip_peer *user;
21513  struct ast_variable *v;
21514  int load_realtime;
21515 
21516  switch (cmd) {
21517  case CLI_INIT:
21518  e->command = "sip show user";
21519  e->usage =
21520  "Usage: sip show user <name> [load]\n"
21521  " Shows all details on one SIP user and the current status.\n"
21522  " Option \"load\" forces lookup of peer in realtime storage.\n";
21523  return NULL;
21524  case CLI_GENERATE:
21525  if (a->pos == 4) {
21526  static const char * const completions[] = { "load", NULL };
21527  return ast_cli_complete(a->word, completions, a->n);
21528  } else {
21529  return complete_sip_show_user(a->line, a->word, a->pos, a->n);
21530  }
21531  }
21532 
21533  if (a->argc < 4)
21534  return CLI_SHOWUSAGE;
21535 
21536  /* Load from realtime storage? */
21537  load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? TRUE : FALSE;
21538 
21539  if ((user = sip_find_peer(a->argv[3], NULL, load_realtime, FINDUSERS, FALSE, 0))) {
21540  ao2_lock(user);
21541  ast_cli(a->fd, "\n\n");
21542  ast_cli(a->fd, " * Name : %s\n", user->name);
21543  ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>");
21544  ast_cli(a->fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>");
21545  ast_cli(a->fd, " Context : %s\n", user->context);
21546  ast_cli(a->fd, " Language : %s\n", user->language);
21547  if (!ast_strlen_zero(user->accountcode))
21548  ast_cli(a->fd, " Accountcode : %s\n", user->accountcode);
21549  ast_cli(a->fd, " AMA flags : %s\n", ast_channel_amaflags2string(user->amaflags));
21550  ast_cli(a->fd, " Tonezone : %s\n", user->zone[0] != '\0' ? user->zone : "<Not set>");
21551  ast_cli(a->fd, " Transfer mode: %s\n", transfermode2str(user->allowtransfer));
21552  ast_cli(a->fd, " MaxCallBR : %d kbps\n", user->maxcallbitrate);
21553  ast_cli(a->fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres));
21554  ast_cli(a->fd, " Call limit : %d\n", user->call_limit);
21555  ast_cli(a->fd, " Callgroup : ");
21556  print_group(a->fd, user->callgroup, 0);
21557  ast_cli(a->fd, " Pickupgroup : ");
21558  print_group(a->fd, user->pickupgroup, 0);
21559  ast_cli(a->fd, " Named Callgr : ");
21560  print_named_groups(a->fd, user->named_callgroups, 0);
21561  ast_cli(a->fd, " Nam. Pickupgr: ");
21563  ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>"));
21564  ast_cli(a->fd, " ACL : %s\n", AST_CLI_YESNO(ast_acl_list_is_empty(user->acl) == 0));
21565  ast_cli(a->fd, " Sess-Timers : %s\n", stmode2str(user->stimer.st_mode_oper));
21566  ast_cli(a->fd, " Sess-Refresh : %s\n", strefresherparam2str(user->stimer.st_ref));
21567  ast_cli(a->fd, " Sess-Expires : %d secs\n", user->stimer.st_max_se);
21568  ast_cli(a->fd, " Sess-Min-SE : %d secs\n", user->stimer.st_min_se);
21569  ast_cli(a->fd, " RTP Engine : %s\n", user->engine);
21570 
21571  ast_cli(a->fd, " Auto-Framing: %s \n", AST_CLI_YESNO(user->autoframing));
21572  if (user->chanvars) {
21573  ast_cli(a->fd, " Variables :\n");
21574  for (v = user->chanvars ; v ; v = v->next)
21575  ast_cli(a->fd, " %s = %s\n", v->name, v->value);
21576  }
21577 
21578  ast_cli(a->fd, "\n");
21579 
21580  ao2_unlock(user);
21581  sip_unref_peer(user, "sip show user");
21582  } else {
21583  ast_cli(a->fd, "User %s not found.\n", a->argv[3]);
21584  ast_cli(a->fd, "\n");
21585  }
21586 
21587  return CLI_SUCCESS;
21588 }
static char user[512]
int st_min_se
Definition: sip.h:978
struct ast_variable * next
struct ast_namedgroups * named_pickupgroups
Definition: sip.h:1349
#define FALSE
Definition: app_minivm.c:521
struct sip_peer * sip_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.
Definition: chan_sip.c:5851
static char * complete_sip_show_user(const char *line, const char *word, int pos, int state)
Support routine for &#39;sip show user&#39; CLI.
Definition: chan_sip.c:21500
const ast_string_field language
Definition: sip.h:1306
const char * ast_describe_caller_presentation(int data)
Convert caller ID pres value to explanatory string.
Definition: callerid.c:1164
const ast_string_field accountcode
Definition: sip.h:1306
const int argc
Definition: cli.h:160
Structure for variables, used for configurations and for channel variables.
Definition: cli.h:152
const char * ast_channel_amaflags2string(enum ama_flags flags)
Convert the enum representation of an AMA flag to a string representation.
Definition: channel.c:4418
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
int st_max_se
Definition: sip.h:979
const char * line
Definition: cli.h:162
char name[80]
Definition: sip.h:1274
static const char * stmode2str(enum st_mode m)
Definition: chan_sip.c:19990
struct ast_variable * chanvars
Definition: sip.h:1366
static char * transfermode2str(enum transfermodes mode) attribute_const
Convert transfer mode to text string.
Definition: chan_sip.c:19968
#define ast_strlen_zero(foo)
Definition: strings.h:52
char * ast_cli_complete(const char *word, const char *const choices[], int pos)
Definition: main/cli.c:1811
static const char * strefresherparam2str(enum st_refresher_param r)
Definition: chan_sip.c:20015
enum transfermodes allowtransfer
Definition: sip.h:1332
struct ast_namedgroups * named_callgroups
Definition: sip.h:1348
struct ast_acl_list * acl
Definition: sip.h:1363
char * ast_callerid_merge(char *buf, int bufsiz, const char *name, const char *num, const char *unknown)
Definition: callerid.c:1073
int amaflags
Definition: sip.h:1323
static void print_group(int fd, ast_group_t group, int crlf)
Print call group and pickup group.
Definition: chan_sip.c:20571
const int fd
Definition: cli.h:159
const int n
Definition: cli.h:165
int call_limit
Definition: sip.h:1328
#define ao2_lock(a)
Definition: astobj2.h:718
int maxcallbitrate
Definition: sip.h:1340
const ast_string_field md5secret
Definition: sip.h:1306
int ast_acl_list_is_empty(struct ast_acl_list *acl_list)
Determines if an ACL is empty or if it contains entries.
Definition: acl.c:541
const char *const * argv
Definition: cli.h:161
#define FINDUSERS
Definition: sip.h:52
const ast_string_field zone
Definition: sip.h:1306
#define CLI_SHOWUSAGE
Definition: cli.h:45
static void print_named_groups(int fd, struct ast_namedgroups *groups, int crlf)
Print named call groups and pickup groups.
Definition: chan_sip.c:20578
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
char * command
Definition: cli.h:186
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
const char * word
Definition: cli.h:163
enum st_mode st_mode_oper
Definition: sip.h:976
unsigned short autoframing
Definition: sip.h:1317
const char * usage
Definition: cli.h:177
ast_group_t callgroup
Definition: sip.h:1346
const ast_string_field cid_name
Definition: sip.h:1306
#define CLI_SUCCESS
Definition: cli.h:44
const int pos
Definition: cli.h:164
#define TRUE
Definition: app_minivm.c:518
const ast_string_field secret
Definition: sip.h:1306
const ast_string_field cid_num
Definition: sip.h:1306
int callingpres
Definition: sip.h:1324
#define AST_CLI_YESNO(x)
Return Yes or No depending on the argument.
Definition: cli.h:71
struct sip_st_cfg stimer
Definition: sip.h:1368
enum st_refresher_param st_ref
Definition: sip.h:977
const ast_string_field engine
Definition: sip.h:1306
ast_group_t pickupgroup
Definition: sip.h:1347
const ast_string_field context
Definition: sip.h:1306

◆ sip_show_users()

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

References sip_peer::accountcode, sip_peer::acl, ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_iterator_next, ao2_unlock, ast_cli_args::argc, ast_cli_args::argv, ast_acl_list_is_empty(), ast_cli(), AST_CLI_YESNO, ast_test_flag, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, sip_peer::context, FALSE, ast_cli_args::fd, sip_peer::flags, FORMAT, sip_peer::name, NULL, sip_peer::secret, SIP_NAT_FORCE_RPORT, SIP_TYPE_USER, sip_unref_peer, TRUE, sip_peer::type, ast_cli_entry::usage, and user.

20108 {
20109  regex_t regexbuf;
20110  int havepattern = FALSE;
20111  struct ao2_iterator user_iter;
20112  struct sip_peer *user;
20113 
20114 #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n"
20115 
20116  switch (cmd) {
20117  case CLI_INIT:
20118  e->command = "sip show users [like]";
20119  e->usage =
20120  "Usage: sip show users [like <pattern>]\n"
20121  " Lists all known SIP users.\n"
20122  " Optional regular expression pattern is used to filter the user list.\n";
20123  return NULL;
20124  case CLI_GENERATE:
20125  return NULL;
20126  }
20127 
20128  switch (a->argc) {
20129  case 5:
20130  if (!strcasecmp(a->argv[3], "like")) {
20131  if (regcomp(&regexbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
20132  return CLI_SHOWUSAGE;
20133  havepattern = TRUE;
20134  } else
20135  return CLI_SHOWUSAGE;
20136  case 3:
20137  break;
20138  default:
20139  return CLI_SHOWUSAGE;
20140  }
20141 
20142  ast_cli(a->fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "Forcerport");
20143 
20144  user_iter = ao2_iterator_init(peers, 0);
20145  while ((user = ao2_t_iterator_next(&user_iter, "iterate thru peers table"))) {
20146  ao2_lock(user);
20147  if (!(user->type & SIP_TYPE_USER)) {
20148  ao2_unlock(user);
20149  sip_unref_peer(user, "sip show users");
20150  continue;
20151  }
20152 
20153  if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0)) {
20154  ao2_unlock(user);
20155  sip_unref_peer(user, "sip show users");
20156  continue;
20157  }
20158 
20159  ast_cli(a->fd, FORMAT, user->name,
20160  user->secret,
20161  user->accountcode,
20162  user->context,
20165  ao2_unlock(user);
20166  sip_unref_peer(user, "sip show users");
20167  }
20168  ao2_iterator_destroy(&user_iter);
20169 
20170  if (havepattern)
20171  regfree(&regexbuf);
20172 
20173  return CLI_SUCCESS;
20174 #undef FORMAT
20175 }
static char user[512]
#define FALSE
Definition: app_minivm.c:521
#define ast_test_flag(p, flag)
Definition: utils.h:63
const ast_string_field accountcode
Definition: sip.h:1306
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define SIP_NAT_FORCE_RPORT
Definition: sip.h:283
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_unlock(a)
Definition: astobj2.h:730
enum sip_peer_type type
Definition: sip.h:1375
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
char name[80]
Definition: sip.h:1274
struct ast_acl_list * acl
Definition: sip.h:1363
const int fd
Definition: cli.h:159
#define ao2_lock(a)
Definition: astobj2.h:718
int ast_acl_list_is_empty(struct ast_acl_list *acl_list)
Determines if an ACL is empty or if it contains entries.
Definition: acl.c:541
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define ao2_t_iterator_next(iter, tag)
Definition: astobj2.h:1931
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
char * command
Definition: cli.h:186
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
struct ast_flags flags[3]
Definition: sip.h:1335
#define TRUE
Definition: app_minivm.c:518
const ast_string_field secret
Definition: sip.h:1306
#define FORMAT
Definition: chan_sip.c:22152
#define AST_CLI_YESNO(x)
Return Yes or No depending on the argument.
Definition: cli.h:71
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
const ast_string_field context
Definition: sip.h:1306

◆ sip_sipredirect()

static int sip_sipredirect ( struct sip_pvt p,
const char *  dest 
)
static

Transfer call before connect with a 302 redirect.

Note
Called by the transfer() dialplan application through the sip_transfer() pbx interface function if the call is in ringing state
Todo:
Fix this function so that we wait for reply to the REFER and react to errors, denials or other issues the other end might have.

Definition at line 34178 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, sip_pvt::initreq, LOG_ERROR, sip_pvt::owner, sip_alreadygone(), sip_get_header(), sip_scheddestroy(), SIP_TRANS_TIMEOUT, strcasestr(), strsep(), and transmit_response_reliable().

Referenced by sip_transfer().

34179 {
34180  char *cdest;
34181  char *extension, *domain;
34182 
34183  cdest = ast_strdupa(dest);
34184 
34185  extension = strsep(&cdest, "@");
34186  domain = cdest;
34187  if (ast_strlen_zero(extension)) {
34188  ast_log(LOG_ERROR, "Missing mandatory argument: extension\n");
34189  return 0;
34190  }
34191 
34192  /* we'll issue the redirect message here */
34193  if (!domain) {
34194  char *local_to_header;
34195  char to_header[256];
34196 
34197  ast_copy_string(to_header, sip_get_header(&p->initreq, "To"), sizeof(to_header));
34198  if (ast_strlen_zero(to_header)) {
34199  ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n");
34200  return 0;
34201  }
34202  if (((local_to_header = strcasestr(to_header, "sip:")) || (local_to_header = strcasestr(to_header, "sips:")))
34203  && (local_to_header = strchr(local_to_header, '@'))) {
34204  char ldomain[256];
34205 
34206  memset(ldomain, 0, sizeof(ldomain));
34207  local_to_header++;
34208  /* Will copy no more than 255 chars plus null terminator. */
34209  sscanf(local_to_header, "%255[^<>; ]", ldomain);
34210  if (ast_strlen_zero(ldomain)) {
34211  ast_log(LOG_ERROR, "Can't find the host address\n");
34212  return 0;
34213  }
34214  domain = ast_strdupa(ldomain);
34215  }
34216  }
34217 
34218  ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s>", extension, domain);
34219  transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq);
34220 
34221  sip_scheddestroy(p, SIP_TRANS_TIMEOUT); /* Make sure we stop send this reply. */
34222  sip_alreadygone(p);
34223 
34224  if (p->owner) {
34226  ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
34227  }
34228  /* hangup here */
34229  return 0;
34230 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
static void sip_alreadygone(struct sip_pvt *dialog)
Encapsulate setting of SIP_ALREADYGONE to be able to trace it with debugging.
Definition: chan_sip.c:3460
ast_control_transfer
Domain data structure.
Definition: sip.h:888
#define ast_strlen_zero(foo)
Definition: strings.h:52
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.
Definition: chan_sip.c:12688
#define ast_log
Definition: astobj2.c:42
struct sip_request initreq
Definition: sip.h:1151
structure to hold extensions
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define LOG_ERROR
Definition: logger.h:285
char * strcasestr(const char *, const char *)
struct ast_channel * owner
Definition: sip.h:1138
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
Definition: stringfields.h:550
char * strsep(char **str, const char *delims)
#define SIP_TRANS_TIMEOUT
Definition: sip.h:102
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen)
Queue a control frame with payload.
Definition: channel.c:1238
void sip_scheddestroy(struct sip_pvt *p, int ms)
Schedule destruction of SIP dialog.
Definition: chan_sip.c:4549

◆ sip_st_alloc()

static struct sip_st_dlg * sip_st_alloc ( struct sip_pvt *const  p)
static

Allocate Session-Timers struct w/in dialog.

Definition at line 8914 of file chan_sip.c.

References ast_calloc, ast_log, LOG_ERROR, NULL, sip_st_dlg::st_schedid, and sip_pvt::stimer.

Referenced by handle_request_invite_st(), and st_get_mode().

8915 {
8916  struct sip_st_dlg *stp;
8917 
8918  if (p->stimer) {
8919  ast_log(LOG_ERROR, "Session-Timer struct already allocated\n");
8920  return p->stimer;
8921  }
8922 
8923  if (!(stp = ast_calloc(1, sizeof(struct sip_st_dlg)))) {
8924  return NULL;
8925  }
8926  stp->st_schedid = -1; /* Session-Timers ast_sched scheduler id */
8927 
8928  p->stimer = stp;
8929 
8930  return p->stimer;
8931 }
int st_schedid
Definition: sip.h:963
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
struct sip_st_dlg * stimer
Definition: sip.h:1184
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
Structure that encapsulates all attributes related to running SIP Session-Timers feature on a per dia...
Definition: sip.h:959

◆ sip_standard_port()

static int sip_standard_port ( enum ast_transport  type,
int  port 
)
static

Returns the port to use for this socket.

Parameters
typeThe type of transport used
portPort we are checking to see if it's the standard port.
Note
port is expected in host byte order

Definition at line 29515 of file chan_sip.c.

References AST_TRANSPORT_TLS, STANDARD_SIP_PORT, and STANDARD_TLS_PORT.

Referenced by initreqprep(), and transmit_notify_with_mwi().

29516 {
29517  if (type & AST_TRANSPORT_TLS)
29518  return port == STANDARD_TLS_PORT;
29519  else
29520  return port == STANDARD_SIP_PORT;
29521 }
static const char type[]
Definition: chan_ooh323.c:109
#define STANDARD_TLS_PORT
Standard SIP TLS port from RFC 3261. DO NOT CHANGE THIS.
Definition: sip.h:178
#define STANDARD_SIP_PORT
Standard SIP unsecure port for UDP and TCP from RFC 3261. DO NOT CHANGE THIS.
Definition: sip.h:176

◆ sip_subscribe_mwi()

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

References ao2_t_alloc, ao2_t_link, ao2_t_ref, ast_copy_string(), ast_log, ast_string_field_init, ast_string_field_set, ast_strlen_zero, AST_TRANSPORT_UDP, buf, hostname, LOG_WARNING, mailbox, NULL, sip_subscription_mwi::portno, sip_subscription_mwi::resub, sip_subscribe_mwi_destroy(), and sip_subscription_mwi::transport.

Referenced by AST_TEST_DEFINE(), and reload_config().

9721 {
9722  struct sip_subscription_mwi *mwi;
9723  int portnum = 0;
9725  char buf[256] = "";
9726  char *username = NULL, *hostname = NULL, *secret = NULL, *authuser = NULL, *porta = NULL, *mailbox = NULL;
9727 
9728  if (!value) {
9729  return -1;
9730  }
9731 
9732  ast_copy_string(buf, value, sizeof(buf));
9733 
9734  username = buf;
9735 
9736  if ((hostname = strrchr(buf, '@'))) {
9737  *hostname++ = '\0';
9738  } else {
9739  return -1;
9740  }
9741 
9742  if ((secret = strchr(username, ':'))) {
9743  *secret++ = '\0';
9744  if ((authuser = strchr(secret, ':'))) {
9745  *authuser++ = '\0';
9746  }
9747  }
9748 
9749  if ((mailbox = strchr(hostname, '/'))) {
9750  *mailbox++ = '\0';
9751  }
9752 
9753  if (ast_strlen_zero(username) || ast_strlen_zero(hostname) || ast_strlen_zero(mailbox)) {
9754  ast_log(LOG_WARNING, "Format for MWI subscription is user[:secret[:authuser]]@host[:port]/mailbox at line %d\n", lineno);
9755  return -1;
9756  }
9757 
9758  if ((porta = strchr(hostname, ':'))) {
9759  *porta++ = '\0';
9760  if (!(portnum = atoi(porta))) {
9761  ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
9762  return -1;
9763  }
9764  }
9765 
9766  if (!(mwi = ao2_t_alloc(sizeof(*mwi), sip_subscribe_mwi_destroy, "allocate an mwi struct"))) {
9767  return -1;
9768  }
9769 
9770  mwi->resub = -1;
9771 
9772  if (ast_string_field_init(mwi, 256)) {
9773  ao2_t_ref(mwi, -1, "failed to string_field_init, drop mwi");
9774  return -1;
9775  }
9776 
9777  ast_string_field_set(mwi, username, username);
9778  if (secret) {
9779  ast_string_field_set(mwi, secret, secret);
9780  }
9781  if (authuser) {
9782  ast_string_field_set(mwi, authuser, authuser);
9783  }
9784  ast_string_field_set(mwi, hostname, hostname);
9785  ast_string_field_set(mwi, mailbox, mailbox);
9786  mwi->portno = portnum;
9787  mwi->transport = transport;
9788 
9789  ao2_t_link(subscription_mwi_list, mwi, "link new mwi object");
9790  ao2_t_ref(mwi, -1, "unref to match ao2_t_alloc");
9791 
9792  return 0;
9793 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
#define ao2_t_alloc(data_size, destructor_fn, debug_msg)
Definition: astobj2.h:409
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
ast_transport
Definition: netsock2.h:59
#define LOG_WARNING
Definition: logger.h:274
#define ao2_t_link(container, obj, tag)
Add an object to a container.
Definition: astobj2.h:1547
#define NULL
Definition: resample.c:96
int value
Definition: syslog.c:37
#define ast_strlen_zero(foo)
Definition: strings.h:52
const ast_string_field username
Definition: sip.h:1461
static char mailbox[AST_MAX_MAILBOX_UNIQUEID]
Definition: chan_mgcp.c:204
#define ast_log
Definition: astobj2.c:42
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:353
static void sip_subscribe_mwi_destroy(void *data)
Destroy MWI subscription object.
Definition: chan_sip.c:6650
enum ast_transport transport
Definition: sip.h:1462
const ast_string_field authuser
Definition: sip.h:1461
Definition of an MWI subscription to another server.
Definition: sip.h:1454
static struct ao2_container * subscription_mwi_list
The MWI subscription list.
Definition: chan_sip.c:1064
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
const ast_string_field secret
Definition: sip.h:1461
static struct ast_str * hostname
Definition: cdr_mysql.c:77
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ sip_subscribe_mwi_destroy()

static void sip_subscribe_mwi_destroy ( void *  data)
static

Destroy MWI subscription object.

Definition at line 6650 of file chan_sip.c.

References ast_string_field_free_memory, sip_subscription_mwi::call, dialog_unref, sip_pvt::mwi, and NULL.

Referenced by sip_subscribe_mwi().

6651 {
6652  struct sip_subscription_mwi *mwi = data;
6653 
6654  if (mwi->call) {
6655  mwi->call->mwi = NULL;
6656  mwi->call = dialog_unref(mwi->call, "sip_subscription_mwi destruction");
6657  }
6658 
6660 }
#define NULL
Definition: resample.c:96
struct sip_subscription_mwi * mwi
Definition: sip.h:1192
struct sip_pvt * call
Definition: sip.h:1466
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
Definition of an MWI subscription to another server.
Definition: sip.h:1454
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:368

◆ sip_subscribe_mwi_do()

static int sip_subscribe_mwi_do ( const void *  data)
static

Send a subscription or resubscription for MWI.

Note
Run by the sched thread.

Definition at line 14923 of file chan_sip.c.

References __sip_subscribe_mwi_do(), ao2_t_ref, and sip_subscription_mwi::resub.

Referenced by __start_mwi_subscription().

14924 {
14925  struct sip_subscription_mwi *mwi = (struct sip_subscription_mwi *) data;
14926 
14927  mwi->resub = -1;
14929  ao2_t_ref(mwi, -1, "Scheduled mwi resub complete");
14930 
14931  return 0;
14932 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
static int __sip_subscribe_mwi_do(struct sip_subscription_mwi *mwi)
Actually setup an MWI subscription or resubscribe.
Definition: chan_sip.c:15075
Definition of an MWI subscription to another server.
Definition: sip.h:1454

◆ sip_t38_abort()

static int sip_t38_abort ( const void *  data)
static

Called to deny a T38 reinvite if the core does not respond to our request.

Note
Run by the sched thread.

Definition at line 26075 of file chan_sip.c.

References ast_channel_unlock, ast_channel_unref, change_t38_state(), dialog_unref, sip_pvt::initreq, sip_pvt_lock_full(), sip_pvt_unlock, t38properties::state, sip_pvt::t38, T38_PEER_REINVITE, T38_REJECTED, sip_pvt::t38id, and transmit_response_reliable().

Referenced by __start_t38_abort_timer().

26076 {
26077  struct sip_pvt *pvt = (struct sip_pvt *) data;
26078  struct ast_channel *owner;
26079 
26080  owner = sip_pvt_lock_full(pvt);
26081  pvt->t38id = -1;
26082 
26083  /*
26084  * An application may have taken ownership of the T.38 negotiation
26085  * on the channel while we were waiting to grab the lock. If it
26086  * did, the T.38 state will have been changed. This is our
26087  * indication that we do *not* want to abort the negotiation
26088  * process.
26089  */
26090  if (pvt->t38.state == T38_PEER_REINVITE) {
26091  /* Still waiting for a response on timeout so reject the offer. */
26093  transmit_response_reliable(pvt, "488 Not acceptable here", &pvt->initreq);
26094  }
26095 
26096  if (owner) {
26097  ast_channel_unlock(owner);
26098  ast_channel_unref(owner);
26099  }
26100  sip_pvt_unlock(pvt);
26101  dialog_unref(pvt, "t38id complete");
26102  return 0;
26103 }
Main Channel structure associated with a channel.
enum t38state state
Definition: sip.h:917
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
struct t38properties t38
Definition: sip.h:1113
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.
Definition: chan_sip.c:12688
struct sip_request initreq
Definition: sip.h:1151
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
static struct ast_channel * sip_pvt_lock_full(struct sip_pvt *pvt)
Definition: chan_sip.c:9400
#define ast_channel_unlock(chan)
Definition: channel.h:2946
static void change_t38_state(struct sip_pvt *p, int state)
Change the T38 state on a SIP dialog.
Definition: chan_sip.c:5889
int t38id
Definition: sip.h:1159

◆ sip_tcp_locate()

static struct ast_tcptls_session_instance* sip_tcp_locate ( struct ast_sockaddr s)
static

Find thread for TCP/TLS session (based on IP/Port.

Note
This function returns an astobj2 reference

Definition at line 29540 of file chan_sip.c.

References ao2_callback, ao2_ref, ao2_t_ref, NULL, sip_threadinfo::tcptls_session, and threadinfo_locate_cb().

Referenced by sip_prepare_socket().

29541 {
29542  struct sip_threadinfo *th;
29543  struct ast_tcptls_session_instance *tcptls_instance = NULL;
29544 
29545  if ((th = ao2_callback(threadt, 0, threadinfo_locate_cb, s))) {
29546  tcptls_instance = (ao2_ref(th->tcptls_session, +1), th->tcptls_session);
29547  ao2_t_ref(th, -1, "decrement ref from callback");
29548  }
29549 
29550  return tcptls_instance;
29551 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
static struct ao2_container * threadt
The table of TCP threads.
Definition: chan_sip.c:1049
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
#define NULL
Definition: resample.c:96
Definition of a thread that handles a socket.
Definition: sip.h:1441
static int threadinfo_locate_cb(void *obj, void *arg, int flags)
Definition: chan_sip.c:29523
#define ao2_ref(o, delta)
Definition: astobj2.h:464
describes a server instance
Definition: tcptls.h:149
struct ast_tcptls_session_instance * tcptls_session
Definition: sip.h:1446

◆ sip_tcp_worker_fn()

static void * sip_tcp_worker_fn ( void *  data)
static

SIP TCP connection handler.

Definition at line 2670 of file chan_sip.c.

References _sip_tcp_helper_thread().

Referenced by sip_prepare_socket().

2671 {
2672  struct ast_tcptls_session_instance *tcptls_session = data;
2673 
2674  return _sip_tcp_helper_thread(tcptls_session);
2675 }
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 requ...
Definition: chan_sip.c:2985
describes a server instance
Definition: tcptls.h:149

◆ sip_tcptls_client_args_destructor()

static void sip_tcptls_client_args_destructor ( void *  obj)
static

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

2546 {
2547  struct ast_tcptls_session_args *args = obj;
2548  if (args->tls_cfg) {
2549  ast_free(args->tls_cfg->certfile);
2550  ast_free(args->tls_cfg->pvtfile);
2551  ast_free(args->tls_cfg->cipher);
2552  ast_free(args->tls_cfg->cafile);
2553  ast_free(args->tls_cfg->capath);
2554 
2555  ast_ssl_teardown(args->tls_cfg);
2556  }
2557  ast_free(args->tls_cfg);
2558  ast_free((char *) args->name);
2559 }
char * pvtfile
Definition: tcptls.h:90
void ast_ssl_teardown(struct ast_tls_config *cfg)
free resources used by an SSL server
Definition: tcptls.c:575
arguments for the accepting thread
Definition: tcptls.h:129
const char * args
char * cafile
Definition: tcptls.h:92
#define ast_free(a)
Definition: astmm.h:182
char * certfile
Definition: tcptls.h:89
const char * name
Definition: tcptls.h:142
char * capath
Definition: tcptls.h:93
struct ast_tls_config * tls_cfg
Definition: tcptls.h:134
char * cipher
Definition: tcptls.h:91

◆ sip_tcptls_read()

static int sip_tcptls_read ( struct sip_request req,
struct ast_tcptls_session_instance tcptls_session,
int  authenticated,
time_t  start 
)
static

Read SIP request or response from a TCP/TLS connection.

Parameters
reqThe request structure to be filled in
tcptls_sessionThe TCP/TLS connection from which to read
Return values
-1Failed to read data
0Successfully read data

Definition at line 2918 of file chan_sip.c.

References ast_debug, ast_iostream_get_fd(), ast_iostream_read(), ast_log, ast_sockaddr_stringify(), ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_strlen(), ast_wait_for_input(), check_message_integrity(), ast_tcptls_session_instance::client, sip_request::data, errno, LOG_WARNING, MESSAGE_FRAGMENT, ast_tcptls_session_instance::overflow_buf, ast_tcptls_session_instance::remote_address, sip_check_authtimeout(), SIP_MAX_PACKET_SIZE, ast_tcptls_session_instance::stream, and timeout.

Referenced by _sip_tcp_helper_thread().

2920 {
2922 
2923  while (message_integrity == MESSAGE_FRAGMENT) {
2924  size_t datalen;
2925 
2926  if (ast_str_strlen(tcptls_session->overflow_buf) == 0) {
2927  char readbuf[4097];
2928  int timeout;
2929  int res;
2930  if (!tcptls_session->client && !authenticated) {
2931  if ((timeout = sip_check_authtimeout(start)) < 0) {
2932  return -1;
2933  }
2934 
2935  if (timeout == 0) {
2936  ast_debug(2, "SIP TCP/TLS server timed out\n");
2937  return -1;
2938  }
2939  } else {
2940  timeout = -1;
2941  }
2942  res = ast_wait_for_input(ast_iostream_get_fd(tcptls_session->stream), timeout);
2943  if (res < 0) {
2944  ast_debug(2, "SIP TCP/TLS server :: ast_wait_for_input returned %d\n", res);
2945  return -1;
2946  } else if (res == 0) {
2947  ast_debug(2, "SIP TCP/TLS server timed out\n");
2948  return -1;
2949  }
2950 
2951  res = ast_iostream_read(tcptls_session->stream, readbuf, sizeof(readbuf) - 1);
2952  if (res < 0) {
2953  if (errno == EAGAIN || errno == EINTR) {
2954  continue;
2955  }
2956  ast_debug(2, "SIP TCP/TLS server error when receiving data\n");
2957  return -1;
2958  } else if (res == 0) {
2959  ast_debug(2, "SIP TCP/TLS server has shut down\n");
2960  return -1;
2961  }
2962  readbuf[res] = '\0';
2963  ast_str_append(&req->data, 0, "%s", readbuf);
2964  } else {
2965  ast_str_append(&req->data, 0, "%s", ast_str_buffer(tcptls_session->overflow_buf));
2966  ast_str_reset(tcptls_session->overflow_buf);
2967  }
2968 
2969  datalen = ast_str_strlen(req->data);
2970  if (datalen > SIP_MAX_PACKET_SIZE) {
2971  ast_log(LOG_WARNING, "Rejecting TCP/TLS packet from '%s' because way too large: %zu\n",
2972  ast_sockaddr_stringify(&tcptls_session->remote_address), datalen);
2973  return -1;
2974  }
2975 
2976  message_integrity = check_message_integrity(&req->data, &tcptls_session->overflow_buf);
2977  }
2978 
2979  return 0;
2980 }
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.
Definition: chan_sip.c:2849
struct ast_str * overflow_buf
Definition: tcptls.h:158
static int sip_check_authtimeout(time_t start)
Check if the authtimeout has expired.
Definition: chan_sip.c:2740
#define LOG_WARNING
Definition: logger.h:274
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
static int timeout
Definition: cdr_mysql.c:86
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
int ast_iostream_get_fd(struct ast_iostream *stream)
Get an iostream&#39;s file descriptor.
Definition: iostream.c:84
ssize_t ast_iostream_read(struct ast_iostream *stream, void *buffer, size_t count)
Read data from an iostream.
Definition: iostream.c:273
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
struct ast_str * data
Definition: sip.h:843
int errno
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
message_integrity
Indication of a TCP message&#39;s integrity.
Definition: chan_sip.c:2761
struct ast_iostream * stream
Definition: tcptls.h:160
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:653
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
int ast_wait_for_input(int fd, int ms)
Definition: main/utils.c:1519
struct ast_sockaddr remote_address
Definition: tcptls.h:151
#define SIP_MAX_PACKET_SIZE
Definition: sip.h:113

◆ sip_tcptls_write()

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

References sip_threadinfo::alert_pipe, ao2_alloc, ao2_lock, ao2_t_find, ao2_t_ref, ao2_unlock, AST_LIST_INSERT_TAIL, ast_log, ast_str_create, ast_str_set(), tcptls_packet::data, errno, len(), tcptls_packet::len, LOG_ERROR, NULL, OBJ_POINTER, sip_threadinfo::packet_q, ast_tcptls_session_instance::stream, TCPTLS_ALERT_DATA, tcptls_packet_destructor(), tmp(), and XMIT_ERROR.

Referenced by __sip_xmit(), and sip_send_keepalive().

2609 {
2610  int res = len;
2611  struct sip_threadinfo *th = NULL;
2612  struct tcptls_packet *packet = NULL;
2613  struct sip_threadinfo tmp = {
2614  .tcptls_session = tcptls_session,
2615  };
2616  enum sip_tcptls_alert alert = TCPTLS_ALERT_DATA;
2617 
2618  if (!tcptls_session) {
2619  return XMIT_ERROR;
2620  }
2621 
2622  ao2_lock(tcptls_session);
2623 
2624  if (!tcptls_session->stream ||
2625  !(packet = ao2_alloc(sizeof(*packet), tcptls_packet_destructor)) ||
2626  !(packet->data = ast_str_create(len))) {
2627  goto tcptls_write_setup_error;
2628  }
2629 
2630  if (!(th = ao2_t_find(threadt, &tmp, OBJ_POINTER, "ao2_find, getting sip_threadinfo in tcp helper thread"))) {
2631  ast_log(LOG_ERROR, "Unable to locate tcptls_session helper thread.\n");
2632  goto tcptls_write_setup_error;
2633  }
2634 
2635  /* goto tcptls_write_error should _NOT_ be used beyond this point */
2636  ast_str_set(&packet->data, 0, "%s", (char *) buf);
2637  packet->len = len;
2638 
2639  /* alert tcptls thread handler that there is a packet to be sent.
2640  * must lock the thread info object to guarantee control of the
2641  * packet queue */
2642  ao2_lock(th);
2643  if (write(th->alert_pipe[1], &alert, sizeof(alert)) == -1) {
2644  ast_log(LOG_ERROR, "write() to alert pipe failed: %s\n", strerror(errno));
2645  ao2_t_ref(packet, -1, "could not write to alert pipe, remove packet");
2646  packet = NULL;
2647  res = XMIT_ERROR;
2648  } else { /* it is safe to queue the frame after issuing the alert when we hold the threadinfo lock */
2649  AST_LIST_INSERT_TAIL(&th->packet_q, packet, entry);
2650  }
2651  ao2_unlock(th);
2652 
2653  ao2_unlock(tcptls_session);
2654  ao2_t_ref(th, -1, "In sip_tcptls_write, unref threadinfo object after finding it");
2655  return res;
2656 
2657 tcptls_write_setup_error:
2658  if (th) {
2659  ao2_t_ref(th, -1, "In sip_tcptls_write, unref threadinfo obj, could not create packet");
2660  }
2661  if (packet) {
2662  ao2_t_ref(packet, -1, "could not allocate packet's data");
2663  }
2664  ao2_unlock(tcptls_session);
2665 
2666  return XMIT_ERROR;
2667 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
static struct ao2_container * threadt
The table of TCP threads.
Definition: chan_sip.c:1049
struct ast_str * data
Definition: sip.h:1437
There is new data to be sent out.
Definition: sip.h:698
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define OBJ_POINTER
Definition: astobj2.h:1154
static int tmp()
Definition: bt_open.c:389
static void tcptls_packet_destructor(void *obj)
Definition: chan_sip.c:2538
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
Definition of a thread that handles a socket.
Definition: sip.h:1441
#define ast_log
Definition: astobj2.c:42
int alert_pipe[2]
Definition: sip.h:1444
#define ao2_lock(a)
Definition: astobj2.h:718
#define XMIT_ERROR
Definition: sip.h:58
#define LOG_ERROR
Definition: logger.h:285
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int errno
struct sip_threadinfo::@178 packet_q
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
struct ast_iostream * stream
Definition: tcptls.h:160
sip_tcptls_alert
Definition: sip.h:697
#define ao2_t_find(container, arg, flags, tag)
Definition: astobj2.h:1754
size_t len
Definition: sip.h:1438
Definition: search.h:40
struct ast_tcptls_session_instance * tcptls_session
Definition: sip.h:1446
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ sip_threadinfo_create()

static struct sip_threadinfo* sip_threadinfo_create ( struct ast_tcptls_session_instance tcptls_session,
int  transport 
)
static

creates a sip_threadinfo object and links it into the threadt table.

Definition at line 2584 of file chan_sip.c.

References sip_threadinfo::alert_pipe, ao2_alloc, ao2_t_link, ao2_t_ref, ast_iostream_get_ssl(), ast_log, AST_TRANSPORT_TCP, AST_TRANSPORT_TLS, errno, LOG_ERROR, NULL, sip_threadinfo_destructor(), ast_tcptls_session_instance::stream, sip_threadinfo::tcptls_session, and sip_threadinfo::type.

Referenced by _sip_tcp_helper_thread(), and sip_prepare_socket().

2585 {
2586  struct sip_threadinfo *th;
2587 
2588  if (!tcptls_session || !(th = ao2_alloc(sizeof(*th), sip_threadinfo_destructor))) {
2589  return NULL;
2590  }
2591 
2592  th->alert_pipe[0] = th->alert_pipe[1] = -1;
2593 
2594  if (pipe(th->alert_pipe) == -1) {
2595  ao2_t_ref(th, -1, "Failed to open alert pipe on sip_threadinfo");
2596  ast_log(LOG_ERROR, "Could not create sip alert pipe in tcptls thread, error %s\n", strerror(errno));
2597  return NULL;
2598  }
2599  ao2_t_ref(tcptls_session, +1, "tcptls_session ref for sip_threadinfo object");
2601  th->type = transport ? transport : (ast_iostream_get_ssl(tcptls_session->stream) ? AST_TRANSPORT_TLS: AST_TRANSPORT_TCP);
2602  ao2_t_link(threadt, th, "Adding new tcptls helper thread");
2603  ao2_t_ref(th, -1, "Decrementing threadinfo ref from alloc, only table ref remains");
2604  return th;
2605 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
static struct ao2_container * threadt
The table of TCP threads.
Definition: chan_sip.c:1049
static void sip_threadinfo_destructor(void *obj)
Definition: chan_sip.c:2561
#define ao2_t_link(container, obj, tag)
Add an object to a container.
Definition: astobj2.h:1547
#define NULL
Definition: resample.c:96
SSL * ast_iostream_get_ssl(struct ast_iostream *stream)
Get a pointer to an iostream&#39;s OpenSSL SSL structure.
Definition: iostream.c:108
Definition of a thread that handles a socket.
Definition: sip.h:1441
#define ast_log
Definition: astobj2.c:42
int alert_pipe[2]
Definition: sip.h:1444
#define LOG_ERROR
Definition: logger.h:285
int errno
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
struct ast_iostream * stream
Definition: tcptls.h:160
enum ast_transport type
Definition: sip.h:1447
struct ast_tcptls_session_instance * tcptls_session
Definition: sip.h:1446

◆ sip_threadinfo_destructor()

static void sip_threadinfo_destructor ( void *  obj)
static

Definition at line 2561 of file chan_sip.c.

References sip_threadinfo::alert_pipe, ao2_t_ref, AST_LIST_REMOVE_HEAD, sip_threadinfo::packet_q, and sip_threadinfo::tcptls_session.

Referenced by sip_threadinfo_create().

2562 {
2563  struct sip_threadinfo *th = obj;
2564  struct tcptls_packet *packet;
2565 
2566  if (th->alert_pipe[0] > -1) {
2567  close(th->alert_pipe[0]);
2568  }
2569  if (th->alert_pipe[1] > -1) {
2570  close(th->alert_pipe[1]);
2571  }
2572  th->alert_pipe[0] = th->alert_pipe[1] = -1;
2573 
2574  while ((packet = AST_LIST_REMOVE_HEAD(&th->packet_q, entry))) {
2575  ao2_t_ref(packet, -1, "thread destruction, removing packet from frame queue");
2576  }
2577 
2578  if (th->tcptls_session) {
2579  ao2_t_ref(th->tcptls_session, -1, "remove tcptls_session for sip_threadinfo object");
2580  }
2581 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
Definition of a thread that handles a socket.
Definition: sip.h:1441
int alert_pipe[2]
Definition: sip.h:1444
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
struct sip_threadinfo::@178 packet_q
Definition: search.h:40
struct ast_tcptls_session_instance * tcptls_session
Definition: sip.h:1446

◆ sip_transfer()

static int sip_transfer ( struct ast_channel ast,
const char *  dest 
)
static

Transfer SIP call.

Definition at line 7730 of file chan_sip.c.

References ast_channel_name(), ast_channel_tech_pvt(), ast_debug, AST_STATE_RING, NULL, sip_pvt_lock, sip_pvt_unlock, sip_sipredirect(), and transmit_refer().

7731 {
7732  struct sip_pvt *p = ast_channel_tech_pvt(ast);
7733  int res;
7734 
7735  if (!p) {
7736  ast_debug(1, "Asked to transfer channel %s with no pvt; ignoring\n",
7737  ast_channel_name(ast));
7738  return -1;
7739  }
7740 
7741  if (dest == NULL) /* functions below do not take a NULL */
7742  dest = "";
7743  sip_pvt_lock(p);
7744  if (ast_channel_state(ast) == AST_STATE_RING)
7745  res = sip_sipredirect(p, dest);
7746  else
7747  res = transmit_refer(p, dest);
7748  sip_pvt_unlock(p);
7749  return res;
7750 }
static int sip_sipredirect(struct sip_pvt *p, const char *dest)
Transfer call before connect with a 302 redirect.
Definition: chan_sip.c:34178
static int transmit_refer(struct sip_pvt *p, const char *dest)
Transmit SIP REFER message (initiated by the transfer() dialplan application.
Definition: chan_sip.c:16402
void * ast_channel_tech_pvt(const struct ast_channel *chan)
ast_channel_state
ast_channel states
Definition: channelstate.h:35
#define NULL
Definition: resample.c:96
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
const char * ast_channel_name(const struct ast_channel *chan)

◆ sip_unregister()

static char * sip_unregister ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Unregister (force expiration) a SIP peer in the registry via CLI.

Note
This function does not tell the SIP device what's going on, so use it with great care.

Definition at line 21705 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(), sip_peer::expire, expire_register(), ast_cli_args::fd, FINDPEERS, ast_cli_args::line, ast_cli_args::n, NULL, ast_cli_args::pos, sip_find_peer(), sip_ref_peer, sip_unref_peer, TRUE, ast_cli_entry::usage, and ast_cli_args::word.

21706 {
21707  struct sip_peer *peer;
21708  int load_realtime = 0;
21709 
21710  switch (cmd) {
21711  case CLI_INIT:
21712  e->command = "sip unregister";
21713  e->usage =
21714  "Usage: sip unregister <peer>\n"
21715  " Unregister (force expiration) a SIP peer from the registry\n";
21716  return NULL;
21717  case CLI_GENERATE:
21718  return complete_sip_unregister(a->line, a->word, a->pos, a->n);
21719  }
21720 
21721  if (a->argc != 3)
21722  return CLI_SHOWUSAGE;
21723 
21724  if ((peer = sip_find_peer(a->argv[2], NULL, load_realtime, FINDPEERS, TRUE, 0))) {
21725  if (peer->expire > -1) {
21727  sip_unref_peer(peer, "remove register expire ref"));
21728  expire_register(sip_ref_peer(peer, "ref for expire_register"));
21729  ast_cli(a->fd, "Unregistered peer \'%s\'\n\n", a->argv[2]);
21730  } else {
21731  ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
21732  }
21733  sip_unref_peer(peer, "sip_unregister: sip_unref_peer via sip_unregister: done with peer from sip_find_peer call");
21734  } else {
21735  ast_cli(a->fd, "Peer unknown: \'%s\'. Not unregistered.\n", a->argv[2]);
21736  }
21737 
21738  return CLI_SUCCESS;
21739 }
static int expire_register(const void *data)
Expire registration of SIP peer.
Definition: chan_sip.c:16646
struct sip_peer * sip_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.
Definition: chan_sip.c:5851
const int argc
Definition: cli.h:160
static char * complete_sip_unregister(const char *line, const char *word, int pos, int state)
Support routine for &#39;sip unregister&#39; CLI.
Definition: chan_sip.c:22350
Definition: sched.c:76
Definition: cli.h:152
#define AST_SCHED_DEL_UNREF(sched, id, refcall)
schedule task to get deleted and call unref function
Definition: sched.h:80
#define NULL
Definition: resample.c:96
#define sip_ref_peer(peer, tag)
Definition: sip.h:1894
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const char * line
Definition: cli.h:162
const int fd
Definition: cli.h:159
const int n
Definition: cli.h:165
const char *const * argv
Definition: cli.h:161
int expire
Definition: sip.h:1341
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
char * command
Definition: cli.h:186
#define FINDPEERS
Definition: sip.h:53
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
const char * word
Definition: cli.h:163
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
const int pos
Definition: cli.h:164
#define TRUE
Definition: app_minivm.c:518

◆ sip_unregister_tests()

static void sip_unregister_tests ( void  )
static

SIP test registration.

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

34734 {
34738 }
void sip_dialplan_function_unregister_tests(void)
SIP test registration.
void sip_config_parser_unregister_tests(void)
SIP test registration.
void sip_request_parser_unregister_tests(void)
unregister request parsing tests

◆ sip_websocket_callback()

static void sip_websocket_callback ( struct ast_websocket session,
struct ast_variable parameters,
struct ast_variable headers 
)
static

SIP WebSocket connection handler.

Definition at line 2678 of file chan_sip.c.

References AST_DYNSTR_BUILD_FAILED, ast_str_create, ast_str_set(), AST_TRANSPORT_WS, AST_TRANSPORT_WSS, ast_wait_for_input(), ast_websocket_fd(), ast_websocket_is_secure(), AST_WEBSOCKET_OPCODE_BINARY, AST_WEBSOCKET_OPCODE_CLOSE, AST_WEBSOCKET_OPCODE_TEXT, ast_websocket_read(), ast_websocket_remote_address(), ast_websocket_set_nonblock(), ast_websocket_set_timeout(), ast_websocket_unref(), sip_request::data, deinit_req(), end, sip_socket::fd, handle_request_do(), session, set_socket_transport(), sip_cfg, sip_request::socket, sip_settings::websocket_write_timeout, and sip_socket::ws_session.

Referenced by load_module(), reload_config(), and unload_module().

2679 {
2680  int res;
2681 
2682  if (ast_websocket_set_nonblock(session)) {
2683  goto end;
2684  }
2685 
2687  goto end;
2688  }
2689 
2690  while ((res = ast_wait_for_input(ast_websocket_fd(session), -1)) > 0) {
2691  char *payload;
2692  uint64_t payload_len;
2693  enum ast_websocket_opcode opcode;
2694  int fragmented;
2695 
2696  if (ast_websocket_read(session, &payload, &payload_len, &opcode, &fragmented)) {
2697  /* We err on the side of caution and terminate the session if any error occurs */
2698  break;
2699  }
2700 
2701  if (opcode == AST_WEBSOCKET_OPCODE_TEXT || opcode == AST_WEBSOCKET_OPCODE_BINARY) {
2702  struct sip_request req = { 0, };
2703  char data[payload_len + 1];
2704 
2705  if (!(req.data = ast_str_create(payload_len + 1))) {
2706  goto end;
2707  }
2708 
2709  strncpy(data, payload, payload_len);
2710  data[payload_len] = '\0';
2711 
2712  if (ast_str_set(&req.data, -1, "%s", data) == AST_DYNSTR_BUILD_FAILED) {
2713  deinit_req(&req);
2714  goto end;
2715  }
2716 
2717  req.socket.fd = ast_websocket_fd(session);
2719  req.socket.ws_session = session;
2720 
2722  deinit_req(&req);
2723 
2724  } else if (opcode == AST_WEBSOCKET_OPCODE_CLOSE) {
2725  break;
2726  }
2727  }
2728 
2729 end:
2730  ast_websocket_unref(session);
2731 }
int AST_OPTIONAL_API_NAME() ast_websocket_read(struct ast_websocket *session, char **payload, uint64_t *payload_len, enum ast_websocket_opcode *opcode, int *fragmented)
int AST_OPTIONAL_API_NAME() ast_websocket_is_secure(struct ast_websocket *session)
char * end
Definition: eagi_proxy.c:73
int fd
Definition: sip.h:799
int AST_OPTIONAL_API_NAME() ast_websocket_fd(struct ast_websocket *session)
static void deinit_req(struct sip_request *req)
Deinitialize SIP response/request.
Definition: chan_sip.c:12195
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
struct ast_websocket * ws_session
Definition: sip.h:802
static struct ast_mansession session
struct ast_sockaddr *AST_OPTIONAL_API_NAME() ast_websocket_remote_address(struct ast_websocket *session)
struct ast_str * data
Definition: sip.h:843
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
int AST_OPTIONAL_API_NAME() ast_websocket_set_timeout(struct ast_websocket *session, int timeout)
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
static int handle_request_do(struct sip_request *req, struct ast_sockaddr *addr)
Handle incoming SIP message - request or response.
Definition: chan_sip.c:29424
int ast_wait_for_input(int fd, int ms)
Definition: main/utils.c:1519
struct sip_socket socket
Definition: sip.h:846
static void set_socket_transport(struct sip_socket *socket, int transport)
Definition: chan_sip.c:16629
int AST_OPTIONAL_API_NAME() ast_websocket_set_nonblock(struct ast_websocket *session)
void AST_OPTIONAL_API_NAME() ast_websocket_unref(struct ast_websocket *session)
ast_websocket_opcode
WebSocket operation codes.
int websocket_write_timeout
Definition: sip.h:790
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ sip_write()

static int sip_write ( struct ast_channel ast,
struct ast_frame frame 
)
static

Send frame to media channel (rtp)

Definition at line 7511 of file chan_sip.c.

References ast_channel_nativeformats(), ast_channel_readformat(), ast_channel_tech_pvt(), ast_channel_writeformat(), ast_format_cap_get_names(), ast_format_cap_iscompatible_format(), AST_FORMAT_CAP_NAMES_LEN, AST_FORMAT_CMP_NOT_EQUAL, ast_format_get_name(), AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log, ast_rtp_instance_update_source(), ast_rtp_instance_write(), ast_rtp_red_buffer(), ast_set_flag, AST_STATE_UP, ast_str_alloca, ast_test_flag, ast_udptl_write(), sip_pvt::flags, ast_frame_subclass::format, ast_frame::frametype, global_prematuremediafilter, sip_pvt::initreq, INV_EARLY_MEDIA, sip_pvt::invitestate, sip_pvt::lastrtptx, LOG_WARNING, NULL, sip_pvt::red, sip_pvt::rtp, SIP_OUTGOING, SIP_PROGRESS_SENT, sip_pvt_lock, sip_pvt_unlock, t38properties::state, ast_frame::subclass, sip_pvt::t38, T38_ENABLED, transmit_provisional_response(), sip_pvt::trtp, TRUE, sip_pvt::udptl, and sip_pvt::vrtp.

7512 {
7513  struct sip_pvt *p = ast_channel_tech_pvt(ast);
7514  int res = 0;
7515 
7516  switch (frame->frametype) {
7517  case AST_FRAME_VOICE:
7519  struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
7520  ast_log(LOG_WARNING, "Asked to transmit frame type %s, while native formats is %s read/write = %s/%s\n",
7525  return 0;
7526  }
7527  if (p) {
7528  sip_pvt_lock(p);
7529  if (p->t38.state == T38_ENABLED) {
7530  /* drop frame, can't sent VOICE frames while in T.38 mode */
7531  sip_pvt_unlock(p);
7532  break;
7533  } else if (p->rtp) {
7534  /* If channel is not up, activate early media session */
7535  if ((ast_channel_state(ast) != AST_STATE_UP) &&
7537  !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
7541  transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE);
7543  }
7544  }
7547  p->lastrtptx = time(NULL);
7548  res = ast_rtp_instance_write(p->rtp, frame);
7549  }
7550  }
7551  sip_pvt_unlock(p);
7552  }
7553  break;
7554  case AST_FRAME_VIDEO:
7555  if (p) {
7556  sip_pvt_lock(p);
7557  if (p->vrtp) {
7558  /* Activate video early media */
7559  if ((ast_channel_state(ast) != AST_STATE_UP) &&
7561  !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
7563  transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE);
7565  }
7568  p->lastrtptx = time(NULL);
7569  res = ast_rtp_instance_write(p->vrtp, frame);
7570  }
7571  }
7572  sip_pvt_unlock(p);
7573  }
7574  break;
7575  case AST_FRAME_TEXT:
7576  if (p) {
7577  sip_pvt_lock(p);
7578  if (p->red) {
7579  ast_rtp_red_buffer(p->trtp, frame);
7580  } else {
7581  if (p->trtp) {
7582  /* Activate text early media */
7583  if ((ast_channel_state(ast) != AST_STATE_UP) &&
7585  !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
7587  transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE);
7589  }
7592  p->lastrtptx = time(NULL);
7593  res = ast_rtp_instance_write(p->trtp, frame);
7594  }
7595  }
7596  }
7597  sip_pvt_unlock(p);
7598  }
7599  break;
7600  case AST_FRAME_IMAGE:
7601  return 0;
7602  break;
7603  case AST_FRAME_MODEM:
7604  if (p) {
7605  sip_pvt_lock(p);
7606  /* UDPTL requires two-way communication, so early media is not needed here.
7607  we simply forget the frames if we get modem frames before the bridge is up.
7608  Fax will re-transmit.
7609  */
7610  if ((ast_channel_state(ast) == AST_STATE_UP) &&
7611  p->udptl &&
7612  (p->t38.state == T38_ENABLED)) {
7613  res = ast_udptl_write(p->udptl, frame);
7614  }
7615  sip_pvt_unlock(p);
7616  }
7617  break;
7618  default:
7619  ast_log(LOG_WARNING, "Can't send %u type frames with SIP write\n", frame->frametype);
7620  return 0;
7621  }
7622 
7623  return res;
7624 }
#define T38_ENABLED
Definition: chan_ooh323.c:102
enum t38state state
Definition: sip.h:917
void * ast_channel_tech_pvt(const struct ast_channel *chan)
struct ast_rtp_instance * trtp
Definition: sip.h:1176
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define LOG_WARNING
Definition: logger.h:274
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:326
int ast_rtp_instance_write(struct ast_rtp_instance *instance, struct ast_frame *frame)
Send a frame out over RTP.
Definition: rtp_engine.c:568
ast_channel_state
ast_channel states
Definition: channelstate.h:35
struct ast_flags flags[3]
Definition: sip.h:1075
#define ast_str_alloca(init_len)
Definition: strings.h:800
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
#define NULL
Definition: resample.c:96
int red
Definition: sip.h:1189
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
struct t38properties t38
Definition: sip.h:1113
struct ast_frame_subclass subclass
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
enum ast_format_cmp_res ast_format_cap_iscompatible_format(const struct ast_format_cap *cap, const struct ast_format *format)
Find if ast_format is within the capabilities of the ast_format_cap object.
Definition: format_cap.c:583
#define ast_log
Definition: astobj2.c:42
struct sip_request initreq
Definition: sip.h:1151
struct ast_udptl * udptl
Definition: sip.h:1115
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
struct ast_rtp_instance * vrtp
Definition: sip.h:1175
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition: format_cap.c:736
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
static int transmit_provisional_response(struct sip_pvt *p, const char *msg, const struct sip_request *req, int with_sdp)
Definition: chan_sip.c:12867
struct ast_rtp_instance * rtp
Definition: sip.h:1174
enum invitestates invitestate
Definition: sip.h:1007
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
time_t lastrtptx
Definition: sip.h:1130
int ast_rtp_red_buffer(struct ast_rtp_instance *instance, struct ast_frame *frame)
Buffer a frame in an RTP instance for RED.
Definition: rtp_engine.c:2432
#define TRUE
Definition: app_minivm.c:518
int ast_udptl_write(struct ast_udptl *udptl, struct ast_frame *f)
Definition: udptl.c:1161
enum ast_frame_type frametype
#define SIP_OUTGOING
Definition: sip.h:257
struct ast_format * format
void ast_rtp_instance_update_source(struct ast_rtp_instance *instance)
Indicate that the RTP marker bit should be set on an RTP stream.
Definition: rtp_engine.c:2151
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
#define SIP_PROGRESS_SENT
Definition: sip.h:260
static int global_prematuremediafilter
Definition: chan_sip.c:822

◆ sipinfo_send()

static int sipinfo_send ( struct ast_channel chan,
struct ast_variable headers,
const char *  content_type,
const char *  content,
const char *  useragent_filter 
)
static

Definition at line 7897 of file chan_sip.c.

References add_content(), add_header(), ast_channel_lock, ast_channel_name(), ast_channel_tech(), ast_channel_tech_pvt(), ast_channel_unlock, ast_log, ast_strlen_zero, cleanup(), LOG_WARNING, match(), ast_variable::name, ast_variable::next, sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, sip_pvt_lock, sip_pvt_unlock, sip_pvt::useragent, ast_variable::value, var, and XMIT_RELIABLE.

7903 {
7904  struct sip_pvt *p;
7905  struct ast_variable *var;
7906  struct sip_request req;
7907  int res = -1;
7908 
7909  ast_channel_lock(chan);
7910 
7911  if (ast_channel_tech(chan) != &sip_tech) {
7912  ast_log(LOG_WARNING, "Attempted to send a custom INFO on a non-SIP channel %s\n", ast_channel_name(chan));
7913  ast_channel_unlock(chan);
7914  return res;
7915  }
7916 
7917  p = ast_channel_tech_pvt(chan);
7918  sip_pvt_lock(p);
7919 
7920  if (!(ast_strlen_zero(useragent_filter))) {
7921  int match = (strstr(p->useragent, useragent_filter)) ? 1 : 0;
7922  if (!match) {
7923  goto cleanup;
7924  }
7925  }
7926 
7927  reqprep(&req, p, SIP_INFO, 0, 1);
7928  for (var = headers; var; var = var->next) {
7929  add_header(&req, var->name, var->value);
7930  }
7931  if (!ast_strlen_zero(content) && !ast_strlen_zero(content_type)) {
7932  add_header(&req, "Content-Type", content_type);
7933  add_content(&req, content);
7934  }
7935 
7936  res = send_request(p, &req, XMIT_RELIABLE, p->ocseq);
7937 
7938 cleanup:
7939  sip_pvt_unlock(p);
7940  ast_channel_unlock(chan);
7941  return res;
7942 }
Definition: sip.h:626
struct ast_variable * next
#define ast_channel_lock(chan)
Definition: channel.h:2945
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define LOG_WARNING
Definition: logger.h:274
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Definition: chan_iax2.c:2315
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
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)
Definition: chan_sip.c:12361
#define ast_log
Definition: astobj2.c:42
const ast_string_field useragent
Definition: sip.h:1063
struct ast_str * content
Definition: sip.h:844
static int send_request(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno)
Definition: chan_sip.c:4863
uint32_t ocseq
Definition: sip.h:1067
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
#define ast_channel_unlock(chan)
Definition: channel.h:2946
static void * cleanup(void *unused)
Definition: pbx_realtime.c:124
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
const char * ast_channel_name(const struct ast_channel *chan)
struct ast_channel_tech sip_tech
Definition of this channel for PBX channel registration.
Definition: chan_sip.c:1573
static int add_content(struct sip_request *req, const char *line)
Add content (not header) to SIP message.
Definition: chan_sip.c:11931
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)

◆ sipsock_read()

static int sipsock_read ( int *  id,
int  fd,
short  events,
void *  ignore 
)
static

Read data from SIP UDP socket.

Note
sipsock_read locks the owner channel while we are processing the SIP message
Returns
1 on error, 0 on success
Note
Successful messages is connected to SIP call and forwarded to handle_incoming()

Definition at line 29380 of file chan_sip.c.

References AST_DYNSTR_BUILD_FAILED, ast_log, ast_recvfrom(), ast_str_create, ast_str_set(), AST_TRANSPORT_UDP, sip_request::data, deinit_req(), errno, sip_socket::fd, handle_request_do(), LOG_NOTICE, LOG_WARNING, NULL, set_socket_transport(), SIP_MIN_PACKET, sipsock, sip_request::socket, and sip_socket::tcptls_session.

Referenced by do_monitor().

29381 {
29382  struct sip_request req;
29383  struct ast_sockaddr addr;
29384  int res;
29385  static char readbuf[65535];
29386 
29387  memset(&req, 0, sizeof(req));
29388  res = ast_recvfrom(fd, readbuf, sizeof(readbuf) - 1, 0, &addr);
29389  if (res < 0) {
29390 #if !defined(__FreeBSD__)
29391  if (errno == EAGAIN)
29392  ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n");
29393  else
29394 #endif
29395  if (errno != ECONNREFUSED)
29396  ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno));
29397  return 1;
29398  }
29399 
29400  readbuf[res] = '\0';
29401 
29402  if (!(req.data = ast_str_create(SIP_MIN_PACKET))) {
29403  return 1;
29404  }
29405 
29406  if (ast_str_set(&req.data, 0, "%s", readbuf) == AST_DYNSTR_BUILD_FAILED) {
29407  return -1;
29408  }
29409 
29410  req.socket.fd = sipsock;
29412  req.socket.tcptls_session = NULL;
29413 
29414  handle_request_do(&req, &addr);
29415  deinit_req(&req);
29416 
29417  return 1;
29418 }
#define LOG_WARNING
Definition: logger.h:274
#define NULL
Definition: resample.c:96
Socket address structure.
Definition: netsock2.h:97
static void deinit_req(struct sip_request *req)
Deinitialize SIP response/request.
Definition: chan_sip.c:12195
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
#define ast_log
Definition: astobj2.c:42
int errno
ssize_t ast_recvfrom(int sockfd, void *buf, size_t len, int flags, struct ast_sockaddr *src_addr)
Wrapper around recvfrom(2) that uses struct ast_sockaddr.
Definition: netsock2.c:606
#define LOG_NOTICE
Definition: logger.h:263
static int sipsock
Main socket for UDP SIP communication.
Definition: chan_sip.c:1104
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
#define SIP_MIN_PACKET
Definition: sip.h:114
static int handle_request_do(struct sip_request *req, struct ast_sockaddr *addr)
Handle incoming SIP message - request or response.
Definition: chan_sip.c:29424
static void set_socket_transport(struct sip_socket *socket, int transport)
Definition: chan_sip.c:16629
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ sockaddr_is_null_or_any()

static int sockaddr_is_null_or_any ( const struct ast_sockaddr addr)
static

Definition at line 10177 of file chan_sip.c.

References ast_sockaddr_is_any(), and ast_sockaddr_isnull().

Referenced by process_sdp().

10178 {
10179  return ast_sockaddr_isnull(addr) || ast_sockaddr_is_any(addr);
10180 }
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
int ast_sockaddr_is_any(const struct ast_sockaddr *addr)
Determine if the address type is unspecified, or "any" address.
Definition: netsock2.c:534

◆ st_get_mode()

enum st_mode st_get_mode ( struct sip_pvt p,
int  no_cached 
)
static

Get the session-timer mode.

Parameters
ppointer to the SIP dialog
no_cachedSet this to true in order to force a peername lookup on the session timer mode.

Definition at line 30447 of file chan_sip.c.

References global_st_mode, sip_pvt::relatedpeer, SESSION_TIMER_MODE_INVALID, sip_st_alloc(), sip_st_dlg::st_cached_mode, sip_st_cfg::st_mode_oper, sip_pvt::stimer, and sip_peer::stimer.

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

30448 {
30449  if (!p->stimer) {
30450  sip_st_alloc(p);
30451  if (!p->stimer) {
30453  }
30454  }
30455 
30456  if (!no_cached && p->stimer->st_cached_mode != SESSION_TIMER_MODE_INVALID)
30457  return p->stimer->st_cached_mode;
30458 
30459  if (p->relatedpeer) {
30461  return p->stimer->st_cached_mode;
30462  }
30463 
30465  return global_st_mode;
30466 }
struct sip_peer * relatedpeer
Definition: sip.h:1171
enum st_mode st_cached_mode
Definition: sip.h:967
static struct sip_st_dlg * sip_st_alloc(struct sip_pvt *const p)
Allocate Session-Timers struct w/in dialog.
Definition: chan_sip.c:8914
struct sip_st_dlg * stimer
Definition: sip.h:1184
enum st_mode st_mode_oper
Definition: sip.h:976
static enum st_mode global_st_mode
Definition: chan_sip.c:855
struct sip_st_cfg stimer
Definition: sip.h:1368

◆ st_get_refresher()

enum st_refresher st_get_refresher ( struct sip_pvt p)
static

Get the entity (UAC or UAS) that's acting as the session-timer refresher.

Note
This is only called when processing an INVITE, so in that case Asterisk is always currently the UAS. If this is ever used to process responses, the function will have to be changed.
Parameters
ppointer to the SIP dialog

Definition at line 30425 of file chan_sip.c.

References global_st_refresher, sip_pvt::relatedpeer, SESSION_TIMER_REFRESHER_AUTO, SESSION_TIMER_REFRESHER_PARAM_UAC, SESSION_TIMER_REFRESHER_THEM, SESSION_TIMER_REFRESHER_US, sip_st_dlg::st_cached_ref, sip_st_cfg::st_ref, sip_pvt::stimer, and sip_peer::stimer.

Referenced by handle_request_invite_st().

30426 {
30428  return p->stimer->st_cached_ref;
30429  }
30430 
30431  if (p->relatedpeer) {
30433  return p->stimer->st_cached_ref;
30434  }
30435 
30437  return p->stimer->st_cached_ref;
30438 }
struct sip_peer * relatedpeer
Definition: sip.h:1171
enum st_refresher st_cached_ref
Definition: sip.h:968
struct sip_st_dlg * stimer
Definition: sip.h:1184
static enum st_refresher_param global_st_refresher
Definition: chan_sip.c:856
struct sip_st_cfg stimer
Definition: sip.h:1368
enum st_refresher_param st_ref
Definition: sip.h:977

◆ st_get_se()

int st_get_se ( struct sip_pvt p,
int  max 
)
static

Get Max or Min SE (session timer expiry)

Parameters
ppointer to the SIP dialog
maxif true, get max se, otherwise min se

Definition at line 30393 of file chan_sip.c.

References global_max_se, global_min_se, sip_pvt::relatedpeer, sip_st_dlg::st_cached_max_se, sip_st_dlg::st_cached_min_se, sip_st_cfg::st_max_se, sip_st_cfg::st_min_se, sip_pvt::stimer, sip_peer::stimer, and TRUE.

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

30394 {
30395  if (max == TRUE) {
30396  if (p->stimer->st_cached_max_se) {
30397  return p->stimer->st_cached_max_se;
30398  }
30399  if (p->relatedpeer) {
30401  return (p->stimer->st_cached_max_se);
30402  }
30404  return (p->stimer->st_cached_max_se);
30405  }
30406  /* Find Min SE timer */
30407  if (p->stimer->st_cached_min_se) {
30408  return p->stimer->st_cached_min_se;
30409  }
30410  if (p->relatedpeer) {
30412  return (p->stimer->st_cached_min_se);
30413  }
30415  return (p->stimer->st_cached_min_se);
30416 }
int st_min_se
Definition: sip.h:978
struct sip_peer * relatedpeer
Definition: sip.h:1171
int st_max_se
Definition: sip.h:979
int st_cached_max_se
Definition: sip.h:966
struct sip_st_dlg * stimer
Definition: sip.h:1184
int st_cached_min_se
Definition: sip.h:965
static int global_max_se
Definition: chan_sip.c:858
#define TRUE
Definition: app_minivm.c:518
struct sip_st_cfg stimer
Definition: sip.h:1368
static int global_min_se
Definition: chan_sip.c:857
#define max(a, b)
Definition: f2c.h:198

◆ start_ice()

static void start_ice ( struct ast_rtp_instance instance,
int  offer 
)
static

Start ICE negotiation on an RTP instance.

Definition at line 13180 of file chan_sip.c.

References AST_RTP_ICE_ROLE_CONTROLLED, AST_RTP_ICE_ROLE_CONTROLLING, ast_rtp_instance_get_ice(), ast_rtp_engine_ice::set_role, and ast_rtp_engine_ice::start.

Referenced by add_sdp(), and process_sdp().

13181 {
13182  struct ast_rtp_engine_ice *ice = ast_rtp_instance_get_ice(instance);
13183 
13184  if (!ice) {
13185  return;
13186  }
13187 
13188  /* If we are the offerer then we are the controlling agent, otherwise they are */
13190  ice->start(instance);
13191 }
struct ast_rtp_engine_ice * ast_rtp_instance_get_ice(struct ast_rtp_instance *instance)
Obtain a pointer to the ICE support present on an RTP instance.
Definition: rtp_engine.c:2891
void(* set_role)(struct ast_rtp_instance *instance, enum ast_rtp_ice_role role)
Definition: rtp_engine.h:503
void(* start)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:491
Structure that represents the optional ICE support within an RTP engine.
Definition: rtp_engine.h:485

◆ start_mwi_subscription()

static void start_mwi_subscription ( struct sip_subscription_mwi mwi,
int  ms 
)
static

Definition at line 14989 of file chan_sip.c.

References __start_mwi_subscription(), ao2_t_ref, ast_free, ast_malloc, ast_sched_add(), mwi_subscription_data::ms, and mwi_subscription_data::mwi.

Referenced by handle_response_subscribe(), and sip_send_all_mwi_subscriptions().

14990 {
14991  struct mwi_subscription_data *sched_data;
14992 
14993  sched_data = ast_malloc(sizeof(*sched_data));
14994  if (!sched_data) {
14995  /* Uh Oh. Expect bad behavior. */
14996  return;
14997  }
14998  sched_data->mwi = mwi;
14999  sched_data->ms = ms;
15000  ao2_t_ref(mwi, +1, "Start MWI subscription action");
15001  if (ast_sched_add(sched, 0, __start_mwi_subscription, sched_data) < 0) {
15002  /* Uh Oh. Expect bad behavior. */
15003  ao2_t_ref(mwi, -1, "Failed to schedule start MWI subscription action");
15004  ast_free(sched_data);
15005  }
15006 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
Definition: sched.c:76
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
static int __start_mwi_subscription(const void *data)
Definition: chan_sip.c:14967
#define ast_free(a)
Definition: astmm.h:182
struct sip_subscription_mwi * mwi
Definition: chan_sip.c:14962
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565

◆ start_register_timeout()

static void start_register_timeout ( struct sip_registry reg)
static

Definition at line 16080 of file chan_sip.c.

References __start_register_timeout(), ao2_t_ref, and ast_sched_add().

Referenced by transmit_register().

16081 {
16082  ao2_t_ref(reg, +1, "Start register timeout action");
16083  if (ast_sched_add(sched, 0, __start_register_timeout, reg) < 0) {
16084  /* Uh Oh. Expect bad behavior. */
16085  ao2_t_ref(reg, -1, "Failed to schedule start register timeout action");
16086  }
16087 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
Definition: sched.c:76
static int __start_register_timeout(const void *data)
Definition: chan_sip.c:16060
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565

◆ start_reregister_timeout()

static void start_reregister_timeout ( struct sip_registry reg,
int  ms 
)
static

Definition at line 15945 of file chan_sip.c.

References __start_reregister_timeout(), ao2_t_ref, ast_free, ast_malloc, ast_sched_add(), reregister_data::ms, and reregister_data::reg.

Referenced by handle_response_register(), and sip_send_all_registers().

15946 {
15947  struct reregister_data *sched_data;
15948 
15949  sched_data = ast_malloc(sizeof(*sched_data));
15950  if (!sched_data) {
15951  /* Uh Oh. Expect bad behavior. */
15952  return;
15953  }
15954  sched_data->reg = reg;
15955  sched_data->ms = ms;
15956  ao2_t_ref(reg, +1, "Start reregister timeout action");
15957  if (ast_sched_add(sched, 0, __start_reregister_timeout, sched_data) < 0) {
15958  /* Uh Oh. Expect bad behavior. */
15959  ao2_t_ref(reg, -1, "Failed to schedule start reregister timeout action");
15960  ast_free(sched_data);
15961  }
15962 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
struct sip_registry * reg
Definition: chan_sip.c:15918
Definition: sched.c:76
static int __start_reregister_timeout(const void *data)
Definition: chan_sip.c:15923
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
#define ast_free(a)
Definition: astmm.h:182
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565

◆ start_session_timer()

static void start_session_timer ( struct sip_pvt p)
static

Session-Timers: Start session timer.

Definition at line 30265 of file chan_sip.c.

References __start_session_timer(), ast_sched_add(), dialog_ref, dialog_unref, sip_st_dlg::st_active, sip_pvt::stimer, and TRUE.

Referenced by handle_response_invite(), and restart_session_timer().

30266 {
30267  struct sip_st_dlg *stimer = pvt->stimer;
30268 
30269  stimer->st_active = TRUE;
30270  dialog_ref(pvt, "Start session timer action");
30271  if (ast_sched_add(sched, 0, __start_session_timer, pvt) < 0) {
30272  /* Uh Oh. Expect bad behavior. */
30273  dialog_unref(pvt, "Failed to schedule start session timer action");
30274  }
30275 }
Definition: sched.c:76
int st_active
Definition: sip.h:960
static int __start_session_timer(const void *data)
Definition: chan_sip.c:30226
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
#define dialog_ref(dialog, tag)
when we create or delete references, make sure to use these functions so we keep track of the refcoun...
Definition: dialog.h:32
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565
#define TRUE
Definition: app_minivm.c:518
Structure that encapsulates all attributes related to running SIP Session-Timers feature on a per dia...
Definition: sip.h:959

◆ start_t38_abort_timer()

static void start_t38_abort_timer ( struct sip_pvt pvt)
static

Definition at line 26144 of file chan_sip.c.

References __start_t38_abort_timer(), ast_sched_add(), dialog_ref, and dialog_unref.

Referenced by handle_request_invite().

26145 {
26146  dialog_ref(pvt, "Start t38id action");
26147  if (ast_sched_add(sched, 0, __start_t38_abort_timer, pvt) < 0) {
26148  /* Uh Oh. Expect bad behavior. */
26149  dialog_unref(pvt, "Failed to schedule start t38id action");
26150  }
26151 }
static int __start_t38_abort_timer(const void *data)
Definition: chan_sip.c:26126
Definition: sched.c:76
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
#define dialog_ref(dialog, tag)
when we create or delete references, make sure to use these functions so we keep track of the refcoun...
Definition: dialog.h:32
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565

◆ startup_event_cb()

static void startup_event_cb ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Event callback which indicates we're fully booted.

Definition at line 35461 of file chan_sip.c.

References ast_json_object_get(), ast_json_string_get(), ast_manager_get_generic_type(), deprecation_notice(), ast_json_payload::json, stasis_message_data(), stasis_message_type(), stasis_unsubscribe(), type, and unload_module().

Referenced by load_module().

35462 {
35463  struct ast_json_payload *payload;
35464  const char *type;
35465 
35467  return;
35468  }
35469 
35470  payload = stasis_message_data(message);
35471  type = ast_json_string_get(ast_json_object_get(payload->json, "type"));
35472 
35473  if (strcmp(type, "FullyBooted")) {
35474  return;
35475  }
35476 
35478 
35479  stasis_unsubscribe(sub);
35480 }
static const char type[]
Definition: chan_ooh323.c:109
struct ast_json * json
Definition: json.h:1025
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
static void deprecation_notice(void)
Definition: chan_sip.c:35452
struct stasis_message_type * ast_manager_get_generic_type(void)
Get the stasis_message_type for generic messages.
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
Definition: json.c:273
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
struct stasis_subscription * stasis_unsubscribe(struct stasis_subscription *subscription)
Cancel a subscription.
Definition: stasis.c:973
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:397

◆ STASIS_MESSAGE_TYPE_DEFN_LOCAL()

STASIS_MESSAGE_TYPE_DEFN_LOCAL ( session_timeout_type  ,
to_ami = session_timeout_to_ami 
)

◆ state_notify_build_xml()

static void state_notify_build_xml ( struct state_notify_data data,
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 15193 of file chan_sip.c.

References allow_notify_user_presence(), ast_alloca, ast_channel_caller(), ast_channel_connected(), 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_PRESENCE_INVALID, AST_PRESENCE_NOT_SET, ast_presence_state2str(), ast_str_append(), ast_strdupa, ast_test_suite_event_notify, ast_xml_escape(), sip_pvt::callid, cid_num, CPIM_PIDF_XML, state_notify_data::device_state_info, DIALOG_INFO_XML, sip_pvt::dialogver, find_ringing_channel(), sip_pvt::fromdomain, ast_party_caller::id, ast_party_connected_line::id, name, NONE, NOTIFY_CLOSED, NOTIFY_INUSE, NOTIFY_OPEN, sip_settings::notifycid, sip_settings::notifyringing, NOTIFYRINGING_ENABLED, NULL, ast_party_id::number, sip_settings::pedanticsipchecking, PIDF_XML, state_notify_data::presence_message, state_notify_data::presence_state, state_notify_data::presence_subtype, ast_party_number::presentation, S_COR, S_OR, sip_cfg, state_notify_data::state, strsep(), sip_pvt::tag, sip_pvt::theirtag, and XPIDF_XML.

Referenced by transmit_state_notify().

15194 {
15195  enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN;
15196  const char *statestring = "terminated";
15197  const char *pidfstate = "--";
15198  const char *pidfnote ="Ready";
15199  char hint[AST_MAX_EXTENSION];
15200 
15201  switch (data->state) {
15203  statestring = (sip_cfg.notifyringing == NOTIFYRINGING_ENABLED) ? "early" : "confirmed";
15204  local_state = NOTIFY_INUSE;
15205  pidfstate = "busy";
15206  pidfnote = "Ringing";
15207  break;
15208  case AST_EXTENSION_RINGING:
15209  statestring = "early";
15210  local_state = NOTIFY_INUSE;
15211  pidfstate = "busy";
15212  pidfnote = "Ringing";
15213  break;
15214  case AST_EXTENSION_INUSE:
15215  statestring = "confirmed";
15216  local_state = NOTIFY_INUSE;
15217  pidfstate = "busy";
15218  pidfnote = "On the phone";
15219  break;
15220  case AST_EXTENSION_BUSY:
15221  statestring = "confirmed";
15222  local_state = NOTIFY_CLOSED;
15223  pidfstate = "busy";
15224  pidfnote = "On the phone";
15225  break;
15227  statestring = "terminated";
15228  local_state = NOTIFY_CLOSED;
15229  pidfstate = "away";
15230  pidfnote = "Unavailable";
15231  break;
15232  case AST_EXTENSION_ONHOLD:
15233  statestring = "confirmed";
15234  local_state = NOTIFY_CLOSED;
15235  pidfstate = "busy";
15236  pidfnote = "On hold";
15237  break;
15239  default:
15240  /* Default setting */
15241  break;
15242  }
15243 
15244  /* Check which device/devices we are watching and if they are registered */
15245  if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten)) {
15246  char *hint2;
15247  char *individual_hint = NULL;
15248  int hint_count = 0, unavailable_count = 0;
15249 
15250  /* strip off any possible PRESENCE providers from hint */
15251  if ((hint2 = strrchr(hint, ','))) {
15252  *hint2 = '\0';
15253  }
15254  hint2 = hint;
15255 
15256  while ((individual_hint = strsep(&hint2, "&"))) {
15257  hint_count++;
15258 
15259  if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE)
15260  unavailable_count++;
15261  }
15262 
15263  /* If none of the hinted devices are registered, we will
15264  * override notification and show no availability.
15265  */
15266  if (hint_count > 0 && hint_count == unavailable_count) {
15267  local_state = NOTIFY_CLOSED;
15268  pidfstate = "away";
15269  pidfnote = "Not online";
15270  }
15271  }
15272 
15273  switch (subscribed) {
15274  case XPIDF_XML:
15275  case CPIM_PIDF_XML:
15276  ast_str_append(tmp, 0,
15277  "<?xml version=\"1.0\"?>\n"
15278  "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"
15279  "<presence>\n");
15280  ast_str_append(tmp, 0, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom);
15281  ast_str_append(tmp, 0, "<atom id=\"%s\">\n", exten);
15282  ast_str_append(tmp, 0, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto);
15283  ast_str_append(tmp, 0, "<status status=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed");
15284  ast_str_append(tmp, 0, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline");
15285  ast_str_append(tmp, 0, "</address>\n</atom>\n</presence>\n");
15286  break;
15287  case PIDF_XML: /* Eyebeam supports this format */
15288  ast_str_append(tmp, 0,
15289  "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"
15290  "<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);
15291  ast_str_append(tmp, 0, "<pp:person><status>\n");
15292  if (pidfstate[0] != '-') {
15293  ast_str_append(tmp, 0, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate);
15294  }
15295  ast_str_append(tmp, 0, "</status></pp:person>\n");
15296  ast_str_append(tmp, 0, "<note>%s</note>\n", pidfnote); /* Note */
15297  ast_str_append(tmp, 0, "<tuple id=\"%s\">\n", exten); /* Tuple start */
15298  ast_str_append(tmp, 0, "<contact priority=\"1\">%s</contact>\n", mto);
15299  if (pidfstate[0] == 'b') /* Busy? Still open ... */
15300  ast_str_append(tmp, 0, "<status><basic>open</basic></status>\n");
15301  else
15302  ast_str_append(tmp, 0, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed");
15303 
15305  && (data->presence_state != AST_PRESENCE_NOT_SET)) {
15306  ast_str_append(tmp, 0, "</tuple>\n");
15307  ast_str_append(tmp, 0, "<tuple id=\"digium-presence\">\n");
15308  ast_str_append(tmp, 0, "<status>\n");
15309  ast_str_append(tmp, 0, "<digium_presence type=\"%s\" subtype=\"%s\">%s</digium_presence>\n",
15311  S_OR(data->presence_subtype, ""),
15312  S_OR(data->presence_message, ""));
15313  ast_str_append(tmp, 0, "</status>\n");
15314  ast_test_suite_event_notify("DIGIUM_PRESENCE_SENT",
15315  "PresenceState: %s\r\n"
15316  "Subtype: %s\r\n"
15317  "Message: %s",
15319  S_OR(data->presence_subtype, ""),
15320  S_OR(data->presence_message, ""));
15321  }
15322  ast_str_append(tmp, 0, "</tuple>\n</presence>\n");
15323  break;
15324  case DIALOG_INFO_XML: /* SNOM subscribes in this format */
15325  ast_str_append(tmp, 0, "<?xml version=\"1.0\"?>\n");
15326  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);
15327  if (data->state > 0 && (data->state & AST_EXTENSION_RINGING) && sip_cfg.notifyringing) {
15328  /* Twice the extension length should be enough for XML encoding */
15329  char local_display[AST_MAX_EXTENSION * 2];
15330  char remote_display[AST_MAX_EXTENSION * 2];
15331  char *local_target = ast_strdupa(mto);
15332  /* It may seem odd to base the remote_target on the To header here,
15333  * but testing by reporters on issue ASTERISK-16735 found that basing
15334  * on the From header would cause ringing state hints to not work
15335  * properly on certain SNOM devices. If you are using notifycid properly
15336  * (i.e. in the same extension and context as the dialed call) then this
15337  * should not be an issue since the data will be overwritten shortly
15338  * with channel caller ID
15339  */
15340  char *remote_target = ast_strdupa(mto);
15341 
15342  ast_xml_escape(exten, local_display, sizeof(local_display));
15343  ast_xml_escape(exten, remote_display, sizeof(remote_display));
15344 
15345  /* There are some limitations to how this works. The primary one is that the
15346  callee must be dialing the same extension that is being monitored. Simply dialing
15347  the hint'd device is not sufficient. */
15348  if (sip_cfg.notifycid) {
15349  struct ast_channel *callee;
15350 
15351  callee = find_ringing_channel(data->device_state_info, p);
15352  if (callee) {
15353  static char *anonymous = "anonymous";
15354  static char *invalid = "anonymous.invalid";
15355  char *cid_num;
15356  char *connected_num;
15357  int need;
15358  int cid_num_restricted, connected_num_restricted;
15359 
15360  ast_channel_lock(callee);
15361 
15362  cid_num_restricted = (ast_channel_caller(callee)->id.number.presentation &
15364  cid_num = S_COR(ast_channel_caller(callee)->id.number.valid,
15365  S_COR(cid_num_restricted, anonymous,
15366  ast_channel_caller(callee)->id.number.str), "");
15367 
15368  need = strlen(cid_num) + (cid_num_restricted ? strlen(invalid) :
15369  strlen(p->fromdomain)) + sizeof("sip:@");
15370  local_target = ast_alloca(need);
15371 
15372  snprintf(local_target, need, "sip:%s@%s", cid_num,
15373  cid_num_restricted ? invalid : p->fromdomain);
15374 
15375  ast_xml_escape(S_COR(ast_channel_caller(callee)->id.name.valid,
15376  S_COR((ast_channel_caller(callee)->id.name.presentation &
15378  ast_channel_caller(callee)->id.name.str), ""),
15379  local_display, sizeof(local_display));
15380 
15381  connected_num_restricted = (ast_channel_connected(callee)->id.number.presentation &
15383  connected_num = S_COR(ast_channel_connected(callee)->id.number.valid,
15384  S_COR(connected_num_restricted, anonymous,
15385  ast_channel_connected(callee)->id.number.str), "");
15386 
15387  need = strlen(connected_num) + (connected_num_restricted ? strlen(invalid) :
15388  strlen(p->fromdomain)) + sizeof("sip:@");
15389  remote_target = ast_alloca(need);
15390 
15391  snprintf(remote_target, need, "sip:%s@%s", connected_num,
15392  connected_num_restricted ? invalid : p->fromdomain);
15393 
15394  ast_xml_escape(S_COR(ast_channel_connected(callee)->id.name.valid,
15395  S_COR((ast_channel_connected(callee)->id.name.presentation &
15396  AST_PRES_RESTRICTION) == AST_PRES_RESTRICTED, anonymous,
15397  ast_channel_connected(callee)->id.name.str), ""),
15398  remote_display, sizeof(remote_display));
15399 
15400  ast_channel_unlock(callee);
15401  callee = ast_channel_unref(callee);
15402  }
15403 
15404  /* We create a fake call-id which the phone will send back in an INVITE
15405  Replaces header which we can grab and do some magic with. */
15407  ast_str_append(tmp, 0, "<dialog id=\"%s\" call-id=\"pickup-%s\" local-tag=\"%s\" remote-tag=\"%s\" direction=\"recipient\">\n",
15408  exten, p->callid, p->theirtag, p->tag);
15409  } else {
15410  ast_str_append(tmp, 0, "<dialog id=\"%s\" call-id=\"pickup-%s\" direction=\"recipient\">\n",
15411  exten, p->callid);
15412  }
15413  ast_str_append(tmp, 0,
15414  "<remote>\n"
15415  /* See the limitations of this above. Luckily the phone seems to still be
15416  happy when these values are not correct. */
15417  "<identity display=\"%s\">%s</identity>\n"
15418  "<target uri=\"%s\"/>\n"
15419  "</remote>\n"
15420  "<local>\n"
15421  "<identity display=\"%s\">%s</identity>\n"
15422  "<target uri=\"%s\"/>\n"
15423  "</local>\n",
15424  remote_display, remote_target, remote_target, local_display, local_target, local_target);
15425  } else {
15426  ast_str_append(tmp, 0, "<dialog id=\"%s\" direction=\"recipient\">\n", exten);
15427  }
15428 
15429  } else {
15430  ast_str_append(tmp, 0, "<dialog id=\"%s\">\n", exten);
15431  }
15432  ast_str_append(tmp, 0, "<state>%s</state>\n", statestring);
15433  if (data->state == AST_EXTENSION_ONHOLD) {
15434  ast_str_append(tmp, 0, "<local>\n<target uri=\"%s\">\n"
15435  "<param pname=\"+sip.rendering\" pvalue=\"no\"/>\n"
15436  "</target>\n</local>\n", mto);
15437  }
15438  ast_str_append(tmp, 0, "</dialog>\n</dialog-info>\n");
15439  break;
15440  case NONE:
15441  default:
15442  break;
15443  }
15444 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
int ast_get_hint(char *hint, int hintsize, char *name, int namesize, struct ast_channel *c, const char *context, const char *exten)
If an extension hint exists, return non-zero.
Definition: pbx.c:4141
#define ast_channel_lock(chan)
Definition: channel.h:2945
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
Main Channel structure associated with a channel.
ast_device_state
Device States.
Definition: devicestate.h:52
enum notifycid_setting notifycid
Definition: sip.h:775
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
Definition: channel.h:296
struct ast_party_id id
Connected party ID.
Definition: channel.h:459
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
#define NONE
Definition: misdn_config.c:45
uint32_t dialogver
Definition: sip.h:1167
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
#define NULL
Definition: resample.c:96
int ast_xml_escape(const char *string, char *outbuf, size_t buflen)
Escape reserved characters for use in XML.
Definition: main/utils.c:718
static char cid_num[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:164
#define AST_PRES_RESTRICTED
Definition: callerid.h:325
static int allow_notify_user_presence(struct sip_pvt *p)
Definition: chan_sip.c:15187
Number structure.
Definition: app_followme.c:154
struct ast_party_id id
Caller party ID.
Definition: channel.h:421
const char * presence_message
Definition: chan_sip.c:1012
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
Definition: sip.h:475
#define AST_MAX_EXTENSION
Definition: channel.h:135
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:85
const ast_string_field fromdomain
Definition: sip.h:1063
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
const ast_string_field theirtag
Definition: sip.h:1063
int pedanticsipchecking
Definition: sip.h:756
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:196
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
static int subscribed
Definition: manager.c:1476
const ast_string_field callid
Definition: sip.h:1063
struct ao2_container * device_state_info
Definition: chan_sip.c:1009
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
Definition: sip.h:478
#define ast_channel_unlock(chan)
Definition: channel.h:2946
static const char name[]
Definition: cdr_mysql.c:74
int notifyringing
Definition: sip.h:773
#define AST_PRES_RESTRICTION
Definition: callerid.h:323
static struct ast_channel * find_ringing_channel(struct ao2_container *device_state_info, struct sip_pvt *p)
Definition: chan_sip.c:15161
const char * presence_subtype
Definition: chan_sip.c:1011
char * strsep(char **str, const char *delims)
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
const ast_string_field tag
Definition: sip.h:1063
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
const char * ast_presence_state2str(enum ast_presence_state state)
Convert presence state to text string for output.
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:343

◆ stmode2str()

static const char* stmode2str ( enum st_mode  m)
static

Definition at line 19990 of file chan_sip.c.

References map_x_s().

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

19991 {
19992  return map_x_s(stmodes, m, "Unknown");
19993 }
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
Definition: chan_sip.c:2411
static const struct _map_x_s stmodes[]
Report Peer status in character string.
Definition: chan_sip.c:19983

◆ stop_media_flows()

static void stop_media_flows ( struct sip_pvt p)
static

Immediately stop RTP, VRTP and UDPTL as applicable.

Definition at line 25156 of file chan_sip.c.

References ast_rtp_instance_stop(), ast_udptl_stop(), sip_pvt::rtp, sip_pvt::trtp, sip_pvt::udptl, and sip_pvt::vrtp.

Referenced by __sip_autodestruct(), handle_request_bye(), handle_request_cancel(), handle_response(), and sip_hangup().

25157 {
25158  /* Immediately stop RTP, VRTP and UDPTL as applicable */
25159  if (p->rtp)
25161  if (p->vrtp)
25163  if (p->trtp)
25165  if (p->udptl)
25166  ast_udptl_stop(p->udptl);
25167 }
struct ast_rtp_instance * trtp
Definition: sip.h:1176
void ast_rtp_instance_stop(struct ast_rtp_instance *instance)
Stop an RTP instance.
Definition: rtp_engine.c:2183
struct ast_udptl * udptl
Definition: sip.h:1115
struct ast_rtp_instance * vrtp
Definition: sip.h:1175
struct ast_rtp_instance * rtp
Definition: sip.h:1174
void ast_udptl_stop(struct ast_udptl *udptl)
Definition: udptl.c:1145

◆ stop_provisional_keepalive()

static void stop_provisional_keepalive ( struct sip_pvt pvt)
static

Definition at line 4783 of file chan_sip.c.

References __stop_provisional_keepalive(), ast_sched_add(), dialog_ref, and dialog_unref.

Referenced by send_response(), and sip_hangup().

4784 {
4785  dialog_ref(pvt, "Stop provisional keepalive action");
4786  if (ast_sched_add(sched, 0, __stop_provisional_keepalive, pvt) < 0) {
4787  /* Uh Oh. Expect bad behavior. */
4788  dialog_unref(pvt, "Failed to schedule stop provisional keepalive action");
4789  }
4790 }
Definition: sched.c:76
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
#define dialog_ref(dialog, tag)
when we create or delete references, make sure to use these functions so we keep track of the refcoun...
Definition: dialog.h:32
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565
static int __stop_provisional_keepalive(const void *data)
Definition: chan_sip.c:4773

◆ stop_register_timeout()

static void stop_register_timeout ( struct sip_registry reg)
static

Definition at line 16050 of file chan_sip.c.

References __stop_register_timeout(), ao2_t_ref, and ast_sched_add().

Referenced by handle_response_register().

16051 {
16052  ao2_t_ref(reg, +1, "Stop register timeout action");
16053  if (ast_sched_add(sched, 0, __stop_register_timeout, reg) < 0) {
16054  /* Uh Oh. Expect bad behavior. */
16055  ao2_t_ref(reg, -1, "Failed to schedule stop register timeout action");
16056  }
16057 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
Definition: sched.c:76
static int __stop_register_timeout(const void *data)
Definition: chan_sip.c:16040
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565

◆ stop_reinvite_retry()

static void stop_reinvite_retry ( struct sip_pvt pvt)
static

Definition at line 23846 of file chan_sip.c.

References __stop_reinvite_retry(), ast_sched_add(), dialog_ref, and dialog_unref.

Referenced by handle_request_bye(), and sip_hangup().

23847 {
23848  dialog_ref(pvt, "Stop reinvite retry action");
23849  if (ast_sched_add(sched, 0, __stop_reinvite_retry, pvt) < 0) {
23850  /* Uh Oh. Expect bad behavior. */
23851  dialog_unref(pvt, "Failed to schedule stop reinvite retry action");
23852  }
23853 }
Definition: sched.c:76
static int __stop_reinvite_retry(const void *data)
Definition: chan_sip.c:23836
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
#define dialog_ref(dialog, tag)
when we create or delete references, make sure to use these functions so we keep track of the refcoun...
Definition: dialog.h:32
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565

◆ stop_reinviteid()

static void stop_reinviteid ( struct sip_pvt pvt)
static

Definition at line 7186 of file chan_sip.c.

References __stop_reinviteid(), ast_sched_add(), dialog_ref, and dialog_unref.

Referenced by handle_response_invite().

7187 {
7188  dialog_ref(pvt, "Stop reinviteid action");
7189  if (ast_sched_add(sched, 0, __stop_reinviteid, pvt) < 0) {
7190  /* Uh Oh. Expect bad behavior. */
7191  dialog_unref(pvt, "Failed to schedule stop reinviteid action");
7192  }
7193 }
Definition: sched.c:76
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
static int __stop_reinviteid(const void *data)
Definition: chan_sip.c:7176
#define dialog_ref(dialog, tag)
when we create or delete references, make sure to use these functions so we keep track of the refcoun...
Definition: dialog.h:32
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565

◆ stop_retrans_pkt()

static void stop_retrans_pkt ( struct sip_pkt pkt)
static

Definition at line 4251 of file chan_sip.c.

References __stop_retrans_pkt(), ao2_t_ref, and ast_sched_add().

Referenced by __sip_ack(), __sip_reliable_xmit(), __sip_semi_ack(), and handle_request_cancel().

4252 {
4253  ao2_t_ref(pkt, +1, "Stop packet retransmission action");
4254  if (ast_sched_add(sched, 0, __stop_retrans_pkt, pkt) < 0) {
4255  /* Uh Oh. Expect bad behavior. */
4256  ao2_t_ref(pkt, -1, "Failed to schedule stop packet retransmission action");
4257  }
4258 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
static int __stop_retrans_pkt(const void *data)
Definition: chan_sip.c:4241
Definition: sched.c:76
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565

◆ stop_session_timer()

static void stop_session_timer ( struct sip_pvt p)
static

Session-Timers: Stop session timer.

Definition at line 30213 of file chan_sip.c.

References __stop_session_timer(), ast_sched_add(), dialog_ref, dialog_unref, FALSE, sip_st_dlg::st_active, and sip_pvt::stimer.

Referenced by __sip_scheddestroy(), handle_request_bye(), and sip_hangup().

30214 {
30215  struct sip_st_dlg *stimer = pvt->stimer;
30216 
30217  stimer->st_active = FALSE;
30218  dialog_ref(pvt, "Stop session timer action");
30219  if (ast_sched_add(sched, 0, __stop_session_timer, pvt) < 0) {
30220  /* Uh Oh. Expect bad behavior. */
30221  dialog_unref(pvt, "Failed to schedule stop session timer action");
30222  }
30223 }
#define FALSE
Definition: app_minivm.c:521
Definition: sched.c:76
int st_active
Definition: sip.h:960
static int __stop_session_timer(const void *data)
Definition: chan_sip.c:30203
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
#define dialog_ref(dialog, tag)
when we create or delete references, make sure to use these functions so we keep track of the refcoun...
Definition: dialog.h:32
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565
Structure that encapsulates all attributes related to running SIP Session-Timers feature on a per dia...
Definition: sip.h:959

◆ stop_t38_abort_timer()

static void stop_t38_abort_timer ( struct sip_pvt pvt)
static

Definition at line 26116 of file chan_sip.c.

References __stop_t38_abort_timer(), ast_sched_add(), dialog_ref, and dialog_unref.

Referenced by interpret_t38_parameters().

26117 {
26118  dialog_ref(pvt, "Stop t38id action");
26119  if (ast_sched_add(sched, 0, __stop_t38_abort_timer, pvt) < 0) {
26120  /* Uh Oh. Expect bad behavior. */
26121  dialog_unref(pvt, "Failed to schedule stop t38id action");
26122  }
26123 }
Definition: sched.c:76
static int __stop_t38_abort_timer(const void *data)
Definition: chan_sip.c:26106
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
#define dialog_ref(dialog, tag)
when we create or delete references, make sure to use these functions so we keep track of the refcoun...
Definition: dialog.h:32
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565

◆ str2dtmfmode()

static int str2dtmfmode ( const char *  str)
static

maps a string to dtmfmode, returns -1 on error

Definition at line 20604 of file chan_sip.c.

References map_s_x().

20605 {
20606  return map_s_x(dtmfstr, str, -1);
20607 }
const char * str
Definition: app_jack.c:147
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...
Definition: chan_sip.c:2426
static const struct _map_x_s dtmfstr[]
mapping between dtmf flags and strings
Definition: chan_sip.c:20588

◆ str2stmode()

static enum st_mode str2stmode ( const char *  s)
static

Definition at line 19995 of file chan_sip.c.

References map_s_x().

Referenced by build_peer(), and reload_config().

19996 {
19997  return map_s_x(stmodes, s, -1);
19998 }
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...
Definition: chan_sip.c:2426
static const struct _map_x_s stmodes[]
Report Peer status in character string.
Definition: chan_sip.c:19983

◆ str2strefresherparam()

static enum st_refresher_param str2strefresherparam ( const char *  s)
static

Definition at line 20020 of file chan_sip.c.

References map_s_x().

Referenced by build_peer(), and reload_config().

20021 {
20022  return map_s_x(strefresher_params, s, -1);
20023 }
static const struct _map_x_s strefresher_params[]
Definition: chan_sip.c:20001
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...
Definition: chan_sip.c:2426

◆ strefresher2str()

static const char* strefresher2str ( enum st_refresher  r)
static

Definition at line 20033 of file chan_sip.c.

References map_x_s().

Referenced by sip_show_channel().

20034 {
20035  return map_x_s(strefreshers, r, "Unknown");
20036 }
static const struct _map_x_s strefreshers[]
Definition: chan_sip.c:20008
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
Definition: chan_sip.c:2411

◆ strefresherparam2str()

static const char * strefresherparam2str ( enum st_refresher_param  r)
static

Definition at line 20015 of file chan_sip.c.

References map_x_s().

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

20016 {
20017  return map_x_s(strefresher_params, r, "Unknown");
20018 }
static const struct _map_x_s strefresher_params[]
Definition: chan_sip.c:20001
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
Definition: chan_sip.c:2411

◆ subscription_type2str()

static const char * subscription_type2str ( enum subscriptiontype  subtype)
static

Show subscription type in string format.

Definition at line 22117 of file chan_sip.c.

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

Referenced by show_channels_cb(), and sip_show_channel().

22118 {
22119  int i;
22120 
22121  for (i = 1; i < ARRAY_LEN(subscription_types); i++) {
22122  if (subscription_types[i].type == subtype) {
22123  return subscription_types[i].text;
22124  }
22125  }
22126  return subscription_types[0].text;
22127 }
static const char type[]
Definition: chan_ooh323.c:109
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static const struct cfsubscription_types subscription_types[]
const char *const text
Definition: chan_sip.c:718

◆ t38_get_rate()

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

13368 {
13369  switch (rate) {
13370  case AST_T38_RATE_2400:
13371  return 2400;
13372  case AST_T38_RATE_4800:
13373  return 4800;
13374  case AST_T38_RATE_7200:
13375  return 7200;
13376  case AST_T38_RATE_9600:
13377  return 9600;
13378  case AST_T38_RATE_12000:
13379  return 12000;
13380  case AST_T38_RATE_14400:
13381  return 14400;
13382  default:
13383  return 0;
13384  }
13385 }

◆ tcptls_packet_destructor()

static void tcptls_packet_destructor ( void *  obj)
static

Definition at line 2538 of file chan_sip.c.

References ast_free, and tcptls_packet::data.

Referenced by sip_tcptls_write().

2539 {
2540  struct tcptls_packet *packet = obj;
2541 
2542  ast_free(packet->data);
2543 }
struct ast_str * data
Definition: sip.h:1437
#define ast_free(a)
Definition: astmm.h:182

◆ temp_peer()

static struct sip_peer * temp_peer ( const char *  name)
static

Create temporary peer (used in autocreatepeer mode)

Definition at line 31550 of file chan_sip.c.

References ao2_t_alloc, ao2_t_ref, apeerobjs, ast_atomic_fetchadd_int(), ast_cc_config_params_init, ast_copy_string(), ast_format_cap_alloc, AST_FORMAT_CAP_FLAG_DEFAULT, ast_string_field_init, sip_peer::caps, sip_peer::cc_params, sip_peer::expire, sip_peer::host_dynamic, sip_peer::keepalivesend, sip_peer::name, NULL, sip_peer::pokeexpire, reg_source_db(), sip_peer::selfdestruct, set_peer_defaults(), sip_destroy_peer_fn(), and TRUE.

Referenced by load_module(), register_verify(), and sip_reload().

31551 {
31552  struct sip_peer *peer;
31553 
31554  if (!(peer = ao2_t_alloc(sizeof(*peer), sip_destroy_peer_fn, "allocate a peer struct")))
31555  return NULL;
31556 
31557  if (ast_string_field_init(peer, 512)) {
31558  ao2_t_ref(peer, -1, "failed to string_field_init, drop peer");
31559  return NULL;
31560  }
31561 
31562  if (!(peer->cc_params = ast_cc_config_params_init())) {
31563  ao2_t_ref(peer, -1, "failed to allocate cc_params for peer");
31564  return NULL;
31565  }
31566 
31568  ao2_t_ref(peer, -1, "failed to allocate format capabilities, drop peer");
31569  return NULL;
31570  }
31571 
31573  peer->expire = -1;
31574  peer->pokeexpire = -1;
31575  peer->keepalivesend = -1;
31576 
31577  set_peer_defaults(peer);
31578 
31579  ast_copy_string(peer->name, name, sizeof(peer->name));
31580 
31581  peer->selfdestruct = TRUE;
31582  peer->host_dynamic = TRUE;
31583  reg_source_db(peer);
31584 
31585  return peer;
31586 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
int keepalivesend
Definition: sip.h:1361
#define ao2_t_alloc(data_size, destructor_fn, debug_msg)
Definition: astobj2.h:409
static void sip_destroy_peer_fn(void *peer)
Definition: chan_sip.c:5303
static void reg_source_db(struct sip_peer *peer)
Get registration details from Asterisk DB.
Definition: chan_sip.c:16743
unsigned short host_dynamic
Definition: sip.h:1314
#define NULL
Definition: resample.c:96
#define ast_cc_config_params_init()
Allocate and initialize an ast_cc_config_params structure.
Definition: ccss.h:135
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:755
char name[80]
Definition: sip.h:1274
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:353
static void set_peer_defaults(struct sip_peer *peer)
Set peer defaults before configuring specific configurations.
Definition: chan_sip.c:31482
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
struct ast_cc_config_params * cc_params
Definition: sip.h:1377
int expire
Definition: sip.h:1341
struct ast_format_cap * caps
Definition: sip.h:1342
static int apeerobjs
Definition: chan_sip.c:881
static const char name[]
Definition: cdr_mysql.c:74
unsigned short selfdestruct
Definition: sip.h:1315
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define TRUE
Definition: app_minivm.c:518
int pokeexpire
Definition: sip.h:1355

◆ temp_pvt_cleanup()

static void temp_pvt_cleanup ( void *  data)
static

Definition at line 12591 of file chan_sip.c.

References ast_free, and ast_string_field_free_memory.

12592 {
12593  struct sip_pvt *p = data;
12594 
12596 
12597  ast_free(data);
12598 }
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
#define ast_free(a)
Definition: astmm.h:182
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:368

◆ temp_pvt_init()

static int temp_pvt_init ( void *  data)
static

Definition at line 12583 of file chan_sip.c.

References ast_string_field_init, and sip_pvt::do_history.

12584 {
12585  struct sip_pvt *p = data;
12586 
12587  p->do_history = 0; /* XXX do we need it ? isn't already all 0 ? */
12588  return ast_string_field_init(p, 512);
12589 }
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:353
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
unsigned short do_history
Definition: sip.h:1078

◆ terminate_uri()

static char* terminate_uri ( char *  uri)
static

Terminate the uri at the first ';' or space. Technically we should ignore escaped space per RFC3261 (19.1.1 etc) but don't do it for the time being. Remember the uri format is: (User-parameters was added after RFC 3261)

*
*  sip:user:password;user-parameters@host:port;uri-parameters?headers
*  sips:user:password;user-parameters@host:port;uri-parameters?headers
*
*
Todo:
As this function does not support user-parameters, it's considered broken and needs fixing.

Definition at line 17815 of file chan_sip.c.

Referenced by check_user_full(), and register_verify().

17816 {
17817  char *t = uri;
17818  while (*t && *t > ' ' && *t != ';') {
17819  t++;
17820  }
17821  *t = '\0';
17822  return uri;
17823 }
const ast_string_field uri
Definition: sip.h:1063

◆ threadinfo_locate_cb()

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

Definition at line 29523 of file chan_sip.c.

References ast_sockaddr_cmp(), CMP_MATCH, CMP_STOP, ast_tcptls_session_instance::remote_address, and sip_threadinfo::tcptls_session.

Referenced by sip_tcp_locate().

29524 {
29525  struct sip_threadinfo *th = obj;
29526  struct ast_sockaddr *s = arg;
29527 
29529  return CMP_MATCH | CMP_STOP;
29530  }
29531 
29532  return 0;
29533 }
int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares two ast_sockaddr structures.
Definition: netsock2.c:388
Socket address structure.
Definition: netsock2.h:97
Definition of a thread that handles a socket.
Definition: sip.h:1441
struct ast_tcptls_session_instance * tcptls_session
Definition: sip.h:1446
struct ast_sockaddr remote_address
Definition: tcptls.h:151

◆ threadt_cmp_cb()

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

Definition at line 34613 of file chan_sip.c.

References CMP_MATCH, CMP_STOP, and sip_threadinfo::tcptls_session.

Referenced by load_module().

34614 {
34615  struct sip_threadinfo *th = obj, *th2 = arg;
34616 
34617  return (th->tcptls_session == th2->tcptls_session) ? CMP_MATCH | CMP_STOP : 0;
34618 }
Definition of a thread that handles a socket.
Definition: sip.h:1441
struct ast_tcptls_session_instance * tcptls_session
Definition: sip.h:1446

◆ threadt_hash_cb()

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

Definition at line 34606 of file chan_sip.c.

References ast_sockaddr_hash(), ast_tcptls_session_instance::remote_address, and sip_threadinfo::tcptls_session.

Referenced by load_module().

34607 {
34608  const struct sip_threadinfo *th = obj;
34609 
34611 }
Definition of a thread that handles a socket.
Definition: sip.h:1441
int ast_sockaddr_hash(const struct ast_sockaddr *addr)
Computes a hash value from the address. The port is ignored.
Definition: netsock2.c:548
struct ast_tcptls_session_instance * tcptls_session
Definition: sip.h:1446
struct ast_sockaddr remote_address
Definition: tcptls.h:151

◆ transfermode2str()

static char * transfermode2str ( enum transfermodes  mode)
static

Convert transfer mode to text string.

Definition at line 19968 of file chan_sip.c.

References TRANSFER_CLOSED, and TRANSFER_OPENFORALL.

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

19969 {
19970  if (mode == TRANSFER_OPENFORALL)
19971  return "open";
19972  else if (mode == TRANSFER_CLOSED)
19973  return "closed";
19974  return "strict";
19975 }

◆ transmit_cc_notify()

static int transmit_cc_notify ( struct ast_cc_agent agent,
struct sip_pvt subscription,
enum sip_cc_notify_state  state 
)
static

Definition at line 15446 of file chan_sip.c.

References add_content(), add_header(), ast_log, CC_READY, sip_pvt::expiry, generate_uri(), LOG_WARNING, sip_cc_agent_pvt::notify_uri, sip_pvt::ocseq, ast_cc_agent::private_data, reqprep(), send_request(), sip_cc_notify_state_map, SIP_NOTIFY, SIPBUFSIZE, state_string, TRUE, and XMIT_RELIABLE.

Referenced by sip_cc_agent_recall(), and sip_cc_agent_respond().

15447 {
15448  struct sip_request req;
15449  struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
15450  char uri[SIPBUFSIZE + sizeof("cc-URI: \r\n") - 1];
15451  char state_str[64];
15452  char subscription_state_hdr[64];
15453 
15455  ast_log(LOG_WARNING, "Invalid state provided for transmit_cc_notify (%u)\n", state);
15456  return -1;
15457  }
15458 
15459  reqprep(&req, subscription, SIP_NOTIFY, 0, TRUE);
15460  snprintf(state_str, sizeof(state_str), "%s\r\n", sip_cc_notify_state_map[state].state_string);
15461  add_header(&req, "Event", "call-completion");
15462  add_header(&req, "Content-Type", "application/call-completion");
15463  snprintf(subscription_state_hdr, sizeof(subscription_state_hdr), "active;expires=%d", subscription->expiry);
15464  add_header(&req, "Subscription-State", subscription_state_hdr);
15465  if (state == CC_READY) {
15466  generate_uri(subscription, agent_pvt->notify_uri, sizeof(agent_pvt->notify_uri));
15467  snprintf(uri, sizeof(uri), "cc-URI: %s\r\n", agent_pvt->notify_uri);
15468  }
15469  add_content(&req, state_str);
15470  if (state == CC_READY) {
15471  add_content(&req, uri);
15472  }
15473  return send_request(subscription, &req, XMIT_RELIABLE, subscription->ocseq);
15474 }
Definition: sip.h:1556
void * private_data
Definition: ccss.h:871
static const struct @131 sip_cc_notify_state_map[]
#define LOG_WARNING
Definition: logger.h:274
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)
Definition: chan_sip.c:12361
#define ast_log
Definition: astobj2.c:42
int expiry
Definition: sip.h:1118
static char * generate_uri(struct sip_pvt *pvt, char *buf, size_t size)
Definition: chan_sip.c:8809
Structure representing an agent.
#define SIPBUFSIZE
Definition: sip.h:56
static int send_request(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno)
Definition: chan_sip.c:4863
uint32_t ocseq
Definition: sip.h:1067
char notify_uri[SIPBUFSIZE]
Definition: sip.h:1802
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
#define TRUE
Definition: app_minivm.c:518
const char * state_string
Definition: chan_sip.c:960
static int add_content(struct sip_request *req, const char *line)
Add content (not header) to SIP message.
Definition: chan_sip.c:11931
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873

◆ transmit_fake_auth_response()

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

References __transmit_response(), AST_DYNSTR_BUILD_FAILED, ast_skip_blanks(), ast_str_buffer(), ast_str_set(), ast_str_thread_get(), ast_strlen_zero, buf, build_nonce(), c, check_auth_buf, CHECK_AUTH_BUF_INITLEN, DEFAULT_TRANS_TIMEOUT, FALSE, sip_request::ignore, sip_pvt::initreq, K_LAST, K_NONCE, sip_pvt::nonce, NULL, sip_get_header(), sip_scheddestroy(), strsep(), and transmit_response_with_auth().

Referenced by register_verify().

17715 {
17716  /* We have to emulate EXACTLY what we'd get with a good peer
17717  * and a bad password, or else we leak information. */
17718  const char *response = "401 Unauthorized";
17719  const char *reqheader = "Authorization";
17720  const char *respheader = "WWW-Authenticate";
17721  const char *authtoken;
17722  struct ast_str *buf;
17723  char *c;
17724 
17725  /* table of recognised keywords, and their value in the digest */
17726  enum keys { K_NONCE, K_LAST };
17727  struct x {
17728  const char *key;
17729  const char *s;
17730  } *i, keys[] = {
17731  [K_NONCE] = { "nonce=", "" },
17732  [K_LAST] = { NULL, NULL}
17733  };
17734 
17735  authtoken = sip_get_header(req, reqheader);
17736  if (req->ignore && !ast_strlen_zero(p->nonce) && ast_strlen_zero(authtoken)) {
17737  /* This is a retransmitted invite/register/etc, don't reconstruct authentication
17738  * information */
17739  transmit_response_with_auth(p, response, req, p->nonce, reliable, respheader, 0);
17740  /* Schedule auto destroy in 32 seconds (according to RFC 3261) */
17742  return;
17743  } else if (ast_strlen_zero(p->nonce) || ast_strlen_zero(authtoken)) {
17744  /* We have no auth, so issue challenge and request authentication */
17745  build_nonce(p, 1);
17746  transmit_response_with_auth(p, response, req, p->nonce, reliable, respheader, 0);
17747  /* Schedule auto destroy in 32 seconds */
17749  return;
17750  }
17751 
17753  __transmit_response(p, "403 Forbidden", &p->initreq, reliable);
17754  return;
17755  }
17756 
17757  /* Make a copy of the response and parse it */
17758  if (ast_str_set(&buf, 0, "%s", authtoken) == AST_DYNSTR_BUILD_FAILED) {
17759  __transmit_response(p, "403 Forbidden", &p->initreq, reliable);
17760  return;
17761  }
17762 
17763  c = ast_str_buffer(buf);
17764 
17765  while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */
17766  for (i = keys; i->key != NULL; i++) {
17767  const char *separator = ","; /* default */
17768 
17769  if (strncasecmp(c, i->key, strlen(i->key)) != 0) {
17770  continue;
17771  }
17772  /* Found. Skip keyword, take text in quotes or up to the separator. */
17773  c += strlen(i->key);
17774  if (*c == '"') { /* in quotes. Skip first and look for last */
17775  c++;
17776  separator = "\"";
17777  }
17778  i->s = c;
17779  strsep(&c, separator);
17780  break;
17781  }
17782  if (i->key == NULL) { /* not found, jump after space or comma */
17783  strsep(&c, " ,");
17784  }
17785  }
17786 
17787  /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */
17788  if (strcasecmp(p->nonce, keys[K_NONCE].s)) {
17789  if (!req->ignore) {
17790  build_nonce(p, 1);
17791  }
17792  transmit_response_with_auth(p, response, req, p->nonce, reliable, respheader, FALSE);
17793 
17794  /* Schedule auto destroy in 32 seconds */
17796  } else {
17797  __transmit_response(p, "403 Forbidden", &p->initreq, reliable);
17798  }
17799 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
#define FALSE
Definition: app_minivm.c:521
static struct ast_threadstorage check_auth_buf
Definition: sip.h:1883
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define DEFAULT_TRANS_TIMEOUT
Definition: sip.h:107
static struct test_val c
#define NULL
Definition: resample.c:96
const ast_string_field nonce
Definition: sip.h:1063
#define ast_strlen_zero(foo)
Definition: strings.h:52
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
struct sip_request initreq
Definition: sip.h:1151
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
Definition: sip.h:707
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
static int __transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable)
Base transmit response function.
Definition: chan_sip.c:12511
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)
Respond with authorization request.
Definition: chan_sip.c:12754
char * strsep(char **str, const char *delims)
static void build_nonce(struct sip_pvt *p, int forceupdate)
builds the sip_pvt&#39;s nonce field which is used for the authentication challenge. When forceupdate is ...
Definition: chan_sip.c:17300
char ignore
Definition: sip.h:839
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
Definition: strings.h:861
#define CHECK_AUTH_BUF_INITLEN
Definition: sip.h:401
void sip_scheddestroy(struct sip_pvt *p, int ms)
Schedule destruction of SIP dialog.
Definition: chan_sip.c:4549
Definition: sip.h:706

◆ transmit_info_with_aoc()

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 16462 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, sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, str, and XMIT_RELIABLE.

Referenced by sip_indicate().

16463 {
16464  struct sip_request req;
16465  struct ast_str *str = ast_str_alloca(512);
16466  const struct ast_aoc_unit_entry *unit_entry = ast_aoc_get_unit_info(decoded, 0);
16467  enum ast_aoc_charge_type charging = ast_aoc_get_charge_type(decoded);
16468 
16469  reqprep(&req, p, SIP_INFO, 0, 1);
16470 
16471  if (ast_aoc_get_msg_type(decoded) == AST_AOC_D) {
16472  ast_str_append(&str, 0, "type=active;");
16473  } else if (ast_aoc_get_msg_type(decoded) == AST_AOC_E) {
16474  ast_str_append(&str, 0, "type=terminated;");
16475  } else {
16476  /* unsupported message type */
16477  return -1;
16478  }
16479 
16480  switch (charging) {
16481  case AST_AOC_CHARGE_FREE:
16482  ast_str_append(&str, 0, "free-of-charge;");
16483  break;
16485  ast_str_append(&str, 0, "charging;");
16486  ast_str_append(&str, 0, "charging-info=currency;");
16487  ast_str_append(&str, 0, "amount=%u;", ast_aoc_get_currency_amount(decoded));
16488  ast_str_append(&str, 0, "multiplier=%s;", ast_aoc_get_currency_multiplier_decimal(decoded));
16489  if (!ast_strlen_zero(ast_aoc_get_currency_name(decoded))) {
16490  ast_str_append(&str, 0, "currency=%s;", ast_aoc_get_currency_name(decoded));
16491  }
16492  break;
16493  case AST_AOC_CHARGE_UNIT:
16494  ast_str_append(&str, 0, "charging;");
16495  ast_str_append(&str, 0, "charging-info=pulse;");
16496  if (unit_entry) {
16497  ast_str_append(&str, 0, "recorded-units=%u;", unit_entry->amount);
16498  }
16499  break;
16500  default:
16501  ast_str_append(&str, 0, "not-available;");
16502  };
16503 
16504  add_header(&req, "AOC", ast_str_buffer(str));
16505 
16506  return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
16507 }
Definition: sip.h:626
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
#define ast_str_alloca(init_len)
Definition: strings.h:800
const char * str
Definition: app_jack.c:147
const char * ast_aoc_get_currency_multiplier_decimal(struct ast_aoc_decoded *decoded)
get the currency multiplier for AOC-D and AOC-E messages in decimal format
Definition: aoc.c:950
#define ast_strlen_zero(foo)
Definition: strings.h:52
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)
Definition: chan_sip.c:12361
ast_aoc_charge_type
Definition: aoc.h:69
unsigned int ast_aoc_get_currency_amount(struct ast_aoc_decoded *decoded)
get the currency amount for AOC-D and AOC-E messages
Definition: aoc.c:940
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
const struct ast_aoc_unit_entry * ast_aoc_get_unit_info(struct ast_aoc_decoded *decoded, unsigned int entry_number)
get a specific unit entry.
Definition: aoc.c:1010
static int send_request(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno)
Definition: chan_sip.c:4863
uint32_t ocseq
Definition: sip.h:1067
const char * ast_aoc_get_currency_name(struct ast_aoc_decoded *decoded)
get the currency name for AOC-D and AOC-E messages
Definition: aoc.c:972
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
enum ast_aoc_charge_type ast_aoc_get_charge_type(struct ast_aoc_decoded *decoded)
get the charging type for an AOC-D or AOC-E message
Definition: aoc.c:897
Definition: aoc.h:66
enum ast_aoc_type ast_aoc_get_msg_type(struct ast_aoc_decoded *decoded)
get the message type, AOC-D, AOC-E, or AOC Request
Definition: aoc.c:892
Definition: aoc.h:178
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873
unsigned int amount
Definition: aoc.h:180
Definition: aoc.h:65

◆ transmit_info_with_digit()

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

References add_digit(), ast_test_flag, sip_pvt::flags, sip_pvt::ocseq, reqprep(), send_request(), SIP_DTMF, SIP_DTMF_SHORTINFO, SIP_INFO, and XMIT_RELIABLE.

Referenced by sip_senddigit_end().

16511 {
16512  struct sip_request req;
16513 
16514  reqprep(&req, p, SIP_INFO, 0, 1);
16515  add_digit(&req, digit, duration, (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_SHORTINFO));
16516  return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
16517 }
Definition: sip.h:626
char digit
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_flags flags[3]
Definition: sip.h:1075
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)
Definition: chan_sip.c:12361
#define SIP_DTMF_SHORTINFO
Definition: sip.h:280
static int send_request(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno)
Definition: chan_sip.c:4863
uint32_t ocseq
Definition: sip.h:1067
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
#define SIP_DTMF
Definition: sip.h:275
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...
Definition: chan_sip.c:12960

◆ transmit_info_with_vidupdate()

static int transmit_info_with_vidupdate ( struct sip_pvt p)
static

Send SIP INFO with video update request.

Definition at line 16520 of file chan_sip.c.

References add_vidupdate(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.

Referenced by sip_indicate().

16521 {
16522  struct sip_request req;
16523 
16524  reqprep(&req, p, SIP_INFO, 0, 1);
16525  add_vidupdate(&req);
16526  return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
16527 }
Definition: sip.h:626
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)
Definition: chan_sip.c:12361
static int send_request(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno)
Definition: chan_sip.c:4863
uint32_t ocseq
Definition: sip.h:1067
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
static int add_vidupdate(struct sip_request *req)
add XML encoded media control with update
Definition: chan_sip.c:13111

◆ transmit_invite()

static int transmit_invite ( struct sip_pvt p,
int  sipmethod,
int  sdp,
int  init,
const char *const  explicit_uri 
)
static

Build REFER/INVITE/OPTIONS/SUBSCRIBE message and transmit it.

Parameters
psip_pvt structure
sipmethod
sdpunknown
init0 = 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 14755 of file chan_sip.c.

References add_content(), add_date(), add_diversion(), add_expires(), add_header(), add_rpid(), add_sdp(), add_supported(), sip_invite_param::addsipheaders, ALLOWED_METHODS, ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_channel_varshead(), 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(), sip_invite_param::auth, sip_invite_param::authheader, sip_epa_entry::body, sip_pvt::branch, build_via(), CALL_COMPLETION, sip_notify::content, DEFAULT_MIN_SE, end, sip_epa_entry::entity_tag, sip_pvt::epa_entry, epa_static_data::event, sip_pvt::expiry, FALSE, sip_pvt::flags, global_refer_addheaders, sip_request::headers, sip_notify::headers, initialize_initreq(), sip_pvt::initreq, initreqprep(), sip_pvt::invite_branch, sip_pvt::lastinvite, LOG_WARNING, MWI_NOTIFICATION, ast_variable::name, ast_variable::next, sip_pvt::notify, sip_pvt::ocseq, offered_media_list_destroy(), sip_pvt::options, sip_pvt::owner, sip_epa_entry::publish_type, sip_pvt::refer, sip_refer::refer_to, sip_refer::referred_by, sip_invite_param::replaces, reqprep(), sip_pvt::rtp, send_request(), SESSION_TIMER_MODE_ACCEPT, SESSION_TIMER_MODE_ORIGINATE, sip_get_header(), SIP_INVITE, SIP_NOTIFY, SIP_PUBLISH, SIP_PUBLISH_INITIAL, SIP_REFER, SIP_SENDRPID, SIP_SUBSCRIBE, SIP_UPDATE, sipdebug, sip_st_dlg::st_active, st_get_mode(), st_get_se(), sip_st_dlg::st_interval, t38properties::state, sip_epa_entry::static_data, sip_pvt::stimer, sip_pvt::subscribed, sip_pvt::t38, T38_LOCAL_REINVITE, TRUE, try_suggested_sip_codec(), sip_pvt::udptl, ast_variable::value, var, XMIT_CRITICAL, and XMIT_RELIABLE.

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(), transmit_publish(), and transmit_refer().

14756 {
14757  struct sip_request req;
14758  struct ast_variable *var;
14759 
14760  if (init) {/* Bump branch even on initial requests */
14761  p->branch ^= ast_random();
14762  p->invite_branch = p->branch;
14763  build_via(p);
14764  }
14765  if (init > 1) {
14766  initreqprep(&req, p, sipmethod, explicit_uri);
14767  } else {
14768  /* If init=1, we should not generate a new branch. If it's 0, we need a new branch. */
14769  reqprep(&req, p, sipmethod, 0, init ? 0 : 1);
14770  }
14771 
14772  if (p->options && p->options->auth) {
14773  add_header(&req, p->options->authheader, p->options->auth);
14774  }
14775  add_date(&req);
14776  if (sipmethod == SIP_REFER && p->refer) { /* Call transfer */
14777  if (!ast_strlen_zero(p->refer->refer_to)) {
14778  add_header(&req, "Refer-To", p->refer->refer_to);
14779  }
14780  if (!ast_strlen_zero(p->refer->referred_by)) {
14781  add_header(&req, "Referred-By", p->refer->referred_by);
14782  }
14783  } else if (sipmethod == SIP_SUBSCRIBE) {
14784  if (p->subscribed == MWI_NOTIFICATION) {
14785  add_header(&req, "Event", "message-summary");
14786  add_header(&req, "Accept", "application/simple-message-summary");
14787  } else if (p->subscribed == CALL_COMPLETION) {
14788  add_header(&req, "Event", "call-completion");
14789  add_header(&req, "Accept", "application/call-completion");
14790  }
14791  add_expires(&req, p->expiry);
14792  }
14793 
14794  /* This new INVITE is part of an attended transfer. Make sure that the
14795  other end knows and replace the current call with this new call */
14796  if (p->options && !ast_strlen_zero(p->options->replaces)) {
14797  add_header(&req, "Replaces", p->options->replaces);
14798  add_header(&req, "Require", "replaces");
14799  }
14800 
14801  /* Add Session-Timers related headers if not already there */
14802  if (ast_strlen_zero(sip_get_header(&req, "Session-Expires")) &&
14806  && st_get_se(p, FALSE) != DEFAULT_MIN_SE))) {
14807  char i2astr[10];
14808 
14809  if (!p->stimer->st_interval) {
14810  p->stimer->st_interval = st_get_se(p, TRUE);
14811  }
14812 
14813  p->stimer->st_active = TRUE;
14815  snprintf(i2astr, sizeof(i2astr), "%d", p->stimer->st_interval);
14816  add_header(&req, "Session-Expires", i2astr);
14817  }
14818 
14819  snprintf(i2astr, sizeof(i2astr), "%d", st_get_se(p, FALSE));
14820  add_header(&req, "Min-SE", i2astr);
14821  }
14822 
14823  add_header(&req, "Allow", ALLOWED_METHODS);
14824  add_supported(p, &req);
14825 
14826  if (p->owner && ((p->options && p->options->addsipheaders)
14827  || (p->refer && global_refer_addheaders))) {
14828  struct ast_channel *chan = p->owner; /* The owner channel */
14829  struct varshead *headp;
14830 
14831  ast_channel_lock(chan);
14832 
14833  headp = ast_channel_varshead(chan);
14834 
14835  if (!headp) {
14836  ast_log(LOG_WARNING, "No Headp for the channel...ooops!\n");
14837  } else {
14838  const struct ast_var_t *current;
14839  AST_LIST_TRAVERSE(headp, current, entries) {
14840  /* SIPADDHEADER: Add SIP header to outgoing call */
14841  if (!strncmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) {
14842  char *content, *end;
14843  const char *header = ast_var_value(current);
14844  char *headdup = ast_strdupa(header);
14845 
14846  /* Strip of the starting " (if it's there) */
14847  if (*headdup == '"') {
14848  headdup++;
14849  }
14850  if ((content = strchr(headdup, ':'))) {
14851  *content++ = '\0';
14852  content = ast_skip_blanks(content); /* Skip white space */
14853  /* Strip the ending " (if it's there) */
14854  end = content + strlen(content) -1;
14855  if (*end == '"') {
14856  *end = '\0';
14857  }
14858 
14859  add_header(&req, headdup, content);
14860  if (sipdebug) {
14861  ast_debug(1, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content);
14862  }
14863  }
14864  }
14865  }
14866  }
14867 
14868  ast_channel_unlock(chan);
14869  }
14871  add_rpid(&req, p);
14872  if (sipmethod == SIP_INVITE) {
14873  add_diversion(&req, p);
14874  }
14875  if (sdp) {
14877  if (p->udptl && p->t38.state == T38_LOCAL_REINVITE) {
14878  ast_debug(1, "T38 is in state %u on channel %s\n", p->t38.state, p->owner ? ast_channel_name(p->owner) : "<none>");
14879  add_sdp(&req, p, FALSE, FALSE, TRUE);
14880  } else if (p->rtp) {
14882  add_sdp(&req, p, FALSE, TRUE, FALSE);
14883  }
14884  } else if (sipmethod == SIP_NOTIFY && p->notify) {
14885  for (var = p->notify->headers; var; var = var->next) {
14886  add_header(&req, var->name, var->value);
14887  }
14888  if (ast_str_strlen(p->notify->content)) {
14890  }
14891  } else if (sipmethod == SIP_PUBLISH) {
14892  switch (p->epa_entry->static_data->event) {
14893  case CALL_COMPLETION:
14894  add_header(&req, "Event", "call-completion");
14895  add_expires(&req, p->expiry);
14897  add_header(&req, "SIP-If-Match", p->epa_entry->entity_tag);
14898  }
14899 
14900  if (!ast_strlen_zero(p->epa_entry->body)) {
14901  add_header(&req, "Content-Type", "application/pidf+xml");
14902  add_content(&req, p->epa_entry->body);
14903  }
14904  default:
14905  break;
14906  }
14907  }
14908 
14909  if (!p->initreq.headers || init > 2) {
14910  initialize_initreq(p, &req);
14911  }
14913  p->lastinvite = p->ocseq;
14914  }
14915  return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq);
14916 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
enum sip_publish_type publish_type
Definition: sip.h:1649
struct ast_variable * next
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
enum subscriptiontype subscribed
Definition: sip.h:1161
#define FALSE
Definition: app_minivm.c:521
static void build_via(struct sip_pvt *p)
Build a Via header for a request.
Definition: chan_sip.c:3847
struct ast_str * content
Definition: sip.h:953
enum t38state state
Definition: sip.h:917
#define ast_test_flag(p, flag)
Definition: utils.h:63
const char * ast_var_value(const struct ast_var_t *var)
Definition: chanvars.c:80
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.
Definition: chan_sip.c:14410
enum subscriptiontype event
Definition: sip.h:1616
const char * ast_var_name(const struct ast_var_t *var)
Definition: chanvars.c:60
#define LOG_WARNING
Definition: logger.h:274
const struct epa_static_data * static_data
Definition: sip.h:1674
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
static void add_expires(struct sip_request *req, int expires)
Add Expires header to SIP message.
Definition: chan_sip.c:12706
int addsipheaders
Definition: sip.h:862
Structure for variables, used for configurations and for channel variables.
static int add_supported(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.
Definition: chan_sip.c:11859
#define var
Definition: ast_expr2f.c:614
static void add_date(struct sip_request *req)
Add date header to SIP message.
Definition: chan_sip.c:12694
struct ast_flags flags[3]
Definition: sip.h:1075
int st_active
Definition: sip.h:960
struct varshead * ast_channel_varshead(struct ast_channel *chan)
char * end
Definition: eagi_proxy.c:73
static enum st_mode st_get_mode(struct sip_pvt *, int no_cached)
Get the session-timer mode.
Definition: chan_sip.c:30447
struct t38properties t38
Definition: sip.h:1113
struct sip_invite_param * options
Definition: sip.h:1183
#define ast_strlen_zero(foo)
Definition: strings.h:52
int st_interval
Definition: sip.h:961
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)
Definition: chan_sip.c:12361
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static unsigned char global_refer_addheaders
Definition: chan_sip.c:863
static void offered_media_list_destroy(struct sip_pvt *p)
Destroy SDP media offer list.
Definition: chan_sip.c:6663
struct sip_request initreq
Definition: sip.h:1151
long branch
Definition: sip.h:1121
long int ast_random(void)
Definition: main/utils.c:2064
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
const ast_string_field refer_to
Definition: sip.h:944
#define DEFAULT_MIN_SE
Definition: sip.h:120
struct sip_epa_entry * epa_entry
Definition: sip.h:1219
int expiry
Definition: sip.h:1118
struct ast_udptl * udptl
Definition: sip.h:1115
sipmethod
SIP Request methods known by Asterisk.
Definition: sip.h:612
char entity_tag[SIPBUFSIZE]
Definition: sip.h:1655
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.
Definition: chan_sip.c:13542
const ast_string_field referred_by
Definition: sip.h:944
const char * replaces
Definition: sip.h:868
struct sip_st_dlg * stimer
Definition: sip.h:1184
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...
Definition: chan_sip.c:3444
static void try_suggested_sip_codec(struct sip_pvt *p)
Try setting the codecs suggested by the SIP_CODEC channel variable.
Definition: chan_sip.c:7405
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
static int send_request(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno)
Definition: chan_sip.c:4863
uint32_t ocseq
Definition: sip.h:1067
int headers
Definition: sip.h:832
#define ALLOWED_METHODS
SIP Methods we support.
Definition: sip.h:173
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_channel_unlock(chan)
Definition: channel.h:2946
char body[SIPBUFSIZE]
Definition: sip.h:1668
struct ast_var_t::@249 entries
struct ast_channel * owner
Definition: sip.h:1138
struct ast_rtp_instance * rtp
Definition: sip.h:1174
static int add_rpid(struct sip_request *req, struct sip_pvt *p)
Add Remote-Party-ID header to SIP message.
Definition: chan_sip.c:12996
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
struct sip_refer * refer
Definition: sip.h:1160
struct ast_variable * headers
Definition: sip.h:952
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
static void add_diversion(struct sip_request *req, struct sip_pvt *pvt)
Add "Diversion" header to outgoing message.
Definition: chan_sip.c:14653
Definition: sip.h:622
const char * ast_channel_name(const struct ast_channel *chan)
#define TRUE
Definition: app_minivm.c:518
uint32_t lastinvite
Definition: sip.h:1074
char * authheader
Definition: sip.h:866
Initial.
Definition: sip.h:1581
static int add_content(struct sip_request *req, const char *line)
Add content (not header) to SIP message.
Definition: chan_sip.c:11931
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873
static int st_get_se(struct sip_pvt *, int max)
Get Max or Min SE (session timer expiry)
Definition: chan_sip.c:30393
long invite_branch
Definition: sip.h:1122
char * auth
Definition: sip.h:865
struct sip_notify * notify
Definition: sip.h:1140
#define SIP_SENDRPID
Definition: sip.h:306

◆ transmit_message()

static int transmit_message ( struct sip_pvt p,
int  init,
int  auth 
)
static

Transmit with SIP MESSAGE method.

Note
The p->msg_headers and p->msg_body are already setup.

Definition at line 16351 of file chan_sip.c.

References add_text(), initialize_initreq(), initreqprep(), NULL, sip_pvt::ocseq, reqprep(), send_request(), SIP_MESSAGE, transmit_request_with_auth(), and XMIT_RELIABLE.

Referenced by do_message_auth(), sip_msg_send(), and sip_sendtext().

16352 {
16353  struct sip_request req;
16354 
16355  if (init) {
16356  initreqprep(&req, p, SIP_MESSAGE, NULL);
16357  initialize_initreq(p, &req);
16358  } else {
16359  reqprep(&req, p, SIP_MESSAGE, 0, 1);
16360  }
16361  if (auth) {
16363  } else {
16364  add_text(&req, p);
16365  return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
16366  }
16367 }
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.
Definition: chan_sip.c:16564
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.
Definition: chan_sip.c:14410
#define NULL
Definition: resample.c:96
static int add_text(struct sip_request *req, struct sip_pvt *p)
Add text body to SIP message.
Definition: chan_sip.c:12931
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)
Definition: chan_sip.c:12361
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...
Definition: chan_sip.c:3444
static int send_request(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno)
Definition: chan_sip.c:4863
uint32_t ocseq
Definition: sip.h:1067
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829

◆ transmit_notify_with_mwi()

static int transmit_notify_with_mwi ( struct sip_pvt p,
int  newmsgs,
int  oldmsgs,
const char *  vmexten 
)
static

Notify user of messages waiting in voicemail (RFC3842)

Note
- Notification only works for registered peers with mailbox= definitions in sip.conf
  • We use the SIP Event package message-summary MIME type defaults to "application/simple-message-summary";

Definition at line 15584 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, AST_TRANSPORT_UDP, default_notifymime, default_vmexten, sip_pvt::expiry, exten, sip_pvt::flags, sip_pvt::fromdomain, sip_pvt::fromdomainport, sip_request::headers, initialize_initreq(), sip_pvt::initreq, initreqprep(), NULL, sip_pvt::ocseq, sip_pvt::ourip, ourport, out, S_OR, send_request(), sip_get_transport(), SIP_NOTIFY, SIP_PAGE2_BUGGY_MWI, sip_standard_port(), sip_pvt::socket, STANDARD_SIP_PORT, sip_pvt::subscribed, sip_socket::type, and XMIT_RELIABLE.

Referenced by sip_send_mwi_to_peer().

15585 {
15586  struct sip_request req;
15587  struct ast_str *out = ast_str_alloca(500);
15589  const char *domain;
15590  const char *exten = S_OR(vmexten, default_vmexten);
15591 
15592  initreqprep(&req, p, SIP_NOTIFY, NULL);
15593  add_header(&req, "Event", "message-summary");
15594  add_header(&req, "Content-Type", default_notifymime);
15595  ast_str_append(&out, 0, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no");
15596 
15597  /* domain initialization occurs here because initreqprep changes ast_sockaddr_stringify string. */
15599 
15600  if (!sip_standard_port(p->socket.type, ourport)) {
15601  if (p->socket.type == AST_TRANSPORT_UDP) {
15602  ast_str_append(&out, 0, "Message-Account: sip:%s@%s:%d\r\n", exten, domain, ourport);
15603  } else {
15604  ast_str_append(&out, 0, "Message-Account: sip:%s@%s:%d;transport=%s\r\n", exten, domain, ourport, sip_get_transport(p->socket.type));
15605  }
15606  } else {
15607  if (p->socket.type == AST_TRANSPORT_UDP) {
15608  ast_str_append(&out, 0, "Message-Account: sip:%s@%s\r\n", exten, domain);
15609  } else {
15610  ast_str_append(&out, 0, "Message-Account: sip:%s@%s;transport=%s\r\n", exten, domain, sip_get_transport(p->socket.type));
15611  }
15612  }
15613  /* Cisco has a bug in the SIP stack where it can't accept the
15614  (0/0) notification. This can temporarily be disabled in
15615  sip.conf with the "buggymwi" option */
15616  ast_str_append(&out, 0, "Voice-Message: %d/%d%s\r\n",
15617  newmsgs, oldmsgs, (ast_test_flag(&p->flags[1], SIP_PAGE2_BUGGY_MWI) ? "" : " (0/0)"));
15618 
15619  if (p->subscribed) {
15620  if (p->expiry) {
15621  add_header(&req, "Subscription-State", "active");
15622  } else { /* Expired */
15623  add_header(&req, "Subscription-State", "terminated;reason=timeout");
15624  }
15625  }
15626 
15627  add_content(&req, ast_str_buffer(out));
15628 
15629  if (!p->initreq.headers) {
15630  initialize_initreq(p, &req);
15631  }
15632  return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
15633 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
enum subscriptiontype subscribed
Definition: sip.h:1161
int fromdomainport
Definition: sip.h:1220
#define ast_test_flag(p, flag)
Definition: utils.h:63
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.
Definition: chan_sip.c:14410
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
struct sip_socket socket
Definition: sip.h:1066
const char * sip_get_transport(enum ast_transport t)
Return transport as string.
Definition: chan_sip.c:3725
struct ast_sockaddr ourip
Definition: sip.h:1136
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
struct ast_flags flags[3]
Definition: sip.h:1075
#define ast_str_alloca(init_len)
Definition: strings.h:800
#define NULL
Definition: resample.c:96
Domain data structure.
Definition: sip.h:888
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:521
#define STANDARD_SIP_PORT
Standard SIP unsecure port for UDP and TCP from RFC 3261. DO NOT CHANGE THIS.
Definition: sip.h:176
static int sip_standard_port(enum ast_transport type, int port)
Returns the port to use for this socket.
Definition: chan_sip.c:29515
struct sip_request initreq
Definition: sip.h:1151
const ast_string_field fromdomain
Definition: sip.h:1063
int expiry
Definition: sip.h:1118
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
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...
Definition: chan_sip.c:3444
static int send_request(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno)
Definition: chan_sip.c:4863
uint32_t ocseq
Definition: sip.h:1067
int headers
Definition: sip.h:832
static char * ast_sockaddr_stringify_host_remote(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only, suitable for a URL (with brack...
Definition: netsock2.h:349
#define SIP_PAGE2_BUGGY_MWI
Definition: sip.h:357
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
FILE * out
Definition: utils/frame.c:33
enum ast_transport type
Definition: sip.h:798
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
static char default_vmexten[AST_MAX_EXTENSION]
Definition: chan_sip.c:796
static char default_notifymime[AST_MAX_EXTENSION]
Definition: chan_sip.c:795
static int add_content(struct sip_request *req, const char *line)
Add content (not header) to SIP message.
Definition: chan_sip.c:11931
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873
static int ourport
Definition: chan_mgcp.c:240
static char vmexten[AST_MAX_EXTENSION]
Definition: chan_skinny.c:206

◆ transmit_notify_with_sipfrag()

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

References add_content(), add_header(), add_supported(), ALLOWED_METHODS, sip_request::headers, initialize_initreq(), sip_pvt::initreq, sip_pvt::ocseq, reqprep(), send_request(), SIP_NOTIFY, SIPBUFSIZE, tmp(), and XMIT_RELIABLE.

Referenced by handle_request_refer(), and local_attended_transfer().

15637 {
15638  struct sip_request req;
15639  char tmp[SIPBUFSIZE/2];
15640 
15641  reqprep(&req, p, SIP_NOTIFY, 0, 1);
15642  snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq);
15643  add_header(&req, "Event", tmp);
15644  add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active");
15645  add_header(&req, "Content-Type", "message/sipfrag;version=2.0");
15646  add_header(&req, "Allow", ALLOWED_METHODS);
15647  add_supported(p, &req);
15648 
15649  snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message);
15650  add_content(&req, tmp);
15651 
15652  if (!p->initreq.headers) {
15653  initialize_initreq(p, &req);
15654  }
15655 
15656  return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
15657 }
static int tmp()
Definition: bt_open.c:389
static int add_supported(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.
Definition: chan_sip.c:11859
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)
Definition: chan_sip.c:12361
struct sip_request initreq
Definition: sip.h:1151
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...
Definition: chan_sip.c:3444
#define SIPBUFSIZE
Definition: sip.h:56
static int send_request(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno)
Definition: chan_sip.c:4863
uint32_t ocseq
Definition: sip.h:1067
int headers
Definition: sip.h:832
#define ALLOWED_METHODS
SIP Methods we support.
Definition: sip.h:173
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
static int add_content(struct sip_request *req, const char *line)
Add content (not header) to SIP message.
Definition: chan_sip.c:11931
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873

◆ transmit_provisional_response()

static int transmit_provisional_response ( struct sip_pvt p,
const char *  msg,
const struct sip_request req,
int  with_sdp 
)
static

Definition at line 12867 of file chan_sip.c.

References FALSE, sip_pvt::last_provisional, transmit_response(), transmit_response_with_sdp(), update_provisional_keepalive(), and XMIT_UNRELIABLE.

Referenced by handle_request_invite(), sip_indicate(), and sip_write().

12868 {
12869  int res;
12870 
12871  if (!(res = with_sdp ? transmit_response_with_sdp(p, msg, req, XMIT_UNRELIABLE, FALSE, FALSE) : transmit_response(p, msg, req))) {
12872  p->last_provisional = msg;
12873  update_provisional_keepalive(p, with_sdp);
12874  }
12875 
12876  return res;
12877 }
const char * last_provisional
Definition: sip.h:1110
#define FALSE
Definition: app_minivm.c:521
static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req)
Transmit response, no retransmits.
Definition: chan_sip.c:12655
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.
Definition: chan_sip.c:14125
static void update_provisional_keepalive(struct sip_pvt *pvt, int with_sdp)
Definition: chan_sip.c:4762

◆ transmit_publish()

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

References ao2_ref, ast_set_flag, ast_sip_ouraddrfor(), create_addr(), DEFAULT_PUBLISH_EXPIRES, DEFAULT_TRANS_TIMEOUT, sip_epa_entry::destination, dialog_unlink_all(), dialog_unref, sip_pvt::epa_entry, sip_pvt::expiry, FALSE, sip_pvt::flags, NULL, sip_pvt::ourip, sip_epa_entry::publish_type, sip_pvt::sa, sip_alloc, SIP_OUTGOING, SIP_PUBLISH, SIP_PUBLISH_REMOVE, 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().

14712 {
14713  struct sip_pvt *pvt;
14714  int expires;
14715 
14716  epa_entry->publish_type = publish_type;
14717 
14718  if (!(pvt = sip_alloc(NULL, NULL, 0, SIP_PUBLISH, NULL, 0))) {
14719  return -1;
14720  }
14721 
14722  sip_pvt_lock(pvt);
14723 
14724  if (create_addr(pvt, epa_entry->destination, NULL, TRUE)) {
14725  sip_pvt_unlock(pvt);
14726  dialog_unlink_all(pvt);
14727  dialog_unref(pvt, "create_addr failed in transmit_publish. Unref dialog");
14728  return -1;
14729  }
14730  ast_sip_ouraddrfor(&pvt->sa, &pvt->ourip, pvt);
14731  ast_set_flag(&pvt->flags[0], SIP_OUTGOING);
14732  expires = (publish_type == SIP_PUBLISH_REMOVE) ? 0 : DEFAULT_PUBLISH_EXPIRES;
14733  pvt->expiry = expires;
14734 
14735  /* Bump refcount for sip_pvt's reference */
14736  ao2_ref(epa_entry, +1);
14737  pvt->epa_entry = epa_entry;
14738 
14739  transmit_invite(pvt, SIP_PUBLISH, FALSE, 2, explicit_uri);
14740  sip_pvt_unlock(pvt);
14742  dialog_unref(pvt, "Done with the sip_pvt allocated for transmitting PUBLISH");
14743  return 0;
14744 }
enum sip_publish_type publish_type
Definition: sip.h:1649
#define FALSE
Definition: app_minivm.c:521
static const int DEFAULT_PUBLISH_EXPIRES
Definition: chan_sip.c:973
#define ast_set_flag(p, flag)
Definition: utils.h:70
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.
Definition: chan_sip.c:14755
#define DEFAULT_TRANS_TIMEOUT
Definition: sip.h:107
struct ast_sockaddr ourip
Definition: sip.h:1136
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?
Definition: chan_sip.c:3866
struct ast_flags flags[3]
Definition: sip.h:1075
#define NULL
Definition: resample.c:96
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
Remove.
Definition: sip.h:1607
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 stor...
Definition: chan_sip.c:3367
struct ast_sockaddr sa
Definition: sip.h:1125
char destination[SIPBUFSIZE]
Definition: sip.h:1661
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define sip_alloc(callid, addr, useglobal_nat, intended_method, req, logger_callid)
Definition: dialog.h:39
struct sip_epa_entry * epa_entry
Definition: sip.h:1219
int expiry
Definition: sip.h:1118
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
#define TRUE
Definition: app_minivm.c:518
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 TR...
Definition: chan_sip.c:6317
#define SIP_OUTGOING
Definition: sip.h:257
void sip_scheddestroy(struct sip_pvt *p, int ms)
Schedule destruction of SIP dialog.
Definition: chan_sip.c:4549

◆ transmit_refer()

static int transmit_refer ( struct sip_pvt p,
const char *  dest 
)
static

Transmit SIP REFER message (initiated by the transfer() dialplan application.

Note
this is currently broken as we have no way of telling the dialplan engine whether a transfer succeeds or fails.
Todo:
Fix the transfer() dialplan function so that a transfer may fail
Todo:
In theory, we should hang around and wait for a reply, before returning to the dial plan here. Don't know really how that would affect the transfer() app or the pbx, but, well, to make this useful we should have a STATUS code on transfer().

Definition at line 16402 of file chan_sip.c.

References ast_copy_string(), ast_debug, ast_log, ast_string_field_set, ast_test_flag, c, sip_pvt::callid, FALSE, sip_pvt::flags, get_in_brackets(), sip_pvt::initreq, LOG_NOTICE, NULL, sip_pvt::our_contact, sip_pvt::refer, REFER_SENT, sip_get_header(), SIP_OUTGOING, SIP_REFER, sip_refer_alloc(), sipdebug, sip_refer::status, transmit_invite(), and TRUE.

Referenced by sip_transfer().

16403 {
16404  char from[256];
16405  const char *of;
16406  char *c;
16407  char referto[256];
16408  int use_tls=FALSE;
16409 
16410  if (sipdebug) {
16411  ast_debug(1, "SIP transfer of %s to %s\n", p->callid, dest);
16412  }
16413 
16414  /* Are we transfering an inbound or outbound call ? */
16415  if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
16416  of = sip_get_header(&p->initreq, "To");
16417  } else {
16418  of = sip_get_header(&p->initreq, "From");
16419  }
16420 
16421  ast_copy_string(from, of, sizeof(from));
16422  of = get_in_brackets(from);
16423  ast_string_field_set(p, from, of);
16424  if (!strncasecmp(of, "sip:", 4)) {
16425  of += 4;
16426  } else if (!strncasecmp(of, "sips:", 5)) {
16427  of += 5;
16428  use_tls = TRUE;
16429  } else {
16430  ast_log(LOG_NOTICE, "From address missing 'sip(s):', assuming sip:\n");
16431  }
16432  /* Get just the username part */
16433  if (strchr(dest, '@')) {
16434  c = NULL;
16435  } else if ((c = strchr(of, '@'))) {
16436  *c++ = '\0';
16437  }
16438  if (c) {
16439  snprintf(referto, sizeof(referto), "<sip%s:%s@%s>", use_tls ? "s" : "", dest, c);
16440  } else {
16441  snprintf(referto, sizeof(referto), "<sip%s:%s>", use_tls ? "s" : "", dest);
16442  }
16443 
16444  /* save in case we get 407 challenge */
16445  sip_refer_alloc(p);
16446  ast_string_field_set(p->refer, refer_to, referto);
16447  ast_string_field_set(p->refer, referred_by, p->our_contact);
16448  p->refer->status = REFER_SENT; /* Set refer status */
16449 
16450  return transmit_invite(p, SIP_REFER, FALSE, 0, NULL);
16451  /* We should propably wait for a NOTIFY here until we ack the transfer */
16452  /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */
16453 
16454  /*! \todo In theory, we should hang around and wait for a reply, before
16455  returning to the dial plan here. Don't know really how that would
16456  affect the transfer() app or the pbx, but, well, to make this
16457  useful we should have a STATUS code on transfer().
16458  */
16459 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
#define FALSE
Definition: app_minivm.c:521
char * get_in_brackets(char *tmp)
Pick out text in brackets from character string.
static int sip_refer_alloc(struct sip_pvt *p)
Allocate SIP refer structure.
Definition: chan_sip.c:16370
#define ast_test_flag(p, flag)
Definition: utils.h:63
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.
Definition: chan_sip.c:14755
enum referstatus status
Definition: sip.h:947
const ast_string_field from
Definition: sip.h:1063
static struct test_val c
struct ast_flags flags[3]
Definition: sip.h:1075
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
struct sip_request initreq
Definition: sip.h:1151
const ast_string_field callid
Definition: sip.h:1063
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
#define LOG_NOTICE
Definition: logger.h:263
struct sip_refer * refer
Definition: sip.h:1160
Definition: sip.h:622
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define TRUE
Definition: app_minivm.c:518
#define SIP_OUTGOING
Definition: sip.h:257
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514
const ast_string_field our_contact
Definition: sip.h:1063

◆ transmit_register()

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

References add_expires(), add_header(), add_max_forwards(), add_supported(), sip_peer::addr, ao2_t_bump, ao2_t_ref, append_history, ast_debug, ast_dnsmgr_lookup_cb(), ast_log, ast_random(), 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(), sip_registry::authdomain, sip_registry::authuser, sip_pvt::branch, build_callid_registry(), build_contact(), build_localtag_registry(), build_reply_digest(), build_via(), sip_registry::call, sip_registry::callback, sip_pvt::callid, sip_registry::callid, sip_registry::callid_valid, create_addr(), default_fromdomain, dialog_ref, dialog_unlink_all(), dialog_unref, sip_registry::dnsmgr, sip_pvt::do_history, sip_registry::expiry, exten, FALSE, FINDPEERS, sip_pvt::flags, sip_pvt::fromdomain, sip_pvt::fromdomainport, get_address_family_filter(), get_srv_protocol(), get_srv_service(), global_reg_timeout, global_useragent, sip_request::headers, sip_registry::hostname, init_req(), initialize_initreq(), sip_pvt::initreq, internip, sip_request::lines, sip_registry::localtag, LOG_NOTICE, LOG_WARNING, MAXHOSTNAMELEN, sip_registry::md5secret, sip_registry::nonce, sip_pvt::noncecount, sip_registry::noncecount, NULL, obproxy_get(), sip_pvt::ocseq, sip_registry::ocseq, on_dns_update_peer(), on_dns_update_registry(), sip_registry::opaque, sip_pvt::our_contact, sip_pvt::ourip, sip_registry::peername, sip_monitor_instance::peername, sip_registry::portno, sip_registry::qop, sip_registry::realm, sip_pvt::recv, REG_STATE_AUTHSENT, REG_STATE_REGSENT, sip_registry::regattempts, sip_registry::regdomain, sip_registry::regdomainport, sip_pvt::registry, sip_registry::regstate, S_OR, sip_pvt::sa, sip_registry::secret, send_request(), set_socket_transport(), sip_alloc, sip_cfg, sip_debug_test_pvt(), sip_find_peer(), sip_methods, SIP_OUTGOING, SIP_REGISTER, sip_sanitized_host(), sip_unref_peer, sipdebug, sip_pvt::socket, sip_settings::srvlookup, ast_sockaddr::ss, STANDARD_SIP_PORT, start_register_timeout(), sip_pvt::tag, cfsip_methods::text, sip_pvt::theirtag, tmp(), sip_pvt::tohost, sip_peer::tohost, sip_registry::transport, TRUE, sip_socket::type, sip_registry::us, sip_registry::username, sip_pvt::via, and XMIT_CRITICAL.

Referenced by __sip_do_register(), do_register_auth(), handle_response_register(), and sip_reg_timeout().

16107 {
16108  struct sip_request req;
16109  char from[256];
16110  char to[256];
16111  char tmp[80];
16112  char addr[80];
16113  struct sip_pvt *p;
16114  struct sip_peer *peer = NULL;
16115  int res;
16116  int portno = 0;
16117 
16118  /* exit if we are already in process with this registrar ?*/
16119  if (r == NULL || ((auth == NULL) && (r->regstate == REG_STATE_REGSENT || r->regstate == REG_STATE_AUTHSENT))) {
16120  if (r) {
16121  ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname);
16122  }
16123  return 0;
16124  }
16125 
16126  if (r->dnsmgr == NULL) {
16127  char transport[MAXHOSTNAMELEN];
16128  peer = sip_find_peer(r->hostname, NULL, TRUE, FINDPEERS, FALSE, 0);
16129  snprintf(transport, sizeof(transport), "_%s._%s",get_srv_service(r->transport), get_srv_protocol(r->transport)); /* have to use static sip_get_transport function */
16130  r->us.ss.ss_family = get_address_family_filter(r->transport); /* Filter address family */
16131 
16132  /* No point in doing a DNS lookup of the register hostname if we're just going to
16133  * end up using an outbound proxy. obproxy_get is safe to call with either of r->call
16134  * or peer NULL. Since we're only concerned with its existence, we're not going to
16135  * bother getting a ref to the proxy*/
16136  if (!obproxy_get(r->call, peer)) {
16137  ao2_t_ref(r, +1, "add reg ref for dnsmgr");
16138  ast_dnsmgr_lookup_cb(peer ? peer->tohost : r->hostname, &r->us, &r->dnsmgr, sip_cfg.srvlookup ? transport : NULL, on_dns_update_registry, r);
16139  if (!r->dnsmgr) {
16140  /*dnsmgr refresh disabled, no reference added! */
16141  ao2_t_ref(r, -1, "remove reg ref, dnsmgr disabled");
16142  }
16143  }
16144  if (peer) {
16145  peer = sip_unref_peer(peer, "removing peer ref for dnsmgr_lookup");
16146  }
16147  }
16148 
16149  if (r->call) { /* We have a registration */
16150  if (!auth) {
16151  ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname);
16152  return 0;
16153  } else {
16154  p = dialog_ref(r->call, "getting a copy of the r->call dialog in transmit_register");
16155  ast_string_field_set(p, theirtag, NULL); /* forget their old tag, so we don't match tags when getting response */
16156  }
16157  } else {
16158  /* Build callid for registration if we haven't registered before */
16159  if (!r->callid_valid) {
16162  r->callid_valid = TRUE;
16163  }
16164  /* Allocate SIP dialog for registration */
16165  if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER, NULL, 0))) {
16166  ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n");
16167  return 0;
16168  }
16169 
16170  /* reset tag to consistent value from registry */
16171  ast_string_field_set(p, tag, r->localtag);
16172 
16173  if (p->do_history) {
16174  append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname);
16175  }
16176 
16177  p->socket.type = r->transport;
16178 
16179  /* Use port number specified if no SRV record was found */
16180  if (!ast_sockaddr_isnull(&r->us)) {
16181  if (!ast_sockaddr_port(&r->us) && r->portno) {
16182  ast_sockaddr_set_port(&r->us, r->portno);
16183  }
16184 
16185  /* It is possible that DNS was unavailable at the time the peer was created.
16186  * Here, if we've updated the address in the registry via manually calling
16187  * ast_dnsmgr_lookup_cb() above, then we call the same function that dnsmgr would
16188  * call if it was updating a peer's address */
16189  if ((peer = sip_find_peer(S_OR(r->peername, r->hostname), NULL, TRUE, FINDPEERS, FALSE, 0))) {
16190  if (ast_sockaddr_cmp(&peer->addr, &r->us)) {
16191  on_dns_update_peer(&peer->addr, &r->us, peer);
16192  }
16193  peer = sip_unref_peer(peer, "unref after sip_find_peer");
16194  }
16195  }
16196 
16197  /* Find address to hostname */
16198  if (create_addr(p, S_OR(r->peername, r->hostname), &r->us, 0)) {
16199  /* we have what we hope is a temporary network error,
16200  * probably DNS. We need to reschedule a registration try */
16201  dialog_unlink_all(p);
16202  p = dialog_unref(p, "unref dialog after unlink_all");
16203  ast_log(LOG_WARNING, "Probably a DNS error for registration to %s@%s, trying REGISTER again (after %d seconds)\n",
16206  r->regattempts++;
16207  return 0;
16208  }
16209 
16210  /* Copy back Call-ID in case create_addr changed it */
16211  ast_string_field_set(r, callid, p->callid);
16212 
16213  if (!r->dnsmgr && r->portno) {
16214  ast_sockaddr_set_port(&p->sa, r->portno);
16216  }
16217  if (!ast_strlen_zero(p->fromdomain)) {
16218  portno = (p->fromdomainport) ? p->fromdomainport : STANDARD_SIP_PORT;
16219  } else if (!ast_strlen_zero(r->regdomain)) {
16220  portno = (r->regdomainport) ? r->regdomainport : STANDARD_SIP_PORT;
16221  } else {
16222  portno = ast_sockaddr_port(&p->sa);
16223  }
16224 
16225  ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */
16226  r->call = dialog_ref(p, "copying dialog into registry r->call"); /* Save pointer to SIP dialog */
16227  p->registry = ao2_t_bump(r, "transmit_register: addref to p->registry in transmit_register"); /* Add pointer to registry in packet */
16228  if (!ast_strlen_zero(r->secret)) { /* Secret (password) */
16229  ast_string_field_set(p, peersecret, r->secret);
16230  }
16231  if (!ast_strlen_zero(r->md5secret))
16232  ast_string_field_set(p, peermd5secret, r->md5secret);
16233  /* User name in this realm
16234  - if authuser is set, use that, otherwise use username */
16235  if (!ast_strlen_zero(r->authuser)) {
16236  ast_string_field_set(p, peername, r->authuser);
16237  ast_string_field_set(p, authname, r->authuser);
16238  } else if (!ast_strlen_zero(r->username)) {
16239  ast_string_field_set(p, peername, r->username);
16240  ast_string_field_set(p, authname, r->username);
16242  }
16243  if (!ast_strlen_zero(r->username)) {
16245  }
16246  /* Save extension in packet */
16247  if (!ast_strlen_zero(r->callback)) {
16249  }
16250 
16251  /* Set transport so the correct contact is built */
16253 
16254  /*
16255  check which address we should use in our contact header
16256  based on whether the remote host is on the external or
16257  internal network so we can register through nat
16258  */
16259  ast_sip_ouraddrfor(&p->sa, &p->ourip, p);
16260  }
16261 
16262  /* set up a timeout */
16263  if (auth == NULL) {
16265  }
16266 
16267  snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, S_OR(r->regdomain, sip_sanitized_host(p->tohost)), p->tag);
16268  if (!ast_strlen_zero(p->theirtag)) {
16269  snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, S_OR(r->regdomain, sip_sanitized_host(p->tohost)), p->theirtag);
16270  } else {
16271  snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, S_OR(r->regdomain, sip_sanitized_host(p->tohost)));
16272  }
16273 
16274  /* Fromdomain is what we are registering to, regardless of actual
16275  host name from SRV */
16276  if (portno && portno != STANDARD_SIP_PORT) {
16277  snprintf(addr, sizeof(addr), "sip:%s:%d", S_OR(p->fromdomain,S_OR(r->regdomain, sip_sanitized_host(r->hostname))), portno);
16278  } else {
16279  snprintf(addr, sizeof(addr), "sip:%s", S_OR(p->fromdomain,S_OR(r->regdomain, sip_sanitized_host(r->hostname))));
16280  }
16281 
16282  ast_string_field_set(p, uri, addr);
16283 
16284  p->branch ^= ast_random();
16285 
16286  init_req(&req, sipmethod, addr);
16287 
16288  /* Add to CSEQ */
16289  snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text);
16290  p->ocseq = r->ocseq;
16291 
16292  build_via(p);
16293  add_header(&req, "Via", p->via);
16294  add_max_forwards(p, &req);
16295  add_header(&req, "From", from);
16296  add_header(&req, "To", to);
16297  add_header(&req, "Call-ID", p->callid);
16298  add_header(&req, "CSeq", tmp);
16299  add_supported(p, &req);
16301  add_header(&req, "User-Agent", global_useragent);
16302 
16303  if (auth) { /* Add auth header */
16304  add_header(&req, authheader, auth);
16305  } else if (!ast_strlen_zero(r->nonce)) {
16306  char digest[1024];
16307 
16308  /* We have auth data to reuse, build a digest header.
16309  * Note, this is not always useful because some parties do not
16310  * like nonces to be reused (for good reasons!) so they will
16311  * challenge us anyways.
16312  */
16313  if (sipdebug) {
16314  ast_debug(1, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname);
16315  }
16316  ast_string_field_set(p, realm, r->realm);
16317  ast_string_field_set(p, nonce, r->nonce);
16319  ast_string_field_set(p, opaque, r->opaque);
16320  ast_string_field_set(p, qop, r->qop);
16321  p->noncecount = ++r->noncecount;
16322 
16323  memset(digest, 0, sizeof(digest));
16324  if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) {
16325  add_header(&req, "Authorization", digest);
16326  } else {
16327  ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname);
16328  }
16329  }
16330 
16331  add_expires(&req, r->expiry);
16332  build_contact(p, &req, 0);
16333  add_header(&req, "Contact", p->our_contact);
16334 
16335  initialize_initreq(p, &req);
16336  if (sip_debug_test_pvt(p)) {
16337  ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
16338  }
16340  r->regattempts++; /* Another attempt */
16341  ast_debug(4, "REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname);
16342  res = send_request(p, &req, XMIT_CRITICAL, p->ocseq);
16343  dialog_unref(p, "p is finished here at the end of transmit_register");
16344  return res;
16345 }
static void on_dns_update_peer(struct ast_sockaddr *old, struct ast_sockaddr *new, void *data)
Definition: chan_sip.c:15029
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
struct sockaddr_storage ss
Definition: netsock2.h:98
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
struct ast_sockaddr addr
Definition: sip.h:1352
#define FALSE
Definition: app_minivm.c:521
int fromdomainport
Definition: sip.h:1220
struct sip_peer * sip_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.
Definition: chan_sip.c:5851
const ast_string_field hostname
Definition: sip.h:1414
static void build_via(struct sip_pvt *p)
Build a Via header for a request.
Definition: chan_sip.c:3847
const ast_string_field username
Definition: sip.h:1414
enum sipregistrystate regstate
Definition: sip.h:1425
char via[128]
Definition: sip.h:1063
static const struct cfsip_methods sip_methods[]
int portno
Definition: sip.h:1416
struct sip_pvt * call
Definition: sip.h:1424
static int get_address_family_filter(unsigned int transport)
Helper for dns resolution to filter by address family.
Definition: chan_sip.c:29558
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define LOG_WARNING
Definition: logger.h:274
static char global_useragent[AST_MAX_EXTENSION]
Definition: chan_sip.c:843
struct ast_sockaddr recv
Definition: sip.h:1135
struct sip_socket socket
Definition: sip.h:1066
static void add_expires(struct sip_request *req, int expires)
Add Expires header to SIP message.
Definition: chan_sip.c:12706
static int tmp()
Definition: bt_open.c:389
static int add_supported(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.
Definition: chan_sip.c:11859
int noncecount
Definition: sip.h:1142
struct ast_sockaddr ourip
Definition: sip.h:1136
static int init_req(struct sip_request *req, int sipmethod, const char *recip)
Initialize SIP request.
Definition: chan_sip.c:12173
static struct ast_sockaddr internip
our (internal) default address/port to put in SIP/SDP messages internip is initialized picking a suit...
Definition: chan_sip.c:1114
static const char * get_srv_protocol(enum ast_transport t)
Return protocol string for srv dns query.
Definition: chan_sip.c:3743
static char default_fromdomain[AST_MAX_EXTENSION]
Definition: chan_sip.c:793
int srvlookup
Definition: sip.h:758
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?
Definition: chan_sip.c:3866
struct ast_flags flags[3]
Definition: sip.h:1075
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
#define MAXHOSTNAMELEN
Definition: network.h:69
const ast_string_field md5secret
Definition: sip.h:1414
#define NULL
Definition: resample.c:96
int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares two ast_sockaddr structures.
Definition: netsock2.c:388
Domain data structure.
Definition: sip.h:888
static void build_localtag_registry(struct sip_registry *reg)
Build SIP From tag value for REGISTER.
Definition: chan_sip.c:8902
struct ast_dnsmgr_entry * dnsmgr
Definition: sip.h:1429
const ast_string_field localtag
Definition: sip.h:1414
#define ast_strlen_zero(foo)
Definition: strings.h:52
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.
Definition: chan_sip.c:8892
const ast_string_field tohost
Definition: sip.h:1306
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:521
int regdomainport
Definition: sip.h:1417
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 stor...
Definition: chan_sip.c:3367
const ast_string_field authuser
Definition: sip.h:1414
struct ast_sockaddr sa
Definition: sip.h:1125
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
struct sip_registry * registry
Definition: sip.h:1173
static int add_max_forwards(struct sip_pvt *dialog, struct sip_request *req)
Add &#39;Max-Forwards&#39; header to SIP message.
Definition: chan_sip.c:11901
static struct sip_proxy * obproxy_get(struct sip_pvt *dialog, struct sip_peer *peer)
Get default outbound proxy or global proxy.
Definition: chan_sip.c:3549
#define STANDARD_SIP_PORT
Standard SIP unsecure port for UDP and TCP from RFC 3261. DO NOT CHANGE THIS.
Definition: sip.h:176
static void start_register_timeout(struct sip_registry *reg)
Definition: chan_sip.c:16080
struct sip_request initreq
Definition: sip.h:1151
long branch
Definition: sip.h:1121
const ast_string_field fromdomain
Definition: sip.h:1063
long int ast_random(void)
Definition: main/utils.c:2064
static const char * sip_sanitized_host(const char *host)
Definition: chan_sip.c:16089
#define sip_alloc(callid, addr, useglobal_nat, intended_method, req, logger_callid)
Definition: dialog.h:39
const ast_string_field username
Definition: sip.h:1306
const ast_string_field nonce
Definition: sip.h:1414
static int build_reply_digest(struct sip_pvt *p, int method, char *digest, int digest_len)
Build reply digest.
Definition: chan_sip.c:23139
const ast_string_field theirtag
Definition: sip.h:1063
uint32_t ocseq
Definition: sip.h:1428
int callid_valid
Definition: sip.h:1427
sipmethod
SIP Request methods known by Asterisk.
Definition: sip.h:612
struct ast_sockaddr us
Definition: sip.h:1430
int regattempts
Definition: sip.h:1421
int noncecount
Definition: sip.h:1431
const ast_string_field callid
Definition: sip.h:1414
const ast_string_field callid
Definition: sip.h:1063
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...
Definition: chan_sip.c:3444
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:537
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
static int global_reg_timeout
Definition: chan_sip.c:826
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
static void on_dns_update_registry(struct ast_sockaddr *old, struct ast_sockaddr *new, void *data)
Definition: chan_sip.c:15008
static int send_request(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno)
Definition: chan_sip.c:4863
uint32_t ocseq
Definition: sip.h:1067
int headers
Definition: sip.h:832
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
#define LOG_NOTICE
Definition: logger.h:263
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
static void build_contact(struct sip_pvt *p, struct sip_request *req, int incoming)
Build contact header.
Definition: chan_sip.c:14385
unsigned short do_history
Definition: sip.h:1078
#define dialog_ref(dialog, tag)
when we create or delete references, make sure to use these functions so we keep track of the refcoun...
Definition: dialog.h:32
#define FINDPEERS
Definition: sip.h:53
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
const ast_string_field opaque
Definition: sip.h:1414
static int sip_debug_test_pvt(struct sip_pvt *p)
Test PVT for debugging output.
Definition: chan_sip.c:3649
const ast_string_field secret
Definition: sip.h:1414
int expiry
Definition: sip.h:1420
char *const text
Definition: chan_sip.c:737
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
const ast_string_field authdomain
Definition: sip.h:1414
#define ao2_t_bump(obj, tag)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:483
struct sip_auth_container * auth
Definition: sip.h:1322
const ast_string_field realm
Definition: sip.h:1414
const ast_string_field peername
Definition: sip.h:1414
enum ast_transport type
Definition: sip.h:798
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
#define TRUE
Definition: app_minivm.c:518
const ast_string_field tohost
Definition: sip.h:1063
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406
const ast_string_field regdomain
Definition: sip.h:1414
const ast_string_field tag
Definition: sip.h:1063
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 TR...
Definition: chan_sip.c:6317
const ast_string_field fromuser
Definition: sip.h:1306
static const char * get_srv_service(enum ast_transport t)
Return service string for srv dns query.
Definition: chan_sip.c:3761
#define SIP_OUTGOING
Definition: sip.h:257
const ast_string_field qop
Definition: sip.h:1414
static void set_socket_transport(struct sip_socket *socket, int transport)
Definition: chan_sip.c:16629
const ast_string_field callback
Definition: sip.h:1414
enum ast_transport transport
Definition: sip.h:1415
int lines
Definition: sip.h:834
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873
int ast_dnsmgr_lookup_cb(const char *name, struct ast_sockaddr *result, struct ast_dnsmgr_entry **dnsmgr, const char *service, dns_update_func func, void *data)
Allocate and initialize a DNS manager entry, with update callback.
Definition: dnsmgr.c:196
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514
const ast_string_field our_contact
Definition: sip.h:1063

◆ transmit_reinvite_with_sdp()

static int transmit_reinvite_with_sdp ( struct sip_pvt p,
int  t38version,
int  oldsdp 
)
static

Transmit reinvite with SDP.

Note
A re-invite is basically a new INVITE with the same CALL-ID and TAG as the INVITE that opened the SIP dialogue We reinvite so that the audio stream (RTP) go directly between the SIP UAs. SIP Signalling stays with * in the path.

If t38version is TRUE, we send T38 SDP for re-invite from audio/video to T38 UDPTL transmission on the channel

If oldsdp is TRUE then the SDP version number is not incremented. This is needed for Session-Timers so we can send a re-invite to refresh the SIP session without modifying the media session.

Definition at line 14212 of file chan_sip.c.

References add_header(), add_rpid(), add_sdp(), add_supported(), ALLOWED_METHODS, append_history, ast_channel_set_fd(), ast_rtp_instance_fd(), AST_RTP_INSTANCE_RTCP_DISABLED, AST_RTP_INSTANCE_RTCP_STANDARD, ast_rtp_instance_set_prop(), AST_RTP_PROPERTY_RTCP, ast_set_flag, ast_sockaddr_isnull(), ast_test_flag, sip_pvt::do_history, FALSE, sip_pvt::flags, initialize_initreq(), sip_pvt::lastinvite, sip_pvt::ocseq, offered_media_list_destroy(), sip_pvt::ongoing_reinvite, sip_pvt::owner, sip_pvt::redirip, reqprep(), sip_pvt::rtp, send_request(), SIP_AUDIO_RTCP_FD, SIP_INVITE, SIP_OUTGOING, SIP_REINVITE_UPDATE, SIP_SENDRPID, SIP_UPDATE, sipdebug, TRUE, try_suggested_sip_codec(), and XMIT_CRITICAL.

Referenced by check_pendings(), handle_response_invite(), interpret_t38_parameters(), proc_session_timer(), sip_sendhtml(), and sip_set_rtp_peer().

14213 {
14214  struct sip_request req;
14215 
14216  if (t38version) {
14217  /* Force media to go through us for T.38. */
14218  memset(&p->redirip, 0, sizeof(p->redirip));
14219  }
14220  if (p->rtp) {
14221  if (t38version) {
14222  /* Silence RTCP while audio RTP is inactive */
14224  if (p->owner) {
14225  /* Prevent audio RTCP reads */
14227  }
14228  } else if (ast_sockaddr_isnull(&p->redirip)) {
14229  /* Enable RTCP since it will be inactive if we're coming back
14230  * with this reinvite */
14232  if (p->owner) {
14233  /* Enable audio RTCP reads */
14235  }
14236  }
14237  }
14238 
14239  reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1);
14240 
14241  add_header(&req, "Allow", ALLOWED_METHODS);
14242  add_supported(p, &req);
14243  if (sipdebug) {
14244  if (oldsdp == TRUE)
14245  add_header(&req, "X-asterisk-Info", "SIP re-invite (Session-Timers)");
14246  else
14247  add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)");
14248  }
14249 
14250  if (ast_test_flag(&p->flags[0], SIP_SENDRPID))
14251  add_rpid(&req, p);
14252 
14253  if (p->do_history) {
14254  append_history(p, "ReInv", "Re-invite sent");
14255  }
14256 
14258 
14260  if (t38version) {
14261  add_sdp(&req, p, oldsdp, FALSE, TRUE);
14262  } else {
14263  add_sdp(&req, p, oldsdp, TRUE, FALSE);
14264  }
14265 
14266  /* Use this as the basis */
14267  initialize_initreq(p, &req);
14268  p->lastinvite = p->ocseq;
14269  ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */
14270  p->ongoing_reinvite = 1;
14271  return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
14272 }
#define FALSE
Definition: app_minivm.c:521
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ast_set_flag(p, flag)
Definition: utils.h:70
struct ast_sockaddr redirip
Definition: sip.h:1126
static int add_supported(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.
Definition: chan_sip.c:11859
unsigned int ongoing_reinvite
Definition: sip.h:1144
struct ast_flags flags[3]
Definition: sip.h:1075
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
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)
Definition: chan_sip.c:12361
static void offered_media_list_destroy(struct sip_pvt *p)
Destroy SDP media offer list.
Definition: chan_sip.c:6663
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.
Definition: chan_sip.c:13542
#define SIP_REINVITE_UPDATE
Definition: sip.h:291
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...
Definition: chan_sip.c:3444
static void try_suggested_sip_codec(struct sip_pvt *p)
Try setting the codecs suggested by the SIP_CODEC channel variable.
Definition: chan_sip.c:7405
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
static int send_request(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno)
Definition: chan_sip.c:4863
uint32_t ocseq
Definition: sip.h:1067
#define ALLOWED_METHODS
SIP Methods we support.
Definition: sip.h:173
unsigned short do_history
Definition: sip.h:1078
struct ast_channel * owner
Definition: sip.h:1138
int ast_rtp_instance_fd(struct ast_rtp_instance *instance, int rtcp)
Get the file descriptor for an RTP session (or RTCP)
Definition: rtp_engine.c:2192
struct ast_rtp_instance * rtp
Definition: sip.h:1174
static int add_rpid(struct sip_request *req, struct sip_pvt *p)
Add Remote-Party-ID header to SIP message.
Definition: chan_sip.c:12996
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition: channel.c:2431
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
#define TRUE
Definition: app_minivm.c:518
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406
uint32_t lastinvite
Definition: sip.h:1074
void ast_rtp_instance_set_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value)
Set the value of an RTP instance property.
Definition: rtp_engine.c:705
#define SIP_OUTGOING
Definition: sip.h:257
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873
#define SIP_SENDRPID
Definition: sip.h:306

◆ transmit_request()

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

References add_header(), sip_pvt::answered_elsewhere, INV_CONFIRMED, sip_pvt::invitestate, sip_pvt::ocseq, reqprep(), send_request(), SIP_ACK, and SIP_CANCEL.

Referenced by check_pendings(), forked_invite_init(), handle_response(), handle_response_invite(), and sip_hangup().

16533 {
16534  struct sip_request resp;
16535 
16536  reqprep(&resp, p, sipmethod, seqno, newbranch);
16537  if (sipmethod == SIP_CANCEL && p->answered_elsewhere) {
16538  add_header(&resp, "Reason", "SIP;cause=200;text=\"Call completed elsewhere\"");
16539  }
16540 
16541  if (sipmethod == SIP_ACK) {
16543  }
16544 
16545  return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);
16546 }
Definition: sip.h:619
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)
Definition: chan_sip.c:12361
sipmethod
SIP Request methods known by Asterisk.
Definition: sip.h:612
static int send_request(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno)
Definition: chan_sip.c:4863
uint32_t ocseq
Definition: sip.h:1067
enum invitestates invitestate
Definition: sip.h:1007
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
unsigned short answered_elsewhere
Definition: sip.h:1084
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873

◆ transmit_request_with_auth()

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

References add_header(), add_text(), ast_cause2str(), ast_log, ast_strlen_zero, ast_test_flag, sip_invite_param::auth_type, buf, build_reply_digest(), sip_pvt::callid, dummy(), sip_pvt::flags, sip_pvt::hangupcause, LOG_WARNING, sip_pvt::ocseq, sip_pvt::options, PROXY_AUTH, sip_pvt::realm, reqprep(), send_request(), sip_auth_headers(), SIP_BYE, SIP_MESSAGE, and SIP_PAGE2_Q850_REASON.

Referenced by __sip_autodestruct(), check_pendings(), sip_hangup(), and transmit_message().

16565 {
16566  struct sip_request resp;
16567 
16568  reqprep(&resp, p, sipmethod, seqno, newbranch);
16569  if (!ast_strlen_zero(p->realm)) {
16570  char digest[1024];
16571 
16572  memset(digest, 0, sizeof(digest));
16573  if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) {
16574  char *dummy, *response;
16575  enum sip_auth_type code = p->options ? p->options->auth_type : PROXY_AUTH; /* XXX force 407 if unknown */
16576  sip_auth_headers(code, &dummy, &response);
16577  add_header(&resp, response, digest);
16578  } else {
16579  ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid);
16580  }
16581  }
16582 
16583  switch (sipmethod) {
16584  case SIP_BYE:
16585  {
16586  char buf[20];
16587 
16588  /*
16589  * We are hanging up. If we know a cause for that, send it in
16590  * clear text to make debugging easier.
16591  */
16593  snprintf(buf, sizeof(buf), "Q.850;cause=%d", p->hangupcause & 0x7f);
16594  add_header(&resp, "Reason", buf);
16595  }
16596 
16597  add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->hangupcause));
16598  snprintf(buf, sizeof(buf), "%d", p->hangupcause);
16599  add_header(&resp, "X-Asterisk-HangupCauseCode", buf);
16600  break;
16601  }
16602  case SIP_MESSAGE:
16603  add_text(&resp, p);
16604  break;
16605  default:
16606  break;
16607  }
16608 
16609  return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);
16610 }
const ast_string_field realm
Definition: sip.h:1063
enum sip_auth_type auth_type
Definition: sip.h:867
int hangupcause
Definition: sip.h:1190
#define ast_test_flag(p, flag)
Definition: utils.h:63
void sip_auth_headers(enum sip_auth_type code, char **header, char **respheader)
return the request and response header for a 401 or 407 code
Definition: chan_sip.c:16549
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
static void dummy(char *unused,...)
Definition: chan_unistim.c:220
struct ast_flags flags[3]
Definition: sip.h:1075
Definition: sip.h:621
struct sip_invite_param * options
Definition: sip.h:1183
#define ast_strlen_zero(foo)
Definition: strings.h:52
static int add_text(struct sip_request *req, struct sip_pvt *p)
Add text body to SIP message.
Definition: chan_sip.c:12931
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)
Definition: chan_sip.c:12361
#define ast_log
Definition: astobj2.c:42
sip_auth_type
Authentication types - proxy or www authentication.
Definition: sip.h:502
static int build_reply_digest(struct sip_pvt *p, int method, char *digest, int digest_len)
Build reply digest.
Definition: chan_sip.c:23139
sipmethod
SIP Request methods known by Asterisk.
Definition: sip.h:612
const ast_string_field callid
Definition: sip.h:1063
#define SIP_PAGE2_Q850_REASON
Definition: sip.h:326
static int send_request(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno)
Definition: chan_sip.c:4863
uint32_t ocseq
Definition: sip.h:1067
const char * ast_cause2str(int state) attribute_pure
Gives the string form of a given cause code.
Definition: channel.c:612
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873

◆ transmit_response()

static int transmit_response ( struct sip_pvt p,
const char *  msg,
const struct sip_request req 
)
static

◆ transmit_response_reliable()

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

References __transmit_response(), sip_request::ignore, XMIT_CRITICAL, and XMIT_UNRELIABLE.

Referenced by handle_incoming(), handle_invite_replaces(), handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_invite_st(), interpret_t38_parameters(), send_check_user_failure_response(), sip_hangup(), sip_indicate(), sip_sipredirect(), and sip_t38_abort().

12689 {
12690  return __transmit_response(p, msg, req, req->ignore ? XMIT_UNRELIABLE : XMIT_CRITICAL);
12691 }
static int __transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable)
Base transmit response function.
Definition: chan_sip.c:12511
char ignore
Definition: sip.h:839

◆ transmit_response_using_temp()

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 12601 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(), sip_pvt::branch, build_via(), check_via(), copy_socket_data(), default_fromdomain, default_fromdomainport, sip_pvt::flags, sip_pvt::fromdomainport, INITIAL_CSEQ, internip, LOG_ERROR, make_our_tag(), sip_pvt::method, NULL, sip_pvt::ocseq, sip_pvt::ourip, sip_pvt::recv, sip_pvt::sa, SIP_NAT_FORCE_RPORT, SIP_PAGE3_NAT_AUTO_RPORT, sip_request::socket, sip_pvt::socket, ts_temp_pvt, and XMIT_UNRELIABLE.

Referenced by __find_call().

12602 {
12603  struct sip_pvt *p = NULL;
12604 
12605  if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) {
12606  ast_log(LOG_ERROR, "Failed to get temporary pvt\n");
12607  return -1;
12608  }
12609 
12610  /* XXX the structure may be dirty from previous usage.
12611  * Here we should state clearly how we should reinitialize it
12612  * before using it.
12613  * E.g. certainly the threadstorage should be left alone,
12614  * but other thihngs such as flags etc. maybe need cleanup ?
12615  */
12616 
12617  /* Initialize the bare minimum */
12618  p->method = intended_method;
12619 
12620  if (!addr) {
12622  } else {
12623  ast_sockaddr_copy(&p->sa, addr);
12624  ast_sip_ouraddrfor(&p->sa, &p->ourip, p);
12625  }
12626 
12627  p->branch = ast_random();
12628  make_our_tag(p);
12629  p->ocseq = INITIAL_CSEQ;
12630 
12631  if (useglobal_nat && addr) {
12634  ast_sockaddr_copy(&p->recv, addr);
12635  check_via(p, req);
12636  }
12637 
12640  build_via(p);
12642 
12643  copy_socket_data(&p->socket, &req->socket);
12644 
12645  /* Use this temporary pvt structure to send the message */
12646  __transmit_response(p, msg, req, XMIT_UNRELIABLE);
12647 
12648  /* Free the string fields, but not the pool space */
12649  ast_string_field_init(p, 0);
12650 
12651  return 0;
12652 }
int fromdomainport
Definition: sip.h:1220
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
static void build_via(struct sip_pvt *p)
Build a Via header for a request.
Definition: chan_sip.c:3847
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:171
static void check_via(struct sip_pvt *p, const struct sip_request *req)
check Via: header for hostname, port and rport request/answer
Definition: chan_sip.c:19164
struct ast_sockaddr recv
Definition: sip.h:1135
struct sip_socket socket
Definition: sip.h:1066
struct ast_sockaddr ourip
Definition: sip.h:1136
#define SIP_NAT_FORCE_RPORT
Definition: sip.h:283
static struct ast_sockaddr internip
our (internal) default address/port to put in SIP/SDP messages internip is initialized picking a suit...
Definition: chan_sip.c:1114
static char default_fromdomain[AST_MAX_EXTENSION]
Definition: chan_sip.c:793
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?
Definition: chan_sip.c:3866
struct ast_flags flags[3]
Definition: sip.h:1075
#define ast_copy_flags(dest, src, flagz)
Definition: utils.h:84
static struct ast_threadstorage ts_temp_pvt
Definition: chan_sip.c:1070
#define NULL
Definition: resample.c:96
static void make_our_tag(struct sip_pvt *pvt)
Make our SIP dialog tag.
Definition: chan_sip.c:8908
struct ast_sockaddr sa
Definition: sip.h:1125
#define ast_log
Definition: astobj2.c:42
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:353
long branch
Definition: sip.h:1121
const ast_string_field fromdomain
Definition: sip.h:1063
long int ast_random(void)
Definition: main/utils.c:2064
static void copy_socket_data(struct sip_socket *to_sock, const struct sip_socket *from_sock)
Definition: chan_sip.c:5952
const ast_string_field callid
Definition: sip.h:1063
#define LOG_ERROR
Definition: logger.h:285
int method
Definition: sip.h:1009
static struct ast_flags global_flags[3]
Definition: chan_sip.c:884
uint32_t ocseq
Definition: sip.h:1067
#define SIP_PAGE3_NAT_AUTO_RPORT
Definition: sip.h:386
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
static int __transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable)
Base transmit response function.
Definition: chan_sip.c:12511
#define INITIAL_CSEQ
Definition: sip.h:117
static int default_fromdomainport
Definition: chan_sip.c:794
struct sip_socket socket
Definition: sip.h:846
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ transmit_response_with_allow()

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

References add_header(), respprep(), and send_response().

Referenced by handle_incoming(), and handle_request_options().

12734 {
12735  struct sip_request resp;
12736  respprep(&resp, p, msg, req);
12737  add_header(&resp, "Accept", "application/sdp");
12738  return send_response(p, &resp, reliable, 0);
12739 }
static int send_response(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno)
Transmit response on SIP request.
Definition: chan_sip.c:4821
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
static int respprep(struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req)
Prepare SIP response packet.
Definition: chan_sip.c:12269
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873

◆ transmit_response_with_auth()

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

References add_header(), append_history, ast_log, get_realm(), LOG_WARNING, sip_pvt::noncecount, sip_pvt::realm, respprep(), send_response(), sip_get_header(), tmp(), and sip_pvt::username.

Referenced by check_auth(), and transmit_fake_auth_response().

12755 {
12756  struct sip_request resp;
12757  char tmp[512];
12758  uint32_t seqno = 0;
12759 
12760  if (reliable && (sscanf(sip_get_header(req, "CSeq"), "%30u ", &seqno) != 1)) {
12761  ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", sip_get_header(req, "CSeq"));
12762  return -1;
12763  }
12764  /* Choose Realm */
12765  get_realm(p, req);
12766 
12767  /* Stale means that they sent us correct authentication, but
12768  based it on an old challenge (nonce) */
12769  snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", p->realm, nonce, stale ? ", stale=true" : "");
12770  respprep(&resp, p, msg, req);
12771  add_header(&resp, header, tmp);
12772  append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount);
12773  return send_response(p, &resp, reliable, seqno);
12774 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
const ast_string_field realm
Definition: sip.h:1063
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=...
Definition: chan_sip.c:12830
#define LOG_WARNING
Definition: logger.h:274
static int tmp()
Definition: bt_open.c:389
const ast_string_field username
Definition: sip.h:1063
int noncecount
Definition: sip.h:1142
#define ast_log
Definition: astobj2.c:42
static int send_response(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno)
Transmit response on SIP request.
Definition: chan_sip.c:4821
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406
static int respprep(struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req)
Prepare SIP response packet.
Definition: chan_sip.c:12269
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873

◆ transmit_response_with_date()

static int transmit_response_with_date ( struct sip_pvt p,
const char *  msg,
const struct sip_request req 
)
static

Add date before transmitting response.

Definition at line 12724 of file chan_sip.c.

References add_date(), respprep(), send_response(), and XMIT_UNRELIABLE.

Referenced by handle_response_subscribe(), and register_verify().

12725 {
12726  struct sip_request resp;
12727  respprep(&resp, p, msg, req);
12728  add_date(&resp);
12729  return send_response(p, &resp, XMIT_UNRELIABLE, 0);
12730 }
static void add_date(struct sip_request *req)
Add date header to SIP message.
Definition: chan_sip.c:12694
static int send_response(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno)
Transmit response on SIP request.
Definition: chan_sip.c:4821
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
static int respprep(struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req)
Prepare SIP response packet.
Definition: chan_sip.c:12269

◆ transmit_response_with_minexpires()

static int transmit_response_with_minexpires ( struct sip_pvt p,
const char *  msg,
const struct sip_request req,
int  minexpires 
)
static

Append Min-Expires header, content length before transmitting response.

Definition at line 12742 of file chan_sip.c.

References add_header(), respprep(), send_response(), tmp(), and XMIT_UNRELIABLE.

Referenced by handle_request_publish(), and handle_request_subscribe().

12743 {
12744  struct sip_request resp;
12745  char tmp[32];
12746 
12747  snprintf(tmp, sizeof(tmp), "%d", minexpires);
12748  respprep(&resp, p, msg, req);
12749  add_header(&resp, "Min-Expires", tmp);
12750  return send_response(p, &resp, XMIT_UNRELIABLE, 0);
12751 }
static int tmp()
Definition: bt_open.c:389
static int send_response(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno)
Transmit response on SIP request.
Definition: chan_sip.c:4821
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
static int respprep(struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req)
Prepare SIP response packet.
Definition: chan_sip.c:12269
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873

◆ transmit_response_with_minse()

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

References add_date(), add_header(), respprep(), send_response(), and XMIT_UNRELIABLE.

Referenced by handle_request_invite_st().

12672 {
12673  struct sip_request resp;
12674  char minse_str[20];
12675 
12676  respprep(&resp, p, msg, req);
12677  add_date(&resp);
12678 
12679  snprintf(minse_str, sizeof(minse_str), "%d", minse_int);
12680  add_header(&resp, "Min-SE", minse_str);
12681  return send_response(p, &resp, XMIT_UNRELIABLE, 0);
12682 }
static void add_date(struct sip_request *req)
Add date header to SIP message.
Definition: chan_sip.c:12694
static int send_response(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno)
Transmit response on SIP request.
Definition: chan_sip.c:4821
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
static int respprep(struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req)
Prepare SIP response packet.
Definition: chan_sip.c:12269
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873

◆ transmit_response_with_retry_after()

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

References add_header(), respprep(), send_response(), and XMIT_UNRELIABLE.

Referenced by handle_incoming().

12716 {
12717  struct sip_request resp;
12718  respprep(&resp, p, msg, req);
12719  add_header(&resp, "Retry-After", seconds);
12720  return send_response(p, &resp, XMIT_UNRELIABLE, 0);
12721 }
static int send_response(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno)
Transmit response on SIP request.
Definition: chan_sip.c:4821
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
static int respprep(struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req)
Prepare SIP response packet.
Definition: chan_sip.c:12269
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873

◆ transmit_response_with_sdp()

static int transmit_response_with_sdp ( struct sip_pvt p,
const char *  msg,
const struct sip_request req,
enum xmittype  reliable,
int  oldsdp,
int  rpid 
)
static

Used for 200 OK and 183 early media.

Returns
Will return XMIT_ERROR for network errors.

Definition at line 14125 of file chan_sip.c.

References add_cc_call_info_to_response(), add_required_respheader(), add_rpid(), add_sdp(), ast_log, ast_rtp_instance_activate(), ast_test_flag, sip_pvt::callid, FALSE, sip_pvt::flags, LOG_ERROR, LOG_WARNING, sip_pvt::pendinginvite, respprep(), sip_pvt::rtp, send_response(), sip_get_header(), SIP_OFFER_CC, t38properties::state, sip_pvt::t38, T38_ENABLED, TRUE, and try_suggested_sip_codec().

Referenced by handle_request_invite(), send_provisional_keepalive_full(), sip_answer(), and transmit_provisional_response().

14126 {
14127  struct sip_request resp;
14128  uint32_t seqno;
14129  if (sscanf(sip_get_header(req, "CSeq"), "%30u ", &seqno) != 1) {
14130  ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", sip_get_header(req, "CSeq"));
14131  return -1;
14132  }
14133  respprep(&resp, p, msg, req);
14134  if (rpid == TRUE) {
14135  add_rpid(&resp, p);
14136  }
14137  if (ast_test_flag(&p->flags[0], SIP_OFFER_CC)) {
14138  add_cc_call_info_to_response(p, &resp);
14139  }
14140  if (p->rtp) {
14143  if (p->t38.state == T38_ENABLED) {
14144  add_sdp(&resp, p, oldsdp, TRUE, TRUE);
14145  } else {
14146  add_sdp(&resp, p, oldsdp, TRUE, FALSE);
14147  }
14148  } else
14149  ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid);
14150  if (reliable && !p->pendinginvite)
14151  p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */
14152  add_required_respheader(&resp);
14153  return send_response(p, &resp, reliable, seqno);
14154 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
int ast_rtp_instance_activate(struct ast_rtp_instance *instance)
Indicate to the RTP engine that packets are now expected to be sent/received on the RTP instance...
Definition: rtp_engine.c:2647
#define T38_ENABLED
Definition: chan_ooh323.c:102
#define FALSE
Definition: app_minivm.c:521
enum t38state state
Definition: sip.h:917
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define LOG_WARNING
Definition: logger.h:274
uint32_t pendinginvite
Definition: sip.h:1147
struct ast_flags flags[3]
Definition: sip.h:1075
struct t38properties t38
Definition: sip.h:1113
static void add_required_respheader(struct sip_request *req)
Definition: chan_sip.c:4792
#define ast_log
Definition: astobj2.c:42
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.
Definition: chan_sip.c:13542
const ast_string_field callid
Definition: sip.h:1063
#define LOG_ERROR
Definition: logger.h:285
static void try_suggested_sip_codec(struct sip_pvt *p)
Try setting the codecs suggested by the SIP_CODEC channel variable.
Definition: chan_sip.c:7405
static int send_response(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno)
Transmit response on SIP request.
Definition: chan_sip.c:4821
struct ast_rtp_instance * rtp
Definition: sip.h:1174
static int add_rpid(struct sip_request *req, struct sip_pvt *p)
Add Remote-Party-ID header to SIP message.
Definition: chan_sip.c:12996
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
#define TRUE
Definition: app_minivm.c:518
static void add_cc_call_info_to_response(struct sip_pvt *p, struct sip_request *resp)
Definition: chan_sip.c:14090
static int respprep(struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req)
Prepare SIP response packet.
Definition: chan_sip.c:12269
#define SIP_OFFER_CC
Definition: sip.h:258

◆ transmit_response_with_sip_etag()

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

References add_header(), create_new_sip_etag(), sip_esc_entry::entity_tag, respprep(), and send_response().

Referenced by handle_sip_publish_initial(), handle_sip_publish_modify(), handle_sip_publish_refresh(), and handle_sip_publish_remove().

12571 {
12572  struct sip_request resp;
12573 
12574  if (need_new_etag) {
12575  create_new_sip_etag(esc_entry, 1);
12576  }
12577  respprep(&resp, p, msg, req);
12578  add_header(&resp, "SIP-ETag", esc_entry->entity_tag);
12579 
12580  return send_response(p, &resp, 0, 0);
12581 }
static void create_new_sip_etag(struct sip_esc_entry *esc_entry, int is_linked)
Definition: chan_sip.c:1777
static int send_response(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno)
Transmit response on SIP request.
Definition: chan_sip.c:4821
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
static int respprep(struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req)
Prepare SIP response packet.
Definition: chan_sip.c:12269
char entity_tag[30]
Definition: sip.h:1742
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873

◆ transmit_response_with_t38_sdp()

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

References add_sdp(), ast_log, sip_pvt::callid, LOG_ERROR, LOG_WARNING, sip_pvt::pendinginvite, respprep(), send_response(), sip_get_header(), and sip_pvt::udptl.

Referenced by handle_request_invite(), and interpret_t38_parameters().

14042 {
14043  struct sip_request resp;
14044  uint32_t seqno;
14045 
14046  if (sscanf(sip_get_header(req, "CSeq"), "%30u ", &seqno) != 1) {
14047  ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", sip_get_header(req, "CSeq"));
14048  return -1;
14049  }
14050  respprep(&resp, p, msg, req);
14051  if (p->udptl) {
14052  add_sdp(&resp, p, 0, 0, 1);
14053  } else
14054  ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid);
14055  if (retrans && !p->pendinginvite)
14056  p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */
14057  return send_response(p, &resp, retrans, seqno);
14058 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
#define LOG_WARNING
Definition: logger.h:274
uint32_t pendinginvite
Definition: sip.h:1147
#define ast_log
Definition: astobj2.c:42
struct ast_udptl * udptl
Definition: sip.h:1115
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.
Definition: chan_sip.c:13542
const ast_string_field callid
Definition: sip.h:1063
#define LOG_ERROR
Definition: logger.h:285
static int send_response(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno)
Transmit response on SIP request.
Definition: chan_sip.c:4821
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
static int respprep(struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req)
Prepare SIP response packet.
Definition: chan_sip.c:12269

◆ transmit_response_with_unsupported()

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

References add_date(), add_header(), respprep(), send_response(), and XMIT_UNRELIABLE.

Referenced by handle_request_bye(), handle_request_invite(), and handle_request_invite_st().

12662 {
12663  struct sip_request resp;
12664  respprep(&resp, p, msg, req);
12665  add_date(&resp);
12666  add_header(&resp, "Unsupported", unsupported);
12667  return send_response(p, &resp, XMIT_UNRELIABLE, 0);
12668 }
static void add_date(struct sip_request *req)
Add date header to SIP message.
Definition: chan_sip.c:12694
static int send_response(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno)
Transmit response on SIP request.
Definition: chan_sip.c:4821
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
static int respprep(struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req)
Prepare SIP response packet.
Definition: chan_sip.c:12269
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873

◆ transmit_state_notify()

static int transmit_state_notify ( struct sip_pvt p,
struct state_notify_data data,
int  full,
int  timeout 
)
static

Used in the SUBSCRIBE notification subsystem (RFC3265)

Definition at line 15477 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, c, sip_pvt::context, CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, cfsubscription_types::event, sip_pvt::expiry, sip_pvt::exten, find_subscription_type(), sip_pvt::flags, get_in_brackets(), sip_pvt::initreq, LOG_WARNING, cfsubscription_types::mediatype, NONE, sip_pvt::ocseq, sip_pvt::pendinginvite, PIDF_XML, remove_uri_parameters(), reqprep(), send_request(), sip_get_header(), SIP_NOTIFY, SIP_PAGE2_DIALOG_ESTABLISHED, state_notify_data::state, state_notify_build_xml(), sip_pvt::subscribed, tmp(), XMIT_CRITICAL, and XPIDF_XML.

Referenced by __sip_autodestruct(), and extensionstate_update().

15478 {
15479  struct ast_str *tmp = ast_str_alloca(4000);
15480  char from[256], to[256];
15481  char *c, *mfrom, *mto;
15482  struct sip_request req;
15483  const struct cfsubscription_types *subscriptiontype;
15484 
15485  /* If the subscription has not yet been accepted do not send a NOTIFY */
15487  return 0;
15488  }
15489 
15490  memset(from, 0, sizeof(from));
15491  memset(to, 0, sizeof(to));
15492 
15493  subscriptiontype = find_subscription_type(p->subscribed);
15494 
15495  ast_copy_string(from, sip_get_header(&p->initreq, "From"), sizeof(from));
15496  c = get_in_brackets(from);
15497  if (strncasecmp(c, "sip:", 4) && strncasecmp(c, "sips:", 5)) {
15498  ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c);
15499  return -1;
15500  }
15501 
15502  mfrom = remove_uri_parameters(c);
15503 
15504  ast_copy_string(to, sip_get_header(&p->initreq, "To"), sizeof(to));
15505  c = get_in_brackets(to);
15506  if (strncasecmp(c, "sip:", 4) && strncasecmp(c, "sips:", 5)) {
15507  ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c);
15508  return -1;
15509  }
15510  mto = remove_uri_parameters(c);
15511 
15512  reqprep(&req, p, SIP_NOTIFY, 0, 1);
15513 
15514  switch(data->state) {
15516  if (timeout)
15517  add_header(&req, "Subscription-State", "terminated;reason=timeout");
15518  else {
15519  add_header(&req, "Subscription-State", "terminated;reason=probation");
15520  add_header(&req, "Retry-After", "60");
15521  }
15522  break;
15523  case AST_EXTENSION_REMOVED:
15524  add_header(&req, "Subscription-State", "terminated;reason=noresource");
15525  break;
15526  default:
15527  if (p->expiry)
15528  add_header(&req, "Subscription-State", "active");
15529  else /* Expired */
15530  add_header(&req, "Subscription-State", "terminated;reason=timeout");
15531  }
15532 
15533  switch (p->subscribed) {
15534  case XPIDF_XML:
15535  case CPIM_PIDF_XML:
15536  add_header(&req, "Event", subscriptiontype->event);
15537  state_notify_build_xml(data, full, p->exten, p->context, &tmp, p, p->subscribed, mfrom, mto);
15538  add_header(&req, "Content-Type", subscriptiontype->mediatype);
15539  p->dialogver++;
15540  break;
15541  case PIDF_XML: /* Eyebeam supports this format */
15542  add_header(&req, "Event", subscriptiontype->event);
15543  state_notify_build_xml(data, full, p->exten, p->context, &tmp, p, p->subscribed, mfrom, mto);
15544  add_header(&req, "Content-Type", subscriptiontype->mediatype);
15545  p->dialogver++;
15546  break;
15547  case DIALOG_INFO_XML: /* SNOM subscribes in this format */
15548  add_header(&req, "Event", subscriptiontype->event);
15549  state_notify_build_xml(data, full, p->exten, p->context, &tmp, p, p->subscribed, mfrom, mto);
15550  add_header(&req, "Content-Type", subscriptiontype->mediatype);
15551  p->dialogver++;
15552  break;
15553  case NONE:
15554  default:
15555  break;
15556  }
15557 
15558  add_content(&req, ast_str_buffer(tmp));
15559 
15560  p->pendinginvite = p->ocseq; /* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */
15561 
15562  /* Send as XMIT_CRITICAL as we may never receive a 200 OK Response which clears p->pendinginvite.
15563  *
15564  * extensionstate_update() uses p->pendinginvite for queuing control.
15565  * Updates stall if pendinginvite <> 0.
15566  *
15567  * The most appropriate solution is to remove the subscription when the NOTIFY transaction fails.
15568  * The client will re-subscribe after restarting or maxexpiry timeout.
15569  */
15570 
15571  /* RFC6665 4.2.2. Sending State Information to Subscribers
15572  * If the NOTIFY request fails due to expiration of SIP Timer F (transaction timeout),
15573  * the notifier SHOULD remove the subscription.
15574  */
15575  return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
15576 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
enum subscriptiontype subscribed
Definition: sip.h:1161
char * get_in_brackets(char *tmp)
Pick out text in brackets from character string.
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define NONE
Definition: misdn_config.c:45
uint32_t dialogver
Definition: sip.h:1167
#define LOG_WARNING
Definition: logger.h:274
uint32_t pendinginvite
Definition: sip.h:1147
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
static int timeout
Definition: cdr_mysql.c:86
static int tmp()
Definition: bt_open.c:389
static void state_notify_build_xml(struct state_notify_data *data, 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.
Definition: chan_sip.c:15193
static struct test_val c
struct ast_flags flags[3]
Definition: sip.h:1075
const ast_string_field context
Definition: sip.h:1063
#define ast_str_alloca(init_len)
Definition: strings.h:800
const char *const event
Definition: chan_sip.c:716
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)
Definition: chan_sip.c:12361
#define ast_log
Definition: astobj2.c:42
Definition: sip.h:475
struct sip_request initreq
Definition: sip.h:1151
static char * remove_uri_parameters(char *uri)
Definition: chan_sip.c:14275
const ast_string_field exten
Definition: sip.h:1063
int expiry
Definition: sip.h:1118
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
static const struct cfsubscription_types * find_subscription_type(enum subscriptiontype subtype)
Find subscription type in array.
Definition: chan_sip.c:22130
Subscription types that we support. We support.
Definition: chan_sip.c:714
static int send_request(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno)
Definition: chan_sip.c:4863
uint32_t ocseq
Definition: sip.h:1067
Definition: sip.h:478
const char *const mediatype
Definition: chan_sip.c:717
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static int add_content(struct sip_request *req, const char *line)
Add content (not header) to SIP message.
Definition: chan_sip.c:11931
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873
#define SIP_PAGE2_DIALOG_ESTABLISHED
Definition: sip.h:358
subscriptiontype
Type of subscription, based on the packages we do support, see subscription_types.
Definition: sip.h:473

◆ trust_id_outbound2str()

static const char* trust_id_outbound2str ( int  mode)
static

Definition at line 20643 of file chan_sip.c.

References map_x_s().

Referenced by _sip_show_peer().

20644 {
20645  return map_x_s(trust_id_outboundstr, mode, "<error>");
20646 }
static const struct _map_x_s trust_id_outboundstr[]
Definition: chan_sip.c:20636
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
Definition: chan_sip.c:2411

◆ try_suggested_sip_codec()

static void try_suggested_sip_codec ( struct sip_pvt p)
static

Try setting the codecs suggested by the SIP_CODEC channel variable.

Definition at line 7405 of file chan_sip.c.

References ao2_ref, ast_format_cache_get, ast_format_cap_alloc, ast_format_cap_append, ast_format_cap_append_from_cap(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_iscompatible_format(), ast_format_cap_remove_by_type(), ast_format_cap_replace_from_cap(), AST_FORMAT_CMP_NOT_EQUAL, ast_log, AST_LOG_NOTICE, AST_MEDIA_TYPE_UNKNOWN, ast_strdupa, ast_strip(), ast_strlen_zero, ast_verb, sip_pvt::caps, codec_list, sip_pvt::jointcaps, NULL, sip_pvt::outgoing_call, sip_pvt::owner, and pbx_builtin_getvar_helper().

Referenced by sip_answer(), transmit_invite(), transmit_reinvite_with_sdp(), and transmit_response_with_sdp().

7406 {
7407  const char *codec_list;
7408  char *codec_list_copy;
7409  struct ast_format_cap *original_jointcaps;
7410  char *codec;
7411  int first_codec = 1;
7412 
7413  char *strtok_ptr;
7414 
7415  if (p->outgoing_call) {
7416  codec_list = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC_OUTBOUND");
7417  } else if (!(codec_list = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC_INBOUND"))) {
7418  codec_list = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC");
7419  }
7420 
7421  if (ast_strlen_zero(codec_list)) {
7422  return;
7423  }
7424 
7425  codec_list_copy = ast_strdupa(codec_list);
7426 
7427  original_jointcaps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
7428  if (!original_jointcaps) {
7429  return;
7430  }
7432 
7433  for (codec = strtok_r(codec_list_copy, ",", &strtok_ptr); codec; codec = strtok_r(NULL, ",", &strtok_ptr)) {
7434  struct ast_format *fmt;
7435 
7436  codec = ast_strip(codec);
7437 
7438  fmt = ast_format_cache_get(codec);
7439  if (!fmt) {
7440  ast_log(AST_LOG_NOTICE, "Ignoring ${SIP_CODEC*} variable because of unrecognized/not configured codec %s (check allow/disallow in sip.conf)\n", codec);
7441  continue;
7442  }
7443  if (ast_format_cap_iscompatible_format(original_jointcaps, fmt) != AST_FORMAT_CMP_NOT_EQUAL) {
7444  if (first_codec) {
7445  ast_verb(4, "Set codec to '%s' for this call because of ${SIP_CODEC*} variable\n", codec);
7447  ast_format_cap_append(p->jointcaps, fmt, 0);
7449  ast_format_cap_append(p->caps, fmt, 0);
7450  first_codec = 0;
7451  } else {
7452  ast_verb(4, "Add codec to '%s' for this call because of ${SIP_CODEC*} variable\n", codec);
7453  /* Add the format to the capabilities structure */
7454  ast_format_cap_append(p->jointcaps, fmt, 0);
7455  ast_format_cap_append(p->caps, fmt, 0);
7456  }
7457  } else {
7458  ast_log(AST_LOG_NOTICE, "Ignoring ${SIP_CODEC*} variable because it is not shared by both ends: %s\n", codec);
7459  }
7460 
7461  ao2_ref(fmt, -1);
7462  }
7463 
7464  /* The original joint formats may have contained negotiated parameters (fmtp)
7465  * like the Opus Codec or iLBC 20. The cached formats contain the default
7466  * parameters, which could be different than the negotiated (joint) result. */
7468 
7469  ao2_ref(original_jointcaps, -1);
7470  return;
7471  }
unsigned short outgoing_call
Definition: sip.h:1083
struct ast_format_cap * jointcaps
Definition: sip.h:1100
Definition of a media format.
Definition: format.c:43
void ast_format_cap_replace_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type)
Replace the formats of provided type in dst with equivalent formats from src.
Definition: format_cap.c:306
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:463
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
#define ast_format_cache_get(name)
Definition: format_cache.h:286
#define ast_strlen_zero(foo)
Definition: strings.h:52
enum ast_format_cmp_res ast_format_cap_iscompatible_format(const struct ast_format_cap *cap, const struct ast_format *format)
Find if ast_format is within the capabilities of the ast_format_cap object.
Definition: format_cap.c:583
#define AST_LOG_NOTICE
Definition: logger.h:268
#define ast_log
Definition: astobj2.c:42
struct ast_format_cap * caps
Definition: sip.h:1099
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:219
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static struct ast_codec codec_list[]
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define ast_format_cap_append(cap, format, framing)
Definition: format_cap.h:103
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
void ast_format_cap_remove_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Remove all formats matching a specific format type.
Definition: format_cap.c:525
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
struct ast_channel * owner
Definition: sip.h:1138
int ast_format_cap_append_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type)
Append the formats of provided type in src to dst.
Definition: format_cap.c:269

◆ uac_sips_contact()

static int uac_sips_contact ( struct sip_request req)
static

Determine if, as a UAC, we need to use a SIPS Contact.

This uses the rules defined in RFC 3621 section 8.1.1.8 to determine if a SIPS URI should be used as the Contact header on our outgoing request.

Parameters
reqThe outgoing SIP request
Return values
0SIPS is not required
1SIPS is required

Definition at line 14351 of file chan_sip.c.

References ast_strdupa, get_in_brackets(), REQ_OFFSET_TO_STR, and sip_get_header().

Referenced by build_contact().

14352 {
14353  const char *route = sip_get_header(req, "Route");
14354 
14355  if (!strncmp(REQ_OFFSET_TO_STR(req, rlpart2), "sips:", 5)) {
14356  return 1;
14357  }
14358 
14359  if (route) {
14360  char *route_uri = get_in_brackets(ast_strdupa(route));
14361 
14362  if (!strncmp(route_uri, "sips:", 5)) {
14363  return 1;
14364  }
14365  }
14366 
14367  return 0;
14368 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
char * get_in_brackets(char *tmp)
Pick out text in brackets from character string.
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define REQ_OFFSET_TO_STR(req, offset)
Definition: sip.h:858

◆ uas_sips_contact()

static int uas_sips_contact ( struct sip_request req)
static

Determine if, as a UAS, we need to use a SIPS Contact.

This uses the rules defined in RFC 3261 section 12.1.1 to determine if a SIPS URI should be used as the Contact header when responding to incoming SIP requests.

Parameters
reqThe incoming SIP request
Return values
0SIPS is not required
1SIPS is required

Definition at line 14314 of file chan_sip.c.

References ast_strdupa, get_in_brackets(), REQ_OFFSET_TO_STR, and sip_get_header().

Referenced by build_contact().

14315 {
14316  const char *record_route = sip_get_header(req, "Record-Route");
14317 
14318  if (!strncmp(REQ_OFFSET_TO_STR(req, rlpart2), "sips:", 5)) {
14319  return 1;
14320  }
14321 
14322  if (record_route) {
14323  char *record_route_uri = get_in_brackets(ast_strdupa(record_route));
14324 
14325  if (!strncmp(record_route_uri, "sips:", 5)) {
14326  return 1;
14327  }
14328  } else {
14329  const char *contact = sip_get_header(req, "Contact");
14330  char *contact_uri = get_in_brackets(ast_strdupa(contact));
14331 
14332  if (!strncmp(contact_uri, "sips:", 5)) {
14333  return 1;
14334  }
14335  }
14336 
14337  return 0;
14338 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
char * get_in_brackets(char *tmp)
Pick out text in brackets from character string.
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define REQ_OFFSET_TO_STR(req, offset)
Definition: sip.h:858

◆ unlink_all_peers_from_tables()

static void unlink_all_peers_from_tables ( void  )
static

Definition at line 3277 of file chan_sip.c.

References SIP_PEERS_ALL, and unlink_peers_from_tables().

Referenced by unload_module().

3278 {
3280 }
static void unlink_peers_from_tables(peer_unlink_flag_t flag)
Definition: chan_sip.c:3249

◆ unlink_marked_peers_from_tables()

static void unlink_marked_peers_from_tables ( void  )
static

Definition at line 3272 of file chan_sip.c.

References SIP_PEERS_MARKED, and unlink_peers_from_tables().

Referenced by sip_do_reload(), and sip_prune_realtime().

3273 {
3275 }
static void unlink_peers_from_tables(peer_unlink_flag_t flag)
Definition: chan_sip.c:3249

◆ unlink_peers_from_tables()

static void unlink_peers_from_tables ( peer_unlink_flag_t  flag)
static

Definition at line 3249 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_t_callback, match_and_cleanup_peer_sched(), OBJ_MULTIPLE, and OBJ_UNLINK.

Referenced by unlink_all_peers_from_tables(), and unlink_marked_peers_from_tables().

3250 {
3251  struct ao2_iterator *peers_iter;
3252 
3253  /*
3254  * We must remove the ref outside of the peers container to prevent
3255  * a deadlock condition when unsubscribing from stasis while it is
3256  * invoking a subscription event callback.
3257  */
3258  peers_iter = ao2_t_callback(peers, OBJ_UNLINK | OBJ_MULTIPLE,
3259  match_and_cleanup_peer_sched, &flag, "initiating callback to remove marked peers");
3260  if (peers_iter) {
3261  ao2_iterator_destroy(peers_iter);
3262  }
3263 
3265  match_and_cleanup_peer_sched, &flag, "initiating callback to remove marked peers_by_ip");
3266  if (peers_iter) {
3267  ao2_iterator_destroy(peers_iter);
3268  }
3269 }
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
static int match_and_cleanup_peer_sched(void *peerobj, void *arg, int flags)
Definition: chan_sip.c:3232
static struct ao2_container * peers_by_ip
Definition: chan_sip.c:1053
#define ao2_t_callback(c, flags, cb_fn, arg, tag)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.
Definition: astobj2.h:1714
long int flag
Definition: f2c.h:83
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841

◆ unload_module()

static int unload_module ( void  )
static

PBX unload module API.

Definition at line 35708 of file chan_sip.c.

References acl_change_event_stasis_unsubscribe(), ao2_cleanup, ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_cleanup, ao2_t_global_obj_release, 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_by_name(), ast_custom_function_unregister(), ast_debug, ast_free, ast_free_acl_list(), ast_free_ha(), ast_io_remove(), ast_logger_unregister_level(), ast_manager_unregister(), AST_MODFLAG_LOAD_ORDER, AST_MODPRI_CHANNEL_DRIVER, AST_MODULE_INFO(), AST_MODULE_SUPPORT_DEPRECATED, ast_msg_tech_unregister(), ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_rtp_dtls_cfg_free(), ast_rtp_glue_unregister(), ast_sched_context_destroy(), ast_sched_dump(), ast_sched_runq(), ast_sip_api_provider_unregister(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_ssl_teardown(), ast_tcptls_server_stop(), AST_TEST_UNREGISTER, ast_tvdiff_sec(), ast_tvnow(), ast_unload_realtime(), ast_unregister_application(), ast_websocket_remove_protocol(), ASTERISK_GPL_KEY, authl_lock, ast_tls_config::cafile, ast_channel_tech::capabilities, ast_tls_config::capath, sip_settings::caps, ast_tls_config::certfile, ast_tls_config::cipher, cleanup_all_regs(), clear_sip_domains(), sip_settings::contact_acl, destroy_escs(), dialog_unlink_all(), io_context_destroy(), load_module(), log_level, ast_tcptls_session_args::master, monitor_thread, monlock, network_change_stasis_unsubscribe(), NULL, sip_pvt::owner, ast_tls_config::pvtfile, reload(), shutdown_mwi_subscription(), sip_cfg, sip_epa_unregister_all(), sip_reqresp_parser_exit(), sip_unregister_tests(), sip_websocket_callback(), sipsock, sipsock_read_id, STASIS_MESSAGE_TYPE_CLEANUP, sip_threadinfo::stop, thread, sip_threadinfo::threadid, ast_tcptls_session_args::tls_cfg, unlink_all_peers_from_tables(), used_context, and sip_settings::websocket_enabled.

Referenced by load_module(), and startup_event_cb().

35709 {
35710  struct sip_pvt *p;
35711  struct sip_threadinfo *th;
35712  struct ao2_iterator i;
35713  struct timeval start;
35714 
35716 
35718 
35719  if (sip_cfg.websocket_enabled) {
35721  }
35722 
35725 
35726  /* First, take us out of the channel type list */
35731 
35732  /* Unregister dial plan functions */
35737 
35738  /* Unregister dial plan applications */
35742 #ifdef TEST_FRAMEWORK
35744 
35745  AST_TEST_UNREGISTER(test_sip_mwi_subscribe_parse);
35746  AST_TEST_UNREGISTER(test_tcp_message_fragmentation);
35747  AST_TEST_UNREGISTER(get_in_brackets_const_test);
35748 #endif
35749  /* Unregister CLI commands */
35751 
35752  /* Disconnect from RTP engine */
35754 
35755  /* Unregister AMI actions */
35756  ast_manager_unregister("SIPpeers");
35757  ast_manager_unregister("SIPshowpeer");
35758  ast_manager_unregister("SIPqualifypeer");
35759  ast_manager_unregister("SIPshowregistry");
35760  ast_manager_unregister("SIPnotify");
35761  ast_manager_unregister("SIPpeerstatus");
35762 
35763  /* Kill TCP/TLS server threads */
35764  if (sip_tcp_desc.master) {
35766  }
35767  if (sip_tls_desc.master) {
35769  }
35771 
35772  /* Kill all existing TCP/TLS threads */
35773  i = ao2_iterator_init(threadt, 0);
35774  while ((th = ao2_t_iterator_next(&i, "iterate through tcp threads for 'sip show tcp'"))) {
35775  pthread_t thread = th->threadid;
35776  th->stop = 1;
35777  pthread_kill(thread, SIGURG);
35778  ao2_t_ref(th, -1, "decrement ref from iterator");
35779  }
35781 
35782  /* Hangup all dialogs if they have an owner */
35783  i = ao2_iterator_init(dialogs, 0);
35784  while ((p = ao2_t_iterator_next(&i, "iterate thru dialogs"))) {
35785  if (p->owner)
35787  ao2_t_ref(p, -1, "toss dialog ptr from iterator_next");
35788  }
35790 
35793  pthread_t th = monitor_thread;
35795  pthread_cancel(th);
35796  pthread_kill(th, SIGURG);
35798  pthread_join(th, NULL);
35799  } else {
35802  }
35803 
35804  /* Clear containers */
35806  cleanup_all_regs();
35808  destroy_escs();
35810 
35811  {
35812  struct ao2_iterator iter;
35813  struct sip_subscription_mwi *mwi;
35814 
35816  while ((mwi = ao2_t_iterator_next(&iter, "unload_module iter"))) {
35818  ao2_t_ref(mwi, -1, "unload_module iter");
35819  }
35820  ao2_iterator_destroy(&iter);
35821  }
35822 
35823  /* Destroy all the dialogs and free their memory */
35824  i = ao2_iterator_init(dialogs, 0);
35825  while ((p = ao2_t_iterator_next(&i, "iterate thru dialogs"))) {
35826  dialog_unlink_all(p);
35827  ao2_t_ref(p, -1, "throw away iterator result");
35828  }
35830 
35831  /*
35832  * Since the monitor thread runs the scheduled events and we
35833  * just stopped the monitor thread above, we have to run any
35834  * pending scheduled immediate events in this thread.
35835  */
35837 
35838  /*
35839  * Wait awhile for the TCP/TLS thread container to become empty.
35840  *
35841  * XXX This is a hack, but the worker threads cannot be created
35842  * joinable. They can die on their own and remove themselves
35843  * from the container thus resulting in a huge memory leak.
35844  */
35845  start = ast_tvnow();
35846  while (ao2_container_count(threadt) && (ast_tvdiff_sec(ast_tvnow(), start) < 5)) {
35847  sched_yield();
35848  }
35850  ast_debug(2, "TCP/TLS thread container did not become empty :(\n");
35851 
35852  return -1;
35853  }
35854 
35855  /* Free memory for local network address mask */
35857 
35859  if (authl) {
35860  ao2_t_cleanup(authl, "Removing global authentication");
35861  authl = NULL;
35862  }
35864 
35870 
35872 
35875 
35876  ao2_t_global_obj_release(g_bogus_peer, "Release the bogus peer.");
35877 
35878  ao2_t_cleanup(peers, "unref the peers table");
35879  ao2_t_cleanup(peers_by_ip, "unref the peers_by_ip table");
35880  ao2_t_cleanup(dialogs, "unref the dialogs table");
35881  ao2_t_cleanup(dialogs_needdestroy, "unref dialogs_needdestroy");
35882  ao2_t_cleanup(dialogs_rtpcheck, "unref dialogs_rtpcheck");
35883  ao2_t_cleanup(threadt, "unref the thread table");
35884  ao2_t_cleanup(sip_monitor_instances, "unref the sip_monitor_instances table");
35885 
35887  if (sipsock_read_id) {
35890  }
35891  close(sipsock);
35894  sched = NULL;
35896  ast_unload_realtime("sipregs");
35897  ast_unload_realtime("sippeers");
35898 
35901 
35902  if (notify_types) {
35904  notify_types = NULL;
35905  }
35906 
35910  sip_cfg.caps = NULL;
35911 
35912  STASIS_MESSAGE_TYPE_CLEANUP(session_timeout_type);
35913  if (log_level != -1) {
35914  ast_logger_unregister_level("SIP_HISTORY");
35915  }
35916 
35917  return 0;
35918 }
static struct ao2_container * dialogs
Definition: chan_sip.c:1043
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
static struct ao2_container * threadt
The table of TCP threads.
Definition: chan_sip.c:1049
static struct ast_tcptls_session_args sip_tls_desc
The TCP/TLS server definition.
Definition: chan_sip.c:2394
pthread_t thread
Definition: app_meetme.c:1089
int stop
Definition: sip.h:1443
void ast_sip_api_provider_unregister(void)
Unregister a SIP API provider.
Definition: sip_api.c:57
char * pvtfile
Definition: tcptls.h:90
#define ao2_t_cleanup(obj, tag)
Definition: astobj2.h:1959
void ast_cc_agent_unregister(const struct ast_cc_agent_callbacks *callbacks)
Unregister a set of agent callbacks with the core.
Definition: ccss.c:1254
static struct ast_ha * localaddr
List of local networks We store "localnet" addresses from the config file into an access list...
Definition: chan_sip.c:1147
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static struct ast_tls_config default_tls_cfg
Default TLS connection configuration.
Definition: chan_sip.c:2377
void ast_ssl_teardown(struct ast_tls_config *cfg)
free resources used by an SSL server
Definition: tcptls.c:575
int ast_sched_runq(struct ast_sched_context *con)
Runs the queue.
Definition: sched.c:755
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
struct ao2_container * dialogs_needdestroy
Definition: chan_sip.c:1024
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition: channel.c:570
static ast_mutex_t monlock
Protect the monitoring thread, so only one process can kill or start it, and not when it&#39;s doing some...
Definition: chan_sip.c:897
static void network_change_stasis_unsubscribe(void)
Definition: chan_sip.c:17557
static struct sip_auth_container * authl
Authentication container for realm authentication.
Definition: chan_sip.c:1079
int64_t ast_tvdiff_sec(struct timeval end, struct timeval start)
Computes the difference (in seconds) between two struct timeval instances.
Definition: time.h:64
int ast_unload_realtime(const char *family)
Release any resources cached for a realtime family.
Definition: main/config.c:3406
static void acl_change_event_stasis_unsubscribe(void)
Definition: chan_sip.c:17573
static struct ast_rtp_glue sip_rtp_glue
Definition: chan_sip.c:34005
static struct ast_cli_entry cli_sip[]
SIP Cli commands definition.
Definition: chan_sip.c:34698
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
Definition: stasis.h:1523
Definition: sched.c:76
struct ao2_container * sip_monitor_instances
Definition: chan_sip.c:1164
static struct ast_config * notify_types
Definition: chan_sip.c:1153
#define ao2_t_global_obj_release(holder, tag)
Release the ao2 object held in the global holder.
Definition: astobj2.h:863
static struct ast_tcptls_session_args sip_tcp_desc
The TCP server definition.
Definition: chan_sip.c:2383
static int * sipsock_read_id
Definition: chan_sip.c:910
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
static void sip_websocket_callback(struct ast_websocket *session, struct ast_variable *parameters, struct ast_variable *headers)
SIP WebSocket connection handler.
Definition: chan_sip.c:2678
#define ast_mutex_lock(a)
Definition: lock.h:187
static struct ast_custom_function sippeer_function
Structure to declare a dialplan function: SIPPEER.
Definition: chan_sip.c:23520
static char * app_sipaddheader
Definition: chan_sip.c:34017
static ast_mutex_t authl_lock
Global authentication container protection while adjusting the references.
Definition: chan_sip.c:1081
#define NULL
Definition: resample.c:96
int websocket_enabled
Definition: sip.h:791
pthread_t threadid
Definition: sip.h:1445
static int log_level
Definition: chan_sip.c:665
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
static struct ao2_container * registry_list
The register list: Other SIP proxies we register with and receive calls from.
Definition: chan_sip.c:1061
static struct ao2_container * peers_by_ip
Definition: chan_sip.c:1053
int ast_context_destroy_by_name(const char *context, const char *registrar)
Destroy a context by name.
Definition: pbx.c:8244
static char used_context[AST_MAX_CONTEXT]
Definition: chan_sip.c:891
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 stor...
Definition: chan_sip.c:3367
void ast_logger_unregister_level(const char *name)
Unregister a previously registered logger level.
Definition: logger.c:2536
static struct ast_custom_function sip_header_function
Definition: chan_sip.c:23305
static void destroy_escs(void)
Definition: chan_sip.c:1830
Definition of a thread that handles a socket.
Definition: sip.h:1441
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static const struct ast_msg_tech sip_msg_tech
Definition: chan_sip.c:27833
void io_context_destroy(struct io_context *ioc)
Destroys a context.
Definition: io.c:107
#define AST_PTHREADT_NULL
Definition: lock.h:66
static char * app_sipsendcustominfo
Definition: chan_sip.c:34020
static void unlink_all_peers_from_tables(void)
Definition: chan_sip.c:3277
int ast_softhangup(struct ast_channel *chan, int reason)
Softly hangup up a channel.
Definition: channel.c:2476
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
static struct ast_custom_function sip_headers_function
Definition: chan_sip.c:23389
int AST_OPTIONAL_API_NAME() ast_websocket_remove_protocol(const char *name, ast_websocket_callback callback)
static struct io_context * io
Definition: chan_sip.c:909
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:7258
int ast_msg_tech_unregister(const struct ast_msg_tech *tech)
Unregister a message technology.
Definition: message.c:1610
#define ao2_t_iterator_next(iter, tag)
Definition: astobj2.h:1931
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128
struct ast_acl_list * ast_free_acl_list(struct ast_acl_list *acl)
Free a list of ACLs.
Definition: acl.c:233
static struct ast_cc_agent_callbacks sip_cc_agent_callbacks
Definition: chan_sip.c:1618
static void sip_unregister_tests(void)
SIP test registration.
Definition: chan_sip.c:34733
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
char * cafile
Definition: tcptls.h:92
struct ast_format_cap * capabilities
Definition: channel.h:633
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
static void clear_sip_domains(void)
Clear our domain list (at reload)
Definition: chan_sip.c:31337
static int sipsock
Main socket for UDP SIP communication.
Definition: chan_sip.c:1104
#define ast_free(a)
Definition: astmm.h:182
struct ast_channel * owner
Definition: sip.h:1138
static void sip_epa_unregister_all(void)
Definition: chan_sip.c:1651
void sip_reqresp_parser_exit(void)
Free resources used by request and response parser.
char * certfile
Definition: tcptls.h:89
struct ast_format_cap * caps
Global list of addresses dynamic peers are not allowed to use.
Definition: sip.h:787
int ast_io_remove(struct io_context *ioc, int *id)
Removes an IO context.
Definition: io.c:245
void ast_free_ha(struct ast_ha *ha)
Free a list of HAs.
Definition: acl.c:222
Definition of an MWI subscription to another server.
Definition: sip.h:1454
static char * app_dtmfmode
Definition: chan_sip.c:34016
static void cleanup_all_regs(void)
Definition: chan_sip.c:32502
static struct ast_cc_monitor_callbacks sip_cc_monitor_callbacks
Definition: chan_sip.c:2093
static struct ao2_container * subscription_mwi_list
The MWI subscription list.
Definition: chan_sip.c:1064
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
void ast_rtp_dtls_cfg_free(struct ast_rtp_dtls_cfg *dtls_cfg)
Free contents of a DTLS configuration structure.
Definition: rtp_engine.c:3131
void ast_sched_dump(struct ast_sched_context *con)
Dumps the scheduler contents.
Definition: sched.c:712
#define AST_PTHREADT_STOP
Definition: lock.h:67
int ast_rtp_glue_unregister(struct ast_rtp_glue *glue)
Unregister RTP glue.
Definition: rtp_engine.c:408
void ast_cc_monitor_unregister(const struct ast_cc_monitor_callbacks *callbacks)
Unregister a set of monitor callbacks with the core.
Definition: ccss.c:1217
char * capath
Definition: tcptls.h:93
void ast_tcptls_server_stop(struct ast_tcptls_session_args *desc)
Shutdown a running server if there is one.
Definition: tcptls.c:849
struct ast_tls_config * tls_cfg
Definition: tcptls.h:134
struct ast_acl_list * contact_acl
Definition: sip.h:786
struct ast_channel_tech sip_tech
Definition of this channel for PBX channel registration.
Definition: chan_sip.c:1573
struct ao2_container * dialogs_rtpcheck
Definition: chan_sip.c:1032
static struct ast_rtp_dtls_cfg default_dtls_cfg
Default DTLS connection configuration.
Definition: chan_sip.c:2380
static char * app_sipremoveheader
Definition: chan_sip.c:34018
static void shutdown_mwi_subscription(struct sip_subscription_mwi *mwi)
Definition: chan_sip.c:14952
static pthread_t monitor_thread
This is the thread for the monitor which checks for input on the channels which are not currently in ...
Definition: chan_sip.c:903
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
char * cipher
Definition: tcptls.h:91
void ast_sched_context_destroy(struct ast_sched_context *c)
destroys a schedule context
Definition: sched.c:269
static struct ast_custom_function checksipdomain_function
Definition: chan_sip.c:23409
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ update_call_counter()

static int update_call_counter ( struct sip_pvt fup,
int  event 
)
static

update_call_counter: Handle call_limit for SIP devices Setting a call-limit will cause calls above the limit not to be accepted.

Remember that for a type=friend, there's one limit for the user and another for the peer, not a combined call limit. This will cause unexpected behaviour in subscriptions, since a "friend" is two devices in Asterisk, not one.

Thought: For realtime, we should probably update storage with inuse counter...

Returns
0 if call is ok (no call limit, below threshold) -1 on rejection of call

Definition at line 6844 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, sip_peer::call_limit, DEC_CALL_LIMIT, DEC_CALL_RINGING, FALSE, sip_pvt::flags, INC_CALL_LIMIT, INC_CALL_RINGING, sip_peer::inuse, LOG_ERROR, LOG_NOTICE, name, sip_peer::name, sip_settings::notifyhold, NULL, sip_pvt::outgoing_call, sip_pvt::peername, sip_pvt::relatedpeer, sip_peer::ringing, ringing(), SIP_CALL_LIMIT, sip_cfg, SIP_INC_COUNT, SIP_INC_RINGING, SIP_PAGE2_CALL_ONHOLD, sip_peer_hold(), sip_pvt_lock, sip_pvt_unlock, sip_ref_peer, sip_unref_peer, sipdebug, and sip_pvt::username.

Referenced by handle_request_cancel(), handle_request_invite(), handle_response_invite(), sip_call(), sip_hangup(), and sip_pvt_dtor().

6845 {
6846  char name[256];
6847  int *inuse = NULL, *call_limit = NULL, *ringing = NULL;
6848  int outgoing = fup->outgoing_call;
6849  struct sip_peer *p = NULL;
6850 
6851  ast_debug(3, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming");
6852 
6853 
6854  /* Test if we need to check call limits, in order to avoid
6855  realtime lookups if we do not need it */
6857  return 0;
6858 
6859  ast_copy_string(name, fup->username, sizeof(name));
6860 
6861  /* Check the list of devices */
6862  if (fup->relatedpeer) {
6863  p = sip_ref_peer(fup->relatedpeer, "ref related peer for update_call_counter");
6864  inuse = &p->inuse;
6865  call_limit = &p->call_limit;
6866  ringing = &p->ringing;
6867  ast_copy_string(name, fup->peername, sizeof(name));
6868  }
6869  if (!p) {
6870  ast_debug(2, "%s is not a local device, no call limit\n", name);
6871  return 0;
6872  }
6873 
6874  switch(event) {
6875  /* incoming and outgoing affects the inuse counter */
6876  case DEC_CALL_LIMIT:
6877  /* Decrement inuse count if applicable */
6878  if (inuse) {
6879  sip_pvt_lock(fup);
6880  ao2_lock(p);
6881  if (*inuse > 0) {
6882  if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) {
6883  (*inuse)--;
6884  ast_clear_flag(&fup->flags[0], SIP_INC_COUNT);
6885  }
6886  } else {
6887  *inuse = 0;
6888  }
6889  ao2_unlock(p);
6890  sip_pvt_unlock(fup);
6891  }
6892 
6893  /* Decrement ringing count if applicable */
6894  if (ringing) {
6895  sip_pvt_lock(fup);
6896  ao2_lock(p);
6897  if (*ringing > 0) {
6898  if (ast_test_flag(&fup->flags[0], SIP_INC_RINGING)) {
6899  (*ringing)--;
6901  }
6902  } else {
6903  *ringing = 0;
6904  }
6905  ao2_unlock(p);
6906  sip_pvt_unlock(fup);
6907  }
6908 
6909  /* Decrement onhold count if applicable */
6910  sip_pvt_lock(fup);
6911  ao2_lock(p);
6914  ao2_unlock(p);
6915  sip_pvt_unlock(fup);
6916  sip_peer_hold(fup, FALSE);
6917  } else {
6918  ao2_unlock(p);
6919  sip_pvt_unlock(fup);
6920  }
6921  if (sipdebug)
6922  ast_debug(2, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", "peer", name, *call_limit);
6923  break;
6924 
6925  case INC_CALL_RINGING:
6926  case INC_CALL_LIMIT:
6927  /* If call limit is active and we have reached the limit, reject the call */
6928  if (*call_limit > 0 ) {
6929  if (*inuse >= *call_limit) {
6930  ast_log(LOG_NOTICE, "Call %s %s '%s' rejected due to usage limit of %d\n", outgoing ? "to" : "from", "peer", name, *call_limit);
6931  sip_unref_peer(p, "update_call_counter: unref peer p, call limit exceeded");
6932  return -1;
6933  }
6934  }
6935  if (ringing && (event == INC_CALL_RINGING)) {
6936  sip_pvt_lock(fup);
6937  ao2_lock(p);
6938  if (!ast_test_flag(&fup->flags[0], SIP_INC_RINGING)) {
6939  (*ringing)++;
6940  ast_set_flag(&fup->flags[0], SIP_INC_RINGING);
6941  }
6942  ao2_unlock(p);
6943  sip_pvt_unlock(fup);
6944  }
6945  if (inuse) {
6946  sip_pvt_lock(fup);
6947  ao2_lock(p);
6948  if (!ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) {
6949  (*inuse)++;
6950  ast_set_flag(&fup->flags[0], SIP_INC_COUNT);
6951  }
6952  ao2_unlock(p);
6953  sip_pvt_unlock(fup);
6954  }
6955  if (sipdebug) {
6956  ast_debug(2, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", "peer", name, *inuse, *call_limit);
6957  }
6958  break;
6959 
6960  case DEC_CALL_RINGING:
6961  if (ringing) {
6962  sip_pvt_lock(fup);
6963  ao2_lock(p);
6964  if (ast_test_flag(&fup->flags[0], SIP_INC_RINGING)) {
6965  if (*ringing > 0) {
6966  (*ringing)--;
6967  }
6969  }
6970  ao2_unlock(p);
6971  sip_pvt_unlock(fup);
6972  }
6973  break;
6974 
6975  default:
6976  ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event);
6977  }
6978 
6980  sip_unref_peer(p, "update_call_counter: sip_unref_peer from call counter");
6981 
6982  return 0;
6983 }
#define SIP_INC_RINGING
Definition: sip.h:266
#define FALSE
Definition: app_minivm.c:521
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct sip_peer * relatedpeer
Definition: sip.h:1171
#define ast_set_flag(p, flag)
Definition: utils.h:70
unsigned short outgoing_call
Definition: sip.h:1083
const ast_string_field username
Definition: sip.h:1063
Definition: astman.c:222
#define SIP_CALL_LIMIT
Definition: sip.h:264
#define DEC_CALL_LIMIT
Definition: sip.h:127
#define SIP_PAGE2_CALL_ONHOLD
Definition: sip.h:351
#define ao2_unlock(a)
Definition: astobj2.h:730
struct ast_flags flags[3]
Definition: sip.h:1075
#define NULL
Definition: resample.c:96
#define sip_ref_peer(peer, tag)
Definition: sip.h:1894
int ringing
Definition: sip.h:1326
#define sip_pvt_unlock(x)
Definition: chan_sip.c:1046
char name[80]
Definition: sip.h:1274
#define sip_pvt_lock(x)
Definition: chan_sip.c:1044
int notifyhold
Definition: sip.h:774
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define SIP_INC_COUNT
Definition: sip.h:265
#define ast_log
Definition: astobj2.c:42
int ast_devstate_changed(enum ast_device_state state, enum ast_devstate_cache cachable, const char *fmt,...)
Tells Asterisk the State for Device is changed.
Definition: devicestate.c:510
#define DEC_CALL_RINGING
Definition: sip.h:129
static void ringing(struct ast_channel *chan)
Helper method to send a ringing indication to a channel in a bridge.
int call_limit
Definition: sip.h:1328
#define ao2_lock(a)
Definition: astobj2.h:718
#define LOG_ERROR
Definition: logger.h:285
static enum sip_debug_e sipdebug
Definition: chan_sip.c:916
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
#define LOG_NOTICE
Definition: logger.h:263
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
static const char name[]
Definition: cdr_mysql.c:74
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
#define INC_CALL_RINGING
Definition: sip.h:130
const ast_string_field peername
Definition: sip.h:1063
#define ast_clear_flag(p, flag)
Definition: utils.h:77
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int inuse
Definition: sip.h:1325
#define INC_CALL_LIMIT
Definition: sip.h:128
static void sip_peer_hold(struct sip_pvt *p, int hold)
Change onhold state of a peer using a pvt structure.
Definition: chan_sip.c:17511

◆ update_connectedline()

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

References add_header(), add_rpid(), add_sdp(), add_supported(), ALLOWED_METHODS, sip_pvt::allowed_methods, append_history, ast_channel_connected_effective_id(), ast_channel_name(), 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, sip_pvt::flags, initialize_initreq(), sip_pvt::initreq, INV_CONFIRMED, INV_TERMINATED, sip_pvt::invitestate, is_method_allowed(), sip_pvt::lastinvite, ast_party_id::name, ast_party_id::number, sip_pvt::ocseq, sip_pvt::okcontacturi, sip_pvt::owner, sip_pvt::pendinginvite, reqprep(), respprep(), S_COR, send_request(), send_response(), SIP_INVITE, SIP_NEEDREINVITE, SIP_OUTGOING, SIP_PAGE2_CONNECTLINEUPDATE_PEND, SIP_PAGE2_RPID_IMMEDIATE, SIP_PROGRESS_SENT, SIP_REINVITE_UPDATE, SIP_RINGING, SIP_SENDRPID, SIP_UPDATE, ast_party_name::str, ast_party_number::str, TRUE, ast_party_name::valid, ast_party_number::valid, XMIT_CRITICAL, and XMIT_UNRELIABLE.

Referenced by sip_indicate().

15770 {
15771  struct ast_party_id connected_id = ast_channel_connected_effective_id(p->owner);
15772 
15773  if (!ast_test_flag(&p->flags[0], SIP_SENDRPID)) {
15774  return;
15775  }
15776  if (!connected_id.number.valid
15777  || ast_strlen_zero(connected_id.number.str)) {
15778  return;
15779  }
15780 
15781  append_history(p, "ConnectedLine", "%s party is now %s <%s>",
15782  ast_test_flag(&p->flags[0], SIP_OUTGOING) ? "Calling" : "Called",
15783  S_COR(connected_id.name.valid, connected_id.name.str, ""),
15784  S_COR(connected_id.number.valid, connected_id.number.str, ""));
15785 
15787  struct sip_request req;
15788 
15789  if (!p->pendinginvite && (p->invitestate == INV_CONFIRMED || p->invitestate == INV_TERMINATED)) {
15790  reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1);
15791 
15792  add_header(&req, "Allow", ALLOWED_METHODS);
15793  add_supported(p, &req);
15794  add_rpid(&req, p);
15795  add_sdp(&req, p, FALSE, TRUE, FALSE);
15796 
15797  initialize_initreq(p, &req);
15798  p->lastinvite = p->ocseq;
15799  ast_set_flag(&p->flags[0], SIP_OUTGOING);
15800  send_request(p, &req, XMIT_CRITICAL, p->ocseq);
15802  reqprep(&req, p, SIP_UPDATE, 0, 1);
15803  add_rpid(&req, p);
15804  add_header(&req, "X-Asterisk-rpid-update", "Yes");
15805  send_request(p, &req, XMIT_CRITICAL, p->ocseq);
15806  } else {
15807  /* We cannot send the update yet, so we have to wait until we can */
15809  }
15810  } else {
15813  struct sip_request resp;
15814 
15817  respprep(&resp, p, "180 Ringing", &p->initreq);
15818  add_rpid(&resp, p);
15819  send_response(p, &resp, XMIT_UNRELIABLE, 0);
15820  ast_set_flag(&p->flags[0], SIP_RINGING);
15821  } else if (ast_channel_state(p->owner) == AST_STATE_RINGING) {
15823  respprep(&resp, p, "183 Session Progress", &p->initreq);
15824  add_rpid(&resp, p);
15825  send_response(p, &resp, XMIT_UNRELIABLE, 0);
15827  } else {
15828  ast_debug(1, "Unable able to send update to '%s' in state '%s'\n", ast_channel_name(p->owner), ast_state2str(ast_channel_state(p->owner)));
15829  }
15830  }
15831  }
15832 }
Information needed to identify an endpoint in a call.
Definition: channel.h:339
char * str
Subscriber phone number (Malloced)
Definition: channel.h:292
#define SIP_PAGE2_CONNECTLINEUPDATE_PEND
Definition: sip.h:329
#define FALSE
Definition: app_minivm.c:521
unsigned int allowed_methods
Definition: sip.h:1196
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_party_name name
Subscriber name.
Definition: channel.h:341
#define ast_set_flag(p, flag)
Definition: utils.h:70
uint32_t pendinginvite
Definition: sip.h:1147
static int add_supported(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.
Definition: chan_sip.c:11859
ast_channel_state
ast_channel states
Definition: channelstate.h:35
char * str
Subscriber name (Malloced)
Definition: channel.h:265
struct ast_flags flags[3]
Definition: sip.h:1075
#define SIP_RINGING
Definition: sip.h:259
const char * ast_state2str(enum ast_channel_state)
Gives the string form of a given channel state.
Definition: channel.c:642
#define SIP_PAGE2_RPID_IMMEDIATE
Definition: sip.h:330
#define ast_strlen_zero(foo)
Definition: strings.h:52
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)
Definition: chan_sip.c:12361
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct sip_request initreq
Definition: sip.h:1151
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:85
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.
Definition: chan_sip.c:13542
#define SIP_REINVITE_UPDATE
Definition: sip.h:291
struct ast_party_id ast_channel_connected_effective_id(struct ast_channel *chan)
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...
Definition: chan_sip.c:3444
static int send_request(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno)
Definition: chan_sip.c:4863
uint32_t ocseq
Definition: sip.h:1067
#define ALLOWED_METHODS
SIP Methods we support.
Definition: sip.h:173
struct ast_channel * owner
Definition: sip.h:1138
static int send_response(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno)
Transmit response on SIP request.
Definition: chan_sip.c:4821
static int add_rpid(struct sip_request *req, struct sip_pvt *p)
Add Remote-Party-ID header to SIP message.
Definition: chan_sip.c:12996
enum invitestates invitestate
Definition: sip.h:1007
#define ast_clear_flag(p, flag)
Definition: utils.h:77
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
static int is_method_allowed(unsigned int *allowed_methods, enum sipmethod method)
Check if method is allowed for a device or a dialog.
Definition: chan_sip.c:9806
const char * ast_channel_name(const struct ast_channel *chan)
#define TRUE
Definition: app_minivm.c:518
#define append_history(p, event, fmt, args...)
Append to SIP dialog history.
Definition: chan_sip.c:2406
uint32_t lastinvite
Definition: sip.h:1074
static int respprep(struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req)
Prepare SIP response packet.
Definition: chan_sip.c:12269
#define SIP_NEEDREINVITE
Definition: sip.h:261
#define SIP_OUTGOING
Definition: sip.h:257
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:280
static int add_header(struct sip_request *req, const char *var, const char *value)
Add header to SIP message.
Definition: chan_sip.c:11873
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:298
#define SIP_PROGRESS_SENT
Definition: sip.h:260
const ast_string_field okcontacturi
Definition: sip.h:1063
#define SIP_SENDRPID
Definition: sip.h:306
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:343

◆ update_peer()

static void update_peer ( struct sip_peer p,
int  expire 
)
static

Update peer data in database (if used)

Definition at line 5382 of file chan_sip.c.

References sip_peer::addr, ast_free, ast_str_buffer(), ast_test_flag, sip_peer::deprecated_username, sip_peer::flags, sip_peer::fullcontact, sip_peer::is_realtime, sip_peer::lastms, sip_peer::name, sip_peer::path, sip_settings::peer_rtupdate, realtime_update_peer(), sip_cfg, SIP_PAGE2_RTCACHEFRIENDS, sip_route_list(), sip_peer::useragent, and sip_peer::username.

Referenced by register_verify().

5383 {
5384  int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS);
5385  if (sip_cfg.peer_rtupdate && (p->is_realtime || rtcachefriends)) {
5386  struct ast_str *r = sip_route_list(&p->path, 0, 0);
5387  if (r) {
5388  realtime_update_peer(p->name, &p->addr, p->username,
5389  p->fullcontact, p->useragent, expire, p->deprecated_username,
5390  p->lastms, ast_str_buffer(r));
5391  ast_free(r);
5392  }
5393  }
5394 }
struct ast_sockaddr addr
Definition: sip.h:1352
#define ast_test_flag(p, flag)
Definition: utils.h:63
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
struct sip_route path
Definition: sip.h:1372
int peer_rtupdate
Definition: sip.h:750
char name[80]
Definition: sip.h:1274
struct ast_str * sip_route_list(const struct sip_route *route, int formatcli, int skip)
Make the comma separated list of route hops.
Definition: route.c:155
int lastms
Definition: sip.h:1356
const ast_string_field username
Definition: sip.h:1306
const ast_string_field useragent
Definition: sip.h:1306
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
const ast_string_field fullcontact
Definition: sip.h:1306
static struct sip_settings sip_cfg
Definition: chan_sip.c:809
#define SIP_PAGE2_RTCACHEFRIENDS
Definition: sip.h:323
unsigned short deprecated_username
Definition: sip.h:1321
#define ast_free(a)
Definition: astmm.h:182
unsigned short is_realtime
Definition: sip.h:1312
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, const char *path)
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: chan_sip.c:5167
struct ast_flags flags[3]
Definition: sip.h:1335

◆ update_peer_lastmsgssent()

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

Definition at line 17841 of file chan_sip.c.

References ao2_lock, ao2_unlock, sip_peer::lastmsgssent, and value.

Referenced by register_verify(), and sip_send_mwi_to_peer().

17842 {
17843  if (!locked) {
17844  ao2_lock(peer);
17845  }
17846  peer->lastmsgssent = value;
17847  if (!locked) {
17848  ao2_unlock(peer);
17849  }
17850 }
int lastmsgssent
Definition: sip.h:1333
#define ao2_unlock(a)
Definition: astobj2.h:730
int value
Definition: syslog.c:37
#define ao2_lock(a)
Definition: astobj2.h:718

◆ update_provisional_keepalive()

static void update_provisional_keepalive ( struct sip_pvt pvt,
int  with_sdp 
)
static

Definition at line 4762 of file chan_sip.c.

References __update_provisional_keepalive(), __update_provisional_keepalive_with_sdp(), ast_sched_add(), dialog_ref, and dialog_unref.

Referenced by transmit_provisional_response().

4763 {
4764  dialog_ref(pvt, "Update provisional keepalive action");
4765  if (ast_sched_add(sched, 0,
4767  pvt) < 0) {
4768  dialog_unref(pvt, "Failed to schedule update provisional keepalive action");
4769  }
4770 }
static int __update_provisional_keepalive(const void *data)
Definition: chan_sip.c:4747
Definition: sched.c:76
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
#define dialog_ref(dialog, tag)
when we create or delete references, make sure to use these functions so we keep track of the refcoun...
Definition: dialog.h:32
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565
static int __update_provisional_keepalive_with_sdp(const void *data)
Definition: chan_sip.c:4755

◆ update_redirecting()

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

References add_diversion(), AST_STATE_UP, ast_test_flag, sip_pvt::flags, sip_pvt::initreq, sip_pvt::owner, respprep(), send_response(), SIP_OUTGOING, and XMIT_UNRELIABLE.

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

15756 {
15757  struct sip_request resp;
15758 
15760  return;
15761  }
15762 
15763  respprep(&resp, p, "181 Call is being forwarded", &p->initreq);
15764  add_diversion(&resp, p);
15765  send_response(p, &resp, XMIT_UNRELIABLE, 0);
15766 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
ast_channel_state
ast_channel states
Definition: channelstate.h:35
struct ast_flags flags[3]
Definition: sip.h:1075
struct sip_request initreq
Definition: sip.h:1151
struct ast_channel * owner
Definition: sip.h:1138
static int send_response(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno)
Transmit response on SIP request.
Definition: chan_sip.c:4821
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
static void add_diversion(struct sip_request *req, struct sip_pvt *pvt)
Add "Diversion" header to outgoing message.
Definition: chan_sip.c:14653
static int respprep(struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req)
Prepare SIP response packet.
Definition: chan_sip.c:12269
#define SIP_OUTGOING
Definition: sip.h:257

◆ use_reason_header()

static int use_reason_header ( struct sip_pvt pvt,
struct sip_request req 
)
static

Parses SIP reason header according to RFC3326 and sets channel's hangupcause if configured so and header present.

Note
This is used in BYE and CANCEL request and SIP response, but according to RFC3326 it could appear in any request, but makes not a lot of sense in others than BYE or CANCEL. Currently only implemented for Q.850 status codes.
Return values
0success
-1on failure or if not configured

Definition at line 16841 of file chan_sip.c.

References ast_channel_hangupcause(), ast_channel_hangupcause_set(), ast_skip_blanks(), ast_test_flag, ast_verbose(), sip_request::debug, sip_pvt::flags, sip_pvt::owner, rh, sip_get_header(), and SIP_PAGE2_Q850_REASON.

Referenced by handle_request_bye(), handle_request_cancel(), and handle_response().

16842 {
16843  int ret, cause;
16844  const char *rp, *rh;
16845 
16846  if (!pvt->owner) {
16847  return -1;
16848  }
16849 
16850  if (!ast_test_flag(&pvt->flags[1], SIP_PAGE2_Q850_REASON) ||
16851  !(rh = sip_get_header(req, "Reason"))) {
16852  return -1;
16853  }
16854 
16855  rh = ast_skip_blanks(rh);
16856  if (strncasecmp(rh, "Q.850", 5)) {
16857  return -1;
16858  }
16859 
16860  ret = -1;
16861  cause = ast_channel_hangupcause(pvt->owner);
16862  rp = strstr(rh, "cause=");
16863  if (rp && sscanf(rp + 6, "%3d", &cause) == 1) {
16864  ret = 0;
16865  ast_channel_hangupcause_set(pvt->owner, cause & 0x7f);
16866  if (req->debug) {
16867  ast_verbose("Using Reason header for cause code: %d\n",
16869  }
16870  }
16871  return ret;
16872 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
char debug
Definition: sip.h:837
#define ast_test_flag(p, flag)
Definition: utils.h:63
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
struct ast_flags flags[3]
Definition: sip.h:1075
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
static rc_handle * rh
Definition: cdr_radius.c:96
#define SIP_PAGE2_Q850_REASON
Definition: sip.h:326
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
struct ast_channel * owner
Definition: sip.h:1138
int ast_channel_hangupcause(const struct ast_channel *chan)

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Session Initiation Protocol (SIP)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_DEPRECATED, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .requires = "ccss,dnsmgr,udptl", .optional_modules = "res_crypto,res_http_websocket", }
static

Definition at line 35928 of file chan_sip.c.

◆ acl_change_sub

struct stasis_subscription* acl_change_sub
static

subscription id for named ACL system change events

Definition at line 888 of file chan_sip.c.

◆ aliases

const struct cfalias aliases[]
static

Definition at line 8510 of file chan_sip.c.

Referenced by ooh323c_set_aliases(), and queue_mwi_event().

◆ allowoverlapstr

const struct _map_x_s allowoverlapstr[]
static

Definition at line 20623 of file chan_sip.c.

◆ apeerobjs

int apeerobjs = 0
static

Autocreated peer objects

Definition at line 881 of file chan_sip.c.

Referenced by sip_destroy_peer(), sip_show_objects(), and temp_peer().

◆ app_dtmfmode

char* app_dtmfmode = "SIPDtmfMode"
static

Definition at line 34016 of file chan_sip.c.

◆ app_sipaddheader

char* app_sipaddheader = "SIPAddHeader"
static

Definition at line 34017 of file chan_sip.c.

◆ app_sipremoveheader

char* app_sipremoveheader = "SIPRemoveHeader"
static

Definition at line 34018 of file chan_sip.c.

◆ app_sipsendcustominfo

char* app_sipsendcustominfo = "SIPSendCustomINFO"
static

Definition at line 34020 of file chan_sip.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 35928 of file chan_sip.c.

◆ authl

struct sip_auth_container* authl = NULL
static

Authentication container for realm authentication.

Definition at line 1079 of file chan_sip.c.

Referenced by build_reply_digest(), and sip_show_settings().

◆ authl_lock

ast_mutex_t authl_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
static

Global authentication container protection while adjusting the references.

Definition at line 1081 of file chan_sip.c.

Referenced by build_reply_digest(), reload_config(), sip_show_settings(), and unload_module().

◆ authlimit

int authlimit = DEFAULT_AUTHLIMIT
static

Definition at line 675 of file chan_sip.c.

Referenced by _sip_tcp_helper_thread(), and reload_config().

◆ authtimeout

int authtimeout = DEFAULT_AUTHTIMEOUT
static

Definition at line 676 of file chan_sip.c.

Referenced by _sip_tcp_helper_thread(), reload_config(), and sip_check_authtimeout().

◆ autopeermodes

struct _map_x_s autopeermodes[]
static

Definition at line 20026 of file chan_sip.c.

◆ bindaddr

struct ast_sockaddr bindaddr

◆ can_parse_xml

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

Referenced by build_peer(), and load_module().

◆ cc_epa_static_data

const struct epa_static_data cc_epa_static_data
static

Definition at line 1671 of file chan_sip.c.

◆ cc_esc_publish_callbacks

const struct sip_esc_publish_callbacks cc_esc_publish_callbacks
static
Initial value:
= {
.initial_handler = cc_esc_publish_handler,
.modify_handler = cc_esc_publish_handler,
}
static int cc_esc_publish_handler(struct sip_pvt *pvt, struct sip_request *req, struct event_state_compositor *esc, struct sip_esc_entry *esc_entry)
Definition: chan_sip.c:28201

Definition at line 978 of file chan_sip.c.

◆ chan_idx

unsigned int chan_idx
static

used in naming sip channel

Definition at line 818 of file chan_sip.c.

Referenced by sip_new().

◆ chan_sip_api_provider

const struct ast_sip_api_tech chan_sip_api_provider
static
Initial value:
= {
.version = AST_SIP_API_VERSION,
.name = "chan_sip",
.sipinfo_send = sipinfo_send,
}
static int sipinfo_send(struct ast_channel *chan, struct ast_variable *headers, const char *content_type, const char *content, const char *useragent_filter)
Definition: chan_sip.c:7897
#define AST_SIP_API_VERSION
Definition: sip_api.h:28

Definition at line 35446 of file chan_sip.c.

◆ checksipdomain_function

struct ast_custom_function checksipdomain_function
static
Initial value:
= {
.name = "CHECKSIPDOMAIN",
}
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.
Definition: chan_sip.c:23396

Definition at line 23409 of file chan_sip.c.

◆ cli_sip

struct ast_cli_entry cli_sip[]
static

SIP Cli commands definition.

Definition at line 34698 of file chan_sip.c.

◆ config

const char config[] = "sip.conf"
static

Main configuration file

Definition at line 690 of file chan_sip.c.

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

◆ debugaddr

struct ast_sockaddr debugaddr
static

Definition at line 1151 of file chan_sip.c.

Referenced by sip_debug_test_addr(), sip_do_debug(), sip_do_debug_ip(), and sip_do_debug_peer().

◆ default_callerid

char default_callerid[AST_MAX_EXTENSION]
static

Default caller ID for sip messages

Definition at line 791 of file chan_sip.c.

Referenced by initreqprep(), reload_config(), and sip_show_settings().

◆ default_dtls_cfg

struct ast_rtp_dtls_cfg default_dtls_cfg
static

Default DTLS connection configuration.

Definition at line 2380 of file chan_sip.c.

◆ default_engine

char default_engine[256]
static

Default RTP engine

Definition at line 803 of file chan_sip.c.

Referenced by __sip_alloc(), reload_config(), and set_peer_defaults().

◆ default_expiry

int default_expiry = DEFAULT_DEFAULT_EXPIRY
static

◆ default_fromdomain

char default_fromdomain[AST_MAX_EXTENSION]
static

Default domain on outound messages

Definition at line 793 of file chan_sip.c.

Referenced by __sip_alloc(), reload_config(), sip_show_settings(), transmit_register(), and transmit_response_using_temp().

◆ default_fromdomainport

int default_fromdomainport
static

Default domain port on outbound messages

Definition at line 794 of file chan_sip.c.

Referenced by __sip_alloc(), reload_config(), sip_show_settings(), and transmit_response_using_temp().

◆ default_jbconf

struct ast_jb_conf default_jbconf
static

Global jitterbuffer configuration - by default, jb is disabled.

Note
Values shown here match the defaults shown in sip.conf.sample

Definition at line 680 of file chan_sip.c.

◆ default_keepalive

int default_keepalive
static

Default keepalive= setting

Definition at line 798 of file chan_sip.c.

Referenced by reload_config(), set_peer_defaults(), and sip_show_settings().

◆ default_language

char default_language[MAX_LANGUAGE]
static

Default language setting for new channels

Definition at line 790 of file chan_sip.c.

Referenced by reload_config(), set_peer_defaults(), and sip_show_settings().

◆ default_maxcallbitrate

int default_maxcallbitrate
static

Maximum bitrate for call

Definition at line 804 of file chan_sip.c.

Referenced by __sip_alloc(), build_peer(), reload_config(), set_peer_defaults(), and sip_show_settings().

◆ default_mohinterpret

char default_mohinterpret[MAX_MUSICCLASS]
static

Global setting for moh class to use when put on hold

Definition at line 799 of file chan_sip.c.

Referenced by __sip_alloc(), reload_config(), set_peer_defaults(), and sip_show_settings().

◆ default_mohsuggest

char default_mohsuggest[MAX_MUSICCLASS]
static

Global setting for moh class to suggest when putting a bridged channel on hold

Definition at line 800 of file chan_sip.c.

Referenced by __sip_alloc(), reload_config(), set_peer_defaults(), and sip_show_settings().

◆ default_mwi_from

char default_mwi_from[80]
static

Default caller ID for MWI updates

Definition at line 792 of file chan_sip.c.

Referenced by reload_config(), and sip_send_mwi_to_peer().

◆ default_notifymime

char default_notifymime[AST_MAX_EXTENSION]
static

Default MIME media type for MWI notify messages

Definition at line 795 of file chan_sip.c.

Referenced by reload_config(), sip_show_settings(), and transmit_notify_with_mwi().

◆ default_parkinglot

char default_parkinglot[AST_MAX_CONTEXT]
static

Parkinglot

Definition at line 802 of file chan_sip.c.

Referenced by __sip_alloc(), and reload_config().

◆ default_primary_transport

unsigned int default_primary_transport
static

Default primary Transport (enum ast_transport) for outbound connections to devices

Definition at line 807 of file chan_sip.c.

Referenced by build_peer(), reload_config(), set_peer_defaults(), and sip_show_settings().

◆ DEFAULT_PUBLISH_EXPIRES

const int DEFAULT_PUBLISH_EXPIRES = 3600
static

Definition at line 973 of file chan_sip.c.

Referenced by determine_sip_publish_type(), and transmit_publish().

◆ default_qualify

int default_qualify
static

Default Qualify= setting

Definition at line 797 of file chan_sip.c.

Referenced by build_peer(), reload_config(), set_peer_defaults(), and sip_show_settings().

◆ default_tls_cfg

struct ast_tls_config default_tls_cfg
static

Default TLS connection configuration.

Definition at line 2377 of file chan_sip.c.

◆ default_transports

unsigned int default_transports
static

Default Transports (enum ast_transport) that are acceptable

Definition at line 806 of file chan_sip.c.

Referenced by build_peer(), reload_config(), set_peer_defaults(), and sip_show_settings().

◆ default_vmexten

char default_vmexten[AST_MAX_EXTENSION]
static

Default From Username on MWI updates

Definition at line 796 of file chan_sip.c.

Referenced by reload_config(), set_peer_defaults(), sip_show_settings(), and transmit_notify_with_mwi().

◆ default_zone

char default_zone[MAX_TONEZONE_COUNTRY]
static

Default tone zone for channels created from the SIP driver

Definition at line 805 of file chan_sip.c.

Referenced by __sip_alloc(), reload_config(), set_peer_defaults(), and sip_show_settings().

◆ dialogs

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

◆ dialogs_needdestroy

struct ao2_container* dialogs_needdestroy

Here we implement the container for dialogs which are in the dialog_needdestroy state to iterate only through the dialogs unlink them instead of iterate through all dialogs

Definition at line 1024 of file chan_sip.c.

◆ dialogs_rtpcheck

struct ao2_container* dialogs_rtpcheck

Here we implement the container for dialogs which have rtp traffic and rtptimeout, rtpholdtimeout or rtpkeepalive set. We use this container instead the whole dialog list.

Definition at line 1032 of file chan_sip.c.

◆ domain_list

struct domain_list domain_list = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
static

The SIP domain list

◆ dtmfstr

const struct _map_x_s dtmfstr[]
static

mapping between dtmf flags and strings

Definition at line 20588 of file chan_sip.c.

Referenced by conf_run(), and send_dtmf().

◆ dumphistory

unsigned int dumphistory
static

Dump history to verbose before destroying SIP dialog

Definition at line 842 of file chan_sip.c.

Referenced by append_history_full(), reload_config(), and sip_pvt_dtor().

◆ epa_static_data_list

struct epa_static_data_list epa_static_data_list = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }

◆ esc_etag_counter

int esc_etag_counter
static

Used to create new entity IDs by ESCs.

Definition at line 972 of file chan_sip.c.

Referenced by create_new_sip_etag().

◆ ESC_MAX_BUCKETS

const int ESC_MAX_BUCKETS = 37
static

Definition at line 1016 of file chan_sip.c.

Referenced by initialize_escs().

◆ event_state_compositors

struct event_state_compositor event_state_compositors[]
static
Initial value:
= {
{CALL_COMPLETION, "call-completion", &cc_esc_publish_callbacks},
}
static const struct sip_esc_publish_callbacks cc_esc_publish_callbacks
Definition: chan_sip.c:978

Referenced by destroy_escs(), get_esc(), and initialize_escs().

◆ externaddr

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

Referenced by ast_sip_ouraddrfor(), reload_config(), and sip_show_settings().

◆ externexpire

time_t externexpire
static

Expiration counter for re-resolving external host name in dynamic DNS

Definition at line 1136 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), and reload_config().

◆ externhost

char externhost[MAXHOSTNAMELEN]
static

External host name

Definition at line 1135 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), reload_config(), and sip_show_settings().

◆ externrefresh

int externrefresh = 10
static

Refresh timer for DNS-based external address (dyndns)

Definition at line 1137 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), reload_config(), and sip_show_settings().

◆ externtcpport

uint16_t externtcpport
static

external tcp port

Definition at line 1138 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), and reload_config().

◆ externtlsport

uint16_t externtlsport
static

external tls port

Definition at line 1139 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), and reload_config().

◆ faxecmodes

struct _map_x_s faxecmodes[]
static

Definition at line 21168 of file chan_sip.c.

◆ global_authfailureevents

int global_authfailureevents
static

Whether we send authentication failure manager events or not. Default no.

Definition at line 846 of file chan_sip.c.

Referenced by register_verify(), reload_config(), and sip_show_settings().

◆ global_autoframing

unsigned int global_autoframing
static

Turn autoframing on or off.

Definition at line 850 of file chan_sip.c.

Referenced by __sip_alloc(), reload_config(), set_peer_defaults(), and sip_show_settings().

◆ global_callcounter

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

Referenced by reload_config(), set_peer_defaults(), and sip_show_settings().

◆ global_cos_audio

unsigned int global_cos_audio
static

802.1p class of service for audio RTP packets

Definition at line 838 of file chan_sip.c.

Referenced by dialog_initialize_rtp(), initialize_udptl(), reload_config(), and sip_show_settings().

◆ global_cos_sip

unsigned int global_cos_sip
static

802.1p class of service for SIP packets

Definition at line 837 of file chan_sip.c.

Referenced by reload_config(), sip_prepare_socket(), and sip_show_settings().

◆ global_cos_text

unsigned int global_cos_text
static

802.1p class of service for text RTP packets

Definition at line 840 of file chan_sip.c.

Referenced by reload_config(), and sip_show_settings().

◆ global_cos_video

unsigned int global_cos_video
static

802.1p class of service for video RTP packets

Definition at line 839 of file chan_sip.c.

Referenced by dialog_initialize_rtp(), reload_config(), and sip_show_settings().

◆ global_dynamic_exclude_static

int global_dynamic_exclude_static = 0
static

Exclude static peers from contact registrations

Definition at line 862 of file chan_sip.c.

Referenced by build_peer(), and reload_config().

◆ global_flags

struct ast_flags global_flags[3] = {{0}}
static

global SIP_ flags

Definition at line 884 of file chan_sip.c.

◆ global_jbconf

struct ast_jb_conf global_jbconf
static

Global jitterbuffer configuration

Definition at line 688 of file chan_sip.c.

Referenced by reload_config(), sip_get_rtp_peer(), sip_new(), and sip_show_settings().

◆ global_match_auth_username

int global_match_auth_username
static

Match auth username if available instead of From: Default off.

Definition at line 819 of file chan_sip.c.

Referenced by check_user_full(), reload_config(), and sip_show_settings().

◆ global_max_se

int global_max_se
static

Highest threshold for session refresh interval

Definition at line 858 of file chan_sip.c.

Referenced by build_peer(), handle_request_invite_st(), reload_config(), set_peer_defaults(), sip_show_settings(), and st_get_se().

◆ global_min_se

int global_min_se
static

Lowest threshold for session refresh interval

Definition at line 857 of file chan_sip.c.

Referenced by build_peer(), reload_config(), set_peer_defaults(), sip_show_settings(), and st_get_se().

◆ global_prematuremediafilter

int global_prematuremediafilter
static

Enable/disable premature frames in a call (causing 183 early media)

Definition at line 822 of file chan_sip.c.

Referenced by reload_config(), sip_show_settings(), and sip_write().

◆ global_qualify_gap

int global_qualify_gap
static

Time between our group of peer pokes

Definition at line 852 of file chan_sip.c.

Referenced by reload_config(), and sip_poke_all_peers().

◆ global_qualify_peers

int global_qualify_peers
static

Number of peers to poke at a given time

Definition at line 853 of file chan_sip.c.

Referenced by reload_config(), and sip_poke_all_peers().

◆ global_qualifyfreq

int global_qualifyfreq
static

Qualify frequency

Definition at line 851 of file chan_sip.c.

Referenced by build_peer(), reg_source_db(), reload_config(), set_peer_defaults(), and sip_show_settings().

◆ global_refer_addheaders

unsigned char global_refer_addheaders
static

Add extra headers to outgoing REFER

Definition at line 863 of file chan_sip.c.

Referenced by reload_config(), and transmit_invite().

◆ global_reg_retry_403

int global_reg_retry_403
static

Treat 403 responses to registrations as 401 responses

Definition at line 828 of file chan_sip.c.

Referenced by handle_response_register(), reload_config(), and sip_show_settings().

◆ global_reg_timeout

int global_reg_timeout
static

Global time between attempts for outbound registrations

Definition at line 826 of file chan_sip.c.

Referenced by __start_register_timeout(), reload_config(), sip_show_settings(), and transmit_register().

◆ global_regattempts_max

int global_regattempts_max
static

Registration attempts before giving up

Definition at line 827 of file chan_sip.c.

Referenced by reload_config(), sip_reg_timeout(), and sip_show_settings().

◆ global_relaxdtmf

int global_relaxdtmf
static

Relax DTMF

Definition at line 821 of file chan_sip.c.

Referenced by enable_dsp_detect(), reload_config(), and sip_show_settings().

◆ global_rtpholdtimeout

int global_rtpholdtimeout
static

Time out call if no RTP during hold

Definition at line 824 of file chan_sip.c.

Referenced by build_peer(), check_user_full(), create_addr(), reload_config(), set_peer_defaults(), and sip_show_settings().

◆ global_rtpkeepalive

int global_rtpkeepalive
static

Send RTP keepalives

Definition at line 825 of file chan_sip.c.

Referenced by build_peer(), check_user_full(), create_addr(), reload_config(), set_peer_defaults(), and sip_show_settings().

◆ global_rtptimeout

int global_rtptimeout
static

Time out call if no RTP

Definition at line 823 of file chan_sip.c.

Referenced by build_peer(), check_user_full(), create_addr(), reload_config(), set_peer_defaults(), and sip_show_settings().

◆ global_sdpowner

char global_sdpowner[AST_MAX_EXTENSION]
static

SDP owner name for the SIP channel

Definition at line 845 of file chan_sip.c.

Referenced by add_sdp(), reload_config(), and sip_show_settings().

◆ global_sdpsession

char global_sdpsession[AST_MAX_EXTENSION]
static

SDP session name for the SIP channel

Definition at line 844 of file chan_sip.c.

Referenced by add_sdp(), reload_config(), and sip_show_settings().

◆ global_shrinkcallerid

int global_shrinkcallerid
static

enable or disable shrinking of caller id

Definition at line 829 of file chan_sip.c.

Referenced by check_peer_ok(), check_user_full(), get_pai(), get_rpid(), and reload_config().

◆ global_st_mode

enum st_mode global_st_mode
static

Mode of operation for Session-Timers

Definition at line 855 of file chan_sip.c.

Referenced by build_peer(), reload_config(), set_peer_defaults(), sip_show_settings(), and st_get_mode().

◆ global_st_refresher

enum st_refresher_param global_st_refresher
static

Session-Timer refresher

Definition at line 856 of file chan_sip.c.

Referenced by build_peer(), reload_config(), set_peer_defaults(), sip_show_settings(), and st_get_refresher().

◆ global_store_sip_cause

int global_store_sip_cause
static

Whether the MASTER_CHANNEL(HASH(SIP_CAUSE,[chan_name])) var should be set

Definition at line 860 of file chan_sip.c.

Referenced by handle_incoming(), reload_config(), and sip_show_settings().

◆ global_t1

int global_t1
static

◆ global_t1min

int global_t1min
static

T1 roundtrip time minimum

Definition at line 848 of file chan_sip.c.

Referenced by build_peer(), check_peer_ok(), create_addr_from_peer(), reload_config(), and sip_show_settings().

◆ global_t38_maxdatagram

unsigned int global_t38_maxdatagram
static

global T.38 FaxMaxDatagram override

Definition at line 885 of file chan_sip.c.

Referenced by handle_t38_options(), initialize_udptl(), reload_config(), set_peer_defaults(), and sip_show_settings().

◆ global_timer_b

int global_timer_b
static

Timer B - RFC 3261 Section 17.1.1.2

Definition at line 849 of file chan_sip.c.

Referenced by __sip_alloc(), build_peer(), create_addr(), reload_config(), set_peer_defaults(), sip_scheddestroy_full(), and sip_show_settings().

◆ global_tos_audio

unsigned int global_tos_audio
static

IP type of service for audio RTP packets

Definition at line 834 of file chan_sip.c.

Referenced by dialog_initialize_rtp(), initialize_udptl(), reload_config(), and sip_show_settings().

◆ global_tos_sip

unsigned int global_tos_sip
static

IP type of service for SIP packets

Definition at line 833 of file chan_sip.c.

Referenced by reload_config(), sip_prepare_socket(), and sip_show_settings().

◆ global_tos_text

unsigned int global_tos_text
static

IP type of service for text RTP packets

Definition at line 836 of file chan_sip.c.

Referenced by reload_config(), and sip_show_settings().

◆ global_tos_video

unsigned int global_tos_video
static

IP type of service for video RTP packets

Definition at line 835 of file chan_sip.c.

Referenced by dialog_initialize_rtp(), reload_config(), and sip_show_settings().

◆ global_useragent

char global_useragent[AST_MAX_EXTENSION]
static

Useragent for the SIP channel

Definition at line 843 of file chan_sip.c.

Referenced by initreqprep(), reload_config(), reqprep(), respprep(), sip_show_settings(), and transmit_register().

◆ HASH_DIALOG_SIZE

const int HASH_DIALOG_SIZE = 563
static

Definition at line 944 of file chan_sip.c.

Referenced by load_module().

◆ HASH_PEER_SIZE

const int HASH_PEER_SIZE = 563
static

Size of peer hash table, prime number preferred!

Definition at line 943 of file chan_sip.c.

Referenced by load_module().

◆ HASH_REGISTRY_SIZE

const int HASH_REGISTRY_SIZE = 563
static

Definition at line 945 of file chan_sip.c.

Referenced by load_module().

◆ insecurestr

const struct _map_x_s insecurestr[]
static

Definition at line 20609 of file chan_sip.c.

◆ internip

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

Referenced by __sip_alloc(), ast_sip_ouraddrfor(), reload_config(), transmit_register(), and transmit_response_using_temp().

◆ invitestate2string

const struct invstate2stringtable invitestate2string[]
static

Referenced by show_chanstats_cb().

◆ io

struct io_context* io
static

The IO context

Definition at line 909 of file chan_sip.c.

◆ localaddr

struct ast_ha* localaddr
static

List of local networks We store "localnet" addresses from the config file into an access list, marked as 'DENY', so the call to ast_apply_ha() will return AST_SENSE_DENY for 'local' addresses, and AST_SENSE_ALLOW for 'non local' (i.e. presumably public) addresses.

List of local networks, on the same side of NAT as this Asterisk

Definition at line 1147 of file chan_sip.c.

Referenced by evt_gen_auth_method_not_allowed(), evt_gen_chal_resp_failed(), evt_gen_chal_sent(), evt_gen_failed_acl(), evt_gen_inval_acct_id(), evt_gen_inval_password(), evt_gen_inval_transport(), evt_gen_load_avg(), evt_gen_mem_limit(), evt_gen_req_bad_format(), evt_gen_req_no_support(), evt_gen_req_not_allowed(), evt_gen_session_limit(), evt_gen_successful_auth(), and evt_gen_unexpected_addr().

◆ log_level

int log_level = -1
static

Definition at line 665 of file chan_sip.c.

Referenced by append_history_va(), load_module(), and unload_module().

◆ max_expiry

int max_expiry = DEFAULT_MAX_EXPIRY
static

Maximum accepted registration time

Definition at line 668 of file chan_sip.c.

Referenced by handle_request_publish(), handle_response_register(), parse_register_contact(), reload_config(), and sip_show_settings().

◆ max_subexpiry

int max_subexpiry = DEFAULT_MAX_EXPIRY
static

Maximum accepted subscription time

Definition at line 671 of file chan_sip.c.

Referenced by handle_request_subscribe(), reload_config(), and sip_show_settings().

◆ media_address

struct ast_sockaddr media_address
static

External RTP IP address if we are behind NAT

Definition at line 1132 of file chan_sip.c.

Referenced by create_rtp(), get_our_media_address(), and reload_config().

◆ min_expiry

int min_expiry = DEFAULT_MIN_EXPIRY
static

Minimum accepted registration time

Definition at line 667 of file chan_sip.c.

Referenced by handle_request_publish(), parse_register_contact(), reload_config(), and sip_show_settings().

◆ min_subexpiry

int min_subexpiry = DEFAULT_MIN_EXPIRY
static

Minimum accepted subscription time

Definition at line 670 of file chan_sip.c.

Referenced by handle_request_subscribe(), reload_config(), and sip_show_settings().

◆ monitor_thread

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

Referenced by __sip_reliable_xmit(), restart_monitor(), and unload_module().

◆ monlock

ast_mutex_t monlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
static

Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.

Definition at line 897 of file chan_sip.c.

Referenced by do_monitor(), restart_monitor(), and unload_module().

◆ mwi_expiry

int mwi_expiry = DEFAULT_MWI_EXPIRY
static

Definition at line 672 of file chan_sip.c.

Referenced by __sip_subscribe_mwi_do(), handle_response_subscribe(), and reload_config().

◆ netlock

ast_mutex_t netlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
static

Definition at line 893 of file chan_sip.c.

Referenced by handle_request_do(), and reload_config().

◆ network_change_sched_id

int network_change_sched_id = -1
static

Definition at line 889 of file chan_sip.c.

Referenced by network_change_sched_cb(), and network_change_stasis_cb().

◆ network_change_sub

struct stasis_subscription* network_change_sub
static

subscription id for network change events

Definition at line 887 of file chan_sip.c.

◆ notify_config

const char notify_config[] = "sip_notify.conf"
static

Configuration file for sending Notify with CLI commands to reconfigure or reboot phones

Definition at line 691 of file chan_sip.c.

Referenced by reload_config(), and sip_cli_notify().

◆ notify_types

struct ast_config* notify_types = NULL
static

The list of manual NOTIFY types we know how to send

Definition at line 1153 of file chan_sip.c.

◆ ourport_tcp

int ourport_tcp
static

The port used for TCP connections

Definition at line 1149 of file chan_sip.c.

Referenced by reload_config().

◆ ourport_tls

int ourport_tls
static

The port used for TCP/TLS connections

Definition at line 1150 of file chan_sip.c.

Referenced by reload_config().

◆ peers

struct ao2_container* peers
static

The peer list: Users, Peers and Friends.

Definition at line 1052 of file chan_sip.c.

Referenced by get_insecure_variable_from_sipregs().

◆ peers_by_ip

struct ao2_container* peers_by_ip
static

Definition at line 1053 of file chan_sip.c.

◆ recordhistory

unsigned int recordhistory
static

Record SIP history. Off by default

Definition at line 841 of file chan_sip.c.

Referenced by __sip_alloc(), append_history_full(), reload_config(), sip_set_history(), sip_show_history(), and sip_show_settings().

◆ referstatusstrings

const struct _map_x_s referstatusstrings[]
static

Definition at line 924 of file chan_sip.c.

◆ registry_list

struct ao2_container* registry_list
static

The register list: Other SIP proxies we register with and receive calls from.

Definition at line 1061 of file chan_sip.c.

◆ regstatestrings

const struct _map_x_s regstatestrings[]
static

Definition at line 15834 of file chan_sip.c.

◆ rpeerobjs

int rpeerobjs = 0
static

Realtime peers

Definition at line 880 of file chan_sip.c.

Referenced by build_peer(), expire_register(), realtime_peer(), sip_destroy_peer(), and sip_show_objects().

◆ rtpbindaddr

struct ast_sockaddr rtpbindaddr
static

RTP: The address we bind to

Definition at line 1133 of file chan_sip.c.

Referenced by dialog_initialize_rtp(), reload_config(), and sip_show_settings().

◆ sched

The scheduling context

Definition at line 908 of file chan_sip.c.

◆ service

enum ast_cc_service_type service

◆ service_string

const char* service_string

Definition at line 950 of file chan_sip.c.

◆ sip_cc_agent_callbacks

struct ast_cc_agent_callbacks sip_cc_agent_callbacks
static

Definition at line 1618 of file chan_sip.c.

◆ sip_cc_monitor_callbacks

struct ast_cc_monitor_callbacks sip_cc_monitor_callbacks
static

Definition at line 2093 of file chan_sip.c.

◆ sip_cc_notify_state_map

const { ... } sip_cc_notify_state_map[]
Initial value:
= {
[CC_QUEUED] = {CC_QUEUED, "cc-state: queued"},
[CC_READY] = {CC_READY, "cc-state: ready"},
}
Definition: sip.h:1556

Referenced by transmit_cc_notify().

◆ sip_cc_service_map

const { ... } sip_cc_service_map[]

◆ sip_cfg

struct sip_settings sip_cfg
static

◆ sip_content_buf

struct ast_threadstorage sip_content_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_sip_content_buf , .custom_init = NULL , }
static

Definition at line 8607 of file chan_sip.c.

Referenced by get_content().

◆ sip_header_function

struct ast_custom_function sip_header_function
static
Initial value:
= {
.name = "SIP_HEADER",
}
static int func_header_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t len)
Read SIP header (dialplan function)
Definition: chan_sip.c:23246

Definition at line 23305 of file chan_sip.c.

◆ sip_headers_function

struct ast_custom_function sip_headers_function
static
Initial value:
= {
.name = "SIP_HEADERS",
}
static int func_headers_read2(struct ast_channel *chan, const char *function, char *data, struct ast_str **buf, ssize_t maxlen)
Read unique list of SIP headers (dialplan function)
Definition: chan_sip.c:23311

Definition at line 23389 of file chan_sip.c.

◆ sip_methods

const struct cfsip_methods sip_methods[]
static

◆ sip_monitor_instances

struct ao2_container* sip_monitor_instances

Definition at line 1164 of file chan_sip.c.

◆ sip_msg_tech

const struct ast_msg_tech sip_msg_tech
static
Initial value:
= {
.name = "sip",
.msg_send = sip_msg_send,
}
static int sip_msg_send(const struct ast_msg *msg, const char *to, const char *from)
Definition: chan_sip.c:27879

Definition at line 27833 of file chan_sip.c.

◆ sip_reason_table

const struct sip_reasons sip_reason_table[]
static

Referenced by sip_reason_code_to_str().

◆ sip_reload_lock

ast_mutex_t sip_reload_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
static

Definition at line 899 of file chan_sip.c.

Referenced by acl_change_stasis_cb(), do_monitor(), and sip_reload().

◆ sip_reloading

int sip_reloading = FALSE
static

Flag for avoiding multiple reloads at the same time

Definition at line 905 of file chan_sip.c.

Referenced by acl_change_stasis_cb(), do_monitor(), and sip_reload().

◆ sip_reloadreason

enum channelreloadreason sip_reloadreason
static

Reason for last reload/load of configuration

Definition at line 906 of file chan_sip.c.

Referenced by acl_change_stasis_cb(), do_monitor(), load_module(), and sip_reload().

◆ sip_rtp_glue

struct ast_rtp_glue sip_rtp_glue
static

Definition at line 34005 of file chan_sip.c.

◆ sip_tcp_desc

struct ast_tcptls_session_args sip_tcp_desc
static

The TCP server definition.

Definition at line 2383 of file chan_sip.c.

◆ sip_tech

struct ast_channel_tech sip_tech

Definition of this channel for PBX channel registration.

Definition at line 1573 of file chan_sip.c.

Referenced by AST_TEST_DEFINE().

◆ sip_tech_info

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

Referenced by load_module(), and sip_new().

◆ sip_tls_cfg

struct ast_tls_config sip_tls_cfg
static

Working TLS connection configuration.

Definition at line 2374 of file chan_sip.c.

◆ sip_tls_desc

struct ast_tcptls_session_args sip_tls_desc
static

The TCP/TLS server definition.

Definition at line 2394 of file chan_sip.c.

◆ sip_transport_str_buf

struct ast_threadstorage sip_transport_str_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_sip_transport_str_buf , .custom_init = NULL , }
static

Definition at line 1073 of file chan_sip.c.

Referenced by get_transport_list().

◆ sipdebug

enum sip_debug_e sipdebug
static

◆ sipdebug_text

int sipdebug_text
static

extra debugging for 'text' related events. At the moment this is set together with sip_debug_console.

Note
It should either go away or be implemented properly.

Definition at line 922 of file chan_sip.c.

Referenced by add_sdp(), sip_do_debug(), and sip_rtp_read().

◆ sippeer_function

struct ast_custom_function sippeer_function
static
Initial value:
= {
.name = "SIPPEER",
}
static int function_sippeer(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
${SIPPEER()} Dialplan function - reads peer data
Definition: chan_sip.c:23415

Structure to declare a dialplan function: SIPPEER.

Definition at line 23520 of file chan_sip.c.

◆ sipsock

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

Referenced by do_monitor(), process_via(), reload_config(), sip_prepare_socket(), sip_send_keepalive(), sipsock_read(), and unload_module().

◆ sipsock_read_id

int* sipsock_read_id
static

ID of IO entry for sipsock FD

Definition at line 910 of file chan_sip.c.

Referenced by do_monitor(), and unload_module().

◆ speerobjs

int speerobjs = 0
static

Static peers

Definition at line 879 of file chan_sip.c.

Referenced by build_peer(), sip_destroy_peer(), sip_keepalive_all_peers(), sip_poke_all_peers(), and sip_show_objects().

◆ state

Definition at line 959 of file chan_sip.c.

Referenced by __state_find_or_add(), action_dahdishowchannels(), action_presencestate(), alsa_read(), alsa_write(), ami_outbound_registration_task(), ami_register(), ami_unregister(), ast_bucket_alloc(), ast_bucket_file_alloc(), ast_channel_get_t38_state(), ast_channel_start_silence_generator(), ast_complete_channels(), ast_devstate_aggregate_add(), ast_devstate_str(), ast_dns_get_nameservers(), ast_extension_state3(), ast_monitor_set_state(), ast_speech_change_state(), ast_stream_set_state(), AST_TEST_DEFINE(), ast_uri_parse(), auth_observer(), bc_next_state_change(), bc_state_change(), bucket_file_wizard_retrieve(), bucket_wizard_retrieve(), calendarstate(), chan_pjsip_devicestate(), chan_pjsip_queryoption(), cli_register(), cli_unregister(), complete_agent(), complete_agent_logoff(), complete_meetmecmd_list(), complete_meetmecmd_mute_kick(), custom_presence_callback(), decode(), destroy_all_channels(), device_state_alloc(), device_state_cb(), device_state_notify_callbacks(), devstate_cached(), dialog_info_generate_body_content(), do_state_change(), extensionstate2devicestate(), gen_alloc(), get_state(), handle_cli_devstate_change(), handle_cli_presencestate_change(), handle_cli_presencestate_list(), handle_hint_change_message_type(), handle_logger_set_level(), hfp_parse_cind(), hfp_parse_cind_test(), hfp_parse_cmgr(), hook_off(), hook_re_enable(), hook_state_alloc(), init_hook(), jingle_endpoint_state_create(), load_module(), media_offer_read_av(), media_offer_write_av(), misdn_get_ch_state(), mkintf(), moh_alloc(), moh_files_alloc(), moh_files_release(), moh_release(), ooh323_queryoption(), poll_mailbox(), presence_read(), presence_write(), publish_device_state_to_stasis(), refer_progress_notification_alloc(), refresh_write_cb(), registration_transport_shutdown_cb(), session_refresh_state_get_or_alloc(), set_state(), setsubstate(), sip_options_get_endpoint_state_compositor_state(), sip_outbound_publish_state_alloc(), sip_outbound_publish_synchronize(), sip_outbound_registration_state_alloc(), skinny_extensionstate_cb(), sla_change_trunk_state(), stasis_app_device_state_update(), stasis_state_publish_by_id(), stasis_state_topic(), state_alloc(), worker_set_state(), xmpp_client_change_state(), xmpp_pubsub_publish_device_state(), and xmpp_show_clients().

◆ state_string

const char* state_string

Definition at line 960 of file chan_sip.c.

Referenced by transmit_cc_notify().

◆ stmodes

const struct _map_x_s stmodes[]
static

Report Peer status in character string.

Returns
0 if peer is unreachable, 1 if peer is online, -1 if unmonitored

Definition at line 19983 of file chan_sip.c.

◆ strefresher_params

const struct _map_x_s strefresher_params[]
static

Definition at line 20001 of file chan_sip.c.

◆ strefreshers

const struct _map_x_s strefreshers[]
static

Definition at line 20008 of file chan_sip.c.

◆ subscription_mwi_list

struct ao2_container* subscription_mwi_list
static

The MWI subscription list.

Definition at line 1064 of file chan_sip.c.

◆ subscription_types

const struct cfsubscription_types subscription_types[]
static

◆ threadt

struct ao2_container* threadt
static

The table of TCP threads.

Definition at line 1049 of file chan_sip.c.

◆ trust_id_outboundstr

const struct _map_x_s trust_id_outboundstr[]
static

Definition at line 20636 of file chan_sip.c.

◆ ts_temp_pvt

struct ast_threadstorage ts_temp_pvt = { .once = PTHREAD_ONCE_INIT , .key_init = __init_ts_temp_pvt , .custom_init = temp_pvt_init , }
static

Definition at line 1070 of file chan_sip.c.

Referenced by transmit_response_using_temp().

◆ unauth_sessions

int unauth_sessions = 0
static

Definition at line 674 of file chan_sip.c.

Referenced by _sip_tcp_helper_thread().

◆ used_context

char used_context[AST_MAX_CONTEXT]
static

name of automatically created context for unloading

Definition at line 891 of file chan_sip.c.

Referenced by reload_config(), and unload_module().