#include "asterisk.h"
#include <signal.h>
#include <sys/signal.h>
#include <regex.h>
#include <inttypes.h>
#include "asterisk/network.h"
#include "asterisk/paths.h"
#include "asterisk/lock.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp_engine.h"
#include "asterisk/udptl.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/musiconhold.h"
#include "asterisk/dsp.h"
#include "asterisk/features.h"
#include "asterisk/srv.h"
#include "asterisk/astdb.h"
#include "asterisk/causes.h"
#include "asterisk/utils.h"
#include "asterisk/file.h"
#include "asterisk/astobj2.h"
#include "asterisk/dnsmgr.h"
#include "asterisk/devicestate.h"
#include "asterisk/monitor.h"
#include "asterisk/netsock2.h"
#include "asterisk/localtime.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/threadstorage.h"
#include "asterisk/translate.h"
#include "asterisk/ast_version.h"
#include "asterisk/event.h"
#include "asterisk/cel.h"
#include "asterisk/data.h"
#include "asterisk/aoc.h"
#include "sip/include/sip.h"
#include "sip/include/globals.h"
#include "sip/include/config_parser.h"
#include "sip/include/reqresp_parser.h"
#include "sip/include/sip_utils.h"
#include "sip/include/srtp.h"
#include "sip/include/sdp_crypto.h"
#include "asterisk/ccss.h"
#include "asterisk/xml.h"
#include "sip/include/dialog.h"
#include "sip/include/dialplan_functions.h"
Go to the source code of this file.
Data Structures | |
| struct | ast_register_list |
| The register list: Other SIP proxies we register with and receive calls from. More... | |
| struct | ast_subscription_mwi_list |
| The MWI subscription list. More... | |
| struct | cfsip_methods |
| The core structure to setup dialogs. We parse incoming messages by using structure and then route the messages according to the type. More... | |
| struct | cfsubscription_types |
Subscription types that we support. We support
| |
| struct | domain_list |
| struct | epa_static_data_list |
| struct | event_state_compositor |
| The Event State Compositors. More... | |
| struct | invstate2stringtable |
| Readable descriptions of device states. More... | |
| struct | match_req_args |
| struct | sip_history_head |
| struct | sip_reasons |
| Diversion header reasons. More... | |
Object counters @{ | |
| |
| #define | append_history(p, event, fmt, args...) append_history_full(p, "%-15s " fmt, event, ## args) |
| Append to SIP dialog history. | |
| #define | CHECK_AUTH_BUF_INITLEN 256 |
| #define | check_request_transport(peer, tmpl) |
| generic function for determining if a correct transport is being used to contact a peer | |
| #define | DATA_EXPORT_SIP_PEER(MEMBER) |
| #define | FORMAT "%-15.15s %-15.15s %-15.15s %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s %-10.10s\n" |
| #define | FORMAT "%-30.30s %-12.12s %-10.10s %-10.10s\n" |
| #define | FORMAT "%-15.15s %-11.11s %-8.8s %-10.10u%-1.1s %-10.10u (%5.2f%%) %-6.4lf %-10.10u%-1.1s %-10.10u (%5.2f%%) %-6.4lf\n" |
| #define | FORMAT "%-39.39s %-6.6s %-12.12s %8d %-20.20s %-25.25s\n" |
| #define | FORMAT "%-40.40s %-20.20s %-16.16s\n" |
| #define | FORMAT "%-25.25s %-39.39s %-3.3s %-3.3s %-3.3s %-8d %-10s %s\n" |
| #define | FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" |
| #define | FORMAT "%-47.47s %-9.9s %-6.6s\n" |
| #define | FORMAT "%-25.25s %-15.15s %-15.15s \n" |
| #define | FORMAT2 "%-15.15s %-15.15s %-15.15s %-15.15s %-7.7s %-15.15s %-10.10s %-10.10s\n" |
| #define | FORMAT2 "%-15.15s %-11.11s %-8.8s %-10.10s %-10.10s ( %%) %-6.6s %-10.10s %-10.10s ( %%) %-6.6s\n" |
| #define | FORMAT2 "%-39.39s %-6.6s %-12.12s %8.8s %-20.20s %-25.25s\n" |
| #define | FORMAT2 "%-25.25s %-39.39s %-3.3s %-10.10s %-3.3s %-8s %-10s %s\n" |
| #define | FORMAT2 "%-47.47s %9.9s %6.6s\n" |
| #define | FORMAT2 "%-25.25s %-15.15s %-15.15s \n" |
| #define | FORMAT3 "%-15.15s %-15.15s %-15.15s %-15.15s %-13.13s %-15.15s %-10.10s %-6.6s\n" |
| #define | FORMAT4 "%-15.15s %-15.15s %-15.15s %-15.15s %-13.13s %-15.15s %-10.10s %-6.6d\n" |
| #define | sip_pvt_lock(x) ao2_lock(x) |
| #define | sip_pvt_trylock(x) ao2_trylock(x) |
| #define | sip_pvt_unlock(x) ao2_unlock(x) |
| #define | UNLINK(element, head, prev) |
| enum | match_req_res { SIP_REQ_MATCH, SIP_REQ_NOT_MATCH, SIP_REQ_LOOP_DETECTED } |
| static const char * | __get_header (const struct sip_request *req, const char *name, int *start) |
| static void | __init_check_auth_buf (void) |
| static void | __init_ts_temp_pvt (void) |
| A per-thread temporary pvt structure. | |
| static void | __reg_module (void) |
| static int | __set_address_from_contact (const char *fullcontact, struct ast_sockaddr *addr, int tcp) |
| int | __sip_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod) |
| Acknowledges receipt of a packet and stops retransmission called with p locked. | |
| static int | __sip_autodestruct (const void *data) |
| Kill a SIP dialog (called only by the scheduler) The scheduler has a reference to this dialog when p->autokillid != -1, and we are called using that reference. So if the event is not rescheduled, we need to call dialog_unref(). | |
| void | __sip_destroy (struct sip_pvt *p, int lockowner, int lockdialoglist) |
| Execute destruction of SIP dialog structure, release memory. | |
| static int | __sip_do_register (struct sip_registry *r) |
| Register with SIP proxy. | |
| void | __sip_pretend_ack (struct sip_pvt *p) |
| Pretend to ack all packets called with p locked. | |
| static int | __sip_reliable_xmit (struct sip_pvt *p, int seqno, int resp, struct ast_str *data, int len, int fatal, int sipmethod) |
| Transmit packet with retransmits. | |
| int | __sip_semi_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod) |
| Acks receipt of packet, keep it around (used for provisional responses). | |
| static int | __sip_subscribe_mwi_do (struct sip_subscription_mwi *mwi) |
| Actually setup an MWI subscription or resubscribe. | |
| static int | __sip_xmit (struct sip_pvt *p, struct ast_str *data, int len) |
| Transmit SIP message Sends a SIP request or response on a given socket (in the pvt) Called by retrans_pkt, send_request, send_response and __sip_reliable_xmit. | |
| static int | __transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
| Base transmit response function. | |
| static void | __unreg_module (void) |
| static char * | _sip_qualify_peer (int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[]) |
| Send qualify message to peer from cli or manager. Mostly for debugging. | |
| static char * | _sip_show_peer (int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[]) |
| Show one peer in detail (main function). | |
| static char * | _sip_show_peers (int fd, int *total, struct mansession *s, const struct message *m, int argc, const char *argv[]) |
| Execute sip show peers command. | |
| static void * | _sip_tcp_helper_thread (struct sip_pvt *pvt, struct ast_tcptls_session_instance *tcptls_session) |
| SIP TCP thread management function This function reads from the socket, parses the packet into a request. | |
| static void | add_blank (struct sip_request *req) |
| add a blank line if no body | |
| static void | add_cc_call_info_to_response (struct sip_pvt *p, struct sip_request *resp) |
| static void | add_codec_to_sdp (const struct sip_pvt *p, format_t codec, struct ast_str **m_buf, struct ast_str **a_buf, int debug, int *min_packet_size) |
| Add codec offer to SDP offer/answer body in INVITE or 200 OK. | |
| static int | add_content (struct sip_request *req, const char *line) |
| Add content (not header) to SIP message. | |
| static int | add_digit (struct sip_request *req, char digit, unsigned int duration, int mode) |
| Add DTMF INFO tone to sip message Mode = 0 for application/dtmf-relay (Cisco) 1 for application/dtmf. | |
| static void | add_diversion_header (struct sip_request *req, struct sip_pvt *pvt) |
| Add "Diversion" header to outgoing message. | |
| static int | add_header (struct sip_request *req, const char *var, const char *value) |
| Add header to SIP message. | |
| static int | add_header_max_forwards (struct sip_pvt *dialog, struct sip_request *req) |
| Add 'Max-Forwards' header to SIP message. | |
| static void | add_noncodec_to_sdp (const struct sip_pvt *p, int format, struct ast_str **m_buf, struct ast_str **a_buf, int debug) |
| Add RFC 2833 DTMF offer to SDP. | |
| static void | add_peer_mailboxes (struct sip_peer *peer, const char *value) |
| static void | add_peer_mwi_subs (struct sip_peer *peer) |
| static struct sip_auth * | add_realm_authentication (struct sip_auth *authlist, const char *configuration, int lineno) |
| Add realm authentication in list. | |
| static void | add_route (struct sip_request *req, struct sip_route *route) |
| Add route header into request per learned route. | |
| static int | add_rpid (struct sip_request *req, struct sip_pvt *p) |
| Add Remote-Party-ID header to SIP message. | |
| static enum sip_result | add_sdp (struct sip_request *resp, struct sip_pvt *p, int oldsdp, int add_audio, int add_t38) |
| Add Session Description Protocol message. | |
| static int | add_sip_domain (const char *domain, const enum domain_mode mode, const char *context) |
| Add SIP domain to list of domains we are responsible for. | |
| static int | add_supported_header (struct sip_pvt *pvt, struct sip_request *req) |
| Add "Supported" header to sip message. Since some options may be disabled in the config, the sip_pvt must be inspected to determine what is supported for this dialog. | |
| static void | add_tcodec_to_sdp (const struct sip_pvt *p, int codec, struct ast_str **m_buf, struct ast_str **a_buf, int debug, int *min_packet_size) |
| Add text codec offer to SDP offer/answer body in INVITE or 200 OK. | |
| static int | add_text (struct sip_request *req, const char *text) |
| Add text body to SIP message. | |
| static struct ast_variable * | add_var (const char *buf, struct ast_variable *list) |
| implement the setvar config line | |
| static void | add_vcodec_to_sdp (const struct sip_pvt *p, format_t codec, struct ast_str **m_buf, struct ast_str **a_buf, int debug, int *min_packet_size) |
| Add video codec offer to SDP offer/answer body in INVITE or 200 OK. | |
| static int | add_vidupdate (struct sip_request *req) |
| add XML encoded media control with update | |
| static int | addr_is_multicast (const struct ast_sockaddr *addr) |
| Check if an ip is an multicast IP. addr the address to check. | |
| static void | append_date (struct sip_request *req) |
| Append date to SIP message. | |
| static void | append_history_full (struct sip_pvt *p, const char *fmt,...) |
| Append to SIP dialog history with arg list. | |
| static void | append_history_va (struct sip_pvt *p, const char *fmt, va_list ap) |
| Append to SIP dialog history with arg list. | |
| static int | apply_directmedia_ha (struct sip_pvt *p, const char *op) |
| AST_DATA_STRUCTURE (sip_peer, DATA_EXPORT_SIP_PEER) | |
| static void | ast_quiet_chan (struct ast_channel *chan) |
| Turn off generator data XXX Does this function belong in the SIP channel? | |
| static void | ast_sip_ouraddrfor (const struct ast_sockaddr *them, struct ast_sockaddr *us, struct sip_pvt *p) |
| NAT fix - decide which IP address to use for Asterisk server? | |
| static int | ast_sockaddr_resolve_first (struct ast_sockaddr *addr, const char *name, int flag) |
| Return the first entry from ast_sockaddr_resolve filtered by family of binddaddr. | |
| static int | ast_sockaddr_resolve_first_af (struct ast_sockaddr *addr, const char *name, int flag, int family) |
| Return the first entry from ast_sockaddr_resolve filtered by address family. | |
| static int | attempt_transfer (struct sip_dual *transferer, struct sip_dual *target) |
| Attempt transfer of SIP call This fix for attended transfers on a local PBX. | |
| static void | auth_headers (enum sip_auth_type code, char **header, char **respheader) |
| return the request and response heade for a 401 or 407 code | |
| static int | auto_congest (const void *arg) |
| Scheduled congestion on a call. Only called by the scheduler, must return the reference when done. | |
| static void | build_callid_pvt (struct sip_pvt *pvt) |
| Build SIP Call-ID value for a non-REGISTER transaction. | |
| static void | build_callid_registry (struct sip_registry *reg, const struct ast_sockaddr *ourip, const char *fromdomain) |
| Build SIP Call-ID value for a REGISTER transaction. | |
| static void | build_contact (struct sip_pvt *p) |
| Build contact header - the contact header we send out. | |
| static struct sip_peer * | build_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime, int devstate_only) |
| Build peer from configuration (file or realtime static/dynamic). | |
| static int | build_reply_digest (struct sip_pvt *p, int method, char *digest, int digest_len) |
| Build reply digest. | |
| static void | build_route (struct sip_pvt *p, struct sip_request *req, int backwards) |
| Build route list from Record-Route header. | |
| static void | build_via (struct sip_pvt *p) |
| Build a Via header for a request. | |
| static int | cb_extensionstate (char *context, char *exten, int state, void *data) |
| Callback for the devicestate notification (SUBSCRIBE) support subsystem. | |
| static void | cc_epa_destructor (void *data) |
| static 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_hold_state (struct sip_pvt *dialog, struct sip_request *req, int holdstate, int sendonly) |
| Change hold state for a call. | |
| static void | change_redirecting_information (struct sip_pvt *p, struct sip_request *req, struct ast_party_redirecting *redirecting, struct ast_set_party_redirecting *update_redirecting, int set_call_forward) |
| update redirecting information for a channel based on headers | |
| static void | change_t38_state (struct sip_pvt *p, int state) |
| Change the T38 state on a SIP dialog. | |
| static enum check_auth_result | check_auth (struct sip_pvt *p, struct sip_request *req, const char *username, const char *secret, const char *md5secret, int sipmethod, const char *uri, enum xmittype reliable, int ignore) |
| Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set). | |
| static enum check_auth_result | check_peer_ok (struct sip_pvt *p, char *of, struct sip_request *req, int sipmethod, struct ast_sockaddr *addr, struct sip_peer **authpeer, enum xmittype reliable, char *calleridname, char *uri2) |
| Validate device authentication. | |
| static void | check_pendings (struct sip_pvt *p) |
| Check pending actions on SIP call. | |
| static void | check_rtp_timeout (struct sip_pvt *dialog, time_t t) |
| helper function for the monitoring thread -- seems to be called with the assumption that the dialog is locked | |
| static int | check_sip_domain (const char *domain, char *context, size_t len) |
| check_sip_domain: Check if domain part of uri is local to our server | |
| static int | check_user (struct sip_pvt *p, struct sip_request *req, int sipmethod, const char *uri, enum xmittype reliable, struct ast_sockaddr *addr) |
| Find user If we get a match, this will add a reference pointer to the user object in ASTOBJ, that needs to be unreferenced. | |
| static enum check_auth_result | check_user_full (struct sip_pvt *p, struct sip_request *req, int sipmethod, const char *uri, enum xmittype reliable, struct ast_sockaddr *addr, struct sip_peer **authpeer) |
| Check if matching user or peer is defined Match user on From: user name and peer on IP/port This is used on first invite (not re-invites) and subscribe requests. | |
| static void | check_via (struct sip_pvt *p, struct sip_request *req) |
| check Via: header for hostname, port and rport request/answer | |
| static attribute_unused void | check_via_response (struct sip_pvt *p, struct sip_request *req) |
| check received= and rport= in a SIP response. If we get a response with received= and/or rport= in the Via: line, use them as 'p->ourip' (see RFC 3581 for rport, and RFC 3261 for received). Using these two fields SIP can produce the correct address and port in the SIP headers without the need for STUN. The address part is also reused for the media sessions. Note that ast_sip_ouraddrfor() still rewrites p->ourip if you specify externaddr/seternaddr/. | |
| static void | cleanup_stale_contexts (char *new, char *old) |
| Destroy disused contexts between reloads Only used in reload_config so the code for regcontext doesn't get ugly. | |
| static void | clear_peer_mailboxes (struct sip_peer *peer) |
| static int | clear_realm_authentication (struct sip_auth *authlist) |
| Clear realm authentication list (at reload). | |
| static void | clear_sip_domains (void) |
| Clear our domain list (at reload). | |
| static char * | complete_sip_peer (const char *word, int state, int flags2) |
| Do completion on peer name. | |
| static char * | complete_sip_registered_peer (const char *word, int state, int flags2) |
| Do completion on registered peer name. | |
| static char * | complete_sip_show_history (const char *line, const char *word, int pos, int state) |
| Support routine for 'sip show history' CLI. | |
| static char * | complete_sip_show_peer (const char *line, const char *word, int pos, int state) |
| Support routine for 'sip show peer' CLI. | |
| static char * | complete_sip_show_user (const char *line, const char *word, int pos, int state) |
| Support routine for 'sip show user' CLI. | |
| static char * | complete_sip_unregister (const char *line, const char *word, int pos, int state) |
| Support routine for 'sip unregister' CLI. | |
| static char * | complete_sip_user (const char *word, int state) |
| Do completion on user name. | |
| static char * | complete_sipch (const char *line, const char *word, int pos, int state) |
| Support routine for 'sip show channel' and 'sip show history' CLI This is in charge of generating all strings that match a prefix in the given position. As many functions of this kind, each invokation has O(state) time complexity so be careful in using it. | |
| static char * | complete_sipnotify (const char *line, const char *word, int pos, int state) |
| Support routine for 'sip notify' CLI. | |
| static int | construct_pidf_body (enum sip_cc_publish_state state, char *pidf_body, size_t size, const char *presentity) |
| static int | copy_all_header (struct sip_request *req, const struct sip_request *orig, const char *field) |
| Copy all headers from one request to another. | |
| static int | copy_header (struct sip_request *req, const struct sip_request *orig, const char *field) |
| Copy one header field from one request to another. | |
| static void | copy_request (struct sip_request *dst, const struct sip_request *src) |
| copy SIP request (mostly used to save request for responses) | |
| static void | copy_socket_data (struct sip_socket *to_sock, const struct sip_socket *from_sock) |
| static struct ast_variable * | copy_vars (struct ast_variable *src) |
| duplicate a list of channel variables, | |
| static int | copy_via_headers (struct sip_pvt *p, struct sip_request *req, const struct sip_request *orig, const char *field) |
| Copy SIP VIA Headers from the request to the response. | |
| static int | create_addr (struct sip_pvt *dialog, const char *opeer, struct ast_sockaddr *addr, int newdialog, struct ast_sockaddr *remote_address) |
| create address structure from device name Or, if peer not found, find it in the global DNS returns TRUE (-1) on failure, FALSE on success | |
| static int | create_addr_from_peer (struct sip_pvt *dialog, struct sip_peer *peer) |
| Create address structure from peer reference. This function copies data from peer to the dialog, so we don't have to look up the peer again from memory or database during the life time of the dialog. | |
| static struct sip_epa_entry * | create_epa_entry (const char *const event_package, const char *const destination) |
| static struct sip_esc_entry * | create_esc_entry (struct event_state_compositor *esc, struct sip_request *req, const int expires) |
| static void | create_new_sip_etag (struct sip_esc_entry *esc_entry, int is_linked) |
| static void | deinit_req (struct sip_request *req) |
| Deinitialize SIP response/request. | |
| static void | destroy_association (struct sip_peer *peer) |
| Remove registration data from realtime database or AST/DB when registration expires. | |
| static void | destroy_escs (void) |
| static void | destroy_mailbox (struct sip_mailbox *mailbox) |
| static int | determine_firstline_parts (struct sip_request *req) |
| Parse first line of incoming SIP request. | |
| static enum sip_publish_type | determine_sip_publish_type (struct sip_request *req, const char *const event, const char *const etag, const char *const expires, int *expires_int) |
| static int | dialog_cmp_cb (void *obj, void *arg, int flags) |
| static int | dialog_dump_func (void *userobj, void *arg, int flags) |
| static int | dialog_find_multiple (void *obj, void *arg, int flags) |
| static int | dialog_hash_cb (const void *obj, const int flags) |
| static int | dialog_initialize_rtp (struct sip_pvt *dialog) |
| Initialize RTP portion of a dialog. | |
| static int | dialog_needdestroy (void *dialogobj, void *arg, int flags) |
| Match dialogs that need to be destroyed. | |
| sip_pvt * | dialog_ref_debug (struct sip_pvt *p, char *tag, char *file, int line, const char *func) |
| void * | dialog_unlink_all (struct sip_pvt *dialog, int lockowner, int lockdialoglist) |
| Unlink a dialog from the dialogs container, as well as any other places that it may be currently stored. | |
| sip_pvt * | dialog_unref_debug (struct sip_pvt *p, char *tag, char *file, int line, const char *func) |
| static void | disable_dsp_detect (struct sip_pvt *p) |
| static int | do_magic_pickup (struct ast_channel *channel, const char *extension, const char *context) |
| static void * | do_monitor (void *data) |
| The SIP monitoring thread. | |
| static int | do_proxy_auth (struct sip_pvt *p, struct sip_request *req, enum sip_auth_type code, int sipmethod, int init) |
| Add authentication on outbound SIP packet. | |
| static int | do_register_auth (struct sip_pvt *p, struct sip_request *req, enum sip_auth_type code) |
| Authenticate for outbound registration. | |
| static void | do_setnat (struct sip_pvt *p) |
| Set nat mode on the various data sockets. | |
| static const char * | domain_mode_to_text (const enum domain_mode mode) |
| Print domain mode to cli. | |
| static const char * | dtmfmode2str (int mode) |
| Convert DTMF mode to printable string. | |
| static void | enable_dsp_detect (struct sip_pvt *p) |
| static int | esc_cmp_fn (void *obj, void *arg, int flags) |
| static void | esc_entry_destructor (void *obj) |
| static int | esc_hash_fn (const void *obj, const int flags) |
| static int | expire_register (const void *data) |
| Expire registration of SIP peer. | |
| static void | extract_uri (struct sip_pvt *p, struct sip_request *req) |
| Check Contact: URI of SIP message. | |
| static const char * | faxec2str (int faxec) |
| static int | finalize_content (struct sip_request *req) |
| Add 'Content-Length' header and content to SIP message. | |
| static const char * | find_alias (const char *name, const char *_default) |
| Find compressed SIP alias. | |
| static int | find_by_callid_helper (void *obj, void *arg, int flags) |
| static int | find_by_name (void *obj, void *arg, void *data, int flags) |
| static int | find_by_notify_uri_helper (void *obj, void *arg, int flags) |
| static int | find_by_subscribe_uri_helper (void *obj, void *arg, int flags) |
| static struct sip_pvt * | find_call (struct sip_request *req, struct ast_sockaddr *addr, const int intended_method) |
| find or create a dialog structure for an incoming SIP message. Connect incoming SIP message to current dialog or create new dialog structure Returns a reference to the sip_pvt object, remember to give it back once done. Called by handle_incoming(), sipsock_read | |
| static int | find_calling_channel (void *obj, void *arg, void *data, int flags) |
| Find the channel that is causing the RINGING update. | |
| const char * | find_closing_quote (const char *start, const char *lim) |
| Locate closing quote in a string, skipping escaped quotes. optionally with a limit on the search. start must be past the first quote. | |
| static struct sip_peer * | find_peer (const char *peer, struct ast_sockaddr *addr, int realtime, int which_objects, int devstate_only, int transport) |
| Locate device by name or ip address. | |
| static struct sip_auth * | find_realm_authentication (struct sip_auth *authlist, const char *realm) |
| Find authentication for a specific realm. | |
| static int | find_sdp (struct sip_request *req) |
| Determine whether a SIP message contains an SDP in its body. | |
| static struct ast_cc_agent * | find_sip_cc_agent_by_notify_uri (const char *const uri) |
| static struct ast_cc_agent * | find_sip_cc_agent_by_original_callid (struct sip_pvt *pvt) |
| static struct ast_cc_agent * | find_sip_cc_agent_by_subscribe_uri (const char *const uri) |
| static int | find_sip_method (const char *msg) |
| find_sip_method: Find SIP method from header | |
| static int | find_sip_monitor_instance_by_subscription_pvt (void *obj, void *arg, int flags) |
| static int | find_sip_monitor_instance_by_suspension_entry (void *obj, void *arg, int flags) |
| static struct epa_static_data * | find_static_data (const char *const event_package) |
| static struct cfsubscription_types * | find_subscription_type (enum subscriptiontype subtype) |
| Find subscription type in array. | |
| static void | free_old_route (struct sip_route *route) |
| Remove route from route list. | |
| static int | func_check_sipdomain (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
| Dial plan function to check if domain is local. | |
| static int | func_header_read (struct ast_channel *chan, const char *function, char *data, char *buf, size_t len) |
| Read SIP header (dialplan function). | |
| static int | function_sipchaninfo_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
| ${SIPCHANINFO()} Dialplan function - reads sip channel data | |
| static int | function_sippeer (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
| ${SIPPEER()} Dialplan function - reads peer data | |
| static char * | generate_random_string (char *buf, size_t size) |
| Generate 32 byte random string for callid's etc. | |
| static char * | generate_uri (struct sip_pvt *pvt, char *buf, size_t size) |
| static int | get_address_family_filter (const struct ast_sockaddr *addr) |
| Helper for dns resolution to filter by address family. | |
| static int | get_also_info (struct sip_pvt *p, struct sip_request *oreq) |
| Call transfer support (old way, deprecated by the IETF). | |
| static char * | get_body (struct sip_request *req, char *name, char delimiter) |
| Get a specific line from the message body. | |
| static char * | get_body_by_line (const char *line, const char *name, int nameLen, char delimiter) |
| Reads one line of SIP message body. | |
| static int | get_cached_mwi (struct sip_peer *peer, int *new, int *old) |
| Get cached MWI info. | |
| static void | get_crypto_attrib (struct sip_srtp *srtp, const char **a_crypto) |
| static enum sip_get_dest_result | get_destination (struct sip_pvt *p, struct sip_request *oreq, int *cc_recall_core_id) |
| Find out who the call is for. We use the request uri as a destination. This code assumes authentication has been done, so that the device (peer/user) context is already set. | |
| static int | get_domain (const char *str, char *domain, int len) |
| Extract domain from SIP To/From header. | |
| static struct event_state_compositor * | get_esc (const char *const event_package) |
| static struct sip_esc_entry * | get_esc_entry (const char *entity_tag, struct event_state_compositor *esc) |
| static const char * | get_header (const struct sip_request *req, const char *name) |
| Get header from SIP request. | |
| static struct ast_variable * | get_insecure_variable_from_config (struct ast_config *config) |
| static int | get_ip_and_port_from_sdp (struct sip_request *req, const enum media_type media, struct ast_sockaddr *addr) |
| static int | get_msg_text (char *buf, int len, struct sip_request *req, int addnewline) |
| Get text out of a SIP MESSAGE packet. | |
| static const char * | get_name_from_variable (struct ast_variable *var, const char *newpeername) |
| static void | get_our_media_address (struct sip_pvt *p, int needvideo, int needtext, struct ast_sockaddr *addr, struct ast_sockaddr *vaddr, struct ast_sockaddr *taddr, struct ast_sockaddr *dest, struct ast_sockaddr *vdest, struct ast_sockaddr *tdest) |
| Set all IP media addresses for this call. | |
| static int | get_pai (struct sip_pvt *p, struct sip_request *req) |
| Parse the parts of the P-Asserted-Identity header on an incoming packet. Returns 1 if a valid header is found and it is different from the current caller id. | |
| static void | get_pidf_body (struct sip_request *req, char *pidf_body, size_t size) |
| static int | get_rdnis (struct sip_pvt *p, struct sip_request *oreq, char **name, char **number, int *reason) |
| Get referring dnis. | |
| static void | get_realm (struct sip_pvt *p, const struct sip_request *req) |
| Choose realm based on From header and then To header or use globaly configured realm. Realm from From/To header should be listed among served domains in config file: domain=... | |
| static int | get_refer_info (struct sip_pvt *transferer, struct sip_request *outgoing_req) |
| Call transfer support (the REFER method) Extracts Refer headers into pvt dialog structure. | |
| static int | get_rpid (struct sip_pvt *p, struct sip_request *oreq) |
| Get name, number and presentation from remote party id header, returns true if a valid header was found and it was different from the current caller id. | |
| static const char * | get_sdp_iterate (int *start, struct sip_request *req, const char *name) |
| Lookup 'name' in the SDP starting at the 'start' line. Returns the matching line, and 'start' is updated with the next line number. | |
| static char | get_sdp_line (int *start, int stop, struct sip_request *req, const char **value) |
| Fetches the next valid SDP line between the 'start' line (inclusive) and the 'stop' line (exclusive). Returns the type ('a', 'c', ...) and matching line in reference 'start' is updated with the next line number. | |
| static struct sip_pvt * | get_sip_pvt_byid_locked (const char *callid, const char *totag, const char *fromtag) |
| Lock dialog lock and find matching pvt lock. | |
| static const char * | get_srv_protocol (enum sip_transport t) |
| Return protocol string for srv dns query. | |
| static const char * | get_srv_service (enum sip_transport t) |
| Return service string for srv dns query. | |
| static const char * | get_transport (enum sip_transport t) |
| Return transport as string. | |
| static const char * | get_transport_list (unsigned int transports) |
| Return configuration of transports for a device. | |
| static const char * | get_transport_pvt (struct sip_pvt *p) |
| Return transport of dialog. | |
| static int | get_transport_str2enum (const char *transport) |
| Return int representing a bit field of transport types found in const char *transport. | |
| static const char * | gettag (const struct sip_request *req, const char *header, char *tagbuf, int tagbufsize) |
| Get tag from packet. | |
| static int | handle_cc_notify (struct sip_pvt *pvt, struct sip_request *req) |
| static int | handle_cc_subscribe (struct sip_pvt *p, struct sip_request *req) |
| static int | handle_common_options (struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v) |
| Handle flag-type options common to configuration of devices - peers. | |
| static int | handle_incoming (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, int *recount, int *nounlock) |
| Handle incoming SIP requests (methods). | |
| static int | handle_invite_replaces (struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct ast_sockaddr *addr, int *nounlock) |
| Handle the transfer part of INVITE with a replaces: header, meaning a target pickup or an attended transfer. Used only once. XXX 'ignore' is unused. | |
| static int | handle_request_bye (struct sip_pvt *p, struct sip_request *req) |
| Handle incoming BYE request. | |
| static int | handle_request_cancel (struct sip_pvt *p, struct sip_request *req) |
| Handle incoming CANCEL request. | |
| static int | handle_request_do (struct sip_request *req, struct ast_sockaddr *addr) |
| Handle incoming SIP message - request or response. | |
| static void | handle_request_info (struct sip_pvt *p, struct sip_request *req) |
| Receive SIP INFO Message. | |
| static int | handle_request_invite (struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct ast_sockaddr *addr, int *recount, const char *e, int *nounlock) |
| Handle incoming INVITE request. | |
| static int | handle_request_message (struct sip_pvt *p, struct sip_request *req) |
| Handle incoming MESSAGE request. | |
| static int | handle_request_notify (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, int seqno, const char *e) |
| Handle incoming notifications. | |
| static int | handle_request_options (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, const char *e) |
| Handle incoming OPTIONS request An OPTIONS request should be answered like an INVITE from the same UA, including SDP. | |
| static int | handle_request_publish (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, const int seqno, const char *uri) |
| static int | handle_request_refer (struct sip_pvt *p, struct sip_request *req, int debug, int seqno, int *nounlock) |
| static int | handle_request_register (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, const char *e) |
| Handle incoming REGISTER request. | |
| static int | handle_request_subscribe (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, int seqno, const char *e) |
| Handle incoming SUBSCRIBE request. | |
| static int | handle_request_update (struct sip_pvt *p, struct sip_request *req) |
| bare-bones support for SIP UPDATE | |
| static void | handle_response (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno) |
| Handle SIP response in dialogue. | |
| static void | handle_response_invite (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno) |
| Handle SIP response to INVITE dialogue. | |
| static void | handle_response_notify (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno) |
| static void | handle_response_peerpoke (struct sip_pvt *p, int resp, struct sip_request *req) |
| Handle qualification responses (OPTIONS). | |
| static void | handle_response_publish (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno) |
| static void | handle_response_refer (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno) |
| static int | handle_response_register (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno) |
| Handle responses on REGISTER to services. | |
| static void | handle_response_subscribe (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno) |
| static void | handle_response_update (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno) |
| Handle authentication challenge for SIP UPDATE. | |
| static int | handle_sip_publish_initial (struct sip_pvt *p, struct sip_request *req, struct event_state_compositor *esc, const int expires) |
| static int | handle_sip_publish_modify (struct sip_pvt *p, struct sip_request *req, struct event_state_compositor *esc, const char *const etag, const int expires) |
| static int | handle_sip_publish_refresh (struct sip_pvt *p, struct sip_request *req, struct event_state_compositor *esc, const char *const etag, const int expires) |
| static int | handle_sip_publish_remove (struct sip_pvt *p, struct sip_request *req, struct event_state_compositor *esc, const char *const etag) |
| static int | handle_t38_options (struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v, int *maxdatagram) |
| Handle T.38 configuration options common to users and peers. | |
| const char * | hangup_cause2sip (int cause) |
| Convert Asterisk hangup causes to SIP codes. | |
| int | hangup_sip2cause (int cause) |
| Convert SIP hangup causes to Asterisk hangup causes. | |
| static int | init_req (struct sip_request *req, int sipmethod, const char *recip) |
| Initialize SIP request. | |
| static int | init_resp (struct sip_request *resp, const char *msg) |
| Initialize SIP response, based on SIP request. | |
| static int | initialize_escs (void) |
| static void | initialize_initreq (struct sip_pvt *p, struct sip_request *req) |
| Initialize the initital request packet in the pvt structure. This packet is used for creating replies and future requests in a dialog. | |
| static void | initreqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod, const char *const explicit_uri) |
| Initiate new SIP request to peer/user. | |
| static const char * | insecure2str (int mode) |
| Convert Insecure setting to printable string. | |
| static int | interpret_t38_parameters (struct sip_pvt *p, const struct ast_control_t38_parameters *parameters) |
| Helper function which updates T.38 capability information and triggers a reinvite. | |
| static int | is_method_allowed (unsigned int *allowed_methods, enum sipmethod method) |
| Check if method is allowed for a device or a dialog. | |
| static void | list_route (struct sip_route *route) |
| List all routes - mostly for debugging. | |
| static int | load_module (void) |
| PBX load module - initialization. | |
| static int | local_attended_transfer (struct sip_pvt *transferer, struct sip_dual *current, struct sip_request *req, int seqno, int *nounlock) |
| Find all call legs and bridge transferee with target called from handle_request_refer. | |
| static int | lws2sws (char *msgbuf, int len) |
| Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled. | |
| static void | make_our_tag (char *tagbuf, size_t len) |
| Make our SIP dialog tag. | |
| static int | manager_show_registry (struct mansession *s, const struct message *m) |
| Show SIP registrations in the manager API. | |
| static int | manager_sip_qualify_peer (struct mansession *s, const struct message *m) |
| Qualify SIP peers in the manager API. | |
| static int | manager_sip_show_peer (struct mansession *s, const struct message *m) |
| Show SIP peers in the manager API. | |
| static int | manager_sip_show_peers (struct mansession *s, const struct message *m) |
| Show SIP peers in the manager API. | |
| static int | manager_sipnotify (struct mansession *s, const struct message *m) |
| static int | map_s_x (const struct _map_x_s *table, const char *s, int errorvalue) |
| map from a string to an integer value, case insensitive. If no match is found, return errorvalue. | |
| static const char * | map_x_s (const struct _map_x_s *table, int x, const char *errorstring) |
| map from an integer value to a string. If no match is found, return errorstring | |
| static void | mark_method_allowed (unsigned int *allowed_methods, enum sipmethod method) |
| static void | mark_method_unallowed (unsigned int *allowed_methods, enum sipmethod method) |
| static void | mark_parsed_methods (unsigned int *methods, char *methods_str) |
| static enum match_req_res | match_req_to_dialog (struct sip_pvt *sip_pvt_ptr, struct match_req_args *arg) |
| static int | method_match (enum sipmethod id, const char *name) |
| returns true if 'name' (with optional trailing whitespace) matches the sip method 'id'. Strictly speaking, SIP methods are case SENSITIVE, but we do a case-insensitive comparison to be more tolerant. following Jon Postel's rule: Be gentle in what you accept, strict with what you send | |
| static void | mwi_event_cb (const struct ast_event *event, void *userdata) |
| Receive MWI events that we have subscribed to. | |
| static void | network_change_event_cb (const struct ast_event *, void *) |
| static int | network_change_event_sched_cb (const void *data) |
| static void | network_change_event_subscribe (void) |
| static void | network_change_event_unsubscribe (void) |
| static struct sip_proxy * | obproxy_get (struct sip_pvt *dialog, struct sip_peer *peer) |
| Get default outbound proxy or global proxy. | |
| static unsigned int | parse_allowed_methods (struct sip_request *req) |
| parse the Allow header to see what methods the endpoint we are communicating with allows. | |
| static void | parse_copy (struct sip_request *dst, const struct sip_request *src) |
| Copy SIP request, parse it. | |
| static int | parse_minse (const char *p_hdrval, int *const p_interval) |
| Session-Timers: Function for parsing Min-SE header. | |
| static void | parse_moved_contact (struct sip_pvt *p, struct sip_request *req, char **name, char **number, int set_call_forward) |
| Parse 302 Moved temporalily response. | |
| static int | parse_ok_contact (struct sip_pvt *pvt, struct sip_request *req) |
| Save contact header for 200 OK on INVITE. | |
| static enum parse_register_result | parse_register_contact (struct sip_pvt *pvt, struct sip_peer *peer, struct sip_request *req) |
| Parse contact header and save registration (peer registration). | |
| static int | parse_request (struct sip_request *req) |
| Parse a SIP message. | |
| static int | parse_session_expires (const char *p_hdrval, int *const p_interval, enum st_refresher *const p_ref) |
| Session-Timers: Function for parsing Session-Expires header. | |
| static int | peer_cmp_cb (void *obj, void *arg, int flags) |
| static int | peer_dump_func (void *userobj, void *arg, int flags) |
| static int | peer_hash_cb (const void *obj, const int flags) |
| static int | peer_ipcmp_cb (void *obj, void *arg, int flags) |
| static int | peer_iphash_cb (const void *obj, const int flags) |
| static int | peer_is_marked (void *peerobj, void *arg, int flags) |
| static void | peer_mailboxes_to_str (struct ast_str **mailbox_str, struct sip_peer *peer) |
| list peer mailboxes to CLI | |
| static int | peer_markall_func (void *device, void *arg, int flags) |
| static int | peer_status (struct sip_peer *peer, char *status, int statuslen) |
| int | peercomparefunc (const void *a, const void *b) |
| static int | peers_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root) |
| 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. | |
| static void | print_codec_to_cli (int fd, struct ast_codec_pref *pref) |
| Print codec list from preference to CLI/manager. | |
| static void | print_group (int fd, ast_group_t group, int crlf) |
| Print call group and pickup group. | |
| static void | proc_422_rsp (struct sip_pvt *p, struct sip_request *rsp) |
| Handle 422 response to INVITE with session-timer requested. | |
| static int | proc_session_timer (const void *vp) |
| Session-Timers: Process session refresh timeout event. | |
| static int | process_crypto (struct sip_pvt *p, struct ast_rtp_instance *rtp, struct sip_srtp **srtp, const char *a) |
| static void | process_request_queue (struct sip_pvt *p, int *recount, int *nounlock) |
| static int | process_sdp (struct sip_pvt *p, struct sip_request *req, int t38action) |
| Process SIP SDP offer, select formats and activate RTP channels If offer is rejected, we will not change any properties of the call Return 0 on success, a negative value on errors. Must be called after find_sdp(). | |
| static int | process_sdp_a_audio (const char *a, struct sip_pvt *p, struct ast_rtp_codecs *newaudiortp, int *last_rtpmap_codec) |
| static int | process_sdp_a_image (const char *a, struct sip_pvt *p) |
| static int | process_sdp_a_sendonly (const char *a, int *sendonly) |
| static int | process_sdp_a_text (const char *a, struct sip_pvt *p, struct ast_rtp_codecs *newtextrtp, char *red_fmtp, int *red_num_gen, int *red_data_pt, int *last_rtpmap_codec) |
| static int | process_sdp_a_video (const char *a, struct sip_pvt *p, struct ast_rtp_codecs *newvideortp, int *last_rtpmap_codec) |
| static int | process_sdp_c (const char *c, struct ast_sockaddr *addr) |
| static int | process_sdp_o (const char *o, struct sip_pvt *p) |
| static int | process_via (struct sip_pvt *p, const struct sip_request *req) |
| Process the Via header according to RFC 3261 section 18.2.2. | |
| static int | proxy_update (struct sip_proxy *proxy) |
| static int | publish_expire (const void *data) |
| static void | pvt_set_needdestroy (struct sip_pvt *pvt, const char *reason) |
| static int | queue_request (struct sip_pvt *p, const struct sip_request *req) |
| static struct sip_peer * | realtime_peer (const char *newpeername, struct ast_sockaddr *addr, int devstate_only, int which_objects) |
| realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf Checks the "sipregs" realtime family from extconfig.conf if it's configured. This returns a pointer to a peer and because we use build_peer, we can rest assured that the refcount is bumped. | |
| static void | realtime_update_peer (const char *peername, struct ast_sockaddr *addr, const char *defaultuser, const char *fullcontact, const char *useragent, int expirey, unsigned short deprecated_username, int lastms) |
| Update peer object in realtime storage If the Asterisk system name is set in asterisk.conf, we will use that name and store that in the "regserver" field in the sippeers table to facilitate multi-server setups. | |
| static void | receive_message (struct sip_pvt *p, struct sip_request *req) |
| Receive SIP MESSAGE method messages. | |
| static struct sip_peer * | ref_peer (struct sip_peer *peer, char *tag) |
| static void | ref_proxy (struct sip_pvt *pvt, struct sip_proxy *proxy) |
| maintain proper refcounts for a sip_pvt's outboundproxy | |
| static const char * | referstatus2str (enum referstatus rstatus) |
| Convert transfer status to string. | |
| static void | reg_source_db (struct sip_peer *peer) |
| Get registration details from Asterisk DB. | |
| static void | register_peer_exten (struct sip_peer *peer, int onoff) |
| Automatically add peer extension to dial plan. | |
| static enum check_auth_result | register_verify (struct sip_pvt *p, struct ast_sockaddr *addr, struct sip_request *req, const char *uri) |
Verify registration of user
| |
| static struct sip_registry * | registry_addref (struct sip_registry *reg, char *tag) |
| Add object reference to SIP registry. | |
| static void * | registry_unref (struct sip_registry *reg, char *tag) |
| static const char * | regstate2str (enum sipregistrystate regstate) |
| Convert registration state status to string. | |
| static int | reload (void) |
| Part of Asterisk module interface. | |
| static int | reload_config (enum channelreloadreason reason) |
| Re-read SIP.conf config file. | |
| static char * | remove_uri_parameters (char *uri) |
| static int | reply_digest (struct sip_pvt *p, struct sip_request *req, char *header, int sipmethod, char *digest, int digest_len) |
| reply to authentication for outbound registrations | |
| static int | reqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod, int seqno, int newbranch) |
| Initialize a SIP request message (not the initial one in a dialog). | |
| static int | resp_needs_contact (const char *msg, enum sipmethod method) |
| Test if this response needs a contact header. | |
| static int | respprep (struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req) |
| Prepare SIP response packet. | |
| static int | restart_monitor (void) |
| Start the channel monitor thread. | |
| static void | restart_session_timer (struct sip_pvt *p) |
| Session-Timers: Restart session timer. | |
| static int | retrans_pkt (const void *data) |
| Retransmit SIP message if no answer (Called from scheduler). | |
| static int | scheduler_process_request_queue (const void *data) |
| static int | send_provisional_keepalive (const void *data) |
| static int | send_provisional_keepalive_full (struct sip_pvt *pvt, int with_sdp) |
| static int | send_provisional_keepalive_with_sdp (const void *data) |
| static int | send_request (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno) |
| Send SIP Request to the other part of the dialogue. | |
| static int | send_response (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno) |
| Transmit response on SIP request. | |
| static enum ast_cc_service_type | service_string_to_service_type (const char *const service_string) |
| static int | set_address_from_contact (struct sip_pvt *pvt) |
| Change the other partys IP address based on given contact. | |
| static void | set_destination (struct sip_pvt *p, char *uri) |
| Set destination from SIP URI. | |
| static void | set_insecure_flags (struct ast_flags *flags, const char *value, int lineno) |
| Parse insecure= setting in sip.conf and set flags according to setting. | |
| static void | set_nonce_randdata (struct sip_pvt *p, int forceupdate) |
| builds the sip_pvt's randdata field which is used for the nonce challenge. When forceupdate is not set, the nonce is only updated if the current one is stale. In this case, a stalenonce is one which has already received a response, if a nonce has not received a response it is not always necessary or beneficial to create a new one. | |
| static void | set_peer_defaults (struct sip_peer *peer) |
| Set peer defaults before configuring specific configurations. | |
| static unsigned int | set_pvt_allowed_methods (struct sip_pvt *pvt, struct sip_request *req) |
| static void | set_socket_transport (struct sip_socket *socket, int transport) |
| static void | set_t38_capabilities (struct sip_pvt *p) |
| Set the global T38 capabilities on a SIP dialog structure. | |
| static int | setup_srtp (struct sip_srtp **srtp) |
| static int | show_channels_cb (void *__cur, void *__arg, int flags) |
| callback for show channel|subscription | |
| static int | show_chanstats_cb (void *__cur, void *__arg, int flags) |
| Callback for show_chanstats. | |
| static int | sip_addheader (struct ast_channel *chan, const char *data) |
| Add a SIP header to an outbound INVITE. | |
| sip_pvt * | sip_alloc (ast_string_field callid, struct ast_sockaddr *addr, int useglobal_nat, const int intended_method, struct sip_request *req) |
| Allocate sip_pvt structure, set defaults and link in the container. Returns a reference to the object so whoever uses it later must remember to release the reference. | |
| static void | sip_alreadygone (struct sip_pvt *dialog) |
| Encapsulate setting of SIP_ALREADYGONE to be able to trace it with debugging. | |
| static int | sip_answer (struct ast_channel *ast) |
| sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface | |
| static int | sip_call (struct ast_channel *ast, char *dest, int timeout) |
| Initiate SIP call from PBX used from the dial() application. | |
| int | sip_cancel_destroy (struct sip_pvt *p) |
| Cancel destruction of SIP dialog. Be careful as this also absorbs the reference - if you call it from within the scheduler, this might be the last reference. | |
| static void | sip_cc_agent_destructor (struct ast_cc_agent *agent) |
| static int | sip_cc_agent_init (struct ast_cc_agent *agent, struct ast_channel *chan) |
| static int | sip_cc_agent_recall (struct ast_cc_agent *agent) |
| static void | sip_cc_agent_respond (struct ast_cc_agent *agent, enum ast_cc_agent_response_reason reason) |
| static int | sip_cc_agent_start_monitoring (struct ast_cc_agent *agent) |
| static int | sip_cc_agent_start_offer_timer (struct ast_cc_agent *agent) |
| static int | sip_cc_agent_status_request (struct ast_cc_agent *agent) |
| static int | sip_cc_agent_stop_offer_timer (struct ast_cc_agent *agent) |
| static int | sip_cc_monitor_cancel_available_timer (struct ast_cc_monitor *monitor, int *sched_id) |
| static void | sip_cc_monitor_destructor (void *private_data) |
| static int | sip_cc_monitor_request_cc (struct ast_cc_monitor *monitor, int *available_timer_id) |
| static int | sip_cc_monitor_suspend (struct ast_cc_monitor *monitor) |
| static int | sip_cc_monitor_unsuspend (struct ast_cc_monitor *monitor) |
| static int | sip_check_authtimeout (time_t start) |
| Check if the authtimeout has expired. | |
| static char * | sip_cli_notify (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Cli command to send SIP notify to peer. | |
| static int | sip_debug_test_addr (const struct ast_sockaddr *addr) |
| See if we pass debug IP filter. | |
| static int | sip_debug_test_pvt (struct sip_pvt *p) |
| Test PVT for debugging output. | |
| sip_pvt * | sip_destroy (struct sip_pvt *p) |
| Destroy SIP call structure. Make it return NULL so the caller can do things like foo = sip_destroy(foo); and reduce the chance of bugs due to dangling pointers. | |
| static void | sip_destroy_fn (void *p) |
| static void | sip_destroy_peer (struct sip_peer *peer) |
| Destroy peer object from memory. | |
| static void | sip_destroy_peer_fn (void *peer) |
| static int | sip_devicestate (void *data) |
| Part of PBX channel interface. | |
| static char * | sip_do_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Turn on SIP debugging (CLI command). | |
| static char * | sip_do_debug_ip (int fd, const char *arg) |
| Enable SIP Debugging for a single IP. | |
| static char * | sip_do_debug_peer (int fd, const char *arg) |
| Turn on SIP debugging for a given peer. | |
| static int | sip_do_reload (enum channelreloadreason reason) |
| Reload module. | |
| static int | sip_dtmfmode (struct ast_channel *chan, const char *data) |
| Set the DTMFmode for an outbound SIP call (application). | |
| static void | sip_dump_history (struct sip_pvt *dialog) |
| Dump SIP history to debug log file at end of lifespan for SIP dialog. | |
| static int | sip_epa_register (const struct epa_static_data *static_data) |
| static int | sip_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
| sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links | |
| static const char * | sip_get_callid (struct ast_channel *chan) |
| Deliver SIP call ID for the call. | |
| static int | sip_get_cc_information (struct sip_request *req, char *subscribe_uri, size_t size, enum ast_cc_service_type *service) |
| static format_t | sip_get_codec (struct ast_channel *chan) |
| static enum ast_rtp_glue_result | sip_get_rtp_peer (struct ast_channel *chan, struct ast_rtp_instance **instance) |
| static enum ast_rtp_glue_result | sip_get_trtp_peer (struct ast_channel *chan, struct ast_rtp_instance **instance) |
| static struct ast_udptl * | sip_get_udptl_peer (struct ast_channel *chan) |
| static enum ast_rtp_glue_result | sip_get_vrtp_peer (struct ast_channel *chan, struct ast_rtp_instance **instance) |
| static void | sip_handle_cc (struct sip_pvt *pvt, struct sip_request *req, enum ast_cc_service_type service) |
| static int | sip_hangup (struct ast_channel *ast) |
| sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup | |
| static int | sip_indicate (struct ast_channel *ast, int condition, const void *data, size_t datalen) |
| Play indication to user With SIP a lot of indications is sent as messages, letting the device play the indication - busy signal, congestion etc. | |
| static int | sip_is_xml_parsable (void) |
| static int | sip_monitor_instance_cmp_fn (void *obj, void *arg, int flags) |
| static void | sip_monitor_instance_destructor (void *data) |
| static int | sip_monitor_instance_hash_fn (const void *obj, const int flags) |
| static struct sip_monitor_instance * | sip_monitor_instance_init (int core_id, const char *const subscribe_uri, const char *const peername, const char *const device_name) |
| static const char * | sip_nat_mode (const struct sip_pvt *p) |
| Display SIP nat mode. | |
| static struct ast_channel * | sip_new (struct sip_pvt *i, int state, const char *title, const char *linkedid) |
| Initiate a call in the SIP channel called from sip_request_call (calls from the pbx ) for outbound channels and from handle_request_invite for inbound channels. | |
| static int | sip_notify_allocate (struct sip_pvt *p) |
| Allocate SIP refer structure. | |
| static int | sip_offer_timer_expire (const void *data) |
| static int | sip_park (struct ast_channel *chan1, struct ast_channel *chan2, struct sip_request *req, int seqno, char *parkexten) |
| Park a call using the subsystem in res_features.c This is executed in a separate thread. | |
| static void * | sip_park_thread (void *stuff) |
| Park SIP call support function Starts in a new thread, then parks the call XXX Should we add a wait period after streaming audio and before hangup?? Sometimes the audio can't be heard before hangup. | |
| static void | sip_peer_hold (struct sip_pvt *p, int hold) |
| Change onhold state of a peer using a pvt structure. | |
| static int | sip_pidf_validate (struct sip_request *req, struct ast_xml_doc **pidf_doc) |
| Makes sure that body is properly formatted PIDF. | |
| static void | sip_poke_all_peers (void) |
| Send a poke to all known peers. | |
| static int | sip_poke_noanswer (const void *data) |
| React to lack of answer to Qualify poke. | |
| static int | sip_poke_peer (struct sip_peer *peer, int force) |
| Check availability of peer, also keep NAT open. | |
| static int | sip_poke_peer_s (const void *data) |
| Poke peer (send qualify to check if peer is alive and well). | |
| static int | sip_prepare_socket (struct sip_pvt *p) |
| static char * | sip_prune_realtime (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Remove temporary realtime objects from memory (CLI). | |
| static char * | sip_qualify_peer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Send an OPTIONS packet to a SIP peer. | |
| static int | sip_queryoption (struct ast_channel *chan, int option, void *data, int *datalen) |
| Query an option on a SIP dialog. | |
| static struct ast_frame * | sip_read (struct ast_channel *ast) |
| Read SIP RTP from channel. | |
| static struct ast_sockaddr * | sip_real_dst (const struct sip_pvt *p) |
| The real destination address for a write. | |
| static const char * | sip_reason_code_to_str (enum AST_REDIRECTING_REASON code) |
| static enum AST_REDIRECTING_REASON | sip_reason_str_to_code (const char *text) |
| static int | sip_refer_allocate (struct sip_pvt *p) |
| Allocate SIP refer structure. | |
| static int | sip_reg_timeout (const void *data) |
| Registration timeout, register again Registered as a timeout handler during transmit_register(), to retransmit the packet if a reply does not come back. This is called by the scheduler so the event is not pending anymore when we are called. | |
| static int | sip_register (const char *value, int lineno) |
| create sip_registry object from register=> line in sip.conf and link into reg container | |
| static void | sip_register_tests (void) |
| SIP test registration. | |
| static void | sip_registry_destroy (struct sip_registry *reg) |
| Destroy registry object Objects created with the register= statement in static configuration. | |
| static int | sip_reinvite_retry (const void *data) |
| Reset the NEEDREINVITE flag after waiting when we get 491 on a Re-invite to avoid race conditions between asterisk servers. Called from the scheduler. | |
| static char * | sip_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Force reload of module from cli. | |
| static int | sip_removeheader (struct ast_channel *chan, const char *data) |
| Remove SIP headers added previously with SipAddHeader application. | |
| static struct ast_channel * | sip_request_call (const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause) |
| PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here. | |
| static int | sip_reregister (const void *data) |
| Update registration with SIP Proxy. Called from the scheduler when the previous registration expires, so we don't have to cancel the pending event. We assume the reference so the sip_registry is valid, since it is stored in the scheduled event anyways. | |
| static struct ast_frame * | sip_rtp_read (struct ast_channel *ast, struct sip_pvt *p, int *faxdetect) |
| Read RTP from network. | |
| void | sip_scheddestroy (struct sip_pvt *p, int ms) |
| Schedule destruction of SIP dialog. | |
| void | sip_scheddestroy_final (struct sip_pvt *p, int ms) |
| Schedule final destruction of SIP dialog. This can not be canceled. This function is used to keep a dialog around for a period of time in order to properly respond to any retransmits. | |
| static void | sip_send_all_mwi_subscriptions (void) |
| Send all MWI subscriptions. | |
| static void | sip_send_all_registers (void) |
| Send all known registrations. | |
| static int | sip_send_mwi_to_peer (struct sip_peer *peer, const struct ast_event *event, int cache_only) |
| Send message waiting indication to alert peer that they've got voicemail. | |
| static int | sip_senddigit_begin (struct ast_channel *ast, char digit) |
| static int | sip_senddigit_end (struct ast_channel *ast, char digit, unsigned int duration) |
| Send DTMF character on SIP channel within one call, we're able to transmit in many methods simultaneously. | |
| static int | sip_sendhtml (struct ast_channel *chan, int subclass, const char *data, int datalen) |
| Send message with Access-URL header, if this is an HTML URL only! | |
| static int | sip_sendtext (struct ast_channel *ast, const char *text) |
| Send SIP MESSAGE text within a call Called from PBX core sendtext() application. | |
| static char * | sip_set_history (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Enable/Disable SIP History logging (CLI). | |
| static void | sip_set_redirstr (struct sip_pvt *p, char *reason) |
| Translate referring cause. | |
| static int | sip_set_rtp_peer (struct ast_channel *chan, struct ast_rtp_instance *instance, struct ast_rtp_instance *vinstance, struct ast_rtp_instance *tinstance, format_t codecs, int nat_active) |
| static int | sip_set_udptl_peer (struct ast_channel *chan, struct ast_udptl *udptl) |
| static int | sip_setoption (struct ast_channel *chan, int option, void *data, int datalen) |
| Set an option on a SIP dialog. | |
| static char * | sip_show_channel (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Show details of one active dialog. | |
| static char * | sip_show_channels (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| CLI for show channels or subscriptions. This is a new-style CLI handler so a single function contains the prototype for the function, the 'generator' to produce multiple entries in case it is required, and the actual handler for the command. | |
| static char * | sip_show_channelstats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| SIP show channelstats CLI (main function). | |
| static char * | sip_show_domains (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| CLI command to list local domains. | |
| static char * | sip_show_history (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Show history details of one dialog. | |
| static char * | sip_show_inuse (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| CLI Command to show calls within limits set by call_limit. | |
| static char * | sip_show_mwi (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | sip_show_objects (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| List all allocated SIP Objects (realtime or static). | |
| static char * | sip_show_peer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Show one peer in detail. | |
| static char * | sip_show_peers (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| CLI Show Peers command. | |
| static char * | sip_show_registry (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Show SIP Registry (registrations with other SIP proxies. | |
| static char * | sip_show_sched (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | sip_show_settings (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| List global settings for the SIP channel. | |
| static char * | sip_show_tcp (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Show active TCP connections. | |
| static char * | sip_show_user (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Show one user in detail. | |
| static char * | sip_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| CLI Command 'SIP Show Users'. | |
| static int | sip_sipredirect (struct sip_pvt *p, const char *dest) |
| Transfer call before connect with a 302 redirect. | |
| static struct sip_st_dlg * | sip_st_alloc (struct sip_pvt *const p) |
| Allocate Session-Timers struct w/in dialog. | |
| static int | sip_standard_port (enum sip_transport type, int port) |
| Returns the port to use for this socket. | |
| static int | sip_subscribe_mwi (const char *value, int lineno) |
| Parse mwi=> line in sip.conf and add to list. | |
| static void | sip_subscribe_mwi_destroy (struct sip_subscription_mwi *mwi) |
| Destroy MWI subscription object. | |
| static int | sip_subscribe_mwi_do (const void *data) |
| Send a subscription or resubscription for MWI. | |
| static int | sip_t38_abort (const void *data) |
| Called to deny a T38 reinvite if the core does not respond to our request. | |
| static struct ast_tcptls_session_instance * | sip_tcp_locate (struct ast_sockaddr *s) |
| Find thread for TCP/TLS session (based on IP/Port. | |
| static void * | sip_tcp_worker_fn (void *data) |
| SIP TCP connection handler. | |
| static void | sip_tcptls_client_args_destructor (void *obj) |
| static int | sip_tcptls_write (struct ast_tcptls_session_instance *tcptls_session, const void *buf, size_t len) |
| used to indicate to a tcptls thread that data is ready to be written | |
| static struct sip_threadinfo * | sip_threadinfo_create (struct ast_tcptls_session_instance *tcptls_session, int transport) |
| creates a sip_threadinfo object and links it into the threadt table. | |
| static void | sip_threadinfo_destructor (void *obj) |
| static int | sip_transfer (struct ast_channel *ast, const char *dest) |
| Transfer SIP call. | |
| static char * | sip_unregister (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Unregister (force expiration) a SIP peer in the registry via CLI. | |
| static void | sip_unregister_tests (void) |
| SIP test registration. | |
| static int | sip_write (struct ast_channel *ast, struct ast_frame *frame) |
| Send frame to media channel (rtp). | |
| static int | sipsock_read (int *id, int fd, short events, void *ignore) |
| Read data from SIP UDP socket. | |
| static enum st_mode | st_get_mode (struct sip_pvt *p) |
| Get the session-timer mode. | |
| static enum st_refresher | st_get_refresher (struct sip_pvt *p) |
| Get the entity (UAC or UAS) that's acting as the session-timer refresher. | |
| static int | st_get_se (struct sip_pvt *p, int max) |
| Get Max or Min SE (session timer expiry). | |
| static void | start_session_timer (struct sip_pvt *p) |
| Session-Timers: Start session timer. | |
| static void | state_notify_build_xml (int state, int full, const char *exten, const char *context, struct ast_str **tmp, struct sip_pvt *p, int subscribed, const char *mfrom, const char *mto) |
| Builds XML portion of NOTIFY messages for presence or dialog updates. | |
| static const char * | stmode2str (enum st_mode m) |
| static void | stop_media_flows (struct sip_pvt *p) |
| Immediately stop RTP, VRTP and UDPTL as applicable. | |
| static void | stop_session_timer (struct sip_pvt *p) |
| Session-Timers: Stop session timer. | |
| static int | str2dtmfmode (const char *str) |
| maps a string to dtmfmode, returns -1 on error | |
| static enum st_mode | str2stmode (const char *s) |
| static enum st_refresher | str2strefresher (const char *s) |
| static const char * | strefresher2str (enum st_refresher r) |
| static const char * | subscription_type2str (enum subscriptiontype subtype) |
| Show subscription type in string format. | |
| static unsigned int | t38_get_rate (enum ast_control_t38_rate rate) |
| Get Max T.38 Transmission rate from T38 capabilities. | |
| static void | tcptls_packet_destructor (void *obj) |
| static struct sip_peer * | temp_peer (const char *name) |
| Create temporary peer (used in autocreatepeer mode). | |
| static void | temp_pvt_cleanup (void *) |
| static int | temp_pvt_init (void *) |
| static char * | terminate_uri (char *uri) |
| static int | threadinfo_locate_cb (void *obj, void *arg, int flags) |
| static int | threadt_cmp_cb (void *obj, void *arg, int flags) |
| static int | threadt_hash_cb (const void *obj, const int flags) |
| static char * | transfermode2str (enum transfermodes mode) |
| Convert transfer mode to text string. | |
| static int | transmit_cc_notify (struct ast_cc_agent *agent, struct sip_pvt *subscription, enum sip_cc_notify_state state) |
| static void | transmit_fake_auth_response (struct sip_pvt *p, int sipmethod, struct sip_request *req, enum xmittype reliable) |
| Send a fake 401 Unauthorized response when the administrator wants to hide the names of local devices from fishers. | |
| static int | transmit_info_with_aoc (struct sip_pvt *p, struct ast_aoc_decoded *decoded) |
| Send SIP INFO advice of charge message. | |
| static int | transmit_info_with_digit (struct sip_pvt *p, const char digit, unsigned int duration) |
| Send SIP INFO dtmf message, see Cisco documentation on cisco.com. | |
| static int | transmit_info_with_vidupdate (struct sip_pvt *p) |
| Send SIP INFO with video update request. | |
| static int | transmit_invite (struct sip_pvt *p, int sipmethod, int sdp, int init, const char *const explicit_uri) |
| Build REFER/INVITE/OPTIONS/SUBSCRIBE message and transmit it. | |
| static int | transmit_message_with_text (struct sip_pvt *p, const char *text) |
| Transmit text with SIP MESSAGE method. | |
| static int | transmit_notify_with_mwi (struct sip_pvt *p, int newmsgs, int oldmsgs, const char *vmexten) |
| Notify user of messages waiting in voicemail (RFC3842). | |
| static int | transmit_notify_with_sipfrag (struct sip_pvt *p, int cseq, char *message, int terminate) |
| Notify a transferring party of the status of transfer (RFC3515). | |
| static int | transmit_provisional_response (struct sip_pvt *p, const char *msg, const struct sip_request *req, int with_sdp) |
| static int | transmit_publish (struct sip_epa_entry *epa_entry, enum sip_publish_type publish_type, const char *const explicit_uri) |
| static int | transmit_refer (struct sip_pvt *p, const char *dest) |
| Transmit SIP REFER message (initiated by the transfer() dialplan application. | |
| static int | transmit_register (struct sip_registry *r, int sipmethod, const char *auth, const char *authheader) |
| Transmit register to SIP proxy or UA auth = NULL on the initial registration (from sip_reregister()). | |
| static int | transmit_reinvite_with_sdp (struct sip_pvt *p, int t38version, int oldsdp) |
| Transmit reinvite with SDP. | |
| static int | transmit_request (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch) |
| Transmit generic SIP request returns XMIT_ERROR if transmit failed with a critical error (don't retry). | |
| static int | transmit_request_with_auth (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch) |
| Transmit SIP request, auth added. | |
| static int | transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
| Transmit response, no retransmits. | |
| static int | transmit_response_reliable (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
| Transmit response, Make sure you get an ACK This is only used for responses to INVITEs, where we need to make sure we get an ACK. | |
| static int | transmit_response_using_temp (ast_string_field callid, struct ast_sockaddr *addr, int useglobal_nat, const int intended_method, const struct sip_request *req, const char *msg) |
| Transmit response, no retransmits, using a temporary pvt structure. | |
| static int | transmit_response_with_allow (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
| Append Accept header, content length before transmitting response. | |
| static int | transmit_response_with_auth (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *randdata, enum xmittype reliable, const char *header, int stale) |
| Respond with authorization request. | |
| static int | transmit_response_with_date (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
| Append date and content length before transmitting response. | |
| static int | transmit_response_with_minexpires (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
| Append Min-Expires header, content length before transmitting response. | |
| static int | transmit_response_with_minse (struct sip_pvt *p, const char *msg, const struct sip_request *req, int minse_int) |
| Transmit 422 response with Min-SE header (Session-Timers). | |
| static int | transmit_response_with_retry_after (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *seconds) |
| Append Retry-After header field when transmitting response. | |
| static int | transmit_response_with_sdp (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable, int oldsdp, int rpid) |
| Used for 200 OK and 183 early media. | |
| static int | transmit_response_with_sip_etag (struct sip_pvt *p, const char *msg, const struct sip_request *req, struct sip_esc_entry *esc_entry, int need_new_etag) |
| static int | transmit_response_with_t38_sdp (struct sip_pvt *p, char *msg, struct sip_request *req, int retrans) |
| Used for 200 OK and 183 early media. | |
| static int | transmit_response_with_unsupported (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *unsupported) |
| Transmit response, no retransmits. | |
| static int | transmit_state_notify (struct sip_pvt *p, int state, int full, int timeout) |
| Used in the SUBSCRIBE notification subsystem (RFC3265). | |
| static void | try_suggested_sip_codec (struct sip_pvt *p) |
| Try setting codec suggested by the SIP_CODEC channel variable. | |
| static void | unlink_marked_peers_from_tables (void) |
| static void | unlink_peer_from_tables (struct sip_peer *peer) |
| static int | unload_module (void) |
| PBX unload module API. | |
| static void * | unref_peer (struct sip_peer *peer, char *tag) |
| static int | update_call_counter (struct sip_pvt *fup, int event) |
| update_call_counter: Handle call_limit for SIP devices Setting a call-limit will cause calls above the limit not to be accepted. | |
| static void | update_connectedline (struct sip_pvt *p, const void *data, size_t datalen) |
| Notify peer that the connected line has changed. | |
| static void | update_peer (struct sip_peer *p, int expire) |
| Update peer data in database (if used). | |
| static void | update_provisional_keepalive (struct sip_pvt *pvt, int with_sdp) |
| static void | update_redirecting (struct sip_pvt *p, const void *data, size_t datalen) |
| Send a provisional response indicating that a call was redirected. | |
| 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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .nonoptreq = "res_crypto,chan_local", } |
| static int | apeerobjs = 0 |
| static char * | app_dtmfmode = "SIPDtmfMode" |
| static char * | app_sipaddheader = "SIPAddHeader" |
| static char * | app_sipremoveheader = "SIPRemoveHeader" |
| static struct ast_module_info * | ast_module_info = &__mod_info |
| static struct sip_auth * | authl = NULL |
| Authentication list for realm authentication. | |
| ast_sockaddr | bindaddr |
| static struct epa_static_data | cc_epa_static_data |
| static struct sip_esc_publish_callbacks | cc_esc_publish_callbacks |
| static struct ast_threadstorage | check_auth_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_check_auth_buf , .custom_init = NULL , } |
| static struct ast_custom_function | checksipdomain_function |
| static struct ast_cli_entry | cli_sip [] |
| SIP Cli commands definition. | |
| static struct ast_sockaddr | debugaddr |
| static const int | DEFAULT_PUBLISH_EXPIRES = 3600 |
| static struct ast_tls_config | default_tls_cfg |
| Default TLS connection configuration. | |
| static struct ao2_container * | dialogs |
| Here we implement the container for dialogs (sip_pvt), defining generic wrapper functions to ease the transition from the current implementation (a single linked list) to a different container. In addition to a reference to the container, we need functions to lock/unlock the container and individual items, and functions to add/remove references to the individual items. | |
| static struct _map_x_s | dtmfstr [] |
| mapping between dtmf flags and strings | |
| static int | esc_etag_counter |
| static const int | ESC_MAX_BUCKETS = 37 |
| static struct event_state_compositor | event_state_compositors [] |
| The Event State Compositors. | |
| static struct ast_sockaddr | externaddr |
| our external IP address/port for SIP sessions. externaddr.sin_addr is only set when we know we might be behind a NAT, and this is done using a variety of (mutually exclusive) ways from the config file: | |
| static time_t | externexpire |
| static char | externhost [MAXHOSTNAMELEN] |
| static int | externrefresh = 10 |
| static uint16_t | externtcpport |
| static uint16_t | externtlsport |
| static struct _map_x_s | faxecmodes [] |
| static struct ast_flags | global_flags [3] = {{0}} |
| static int | global_t38_maxdatagram |
| static const int | HASH_DIALOG_SIZE = 563 |
| static const int | HASH_PEER_SIZE = 563 |
| static struct _map_x_s | insecurestr [] |
| static struct ast_sockaddr | internip |
| our (internal) default address/port to put in SIP/SDP messages internip is initialized picking a suitable address from one of the interfaces, and the same port number we bind to. It is used as the default address/port in SIP messages, and as the default address (but not port) in SDP messages. | |
| static struct io_context * | io |
| static struct ast_ha * | localaddr |
| List of local networks We store "localnet" addresses from the config file into an access list, marked as 'DENY', so the call to ast_apply_ha() will return AST_SENSE_DENY for 'local' addresses, and AST_SENSE_ALLOW for 'non local' (i.e. presumably public) addresses. | |
| static struct ast_sockaddr | media_address |
| static pthread_t | monitor_thread = AST_PTHREADT_NULL |
| This is the thread for the monitor which checks for input on the channels which are not currently in use. | |
| static ast_mutex_t | monlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } |
| Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical. | |
| static ast_mutex_t | netlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } |
| static int | network_change_event_sched_id = -1 |
| static struct ast_event_sub * | network_change_event_subscription |
| static struct ast_config * | notify_types = NULL |
| static int | ourport_tcp |
| static int | ourport_tls |
| static struct ao2_container * | peers |
| The peer list: Users, Peers and Friends. | |
| static struct ao2_container * | peers_by_ip |
| static struct ast_data_handler | peers_data_provider |
| static struct _map_x_s | referstatusstrings [] |
| static struct ast_register_list | regl |
| The register list: Other SIP proxies we register with and receive calls from. | |
| static int | regobjs = 0 |
| static struct _map_x_s | regstatestrings [] |
| static int | rpeerobjs = 0 |
| sched_context * | sched |
| static struct ast_cc_agent_callbacks | sip_cc_agent_callbacks |
| static struct ast_cc_monitor_callbacks | sip_cc_monitor_callbacks |
| struct { | |
| enum sip_cc_notify_state state | |
| const char * state_string | |
| } | sip_cc_notify_state_map [] |
| struct { | |
| enum ast_cc_service_type service | |
| const char * service_string | |
| } | sip_cc_service_map [] |
| static struct ast_data_entry | sip_data_providers [] |
| static struct ast_custom_function | sip_header_function |
| ao2_container * | sip_monitor_instances |
| static ast_mutex_t | sip_reload_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } |
| 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. | |
| ast_channel_tech | sip_tech |
| Definition of this channel for PBX channel registration. | |
| ast_channel_tech | sip_tech_info |
| This version of the sip channel tech has no send_digit_begin callback so that the core knows that the channel does not want DTMF BEGIN frames. The struct is initialized just before registering the channel driver, and is for use with channels using SIP INFO DTMF. | |
| static struct ast_tls_config | sip_tls_cfg |
| Working TLS connection configuration. | |
| static struct ast_tcptls_session_args | sip_tls_desc |
| The TCP/TLS server definition. | |
| static struct ast_udptl_protocol | sip_udptl |
| Interface structure with callbacks used to connect to UDPTL module. | |
| static struct ast_custom_function | sipchaninfo_function |
| Structure to declare a dialplan function: SIPCHANINFO. | |
| static enum sip_debug_e | sipdebug |
| static int | sipdebug_text |
| extra debugging for 'text' related events. At the moment this is set together with sip_debug_console. | |
| static struct ast_custom_function | sippeer_function |
| Structure to declare a dialplan function: SIPPEER. | |
| static int | sipsock = -1 |
| Main socket for UDP SIP communication. | |
| static int * | sipsock_read_id |
| static int | speerobjs = 0 |
| static struct _map_x_s | stmodes [] |
| Report Peer status in character string. | |
| static struct _map_x_s | strefreshers [] |
| static struct ast_subscription_mwi_list | submwil |
| The MWI subscription list. | |
| static struct ao2_container * | threadt |
| The table of TCP threads. | |
| static struct ast_threadstorage | ts_temp_pvt = { .once = PTHREAD_ONCE_INIT , .key_init = __init_ts_temp_pvt , .custom_init = temp_pvt_init , } |
| static char | used_context [AST_MAX_CONTEXT] |
DefaultSettings | |
| Default setttings are used as a channel setting and as a default when configuring devices | |
| static char | default_callerid [AST_MAX_EXTENSION] |
| static char | default_engine [256] |
| static char | default_fromdomain [AST_MAX_EXTENSION] |
| static int | default_fromdomainport |
| static char | default_language [MAX_LANGUAGE] |
| static int | default_maxcallbitrate |
| static char | default_mohinterpret [MAX_MUSICCLASS] |
| static char | default_mohsuggest [MAX_MUSICCLASS] |
| static char | default_mwi_from [80] |
| static char | default_notifymime [AST_MAX_EXTENSION] |
| static char | default_parkinglot [AST_MAX_CONTEXT] |
| static struct ast_codec_pref | default_prefs |
| static unsigned int | default_primary_transport |
| static int | default_qualify |
| static unsigned int | default_transports |
| static char | default_vmexten [AST_MAX_EXTENSION] |
Defines | |
| #define | SIP_PEDANTIC_DECODE(str) |
Variables | |
| static int | authlimit = DEFAULT_AUTHLIMIT |
| static int | authtimeout = DEFAULT_AUTHTIMEOUT |
| static int | can_parse_xml |
| static unsigned int | chan_idx |
| static const char | config [] = "sip.conf" |
| static int | default_expiry = DEFAULT_DEFAULT_EXPIRY |
| static struct ast_jb_conf | default_jbconf |
| Global jitterbuffer configuration - by default, jb is disabled. | |
| static unsigned int | dumphistory |
| static int | global_authfailureevents |
| static unsigned int | global_autoframing |
| static int | global_callcounter |
| static unsigned int | global_cos_audio |
| static unsigned int | global_cos_sip |
| static unsigned int | global_cos_text |
| static unsigned int | global_cos_video |
| static int | global_dynamic_exclude_static = 0 |
| static struct ast_jb_conf | global_jbconf |
| static int | global_match_auth_username |
| static int | global_max_se |
| static int | global_min_se |
| static int | global_prematuremediafilter |
| static int | global_qualify_gap |
| static int | global_qualify_peers |
| static int | global_qualifyfreq |
| static int | global_reg_timeout |
| static int | global_regattempts_max |
| static int | global_relaxdtmf |
| static int | global_rtpholdtimeout |
| static int | global_rtpkeepalive |
| static int | global_rtptimeout |
| static char | global_sdpowner [AST_MAX_EXTENSION] |
| static char | global_sdpsession [AST_MAX_EXTENSION] |
| static int | global_shrinkcallerid |
| static enum st_mode | global_st_mode |
| static enum st_refresher | global_st_refresher |
| static int | global_t1 |
| static int | global_t1min |
| static int | global_timer_b |
| static unsigned int | global_tos_audio |
| static unsigned int | global_tos_sip |
| static unsigned int | global_tos_text |
| static unsigned int | global_tos_video |
| static char | global_useragent [AST_MAX_EXTENSION] |
| static struct invstate2stringtable | invitestate2string [] |
| Readable descriptions of device states. | |
| static int | max_expiry = DEFAULT_MAX_EXPIRY |
| static int | min_expiry = DEFAULT_MIN_EXPIRY |
| static int | mwi_expiry = DEFAULT_MWI_EXPIRY |
| static const char | notify_config [] = "sip_notify.conf" |
| static unsigned int | recordhistory |
| static struct sip_settings | sip_cfg |
| static struct cfsip_methods | sip_methods [] |
| The core structure to setup dialogs. We parse incoming messages by using structure and then route the messages according to the type. | |
| static struct sip_reasons | sip_reason_table [] |
| Diversion header reasons. | |
| static struct cfsubscription_types | subscription_types [] |
Subscription types that we support. We support
| |
| static int | unauth_sessions = 0 |
********** IMPORTANT *
VIA branch tag transaction checking
Transaction support
A new INVITE is sent to handle_request_invite(), that will end up starting a new channel in the PBX, the new channel after that executing in a separate channel thread. This is an incoming "call". When the call is answered, either by a bridged channel or the PBX itself the sip_answer() function is called.
The actual media - Video or Audio - is mostly handled by the RTP subsystem in rtp.c
Definition in file chan_sip.c.
| #define append_history | ( | p, | |||
| event, | |||||
| fmt, | |||||
| args... | ) | append_history_full(p, "%-15s " fmt, event, ## args) |
Append to SIP dialog history.
Definition at line 2190 of file chan_sip.c.
Referenced by __sip_autodestruct(), __sip_reliable_xmit(), auto_congest(), build_reply_digest(), cb_extensionstate(), change_hold_state(), do_register_auth(), handle_invite_replaces(), handle_request_bye(), handle_request_do(), handle_request_invite(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response(), handle_response_invite(), local_attended_transfer(), obproxy_get(), pvt_set_needdestroy(), retrans_pkt(), send_request(), send_response(), sip_cancel_destroy(), sip_fixup(), sip_hangup(), sip_new(), sip_park_thread(), sip_reregister(), sip_scheddestroy(), sip_set_rtp_peer(), transmit_register(), transmit_reinvite_with_sdp(), transmit_response_with_auth(), and update_connectedline().
| #define CHECK_AUTH_BUF_INITLEN 256 |
Definition at line 13585 of file chan_sip.c.
Referenced by check_auth(), and transmit_fake_auth_response().
| #define check_request_transport | ( | peer, | |||
| tmpl | ) |
generic function for determining if a correct transport is being used to contact a peer
this is done as a macro so that the "tmpl" var can be passed either a sip_request or a sip_peer
Definition at line 2273 of file chan_sip.c.
Referenced by create_addr_from_peer(), and register_verify().
| #define DATA_EXPORT_SIP_PEER | ( | MEMBER | ) |
Definition at line 28855 of file chan_sip.c.
| #define FORMAT "%-15.15s %-15.15s %-15.15s %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s %-10.10s\n" |
Definition at line 17420 of file chan_sip.c.
| #define FORMAT "%-30.30s %-12.12s %-10.10s %-10.10s\n" |
Definition at line 17420 of file chan_sip.c.
| #define FORMAT "%-15.15s %-11.11s %-8.8s %-10.10u%-1.1s %-10.10u (%5.2f%%) %-6.4lf %-10.10u%-1.1s %-10.10u (%5.2f%%) %-6.4lf\n" |
Definition at line 17420 of file chan_sip.c.
| #define FORMAT "%-39.39s %-6.6s %-12.12s %8d %-20.20s %-25.25s\n" |
Definition at line 17420 of file chan_sip.c.
| #define FORMAT "%-40.40s %-20.20s %-16.16s\n" |
Definition at line 17420 of file chan_sip.c.
| #define FORMAT "%-25.25s %-39.39s %-3.3s %-3.3s %-3.3s %-8d %-10s %s\n" |
Definition at line 17420 of file chan_sip.c.
| #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" |
Definition at line 17420 of file chan_sip.c.
| #define FORMAT "%-47.47s %-9.9s %-6.6s\n" |
Definition at line 17420 of file chan_sip.c.
| #define FORMAT "%-25.25s %-15.15s %-15.15s \n" |
Definition at line 17420 of file chan_sip.c.
| #define FORMAT2 "%-15.15s %-15.15s %-15.15s %-15.15s %-7.7s %-15.15s %-10.10s %-10.10s\n" |
Definition at line 17419 of file chan_sip.c.
| #define FORMAT2 "%-15.15s %-11.11s %-8.8s %-10.10s %-10.10s ( %%) %-6.6s %-10.10s %-10.10s ( %%) %-6.6s\n" |
Definition at line 17419 of file chan_sip.c.
| #define FORMAT2 "%-39.39s %-6.6s %-12.12s %8.8s %-20.20s %-25.25s\n" |
Definition at line 17419 of file chan_sip.c.
| #define FORMAT2 "%-25.25s %-39.39s %-3.3s %-10.10s %-3.3s %-8s %-10s %s\n" |
Definition at line 17419 of file chan_sip.c.
| #define FORMAT2 "%-47.47s %9.9s %6.6s\n" |
Definition at line 17419 of file chan_sip.c.
| #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" |
Definition at line 17419 of file chan_sip.c.
| #define FORMAT3 "%-15.15s %-15.15s %-15.15s %-15.15s %-13.13s %-15.15s %-10.10s %-6.6s\n" |
| #define FORMAT4 "%-15.15s %-15.15s %-15.15s %-15.15s %-13.13s %-15.15s %-10.10s %-6.6d\n" |
| #define SIP_PEDANTIC_DECODE | ( | str | ) |
Value:
if (sip_cfg.pedanticsipchecking && !ast_strlen_zero(str)) { \ ast_uri_decode(str); \ } \
Definition at line 700 of file chan_sip.c.
Referenced by check_user_full(), get_also_info(), get_destination(), get_refer_info(), and register_verify().
| #define sip_pvt_lock | ( | x | ) | ao2_lock(x) |
Definition at line 1081 of file chan_sip.c.
Referenced by __sip_ack(), __sip_autodestruct(), auto_congest(), cb_extensionstate(), check_rtp_timeout(), complete_sipch(), find_call(), get_sip_pvt_byid_locked(), handle_incoming(), handle_invite_replaces(), handle_request_bye(), handle_request_invite(), handle_request_refer(), local_attended_transfer(), proc_session_timer(), retrans_pkt(), scheduler_process_request_queue(), sip_answer(), sip_call(), sip_cc_agent_destructor(), sip_cc_agent_init(), sip_cc_agent_recall(), sip_cc_agent_respond(), sip_cc_monitor_request_cc(), sip_dtmfmode(), sip_fixup(), sip_get_rtp_peer(), sip_get_trtp_peer(), sip_get_udptl_peer(), sip_get_vrtp_peer(), sip_hangup(), sip_indicate(), sip_monitor_instance_destructor(), sip_new(), sip_park(), sip_queryoption(), sip_read(), sip_reg_timeout(), sip_reinvite_retry(), sip_request_call(), sip_senddigit_begin(), sip_senddigit_end(), sip_set_rtp_peer(), sip_set_udptl_peer(), sip_show_channel(), sip_show_history(), sip_t38_abort(), sip_transfer(), sip_write(), transmit_publish(), and update_call_counter().
| #define sip_pvt_trylock | ( | x | ) | ao2_trylock(x) |
| #define sip_pvt_unlock | ( | x | ) | ao2_unlock(x) |
Definition at line 1083 of file chan_sip.c.
Referenced by __sip_ack(), __sip_autodestruct(), auto_congest(), cb_extensionstate(), check_rtp_timeout(), complete_sipch(), dialog_needdestroy(), get_sip_pvt_byid_locked(), handle_incoming(), handle_invite_replaces(), handle_request_bye(), handle_request_do(), handle_request_invite(), handle_request_refer(), local_attended_transfer(), proc_session_timer(), retrans_pkt(), scheduler_process_request_queue(), sip_answer(), sip_call(), sip_cc_agent_destructor(), sip_cc_agent_init(), sip_cc_agent_recall(), sip_cc_agent_respond(), sip_cc_monitor_request_cc(), sip_dtmfmode(), sip_fixup(), sip_get_rtp_peer(), sip_get_trtp_peer(), sip_get_udptl_peer(), sip_get_vrtp_peer(), sip_hangup(), sip_indicate(), sip_monitor_instance_destructor(), sip_new(), sip_park(), sip_queryoption(), sip_read(), sip_reg_timeout(), sip_reinvite_retry(), sip_request_call(), sip_senddigit_begin(), sip_senddigit_end(), sip_set_rtp_peer(), sip_set_udptl_peer(), sip_show_channel(), sip_show_history(), sip_t38_abort(), sip_transfer(), sip_write(), transmit_publish(), and update_call_counter().
| #define UNLINK | ( | element, | |||
| head, | |||||
| prev | ) |
some list management macros.
Definition at line 1180 of file chan_sip.c.
Referenced by __sip_ack(), handle_request_cancel(), and retrans_pkt().
| enum match_req_res |
Definition at line 7460 of file chan_sip.c.
07460 { 07461 SIP_REQ_MATCH, 07462 SIP_REQ_NOT_MATCH, 07463 SIP_REQ_LOOP_DETECTED, 07464 };
| static const char * __get_header | ( | const struct sip_request * | req, | |
| const char * | name, | |||
| int * | start | |||
| ) | [static] |
Definition at line 6987 of file chan_sip.c.
References ast_skip_blanks(), find_alias(), len(), pass, and sip_cfg.
06988 { 06989 int pass; 06990 06991 /* 06992 * Technically you can place arbitrary whitespace both before and after the ':' in 06993 * a header, although RFC3261 clearly says you shouldn't before, and place just 06994 * one afterwards. If you shouldn't do it, what absolute idiot decided it was 06995 * a good idea to say you can do it, and if you can do it, why in the hell would. 06996 * you say you shouldn't. 06997 * Anyways, pedanticsipchecking controls whether we allow spaces before ':', 06998 * and we always allow spaces after that for compatibility. 06999 */ 07000 for (pass = 0; name && pass < 2;pass++) { 07001 int x, len = strlen(name); 07002 for (x = *start; x < req->headers; x++) { 07003 const char *header = REQ_OFFSET_TO_STR(req, header[x]); 07004 if (!strncasecmp(header, name, len)) { 07005 const char *r = header + len; /* skip name */ 07006 if (sip_cfg.pedanticsipchecking) 07007 r = ast_skip_blanks(r); 07008 07009 if (*r == ':') { 07010 *start = x+1; 07011 return ast_skip_blanks(r+1); 07012 } 07013 } 07014 } 07015 if (pass == 0) /* Try aliases */ 07016 name = find_alias(name, NULL); 07017 } 07018 07019 /* Don't return NULL, so get_header is always a valid pointer */ 07020 return ""; 07021 }
| static void __init_check_auth_buf | ( | void | ) | [static] |
| static void __init_ts_temp_pvt | ( | void | ) | [static] |
| static void __reg_module | ( | void | ) | [static] |
Definition at line 29295 of file chan_sip.c.
| static int __set_address_from_contact | ( | const char * | fullcontact, | |
| struct ast_sockaddr * | addr, | |||
| int | tcp | |||
| ) | [static] |
Definition at line 13151 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_sockaddr_port, ast_sockaddr_resolve_first(), ast_sockaddr_set_port, get_transport_str2enum(), and LOG_WARNING.
Referenced by build_peer(), and set_address_from_contact().
13152 { 13153 char *domain, *transport; 13154 char contact_buf[256]; 13155 char *contact; 13156 13157 /* Work on a copy */ 13158 ast_copy_string(contact_buf, fullcontact, sizeof(contact_buf)); 13159 contact = contact_buf; 13160 13161 /* 13162 * We have only the part in <brackets> here so we just need to parse a SIP URI. 13163 * 13164 * Note: The outbound proxy could be using UDP between the proxy and Asterisk. 13165 * We still need to be able to send to the remote agent through the proxy. 13166 */ 13167 13168 if (parse_uri(contact, "sip:,sips:", &contact, NULL, &domain, 13169 &transport)) { 13170 ast_log(LOG_WARNING, "Invalid contact uri %s (missing sip: or sips:), attempting to use anyway\n", fullcontact); 13171 } 13172 13173 /* XXX This could block for a long time XXX */ 13174 /* We should only do this if it's a name, not an IP */ 13175 /* \todo - if there's no PORT number in contact - we are required to check NAPTR/SRV records 13176 to find transport, port address and hostname. If there's a port number, we have to 13177 assume that the domain part is a host name and only look for an A/AAAA record in DNS. 13178 */ 13179 13180 if (ast_sockaddr_resolve_first(addr, domain, 0)) { 13181 ast_log(LOG_WARNING, "Invalid host name in Contact: (can't " 13182 "resolve in DNS) : '%s'\n", domain); 13183 return -1; 13184 } 13185 13186 /* set port */ 13187 if (!ast_sockaddr_port(addr)) { 13188 ast_sockaddr_set_port(addr, 13189 (get_transport_str2enum(transport) == 13190 SIP_TRANSPORT_TLS || 13191 !strncasecmp(fullcontact, "sips", 4)) ? 13192 STANDARD_TLS_PORT : STANDARD_SIP_PORT); 13193 } 13194 13195 return 0; 13196 }
| int __sip_ack | ( | struct sip_pvt * | p, | |
| int | seqno, | |||
| int | resp, | |||
| int | sipmethod | |||
| ) |
Acknowledges receipt of a packet and stops retransmission called with p locked.
Definition at line 3885 of file chan_sip.c.
References ast_debug, ast_free, ast_sched_del(), FALSE, ref_proxy(), sip_pvt_lock, sip_pvt_unlock, sipdebug, TRUE, and UNLINK.
Referenced by __sip_pretend_ack(), handle_incoming(), handle_request_invite(), handle_request_publish(), and handle_response().
03886 { 03887 struct sip_pkt *cur, *prev = NULL; 03888 const char *msg = "Not Found"; /* used only for debugging */ 03889 int res = FALSE; 03890 03891 /* If we have an outbound proxy for this dialog, then delete it now since 03892 the rest of the requests in this dialog needs to follow the routing. 03893 If obforcing is set, we will keep the outbound proxy during the whole 03894 dialog, regardless of what the SIP rfc says 03895 */ 03896 if (p->outboundproxy && !p->outboundproxy->force){ 03897 ref_proxy(p, NULL); 03898 } 03899 03900 for (cur = p->packets; cur; prev = cur, cur = cur->next) { 03901 if (cur->seqno != seqno || cur->is_resp != resp) { 03902 continue; 03903 } 03904 if (cur->is_resp || cur->method == sipmethod) { 03905 res = TRUE; 03906 msg = "Found"; 03907 if (!resp && (seqno == p->pendinginvite)) { 03908 ast_debug(1, "Acked pending invite %d\n", p->pendinginvite); 03909 p->pendinginvite = 0; 03910 } 03911 if (cur->retransid > -1) { 03912 if (sipdebug) 03913 ast_debug(4, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid); 03914 } 03915 /* This odd section is designed to thwart a 03916 * race condition in the packet scheduler. There are 03917 * two conditions under which deleting the packet from the 03918 * scheduler can fail. 03919 * 03920 * 1. The packet has been removed from the scheduler because retransmission 03921 * is being attempted. The problem is that if the packet is currently attempting 03922 * retransmission and we are at this point in the code, then that MUST mean 03923 * that retrans_pkt is waiting on p's lock. Therefore we will relinquish the 03924 * lock temporarily to allow retransmission. 03925 * 03926 * 2. The packet has reached its maximum number of retransmissions and has 03927 * been permanently removed from the packet scheduler. If this is the case, then 03928 * the packet's retransid will be set to -1. The atomicity of the setting and checking 03929 * of the retransid to -1 is ensured since in both cases p's lock is held. 03930 */ 03931 while (cur->retransid > -1 && ast_sched_del(sched, cur->retransid)) { 03932 sip_pvt_unlock(p); 03933 usleep(1); 03934 sip_pvt_lock(p); 03935 } 03936 UNLINK(cur, p->packets, prev); 03937 dialog_unref(cur->owner, "unref pkt cur->owner dialog from sip ack before freeing pkt"); 03938 if (cur->data) { 03939 ast_free(cur->data); 03940 } 03941 ast_free(cur); 03942 break; 03943 } 03944 } 03945 ast_debug(1, "Stopping retransmission on '%s' of %s %d: Match %s\n", 03946 p->callid, resp ? "Response" : "Request", seqno, msg); 03947 return res; 03948 }
| 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 3741 of file chan_sip.c.
References __sip_pretend_ack(), append_history, AST_CAUSE_PROTOCOL_ERROR, ast_channel_trylock, ast_channel_unlock, ast_debug, AST_EXTENSION_DEACTIVATED, ast_log(), ast_queue_hangup_with_cause(), dialog_unlink_all(), LOG_WARNING, method_match(), NONE, pvt_set_needdestroy(), sip_methods, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), cfsip_methods::text, transmit_request_with_auth(), transmit_state_notify(), and TRUE.
Referenced by sip_scheddestroy(), and sip_show_sched().
03742 { 03743 struct sip_pvt *p = (struct sip_pvt *)data; 03744 03745 /* If this is a subscription, tell the phone that we got a timeout */ 03746 if (p->subscribed && p->subscribed != MWI_NOTIFICATION && p->subscribed != CALL_COMPLETION) { 03747 transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE); /* Send last notification */ 03748 p->subscribed = NONE; 03749 append_history(p, "Subscribestatus", "timeout"); 03750 ast_debug(3, "Re-scheduled destruction of SIP subscription %s\n", p->callid ? p->callid : "<unknown>"); 03751 return 10000; /* Reschedule this destruction so that we know that it's gone */ 03752 } 03753 03754 /* If there are packets still waiting for delivery, delay the destruction */ 03755 if (p->packets) { 03756 if (!p->needdestroy) { 03757 char method_str[31]; 03758 ast_debug(3, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>"); 03759 append_history(p, "ReliableXmit", "timeout"); 03760 if (sscanf(p->lastmsg, "Tx: %30s", method_str) == 1 || sscanf(p->lastmsg, "Rx: %30s", method_str) == 1) { 03761 if (method_match(SIP_CANCEL, method_str) || method_match(SIP_BYE, method_str)) { 03762 pvt_set_needdestroy(p, "autodestruct"); 03763 } 03764 } 03765 return 10000; 03766 } else { 03767 /* They've had their chance to respond. Time to bail */ 03768 __sip_pretend_ack(p); 03769 } 03770 } 03771 03772 /* Reset schedule ID */ 03773 p->autokillid = -1; 03774 03775 03776 /* 03777 * Lock both the pvt and the channel safely so that we can queue up a frame. 03778 */ 03779 sip_pvt_lock(p); 03780 while (p->owner && ast_channel_trylock(p->owner)) { 03781 sip_pvt_unlock(p); 03782 sched_yield(); 03783 sip_pvt_lock(p); 03784 } 03785 03786 if (p->owner) { 03787 ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text); 03788 ast_queue_hangup_with_cause(p->owner, AST_CAUSE_PROTOCOL_ERROR); 03789 ast_channel_unlock(p->owner); 03790 } else if (p->refer && !p->alreadygone) { 03791 ast_debug(3, "Finally hanging up channel after transfer: %s\n", p->callid); 03792 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 03793 append_history(p, "ReferBYE", "Sending BYE on transferer call leg %s", p->callid); 03794 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03795 } else { 03796 append_history(p, "AutoDestroy", "%s", p->callid); 03797 ast_debug(3, "Auto destroying SIP dialog '%s'\n", p->callid); 03798 dialog_unlink_all(p, TRUE, TRUE); /* once it's unlinked and unrefd everywhere, it'll be freed automagically */ 03799 /* dialog_unref(p, "unref dialog-- no other matching conditions"); -- unlink all now should finish off the dialog's references and free it. */ 03800 /* sip_destroy(p); */ /* Go ahead and destroy dialog. All attempts to recover is done */ 03801 /* sip_destroy also absorbs the reference */ 03802 } 03803 03804 sip_pvt_unlock(p); 03805 03806 dialog_unref(p, "The ref to a dialog passed to this sched callback is going out of scope; unref it."); 03807 03808 return 0; 03809 }
| void __sip_destroy | ( | struct sip_pvt * | p, | |
| int | lockowner, | |||
| int | lockdialoglist | |||
| ) |
Execute destruction of SIP dialog structure, release memory.
Definition at line 5453 of file chan_sip.c.
References ao2_ref, ast_cc_config_params_destroy(), ast_channel_lock, ast_channel_unlock, ast_debug, ast_free, ast_free_ha(), AST_LIST_REMOVE_HEAD, ast_rtp_instance_destroy(), AST_SCHED_DEL_UNREF, AST_SOFTHANGUP_DEV, ast_string_field_free_memory, ast_test_flag, ast_udptl_destroy(), ast_variables_destroy(), ast_verbose, deinit_req(), dumphistory, free_old_route(), registry_unref(), sip_debug_test_pvt(), sip_dump_history(), sip_methods, cfsip_methods::text, TRUE, unref_peer(), and update_call_counter().
Referenced by sip_destroy().
05454 { 05455 struct sip_request *req; 05456 05457 if (p->stimer) { 05458 ast_free(p->stimer); 05459 p->stimer = NULL; 05460 } 05461 05462 if (sip_debug_test_pvt(p)) 05463 ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 05464 05465 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 05466 update_call_counter(p, DEC_CALL_LIMIT); 05467 ast_debug(2, "This call did not properly clean up call limits. Call ID %s\n", p->callid); 05468 } 05469 05470 /* Unlink us from the owner if we have one */ 05471 if (p->owner) { 05472 if (lockowner) 05473 ast_channel_lock(p->owner); 05474 ast_debug(1, "Detaching from %s\n", p->owner->name); 05475 p->owner->tech_pvt = NULL; 05476 /* Make sure that the channel knows its backend is going away */ 05477 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 05478 if (lockowner) 05479 ast_channel_unlock(p->owner); 05480 /* Give the channel a chance to react before deallocation */ 05481 usleep(1); 05482 } 05483 05484 /* Remove link from peer to subscription of MWI */ 05485 if (p->relatedpeer && p->relatedpeer->mwipvt) 05486 p->relatedpeer->mwipvt = dialog_unref(p->relatedpeer->mwipvt, "delete ->relatedpeer->mwipvt"); 05487 if (p->relatedpeer && p->relatedpeer->call == p) 05488 p->relatedpeer->call = dialog_unref(p->relatedpeer->call, "unset the relatedpeer->call field in tandem with relatedpeer field itself"); 05489 05490 if (p->relatedpeer) 05491 p->relatedpeer = unref_peer(p->relatedpeer,"unsetting a dialog relatedpeer field in sip_destroy"); 05492 05493 if (p->registry) { 05494 if (p->registry->call == p) 05495 p->registry->call = dialog_unref(p->registry->call, "nulling out the registry's call dialog field in unlink_all"); 05496 p->registry = registry_unref(p->registry, "delete p->registry"); 05497 } 05498 05499 if (p->mwi) { 05500 p->mwi->call = NULL; 05501 } 05502 05503 if (dumphistory) 05504 sip_dump_history(p); 05505 05506 if (p->options) 05507 ast_free(p->options); 05508 05509 if (p->notify) { 05510 ast_variables_destroy(p->notify->headers); 05511 ast_free(p->notify->content); 05512 ast_free(p->notify); 05513 } 05514 if (p->rtp) { 05515 ast_rtp_instance_destroy(p->rtp); 05516 } 05517 if (p->vrtp) { 05518 ast_rtp_instance_destroy(p->vrtp); 05519 } 05520 if (p->trtp) { 05521 ast_rtp_instance_destroy(p->trtp); 05522 } 05523 if (p->udptl) 05524 ast_udptl_destroy(p->udptl); 05525 if (p->refer) 05526 ast_free(p->refer); 05527 if (p->route) { 05528 free_old_route(p->route); 05529 p->route = NULL; 05530 } 05531 deinit_req(&p->initreq); 05532 05533 /* Destroy Session-Timers if allocated */ 05534 if (p->stimer) { 05535 p->stimer->quit_flag = 1; 05536 if (p->stimer->st_active == TRUE && p->stimer->st_schedid > -1) { 05537 AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid, 05538 dialog_unref(p, "removing session timer ref")); 05539 } 05540 ast_free(p->stimer); 05541 p->stimer = NULL; 05542 } 05543 05544 /* Clear history */ 05545 if (p->history) { 05546 struct sip_history *hist; 05547 while ( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) { 05548 ast_free(hist); 05549 p->history_entries--; 05550 } 05551 ast_free(p->history); 05552 p->history = NULL; 05553 } 05554 05555 while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) { 05556 ast_free(req); 05557 } 05558 05559 if (p->chanvars) { 05560 ast_variables_destroy(p->chanvars); 05561 p->chanvars = NULL; 05562 } 05563 05564 if (p->srtp) { 05565 sip_srtp_destroy(p->srtp); 05566 p->srtp = NULL; 05567 } 05568 05569 if (p->vsrtp) { 05570 sip_srtp_destroy(p->vsrtp); 05571 p->vsrtp = NULL; 05572 } 05573 05574 if (p->tsrtp) { 05575 sip_srtp_destroy(p->tsrtp); 05576 p->tsrtp = NULL; 05577 } 05578 05579 if (p->directmediaha) { 05580 ast_free_ha(p->directmediaha); 05581 p->directmediaha = NULL; 05582 } 05583 05584 ast_string_field_free_memory(p); 05585 05586 ast_cc_config_params_destroy(p->cc_params); 05587 05588 if (p->epa_entry) { 05589 ao2_ref(p->epa_entry, -1); 05590 p->epa_entry = NULL; 05591 } 05592 05593 if (p->socket.tcptls_session) { 05594 ao2_ref(p->socket.tcptls_session, -1); 05595 p->socket.tcptls_session = NULL; 05596 } 05597 }
| static int __sip_do_register | ( | struct sip_registry * | r | ) | [static] |
Register with SIP proxy.
Definition at line 12416 of file chan_sip.c.
References transmit_register().
Referenced by sip_reregister().
12417 { 12418 int res; 12419 12420 res = transmit_register(r, SIP_REGISTER, NULL, NULL); 12421 return res; 12422 }
| void __sip_pretend_ack | ( | struct sip_pvt * | p | ) |
Pretend to ack all packets called with p locked.
Definition at line 3952 of file chan_sip.c.
References __sip_ack(), ast_log(), find_sip_method(), LOG_WARNING, sip_methods, and cfsip_methods::text.
Referenced by __sip_autodestruct(), handle_request_bye(), handle_request_cancel(), and sip_reg_timeout().
03953 { 03954 struct sip_pkt *cur = NULL; 03955 03956 while (p->packets) { 03957 int method; 03958 if (cur == p->packets) { 03959 ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text); 03960 return; 03961 } 03962 cur = p->packets; 03963 method = (cur->method) ? cur->method : find_sip_method(cur->data->str); 03964 __sip_ack(p, cur->seqno, cur->is_resp, method); 03965 } 03966 }
| static enum sip_result __sip_reliable_xmit | ( | struct sip_pvt * | p, | |
| int | seqno, | |||
| int | resp, | |||
| struct ast_str * | data, | |||
| int | len, | |||
| int | fatal, | |||
| int | sipmethod | |||
| ) | [static] |
Transmit packet with retransmits.
Definition at line 3649 of file chan_sip.c.
References __sip_xmit(), append_history, ast_calloc, ast_debug, ast_free, ast_log(), AST_PTHREADT_NULL, AST_SCHED_DEL, AST_SCHED_REPLACE_VARIABLE, ast_str_buffer(), ast_str_create(), ast_str_set(), ast_tvnow(), DEFAULT_RETRANS, LOG_ERROR, monitor_thread, retrans_pkt(), and sipdebug.
Referenced by send_request(), and send_response().
03650 { 03651 struct sip_pkt *pkt = NULL; 03652 int siptimer_a = DEFAULT_RETRANS; 03653 int xmitres = 0; 03654 int respid; 03655 03656 if (sipmethod == SIP_INVITE) { 03657 /* Note this is a pending invite */ 03658 p->pendinginvite = seqno; 03659 } 03660 03661 /* If the transport is something reliable (TCP or TLS) then don't really send this reliably */ 03662 /* I removed the code from retrans_pkt that does the same thing so it doesn't get loaded into the scheduler */ 03663 /*! \todo According to the RFC some packets need to be retransmitted even if its TCP, so this needs to get revisited */ 03664 if (!(p->socket.type & SIP_TRANSPORT_UDP)) { 03665 xmitres = __sip_xmit(p, data, len); /* Send packet */ 03666 if (xmitres == XMIT_ERROR) { /* Serious network trouble, no need to try again */ 03667 append_history(p, "XmitErr", "%s", fatal ? "(Critical)" : "(Non-critical)"); 03668 return AST_FAILURE; 03669 } else { 03670 return AST_SUCCESS; 03671 } 03672 } 03673 03674 if (!(pkt = ast_calloc(1, sizeof(*pkt) + len + 1))) { 03675 return AST_FAILURE; 03676 } 03677 /* copy data, add a terminator and save length */ 03678 if (!(pkt->data = ast_str_create(len))) { 03679 ast_free(pkt); 03680 return AST_FAILURE; 03681 } 03682 ast_str_set(&pkt->data, 0, "%s%s", data->str, "\0"); 03683 pkt->packetlen = len; 03684 /* copy other parameters from the caller */ 03685 pkt->method = sipmethod; 03686 pkt->seqno = seqno; 03687 pkt->is_resp = resp; 03688 pkt->is_fatal = fatal; 03689 pkt->owner = dialog_ref(p, "__sip_reliable_xmit: setting pkt->owner"); 03690 pkt->next = p->packets; 03691 p->packets = pkt; /* Add it to the queue */ 03692 if (resp) { 03693 /* Parse out the response code */ 03694 if (sscanf(ast_str_buffer(pkt->data), "SIP/2.0 %30u", &respid) == 1) { 03695 pkt->response_code = respid; 03696 } 03697 } 03698 pkt->timer_t1 = p->timer_t1; /* Set SIP timer T1 */ 03699 pkt->retransid = -1; 03700 if (pkt->timer_t1) { 03701 siptimer_a = pkt->timer_t1; 03702 } 03703 03704 pkt->time_sent = ast_tvnow(); /* time packet was sent */ 03705 pkt->retrans_stop_time = 64 * (pkt->timer_t1 ? pkt->timer_t1 : DEFAULT_TIMER_T1); /* time in ms after pkt->time_sent to stop retransmission */ 03706 03707 /* Schedule retransmission */ 03708 AST_SCHED_REPLACE_VARIABLE(pkt->retransid, sched, siptimer_a, retrans_pkt, pkt, 1); 03709 if (sipdebug) { 03710 ast_debug(4, "*** SIP TIMER: Initializing retransmit timer on packet: Id #%d\n", pkt->retransid); 03711 } 03712 03713 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); /* Send packet */ 03714 03715 if (xmitres == XMIT_ERROR) { /* Serious network trouble, no need to try again */ 03716 append_history(pkt->owner, "XmitErr", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)"); 03717 ast_log(LOG_ERROR, "Serious Network Trouble; __sip_xmit returns error for pkt data\n"); 03718 AST_SCHED_DEL(sched, pkt->retransid); 03719 p->packets = pkt->next; 03720 pkt->owner = dialog_unref(pkt->owner,"pkt is being freed, its dialog ref is dead now"); 03721 ast_free(pkt->data); 03722 ast_free(pkt); 03723 return AST_FAILURE; 03724 } else { 03725 /* This is odd, but since the retrans timer starts at 500ms and the do_monitor thread 03726 * only wakes up every 1000ms by default, we have to poke the thread here to make 03727 * sure it successfully detects this must be retransmitted in less time than 03728 * it usually sleeps for. Otherwise it might not retransmit this packet for 1000ms. */ 03729 if (monitor_thread != AST_PTHREADT_NULL) { 03730 pthread_kill(monitor_thread, SIGURG); 03731 } 03732 return AST_SUCCESS; 03733 } 03734 }
| int __sip_semi_ack | ( | struct sip_pvt * | p, | |
| int | seqno, | |||
| int | resp, | |||
| int | sipmethod | |||
| ) |
Acks receipt of packet, keep it around (used for provisional responses).
Definition at line 3969 of file chan_sip.c.
References ast_debug, AST_SCHED_DEL, FALSE, method_match(), sip_methods, sipdebug, cfsip_methods::text, and TRUE.
Referenced by handle_response(), and sip_hangup().
03970 { 03971 struct sip_pkt *cur; 03972 int res = FALSE; 03973 03974 for (cur = p->packets; cur; cur = cur->next) { 03975 if (cur->seqno == seqno && cur->is_resp == resp && 03976 (cur->is_resp || method_match(sipmethod, cur->data->str))) { 03977 /* this is our baby */ 03978 if (cur->retransid > -1) { 03979 if (sipdebug) 03980 ast_debug(4, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text); 03981 } 03982 AST_SCHED_DEL(sched, cur->retransid); 03983 res = TRUE; 03984 break; 03985 } 03986 } 03987 ast_debug(1, "(Provisional) Stopping retransmission (but retaining packet) on '%s' %s %d: %s\n", p->callid, resp ? "Response" : "Request", seqno, res == -1 ? "Not Found" : "Found"); 03988 return res; 03989 }
| static int __sip_subscribe_mwi_do | ( | struct sip_subscription_mwi * | mwi | ) | [static] |
Actually setup an MWI subscription or resubscribe.
Definition at line 11763 of file chan_sip.c.
References ast_dnsmgr_lookup(), ast_set_flag, ast_sip_ouraddrfor(), ast_sockaddr_port, ast_sockaddr_set_port, ast_string_field_set, ast_strlen_zero(), ASTOBJ_REF, bindaddr, build_callid_pvt(), build_contact(), build_via(), create_addr(), dialog_unlink_all(), get_address_family_filter(), get_srv_protocol(), get_srv_service(), MAXHOSTNAMELEN, mwi_expiry, obproxy_get(), ref_proxy(), set_socket_transport(), sip_alloc(), sip_cfg, transmit_invite(), and TRUE.
Referenced by sip_subscribe_mwi_do().
11764 { 11765 /* If we have no DNS manager let's do a lookup */ 11766 if (!mwi->dnsmgr) { 11767 char transport[MAXHOSTNAMELEN]; 11768 snprintf(transport, sizeof(transport), "_%s._%s", get_srv_service(mwi->transport), get_srv_protocol(mwi->transport)); 11769 11770 mwi->us.ss.ss_family = get_address_family_filter(&bindaddr); /* Filter address family */ 11771 ast_dnsmgr_lookup(mwi->hostname, &mwi->us, &mwi->dnsmgr, sip_cfg.srvlookup ? transport : NULL); 11772 } 11773 11774 /* If we already have a subscription up simply send a resubscription */ 11775 if (mwi->call) { 11776 transmit_invite(mwi->call, SIP_SUBSCRIBE, 0, 0, NULL); 11777 return 0; 11778 } 11779 11780 /* Create a dialog that we will use for the subscription */ 11781 if (!(mwi->call = sip_alloc(NULL, NULL, 0, SIP_SUBSCRIBE, NULL))) { 11782 return -1; 11783 } 11784 11785 ref_proxy(mwi->call, obproxy_get(mwi->call, NULL)); 11786 11787 if (!ast_sockaddr_port(&mwi->us) && mwi->portno) { 11788 ast_sockaddr_set_port(&mwi->us, mwi->portno); 11789 } 11790 11791 /* Setup the destination of our subscription */ 11792 if (create_addr(mwi->call, mwi->hostname, &mwi->us, 0, NULL)) { 11793 dialog_unlink_all(mwi->call, TRUE, TRUE); 11794 mwi->call = dialog_unref(mwi->call, "unref dialog after unlink_all"); 11795 return 0; 11796 } 11797 11798 mwi->call->expiry = mwi_expiry; 11799 11800 if (!mwi->dnsmgr && mwi->portno) { 11801 ast_sockaddr_set_port(&mwi->call->sa, mwi->portno); 11802 ast_sockaddr_set_port(&mwi->call->recv, mwi->portno); 11803 } else { 11804 mwi->portno = ast_sockaddr_port(&mwi->call->sa); 11805 } 11806 11807 /* Set various other information */ 11808 if (!ast_strlen_zero(mwi->authuser)) { 11809 ast_string_field_set(mwi->call, peername, mwi->authuser); 11810 ast_string_field_set(mwi->call, authname, mwi->authuser); 11811 ast_string_field_set(mwi->call, fromuser, mwi->authuser); 11812 } else { 11813 ast_string_field_set(mwi->call, peername, mwi->username); 11814 ast_string_field_set(mwi->call, authname, mwi->username); 11815 ast_string_field_set(mwi->call, fromuser, mwi->username); 11816 } 11817 ast_string_field_set(mwi->call, username, mwi->username); 11818 if (!ast_strlen_zero(mwi->secret)) { 11819 ast_string_field_set(mwi->call, peersecret, mwi->secret); 11820 } 11821 set_socket_transport(&mwi->call->socket, mwi->transport); 11822 mwi->call->socket.port = htons(mwi->portno); 11823 ast_sip_ouraddrfor(&mwi->call->sa, &mwi->call->ourip, mwi->call); 11824 build_contact(mwi->call); 11825 build_via(mwi->call); 11826 build_callid_pvt(mwi->call); 11827 ast_set_flag(&mwi->call->flags[0], SIP_OUTGOING); 11828 11829 /* Associate the call with us */ 11830 mwi->call->mwi = ASTOBJ_REF(mwi); 11831 11832 mwi->call->subscribed = MWI_NOTIFICATION; 11833 11834 /* Actually send the packet */ 11835 transmit_invite(mwi->call, SIP_SUBSCRIBE, 0, 2, NULL); 11836 11837 return 0; 11838 }
| static int __sip_xmit | ( | struct sip_pvt * | p, | |
| struct ast_str * | data, | |||
| int | len | |||
| ) | [static] |
Transmit SIP message Sends a SIP request or response on a given socket (in the pvt) Called by retrans_pkt, send_request, send_response and __sip_reliable_xmit.
Definition at line 3249 of file chan_sip.c.
References ast_debug, ast_log(), ast_sendto(), ast_sockaddr_stringify(), errno, get_transport_pvt(), LOG_WARNING, sip_prepare_socket(), sip_real_dst(), and sip_tcptls_write().
Referenced by __sip_reliable_xmit(), retrans_pkt(), send_request(), and send_response().
03250 { 03251 int res = 0; 03252 const struct ast_sockaddr *dst = sip_real_dst(p); 03253 03254 ast_debug(2, "Trying to put '%.11s' onto %s socket destined for %s\n", data->str, get_transport_pvt(p), ast_sockaddr_stringify(dst)); 03255 03256 if (sip_prepare_socket(p) < 0) { 03257 return XMIT_ERROR; 03258 } 03259 03260 if (p->socket.type == SIP_TRANSPORT_UDP) { 03261 res = ast_sendto(p->socket.fd, data->str, len, 0, dst); 03262 } else if (p->socket.tcptls_session) { 03263 res = sip_tcptls_write(p->socket.tcptls_session, data->str, len); 03264 } else { 03265 ast_debug(2, "Socket type is TCP but no tcptls_session is present to write to\n"); 03266 return XMIT_ERROR; 03267 } 03268 03269 if (res == -1) { 03270 switch (errno) { 03271 case EBADF: /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */ 03272 case EHOSTUNREACH: /* Host can't be reached */ 03273 case ENETDOWN: /* Interface down */ 03274 case ENETUNREACH: /* Network failure */ 03275 case ECONNREFUSED: /* ICMP port unreachable */ 03276 res = XMIT_ERROR; /* Don't bother with trying to transmit again */ 03277 } 03278 } 03279 if (res != len) { 03280 ast_log(LOG_WARNING, "sip_xmit of %p (len %d) to %s returned %d: %s\n", data, len, ast_sockaddr_stringify(dst), res, strerror(errno)); 03281 } 03282 03283 return res; 03284 }
| 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 9921 of file chan_sip.c.
References add_cc_call_info_to_response(), add_header(), add_rpid(), ast_cause2str(), ast_clear_flag, ast_log(), ast_test_flag, get_header(), hangup_sip2cause(), LOG_WARNING, respprep(), and send_response().
Referenced by transmit_response(), transmit_response_reliable(), and transmit_response_using_temp().
09922 { 09923 struct sip_request resp; 09924 int seqno = 0; 09925 09926 if (reliable && (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1)) { 09927 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 09928 return -1; 09929 } 09930 respprep(&resp, p, msg, req); 09931 09932 if (ast_test_flag(&p->flags[0], SIP_SENDRPID) 09933 && ast_test_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND) 09934 && (!strncmp(msg, "180", 3) || !strncmp(msg, "183", 3))) { 09935 ast_clear_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND); 09936 add_rpid(&resp, p); 09937 } 09938 if (ast_test_flag(&p->flags[0], SIP_OFFER_CC)) { 09939 add_cc_call_info_to_response(p, &resp); 09940 } 09941 09942 /* If we are cancelling an incoming invite for some reason, add information 09943 about the reason why we are doing this in clear text */ 09944 if (p->method == SIP_INVITE && msg[0] != '1') { 09945 char buf[20]; 09946 09947 if (ast_test_flag(&p->flags[1], SIP_PAGE2_Q850_REASON)) { 09948 int hangupcause = 0; 09949 09950 if (p->owner && p->owner->hangupcause) { 09951 hangupcause = p->owner->hangupcause; 09952 } else if (p->hangupcause) { 09953 hangupcause = p->hangupcause; 09954 } else { 09955 int respcode; 09956 if (sscanf(msg, "%30d ", &respcode)) 09957 hangupcause = hangup_sip2cause(respcode); 09958 } 09959 09960 if (hangupcause) { 09961 sprintf(buf, "Q.850;cause=%i", hangupcause & 0x7f); 09962 add_header(&resp, "Reason", buf); 09963 } 09964 } 09965 09966 if (p->owner && p->owner->hangupcause) { 09967 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 09968 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 09969 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 09970 } 09971 } 09972 return send_response(p, &resp, reliable, seqno); 09973 }
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 29295 of file chan_sip.c.
| static char * _sip_qualify_peer | ( | int | type, | |
| int | fd, | |||
| struct mansession * | s, | |||
| const struct message * | m, | |||
| int | argc, | |||
| const char * | argv[] | |||
| ) | [static] |
Send qualify message to peer from cli or manager. Mostly for debugging.
Definition at line 16474 of file chan_sip.c.
References ast_cli(), astman_send_error(), CLI_SHOWUSAGE, CLI_SUCCESS, FALSE, find_peer(), sip_poke_peer(), TRUE, and unref_peer().
Referenced by manager_sip_qualify_peer(), and sip_qualify_peer().
16475 { 16476 struct sip_peer *peer; 16477 int load_realtime; 16478 16479 if (argc < 4) 16480 return CLI_SHOWUSAGE; 16481 16482 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 16483 if ((peer = find_peer(argv[3], NULL, load_realtime, FINDPEERS, FALSE, 0))) { 16484 sip_poke_peer(peer, 1); 16485 unref_peer(peer, "qualify: done with peer"); 16486 } else if (type == 0) { 16487 ast_cli(fd, "Peer '%s' not found\n", argv[3]); 16488 } else { 16489 astman_send_error(s, m, "Peer not found"); 16490 } 16491 return CLI_SUCCESS; 16492 }
| 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 16559 of file chan_sip.c.
References ARRAY_LEN, ast_callerid_merge(), ast_cdr_flags2str(), ast_check_realtime(), ast_cli(), AST_CLI_YESNO, ast_codec_pref_index(), ast_describe_caller_presentation(), ast_getformatname(), ast_getformatname_multiple(), ast_print_group(), ast_sched_when(), ast_sockaddr_port, ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_str_alloca, ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), astman_send_error(), CLI_SHOWUSAGE, CLI_SUCCESS, dtmfmode2str(), FALSE, faxec2str(), find_peer(), get_transport(), get_transport_list(), insecure2str(), ast_variable::name, ast_variable::next, peer_mailboxes_to_str(), peer_status(), print_codec_to_cli(), print_group(), S_OR, sip_cfg, status, stmode2str(), strefresher2str(), transfermode2str(), TRUE, unref_peer(), and ast_variable::value.
Referenced by manager_sip_show_peer(), and sip_show_peer().
16560 { 16561 char status[30] = ""; 16562 char cbuf[256]; 16563 struct sip_peer *peer; 16564 char codec_buf[512]; 16565 struct ast_codec_pref *pref; 16566 struct ast_variable *v; 16567 struct sip_auth *auth; 16568 int x = 0, load_realtime; 16569 format_t codec = 0; 16570 int realtimepeers; 16571 16572 realtimepeers = ast_check_realtime("sippeers"); 16573 16574 if (argc < 4) 16575 return CLI_SHOWUSAGE; 16576 16577 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 16578 peer = find_peer(argv[3], NULL, load_realtime, FINDPEERS, FALSE, 0); 16579 16580 if (s) { /* Manager */ 16581 if (peer) { 16582 const char *id = astman_get_header(m, "ActionID"); 16583 16584 astman_append(s, "Response: Success\r\n"); 16585 if (!ast_strlen_zero(id)) 16586 astman_append(s, "ActionID: %s\r\n", id); 16587 } else { 16588 snprintf (cbuf, sizeof(cbuf), "Peer %s not found.", argv[3]); 16589 astman_send_error(s, m, cbuf); 16590 return CLI_SUCCESS; 16591 } 16592 } 16593 if (peer && type==0 ) { /* Normal listing */ 16594 struct ast_str *mailbox_str = ast_str_alloca(512); 16595 ast_cli(fd, "\n\n"); 16596 ast_cli(fd, " * Name : %s\n", peer->name); 16597 if (realtimepeers) { /* Realtime is enabled */ 16598 ast_cli(fd, " Realtime peer: %s\n", peer->is_realtime ? "Yes, cached" : "No"); 16599 } 16600 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 16601 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>"); 16602 ast_cli(fd, " Remote Secret: %s\n", ast_strlen_zero(peer->remotesecret)?"<Not set>":"<Set>"); 16603 for (auth = peer->auth; auth; auth = auth->next) { 16604 ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s ", auth->realm, auth->username); 16605 ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>")); 16606 } 16607 ast_cli(fd, " Context : %s\n", peer->context); 16608 ast_cli(fd, " Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") ); 16609 ast_cli(fd, " Language : %s\n", peer->language); 16610 if (!ast_strlen_zero(peer->accountcode)) 16611 ast_cli(fd, " Accountcode : %s\n", peer->accountcode); 16612 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(peer->amaflags)); 16613 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(peer->allowtransfer)); 16614 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres)); 16615 if (!ast_strlen_zero(peer->fromuser)) 16616 ast_cli(fd, " FromUser : %s\n", peer->fromuser); 16617 if (!ast_strlen_zero(peer->fromdomain)) 16618 ast_cli(fd, " FromDomain : %s Port %d\n", peer->fromdomain, (peer->fromdomainport) ? peer->fromdomainport : STANDARD_SIP_PORT); 16619 ast_cli(fd, " Callgroup : "); 16620 print_group(fd, peer->callgroup, 0); 16621 ast_cli(fd, " Pickupgroup : "); 16622 print_group(fd, peer->pickupgroup, 0); 16623 peer_mailboxes_to_str(&mailbox_str, peer); 16624 ast_cli(fd, " MOH Suggest : %s\n", peer->mohsuggest); 16625 ast_cli(fd, " Mailbox : %s\n", mailbox_str->str); 16626 ast_cli(fd, " VM Extension : %s\n", peer->vmexten); 16627 ast_cli(fd, " LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff); 16628 ast_cli(fd, " Call limit : %d\n", peer->call_limit); 16629 ast_cli(fd, " Max forwards : %d\n", peer->maxforwards); 16630 if (peer->busy_level) 16631 ast_cli(fd, " Busy level : %d\n", peer->busy_level); 16632 ast_cli(fd, " Dynamic : %s\n", AST_CLI_YESNO(peer->host_dynamic)); 16633 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 16634 ast_cli(fd, " MaxCallBR : %d kbps\n", peer->maxcallbitrate); 16635 ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, peer->expire)); 16636 ast_cli(fd, " Insecure : %s\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE))); 16637 ast_cli(fd, " Force rport : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT))); 16638 ast_cli(fd, " ACL : %s\n", AST_CLI_YESNO(peer->ha != NULL)); 16639 ast_cli(fd, " DirectMedACL : %s\n", AST_CLI_YESNO(peer->directmediaha != NULL)); 16640 ast_cli(fd, " T.38 support : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT))); 16641 ast_cli(fd, " T.38 EC mode : %s\n", faxec2str(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT))); 16642 ast_cli(fd, " T.38 MaxDtgrm: %d\n", peer->t38_maxdatagram); 16643 ast_cli(fd, " DirectMedia : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_DIRECT_MEDIA))); 16644 ast_cli(fd, " PromiscRedir : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR))); 16645 ast_cli(fd, " User=Phone : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_USEREQPHONE))); 16646 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))); 16647 ast_cli(fd, " Text Support : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT))); 16648 ast_cli(fd, " Ign SDP ver : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_IGNORESDPVERSION))); 16649 ast_cli(fd, " Trust RPID : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_TRUSTRPID))); 16650 ast_cli(fd, " Send RPID : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_SENDRPID))); 16651 ast_cli(fd, " Subscriptions: %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))); 16652 ast_cli(fd, " Overlap dial : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP))); 16653 if (peer->outboundproxy) 16654 ast_cli(fd, " Outb. proxy : %s %s\n", ast_strlen_zero(peer->outboundproxy->name) ? "<not set>" : peer->outboundproxy->name, 16655 peer->outboundproxy->force ? "(forced)" : ""); 16656 16657 /* - is enumerated */ 16658 ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 16659 ast_cli(fd, " Timer T1 : %d\n", peer->timer_t1); 16660 ast_cli(fd, " Timer B : %d\n", peer->timer_b); 16661 ast_cli(fd, " ToHost : %s\n", peer->tohost); 16662 ast_cli(fd, " Addr->IP : %s\n", ast_sockaddr_stringify(&peer->addr)); 16663 ast_cli(fd, " Defaddr->IP : %s\n", ast_sockaddr_stringify(&peer->defaddr)); 16664 ast_cli(fd, " Prim.Transp. : %s\n", get_transport(peer->socket.type)); 16665 ast_cli(fd, " Allowed.Trsp : %s\n", get_transport_list(peer->transports)); 16666 if (!ast_strlen_zero(sip_cfg.regcontext)) 16667 ast_cli(fd, " Reg. exten : %s\n", peer->regexten); 16668 ast_cli(fd, " Def. Username: %s\n", peer->username); 16669 ast_cli(fd, " SIP Options : "); 16670 if (peer->sipoptions) { 16671 int lastoption = -1; 16672 for (x = 0 ; x < ARRAY_LEN(sip_options); x++) { 16673 if (sip_options[x].id != lastoption) { 16674 if (peer->sipoptions & sip_options[x].id) 16675 ast_cli(fd, "%s ", sip_options[x].text); 16676 lastoption = x; 16677 } 16678 } 16679 } else 16680 ast_cli(fd, "(none)"); 16681 16682 ast_cli(fd, "\n"); 16683 ast_cli(fd, " Codecs : "); 16684 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 16685 ast_cli(fd, "%s\n", codec_buf); 16686 ast_cli(fd, " Codec Order : ("); 16687 print_codec_to_cli(fd, &peer->prefs); 16688 ast_cli(fd, ")\n"); 16689 16690 ast_cli(fd, " Auto-Framing : %s \n", AST_CLI_YESNO(peer->autoframing)); 16691 ast_cli(fd, " 100 on REG : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_REGISTERTRYING))); 16692 ast_cli(fd, " Status : "); 16693 peer_status(peer, status, sizeof(status)); 16694 ast_cli(fd, "%s\n", status); 16695 ast_cli(fd, " Useragent : %s\n", peer->useragent); 16696 ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); 16697 ast_cli(fd, " Qualify Freq : %d ms\n", peer->qualifyfreq); 16698 if (peer->chanvars) { 16699 ast_cli(fd, " Variables :\n"); 16700 for (v = peer->chanvars ; v ; v = v->next) 16701 ast_cli(fd, " %s = %s\n", v->name, v->value); 16702 } 16703 16704 ast_cli(fd, " Sess-Timers : %s\n", stmode2str(peer->stimer.st_mode_oper)); 16705 ast_cli(fd, " Sess-Refresh : %s\n", strefresher2str(peer->stimer.st_ref)); 16706 ast_cli(fd, " Sess-Expires : %d secs\n", peer->stimer.st_max_se); 16707 ast_cli(fd, " Min-Sess : %d secs\n", peer->stimer.st_min_se); 16708 ast_cli(fd, " RTP Engine : %s\n", peer->engine); 16709 ast_cli(fd, " Parkinglot : %s\n", peer->parkinglot); 16710 ast_cli(fd, " Use Reason : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_Q850_REASON))); 16711 ast_cli(fd, " Encryption : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_USE_SRTP))); 16712 ast_cli(fd, "\n"); 16713 peer = unref_peer(peer, "sip_show_peer: unref_peer: done with peer ptr"); 16714 } else if (peer && type == 1) { /* manager listing */ 16715 char buffer[256]; 16716 struct ast_str *mailbox_str = ast_str_alloca(512); 16717 astman_append(s, "Channeltype: SIP\r\n"); 16718 astman_append(s, "ObjectName: %s\r\n", peer->name); 16719 astman_append(s, "ChanObjectType: peer\r\n"); 16720 astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y"); 16721 astman_append(s, "RemoteSecretExist: %s\r\n", ast_strlen_zero(peer->remotesecret)?"N":"Y"); 16722 astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y"); 16723 astman_append(s, "Context: %s\r\n", peer->context); 16724 astman_append(s, "Language: %s\r\n", peer->language); 16725 if (!ast_strlen_zero(peer->accountcode)) 16726 astman_append(s, "Accountcode: %s\r\n", peer->accountcode); 16727 astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags)); 16728 astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres)); 16729 if (!ast_strlen_zero(peer->fromuser)) 16730 astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser); 16731 if (!ast_strlen_zero(peer->fromdomain)) 16732 astman_append(s, "SIP-FromDomain: %s\r\nSip-FromDomain-Port: %d\r\n", peer->fromdomain, (peer->fromdomainport) ? peer->fromdomainport : STANDARD_SIP_PORT); 16733 astman_append(s, "Callgroup: "); 16734 astman_append(s, "%s\r\n", ast_print_group(buffer, sizeof(buffer), peer->callgroup)); 16735 astman_append(s, "Pickupgroup: "); 16736 astman_append(s, "%s\r\n", ast_print_group(buffer, sizeof(buffer), peer->pickupgroup)); 16737 astman_append(s, "MOHSuggest: %s\r\n", peer->mohsuggest); 16738 peer_mailboxes_to_str(&mailbox_str, peer); 16739 astman_append(s, "VoiceMailbox: %s\r\n", mailbox_str->str); 16740 astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer)); 16741 astman_append(s, "Maxforwards: %d\r\n", peer->maxforwards); 16742 astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent); 16743 astman_append(s, "Maxforwards: %d\r\n", peer->maxforwards); 16744 astman_append(s, "Call-limit: %d\r\n", peer->call_limit); 16745 astman_append(s, "Busy-level: %d\r\n", peer->busy_level); 16746 astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate); 16747 astman_append(s, "Dynamic: %s\r\n", peer->host_dynamic?"Y":"N"); 16748 astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); 16749 astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched, peer->expire)); 16750 astman_append(s, "SIP-AuthInsecure: %s\r\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE))); 16751 astman_append(s, "SIP-Forcerport: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT)?"Y":"N")); 16752 astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N")); 16753 astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_DIRECT_MEDIA)?"Y":"N")); 16754 astman_append(s, "SIP-DirectMedia: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_DIRECT_MEDIA)?"Y":"N")); 16755 astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N")); 16756 astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N")); 16757 astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N")); 16758 astman_append(s, "SIP-TextSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT)?"Y":"N")); 16759 astman_append(s, "SIP-T.38Support: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT)?"Y":"N")); 16760 astman_append(s, "SIP-T.38EC: %s\r\n", faxec2str(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT))); 16761 astman_append(s, "SIP-T.38MaxDtgrm: %d\r\n", peer->t38_maxdatagram); 16762 astman_append(s, "SIP-Sess-Timers: %s\r\n", stmode2str(peer->stimer.st_mode_oper)); 16763 astman_append(s, "SIP-Sess-Refresh: %s\r\n", strefresher2str(peer->stimer.st_ref)); 16764 astman_append(s, "SIP-Sess-Expires: %d\r\n", peer->stimer.st_max_se); 16765 astman_append(s, "SIP-Sess-Min: %d\r\n", peer->stimer.st_min_se); 16766 astman_append(s, "SIP-RTP-Engine: %s\r\n", peer->engine); 16767 astman_append(s, "SIP-Encryption: %s\r\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_USE_SRTP) ? "Y" : "N"); 16768 16769 /* - is enumerated */ 16770 astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 16771 astman_append(s, "ToHost: %s\r\n", peer->tohost); 16772 astman_append(s, "Address-IP: %s\r\nAddress-Port: %d\r\n", ast_sockaddr_stringify_addr(&peer->addr), ast_sockaddr_port(&peer->addr)); 16773 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)); 16774 astman_append(s, "Default-Username: %s\r\n", peer->username); 16775 if (!ast_strlen_zero(sip_cfg.regcontext)) 16776 astman_append(s, "RegExtension: %s\r\n", peer->regexten); 16777 astman_append(s, "Codecs: "); 16778 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 16779 astman_append(s, "%s\r\n", codec_buf); 16780 astman_append(s, "CodecOrder: "); 16781 pref = &peer->prefs; 16782 for(x = 0; x < 64 ; x++) { 16783 codec = ast_codec_pref_index(pref, x); 16784 if (!codec) 16785 break; 16786 astman_append(s, "%s", ast_getformatname(codec)); 16787 if (x < 63 && ast_codec_pref_index(pref, x+1)) 16788 astman_append(s, ","); 16789 } 16790 16791 astman_append(s, "\r\n"); 16792 astman_append(s, "Status: "); 16793 peer_status(peer, status, sizeof(status)); 16794 astman_append(s, "%s\r\n", status); 16795 astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent); 16796 astman_append(s, "Reg-Contact: %s\r\n", peer->fullcontact); 16797 astman_append(s, "QualifyFreq: %d ms\r\n", peer->qualifyfreq); 16798 astman_append(s, "Parkinglot: %s\r\n", peer->parkinglot); 16799 if (peer->chanvars) { 16800 for (v = peer->chanvars ; v ; v = v->next) { 16801 astman_append(s, "ChanVariable: %s=%s\r\n", v->name, v->value); 16802 } 16803 } 16804 astman_append(s, "SIP-Use-Reason-Header : %s\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_Q850_REASON)) ? "Y" : "N"); 16805 16806 peer = unref_peer(peer, "sip_show_peer: unref_peer: done with peer"); 16807 16808 } else { 16809 ast_cli(fd, "Peer %s not found.\n", argv[3]); 16810 ast_cli(fd, "\n"); 16811 } 16812 16813 return CLI_SUCCESS; 16814 }
| 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 15877 of file chan_sip.c.
References ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_iterator_next, ao2_unlock, ast_calloc, ast_check_realtime(), ast_cli(), ast_copy_string(), ast_free, ast_sockaddr_isnull(), ast_sockaddr_port, AST_SOCKADDR_STR_HOST, ast_sockaddr_stringify_addr(), ast_sockaddr_stringify_fmt(), ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), CLI_SHOWUSAGE, CLI_SUCCESS, FALSE, FORMAT, FORMAT2, id, name, peer_status(), peercomparefunc(), status, TRUE, and unref_peer().
Referenced by manager_sip_show_peers(), and sip_show_peers().
15878 { 15879 regex_t regexbuf; 15880 int havepattern = FALSE; 15881 struct sip_peer *peer; 15882 struct ao2_iterator i; 15883 15884 /* the last argument is left-aligned, so we don't need a size anyways */ 15885 #define FORMAT2 "%-25.25s %-39.39s %-3.3s %-10.10s %-3.3s %-8s %-10s %s\n" 15886 #define FORMAT "%-25.25s %-39.39s %-3.3s %-3.3s %-3.3s %-8d %-10s %s\n" 15887 15888 char name[256]; 15889 int total_peers = 0; 15890 int peers_mon_online = 0; 15891 int peers_mon_offline = 0; 15892 int peers_unmon_offline = 0; 15893 int peers_unmon_online = 0; 15894 const char *id; 15895 char idtext[256] = ""; 15896 int realtimepeers; 15897 int objcount = ao2_container_count(peers); 15898 struct sip_peer **peerarray; 15899 int k; 15900 15901 15902 realtimepeers = ast_check_realtime("sippeers"); 15903 peerarray = ast_calloc(sizeof(struct sip_peer *), objcount); 15904 15905 if (s) { /* Manager - get ActionID */ 15906 id = astman_get_header(m, "ActionID"); 15907 if (!ast_strlen_zero(id)) 15908 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 15909 } 15910 15911 switch (argc) { 15912 case 5: 15913 if (!strcasecmp(argv[3], "like")) { 15914 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 15915 return CLI_SHOWUSAGE; 15916 havepattern = TRUE; 15917 } else 15918 return CLI_SHOWUSAGE; 15919 case 3: 15920 break; 15921 default: 15922 return CLI_SHOWUSAGE; 15923 } 15924 15925 if (!s) /* Normal list */ 15926 ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Forcerport", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : "")); 15927 15928 15929 i = ao2_iterator_init(peers, 0); 15930 while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) { 15931 ao2_lock(peer); 15932 15933 if (!(peer->type & SIP_TYPE_PEER)) { 15934 ao2_unlock(peer); 15935 unref_peer(peer, "unref peer because it's actually a user"); 15936 continue; 15937 } 15938 15939 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) { 15940 objcount--; 15941 ao2_unlock(peer); 15942 unref_peer(peer, "toss iterator peer ptr before continue"); 15943 continue; 15944 } 15945 15946 peerarray[total_peers++] = peer; 15947 ao2_unlock(peer); 15948 } 15949 ao2_iterator_destroy(&i); 15950 15951 qsort(peerarray, total_peers, sizeof(struct sip_peer *), peercomparefunc); 15952 15953 for(k=0; k < total_peers; k++) { 15954 char status[20] = ""; 15955 char srch[2000]; 15956 char pstatus; 15957 peer = peerarray[k]; 15958 15959 ao2_lock(peer); 15960 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) { 15961 ao2_unlock(peer); 15962 unref_peer(peer, "toss iterator peer ptr before continue"); 15963 continue; 15964 } 15965 15966 if (!ast_strlen_zero(peer->username) && !s) 15967 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 15968 else 15969 ast_copy_string(name, peer->name, sizeof(name)); 15970 15971 pstatus = peer_status(peer, status, sizeof(status)); 15972 if (pstatus == 1) 15973 peers_mon_online++; 15974 else if (pstatus == 0) 15975 peers_mon_offline++; 15976 else { 15977 if (ast_sockaddr_isnull(&peer->addr) || 15978 !ast_sockaddr_port(&peer->addr)) { 15979 peers_unmon_offline++; 15980 } else { 15981 peers_unmon_online++; 15982 } 15983 } 15984 15985 snprintf(srch, sizeof(srch), FORMAT, name, 15986 ast_sockaddr_isnull(&peer->addr) ? "(Unspecified)" : ast_sockaddr_stringify_addr(&peer->addr), 15987 peer->host_dynamic ? " D " : " ", /* Dynamic or not? */ 15988 ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? " N " : " ", /* NAT=yes? */ 15989 peer->ha ? " A " : " ", /* permit/deny */ 15990 ast_sockaddr_isnull(&peer->addr) ? 0 : ast_sockaddr_port(&peer->addr), status, 15991 realtimepeers ? (peer->is_realtime ? "Cached RT":"") : ""); 15992 15993 if (!s) {/* Normal CLI list */ 15994 ast_cli(fd, FORMAT, name, 15995 ast_sockaddr_isnull(&peer->addr) ? "(Unspecified)" : ast_sockaddr_stringify_addr(&peer->addr), 15996 peer->host_dynamic ? " D " : " ", /* Dynamic or not? */ 15997 ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? " N " : " ", /* NAT=yes? */ 15998 peer->ha ? " A " : " ", /* permit/deny */ 15999 ast_sockaddr_isnull(&peer->addr) ? 0 : ast_sockaddr_port(&peer->addr), status, 16000 realtimepeers ? (peer->is_realtime ? "Cached RT":"") : ""); 16001 } else { /* Manager format */ 16002 /* The names here need to be the same as other channels */ 16003 astman_append(s, 16004 "Event: PeerEntry\r\n%s" 16005 "Channeltype: SIP\r\n" 16006 "ObjectName: %s\r\n" 16007 "ChanObjectType: peer\r\n" /* "peer" or "user" */ 16008 "IPaddress: %s\r\n" 16009 "IPport: %d\r\n" 16010 "Dynamic: %s\r\n" 16011 "Forcerport: %s\r\n" 16012 "VideoSupport: %s\r\n" 16013 "TextSupport: %s\r\n" 16014 "ACL: %s\r\n" 16015 "Status: %s\r\n" 16016 "RealtimeDevice: %s\r\n\r\n", 16017 idtext, 16018 peer->name, 16019 ast_sockaddr_isnull(&peer->addr) ? "-none-" : ast_sockaddr_stringify_fmt(&peer->addr, AST_SOCKADDR_STR_HOST), 16020 ast_sockaddr_isnull(&peer->addr) ? 0 : ast_sockaddr_port(&peer->addr), 16021 peer->host_dynamic ? "yes" : "no", /* Dynamic or not? */ 16022 ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? "yes" : "no", /* NAT=yes? */ 16023 ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */ 16024 ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT) ? "yes" : "no", /* TEXTSUPPORT=yes? */ 16025 peer->ha ? "yes" : "no", /* permit/deny */ 16026 status, 16027 realtimepeers ? (peer->is_realtime ? "yes":"no") : "no"); 16028 } 16029 ao2_unlock(peer); 16030 unref_peer(peer, "toss iterator peer ptr"); 16031 } 16032 16033 if (!s) 16034 ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n", 16035 total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline); 16036 16037 if (havepattern) 16038 regfree(®exbuf); 16039 16040 if (total) 16041 *total = total_peers; 16042 16043 ast_free(peerarray); 16044 16045 return CLI_SUCCESS; 16046 #undef FORMAT 16047 #undef FORMAT2 16048 }
| static void * _sip_tcp_helper_thread | ( | struct sip_pvt * | pvt, | |
| struct ast_tcptls_session_instance * | tcptls_session | |||
| ) | [static] |
SIP TCP thread management function This function reads from the socket, parses the packet into a request.
Definition at line 2473 of file chan_sip.c.
References ao2_t_find, ao2_t_ref, ast_atomic_fetchadd_int(), ast_debug, ast_log(), ast_str_create(), ast_tcptls_client_start(), authlimit, cleanup(), ast_tcptls_session_instance::client, errno, ast_tcptls_session_instance::fd, LOG_ERROR, OBJ_POINTER, ast_tcptls_session_instance::parent, sip_check_authtimeout(), sip_threadinfo_create(), ast_tcptls_session_instance::ssl, threadt, and unauth_sessions.
Referenced by sip_tcp_worker_fn().
02474 { 02475 int res, cl, timeout = -1, authenticated = 0, flags, after_poll = 0, need_poll = 1; 02476 time_t start; 02477 struct sip_request req = { 0, } , reqcpy = { 0, }; 02478 struct sip_threadinfo *me = NULL; 02479 char buf[1024] = ""; 02480 struct pollfd fds[2] = { { 0 }, { 0 }, }; 02481 struct ast_tcptls_session_args *ca = NULL; 02482 02483 /* If this is a server session, then the connection has already been 02484 * setup. Check if the authlimit has been reached and if not create the 02485 * threadinfo object so we can access this thread for writing. 02486 * 02487 * if this is a client connection more work must be done. 02488 * 1. We own the parent session args for a client connection. This pointer needs 02489 * to be held on to so we can decrement it's ref count on thread destruction. 02490 * 2. The threadinfo object was created before this thread was launched, however 02491 * it must be found within the threadt table. 02492 * 3. Last, the tcptls_session must be started. 02493 */ 02494 if (!tcptls_session->client) { 02495 if (ast_atomic_fetchadd_int(&unauth_sessions, +1) >= authlimit) { 02496 /* unauth_sessions is decremented in the cleanup code */ 02497 goto cleanup; 02498 } 02499 02500 if ((flags = fcntl(tcptls_session->fd, F_GETFL)) == -1) { 02501 ast_log(LOG_ERROR, "error setting socket to non blocking mode, fcntl() failed: %s\n", strerror(errno)); 02502 goto cleanup; 02503 } 02504 02505 flags |= O_NONBLOCK; 02506 if (fcntl(tcptls_session->fd, F_SETFL, flags) == -1) { 02507 ast_log(LOG_ERROR, "error setting socket to non blocking mode, fcntl() failed: %s\n", strerror(errno)); 02508 goto cleanup; 02509 } 02510 02511 if (!(me = sip_threadinfo_create(tcptls_session, tcptls_session->ssl ? SIP_TRANSPORT_TLS : SIP_TRANSPORT_TCP))) { 02512 goto cleanup; 02513 } 02514 ao2_t_ref(me, +1, "Adding threadinfo ref for tcp_helper_thread"); 02515 } else { 02516 struct sip_threadinfo tmp = { 02517 .tcptls_session = tcptls_session, 02518 }; 02519 02520 if ((!(ca = tcptls_session->parent)) || 02521 (!(me = ao2_t_find(threadt, &tmp, OBJ_POINTER, "ao2_find, getting sip_threadinfo in tcp helper thread"))) || 02522 (!(tcptls_session = ast_tcptls_client_start(tcptls_session)))) { 02523 goto cleanup; 02524 } 02525 } 02526 02527 me->threadid = pthread_self(); 02528 ast_debug(2, "Starting thread for %s server\n", tcptls_session->ssl ? "SSL" : "TCP"); 02529 02530 /* set up pollfd to watch for reads on both the socket and the alert_pipe */ 02531 fds[0].fd = tcptls_session->fd; 02532 fds[1].fd = me->alert_pipe[0]; 02533 fds[0].events = fds[1].events = POLLIN | POLLPRI; 02534 02535 if (!(req.data = ast_str_create(SIP_MIN_PACKET))) { 02536 goto cleanup; 02537 } 02538 if (!(reqcpy.data = ast_str_create(SIP_MIN_PACKET))) { 02539 goto cleanup; 02540 } 02541 02542 if(time(&start) == -1) { 02543 ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno)); 02544 goto cleanup; 02545 } 02546 02547 for (;;) { 02548 struct ast_str *str_save; 02549 02550 if (!tcptls_session->client && req.authenticated && !authenticated) { 02551 authenticated = 1; 02552 ast_atomic_fetchadd_int(&unauth_sessions, -1); 02553 } 02554 02555 /* calculate the timeout for unauthenticated server sessions */ 02556 if (!tcptls_session->client && !authenticated ) { 02557 if ((timeout = sip_check_authtimeout(start)) < 0) { 02558 goto cleanup; 02559 } 02560 02561 if (timeout == 0) { 02562 ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP"); 02563 goto cleanup; 02564 } 02565 } else { 02566 timeout = -1; 02567 } 02568 02569 res = ast_poll(fds, 2, timeout); /* polls for both socket and alert_pipe */ 02570 if (res < 0) { 02571 ast_debug(2, "SIP %s server :: ast_wait_for_input returned %d\n", tcptls_session->ssl ? "SSL": "TCP", res); 02572 goto cleanup; 02573 } else if (res == 0) { 02574 /* timeout */ 02575 ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP"); 02576 goto cleanup; 02577 } 02578 02579 /* handle the socket event, check for both reads from the socket fd, 02580 * and writes from alert_pipe fd */ 02581 if (fds[0].revents) { /* there is data on the socket to be read */ 02582 after_poll = 1; 02583 02584 fds[0].revents = 0; 02585 02586 /* clear request structure */ 02587 str_save = req.data; 02588 memset(&req, 0, sizeof(req)); 02589 req.data = str_save; 02590 ast_str_reset(req.data); 02591 02592 str_save = reqcpy.data; 02593 memset(&reqcpy, 0, sizeof(reqcpy)); 02594 reqcpy.data = str_save; 02595 ast_str_reset(reqcpy.data); 02596 02597 memset(buf, 0, sizeof(buf)); 02598 02599 if (tcptls_session->ssl) { 02600 set_socket_transport(&req.socket, SIP_TRANSPORT_TLS); 02601 req.socket.port = htons(ourport_tls); 02602 } else { 02603 set_socket_transport(&req.socket, SIP_TRANSPORT_TCP); 02604 req.socket.port = htons(ourport_tcp); 02605 } 02606 req.socket.fd = tcptls_session->fd; 02607 02608 /* Read in headers one line at a time */ 02609 while (req.len < 4 || strncmp(REQ_OFFSET_TO_STR(&req, len - 4), "\r\n\r\n", 4)) { 02610 if (!tcptls_session->client && !authenticated ) { 02611 if ((timeout = sip_check_authtimeout(start)) < 0) { 02612 goto cleanup; 02613 } 02614 02615 if (timeout == 0) { 02616 ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP"); 02617 goto cleanup; 02618 } 02619 } else { 02620 timeout = -1; 02621 } 02622 02623 /* special polling behavior is required for TLS 02624 * sockets because of the buffering done in the 02625 * TLS layer */ 02626 if (!tcptls_session->ssl || need_poll) { 02627 need_poll = 0; 02628 after_poll = 1; 02629 res = ast_wait_for_input(tcptls_session->fd, timeout); 02630 if (res < 0) { 02631 ast_debug(2, "SIP TCP server :: ast_wait_for_input returned %d\n", res); 02632 goto cleanup; 02633 } else if (res == 0) { 02634 /* timeout */ 02635 ast_debug(2, "SIP TCP server timed out\n"); 02636 goto cleanup; 02637 } 02638 } 02639 02640 ast_mutex_lock(&tcptls_session->lock); 02641 if (!fgets(buf, sizeof(buf), tcptls_session->f)) { 02642 ast_mutex_unlock(&tcptls_session->lock); 02643 if (after_poll) { 02644 goto cleanup; 02645 } else { 02646 need_poll = 1; 02647 continue; 02648 } 02649 } 02650 ast_mutex_unlock(&tcptls_session->lock); 02651 after_poll = 0; 02652 if (me->stop) { 02653 goto cleanup; 02654 } 02655 ast_str_append(&req.data, 0, "%s", buf); 02656 req.len = req.data->used; 02657 } 02658 copy_request(&reqcpy, &req); 02659 parse_request(&reqcpy); 02660 /* In order to know how much to read, we need the content-length header */ 02661 if (sscanf(get_header(&reqcpy, "Content-Length"), "%30d", &cl)) { 02662 while (cl > 0) { 02663 size_t bytes_read; 02664 if (!tcptls_session->client && !authenticated ) { 02665 if ((timeout = sip_check_authtimeout(start)) < 0) { 02666 goto cleanup; 02667 } 02668 02669 if (timeout == 0) { 02670 ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP"); 02671 goto cleanup; 02672 } 02673 } else { 02674 timeout = -1; 02675 } 02676 02677 if (!tcptls_session->ssl || need_poll) { 02678 need_poll = 0; 02679 after_poll = 1; 02680 res = ast_wait_for_input(tcptls_session->fd, timeout); 02681 if (res < 0) { 02682 ast_debug(2, "SIP TCP server :: ast_wait_for_input returned %d\n", res); 02683 goto cleanup; 02684 } else if (res == 0) { 02685 /* timeout */ 02686 ast_debug(2, "SIP TCP server timed out\n"); 02687 goto cleanup; 02688 } 02689 } 02690 02691 ast_mutex_lock(&tcptls_session->lock); 02692 if (!(bytes_read = fread(buf, 1, MIN(sizeof(buf) - 1, cl), tcptls_session->f))) { 02693 ast_mutex_unlock(&tcptls_session->lock); 02694 if (after_poll) { 02695 goto cleanup; 02696 } else { 02697 need_poll = 1; 02698 continue; 02699 } 02700 } 02701 buf[bytes_read] = '\0'; 02702 ast_mutex_unlock(&tcptls_session->lock); 02703 after_poll = 0; 02704 if (me->stop) { 02705 goto cleanup; 02706 } 02707 cl -= strlen(buf); 02708 ast_str_append(&req.data, 0, "%s", buf); 02709 req.len = req.data->used; 02710 } 02711 } 02712 /*! \todo XXX If there's no Content-Length or if the content-length and what 02713 we receive is not the same - we should generate an error */ 02714 02715 req.socket.tcptls_session = tcptls_session; 02716 handle_request_do(&req, &tcptls_session->remote_address); 02717 } 02718 02719 if (fds[1].revents) { /* alert_pipe indicates there is data in the send queue to be sent */ 02720 enum sip_tcptls_alert alert; 02721 struct tcptls_packet *packet; 02722 02723 fds[1].revents = 0; 02724 02725 if (read(me->alert_pipe[0], &alert, sizeof(alert)) == -1) { 02726 ast_log(LOG_ERROR, "read() failed: %s\n", strerror(errno)); 02727 continue; 02728 } 02729 02730 switch (alert) { 02731 case TCPTLS_ALERT_STOP: 02732 goto cleanup; 02733 case TCPTLS_ALERT_DATA: 02734 ao2_lock(me); 02735 if (!(packet = AST_LIST_REMOVE_HEAD(&me->packet_q, entry))) { 02736 ast_log(LOG_WARNING, "TCPTLS thread alert_pipe indicated packet should be sent, but frame_q is empty"); 02737 } else if (ast_tcptls_server_write(tcptls_session, ast_str_buffer(packet->data), packet->len) == -1) { 02738 ast_log(LOG_WARNING, "Failure to write to tcp/tls socket\n"); 02739 } 02740 02741 if (packet) { 02742 ao2_t_ref(packet, -1, "tcptls packet sent, this is no longer needed"); 02743 } 02744 ao2_unlock(me); 02745 break; 02746 default: 02747 ast_log(LOG_ERROR, "Unknown tcptls thread alert '%d'\n", alert); 02748 } 02749 } 02750 } 02751 02752 ast_debug(2, "Shutting down thread for %s server\n", tcptls_session->ssl ? "SSL" : "TCP"); 02753 02754 cleanup: 02755 if (tcptls_session && !tcptls_session->client && !authenticated) { 02756 ast_atomic_fetchadd_int(&unauth_sessions, -1); 02757 } 02758 02759 if (me) { 02760 ao2_t_unlink(threadt, me, "Removing tcptls helper thread, thread is closing"); 02761 ao2_t_ref(me, -1, "Removing tcp_helper_threads threadinfo ref"); 02762 } 02763 deinit_req(&reqcpy); 02764 deinit_req(&req); 02765 02766 /* if client, we own the parent session arguments and must decrement ref */ 02767 if (ca) { 02768 ao2_t_ref(ca, -1, "closing tcptls thread, getting rid of client tcptls_session arguments"); 02769 } 02770 02771 if (tcptls_session) { 02772 ast_mutex_lock(&tcptls_session->lock); 02773 if (tcptls_session->f) { 02774 fclose(tcptls_session->f); 02775 tcptls_session->f = NULL; 02776 } 02777 if (tcptls_session->fd != -1) { 02778 close(tcptls_session->fd); 02779 tcptls_session->fd = -1; 02780 } 02781 tcptls_session->parent = NULL; 02782 ast_mutex_unlock(&tcptls_session->lock); 02783 02784 ao2_ref(tcptls_session, -1); 02785 tcptls_session = NULL; 02786 } 02787 return NULL; 02788 }
| static void add_blank | ( | struct sip_request * | req | ) | [static] |
add a blank line if no body
Definition at line 4000 of file chan_sip.c.
References ast_str_append(), and ast_str_strlen().
Referenced by send_request(), and send_response().
04001 { 04002 if (!req->lines) { 04003 /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */ 04004 ast_str_append(&req->data, 0, "\r\n"); 04005 req->len = ast_str_strlen(req->data); 04006 } 04007 }
| static void add_cc_call_info_to_response | ( | struct sip_pvt * | p, | |
| struct sip_request * | resp | |||
| ) | [static] |
Definition at line 11117 of file chan_sip.c.
References add_header(), ao2_ref, ast_copy_string(), ast_log(), ast_str_alloca, ast_str_buffer(), ast_str_set(), ast_strlen_zero(), find_sip_cc_agent_by_original_callid(), generate_uri(), LOG_WARNING, and ast_cc_agent::private_data.
Referenced by __transmit_response(), and transmit_response_with_sdp().
11118 { 11119 char uri[SIPBUFSIZE]; 11120 struct ast_str *header = ast_str_alloca(SIPBUFSIZE); 11121 struct ast_cc_agent *agent = find_sip_cc_agent_by_original_callid(p); 11122 struct sip_cc_agent_pvt *agent_pvt; 11123 11124 if (!agent) { 11125 /* Um, what? How could the SIP_OFFER_CC flag be set but there not be an 11126 * agent? Oh well, we'll just warn and return without adding the header. 11127 */ 11128 ast_log(LOG_WARNING, "Can't find SIP CC agent for call '%s' even though OFFER_CC flag was set?\n", p->callid); 11129 return; 11130 } 11131 11132 agent_pvt = agent->private_data; 11133 11134 if (!ast_strlen_zero(agent_pvt->subscribe_uri)) { 11135 ast_copy_string(uri, agent_pvt->subscribe_uri, sizeof(uri)); 11136 } else { 11137 generate_uri(p, uri, sizeof(uri)); 11138 ast_copy_string(agent_pvt->subscribe_uri, uri, sizeof(agent_pvt->subscribe_uri)); 11139 } 11140 /* XXX Hardcode "NR" as the m reason for now. This should perhaps be changed 11141 * to be more accurate. This parameter has no bearing on the actual operation 11142 * of the feature; it's just there for informational purposes. 11143 */ 11144 ast_str_set(&header, 0, "<%s>;purpose=call-completion;m=%s", uri, "NR"); 11145 add_header(resp, "Call-Info", ast_str_buffer(header)); 11146 ao2_ref(agent, -1); 11147 }
| static void add_codec_to_sdp | ( | const struct sip_pvt * | p, | |
| format_t | codec, | |||
| struct ast_str ** | m_buf, | |||
| struct ast_str ** | a_buf, | |||
| int | debug, | |||
| int * | min_packet_size | |||
| ) | [static] |
Add codec offer to SDP offer/answer body in INVITE or 200 OK.
Definition at line 10417 of file chan_sip.c.
References ast_codec_pref_getsize(), AST_FORMAT_G719, AST_FORMAT_G723_1, AST_FORMAT_G729A, AST_FORMAT_ILBC, AST_FORMAT_SIREN14, AST_FORMAT_SIREN7, ast_getformatname(), ast_rtp_codecs_payload_code(), ast_rtp_instance_get_codecs(), ast_rtp_lookup_mime_subtype2(), ast_rtp_lookup_sample_rate2(), AST_RTP_OPT_G726_NONSTANDARD, ast_str_append(), ast_test_flag, ast_verbose, ast_format_list::cur_ms, and ast_rtp_codecs::pref.
Referenced by add_sdp().
10420 { 10421 int rtp_code; 10422 struct ast_format_list fmt; 10423 10424 10425 if (debug) 10426 ast_verbose("Adding codec 0x%" PRIx64 " (%s) to SDP\n", codec, ast_getformatname(codec)); 10427 if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->rtp), 1, codec)) == -1) 10428 return; 10429 10430 if (p->rtp) { 10431 struct ast_codec_pref *pref = &ast_rtp_instance_get_codecs(p->rtp)->pref; 10432 fmt = ast_codec_pref_getsize(pref, codec); 10433 } else /* I don't see how you couldn't have p->rtp, but good to check for and error out if not there like earlier code */ 10434 return; 10435 ast_str_append(m_buf, 0, " %d", rtp_code); 10436 ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code, 10437 ast_rtp_lookup_mime_subtype2(1, codec, 10438 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0), 10439 ast_rtp_lookup_sample_rate2(1, codec)); 10440 10441 switch (codec) { 10442 case AST_FORMAT_G729A: 10443 /* Indicate that we don't support VAD (G.729 annex B) */ 10444 ast_str_append(a_buf, 0, "a=fmtp:%d annexb=no\r\n", rtp_code); 10445 break; 10446 case AST_FORMAT_G723_1: 10447 /* Indicate that we don't support VAD (G.723.1 annex A) */ 10448 ast_str_append(a_buf, 0, "a=fmtp:%d annexa=no\r\n", rtp_code); 10449 break; 10450 case AST_FORMAT_ILBC: 10451 /* Add information about us using only 20/30 ms packetization */ 10452 ast_str_append(a_buf, 0, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms); 10453 break; 10454 case AST_FORMAT_SIREN7: 10455 /* Indicate that we only expect 32Kbps */ 10456 ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=32000\r\n", rtp_code); 10457 break; 10458 case AST_FORMAT_SIREN14: 10459 /* Indicate that we only expect 48Kbps */ 10460 ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=48000\r\n", rtp_code); 10461 break; 10462 case AST_FORMAT_G719: 10463 /* Indicate that we only expect 64Kbps */ 10464 ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=64000\r\n", rtp_code); 10465 break; 10466 } 10467 10468 if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size)) 10469 *min_packet_size = fmt.cur_ms; 10470 10471 /* Our first codec packetization processed cannot be zero */ 10472 if ((*min_packet_size)==0 && fmt.cur_ms) 10473 *min_packet_size = fmt.cur_ms; 10474 }
| static int add_content | ( | struct sip_request * | req, | |
| const char * | line | |||
| ) | [static] |
Add content (not header) to SIP message.
Definition at line 9371 of file chan_sip.c.
References ast_log(), ast_str_append(), and LOG_WARNING.
Referenced by add_digit(), add_sdp(), add_text(), add_vidupdate(), transmit_cc_notify(), transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), and transmit_state_notify().
09372 { 09373 if (req->lines) { 09374 ast_log(LOG_WARNING, "Can't add more content when the content has been finalized\n"); 09375 return -1; 09376 } 09377 09378 ast_str_append(&req->content, 0, "%s", line); 09379 return 0; 09380 }
| 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 10281 of file chan_sip.c.
References add_content(), and add_header().
Referenced by transmit_info_with_digit().
10282 { 10283 char tmp[256]; 10284 int event; 10285 if (mode) { 10286 /* Application/dtmf short version used by some implementations */ 10287 if (digit == '*') 10288 event = 10; 10289 else if (digit == '#') 10290 event = 11; 10291 else if ((digit >= 'A') && (digit <= 'D')) 10292 event = 12 + digit - 'A'; 10293 else 10294 event = atoi(&digit); 10295 snprintf(tmp, sizeof(tmp), "%d\r\n", event); 10296 add_header(req, "Content-Type", "application/dtmf"); 10297 add_content(req, tmp); 10298 } else { 10299 /* Application/dtmf-relay as documented by Cisco */ 10300 snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration); 10301 add_header(req, "Content-Type", "application/dtmf-relay"); 10302 add_content(req, tmp); 10303 } 10304 return 0; 10305 }
| static void add_diversion_header | ( | struct sip_request * | req, | |
| struct sip_pvt * | pvt | |||
| ) | [static] |
Add "Diversion" header to outgoing message.
We need to add a Diversion header if the owner channel of this dialog has redirecting information associated with it.
| req | The request/response to which we will add the header | |
| pvt | The sip_pvt which represents the call-leg |
Definition at line 11502 of file chan_sip.c.
References add_header(), ast_sockaddr_stringify_host(), ast_strlen_zero(), and sip_reason_code_to_str().
Referenced by transmit_invite(), and update_redirecting().
11503 { 11504 const char *diverting_number; 11505 const char *diverting_name; 11506 const char *reason; 11507 char header_text[256]; 11508 11509 if (!pvt->owner) { 11510 return; 11511 } 11512 11513 diverting_number = pvt->owner->redirecting.from.number.str; 11514 if (!pvt->owner->redirecting.from.number.valid 11515 || ast_strlen_zero(diverting_number)) { 11516 return; 11517 } 11518 11519 reason = sip_reason_code_to_str(pvt->owner->redirecting.reason); 11520 11521 /* We at least have a number to place in the Diversion header, which is enough */ 11522 diverting_name = pvt->owner->redirecting.from.name.str; 11523 if (!pvt->owner->redirecting.from.name.valid 11524 || ast_strlen_zero(diverting_name)) { 11525 snprintf(header_text, sizeof(header_text), "<sip:%s@%s>;reason=%s", diverting_number, 11526 ast_sockaddr_stringify_host(&pvt->ourip), reason); 11527 } else { 11528 snprintf(header_text, sizeof(header_text), "\"%s\" <sip:%s@%s>;reason=%s", 11529 diverting_name, diverting_number, 11530 ast_sockaddr_stringify_host(&pvt->ourip), reason); 11531 } 11532 11533 add_header(req, "Diversion", header_text); 11534 }
| static int add_header | ( | struct sip_request * | req, | |
| const char * | var, | |||
| const char * | value | |||
| ) | [static] |
Add header to SIP message.
Definition at line 9311 of file chan_sip.c.
References ast_log(), ast_str_append(), ast_str_strlen(), find_alias(), LOG_WARNING, and sip_cfg.
09312 { 09313 if (req->headers == SIP_MAX_HEADERS) { 09314 ast_log(LOG_WARNING, "Out of SIP header space\n"); 09315 return -1; 09316 } 09317 09318 if (req->lines) { 09319 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 09320 return -1; 09321 } 09322 09323 if (sip_cfg.compactheaders) { 09324 var = find_alias(var, var); 09325 } 09326 09327 ast_str_append(&req->data, 0, "%s: %s\r\n", var, value); 09328 req->header[req->headers] = req->len; 09329 09330 req->len = ast_str_strlen(req->data); 09331 req->headers++; 09332 09333 return 0; 09334 }
| static int add_header_max_forwards | ( | struct sip_pvt * | dialog, | |
| struct sip_request * | req | |||
| ) | [static] |
Add 'Max-Forwards' header to SIP message.
Definition at line 9340 of file chan_sip.c.
References add_header().
Referenced by initreqprep(), reqprep(), and transmit_register().
09341 { 09342 char clen[10]; 09343 09344 snprintf(clen, sizeof(clen), "%d", dialog->maxforwards); 09345 09346 return add_header(req, "Max-Forwards", clen); 09347 }
| 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 10555 of file chan_sip.c.
References ast_rtp_codecs_payload_code(), AST_RTP_DTMF, ast_rtp_instance_get_codecs(), ast_rtp_lookup_mime_subtype2(), ast_rtp_lookup_sample_rate2(), ast_str_append(), and ast_verbose.
Referenced by add_sdp().
10558 { 10559 int rtp_code; 10560 10561 if (debug) 10562 ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype2(0, format, 0)); 10563 if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->rtp), 0, format)) == -1) 10564 return; 10565 10566 ast_str_append(m_buf, 0, " %d", rtp_code); 10567 ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code, 10568 ast_rtp_lookup_mime_subtype2(0, format, 0), 10569 ast_rtp_lookup_sample_rate2(0, format)); 10570 if (format == AST_RTP_DTMF) /* Indicate we support DTMF and FLASH... */ 10571 ast_str_append(a_buf, 0, "a=fmtp:%d 0-16\r\n", rtp_code); 10572 }
| static void add_peer_mailboxes | ( | struct sip_peer * | peer, | |
| const char * | value | |||
| ) | [static] |
Definition at line 25979 of file chan_sip.c.
References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_strdupa, ast_strlen_zero(), context, mailbox, mbox(), S_OR, and strsep().
Referenced by build_peer().
25980 { 25981 char *next, *mbox, *context; 25982 25983 next = ast_strdupa(value); 25984 25985 while ((mbox = context = strsep(&next, ","))) { 25986 struct sip_mailbox *mailbox; 25987 int duplicate = 0; 25988 25989 strsep(&context, "@"); 25990 25991 if (ast_strlen_zero(mbox)) { 25992 continue; 25993 } 25994 25995 /* Check whether the mailbox is already in the list */ 25996 AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { 25997 if (!strcmp(mailbox->mailbox, mbox) && !strcmp(S_OR(mailbox->context, ""), S_OR(context, ""))) { 25998 duplicate = 1; 25999 mailbox->delme = 0; 26000 break; 26001 } 26002 } 26003 if (duplicate) { 26004 continue; 26005 } 26006 26007 if (!(mailbox = ast_calloc(1, sizeof(*mailbox) + strlen(mbox) + strlen(S_OR(context, ""))))) { 26008 continue; 26009 } 26010 26011 if (!ast_strlen_zero(context)) { 26012 mailbox->context = mailbox->mailbox + strlen(mbox) + 1; 26013 strcpy(mailbox->context, context); /* SAFE */ 26014 } 26015 strcpy(mailbox->mailbox, mbox); /* SAFE */ 26016 26017 AST_LIST_INSERT_TAIL(&peer->mailboxes, mailbox, entry); 26018 } 26019 }
| static void add_peer_mwi_subs | ( | struct sip_peer * | peer | ) | [static] |
Definition at line 23303 of file chan_sip.c.
References AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, ast_event_subscribe(), AST_LIST_TRAVERSE, mailbox, mwi_event_cb(), and S_OR.
Referenced by build_peer(), and handle_request_subscribe().
23304 { 23305 struct sip_mailbox *mailbox; 23306 23307 AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { 23308 mailbox->event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "SIP mbox event", peer, 23309 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox->mailbox, 23310 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, S_OR(mailbox->context, "default"), 23311 AST_EVENT_IE_END); 23312 } 23313 }
| static struct sip_auth * add_realm_authentication | ( | struct sip_auth * | authlist, | |
| const char * | configuration, | |||
| int | lineno | |||
| ) | [static] |
Add realm authentication in list.
Definition at line 25787 of file chan_sip.c.
References ast_calloc, ast_copy_string(), ast_debug, ast_log(), ast_strlen_zero(), ast_verb, LOG_WARNING, and secret.
Referenced by build_peer().
25788 { 25789 char authcopy[256]; 25790 char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; 25791 struct sip_auth *a, *b, *auth; 25792 25793 if (ast_strlen_zero(configuration)) 25794 return authlist; 25795 25796 ast_debug(1, "Auth config :: %s\n", configuration); 25797 25798 ast_copy_string(authcopy, configuration, sizeof(authcopy)); 25799 username = authcopy; 25800 25801 /* split user[:secret] and relm */ 25802 realm = strrchr(username, '@'); 25803 if (realm) 25804 *realm++ = '\0'; 25805 if (ast_strlen_zero(username) || ast_strlen_zero(realm)) { 25806 ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno); 25807 return authlist; 25808 } 25809 25810 /* parse username at ':' for secret, or '#" for md5secret */ 25811 if ((secret = strchr(username, ':'))) { 25812 *secret++ = '\0'; 25813 } else if ((md5secret = strchr(username, '#'))) { 25814 *md5secret++ = '\0'; 25815 } 25816 25817 if (!(auth = ast_calloc(1, sizeof(*auth)))) 25818 return authlist; 25819 25820 ast_copy_string(auth->realm, realm, sizeof(auth->realm)); 25821 ast_copy_string(auth->username, username, sizeof(auth->username)); 25822 if (secret) 25823 ast_copy_string(auth->secret, secret, sizeof(auth->secret)); 25824 if (md5secret) 25825 ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret)); 25826 25827 /* find the end of the list */ 25828 for (b = NULL, a = authlist; a ; b = a, a = a->next) 25829 ; 25830 if (b) 25831 b->next = auth; /* Add structure add end of list */ 25832 else 25833 authlist = auth; 25834 25835 ast_verb(3, "Added authentication for realm %s\n", realm); 25836 25837 return authlist; 25838 25839 }
| static void add_route | ( | struct sip_request * | req, | |
| struct sip_route * | route | |||
| ) | [static] |
Add route header into request per learned route.
Definition at line 9482 of file chan_sip.c.
References add_header(), and ast_copy_string().
Referenced by initreqprep(), and reqprep().
09483 { 09484 char r[SIPBUFSIZE*2], *p; 09485 int n, rem = sizeof(r); 09486 09487 if (!route) 09488 return; 09489 09490 p = r; 09491 for (;route ; route = route->next) { 09492 n = strlen(route->hop); 09493 if (rem < n+3) /* we need room for ",<route>" */ 09494 break; 09495 if (p != r) { /* add a separator after fist route */ 09496 *p++ = ','; 09497 --rem; 09498 } 09499 *p++ = '<'; 09500 ast_copy_string(p, route->hop, rem); /* cannot fail */ 09501 p += n; 09502 *p++ = '>'; 09503 rem -= (n+2); 09504 } 09505 *p = '\0'; 09506 add_header(req, "Route", r); 09507 }
| static int add_rpid | ( | struct sip_request * | req, | |
| struct sip_pvt * | p | |||
| ) | [static] |
Add Remote-Party-ID header to SIP message.
Definition at line 10311 of file chan_sip.c.
References add_header(), ast_party_id_presentation(), AST_PRES_ALLOWED, AST_PRES_ALLOWED_NETWORK_NUMBER, AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, AST_PRES_PROHIB_NETWORK_NUMBER, AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, AST_PRES_RESTRICTION, ast_sockaddr_stringify_host(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_set(), ast_strlen_zero(), ast_test_flag, ast_uri_encode(), and S_OR.
Referenced by __transmit_response(), transmit_invite(), transmit_reinvite_with_sdp(), transmit_response_with_sdp(), and update_connectedline().
10312 { 10313 struct ast_str *tmp = ast_str_alloca(256); 10314 char tmp2[256]; 10315 char *lid_num = NULL; 10316 char *lid_name = NULL; 10317 int lid_pres; 10318 const char *fromdomain; 10319 const char *privacy = NULL; 10320 const char *screen = NULL; 10321 const char *anonymous_string = "\"Anonymous\" <sip:anonymous@anonymous.invalid>"; 10322 10323 if (!ast_test_flag(&p->flags[0], SIP_SENDRPID)) { 10324 return 0; 10325 } 10326 10327 if (p->owner && p->owner->connected.id.number.valid 10328 && p->owner->connected.id.number.str) { 10329 lid_num = p->owner->connected.id.number.str; 10330 } 10331 if (p->owner && p->owner->connected.id.name.valid 10332 && p->owner->connected.id.name.str) { 10333 lid_name = p->owner->connected.id.name.str; 10334 } 10335 lid_pres = (p->owner) ? ast_party_id_presentation(&p->owner->connected.id) : AST_PRES_NUMBER_NOT_AVAILABLE; 10336 10337 if (ast_strlen_zero(lid_num)) 10338 return 0; 10339 if (ast_strlen_zero(lid_name)) 10340 lid_name = lid_num; 10341 fromdomain = S_OR(p->fromdomain, ast_sockaddr_stringify_host(&p->ourip)); 10342 10343 lid_num = ast_uri_encode(lid_num, tmp2, sizeof(tmp2), 1); 10344 10345 if (ast_test_flag(&p->flags[0], SIP_SENDRPID_PAI)) { 10346 if ((lid_pres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) { 10347 ast_str_set(&tmp, -1, "%s", anonymous_string); 10348 } else { 10349 ast_str_set(&tmp, -1, "\"%s\" <sip:%s@%s>", lid_name, lid_num, fromdomain); 10350 } 10351 add_header(req, "P-Asserted-Identity", ast_str_buffer(tmp)); 10352 } else { 10353 ast_str_set(&tmp, -1, "\"%s\" <sip:%s@%s>;party=%s", lid_name, lid_num, fromdomain, ast_test_flag(&p->flags[0], SIP_OUTGOING) ? "calling" : "called"); 10354 10355 switch (lid_pres) { 10356 case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 10357 case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 10358 privacy = "off"; 10359 screen = "no"; 10360 break; 10361 case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 10362 case AST_PRES_ALLOWED_NETWORK_NUMBER: 10363 privacy = "off"; 10364 screen = "yes"; 10365 break; 10366 case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 10367 case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 10368 privacy = "full"; 10369 screen = "no"; 10370 break; 10371 case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 10372 case AST_PRES_PROHIB_NETWORK_NUMBER: 10373 privacy = "full"; 10374 screen = "yes"; 10375 break; 10376 case AST_PRES_NUMBER_NOT_AVAILABLE: 10377 break; 10378 default: 10379 if ((lid_pres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) { 10380 privacy = "full"; 10381 } 10382 else 10383 privacy = "off"; 10384 screen = "no"; 10385 break; 10386 } 10387 10388 if (!ast_strlen_zero(privacy) && !ast_strlen_zero(screen)) { 10389 ast_str_append(&tmp, -1, ";privacy=%s;screen=%s", privacy, screen); 10390 } 10391 10392 add_header(req, "Remote-Party-ID", ast_str_buffer(tmp)); 10393 } 10394 return 0; 10395 }
| 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 10693 of file chan_sip.c.
References add_codec_to_sdp(), add_content(), add_header(), add_noncodec_to_sdp(), add_tcodec_to_sdp(), add_vcodec_to_sdp(), ast_codec_pref_index(), ast_debug, AST_FORMAT_AUDIO_MASK, AST_FORMAT_TEXT_MASK, AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_internal_timing_enabled(), ast_log(), ast_random(), AST_RTP_MAX, ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_is_ipv4_mapped(), ast_sockaddr_is_ipv6(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_sockaddr_stringify_port(), ast_str_alloca, ast_str_append(), ast_strlen_zero(), AST_T38_RATE_MANAGEMENT_LOCAL_TCF, AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF, ast_test_flag, ast_udptl_get_error_correction_scheme(), ast_udptl_get_local_max_datagram(), ast_udptl_get_us(), ast_verbose, capability, debug, FALSE, get_crypto_attrib(), get_our_media_address(), global_sdpowner, global_sdpsession, LOG_WARNING, sip_debug_test_pvt(), sipdebug_text, t38_get_rate(), TRUE, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_REDUNDANCY, and version.
10694 { 10695 format_t alreadysent = 0; 10696 int doing_directmedia = FALSE; 10697 10698 struct ast_sockaddr addr = { {0,} }; 10699 struct ast_sockaddr vaddr = { {0,} }; 10700 struct ast_sockaddr taddr = { {0,} }; 10701 struct ast_sockaddr udptladdr = { {0,} }; 10702 struct ast_sockaddr dest = { {0,} }; 10703 struct ast_sockaddr vdest = { {0,} }; 10704 struct ast_sockaddr tdest = { {0,} }; 10705 struct ast_sockaddr udptldest = { {0,} }; 10706 10707 /* SDP fields */ 10708 char *version = "v=0\r\n"; /* Protocol version */ 10709 char subject[256]; /* Subject of the session */ 10710 char owner[256]; /* Session owner/creator */ 10711 char connection[256]; /* Connection data */ 10712 char *session_time = "t=0 0\r\n"; /* Time the session is active */ 10713 char bandwidth[256] = ""; /* Max bitrate */ 10714 char *hold = ""; 10715 struct ast_str *m_audio = ast_str_alloca(256); /* Media declaration line for audio */ 10716 struct ast_str *m_video = ast_str_alloca(256); /* Media declaration line for video */ 10717 struct ast_str *m_text = ast_str_alloca(256); /* Media declaration line for text */ 10718 struct ast_str *m_modem = ast_str_alloca(256); /* Media declaration line for modem */ 10719 struct ast_str *a_audio = ast_str_alloca(1024); /* Attributes for audio */ 10720 struct ast_str *a_video = ast_str_alloca(1024); /* Attributes for video */ 10721 struct ast_str *a_text = ast_str_alloca(1024); /* Attributes for text */ 10722 struct ast_str *a_modem = ast_str_alloca(1024); /* Attributes for modem */ 10723 const char *a_crypto = NULL; 10724 const char *v_a_crypto = NULL; 10725 const char *t_a_crypto = NULL; 10726 10727 format_t x; 10728 format_t capability = 0; 10729 int needaudio = FALSE; 10730 int needvideo = FALSE; 10731 int needtext = FALSE; 10732 int debug = sip_debug_test_pvt(p); 10733 int min_audio_packet_size = 0; 10734 int min_video_packet_size = 0; 10735 int min_text_packet_size = 0; 10736 10737 char codecbuf[SIPBUFSIZE]; 10738 char buf[SIPBUFSIZE]; 10739 char dummy_answer[256]; 10740 10741 /* Set the SDP session name */ 10742 snprintf(subject, sizeof(subject), "s=%s\r\n", ast_strlen_zero(global_sdpsession) ? "-" : global_sdpsession); 10743 10744 if (!p->rtp) { 10745 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 10746 return AST_FAILURE; 10747 } 10748 /* XXX We should not change properties in the SIP dialog until 10749 we have acceptance of the offer if this is a re-invite */ 10750 10751 /* Set RTP Session ID and version */ 10752 if (!p->sessionid) { 10753 p->sessionid = (int)ast_random(); 10754 p->sessionversion = p->sessionid; 10755 } else { 10756 if (oldsdp == FALSE) 10757 p->sessionversion++; 10758 } 10759 10760 if (add_audio) { 10761 doing_directmedia = (!ast_sockaddr_isnull(&p->redirip) && p->redircodecs) ? TRUE : FALSE; 10762 /* Check if we need video in this call */ 10763 if ((p->jointcapability & AST_FORMAT_VIDEO_MASK) && !p->novideo) { 10764 if (p->vrtp) { 10765 needvideo = TRUE; 10766 ast_debug(2, "This call needs video offers!\n"); 10767 } else 10768 ast_debug(2, "This call needs video offers, but there's no video support enabled!\n"); 10769 } 10770 /* Check if we need text in this call */ 10771 if ((p->jointcapability & AST_FORMAT_TEXT_MASK) && !p->notext) { 10772 if (sipdebug_text) 10773 ast_verbose("We think we can do text\n"); 10774 if (p->trtp) { 10775 if (sipdebug_text) { 10776 ast_verbose("And we have a text rtp object\n"); 10777 } 10778 needtext = TRUE; 10779 ast_debug(2, "This call needs text offers! \n"); 10780 } else { 10781 ast_debug(2, "This call needs text offers, but there's no text support enabled ! \n"); 10782 } 10783 } 10784 } 10785 10786 get_our_media_address(p, needvideo, needtext, &addr, &vaddr, &taddr, &dest, &vdest, &tdest); 10787 10788 snprintf(owner, sizeof(owner), "o=%s %d %d IN %s %s\r\n", 10789 ast_strlen_zero(global_sdpowner) ? "-" : global_sdpowner, 10790 p->sessionid, p->sessionversion, 10791 (ast_sockaddr_is_ipv6(&dest) && !ast_sockaddr_is_ipv4_mapped(&dest)) ? 10792 "IP6" : "IP4", 10793 ast_sockaddr_stringify_addr(&dest)); 10794 10795 snprintf(connection, sizeof(connection), "c=IN %s %s\r\n", 10796 (ast_sockaddr_is_ipv6(&dest) && !ast_sockaddr_is_ipv4_mapped(&dest)) ? 10797 "IP6" : "IP4", 10798 ast_sockaddr_stringify_addr(&dest)); 10799 10800 if (add_audio) { 10801 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR) { 10802 hold = "a=recvonly\r\n"; 10803 doing_directmedia = FALSE; 10804 } else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE) { 10805 hold = "a=inactive\r\n"; 10806 doing_directmedia = FALSE; 10807 } else { 10808 hold = "a=sendrecv\r\n"; 10809 } 10810 10811 capability = p->jointcapability; 10812 10813 /* XXX note, Video and Text are negated - 'true' means 'no' */ 10814 ast_debug(1, "** Our capability: %s Video flag: %s Text flag: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), capability), 10815 p->novideo ? "True" : "False", p->notext ? "True" : "False"); 10816 ast_debug(1, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec)); 10817 10818 if (doing_directmedia) { 10819 capability &= p->redircodecs; 10820 ast_debug(1, "** Our native-bridge filtered capablity: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), capability)); 10821 } 10822 10823 /* Check if we need audio */ 10824 if (capability & AST_FORMAT_AUDIO_MASK) 10825 needaudio = TRUE; 10826 10827 if (debug) { 10828 ast_verbose("Audio is at %s\n", ast_sockaddr_stringify_port(&p->ourip)); 10829 } 10830 10831 /* Ok, we need video. Let's add what we need for video and set codecs. 10832 Video is handled differently than audio since we can not transcode. */ 10833 if (needvideo) { 10834 get_crypto_attrib(p->vsrtp, &v_a_crypto); 10835 ast_str_append(&m_video, 0, "m=video %d RTP/%s", ast_sockaddr_port(&vdest), 10836 v_a_crypto ? "SAVP" : "AVP"); 10837 10838 /* Build max bitrate string */ 10839 if (p->maxcallbitrate) 10840 snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate); 10841 if (debug) { 10842 ast_verbose("Video is at %s\n", ast_sockaddr_stringify(&p->ourip)); 10843 } 10844 } 10845 10846 /* Ok, we need text. Let's add what we need for text and set codecs. 10847 Text is handled differently than audio since we can not transcode. */ 10848 if (needtext) { 10849 if (sipdebug_text) 10850 ast_verbose("Lets set up the text sdp\n"); 10851 get_crypto_attrib(p->tsrtp, &t_a_crypto); 10852 ast_str_append(&m_text, 0, "m=text %d RTP/%s", ast_sockaddr_port(&tdest), 10853 t_a_crypto ? "SAVP" : "AVP"); 10854 if (debug) { /* XXX should I use tdest below ? */ 10855 ast_verbose("Text is at %s\n", ast_sockaddr_stringify(&p->ourip)); 10856 } 10857 } 10858 10859 /* Start building generic SDP headers */ 10860 10861 /* We break with the "recommendation" and send our IP, in order that our 10862 peer doesn't have to ast_gethostbyname() us */ 10863 10864 get_crypto_attrib(p->srtp, &a_crypto); 10865 ast_str_append(&m_audio, 0, "m=audio %d RTP/%s", ast_sockaddr_port(&dest), 10866 a_crypto ? "SAVP" : "AVP"); 10867 10868 /* Now, start adding audio codecs. These are added in this order: 10869 - First what was requested by the calling channel 10870 - Then preferences in order from sip.conf device config for this peer/user 10871 - Then other codecs in capabilities, including video 10872 */ 10873 10874 /* Prefer the audio codec we were requested to use, first, no matter what 10875 Note that p->prefcodec can include video codecs, so mask them out 10876 */ 10877 if (capability & p->prefcodec) { 10878 format_t codec = p->prefcodec & AST_FORMAT_AUDIO_MASK; 10879 10880 add_codec_to_sdp(p, codec, &m_audio, &a_audio, debug, &min_audio_packet_size); 10881 alreadysent |= codec; 10882 } 10883 10884 /* Start by sending our preferred audio/video codecs */ 10885 for (x = 0; x < 64; x++) { 10886 format_t codec; 10887 10888 if (!(codec = ast_codec_pref_index(&p->prefs, x))) 10889 break; 10890 10891 if (!(capability & codec)) 10892 continue; 10893 10894 if (alreadysent & codec) 10895 continue; 10896 10897 add_codec_to_sdp(p, codec, &m_audio, &a_audio, debug, &min_audio_packet_size); 10898 alreadysent |= codec; 10899 } 10900 10901 /* Now send any other common audio and video codecs, and non-codec formats: */ 10902 for (x = 1ULL; x <= (needtext ? AST_FORMAT_TEXT_MASK : (needvideo ? AST_FORMAT_VIDEO_MASK : AST_FORMAT_AUDIO_MASK)); x <<= 1) { 10903 if (!(capability & x)) /* Codec not requested */ 10904 continue; 10905 10906 if (alreadysent & x) /* Already added to SDP */ 10907 continue; 10908 10909 if (x & AST_FORMAT_AUDIO_MASK) 10910 add_codec_to_sdp(p, x, &m_audio, &a_audio, debug, &min_audio_packet_size); 10911 else if (x & AST_FORMAT_VIDEO_MASK) 10912 add_vcodec_to_sdp(p, x, &m_video, &a_video, debug, &min_video_packet_size); 10913 else if (x & AST_FORMAT_TEXT_MASK) 10914 add_tcodec_to_sdp(p, x, &m_text, &a_text, debug, &min_text_packet_size); 10915 } 10916 10917 /* Now add DTMF RFC2833 telephony-event as a codec */ 10918 for (x = 1LL; x <= AST_RTP_MAX; x <<= 1) { 10919 if (!(p->jointnoncodeccapability & x)) 10920 continue; 10921 10922 add_noncodec_to_sdp(p, x, &m_audio, &a_audio, debug); 10923 } 10924 10925 ast_debug(3, "-- Done with adding codecs to SDP\n"); 10926 10927 if (!p->owner || !ast_internal_timing_enabled(p->owner)) 10928 ast_str_append(&a_audio, 0, "a=silenceSupp:off - - - -\r\n"); 10929 10930 if (min_audio_packet_size) 10931 ast_str_append(&a_audio, 0, "a=ptime:%d\r\n", min_audio_packet_size); 10932 10933 /* XXX don't think you can have ptime for video */ 10934 if (min_video_packet_size) 10935 ast_str_append(&a_video, 0, "a=ptime:%d\r\n", min_video_packet_size); 10936 10937 /* XXX don't think you can have ptime for text */ 10938 if (min_text_packet_size) 10939 ast_str_append(&a_text, 0, "a=ptime:%d\r\n", min_text_packet_size); 10940 10941 if (m_audio->len - m_audio->used < 2 || m_video->len - m_video->used < 2 || 10942 m_text->len - m_text->used < 2 || a_text->len - a_text->used < 2 || 10943 a_audio->len - a_audio->used < 2 || a_video->len - a_video->used < 2) 10944 ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n"); 10945 } 10946 10947 if (add_t38) { 10948 /* Our T.38 end is */ 10949 ast_udptl_get_us(p->udptl, &udptladdr); 10950 10951 /* Determine T.38 UDPTL destination */ 10952 if (!ast_sockaddr_isnull(&p->udptlredirip)) { 10953 ast_sockaddr_copy(&udptldest, &p->udptlredirip); 10954 } else { 10955 ast_sockaddr_copy(&udptldest, &p->ourip); 10956 ast_sockaddr_set_port(&udptldest, ast_sockaddr_port(&udptladdr)); 10957 } 10958 10959 if (debug) { 10960 ast_debug(1, "T.38 UDPTL is at %s port %d\n", ast_sockaddr_stringify_addr(&p->ourip), ast_sockaddr_port(&udptladdr)); 10961 } 10962 10963 /* We break with the "recommendation" and send our IP, in order that our 10964 peer doesn't have to ast_gethostbyname() us */ 10965 10966 ast_str_append(&m_modem, 0, "m=image %d udptl t38\r\n", ast_sockaddr_port(&udptldest)); 10967 10968 if (!ast_sockaddr_cmp(&udptldest, &dest)) { 10969 ast_str_append(&m_modem, 0, "c=IN %s %s\r\n", 10970 (ast_sockaddr_is_ipv6(&dest) && !ast_sockaddr_is_ipv4_mapped(&dest)) ? 10971 "IP6" : "IP4", ast_sockaddr_stringify_addr(&udptldest)); 10972 } 10973 10974 ast_str_append(&a_modem, 0, "a=T38FaxVersion:%d\r\n", p->t38.our_parms.version); 10975 ast_str_append(&a_modem, 0, "a=T38MaxBitRate:%d\r\n", t38_get_rate(p->t38.our_parms.rate)); 10976 if (p->t38.our_parms.fill_bit_removal) { 10977 ast_str_append(&a_modem, 0, "a=T38FaxFillBitRemoval\r\n"); 10978 } 10979 if (p->t38.our_parms.transcoding_mmr) { 10980 ast_str_append(&a_modem, 0, "a=T38FaxTranscodingMMR\r\n"); 10981 } 10982 if (p->t38.our_parms.transcoding_jbig) { 10983 ast_str_append(&a_modem, 0, "a=T38FaxTranscodingJBIG\r\n"); 10984 } 10985 switch (p->t38.our_parms.rate_management) { 10986 case AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF: 10987 ast_str_append(&a_modem, 0, "a=T38FaxRateManagement:transferredTCF\r\n"); 10988 break; 10989 case AST_T38_RATE_MANAGEMENT_LOCAL_TCF: 10990 ast_str_append(&a_modem, 0, "a=T38FaxRateManagement:localTCF\r\n"); 10991 break; 10992 } 10993 ast_str_append(&a_modem, 0, "a=T38FaxMaxDatagram:%u\r\n", ast_udptl_get_local_max_datagram(p->udptl)); 10994 switch (ast_udptl_get_error_correction_scheme(p->udptl)) { 10995 case UDPTL_ERROR_CORRECTION_NONE: 10996 break; 10997 case UDPTL_ERROR_CORRECTION_FEC: 10998 ast_str_append(&a_modem, 0, "a=T38FaxUdpEC:t38UDPFEC\r\n"); 10999 break; 11000 case UDPTL_ERROR_CORRECTION_REDUNDANCY: 11001 ast_str_append(&a_modem, 0, "a=T38FaxUdpEC:t38UDPRedundancy\r\n"); 11002 break; 11003 } 11004 } 11005 11006 if (needaudio) 11007 ast_str_append(&m_audio, 0, "\r\n"); 11008 if (needvideo) 11009 ast_str_append(&m_video, 0, "\r\n"); 11010 if (needtext) 11011 ast_str_append(&m_text, 0, "\r\n"); 11012 11013 add_header(resp, "Content-Type", "application/sdp"); 11014 add_content(resp, version); 11015 add_content(resp, owner); 11016 add_content(resp, subject); 11017 add_content(resp, connection); 11018 if (needvideo) /* only if video response is appropriate */ 11019 add_content(resp, bandwidth); 11020 add_content(resp, session_time); 11021 if (needaudio) { 11022 add_content(resp, m_audio->str); 11023 add_content(resp, a_audio->str); 11024 add_content(resp, hold); 11025 if (a_crypto) { 11026 add_content(resp, a_crypto); 11027 } 11028 } else if (p->offered_media[SDP_AUDIO].offered) { 11029 snprintf(dummy_answer, sizeof(dummy_answer), "m=audio 0 RTP/AVP %s\r\n", p->offered_media[SDP_AUDIO].codecs); 11030 add_content(resp, dummy_answer); 11031 } 11032 if (needvideo) { /* only if video response is appropriate */ 11033 add_content(resp, m_video->str); 11034 add_content(resp, a_video->str); 11035 add_content(resp, hold); /* Repeat hold for the video stream */ 11036 if (v_a_crypto) { 11037 add_content(resp, v_a_crypto); 11038 } 11039 } else if (p->offered_media[SDP_VIDEO].offered) { 11040 snprintf(dummy_answer, sizeof(dummy_answer), "m=video 0 RTP/AVP %s\r\n", p->offered_media[SDP_VIDEO].codecs); 11041 add_content(resp, dummy_answer); 11042 } 11043 if (needtext) { /* only if text response is appropriate */ 11044 add_content(resp, m_text->str); 11045 add_content(resp, a_text->str); 11046 add_content(resp, hold); /* Repeat hold for the text stream */ 11047 if (t_a_crypto) { 11048 add_content(resp, t_a_crypto); 11049 } 11050 } else if (p->offered_media[SDP_TEXT].offered) { 11051 snprintf(dummy_answer, sizeof(dummy_answer), "m=text 0 RTP/AVP %s\r\n", p->offered_media[SDP_TEXT].codecs); 11052 add_content(resp, dummy_answer); 11053 } 11054 if (add_t38) { 11055 add_content(resp, m_modem->str); 11056 add_content(resp, a_modem->str); 11057 } else if (p->offered_media[SDP_IMAGE].offered) { 11058 add_content(resp, "m=image 0 udptl t38\r\n"); 11059 } 11060 11061 /* Update lastrtprx when we send our SDP */ 11062 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 11063 11064 ast_debug(3, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, capability)); 11065 11066 return AST_SUCCESS; 11067 }
| 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 25723 of file chan_sip.c.
References ast_calloc, ast_copy_string(), ast_debug, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strlen_zero(), and LOG_WARNING.
25724 { 25725 struct domain *d; 25726 25727 if (ast_strlen_zero(domain)) { 25728 ast_log(LOG_WARNING, "Zero length domain.\n"); 25729 return 1; 25730 } 25731 25732 if (!(d = ast_calloc(1, sizeof(*d)))) 25733 return 0; 25734 25735 ast_copy_string(d->domain, domain, sizeof(d->domain)); 25736 25737 if (!ast_strlen_zero(context)) 25738 ast_copy_string(d->context, context, sizeof(d->context)); 25739 25740 d->mode = mode; 25741 25742 AST_LIST_LOCK(&domain_list); 25743 AST_LIST_INSERT_TAIL(&domain_list, d, list); 25744 AST_LIST_UNLOCK(&domain_list); 25745 25746 if (sipdebug) 25747 ast_debug(1, "Added local SIP domain '%s'\n", domain); 25748 25749 return 1; 25750 }
| static int add_supported_header | ( | struct sip_pvt * | pvt, | |
| struct sip_request * | req | |||
| ) | [static] |
Add "Supported" header to sip message. Since some options may be disabled in the config, the sip_pvt must be inspected to determine what is supported for this dialog.
Definition at line 9299 of file chan_sip.c.
References add_header(), and st_get_mode().
Referenced by respprep(), transmit_invite(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_reinvite_with_sdp(), and update_connectedline().
09300 { 09301 int res; 09302 if (st_get_mode(pvt) != SESSION_TIMER_MODE_REFUSE) { 09303 res = add_header(req, "Supported", "replaces, timer"); 09304 } else { 09305 res = add_header(req, "Supported", "replaces"); 09306 } 09307 return res; 09308 }
| static void add_tcodec_to_sdp | ( | const struct sip_pvt * | p, | |
| int | codec, | |||
| struct ast_str ** | m_buf, | |||
| struct ast_str ** | a_buf, | |||
| int | debug, | |||
| int * | min_packet_size | |||
| ) | [static] |
Add text codec offer to SDP offer/answer body in INVITE or 200 OK.
Definition at line 10501 of file chan_sip.c.
References AST_FORMAT_T140, AST_FORMAT_T140RED, ast_getformatname(), ast_rtp_codecs_payload_code(), ast_rtp_instance_get_codecs(), ast_rtp_lookup_mime_subtype2(), ast_rtp_lookup_sample_rate2(), ast_str_append(), and ast_verbose.
Referenced by add_sdp().
10504 { 10505 int rtp_code; 10506 10507 if (!p->trtp) 10508 return; 10509 10510 if (debug) 10511 ast_verbose("Adding text codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec)); 10512 10513 if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->trtp), 1, codec)) == -1) 10514 return; 10515 10516 ast_str_append(m_buf, 0, " %d", rtp_code); 10517 ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code, 10518 ast_rtp_lookup_mime_subtype2(1, codec, 0), 10519 ast_rtp_lookup_sample_rate2(1, codec)); 10520 /* Add fmtp code here */ 10521 10522 if (codec == AST_FORMAT_T140RED) { 10523 int t140code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->trtp), 1, AST_FORMAT_T140); 10524 ast_str_append(a_buf, 0, "a=fmtp:%d %d/%d/%d\r\n", rtp_code, 10525 t140code, 10526 t140code, 10527 t140code); 10528 10529 } 10530 }
| static int add_text | ( | struct sip_request * | req, | |
| const char * | text | |||
| ) | [static] |
Add text body to SIP message.
Definition at line 10269 of file chan_sip.c.
References add_content(), and add_header().
Referenced by transmit_message_with_text().
10270 { 10271 /* XXX Convert \n's to \r\n's XXX */ 10272 add_header(req, "Content-Type", "text/plain;charset=UTF-8"); 10273 add_content(req, text); 10274 return 0; 10275 }
| static struct ast_variable* add_var | ( | const char * | buf, | |
| struct ast_variable * | list | |||
| ) | [static] |
implement the setvar config line
Definition at line 25872 of file chan_sip.c.
References ast_strdupa, ast_variable_new(), and ast_variable::next.
25873 { 25874 struct ast_variable *tmpvar = NULL; 25875 char *varname = ast_strdupa(buf), *varval = NULL; 25876 25877 if ((varval = strchr(varname, '='))) { 25878 *varval++ = '\0'; 25879 if ((tmpvar = ast_variable_new(varname, varval, ""))) { 25880 tmpvar->next = list; 25881 list = tmpvar; 25882 } 25883 } 25884 return list; 25885 }
| static void add_vcodec_to_sdp | ( | const struct sip_pvt * | p, | |
| format_t | codec, | |||
| struct ast_str ** | m_buf, | |||
| struct ast_str ** | a_buf, | |||
| int | debug, | |||
| int * | min_packet_size | |||
| ) | [static] |
Add video codec offer to SDP offer/answer body in INVITE or 200 OK.
Definition at line 10478 of file chan_sip.c.
References ast_getformatname(), ast_rtp_codecs_payload_code(), ast_rtp_instance_get_codecs(), ast_rtp_lookup_mime_subtype2(), ast_rtp_lookup_sample_rate2(), ast_str_append(), and ast_verbose.
Referenced by add_sdp().
10481 { 10482 int rtp_code; 10483 10484 if (!p->vrtp) 10485 return; 10486 10487 if (debug) 10488 ast_verbose("Adding video codec 0x%" PRIx64 " (%s) to SDP\n", codec, ast_getformatname(codec)); 10489 10490 if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->vrtp), 1, codec)) == -1) 10491 return; 10492 10493 ast_str_append(m_buf, 0, " %d", rtp_code); 10494 ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code, 10495 ast_rtp_lookup_mime_subtype2(1, codec, 0), 10496 ast_rtp_lookup_sample_rate2(1, codec)); 10497 /* Add fmtp code here */ 10498 }
| static int add_vidupdate | ( | struct sip_request * | req | ) | [static] |
add XML encoded media control with update
Definition at line 10399 of file chan_sip.c.
References add_content(), and add_header().
Referenced by transmit_info_with_vidupdate().
10400 { 10401 const char *xml_is_a_huge_waste_of_space = 10402 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" 10403 " <media_control>\r\n" 10404 " <vc_primitive>\r\n" 10405 " <to_encoder>\r\n" 10406 " <picture_fast_update>\r\n" 10407 " </picture_fast_update>\r\n" 10408 " </to_encoder>\r\n" 10409 " </vc_primitive>\r\n" 10410 " </media_control>\r\n"; 10411 add_header(req, "Content-Type", "application/media_control+xml"); 10412 add_content(req, xml_is_a_huge_waste_of_space); 10413 return 0; 10414 }
| static int addr_is_multicast | ( | const struct ast_sockaddr * | addr | ) | [static] |
Check if an ip is an multicast IP. addr the address to check.
This function checks if an address is in the 224.0.0.0/4 network block.
Definition at line 7395 of file chan_sip.c.
References ast_sockaddr_ipv4().
Referenced by process_via().
07396 { 07397 return ((ast_sockaddr_ipv4(addr) & 0xf0000000) == 0xe0000000); 07398 }
| static void append_date | ( | struct sip_request * | req | ) | [static] |
Append date to SIP message.
Definition at line 10098 of file chan_sip.c.
References add_header().
10099 { 10100 char tmpdat[256]; 10101 struct tm tm; 10102 time_t t = time(NULL); 10103 10104 gmtime_r(&t, &tm); 10105 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm); 10106 add_header(req, "Date", tmpdat); 10107 }
| static void append_history_full | ( | struct sip_pvt * | p, | |
| const char * | fmt, | |||
| ... | ||||
| ) | [static] |
Append to SIP dialog history with arg list.
Definition at line 3440 of file chan_sip.c.
References append_history_va(), dumphistory, and recordhistory.
03441 { 03442 va_list ap; 03443 03444 if (!p) { 03445 return; 03446 } 03447 03448 if (!p->do_history && !recordhistory && !dumphistory) { 03449 return; 03450 } 03451 03452 va_start(ap, fmt); 03453 append_history_va(p, fmt, ap); 03454 va_end(ap); 03455 03456 return; 03457 }
| 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 3412 of file chan_sip.c.
References ast_calloc, ast_free, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, and strsep().
Referenced by append_history_full().
03413 { 03414 char buf[80], *c = buf; /* max history length */ 03415 struct sip_history *hist; 03416 int l; 03417 03418 vsnprintf(buf, sizeof(buf), fmt, ap); 03419 strsep(&c, "\r\n"); /* Trim up everything after \r or \n */ 03420 l = strlen(buf) + 1; 03421 if (!(hist = ast_calloc(1, sizeof(*hist) + l))) { 03422 return; 03423 } 03424 if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) { 03425 ast_free(hist); 03426 return; 03427 } 03428 memcpy(hist->event, buf, l); 03429 if (p->history_entries == MAX_HISTORY_ENTRIES) { 03430 struct sip_history *oldest; 03431 oldest = AST_LIST_REMOVE_HEAD(p->history, list); 03432 p->history_entries--; 03433 ast_free(oldest); 03434 } 03435 AST_LIST_INSERT_TAIL(p->history, hist, list); 03436 p->history_entries++; 03437 }
| static int apply_directmedia_ha | ( | struct sip_pvt * | p, | |
| const char * | op | |||
| ) | [static] |
Definition at line 27756 of file chan_sip.c.
References ast_apply_ha(), ast_debug, ast_rtp_instance_get_local_address(), ast_rtp_instance_get_remote_address(), AST_SENSE_ALLOW, AST_SENSE_DENY, ast_sockaddr_stringify(), and ast_strdupa.
Referenced by sip_get_rtp_peer(), sip_get_trtp_peer(), sip_get_udptl_peer(), and sip_get_vrtp_peer().
27757 { 27758 struct ast_sockaddr us = { { 0, }, }, them = { { 0, }, }; 27759 int res = AST_SENSE_ALLOW; 27760 27761 ast_rtp_instance_get_remote_address(p->rtp, &them); 27762 ast_rtp_instance_get_local_address(p->rtp, &us); 27763 27764 if ((res = ast_apply_ha(p->directmediaha, &them)) == AST_SENSE_DENY) { 27765 const char *us_addr = ast_strdupa(ast_sockaddr_stringify(&us)); 27766 const char *them_addr = ast_strdupa(ast_sockaddr_stringify(&them)); 27767 27768 ast_debug(3, "Reinvite %s to %s denied by directmedia ACL on %s\n", 27769 op, them_addr, us_addr); 27770 } 27771 27772 return res; 27773 }
| AST_DATA_STRUCTURE | ( | sip_peer | , | |
| DATA_EXPORT_SIP_PEER | ||||
| ) |
| static void ast_quiet_chan | ( | struct ast_channel * | chan | ) | [static] |
Turn off generator data XXX Does this function belong in the SIP channel?
Definition at line 20507 of file chan_sip.c.
References ast_channel::_state, ast_deactivate_generator(), AST_FLAG_MOH, ast_moh_stop(), AST_STATE_UP, and ast_test_flag.
Referenced by attempt_transfer(), and handle_invite_replaces().
20508 { 20509 if (chan && chan->_state == AST_STATE_UP) { 20510 if (ast_test_flag(chan, AST_FLAG_MOH)) 20511 ast_moh_stop(chan); 20512 else if (chan->generatordata) 20513 ast_deactivate_generator(chan); 20514 } 20515 }
| 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 3306 of file chan_sip.c.
References ast_apply_ha(), ast_debug, ast_log(), ast_ouraddrfor(), AST_SENSE_ALLOW, ast_sockaddr_copy(), ast_sockaddr_is_any(), ast_sockaddr_is_ipv6(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_resolve_first(), ast_sockaddr_set_port, ast_sockaddr_stringify(), bindaddr, externaddr, externexpire, externhost, externrefresh, externtcpport, externtlsport, get_transport(), internip, ast_tcptls_session_args::local_address, localaddr, LOG_NOTICE, LOG_WARNING, sip_cfg, sip_tcp_desc, and sip_tls_desc.
Referenced by __sip_subscribe_mwi_do(), sip_alloc(), sip_cc_monitor_request_cc(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_publish(), transmit_register(), and transmit_response_using_temp().
03307 { 03308 struct ast_sockaddr theirs; 03309 03310 /* Set want_remap to non-zero if we want to remap 'us' to an externally 03311 * reachable IP address and port. This is done if: 03312 * 1. we have a localaddr list (containing 'internal' addresses marked 03313 * as 'deny', so ast_apply_ha() will return AST_SENSE_DENY on them, 03314 * and AST_SENSE_ALLOW on 'external' ones); 03315 * 2. externaddr is set, so we know what to use as the 03316 * externally visible address; 03317 * 3. the remote address, 'them', is external; 03318 * 4. the address returned by ast_ouraddrfor() is 'internal' (AST_SENSE_DENY 03319 * when passed to ast_apply_ha() so it does need to be remapped. 03320 * This fourth condition is checked later. 03321 */ 03322 int want_remap = 0; 03323 03324 ast_sockaddr_copy(us, &internip); /* starting guess for the internal address */ 03325 /* now ask the system what would it use to talk to 'them' */ 03326 ast_ouraddrfor(them, us); 03327 ast_sockaddr_copy(&theirs, them); 03328 03329 if (ast_sockaddr_is_ipv6(&theirs)) { 03330 if (localaddr && !ast_sockaddr_isnull(&externaddr)) { 03331 ast_log(LOG_WARNING, "Address remapping activated in sip.conf " 03332 "but we're using IPv6, which doesn't need it. Please " 03333 "remove \"localnet\" and/or \"externaddr\" settings.\n"); 03334 } 03335 } else { 03336 want_remap = localaddr && 03337 !ast_sockaddr_isnull(&externaddr) && 03338 ast_apply_ha(localaddr, &theirs) == AST_SENSE_ALLOW ; 03339 } 03340 03341 if (want_remap && 03342 (!sip_cfg.matchexternaddrlocally || !ast_apply_ha(localaddr, us)) ) { 03343 /* if we used externhost, see if it is time to refresh the info */ 03344 if (externexpire && time(NULL) >= externexpire) { 03345 if (ast_sockaddr_resolve_first(&externaddr, externhost, 0)) { 03346 ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost); 03347 } 03348 externexpire = time(NULL) + externrefresh; 03349 } 03350 if (!ast_sockaddr_isnull(&externaddr)) { 03351 ast_sockaddr_copy(us, &externaddr); 03352 switch (p->socket.type) { 03353 case SIP_TRANSPORT_TCP: 03354 if (!externtcpport && ast_sockaddr_port(&externaddr)) { 03355 /* for consistency, default to the externaddr port */ 03356 externtcpport = ast_sockaddr_port(&externaddr); 03357 } 03358 ast_sockaddr_set_port(us, externtcpport); 03359 break; 03360 case SIP_TRANSPORT_TLS: 03361 ast_sockaddr_set_port(us, externtlsport); 03362 break; 03363 case SIP_TRANSPORT_UDP: 03364 if (!ast_sockaddr_port(&externaddr)) { 03365 ast_sockaddr_set_port(us, ast_sockaddr_port(&bindaddr)); 03366 } 03367 break; 03368 default: 03369 break; 03370 } 03371 } 03372 ast_debug(1, "Target address %s is not local, substituting externaddr\n", 03373 ast_sockaddr_stringify(them)); 03374 } else if (p) { 03375 /* no remapping, but we bind to a specific address, so use it. */ 03376 switch (p->socket.type) { 03377 case SIP_TRANSPORT_TCP: 03378 if (!ast_sockaddr_is_any(&sip_tcp_desc.local_address)) { 03379 ast_sockaddr_copy(us, 03380 &sip_tcp_desc.local_address); 03381 } else { 03382 ast_sockaddr_set_port(us, 03383 ast_sockaddr_port(&sip_tcp_desc.local_address)); 03384 } 03385 break; 03386 case SIP_TRANSPORT_TLS: 03387 if (!ast_sockaddr_is_any(&sip_tls_desc.local_address)) { 03388 ast_sockaddr_copy(us, 03389 &sip_tls_desc.local_address); 03390 } else { 03391 ast_sockaddr_set_port(us, 03392 ast_sockaddr_port(&sip_tls_desc.local_address)); 03393 } 03394 break; 03395 case SIP_TRANSPORT_UDP: 03396 /* fall through on purpose */ 03397 default: 03398 if (!ast_sockaddr_is_any(&bindaddr)) { 03399 ast_sockaddr_copy(us, &bindaddr); 03400 } 03401 if (!ast_sockaddr_port(us)) { 03402 ast_sockaddr_set_port(us, ast_sockaddr_port(&bindaddr)); 03403 } 03404 } 03405 } else if (!ast_sockaddr_is_any(&bindaddr)) { 03406 ast_sockaddr_copy(us, &bindaddr); 03407 } 03408 ast_debug(3, "Setting SIP_TRANSPORT_%s with address %s\n", get_transport(p->socket.type), ast_sockaddr_stringify(us)); 03409 }
| static int ast_sockaddr_resolve_first | ( | struct ast_sockaddr * | addr, | |
| const char * | name, | |||
| int | flag | |||
| ) | [static] |
Return the first entry from ast_sockaddr_resolve filtered by family of binddaddr.
Using this function probably means you have a faulty design.
Definition at line 28452 of file chan_sip.c.
References ast_sockaddr_resolve_first_af(), and get_address_family_filter().
Referenced by __set_address_from_contact(), ast_sip_ouraddrfor(), check_via(), create_addr(), parse_register_contact(), process_via(), set_destination(), sip_do_debug_ip(), and sip_request_call().
28454 { 28455 return ast_sockaddr_resolve_first_af(addr, name, flag, get_address_family_filter(&bindaddr)); 28456 }
| static int ast_sockaddr_resolve_first_af | ( | struct ast_sockaddr * | addr, | |
| const char * | name, | |||
| int | flag, | |||
| int | family | |||
| ) | [static] |
Return the first entry from ast_sockaddr_resolve filtered by address family.
Using this function probably means you have a faulty design.
Definition at line 28428 of file chan_sip.c.
References ast_debug, ast_free, ast_sockaddr_copy(), and ast_sockaddr_resolve().
Referenced by ast_sockaddr_resolve_first(), get_ip_and_port_from_sdp(), and process_sdp_c().
28430 { 28431 struct ast_sockaddr *addrs; 28432 int addrs_cnt; 28433 28434 addrs_cnt = ast_sockaddr_resolve(&addrs, name, flag, family); 28435 if (addrs_cnt <= 0) { 28436 return 1; 28437 } 28438 if (addrs_cnt > 1) { 28439 ast_debug(1, "Multiple addresses, using the first one only\n"); 28440 } 28441 28442 ast_sockaddr_copy(addr, &addrs[0]); 28443 28444 ast_free(addrs); 28445 return 0; 28446 }
| static int attempt_transfer | ( | struct sip_dual * | transferer, | |
| struct sip_dual * | target | |||
| ) | [static] |
Attempt transfer of SIP call This fix for attended transfers on a local PBX.
Definition at line 20519 of file chan_sip.c.
References ast_channel_masquerade(), ast_debug, ast_log(), ast_quiet_chan(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), ast_state2str(), LOG_NOTICE, and LOG_WARNING.
20520 { 20521 int res = 0; 20522 struct ast_channel *peera = NULL, 20523 *peerb = NULL, 20524 *peerc = NULL, 20525 *peerd = NULL; 20526 20527 20528 /* We will try to connect the transferee with the target and hangup 20529 all channels to the transferer */ 20530 ast_debug(4, "Sip transfer:--------------------\n"); 20531 if (transferer->chan1) 20532 ast_debug(4, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state)); 20533 else 20534 ast_debug(4, "-- No transferer first channel - odd??? \n"); 20535 if (target->chan1) 20536 ast_debug(4, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state)); 20537 else 20538 ast_debug(4, "-- No target first channel ---\n"); 20539 if (transferer->chan2) 20540 ast_debug(4, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state)); 20541 else 20542 ast_debug(4, "-- No bridged call to transferee\n"); 20543 if (target->chan2) 20544 ast_debug(4, "-- Bridged call to transfer target: %s State %s\n", target->chan2 ? target->chan2->name : "<none>", target->chan2 ? ast_state2str(target->chan2->_state) : "(none)"); 20545 else 20546 ast_debug(4, "-- No target second channel ---\n"); 20547 ast_debug(4, "-- END Sip transfer:--------------------\n"); 20548 if (transferer->chan2) { /* We have a bridge on the transferer's channel */ 20549 peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */ 20550 peerb = target->chan1; /* Transferer - PBX -> target channel - This will get lost in masq */ 20551 peerc = transferer->chan2; /* Asterisk to Transferee */ 20552 peerd = target->chan2; /* Asterisk to Target */ 20553 ast_debug(3, "SIP transfer: Four channels to handle\n"); 20554 } else if (target->chan2) { /* Transferer has no bridge (IVR), but transferee */ 20555 peera = target->chan1; /* Transferer to PBX -> target channel */ 20556 peerb = transferer->chan1; /* Transferer to IVR*/ 20557 peerc = target->chan2; /* Asterisk to Target */ 20558 peerd = transferer->chan2; /* Nothing */ 20559 ast_debug(3, "SIP transfer: Three channels to handle\n"); 20560 } 20561 20562 if (peera && peerb && peerc && (peerb != peerc)) { 20563 ast_quiet_chan(peera); /* Stop generators */ 20564 ast_quiet_chan(peerb); 20565 ast_quiet_chan(peerc); 20566 if (peerd) 20567 ast_quiet_chan(peerd); 20568 20569 ast_debug(4, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name); 20570 if (ast_channel_masquerade(peerb, peerc)) { 20571 ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); 20572 res = -1; 20573 } else 20574 ast_debug(4, "SIP transfer: Succeeded to masquerade channels.\n"); 20575 return res; 20576 } else { 20577 ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n"); 20578 if (transferer->chan1) 20579 ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV); 20580 if (target->chan1) 20581 ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV); 20582 return -1; 20583 } 20584 return 0; 20585 }
| static void auth_headers | ( | enum sip_auth_type | code, | |
| char ** | header, | |||
| char ** | respheader | |||
| ) | [static] |
return the request and response heade for a 401 or 407 code
Definition at line 12917 of file chan_sip.c.
References ast_verbose.
Referenced by check_auth(), do_proxy_auth(), do_register_auth(), and transmit_request_with_auth().
12918 { 12919 if (code == WWW_AUTH) { /* 401 */ 12920 *header = "WWW-Authenticate"; 12921 *respheader = "Authorization"; 12922 } else if (code == PROXY_AUTH) { /* 407 */ 12923 *header = "Proxy-Authenticate"; 12924 *respheader = "Proxy-Authorization"; 12925 } else { 12926 ast_verbose("-- wrong response code %d\n", code); 12927 *header = *respheader = "Invalid"; 12928 } 12929 }
| 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 5249 of file chan_sip.c.
References append_history, ast_channel_trylock, ast_channel_unlock, AST_CONTROL_CONGESTION, ast_queue_control(), sip_pvt_lock, sip_pvt_unlock, and sip_scheddestroy().
05250 { 05251 struct sip_pvt *p = (struct sip_pvt *)arg; 05252 05253 sip_pvt_lock(p); 05254 p->initid = -1; /* event gone, will not be rescheduled */ 05255 if (p->owner) { 05256 /* XXX fails on possible deadlock */ 05257 if (!ast_channel_trylock(p->owner)) { 05258 append_history(p, "Cong", "Auto-congesting (timer)"); 05259 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 05260 ast_channel_unlock(p->owner); 05261 } 05262 05263 /* Give the channel a chance to act before we proceed with destruction */ 05264 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 05265 } 05266 sip_pvt_unlock(p); 05267 dialog_unref(p, "unreffing arg passed into auto_congest callback (p->initid)"); 05268 return 0; 05269 }
| static void build_callid_pvt | ( | struct sip_pvt * | pvt | ) | [static] |
Build SIP Call-ID value for a non-REGISTER transaction.
Definition at line 7192 of file chan_sip.c.
References ast_sockaddr_stringify(), ast_string_field_build, generate_random_string(), and S_OR.
Referenced by __sip_subscribe_mwi_do(), sip_alloc(), sip_poke_peer(), sip_request_call(), and sip_send_mwi_to_peer().
07193 { 07194 char buf[33]; 07195 07196 const char *host = S_OR(pvt->fromdomain, ast_sockaddr_stringify(&pvt->ourip)); 07197 07198 ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 07199 07200 }
| 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 7203 of file chan_sip.c.
References ast_sockaddr_stringify_host(), ast_string_field_build, generate_random_string(), and S_OR.
Referenced by transmit_register().
07204 { 07205 char buf[33]; 07206 07207 const char *host = S_OR(fromdomain, ast_sockaddr_stringify_host(ourip)); 07208 07209 ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 07210 }
| static void build_contact | ( | struct sip_pvt * | p | ) | [static] |
Build contact header - the contact header we send out.
Definition at line 11311 of file chan_sip.c.
References ast_sockaddr_stringify(), ast_string_field_build, ast_strlen_zero(), ast_uri_encode(), and get_transport().
Referenced by __sip_subscribe_mwi_do(), check_user_full(), handle_request_invite(), handle_request_options(), handle_request_subscribe(), initreqprep(), register_verify(), and transmit_register().
11312 { 11313 char tmp[SIPBUFSIZE]; 11314 char *user = ast_uri_encode(p->exten, tmp, sizeof(tmp), 1); 11315 11316 if (p->socket.type == SIP_TRANSPORT_UDP) { 11317 ast_string_field_build(p, our_contact, "<sip:%s%s%s>", user, 11318 ast_strlen_zero(user) ? "" : "@", ast_sockaddr_stringify(&p->ourip)); 11319 } else { 11320 ast_string_field_build(p, our_contact, "<sip:%s%s%s;transport=%s>", user, 11321 ast_strlen_zero(user) ? "" : "@", ast_sockaddr_stringify(&p->ourip), 11322 get_transport(p->socket.type)); 11323 } 11324 }
| 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 26022 of file chan_sip.c.
References __set_address_from_contact(), accountcode, add_peer_mailboxes(), add_peer_mwi_subs(), add_realm_authentication(), add_var(), ao2_alloc, ao2_t_alloc, ao2_t_find, ao2_t_ref, asprintf, ast_append_ha(), ast_atomic_fetchadd_int(), ast_callerid_split(), AST_CC_AGENT_NATIVE, AST_CC_AGENT_NEVER, ast_cc_config_params_init, ast_cc_is_config_param(), ast_cc_set_param(), ast_cdr_amaflags2int(), ast_copy_flags, ast_copy_string(), ast_debug, ast_dnsmgr_lookup(), ast_dnsmgr_refresh(), ast_free, ast_free_ha(), ast_get_cc_agent_policy(), ast_get_group(), ast_get_ip(), ast_get_time_t(), AST_LIST_EMPTY, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), ast_parse_allow_disallow(), ast_parse_caller_presentation(), AST_SCHED_DEL_UNREF, ast_set2_flag, ast_set_cc_agent_policy(), ast_set_flag, ast_skip_blanks(), ast_sockaddr_isnull(), ast_sockaddr_parse(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_setnull(), ast_sockaddr_stringify_addr(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_set(), ast_str_strlen(), ast_strdupa, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variables_destroy(), bindaddr, can_parse_xml, cid_name, cid_num, clear_realm_authentication(), config, context, default_maxcallbitrate, DEFAULT_MAXMS, default_primary_transport, default_qualify, default_transports, destroy_association(), destroy_mailbox(), errno, FALSE, ast_flags::flags, format, get_address_family_filter(), get_srv_protocol(), get_srv_service(), global_dynamic_exclude_static, global_flags, 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(), language, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, mailbox, mark_parsed_methods(), MAXHOSTNAMELEN, mohinterpret, mohsuggest, ast_variable::name, ast_variable::next, OBJ_POINTER, OBJ_UNLINK, parkinglot, PARSE_PORT_FORBID, port_str2int(), proxy_update(), ref_peer(), reg_source_db(), rpeerobjs, secret, set_peer_defaults(), set_socket_transport(), sip_cfg, sip_destroy_peer_fn(), sip_poke_peer(), sip_register(), sip_send_mwi_to_peer(), speerobjs, srvlookup, str2stmode(), str2strefresher(), strsep(), TRUE, unref_peer(), and ast_variable::value.
26023 { 26024 struct sip_peer *peer = NULL; 26025 struct ast_ha *oldha = NULL; 26026 struct ast_ha *olddirectmediaha = NULL; 26027 int found = 0; 26028 int firstpass = 1; 26029 uint16_t port = 0; 26030 int format = 0; /* Ama flags */ 26031 int timerb_set = 0, timert1_set = 0; 26032 time_t regseconds = 0; 26033 struct ast_flags peerflags[3] = {{(0)}}; 26034 struct ast_flags mask[3] = {{(0)}}; 26035 char callback[256] = ""; 26036 struct sip_peer tmp_peer; 26037 const char *srvlookup = NULL; 26038 static int deprecation_warning = 1; 26039 int alt_fullcontact = alt ? 1 : 0, headercount = 0; 26040 struct ast_str *fullcontact = ast_str_alloca(512); 26041 26042 if (!realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 26043 /* Note we do NOT use find_peer here, to avoid realtime recursion */ 26044 /* We also use a case-sensitive comparison (unlike find_peer) so 26045 that case changes made to the peer name will be properly handled 26046 during reload 26047 */ 26048 ast_copy_string(tmp_peer.name, name, sizeof(tmp_peer.name)); 26049 peer = ao2_t_find(peers, &tmp_peer, OBJ_POINTER | OBJ_UNLINK, "find and unlink peer from peers table"); 26050 } 26051 26052 if (peer) { 26053 /* Already in the list, remove it and it will be added back (or FREE'd) */ 26054 found++; 26055 if (!(peer->the_mark)) 26056 firstpass = 0; 26057 } else { 26058 if (!(peer = ao2_t_alloc(sizeof(*peer), sip_destroy_peer_fn, "allocate a peer struct"))) 26059 return NULL; 26060 26061 if (ast_string_field_init(peer, 512)) { 26062 ao2_t_ref(peer, -1, "failed to string_field_init, drop peer"); 26063 return NULL; 26064 } 26065 26066 if (!(peer->cc_params = ast_cc_config_params_init())) { 26067 ao2_t_ref(peer, -1, "failed to allocate cc_params for peer"); 26068 return NULL; 26069 } 26070 26071 if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 26072 ast_atomic_fetchadd_int(&rpeerobjs, 1); 26073 ast_debug(3, "-REALTIME- peer built. Name: %s. Peer objects: %d\n", name, rpeerobjs); 26074 } else 26075 ast_atomic_fetchadd_int(&speerobjs, 1); 26076 } 26077 26078 /* Note that our peer HAS had its reference count increased */ 26079 if (firstpass) { 26080 peer->lastmsgssent = -1; 26081 oldha = peer->ha; 26082 peer->ha = NULL; 26083 olddirectmediaha = peer->directmediaha; 26084 peer->directmediaha = NULL; 26085 set_peer_defaults(peer); /* Set peer defaults */ 26086 peer->type = 0; 26087 } 26088 if (!found && name) 26089 ast_copy_string(peer->name, name, sizeof(peer->name)); 26090 26091 /* If we have channel variables, remove them (reload) */ 26092 if (peer->chanvars) { 26093 ast_variables_destroy(peer->chanvars); 26094 peer->chanvars = NULL; 26095 /* XXX should unregister ? */ 26096 } 26097 26098 if (found) 26099 peer->portinuri = 0; 26100 26101 /* If we have realm authentication information, remove them (reload) */ 26102 clear_realm_authentication(peer->auth); 26103 peer->auth = NULL; 26104 /* clear the transport information. We will detect if a default value is required after parsing the config */ 26105 peer->default_outbound_transport = 0; 26106 peer->transports = 0; 26107 26108 if (!devstate_only) { 26109 struct sip_mailbox *mailbox; 26110 AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { 26111 mailbox->delme = 1; 26112 } 26113 } 26114 26115 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 26116 if (!devstate_only) { 26117 if (handle_common_options(&peerflags[0], &mask[0], v)) { 26118 continue; 26119 } 26120 if (handle_t38_options(&peerflags[0], &mask[0], v, &peer->t38_maxdatagram)) { 26121 continue; 26122 } 26123 if (!strcasecmp(v->name, "transport") && !ast_strlen_zero(v->value)) { 26124 char *val = ast_strdupa(v->value); 26125 char *trans; 26126 26127 while ((trans = strsep(&val, ","))) { 26128 trans = ast_skip_blanks(trans); 26129 26130 if (!strncasecmp(trans, "udp", 3)) { 26131 peer->transports |= SIP_TRANSPORT_UDP; 26132 } else if (!strncasecmp(trans, "tcp", 3)) { 26133 peer->transports |= SIP_TRANSPORT_TCP; 26134 } else if (!strncasecmp(trans, "tls", 3)) { 26135 peer->transports |= SIP_TRANSPORT_TLS; 26136 } else { 26137 ast_log(LOG_NOTICE, "'%s' is not a valid transport type. if no other is specified, udp will be used.\n", trans); 26138 } 26139 26140 if (!peer->default_outbound_transport) { /*!< The first transport listed should be default outbound */ 26141 peer->default_outbound_transport = peer->transports; 26142 } 26143 } 26144 } else if (realtime && !strcasecmp(v->name, "regseconds")) { 26145 ast_get_time_t(v->value, ®seconds, 0, NULL); 26146 } else if (realtime && !strcasecmp(v->name, "name")) { 26147 ast_copy_string(peer->name, v->value, sizeof(peer->name)); 26148 } else if (realtime && !strcasecmp(v->name, "useragent")) { 26149 ast_string_field_set(peer, useragent, v->value); 26150 } else if (!strcasecmp(v->name, "type")) { 26151 if (!strcasecmp(v->value, "peer")) { 26152 peer->type |= SIP_TYPE_PEER; 26153 } else if (!strcasecmp(v->value, "user")) { 26154 peer->type |= SIP_TYPE_USER; 26155 } else if (!strcasecmp(v->value, "friend")) { 26156 peer->type = SIP_TYPE_USER | SIP_TYPE_PEER; 26157 } 26158 } else if (!strcasecmp(v->name, "remotesecret")) { 26159 ast_string_field_set(peer, remotesecret, v->value); 26160 } else if (!strcasecmp(v->name, "secret")) { 26161 ast_string_field_set(peer, secret, v->value); 26162 } else if (!strcasecmp(v->name, "md5secret")) { 26163 ast_string_field_set(peer, md5secret, v->value); 26164 } else if (!strcasecmp(v->name, "auth")) { 26165 peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno); 26166 } else if (!strcasecmp(v->name, "callerid")) { 26167 char cid_name[80] = { '\0' }, cid_num[80] = { '\0' }; 26168 26169 ast_callerid_split(v->value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num)); 26170 ast_string_field_set(peer, cid_name, cid_name); 26171 ast_string_field_set(peer, cid_num, cid_num); 26172 } else if (!strcasecmp(v->name, "mwi_from")) { 26173 ast_string_field_set(peer, mwi_from, v->value); 26174 } else if (!strcasecmp(v->name, "fullname")) { 26175 ast_string_field_set(peer, cid_name, v->value); 26176 } else if (!strcasecmp(v->name, "trunkname")) { 26177 /* This is actually for a trunk, so we don't want to override callerid */ 26178 ast_string_field_set(peer, cid_name, ""); 26179 } else if (!strcasecmp(v->name, "cid_number")) { 26180 ast_string_field_set(peer, cid_num, v->value); 26181 } else if (!strcasecmp(v->name, "cid_tag")) { 26182 ast_string_field_set(peer, cid_tag, v->value); 26183 } else if (!strcasecmp(v->name, "context")) { 26184 ast_string_field_set(peer, context, v->value); 26185 ast_set_flag(&peer->flags[1], SIP_PAGE2_HAVEPEERCONTEXT); 26186 } else if (!strcasecmp(v->name, "subscribecontext")) { 26187 ast_string_field_set(peer, subscribecontext, v->value); 26188 } else if (!strcasecmp(v->name, "fromdomain")) { 26189 char *fromdomainport; 26190 ast_string_field_set(peer, fromdomain, v->value); 26191 if ((fromdomainport = strchr(peer->fromdomain, ':'))) { 26192 *fromdomainport++ = '\0'; 26193 if (!(peer->fromdomainport = port_str2int(fromdomainport, 0))) { 26194 ast_log(LOG_NOTICE, "'%s' is not a valid port number for fromdomain.\n",fromdomainport); 26195 } 26196 } else { 26197 peer->fromdomainport = STANDARD_SIP_PORT; 26198 } 26199 } else if (!strcasecmp(v->name, "usereqphone")) { 26200 ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE); 26201 } else if (!strcasecmp(v->name, "fromuser")) { 26202 ast_string_field_set(peer, fromuser, v->value); 26203 } else if (!strcasecmp(v->name, "outboundproxy")) { 26204 char *tok, *proxyname; 26205 26206 if (ast_strlen_zero(v->value)) { 26207 ast_log(LOG_WARNING, "no value given for outbound proxy on line %d of sip.conf.", v->lineno); 26208 continue; 26209 } 26210 26211 peer->outboundproxy = 26212 ao2_alloc(sizeof(*peer->outboundproxy), NULL); 26213 26214 tok = ast_skip_blanks(strtok(ast_strdupa(v->value), ",")); 26215 26216 sip_parse_host(tok, v->lineno, &proxyname, 26217 &peer->outboundproxy->port, 26218 &peer->outboundproxy->transport); 26219 26220 tok = ast_skip_blanks(strtok(ast_strdupa(v->value), ",")); 26221 26222 if ((tok = strtok(NULL, ","))) { 26223 peer->outboundproxy->force = !strncasecmp(ast_skip_blanks(tok), "force", 5); 26224 } else { 26225 peer->outboundproxy->force = FALSE; 26226 } 26227 26228 if (ast_strlen_zero(proxyname)) { 26229 ast_log(LOG_WARNING, "you must specify a name for the outboundproxy on line %d of sip.conf.", v->lineno); 26230 sip_cfg.outboundproxy.name[0] = '\0'; 26231 continue; 26232 } 26233 26234 ast_copy_string(peer->outboundproxy->name, proxyname, sizeof(peer->outboundproxy->name)); 26235 26236 proxy_update(peer->outboundproxy); 26237 } else if (!strcasecmp(v->name, "host")) { 26238 if (!strcasecmp(v->value, "dynamic")) { 26239 /* They'll register with us */ 26240 if (!found || !peer->host_dynamic) { 26241 /* Initialize stuff if this is a new peer, or if it used to 26242 * not be dynamic before the reload. */ 26243 ast_sockaddr_setnull(&peer->addr); 26244 } 26245 peer->host_dynamic = TRUE; 26246 } else { 26247 /* Non-dynamic. Make sure we become that way if we're not */ 26248 AST_SCHED_DEL_UNREF(sched, peer->expire, 26249 unref_peer(peer, "removing register expire ref")); 26250 peer->host_dynamic = FALSE; 26251 srvlookup = v->value; 26252 } 26253 } else if (!strcasecmp(v->name, "defaultip")) { 26254 if (!ast_strlen_zero(v->value) && ast_get_ip(&peer->defaddr, v->value)) { 26255 unref_peer(peer, "unref_peer: from build_peer defaultip"); 26256 return NULL; 26257 } 26258 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 26259 int ha_error = 0; 26260 if (!ast_strlen_zero(v->value)) { 26261 peer->ha = ast_append_ha(v->name, v->value, peer->ha, &ha_error); 26262 } 26263 if (ha_error) { 26264 ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value); 26265 } 26266 } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) { 26267 int ha_error = 0; 26268 if (!ast_strlen_zero(v->value)) { 26269 peer->contactha = ast_append_ha(v->name + 7, v->value, peer->contactha, &ha_error); 26270 } 26271 if (ha_error) { 26272 ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value); 26273 } 26274 } else if (!strcasecmp(v->name, "directmediapermit") || !strcasecmp(v->name, "directmediadeny")) { 26275 int ha_error = 0; 26276 peer->directmediaha = ast_append_ha(v->name + 11, v->value, peer->directmediaha, &ha_error); 26277 if (ha_error) { 26278 ast_log(LOG_ERROR, "Bad directmedia ACL entry in configuration line %d : %s\n", v->lineno, v->value); 26279 } 26280 } else if (!strcasecmp(v->name, "port")) { 26281 peer->portinuri = 1; 26282 if (!(port = port_str2int(v->value, 0))) { 26283 if (realtime) { 26284 /* If stored as integer, could be 0 for some DBs (notably MySQL) */ 26285 peer->portinuri = 0; 26286 } else { 26287 ast_log(LOG_WARNING, "Invalid peer port configuration at line %d : %s\n", v->lineno, v->value); 26288 } 26289 } 26290 } else if (!strcasecmp(v->name, "callingpres")) { 26291 peer->callingpres = ast_parse_caller_presentation(v->value); 26292 if (peer->callingpres == -1) { 26293 peer->callingpres = atoi(v->value); 26294 } 26295 } else if (!strcasecmp(v->name, "username") || !strcmp(v->name, "defaultuser")) { /* "username" is deprecated */ 26296 ast_string_field_set(peer, username, v->value); 26297 if (!strcasecmp(v->name, "username")) { 26298 if (deprecation_warning) { 26299 ast_log(LOG_NOTICE, "The 'username' field for sip peers has been deprecated in favor of the term 'defaultuser'\n"); 26300 deprecation_warning = 0; 26301 } 26302 peer->deprecated_username = 1; 26303 } 26304 } else if (!strcasecmp(v->name, "language")) { 26305 ast_string_field_set(peer, language, v->value); 26306 } else if (!strcasecmp(v->name, "regexten")) { 26307 ast_string_field_set(peer, regexten, v->value); 26308 } else if (!strcasecmp(v->name, "callbackextension")) { 26309 ast_copy_string(callback, v->value, sizeof(callback)); 26310 } else if (!strcasecmp(v->name, "amaflags")) { 26311 format = ast_cdr_amaflags2int(v->value); 26312 if (format < 0) { 26313 ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno); 26314 } else { 26315 peer->amaflags = format; 26316 } 26317 } else if (!strcasecmp(v->name, "maxforwards")) { 26318 if ((sscanf(v->value, "%30d", &peer->maxforwards) != 1) || (peer->maxforwards < 1)) { 26319 ast_log(LOG_WARNING, "'%s' is not a valid maxforwards value at line %d. Using default.\n", v->value, v->lineno); 26320 peer->maxforwards = sip_cfg.default_max_forwards; 26321 } 26322 } else if (!strcasecmp(v->name, "accountcode")) { 26323 ast_string_field_set(peer, accountcode, v->value); 26324 } else if (!strcasecmp(v->name, "mohinterpret")) { 26325 ast_string_field_set(peer, mohinterpret, v->value); 26326 } else if (!strcasecmp(v->name, "mohsuggest")) { 26327 ast_string_field_set(peer, mohsuggest, v->value); 26328 } else if (!strcasecmp(v->name, "parkinglot")) { 26329 ast_string_field_set(peer, parkinglot, v->value); 26330 } else if (!strcasecmp(v->name, "rtp_engine")) { 26331 ast_string_field_set(peer, engine, v->value); 26332 } else if (!strcasecmp(v->name, "mailbox")) { 26333 add_peer_mailboxes(peer, v->value); 26334 } else if (!strcasecmp(v->name, "hasvoicemail")) { 26335 /* People expect that if 'hasvoicemail' is set, that the mailbox will 26336 * be also set, even if not explicitly specified. */ 26337 if (ast_true(v->value) && AST_LIST_EMPTY(&peer->mailboxes)) { 26338 add_peer_mailboxes(peer, name); 26339 } 26340 } else if (!strcasecmp(v->name, "subscribemwi")) { 26341 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY); 26342 } else if (!strcasecmp(v->name, "vmexten")) { 26343 ast_string_field_set(peer, vmexten, v->value); 26344 } else if (!strcasecmp(v->name, "callgroup")) { 26345 peer->callgroup = ast_get_group(v->value); 26346 } else if (!strcasecmp(v->name, "allowtransfer")) { 26347 peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 26348 } else if (!strcasecmp(v->name, "pickupgroup")) { 26349 peer->pickupgroup = ast_get_group(v->value); 26350 } else if (!strcasecmp(v->name, "allow")) { 26351 int error = ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, TRUE); 26352 if (error) { 26353 ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value); 26354 } 26355 } else if (!strcasecmp(v->name, "disallow")) { 26356 int error = ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, FALSE); 26357 if (error) { 26358 ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value); 26359 } 26360 } else if (!strcasecmp(v->name, "preferred_codec_only")) { 26361 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_PREFERRED_CODEC); 26362 } else if (!strcasecmp(v->name, "registertrying")) { 26363 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_REGISTERTRYING); 26364 } else if (!strcasecmp(v->name, "autoframing")) { 26365 peer->autoframing = ast_true(v->value); 26366 } else if (!strcasecmp(v->name, "rtptimeout")) { 26367 if ((sscanf(v->value, "%30d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) { 26368 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 26369 peer->rtptimeout = global_rtptimeout; 26370 } 26371 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 26372 if ((sscanf(v->value, "%30d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) { 26373 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 26374 peer->rtpholdtimeout = global_rtpholdtimeout; 26375 } 26376 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 26377 if ((sscanf(v->value, "%30d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) { 26378 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 26379 peer->rtpkeepalive = global_rtpkeepalive; 26380 } 26381 } else if (!strcasecmp(v->name, "timert1")) { 26382 if ((sscanf(v->value, "%30d", &peer->timer_t1) != 1) || (peer->timer_t1 < 200) || (peer->timer_t1 < global_t1min)) { 26383 ast_log(LOG_WARNING, "'%s' is not a valid T1 time at line %d. Using default.\n", v->value, v->lineno); 26384 peer->timer_t1 = global_t1min; 26385 } 26386 timert1_set = 1; 26387 } else if (!strcasecmp(v->name, "timerb")) { 26388 if ((sscanf(v->value, "%30d", &peer->timer_b) != 1) || (peer->timer_b < 200)) { 26389 ast_log(LOG_WARNING, "'%s' is not a valid Timer B time at line %d. Using default.\n", v->value, v->lineno); 26390 peer->timer_b = global_timer_b; 26391 } 26392 timerb_set = 1; 26393 } else if (!strcasecmp(v->name, "setvar")) { 26394 peer->chanvars = add_var(v->value, peer->chanvars); 26395 } else if (!strcasecmp(v->name, "header")) { 26396 char tmp[4096]; 26397 snprintf(tmp, sizeof(tmp), "__SIPADDHEADERpre%2d=%s", ++headercount, v->value); 26398 peer->chanvars = add_var(tmp, peer->chanvars); 26399 } else if (!strcasecmp(v->name, "qualifyfreq")) { 26400 int i; 26401 if (sscanf(v->value, "%30d", &i) == 1) { 26402 peer->qualifyfreq = i * 1000; 26403 } else { 26404 ast_log(LOG_WARNING, "Invalid qualifyfreq number '%s' at line %d of %s\n", v->value, v->lineno, config); 26405 peer->qualifyfreq = global_qualifyfreq; 26406 } 26407 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 26408 peer->maxcallbitrate = atoi(v->value); 26409 if (peer->maxcallbitrate < 0) { 26410 peer->maxcallbitrate = default_maxcallbitrate; 26411 } 26412 } else if (!strcasecmp(v->name, "session-timers")) { 26413 int i = (int) str2stmode(v->value); 26414 if (i < 0) { 26415 ast_log(LOG_WARNING, "Invalid session-timers '%s' at line %d of %s\n", v->value, v->lineno, config); 26416 peer->stimer.st_mode_oper = global_st_mode; 26417 } else { 26418 peer->stimer.st_mode_oper = i; 26419 } 26420 } else if (!strcasecmp(v->name, "session-expires")) { 26421 if (sscanf(v->value, "%30d", &peer->stimer.st_max_se) != 1) { 26422 ast_log(LOG_WARNING, "Invalid session-expires '%s' at line %d of %s\n", v->value, v->lineno, config); 26423 peer->stimer.st_max_se = global_max_se; 26424 } 26425 } else if (!strcasecmp(v->name, "session-minse")) { 26426 if (sscanf(v->value, "%30d", &peer->stimer.st_min_se) != 1) { 26427 ast_log(LOG_WARNING, "Invalid session-minse '%s' at line %d of %s\n", v->value, v->lineno, config); 26428 peer->stimer.st_min_se = global_min_se; 26429 } 26430 if (peer->stimer.st_min_se < 90) { 26431 ast_log(LOG_WARNING, "session-minse '%s' at line %d of %s is not allowed to be < 90 secs\n", v->value, v->lineno, config); 26432 peer->stimer.st_min_se = global_min_se; 26433 } 26434 } else if (!strcasecmp(v->name, "session-refresher")) { 26435 int i = (int) str2strefresher(v->value); 26436 if (i < 0) { 26437 ast_log(LOG_WARNING, "Invalid session-refresher '%s' at line %d of %s\n", v->value, v->lineno, config); 26438 peer->stimer.st_ref = global_st_refresher; 26439 } else { 26440 peer->stimer.st_ref = i; 26441 } 26442 } else if (!strcasecmp(v->name, "disallowed_methods")) { 26443 char *disallow = ast_strdupa(v->value); 26444 mark_parsed_methods(&peer->disallowed_methods, disallow); 26445 } else if (!strcasecmp(v->name, "unsolicited_mailbox")) { 26446 ast_string_field_set(peer, unsolicited_mailbox, v->value); 26447 } else if (!strcasecmp(v->name, "use_q850_reason")) { 26448 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_Q850_REASON); 26449 } else if (!strcasecmp(v->name, "encryption")) { 26450 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_USE_SRTP); 26451 } else if (!strcasecmp(v->name, "snom_aoc_enabled")) { 26452 ast_set2_flag(&peer->flags[2], ast_true(v->value), SIP_PAGE3_SNOM_AOC); 26453 } 26454 } 26455 26456 /* These apply to devstate lookups */ 26457 if (realtime && !strcasecmp(v->name, "lastms")) { 26458 sscanf(v->value, "%30d", &peer->lastms); 26459 } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) { 26460 ast_sockaddr_parse(&peer->addr, v->value, PARSE_PORT_FORBID); 26461 } else if (realtime && !strcasecmp(v->name, "fullcontact")) { 26462 if (alt_fullcontact && !alt) { 26463 /* Reset, because the alternate also has a fullcontact and we 26464 * do NOT want the field value to be doubled. It might be 26465 * tempting to skip this, but the first table might not have 26466 * fullcontact and since we're here, we know that the alternate 26467 * absolutely does. */ 26468 alt_fullcontact = 0; 26469 ast_str_reset(fullcontact); 26470 } 26471 /* Reconstruct field, because realtime separates our value at the ';' */ 26472 if (fullcontact->used > 0) { 26473 ast_str_append(&fullcontact, 0, ";%s", v->value); 26474 } else { 26475 ast_str_set(&fullcontact, 0, "%s", v->value); 26476 } 26477 } else if (!strcasecmp(v->name, "qualify")) { 26478 if (!strcasecmp(v->value, "no")) { 26479 peer->maxms = 0; 26480 } else if (!strcasecmp(v->value, "yes")) { 26481 peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS; 26482 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) { 26483 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); 26484 peer->maxms = 0; 26485 } 26486 if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && peer->maxms > 0) { 26487 /* This would otherwise cause a network storm, where the 26488 * qualify response refreshes the peer from the database, 26489 * which in turn causes another qualify to be sent, ad 26490 * infinitum. */ 26491 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); 26492 peer->maxms = 0; 26493 } 26494 } else if (!strcasecmp(v->name, "callcounter")) { 26495 peer->call_limit = ast_true(v->value) ? INT_MAX : 0; 26496 } else if (!strcasecmp(v->name, "call-limit")) { 26497 peer->call_limit = atoi(v->value); 26498 if (peer->call_limit < 0) { 26499 peer->call_limit = 0; 26500 } 26501 } else if (!strcasecmp(v->name, "busylevel")) { 26502 peer->busy_level = atoi(v->value); 26503 if (peer->busy_level < 0) { 26504 peer->busy_level = 0; 26505 } 26506 } else if (ast_cc_is_config_param(v->name)) { 26507 ast_cc_set_param(peer->cc_params, v->name, v->value); 26508 } 26509 } 26510 26511 if (!devstate_only) { 26512 struct sip_mailbox *mailbox; 26513 AST_LIST_TRAVERSE_SAFE_BEGIN(&peer->mailboxes, mailbox, entry) { 26514 if (mailbox->delme) { 26515 AST_LIST_REMOVE_CURRENT(entry); 26516 destroy_mailbox(mailbox); 26517 } 26518 } 26519 AST_LIST_TRAVERSE_SAFE_END; 26520 } 26521 26522 if (!can_parse_xml && (ast_get_cc_agent_policy(peer->cc_params) == AST_CC_AGENT_NATIVE)) { 26523 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); 26524 ast_set_cc_agent_policy(peer->cc_params, AST_CC_AGENT_NEVER); 26525 } 26526 26527 /* Note that Timer B is dependent upon T1 and MUST NOT be lower 26528 * than T1 * 64, according to RFC 3261, Section 17.1.1.2 */ 26529 if (peer->timer_b < peer->timer_t1 * 64) { 26530 if (timerb_set && timert1_set) { 26531 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); 26532 } else if (timerb_set) { 26533 if ((peer->timer_t1 = peer->timer_b / 64) < global_t1min) { 26534 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); 26535 peer->timer_t1 = global_t1min; 26536 peer->timer_b = peer->timer_t1 * 64; 26537 } 26538 peer->timer_t1 = peer->timer_b / 64; 26539 } else { 26540 peer->timer_b = peer->timer_t1 * 64; 26541 } 26542 } 26543 26544 if (!peer->default_outbound_transport) { 26545 /* Set default set of transports */ 26546 peer->transports = default_transports; 26547 /* Set default primary transport */ 26548 peer->default_outbound_transport = default_primary_transport; 26549 } 26550 26551 /* The default transport type set during build_peer should only replace the socket.type when... 26552 * 1. Registration is not present and the socket.type and default transport types are different. 26553 * 2. The socket.type is not an acceptable transport type after rebuilding peer. 26554 * 3. The socket.type is not set yet. */ 26555 if (((peer->socket.type != peer->default_outbound_transport) && (peer->expire == -1)) || 26556 !(peer->socket.type & peer->transports) || !(peer->socket.type)) { 26557 26558 set_socket_transport(&peer->socket, peer->default_outbound_transport); 26559 } 26560 26561 if (ast_str_strlen(fullcontact)) { 26562 ast_string_field_set(peer, fullcontact, ast_str_buffer(fullcontact)); 26563 peer->rt_fromcontact = TRUE; 26564 /* We have a hostname in the fullcontact, but if we don't have an 26565 * address listed on the entry (or if it's 'dynamic'), then we need to 26566 * parse the entry to obtain the IP address, so a dynamic host can be 26567 * contacted immediately after reload (as opposed to waiting for it to 26568 * register once again). But if we have an address for this peer and NAT was 26569 * specified, use that address instead. */ 26570 /* XXX May need to revisit the final argument; does the realtime DB store whether 26571 * the original contact was over TLS or not? XXX */ 26572 if (!ast_test_flag(&peer->flags[0], SIP_NAT_RPORT_PRESENT) || ast_sockaddr_isnull(&peer->addr)) { 26573 __set_address_from_contact(fullcontact->str, &peer->addr, 0); 26574 } 26575 } 26576 26577 if (srvlookup && peer->dnsmgr == NULL) { 26578 char transport[MAXHOSTNAMELEN]; 26579 char _srvlookup[MAXHOSTNAMELEN]; 26580 char *params; 26581 26582 ast_copy_string(_srvlookup, srvlookup, sizeof(_srvlookup)); 26583 if ((params = strchr(_srvlookup, ';'))) { 26584 *params++ = '\0'; 26585 } 26586 26587 snprintf(transport, sizeof(transport), "_%s._%s", get_srv_service(peer->socket.type), get_srv_protocol(peer->socket.type)); 26588 26589 peer->addr.ss.ss_family = get_address_family_filter(&bindaddr); /* Filter address family */ 26590 if (ast_dnsmgr_lookup(_srvlookup, &peer->addr, &peer->dnsmgr, sip_cfg.srvlookup && !peer->portinuri ? transport : NULL)) { 26591 ast_log(LOG_ERROR, "srvlookup failed for host: %s, on peer %s, removing peer\n", _srvlookup, peer->name); 26592 unref_peer(peer, "getting rid of a peer pointer"); 26593 return NULL; 26594 } 26595 26596 ast_string_field_set(peer, tohost, srvlookup); 26597 26598 if (global_dynamic_exclude_static) { 26599 int err = 0; 26600 sip_cfg.contact_ha = ast_append_ha("deny", ast_sockaddr_stringify_addr(&peer->addr), 26601 sip_cfg.contact_ha, &err); 26602 if (err) { 26603 ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value); 26604 } 26605 } 26606 } else if (peer->dnsmgr && !peer->host_dynamic) { 26607 /* force a refresh here on reload if dnsmgr already exists and host is set. */ 26608 ast_dnsmgr_refresh(peer->dnsmgr); 26609 } 26610 26611 if (port && !realtime && peer->host_dynamic) { 26612 ast_sockaddr_set_port(&peer->defaddr, port); 26613 } else if (port) { 26614 ast_sockaddr_set_port(&peer->addr, port); 26615 } 26616 26617 if (ast_sockaddr_port(&peer->addr) == 0) { 26618 ast_sockaddr_set_port(&peer->addr, 26619 (peer->socket.type & SIP_TRANSPORT_TLS) ? 26620 STANDARD_TLS_PORT : STANDARD_SIP_PORT); 26621 } 26622 if (ast_sockaddr_port(&peer->defaddr) == 0) { 26623 ast_sockaddr_set_port(&peer->defaddr, 26624 (peer->socket.type & SIP_TRANSPORT_TLS) ? 26625 STANDARD_TLS_PORT : STANDARD_SIP_PORT); 26626 } 26627 if (!peer->socket.port) { 26628 peer->socket.port = htons(((peer->socket.type & SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT)); 26629 } 26630 26631 if (!sip_cfg.ignore_regexpire && peer->host_dynamic && realtime) { 26632 time_t nowtime = time(NULL); 26633 26634 if ((nowtime - regseconds) > 0) { 26635 destroy_association(peer); 26636 memset(&peer->addr, 0, sizeof(peer->addr)); 26637 peer->lastms = -1; 26638 ast_debug(1, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 26639 } 26640 } 26641 26642 /* Startup regular pokes */ 26643 if (!devstate_only && realtime && peer->lastms > 0) { 26644 ref_peer(peer, "schedule qualify"); 26645 sip_poke_peer(peer, 0); 26646 } 26647 26648 ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags); 26649 ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags); 26650 ast_copy_flags(&peer->flags[2], &peerflags[2], mask[2].flags); 26651 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) { 26652 sip_cfg.allowsubscribe = TRUE; /* No global ban any more */ 26653 } 26654 if (peer->host_dynamic && !peer->is_realtime) { 26655 reg_source_db(peer); 26656 } 26657 26658 /* If they didn't request that MWI is sent *only* on subscribe, go ahead and 26659 * subscribe to it now. */ 26660 if (!devstate_only && !ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) && 26661 !AST_LIST_EMPTY(&peer->mailboxes)) { 26662 add_peer_mwi_subs(peer); 26663 /* Send MWI from the event cache only. This is so we can send initial 26664 * MWI if app_voicemail got loaded before chan_sip. If it is the other 26665 * way, then we will get events when app_voicemail gets loaded. */ 26666 sip_send_mwi_to_peer(peer, NULL, 1); 26667 } 26668 26669 peer->the_mark = 0; 26670 26671 ast_free_ha(oldha); 26672 ast_free_ha(olddirectmediaha); 26673 if (!ast_strlen_zero(callback)) { /* build string from peer info */ 26674 char *reg_string; 26675 if (asprintf(®_string, "%s?%s:%s@%s/%s", peer->name, peer->username, !ast_strlen_zero(peer->remotesecret) ? peer->remotesecret : peer->secret, peer->tohost, callback) < 0) { 26676 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno)); 26677 } else if (reg_string) { 26678 sip_register(reg_string, 0); /* XXX TODO: count in registry_count */ 26679 ast_free(reg_string); 26680 } 26681 } 26682 return peer; 26683 }
| static int build_reply_digest | ( | struct sip_pvt * | p, | |
| int | method, | |||
| char * | digest, | |||
| int | digest_len | |||
| ) | [static] |
Build reply digest.
Definition at line 18352 of file chan_sip.c.
References append_history, ast_copy_string(), ast_debug, ast_md5_hash(), ast_random(), ast_sockaddr_stringify_host(), ast_strlen_zero(), authl, find_realm_authentication(), secret, and sip_methods.
Referenced by reply_digest(), transmit_register(), and transmit_request_with_auth().
18353 { 18354 char a1[256]; 18355 char a2[256]; 18356 char a1_hash[256]; 18357 char a2_hash[256]; 18358 char resp[256]; 18359 char resp_hash[256]; 18360 char uri[256]; 18361 char opaque[256] = ""; 18362 char cnonce[80]; 18363 const char *username; 18364 const char *secret; 18365 const char *md5secret; 18366 struct sip_auth *auth = NULL; /* Realm authentication */ 18367 18368 if (!ast_strlen_zero(p->domain)) 18369 ast_copy_string(uri, p->domain, sizeof(uri)); 18370 else if (!ast_strlen_zero(p->uri)) 18371 ast_copy_string(uri, p->uri, sizeof(uri)); 18372 else 18373 snprintf(uri, sizeof(uri), "sip:%s@%s", p->username, ast_sockaddr_stringify_host(&p->sa)); 18374 18375 snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random()); 18376 18377 /* Check if we have separate auth credentials */ 18378 if(!(auth = find_realm_authentication(p->peerauth, p->realm))) /* Start with peer list */ 18379 auth = find_realm_authentication(authl, p->realm); /* If not, global list */ 18380 18381 if (auth) { 18382 ast_debug(3, "use realm [%s] from peer [%s][%s]\n", auth->username, p->peername, p->username); 18383 username = auth->username; 18384 secret = auth->secret; 18385 md5secret = auth->md5secret; 18386 if (sipdebug) 18387 ast_debug(1, "Using realm %s authentication for call %s\n", p->realm, p->callid); 18388 } else { 18389 /* No authentication, use peer or register= config */ 18390 username = p->authname; 18391 secret = p->peersecret; 18392 md5secret = p->peermd5secret; 18393 } 18394 if (ast_strlen_zero(username)) /* We have no authentication */ 18395 return -1; 18396 18397 /* Calculate SIP digest response */ 18398 snprintf(a1, sizeof(a1), "%s:%s:%s", username, p->realm, secret); 18399 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[method].text, uri); 18400 if (!ast_strlen_zero(md5secret)) 18401 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 18402 else 18403 ast_md5_hash(a1_hash, a1); 18404 ast_md5_hash(a2_hash, a2); 18405 18406 p->noncecount++; 18407 if (!ast_strlen_zero(p->qop)) 18408 snprintf(resp, sizeof(resp), "%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash); 18409 else 18410 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, p->nonce, a2_hash); 18411 ast_md5_hash(resp_hash, resp); 18412 18413 /* only include the opaque string if it's set */ 18414 if (!ast_strlen_zero(p->opaque)) { 18415 snprintf(opaque, sizeof(opaque), ", opaque=\"%s\"", p->opaque); 18416 } 18417 18418 /* XXX We hard code our qop to "auth" for now. XXX */ 18419 if (!ast_strlen_zero(p->qop)) 18420 snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\"%s, qop=auth, cnonce=\"%s\", nc=%08x", username, p->realm, uri, p->nonce, resp_hash, opaque, cnonce, p->noncecount); 18421 else 18422 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); 18423 18424 append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount); 18425 18426 return 0; 18427 }
| static void build_route | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| int | backwards | |||
| ) | [static] |
Build route list from Record-Route header.
Definition at line 13463 of file chan_sip.c.
References __get_header(), ast_copy_string(), ast_debug, ast_malloc, ast_strlen_zero(), free_old_route(), get_header(), len(), list_route(), and sip_debug_test_pvt().
Referenced by build_user_routes(), handle_request_invite(), handle_request_subscribe(), and handle_response_invite().
13464 { 13465 struct sip_route *thishop, *head, *tail; 13466 int start = 0; 13467 int len; 13468 const char *rr, *contact, *c; 13469 13470 /* Once a persistent route is set, don't fool with it */ 13471 if (p->route && p->route_persistent) { 13472 ast_debug(1, "build_route: Retaining previous route: <%s>\n", p->route->hop); 13473 return; 13474 } 13475 13476 if (p->route) { 13477 free_old_route(p->route); 13478 p->route = NULL; 13479 } 13480 13481 /* We only want to create the route set the first time this is called */ 13482 p->route_persistent = 1; 13483 13484 /* Build a tailq, then assign it to p->route when done. 13485 * If backwards, we add entries from the head so they end up 13486 * in reverse order. However, we do need to maintain a correct 13487 * tail pointer because the contact is always at the end. 13488 */ 13489 head = NULL; 13490 tail = head; 13491 /* 1st we pass through all the hops in any Record-Route headers */ 13492 for (;;) { 13493 /* Each Record-Route header */ 13494 rr = __get_header(req, "Record-Route", &start); 13495 if (*rr == '\0') { 13496 break; 13497 } 13498 for (; (rr = strchr(rr, '<')) ; rr += len) { /* Each route entry */ 13499 ++rr; 13500 len = strcspn(rr, ">") + 1; 13501 /* Make a struct route */ 13502 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 13503 /* ast_calloc is not needed because all fields are initialized in this block */ 13504 ast_copy_string(thishop->hop, rr, len); 13505 ast_debug(2, "build_route: Record-Route hop: <%s>\n", thishop->hop); 13506 /* Link in */ 13507 if (backwards) { 13508 /* Link in at head so they end up in reverse order */ 13509 thishop->next = head; 13510 head = thishop; 13511 /* If this was the first then it'll be the tail */ 13512 if (!tail) { 13513 tail = thishop; 13514 } 13515 } else { 13516 thishop->next = NULL; 13517 /* Link in at the end */ 13518 if (tail) { 13519 tail->next = thishop; 13520 } else { 13521 head = thishop; 13522 } 13523 tail = thishop; 13524 } 13525 } 13526 } 13527 } 13528 13529 /* Only append the contact if we are dealing with a strict router */ 13530 if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop, ";lr") == NULL) ) { 13531 /* 2nd append the Contact: if there is one */ 13532 /* Can be multiple Contact headers, comma separated values - we just take the first */ 13533 contact = get_header(req, "Contact"); 13534 if (!ast_strlen_zero(contact)) { 13535 ast_debug(2, "build_route: Contact hop: %s\n", contact); 13536 /* Look for <: delimited address */ 13537 c = strchr(contact, '<'); 13538 if (c) { 13539 /* Take to > */ 13540 ++c; 13541 len = strcspn(c, ">") + 1; 13542 } else { 13543 /* No <> - just take the lot */ 13544 c = contact; 13545 len = strlen(contact) + 1; 13546 } 13547 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 13548 /* ast_calloc is not needed because all fields are initialized in this block */ 13549 ast_copy_string(thishop->hop, c, len); 13550 thishop->next = NULL; 13551 /* Goes at the end */ 13552 if (tail) { 13553 tail->next = thishop; 13554 } else { 13555 head = thishop; 13556 } 13557 } 13558 } 13559 } 13560 13561 /* Store as new route */ 13562 p->route = head; 13563 13564 /* For debugging dump what we ended up with */ 13565 if (sip_debug_test_pvt(p)) { 13566 list_route(p->route); 13567 } 13568 }
| static void build_via | ( | struct sip_pvt * | p | ) | [static] |
Build a Via header for a request.
Definition at line 3287 of file chan_sip.c.
References ast_sockaddr_stringify(), ast_test_flag, and get_transport_pvt().
Referenced by __sip_subscribe_mwi_do(), reqprep(), sip_alloc(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_invite(), transmit_register(), and transmit_response_using_temp().
03288 { 03289 /* Work around buggy UNIDEN UIP200 firmware */ 03290 const char *rport = (ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT) || ast_test_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT)) ? ";rport" : ""; 03291 03292 /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ 03293 snprintf(p->via, sizeof(p->via), "SIP/2.0/%s %s;branch=z9hG4bK%08x%s", 03294 get_transport_pvt(p), 03295 ast_sockaddr_stringify(&p->ourip), 03296 (int) p->branch, rport); 03297 }
| static int cb_extensionstate | ( | char * | context, | |
| char * | exten, | |||
| int | state, | |||
| void * | data | |||
| ) | [static] |
Callback for the devicestate notification (SUBSCRIBE) support subsystem.
Definition at line 13838 of file chan_sip.c.
References append_history, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_REMOVED, ast_extension_state2str(), ast_set_flag, ast_test_flag, ast_verb, FALSE, NONE, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), and transmit_state_notify().
Referenced by handle_request_subscribe(), handle_response(), and handle_response_notify().
13839 { 13840 struct sip_pvt *p = data; 13841 13842 sip_pvt_lock(p); 13843 13844 switch(state) { 13845 case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ 13846 case AST_EXTENSION_REMOVED: /* Extension is gone */ 13847 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); /* Delete subscription in 32 secs */ 13848 ast_verb(2, "Extension state: Watcher for hint %s %s. Notify User %s\n", exten, state == AST_EXTENSION_DEACTIVATED ? "deactivated" : "removed", p->username); 13849 p->stateid = -1; 13850 p->subscribed = NONE; 13851 append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated"); 13852 break; 13853 default: /* Tell user */ 13854 p->laststate = state; 13855 break; 13856 } 13857 if (p->subscribed != NONE) { /* Only send state NOTIFY if we know the format */ 13858 if (!p->pendinginvite) { 13859 transmit_state_notify(p, state, 1, FALSE); 13860 } else { 13861 /* We already have a NOTIFY sent that is not answered. Queue the state up. 13862 if many state changes happen meanwhile, we will only send a notification of the last one */ 13863 ast_set_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 13864 } 13865 } 13866 ast_verb(2, "Extension Changed %s[%s] new state %s for Notify User %s %s\n", exten, context, ast_extension_state2str(state), p->username, 13867 ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE) ? "(queued)" : ""); 13868 13869 sip_pvt_unlock(p); 13870 13871 return 0; 13872 }
| static void cc_epa_destructor | ( | void * | data | ) | [static] |
Definition at line 876 of file chan_sip.c.
References ast_free.
00877 { 00878 struct sip_epa_entry *epa_entry = data; 00879 struct cc_epa_entry *cc_entry = epa_entry->instance_data; 00880 ast_free(cc_entry); 00881 }
| 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 23025 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(), LOG_NOTICE, LOG_WARNING, ast_cc_agent::private_data, sip_pidf_validate(), transmit_response(), and TRUE.
23026 { 23027 const char *uri = REQ_OFFSET_TO_STR(req, rlPart2); 23028 struct ast_cc_agent *agent = find_sip_cc_agent_by_notify_uri(uri); 23029 struct sip_cc_agent_pvt *agent_pvt; 23030 struct ast_xml_doc *pidf_doc = NULL; 23031 const char *basic_status = NULL; 23032 struct ast_xml_node *presence_node; 23033 struct ast_xml_node *presence_children; 23034 struct ast_xml_node *tuple_node; 23035 struct ast_xml_node *tuple_children; 23036 struct ast_xml_node *status_node; 23037 struct ast_xml_node *status_children; 23038 struct ast_xml_node *basic_node; 23039 int res = 0; 23040 23041 if (!agent) { 23042 ast_log(LOG_WARNING, "Could not find agent using uri '%s'\n", uri); 23043 transmit_response(pvt, "412 Conditional Request Failed", req); 23044 return -1; 23045 } 23046 23047 agent_pvt = agent->private_data; 23048 23049 if (sip_pidf_validate(req, &pidf_doc) == FALSE) { 23050 res = -1; 23051 goto cc_publish_cleanup; 23052 } 23053 23054 /* It's important to note that the PIDF validation routine has no knowledge 23055 * of what we specifically want in this instance. A valid PIDF document could 23056 * have no tuples, or it could have tuples whose status element has no basic 23057 * element contained within. While not violating the PIDF spec, these are 23058 * insufficient for our needs in this situation 23059 */ 23060 presence_node = ast_xml_get_root(pidf_doc); 23061 if (!(presence_children = ast_xml_node_get_children(presence_node))) { 23062 ast_log(LOG_WARNING, "No tuples within presence element.\n"); 23063 res = -1; 23064 goto cc_publish_cleanup; 23065 } 23066 23067 if (!(tuple_node = ast_xml_find_element(presence_children, "tuple", NULL, NULL))) { 23068 ast_log(LOG_NOTICE, "Couldn't find tuple node?\n"); 23069 res = -1; 23070 goto cc_publish_cleanup; 23071 } 23072 23073 /* We already made sure that the tuple has a status node when we validated the PIDF 23074 * document earlier. So there's no need to enclose this operation in an if statement. 23075 */ 23076 tuple_children = ast_xml_node_get_children(tuple_node); 23077 status_node = ast_xml_find_element(tuple_children, "status", NULL, NULL); 23078 23079 if (!(status_children = ast_xml_node_get_children(status_node))) { 23080 ast_log(LOG_WARNING, "No basic elements within status element.\n"); 23081 res = -1; 23082 goto cc_publish_cleanup; 23083 } 23084 23085 if (!(basic_node = ast_xml_find_element(status_children, "basic", NULL, NULL))) { 23086 ast_log(LOG_WARNING, "Couldn't find basic node?\n"); 23087 res = -1; 23088 goto cc_publish_cleanup; 23089 } 23090 23091 basic_status = ast_xml_get_text(basic_node); 23092 23093 if (ast_strlen_zero(basic_status)) { 23094 ast_log(LOG_NOTICE, "NOthing in basic node?\n"); 23095 res = -1; 23096 goto cc_publish_cleanup; 23097 } 23098 23099 if (!strcmp(basic_status, "open")) { 23100 agent_pvt->is_available = TRUE; 23101 ast_cc_agent_caller_available(agent->core_id, "Received PUBLISH stating SIP caller %s is available", 23102 agent->device_name); 23103 } else if (!strcmp(basic_status, "closed")) { 23104 agent_pvt->is_available = FALSE; 23105 ast_cc_agent_caller_busy(agent->core_id, "Received PUBLISH stating SIP caller %s is busy", 23106 agent->device_name); 23107 } else { 23108 ast_log(LOG_NOTICE, "Invalid content in basic element: %s\n", basic_status); 23109 } 23110 23111 cc_publish_cleanup: 23112 if (basic_status) { 23113 ast_xml_free_text(basic_status); 23114 } 23115 if (pidf_doc) { 23116 ast_xml_close(pidf_doc); 23117 } 23118 ao2_ref(agent, -1); 23119 if (res) { 23120 transmit_response(pvt, "400 Bad Request", req); 23121 } 23122 return res; 23123 }
| 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 18938 of file chan_sip.c.
References ao2_callback, ao2_ref, ast_cc_monitor_failed(), ast_log(), ast_strlen_zero(), FALSE, find_sip_monitor_instance_by_suspension_entry(), get_header(), LOG_WARNING, sip_monitor_instances, and transmit_invite().
18939 { 18940 struct cc_epa_entry *cc_entry = epa_entry->instance_data; 18941 struct sip_monitor_instance *monitor_instance = ao2_callback(sip_monitor_instances, 0, 18942 find_sip_monitor_instance_by_suspension_entry, epa_entry); 18943 const char *min_expires; 18944 18945 if (!monitor_instance) { 18946 ast_log(LOG_WARNING, "Can't find monitor_instance corresponding to epa_entry %p.\n", epa_entry); 18947 return; 18948 } 18949 18950 if (resp != 423) { 18951 ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->device_name, 18952 "Received error response to our PUBLISH"); 18953 ao2_ref(monitor_instance, -1); 18954 return; 18955 } 18956 18957 /* Allrighty, the other end doesn't like our Expires value. They think it's 18958 * too small, so let's see if they've provided a more sensible value. If they 18959 * haven't, then we'll just double our Expires value and see if they like that 18960 * instead. 18961 * 18962 * XXX Ideally this logic could be placed into its own function so that SUBSCRIBE, 18963 * PUBLISH, and REGISTER could all benefit from the same shared code. 18964 */ 18965 min_expires = get_header(req, "Min-Expires"); 18966 if (ast_strlen_zero(min_expires)) { 18967 pvt->expiry *= 2; 18968 if (pvt->expiry < 0) { 18969 /* You dork! You overflowed! */ 18970 ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->device_name, 18971 "PUBLISH expiry overflowed"); 18972 ao2_ref(monitor_instance, -1); 18973 return; 18974 } 18975 } else if (sscanf(min_expires, "%d", &pvt->expiry) != 1) { 18976 ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->device_name, 18977 "Min-Expires has non-numeric value"); 18978 ao2_ref(monitor_instance, -1); 18979 return; 18980 } 18981 /* At this point, we have most certainly changed pvt->expiry, so try transmitting 18982 * again 18983 */ 18984 transmit_invite(pvt, SIP_PUBLISH, FALSE, 0, NULL); 18985 ao2_ref(monitor_instance, -1); 18986 }
| 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 8210 of file chan_sip.c.
References append_history, ast_clear_flag, ast_set_flag, ast_test_flag, EVENT_FLAG_CALL, manager_event, sip_cfg, and sip_peer_hold().
Referenced by handle_request_invite(), and process_sdp().
08211 { 08212 if (sip_cfg.notifyhold && (!holdstate || !ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD))) 08213 sip_peer_hold(dialog, holdstate); 08214 if (sip_cfg.callevents) 08215 manager_event(EVENT_FLAG_CALL, "Hold", 08216 "Status: %s\r\n" 08217 "Channel: %s\r\n" 08218 "Uniqueid: %s\r\n", 08219 holdstate ? "On" : "Off", 08220 dialog->owner->name, 08221 dialog->owner->uniqueid); 08222 append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", req->data->str); 08223 if (!holdstate) { /* Put off remote hold */ 08224 ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */ 08225 return; 08226 } 08227 /* No address for RTP, we're on hold */ 08228 08229 if (sendonly == 1) /* One directional hold (sendonly/recvonly) */ 08230 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR); 08231 else if (sendonly == 2) /* Inactive stream */ 08232 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE); 08233 else 08234 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE); 08235 return; 08236 }
| 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 18675 of file chan_sip.c.
References ast_debug, ast_free, AST_REDIRECTING_REASON_UNCONDITIONAL, ast_strdup, ast_strlen_zero(), ast_party_redirecting::from, get_header(), get_rdnis(), ast_party_id::name, ast_party_id::number, parse_moved_contact(), ast_party_redirecting::reason, ast_party_name::str, ast_party_number::str, ast_party_id::tag, ast_party_redirecting::to, update_redirecting(), ast_party_name::valid, and ast_party_number::valid.
Referenced by handle_request_invite(), handle_response(), and handle_response_invite().
18678 { 18679 char *redirecting_from_name = NULL; 18680 char *redirecting_from_number = NULL; 18681 char *redirecting_to_name = NULL; 18682 char *redirecting_to_number = NULL; 18683 int reason = AST_REDIRECTING_REASON_UNCONDITIONAL; 18684 int is_response = req->method == SIP_RESPONSE; 18685 int res = 0; 18686 18687 res = get_rdnis(p, req, &redirecting_from_name, &redirecting_from_number, &reason); 18688 if (res == -1) { 18689 if (is_response) { 18690 get_name_and_number(get_header(req, "TO"), &redirecting_from_name, &redirecting_from_number); 18691 } else { 18692 return; 18693 } 18694 } 18695 18696 /* At this point, all redirecting "from" info should be filled in appropriately 18697 * on to the "to" info 18698 */ 18699 18700 if (is_response) { 18701 parse_moved_contact(p, req, &redirecting_to_name, &redirecting_to_number, set_call_forward); 18702 } else { 18703 get_name_and_number(get_header(req, "TO"), &redirecting_to_name, &redirecting_to_number); 18704 } 18705 18706 if (!ast_strlen_zero(redirecting_from_number)) { 18707 ast_debug(3, "Got redirecting from number %s\n", redirecting_from_number); 18708 update_redirecting->from.number = 1; 18709 redirecting->from.number.valid = 1; 18710 ast_free(redirecting->from.number.str); 18711 redirecting->from.number.str = redirecting_from_number; 18712 } 18713 if (!ast_strlen_zero(redirecting_from_name)) { 18714 ast_debug(3, "Got redirecting from name %s\n", redirecting_from_name); 18715 update_redirecting->from.name = 1; 18716 redirecting->from.name.valid = 1; 18717 ast_free(redirecting->from.name.str); 18718 redirecting->from.name.str = redirecting_from_name; 18719 } 18720 if (!ast_strlen_zero(p->cid_tag)) { 18721 ast_free(redirecting->from.tag); 18722 redirecting->from.tag = ast_strdup(p->cid_tag); 18723 ast_free(redirecting->to.tag); 18724 redirecting->to.tag = ast_strdup(p->cid_tag); 18725 } 18726 if (!ast_strlen_zero(redirecting_to_number)) { 18727 ast_debug(3, "Got redirecting to number %s\n", redirecting_to_number); 18728 update_redirecting->to.number = 1; 18729 redirecting->to.number.valid = 1; 18730 ast_free(redirecting->to.number.str); 18731 redirecting->to.number.str = redirecting_to_number; 18732 } 18733 if (!ast_strlen_zero(redirecting_to_name)) { 18734 ast_debug(3, "Got redirecting to name %s\n", redirecting_from_number); 18735 update_redirecting->to.name = 1; 18736 redirecting->to.name.valid = 1; 18737 ast_free(redirecting->to.name.str); 18738 redirecting->to.name.str = redirecting_to_name; 18739 } 18740 redirecting->reason = reason; 18741 }
| static void change_t38_state | ( | struct sip_pvt * | p, | |
| int | state | |||
| ) | [static] |
Change the T38 state on a SIP dialog.
Definition at line 4867 of file chan_sip.c.
References AST_CONTROL_T38_PARAMETERS, ast_debug, ast_queue_control_data(), AST_T38_NEGOTIATED, AST_T38_REFUSED, AST_T38_REQUEST_NEGOTIATE, AST_T38_TERMINATED, ast_udptl_get_far_max_ifp(), ast_udptl_set_tag(), ast_control_t38_parameters::max_ifp, ast_channel::name, and ast_control_t38_parameters::request_response.
Referenced by handle_response_invite(), interpret_t38_parameters(), process_sdp(), and sip_t38_abort().
04868 { 04869 int old = p->t38.state; 04870 struct ast_channel *chan = p->owner; 04871 struct ast_control_t38_parameters parameters = { .request_response = 0 }; 04872 04873 /* Don't bother changing if we are already in the state wanted */ 04874 if (old == state) 04875 return; 04876 04877 p->t38.state = state; 04878 ast_debug(2, "T38 state changed to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>"); 04879 04880 /* If no channel was provided we can't send off a control frame */ 04881 if (!chan) 04882 return; 04883 04884 /* Given the state requested and old state determine what control frame we want to queue up */ 04885 switch (state) { 04886 case T38_PEER_REINVITE: 04887 parameters = p->t38.their_parms; 04888 parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl); 04889 parameters.request_response = AST_T38_REQUEST_NEGOTIATE; 04890 ast_udptl_set_tag(p->udptl, "SIP/%s", p->username); 04891 break; 04892 case T38_ENABLED: 04893 parameters = p->t38.their_parms; 04894 parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl); 04895 parameters.request_response = AST_T38_NEGOTIATED; 04896 ast_udptl_set_tag(p->udptl, "SIP/%s", p->username); 04897 break; 04898 case T38_DISABLED: 04899 if (old == T38_ENABLED) { 04900 parameters.request_response = AST_T38_TERMINATED; 04901 } else if (old == T38_LOCAL_REINVITE) { 04902 parameters.request_response = AST_T38_REFUSED; 04903 } 04904 break; 04905 case T38_LOCAL_REINVITE: 04906 /* wait until we get a peer response before responding to local reinvite */ 04907 break; 04908 } 04909 04910 /* Woot we got a message, create a control frame and send it on! */ 04911 if (parameters.request_response) 04912 ast_queue_control_data(chan, AST_CONTROL_T38_PARAMETERS, ¶meters, sizeof(parameters)); 04913 }
| static enum check_auth_result check_auth | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| const char * | username, | |||
| const char * | secret, | |||
| const char * | md5secret, | |||
| int | sipmethod, | |||
| const char * | uri, | |||
| enum xmittype | reliable, | |||
| int | ignore | |||
| ) | [static] |
Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set).
XXX
XXX
Definition at line 13592 of file chan_sip.c.
References AST_DYNSTR_BUILD_FAILED, ast_skip_blanks(), ast_str_set(), ast_str_thread_get(), ast_strlen_zero(), auth_headers(), check_auth_buf, CHECK_AUTH_BUF_INITLEN, FALSE, get_header(), set_nonce_randdata(), sip_scheddestroy(), strsep(), and transmit_response_with_auth().
Referenced by check_peer_ok(), and register_verify().
13595 { 13596 const char *response; 13597 char *reqheader, *respheader; 13598 const char *authtoken; 13599 char a1_hash[256]; 13600 char resp_hash[256]=""; 13601 char *c; 13602 int wrongnonce = FALSE; 13603 int good_response; 13604 const char *usednonce = p->randdata; 13605 struct ast_str *buf; 13606 int res; 13607 13608 /* table of recognised keywords, and their value in the digest */ 13609 enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST }; 13610 struct x { 13611 const char *key; 13612 const char *s; 13613 } *i, keys[] = { 13614 [K_RESP] = { "response=", "" }, 13615 [K_URI] = { "uri=", "" }, 13616 [K_USER] = { "username=", "" }, 13617 [K_NONCE] = { "nonce=", "" }, 13618 [K_LAST] = { NULL, NULL} 13619 }; 13620 13621 /* Always OK if no secret */ 13622 if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret)) 13623 return AUTH_SUCCESSFUL; 13624 13625 /* Always auth with WWW-auth since we're NOT a proxy */ 13626 /* Using proxy-auth in a B2BUA may block proxy authorization in the same transaction */ 13627 response = "401 Unauthorized"; 13628 13629 /* 13630 * Note the apparent swap of arguments below, compared to other 13631 * usages of auth_headers(). 13632 */ 13633 auth_headers(WWW_AUTH, &respheader, &reqheader); 13634 13635 authtoken = get_header(req, reqheader); 13636 if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 13637 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 13638 information */ 13639 if (!reliable) { 13640 /* Resend message if this was NOT a reliable delivery. Otherwise the 13641 retransmission should get it */ 13642 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 13643 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 13644 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13645 } 13646 return AUTH_CHALLENGE_SENT; 13647 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 13648 /* We have no auth, so issue challenge and request authentication */ 13649 set_nonce_randdata(p, 1); /* Create nonce for challenge */ 13650 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 13651 /* Schedule auto destroy in 32 seconds */ 13652 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13653 return AUTH_CHALLENGE_SENT; 13654 } 13655 13656 /* --- We have auth, so check it */ 13657 13658 /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting 13659 an example in the spec of just what it is you're doing a hash on. */ 13660 13661 if (!(buf = ast_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) { 13662 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 13663 } 13664 13665 /* Make a copy of the response and parse it */ 13666 res = ast_str_set(&buf, 0, "%s", authtoken); 13667 13668 if (res == AST_DYNSTR_BUILD_FAILED) { 13669 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 13670 } 13671 13672 c = buf->str; 13673 13674 while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */ 13675 for (i = keys; i->key != NULL; i++) { 13676 const char *separator = ","; /* default */ 13677 13678 if (strncasecmp(c, i->key, strlen(i->key)) != 0) { 13679 continue; 13680 } 13681 /* Found. Skip keyword, take text in quotes or up to the separator. */ 13682 c += strlen(i->key); 13683 if (*c == '"') { /* in quotes. Skip first and look for last */ 13684 c++; 13685 separator = "\""; 13686 } 13687 i->s = c; 13688 strsep(&c, separator); 13689 break; 13690 } 13691 if (i->key == NULL) { /* not found, jump after space or comma */ 13692 strsep(&c, " ,"); 13693 } 13694 } 13695 13696 /* Verify that digest username matches the username we auth as */ 13697 if (strcmp(username, keys[K_USER].s)) { 13698 ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n", 13699 username, keys[K_USER].s); 13700 /* Oops, we're trying something here */ 13701 return AUTH_USERNAME_MISMATCH; 13702 } 13703 13704 /* Verify nonce from request matches our nonce, and the nonce has not already been responded to. 13705 * If this check fails, send 401 with new nonce */ 13706 if (strcasecmp(p->randdata, keys[K_NONCE].s) || p->stalenonce) { /* XXX it was 'n'casecmp ? */ 13707 wrongnonce = TRUE; 13708 usednonce = keys[K_NONCE].s; 13709 } else { 13710 p->stalenonce = 1; /* now, since the nonce has a response, mark it as stale so it can't be sent or responded to again */ 13711 } 13712 13713 if (!ast_strlen_zero(md5secret)) { 13714 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 13715 } else { 13716 char a1[256]; 13717 13718 snprintf(a1, sizeof(a1), "%s:%s:%s", username, p->realm, secret); 13719 ast_md5_hash(a1_hash, a1); 13720 } 13721 13722 /* compute the expected response to compare with what we received */ 13723 { 13724 char a2[256]; 13725 char a2_hash[256]; 13726 char resp[256]; 13727 13728 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, 13729 S_OR(keys[K_URI].s, uri)); 13730 ast_md5_hash(a2_hash, a2); 13731 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash); 13732 ast_md5_hash(resp_hash, resp); 13733 } 13734 13735 good_response = keys[K_RESP].s && 13736 !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash)); 13737 if (wrongnonce) { 13738 if (good_response) { 13739 if (sipdebug) 13740 ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "From")); 13741 /* We got working auth token, based on stale nonce . */ 13742 set_nonce_randdata(p, 0); 13743 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE); 13744 } else { 13745 /* Everything was wrong, so give the device one more try with a new challenge */ 13746 if (!req->ignore) { 13747 if (sipdebug) { 13748 ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To")); 13749 } 13750 set_nonce_randdata(p, 1); 13751 } else { 13752 if (sipdebug) { 13753 ast_log(LOG_NOTICE, "Duplicate authentication received from '%s'\n", get_header(req, "To")); 13754 } 13755 } 13756 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 13757 } 13758 13759 /* Schedule auto destroy in 32 seconds */ 13760 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13761 return AUTH_CHALLENGE_SENT; 13762 } 13763 if (good_response) { 13764 append_history(p, "AuthOK", "Auth challenge successful for %s", username); 13765 return AUTH_SUCCESSFUL; 13766 } 13767 13768 /* Ok, we have a bad username/secret pair */ 13769 /* Tell the UAS not to re-send this authentication data, because 13770 it will continue to fail 13771 */ 13772 13773 return AUTH_SECRET_FAILED; 13774 }
| 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 15160 of file chan_sip.c.
References accountcode, ao2_t_ref, ast_apply_ha(), ast_cc_copy_config_params(), ast_copy_flags, ast_debug, ast_is_shrinkable_phonenumber(), ast_rtp_codecs_packetization_set(), AST_RTP_DTMF, ast_rtp_instance_get_codecs(), ast_set_flag, ast_shrink_phone_number(), ast_sockaddr_stringify(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose, check_auth(), cid_name, cid_num, context, copy_vars(), debug, dialog_initialize_rtp(), do_setnat(), FALSE, find_peer(), get_rpid(), global_shrinkcallerid, global_t1min, language, mohinterpret, mohsuggest, parkinglot, set_pvt_allowed_methods(), set_t38_capabilities(), sip_debug_test_addr(), TRUE, and unref_peer().
Referenced by check_user_full().
15164 { 15165 enum check_auth_result res; 15166 int debug = sip_debug_test_addr(addr); 15167 struct sip_peer *peer; 15168 15169 if (sipmethod == SIP_SUBSCRIBE) { 15170 /* For subscribes, match on device name only; for other methods, 15171 * match on IP address-port of the incoming request. 15172 */ 15173 peer = find_peer(of, NULL, TRUE, FINDALLDEVICES, FALSE, 0); 15174 } else { 15175 /* First find devices based on username (avoid all type=peer's) */ 15176 peer = find_peer(of, NULL, TRUE, FINDUSERS, FALSE, 0); 15177 15178 /* Then find devices based on IP */ 15179 if (!peer) { 15180 peer = find_peer(NULL, &p->recv, TRUE, FINDPEERS, FALSE, p->socket.type); 15181 } 15182 } 15183 15184 if (!peer) { 15185 if (debug) { 15186 ast_verbose("No matching peer for '%s' from '%s'\n", 15187 of, ast_sockaddr_stringify(&p->recv)); 15188 } 15189 return AUTH_DONT_KNOW; 15190 } 15191 15192 if (!ast_apply_ha(peer->ha, addr)) { 15193 ast_debug(2, "Found peer '%s' for '%s', but fails host access\n", peer->name, of); 15194 unref_peer(peer, "unref_peer: check_peer_ok: from find_peer call, early return of AUTH_ACL_FAILED"); 15195 return AUTH_ACL_FAILED; 15196 } 15197 if (debug) 15198 ast_verbose("Found peer '%s' for '%s' from %s\n", 15199 peer->name, of, ast_sockaddr_stringify(&p->recv)); 15200 15201 /* XXX what about p->prefs = peer->prefs; ? */ 15202 /* Set Frame packetization */ 15203 if (p->rtp) { 15204 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &peer->prefs); 15205 p->autoframing = peer->autoframing; 15206 } 15207 15208 /* Take the peer */ 15209 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 15210 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 15211 ast_copy_flags(&p->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY); 15212 15213 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) && p->udptl) { 15214 p->t38_maxdatagram = peer->t38_maxdatagram; 15215 set_t38_capabilities(p); 15216 } 15217 15218 /* Copy SIP extensions profile to peer */ 15219 /* XXX is this correct before a successful auth ? */ 15220 if (p->sipoptions) 15221 peer->sipoptions = p->sipoptions; 15222 15223 do_setnat(p); 15224 15225 ast_string_field_set(p, peersecret, peer->secret); 15226 ast_string_field_set(p, peermd5secret, peer->md5secret); 15227 ast_string_field_set(p, subscribecontext, peer->subscribecontext); 15228 ast_string_field_set(p, mohinterpret, peer->mohinterpret); 15229 ast_string_field_set(p, mohsuggest, peer->mohsuggest); 15230 if (!ast_strlen_zero(peer->parkinglot)) { 15231 ast_string_field_set(p, parkinglot, peer->parkinglot); 15232 } 15233 ast_string_field_set(p, engine, peer->engine); 15234 p->disallowed_methods = peer->disallowed_methods; 15235 set_pvt_allowed_methods(p, req); 15236 ast_cc_copy_config_params(p->cc_params, peer->cc_params); 15237 if (peer->callingpres) /* Peer calling pres setting will override RPID */ 15238 p->callingpres = peer->callingpres; 15239 if (peer->maxms && peer->lastms) 15240 p->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 15241 else 15242 p->timer_t1 = peer->timer_t1; 15243 15244 /* Set timer B to control transaction timeouts */ 15245 if (peer->timer_b) 15246 p->timer_b = peer->timer_b; 15247 else 15248 p->timer_b = 64 * p->timer_t1; 15249 15250 if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) { 15251 /* Pretend there is no required authentication */ 15252 ast_string_field_set(p, peersecret, NULL); 15253 ast_string_field_set(p, peermd5secret, NULL); 15254 } 15255 if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, req->ignore))) { 15256 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 15257 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 15258 ast_copy_flags(&p->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY); 15259 /* If we have a call limit, set flag */ 15260 if (peer->call_limit) 15261 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 15262 ast_string_field_set(p, peername, peer->name); 15263 ast_string_field_set(p, authname, peer->name); 15264 15265 if (sipmethod == SIP_INVITE) { 15266 /* copy channel vars */ 15267 p->chanvars = copy_vars(peer->chanvars); 15268 } 15269 15270 if (authpeer) { 15271 ao2_t_ref(peer, 1, "copy pointer into (*authpeer)"); 15272 (*authpeer) = peer; /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */ 15273 } 15274 15275 if (!ast_strlen_zero(peer->username)) { 15276 ast_string_field_set(p, username, peer->username); 15277 /* Use the default username for authentication on outbound calls */ 15278 /* XXX this takes the name from the caller... can we override ? */ 15279 ast_string_field_set(p, authname, peer->username); 15280 } 15281 if (!get_rpid(p, req)) { 15282 if (!ast_strlen_zero(peer->cid_num)) { 15283 char *tmp = ast_strdupa(peer->cid_num); 15284 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) 15285 ast_shrink_phone_number(tmp); 15286 ast_string_field_set(p, cid_num, tmp); 15287 } 15288 if (!ast_strlen_zero(peer->cid_name)) 15289 ast_string_field_set(p, cid_name, peer->cid_name); 15290 if (!ast_strlen_zero(peer->cid_tag)) 15291 ast_string_field_set(p, cid_tag, peer->cid_tag); 15292 if (peer->callingpres) 15293 p->callingpres = peer->callingpres; 15294 } 15295 ast_string_field_set(p, fullcontact, peer->fullcontact); 15296 if (!ast_strlen_zero(peer->context)) 15297 ast_string_field_set(p, context, peer->context); 15298 ast_string_field_set(p, peersecret, peer->secret); 15299 ast_string_field_set(p, peermd5secret, peer->md5secret); 15300 ast_string_field_set(p, language, peer->language); 15301 ast_string_field_set(p, accountcode, peer->accountcode); 15302 p->amaflags = peer->amaflags; 15303 p->callgroup = peer->callgroup; 15304 p->pickupgroup = peer->pickupgroup; 15305 p->capability = peer->capability; 15306 p->prefs = peer->prefs; 15307 p->jointcapability = peer->capability; 15308 if (peer->maxforwards > 0) { 15309 p->maxforwards = peer->maxforwards; 15310 } 15311 if (p->peercapability) 15312 p->jointcapability &= p->peercapability; 15313 p->maxcallbitrate = peer->maxcallbitrate; 15314 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 15315 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 15316 p->noncodeccapability |= AST_RTP_DTMF; 15317 else 15318 p->noncodeccapability &= ~AST_RTP_DTMF; 15319 p->jointnoncodeccapability = p->noncodeccapability; 15320 if (!dialog_initialize_rtp(p)) { 15321 if (p->rtp) { 15322 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &peer->prefs); 15323 p->autoframing = peer->autoframing; 15324 } 15325 } else { 15326 res = AUTH_RTP_FAILED; 15327 } 15328 } 15329 unref_peer(peer, "check_peer_ok: unref_peer: tossing temp ptr to peer from find_peer"); 15330 return res; 15331 }
| static void check_pendings | ( | struct sip_pvt * | p | ) | [static] |
Check pending actions on SIP call.
Definition at line 18861 of file chan_sip.c.
References ast_clear_flag, ast_debug, AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), ast_test_flag, FALSE, sip_scheddestroy(), transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), and TRUE.
Referenced by handle_incoming(), handle_response_invite(), and sip_reinvite_retry().
18862 { 18863 if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 18864 /* if we can't BYE, then this is really a pending CANCEL */ 18865 if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) { 18866 p->invitestate = INV_CANCELLED; 18867 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 18868 /* Actually don't destroy us yet, wait for the 487 on our original 18869 INVITE, but do set an autodestruct just in case we never get it. */ 18870 } else { 18871 /* We have a pending outbound invite, don't send something 18872 new in-transaction */ 18873 if (p->pendinginvite) 18874 return; 18875 18876 if (p->owner) { 18877 ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV); 18878 } 18879 /* Perhaps there is an SD change INVITE outstanding */ 18880 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE); 18881 } 18882 ast_clear_flag(&p->flags[0], SIP_PENDINGBYE); 18883 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 18884 } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) { 18885 /* if we can't REINVITE, hold it for later */ 18886 if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) { 18887 ast_debug(2, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid); 18888 } else { 18889 ast_debug(2, "Sending pending reinvite on '%s'\n", p->callid); 18890 /* Didn't get to reinvite yet, so do it now */ 18891 transmit_reinvite_with_sdp(p, (p->t38.state == T38_LOCAL_REINVITE ? TRUE : FALSE), FALSE); 18892 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 18893 } 18894 } 18895 }
| static void check_rtp_timeout | ( | struct sip_pvt * | dialog, | |
| time_t | t | |||
| ) | [static] |
helper function for the monitoring thread -- seems to be called with the assumption that the dialog is locked
Definition at line 24601 of file chan_sip.c.
References ast_channel_trylock, ast_channel_unlock, ast_log(), ast_rtp_instance_get_hold_timeout(), ast_rtp_instance_get_timeout(), ast_rtp_instance_set_hold_timeout(), ast_rtp_instance_set_timeout(), ast_sockaddr_isnull(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, ast_test_flag, LOG_NOTICE, sip_pvt_lock, and sip_pvt_unlock.
Referenced by dialog_needdestroy().
24602 { 24603 /* If we have no RTP or no active owner, no need to check timers */ 24604 if (!dialog->rtp || !dialog->owner) 24605 return; 24606 /* If the call is not in UP state or redirected outside Asterisk, no need to check timers */ 24607 24608 if (dialog->owner->_state != AST_STATE_UP || !ast_sockaddr_isnull(&dialog->redirip)) 24609 return; 24610 24611 /* If the call is involved in a T38 fax session do not check RTP timeout */ 24612 if (dialog->t38.state == T38_ENABLED) 24613 return; 24614 24615 /* If we have no timers set, return now */ 24616 if (!ast_rtp_instance_get_timeout(dialog->rtp) && !ast_rtp_instance_get_hold_timeout(dialog->rtp)) { 24617 return; 24618 } 24619 24620 /*! \todo Check video RTP keepalives 24621 24622 Do we need to move the lastrtptx to the RTP structure to have one for audio and one 24623 for video? It really does belong to the RTP structure. 24624 */ 24625 24626 /* Check AUDIO RTP timers */ 24627 if (dialog->lastrtprx && (ast_rtp_instance_get_timeout(dialog->rtp) || ast_rtp_instance_get_hold_timeout(dialog->rtp)) && (t > dialog->lastrtprx + ast_rtp_instance_get_timeout(dialog->rtp))) { 24628 if (!ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD) || (ast_rtp_instance_get_hold_timeout(dialog->rtp) && (t > dialog->lastrtprx + ast_rtp_instance_get_hold_timeout(dialog->rtp)))) { 24629 /* Needs a hangup */ 24630 if (ast_rtp_instance_get_timeout(dialog->rtp)) { 24631 while (dialog->owner && ast_channel_trylock(dialog->owner)) { 24632 sip_pvt_unlock(dialog); 24633 usleep(1); 24634 sip_pvt_lock(dialog); 24635 } 24636 if (!dialog->owner) { 24637 return; /* channel hangup can occur during deadlock avoidance. */ 24638 } 24639 ast_log(LOG_NOTICE, "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", 24640 dialog->owner->name, (long) (t - dialog->lastrtprx)); 24641 /* Issue a softhangup */ 24642 ast_softhangup_nolock(dialog->owner, AST_SOFTHANGUP_DEV); 24643 ast_channel_unlock(dialog->owner); 24644 /* forget the timeouts for this call, since a hangup 24645 has already been requested and we don't want to 24646 repeatedly request hangups 24647 */ 24648 ast_rtp_instance_set_timeout(dialog->rtp, 0); 24649 ast_rtp_instance_set_hold_timeout(dialog->rtp, 0); 24650 if (dialog->vrtp) { 24651 ast_rtp_instance_set_timeout(dialog->vrtp, 0); 24652 ast_rtp_instance_set_hold_timeout(dialog->vrtp, 0); 24653 } 24654 } 24655 } 24656 } 24657 }
| 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 25753 of file chan_sip.c.
References ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_strlen_zero().
Referenced by func_check_sipdomain(), get_destination(), get_realm(), handle_request_refer(), and register_verify().
25754 { 25755 struct domain *d; 25756 int result = 0; 25757 25758 AST_LIST_LOCK(&domain_list); 25759 AST_LIST_TRAVERSE(&domain_list, d, list) { 25760 if (strcasecmp(d->domain, domain)) 25761 continue; 25762 25763 if (len && !ast_strlen_zero(d->context)) 25764 ast_copy_string(context, d->context, len); 25765 25766 result = 1; 25767 break; 25768 } 25769 AST_LIST_UNLOCK(&domain_list); 25770 25771 return result; 25772 }
| static int check_user | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| int | sipmethod, | |||
| const char * | uri, | |||
| enum xmittype | reliable, | |||
| struct ast_sockaddr * | addr | |||
| ) | [static] |
Find user If we get a match, this will add a reference pointer to the user object in ASTOBJ, that needs to be unreferenced.
Definition at line 15462 of file chan_sip.c.
References check_user_full().
Referenced by handle_request_options(), and handle_request_publish().
15463 { 15464 return check_user_full(p, req, sipmethod, uri, reliable, addr, NULL); 15465 }
| static enum check_auth_result check_user_full | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| int | sipmethod, | |||
| const char * | uri, | |||
| enum xmittype | reliable, | |||
| struct ast_sockaddr * | addr, | |||
| struct sip_peer ** | authpeer | |||
| ) | [static] |
Check if matching user or peer is defined Match user on From: user name and peer on IP/port This is used on first invite (not re-invites) and subscribe requests.
Definition at line 15339 of file chan_sip.c.
References ast_copy_string(), ast_is_shrinkable_phonenumber(), ast_log(), ast_set_flag, ast_shrink_phone_number(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, build_contact(), check_peer_ok(), cid_name, cid_num, dialog_initialize_rtp(), dummy(), exten, get_header(), get_rpid(), global_match_auth_username, global_shrinkcallerid, LOG_ERROR, LOG_NOTICE, sip_cfg, SIP_PEDANTIC_DECODE, strsep(), and terminate_uri().
Referenced by check_user(), handle_request_invite(), and handle_request_subscribe().
15342 { 15343 char from[256] = { 0, }; 15344 char *dummy = NULL; /* dummy return value for parse_uri */ 15345 char *domain = NULL; /* dummy return value for parse_uri */ 15346 char *of; 15347 enum check_auth_result res = AUTH_DONT_KNOW; 15348 char calleridname[50]; 15349 char *uri2 = ast_strdupa(uri); 15350 15351 terminate_uri(uri2); /* trim extra stuff */ 15352 15353 ast_copy_string(from, get_header(req, "From"), sizeof(from)); 15354 /* XXX here tries to map the username for invite things */ 15355 memset(calleridname, 0, sizeof(calleridname)); 15356 15357 /* strip the display-name portion off the beginning of the FROM header. */ 15358 if (!(of = (char *) get_calleridname(from, calleridname, sizeof(calleridname)))) { 15359 ast_log(LOG_ERROR, "FROM header can not be parsed \n"); 15360 return res; 15361 } 15362 15363 if (calleridname[0]) 15364 ast_string_field_set(p, cid_name, calleridname); 15365 15366 if (ast_strlen_zero(p->exten)) { 15367 char *t = uri2; 15368 if (!strncasecmp(t, "sip:", 4)) 15369 t+= 4; 15370 else if (!strncasecmp(t, "sips:", 5)) 15371 t += 5; 15372 ast_string_field_set(p, exten, t); 15373 t = strchr(p->exten, '@'); 15374 if (t) 15375 *t = '\0'; 15376 15377 if (ast_strlen_zero(p->our_contact)) 15378 build_contact(p); 15379 } 15380 15381 of = get_in_brackets(of); 15382 15383 /* save the URI part of the From header */ 15384 ast_string_field_set(p, from, of); 15385 15386 /* ignore all fields but name */ 15387 if (parse_uri(of, "sip:,sips:", &of, &dummy, &domain, NULL)) { 15388 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 15389 } 15390 15391 SIP_PEDANTIC_DECODE(of); 15392 SIP_PEDANTIC_DECODE(domain); 15393 15394 if (ast_strlen_zero(of)) { 15395 /* XXX note: the original code considered a missing @host 15396 * as a username-only URI. The SIP RFC (19.1.1) says that 15397 * this is wrong, and it should be considered as a domain-only URI. 15398 * For backward compatibility, we keep this block, but it is 15399 * really a mistake and should go away. 15400 */ 15401 of = domain; 15402 } else { 15403 char *tmp = ast_strdupa(of); 15404 /* We need to be able to handle auth-headers looking like 15405 <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43> 15406 */ 15407 tmp = strsep(&tmp, ";"); 15408 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) 15409 ast_shrink_phone_number(tmp); 15410 ast_string_field_set(p, cid_num, tmp); 15411 } 15412 15413 if (global_match_auth_username) { 15414 /* 15415 * XXX This is experimental code to grab the search key from the 15416 * Auth header's username instead of the 'From' name, if available. 15417 * Do not enable this block unless you understand the side effects (if any!) 15418 * Note, the search for "username" should be done in a more robust way. 15419 * Note2, at the moment we check both fields, though maybe we should 15420 * pick one or another depending on the request ? XXX 15421 */ 15422 const char *hdr = get_header(req, "Authorization"); 15423 if (ast_strlen_zero(hdr)) 15424 hdr = get_header(req, "Proxy-Authorization"); 15425 15426 if ( !ast_strlen_zero(hdr) && (hdr = strstr(hdr, "username=\"")) ) { 15427 ast_copy_string(from, hdr + strlen("username=\""), sizeof(from)); 15428 of = from; 15429 of = strsep(&of, "\""); 15430 } 15431 } 15432 15433 res = check_peer_ok(p, of, req, sipmethod, addr, 15434 authpeer, reliable, calleridname, uri2); 15435 if (res != AUTH_DONT_KNOW) 15436 return res; 15437 15438 /* Finally, apply the guest policy */ 15439 if (sip_cfg.allowguest) { 15440 get_rpid(p, req); 15441 if (!dialog_initialize_rtp(p)) { 15442 res = AUTH_SUCCESSFUL; 15443 } else { 15444 res = AUTH_RTP_FAILED; 15445 } 15446 } else if (sip_cfg.alwaysauthreject) 15447 res = AUTH_FAKE_AUTH; /* reject with fake authorization request */ 15448 else 15449 res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */ 15450 15451 15452 if (ast_test_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT)) { 15453 ast_set_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT); 15454 } 15455 15456 return res; 15457 }
| static void check_via | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
check Via: header for hostname, port and rport request/answer
Definition at line 15099 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_set_flag, ast_skip_blanks(), ast_sockaddr_port, ast_sockaddr_resolve_first(), ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_verbose, get_header(), LOG_WARNING, sip_debug_test_pvt(), sip_nat_mode(), and sip_real_dst().
Referenced by handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_register(), and handle_request_subscribe().
15100 { 15101 char via[512]; 15102 char *c, *maddr; 15103 struct ast_sockaddr tmp; 15104 uint16_t port; 15105 15106 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 15107 15108 /* Work on the leftmost value of the topmost Via header */ 15109 c = strchr(via, ','); 15110 if (c) 15111 *c = '\0'; 15112 15113 /* Check for rport */ 15114 c = strstr(via, ";rport"); 15115 if (c && (c[6] != '=')) { /* rport query, not answer */ 15116 ast_set_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT); 15117 ast_set_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT); 15118 } 15119 15120 /* Check for maddr */ 15121 maddr = strstr(via, "maddr="); 15122 if (maddr) { 15123 maddr += 6; 15124 c = maddr + strspn(maddr, "abcdefghijklmnopqrstuvwxyz" 15125 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.:[]"); 15126 *c = '\0'; 15127 } 15128 15129 c = strchr(via, ';'); 15130 if (c) 15131 *c = '\0'; 15132 15133 c = strchr(via, ' '); 15134 if (c) { 15135 *c = '\0'; 15136 c = ast_skip_blanks(c+1); 15137 if (strcasecmp(via, "SIP/2.0/UDP") && strcasecmp(via, "SIP/2.0/TCP") && strcasecmp(via, "SIP/2.0/TLS")) { 15138 ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via); 15139 return; 15140 } 15141 15142 if (maddr && ast_sockaddr_resolve_first(&p->sa, maddr, 0)) { 15143 p->sa = p->recv; 15144 } 15145 15146 ast_sockaddr_resolve_first(&tmp, c, 0); 15147 port = ast_sockaddr_port(&tmp); 15148 ast_sockaddr_set_port(&p->sa, 15149 port != 0 ? port : STANDARD_SIP_PORT); 15150 15151 if (sip_debug_test_pvt(p)) { 15152 ast_verbose("Sending to %s (%s)\n", 15153 ast_sockaddr_stringify(sip_real_dst(p)), 15154 sip_nat_mode(p)); 15155 } 15156 } 15157 }
| static attribute_unused void check_via_response | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
check received= and rport= in a SIP response. If we get a response with received= and/or rport= in the Via: line, use them as 'p->ourip' (see RFC 3581 for rport, and RFC 3261 for received). Using these two fields SIP can produce the correct address and port in the SIP headers without the need for STUN. The address part is also reused for the media sessions. Note that ast_sip_ouraddrfor() still rewrites p->ourip if you specify externaddr/seternaddr/.
Definition at line 15069 of file chan_sip.c.
References ast_copy_string(), ast_parse_arg(), ast_sockaddr_set_port, get_header(), PARSE_ADDR, and strsep().
15070 { 15071 char via[256]; 15072 char *cur, *opts; 15073 15074 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 15075 15076 /* Work on the leftmost value of the topmost Via header */ 15077 opts = strchr(via, ','); 15078 if (opts) 15079 *opts = '\0'; 15080 15081 /* parse all relevant options */ 15082 opts = strchr(via, ';'); 15083 if (!opts) 15084 return; /* no options to parse */ 15085 *opts++ = '\0'; 15086 while ( (cur = strsep(&opts, ";")) ) { 15087 if (!strncmp(cur, "rport=", 6)) { 15088 int port = strtol(cur+6, NULL, 10); 15089 /* XXX add error checking */ 15090 ast_sockaddr_set_port(&p->ourip, port); 15091 } else if (!strncmp(cur, "received=", 9)) { 15092 if (ast_parse_arg(cur + 9, PARSE_ADDR, &p->ourip)) 15093 ; /* XXX add error checking */ 15094 } 15095 } 15096 }
| 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 16145 of file chan_sip.c.
References ast_context_destroy(), ast_context_find(), ast_copy_string(), AST_MAX_CONTEXT, and strsep().
Referenced by config_parse_variables().
16146 { 16147 char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT]; 16148 16149 while ((oldcontext = strsep(&old, "&"))) { 16150 stalecontext = '\0'; 16151 ast_copy_string(newlist, new, sizeof(newlist)); 16152 stringp = newlist; 16153 while ((newcontext = strsep(&stringp, "&"))) { 16154 if (!strcmp(newcontext, oldcontext)) { 16155 /* This is not the context you're looking for */ 16156 stalecontext = '\0'; 16157 break; 16158 } else if (strcmp(newcontext, oldcontext)) { 16159 stalecontext = oldcontext; 16160 } 16161 16162 } 16163 if (stalecontext) 16164 ast_context_destroy(ast_context_find(stalecontext), "SIP"); 16165 } 16166 }
| static void clear_peer_mailboxes | ( | struct sip_peer * | peer | ) | [static] |
Destroy all peer-related mailbox subscriptions
Definition at line 4457 of file chan_sip.c.
References AST_LIST_REMOVE_HEAD, destroy_mailbox(), and mailbox.
Referenced by set_peer_defaults(), and sip_destroy_peer().
04458 { 04459 struct sip_mailbox *mailbox; 04460 04461 while ((mailbox = AST_LIST_REMOVE_HEAD(&peer->mailboxes, entry))) 04462 destroy_mailbox(mailbox); 04463 }
| static int clear_realm_authentication | ( | struct sip_auth * | authlist | ) | [static] |
Clear realm authentication list (at reload).
Definition at line 25842 of file chan_sip.c.
References ast_free.
Referenced by build_peer(), reload_config(), sip_destroy_peer(), and unload_module().
25843 { 25844 struct sip_auth *a = authlist; 25845 struct sip_auth *b; 25846 25847 while (a) { 25848 b = a; 25849 a = a->next; 25850 ast_free(b); 25851 } 25852 25853 return 1; 25854 }
| static void clear_sip_domains | ( | void | ) | [static] |
Clear our domain list (at reload).
Definition at line 25775 of file chan_sip.c.
References ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, and AST_LIST_UNLOCK.
Referenced by reload_config(), and unload_module().
25776 { 25777 struct domain *d; 25778 25779 AST_LIST_LOCK(&domain_list); 25780 while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list))) 25781 ast_free(d); 25782 AST_LIST_UNLOCK(&domain_list); 25783 }
| static char * complete_sip_peer | ( | const char * | word, | |
| int | state, | |||
| int | flags2 | |||
| ) | [static] |
Do completion on peer name.
Definition at line 17543 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ast_strdup, ast_test_flag, and unref_peer().
Referenced by complete_sip_show_peer(), complete_sipnotify(), sip_do_debug(), and sip_prune_realtime().
17544 { 17545 char *result = NULL; 17546 int wordlen = strlen(word); 17547 int which = 0; 17548 struct ao2_iterator i = ao2_iterator_init(peers, 0); 17549 struct sip_peer *peer; 17550 17551 while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) { 17552 /* locking of the object is not required because only the name and flags are being compared */ 17553 if (!strncasecmp(word, peer->name, wordlen) && 17554 (!flags2 || ast_test_flag(&peer->flags[1], flags2)) && 17555 ++which > state) 17556 result = ast_strdup(peer->name); 17557 unref_peer(peer, "toss iterator peer ptr before break"); 17558 if (result) { 17559 break; 17560 } 17561 } 17562 ao2_iterator_destroy(&i); 17563 return result; 17564 }
| static char * complete_sip_registered_peer | ( | const char * | word, | |
| int | state, | |||
| int | flags2 | |||
| ) | [static] |
Do completion on registered peer name.
Definition at line 17567 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ast_strdup, ast_test_flag, and unref_peer().
Referenced by complete_sip_unregister().
17568 { 17569 char *result = NULL; 17570 int wordlen = strlen(word); 17571 int which = 0; 17572 struct ao2_iterator i; 17573 struct sip_peer *peer; 17574 17575 i = ao2_iterator_init(peers, 0); 17576 while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) { 17577 if (!strncasecmp(word, peer->name, wordlen) && 17578 (!flags2 || ast_test_flag(&peer->flags[1], flags2)) && 17579 ++which > state && peer->expire > 0) 17580 result = ast_strdup(peer->name); 17581 if (result) { 17582 unref_peer(peer, "toss iterator peer ptr before break"); 17583 break; 17584 } 17585 unref_peer(peer, "toss iterator peer ptr"); 17586 } 17587 ao2_iterator_destroy(&i); 17588 return result; 17589 }
| 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 17592 of file chan_sip.c.
References complete_sipch().
Referenced by sip_show_history().
17593 { 17594 if (pos == 3) 17595 return complete_sipch(line, word, pos, state); 17596 17597 return NULL; 17598 }
| 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 17601 of file chan_sip.c.
References complete_sip_peer().
Referenced by sip_qualify_peer(), and sip_show_peer().
17602 { 17603 if (pos == 3) { 17604 return complete_sip_peer(word, state, 0); 17605 } 17606 17607 return NULL; 17608 }
| 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 16847 of file chan_sip.c.
References complete_sip_user().
Referenced by sip_show_user().
16848 { 16849 if (pos == 3) 16850 return complete_sip_user(word, state); 16851 16852 return NULL; 16853 }
| 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 17611 of file chan_sip.c.
References complete_sip_registered_peer().
Referenced by sip_unregister().
17612 { 17613 if (pos == 2) 17614 return complete_sip_registered_peer(word, state, 0); 17615 17616 return NULL; 17617 }
| static char* complete_sip_user | ( | const char * | word, | |
| int | state | |||
| ) | [static] |
Do completion on user name.
Definition at line 16817 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_unlock, ast_strdup, and unref_peer().
Referenced by complete_sip_show_user().
16818 { 16819 char *result = NULL; 16820 int wordlen = strlen(word); 16821 int which = 0; 16822 struct ao2_iterator user_iter; 16823 struct sip_peer *user; 16824 16825 user_iter = ao2_iterator_init(peers, 0); 16826 while ((user = ao2_iterator_next(&user_iter))) { 16827 ao2_lock(user); 16828 if (!(user->type & SIP_TYPE_USER)) { 16829 ao2_unlock(user); 16830 unref_peer(user, "complete sip user"); 16831 continue; 16832 } 16833 /* locking of the object is not required because only the name and flags are being compared */ 16834 if (!strncasecmp(word, user->name, wordlen) && ++which > state) { 16835 result = ast_strdup(user->name); 16836 } 16837 ao2_unlock(user); 16838 unref_peer(user, "complete sip user"); 16839 if (result) { 16840 break; 16841 } 16842 } 16843 ao2_iterator_destroy(&user_iter); 16844 return result; 16845 }
| 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 17513 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ast_strdup, dialogs, sip_pvt_lock, and sip_pvt_unlock.
Referenced by complete_sip_show_history(), and sip_show_channel().
17514 { 17515 int which=0; 17516 struct sip_pvt *cur; 17517 char *c = NULL; 17518 int wordlen = strlen(word); 17519 struct ao2_iterator i; 17520 17521 if (pos != 3) { 17522 return NULL; 17523 } 17524 17525 i = ao2_iterator_init(dialogs, 0); 17526 while ((cur = ao2_t_iterator_next(&i, "iterate thru dialogs"))) { 17527 sip_pvt_lock(cur); 17528 if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) { 17529 c = ast_strdup(cur->callid); 17530 sip_pvt_unlock(cur); 17531 dialog_unref(cur, "drop ref in iterator loop break"); 17532 break; 17533 } 17534 sip_pvt_unlock(cur); 17535 dialog_unref(cur, "drop ref in iterator loop"); 17536 } 17537 ao2_iterator_destroy(&i); 17538 return c; 17539 }
| static char * complete_sipnotify | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Support routine for 'sip notify' CLI.
Definition at line 17620 of file chan_sip.c.
References ast_category_browse(), ast_strdup, complete_sip_peer(), and notify_types.
Referenced by sip_cli_notify().
17621 { 17622 char *c = NULL; 17623 17624 if (pos == 2) { 17625 int which = 0; 17626 char *cat = NULL; 17627 int wordlen = strlen(word); 17628 17629 /* do completion for notify type */ 17630 17631 if (!notify_types) 17632 return NULL; 17633 17634 while ( (cat = ast_category_browse(notify_types, cat)) ) { 17635 if (!strncasecmp(word, cat, wordlen) && ++which > state) { 17636 c = ast_strdup(cat); 17637 break; 17638 } 17639 } 17640 return c; 17641 } 17642 17643 if (pos > 2) 17644 return complete_sip_peer(word, state, 0); 17645 17646 return NULL; 17647 }
| static int construct_pidf_body | ( | enum sip_cc_publish_state | state, | |
| char * | pidf_body, | |||
| size_t | size, | |||
| const char * | presentity | |||
| ) | [static] |
Definition at line 1921 of file chan_sip.c.
References ast_copy_string(), ast_str_alloca, ast_str_append(), ast_str_buffer(), and generate_random_string().
Referenced by handle_cc_notify(), sip_cc_monitor_suspend(), and sip_cc_monitor_unsuspend().
01922 { 01923 struct ast_str *body = ast_str_alloca(size); 01924 char tuple_id[32]; 01925 01926 generate_random_string(tuple_id, sizeof(tuple_id)); 01927 01928 /* We'll make this a bare-bones pidf body. In state_notify_build_xml, the PIDF 01929 * body gets a lot more extra junk that isn't necessary, so we'll leave it out here. 01930 */ 01931 ast_str_append(&body, 0, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); 01932 /* XXX The entity attribute is currently set to the peer name associated with the 01933 * dialog. This is because we currently only call this function for call-completion 01934 * PUBLISH bodies. In such cases, the entity is completely disregarded. For other 01935 * event packages, it may be crucial to have a proper URI as the presentity so this 01936 * should be revisited as support is expanded. 01937 */ 01938 ast_str_append(&body, 0, "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" entity=\"%s\">\n", presentity); 01939 ast_str_append(&body, 0, "<tuple id=\"%s\">\n", tuple_id); 01940 ast_str_append(&body, 0, "<status><basic>%s</basic></status>\n", state == CC_OPEN ? "open" : "closed"); 01941 ast_str_append(&body, 0, "</tuple>\n"); 01942 ast_str_append(&body, 0, "</presence>\n"); 01943 ast_copy_string(pidf_body, ast_str_buffer(body), size); 01944 return 0; 01945 }
| 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 9394 of file chan_sip.c.
References __get_header(), add_header(), and ast_strlen_zero().
Referenced by respprep().
09395 { 09396 int start = 0; 09397 int copied = 0; 09398 for (;;) { 09399 const char *tmp = __get_header(orig, field, &start); 09400 09401 if (ast_strlen_zero(tmp)) 09402 break; 09403 /* Add what we're responding to */ 09404 add_header(req, field, tmp); 09405 copied++; 09406 } 09407 return copied ? 0 : -1; 09408 }
| 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 9383 of file chan_sip.c.
References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE.
Referenced by reqprep(), and respprep().
09384 { 09385 const char *tmp = get_header(orig, field); 09386 09387 if (!ast_strlen_zero(tmp)) /* Add what we're responding to */ 09388 return add_header(req, field, tmp); 09389 ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field); 09390 return -1; 09391 }
| 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 11090 of file chan_sip.c.
References ast_str_copy_string(), ast_str_create(), and ast_str_strlen().
Referenced by handle_request_bye(), handle_request_invite(), handle_request_options(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), initialize_initreq(), parse_copy(), queue_request(), sip_park(), and sip_park_thread().
11091 { 11092 /* XXX this function can encounter memory allocation errors, perhaps it 11093 * should return a value */ 11094 11095 struct ast_str *duplicate = dst->data; 11096 struct ast_str *duplicate_content = dst->content; 11097 11098 /* copy the entire request then restore the original data and content 11099 * members from the dst request */ 11100 memcpy(dst, src, sizeof(*dst)); 11101 dst->data = duplicate; 11102 dst->content = duplicate_content; 11103 11104 /* copy the data into the dst request */ 11105 if (!dst->data && !(dst->data = ast_str_create(ast_str_strlen(src->data) + 1))) 11106 return; 11107 ast_str_copy_string(&dst->data, src->data); 11108 11109 /* copy the content into the dst request (if it exists) */ 11110 if (src->content) { 11111 if (!dst->content && !(dst->content = ast_str_create(ast_str_strlen(src->content) + 1))) 11112 return; 11113 ast_str_copy_string(&dst->content, src->content); 11114 } 11115 }
| static void copy_socket_data | ( | struct sip_socket * | to_sock, | |
| const struct sip_socket * | from_sock | |||
| ) | [static] |
Definition at line 4929 of file chan_sip.c.
References ao2_ref.
Referenced by create_addr_from_peer(), handle_request_do(), parse_register_contact(), sip_poke_peer(), and transmit_response_using_temp().
04930 { 04931 if (to_sock->tcptls_session) { 04932 ao2_ref(to_sock->tcptls_session, -1); 04933 to_sock->tcptls_session = NULL; 04934 } 04935 04936 if (from_sock->tcptls_session) { 04937 ao2_ref(from_sock->tcptls_session, +1); 04938 } 04939 04940 *to_sock = *from_sock; 04941 }
| static struct ast_variable * copy_vars | ( | struct ast_variable * | src | ) | [static] |
duplicate a list of channel variables,
Definition at line 2300 of file chan_sip.c.
References ast_variable_new(), and ast_variable::next.
02301 { 02302 struct ast_variable *res = NULL, *tmp, *v = NULL; 02303 02304 for (v = src ; v ; v = v->next) { 02305 if ((tmp = ast_variable_new(v->name, v->value, v->file))) { 02306 tmp->next = res; 02307 res = tmp; 02308 } 02309 } 02310 return res; 02311 }
| static int copy_via_headers | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| const struct sip_request * | orig, | |||
| const char * | field | |||
| ) | [static] |
Copy SIP VIA Headers from the request to the response.
We always add ;received=<ip address> to the topmost via header.
Definition at line 9418 of file chan_sip.c.
References __get_header(), add_header(), ast_copy_string(), ast_log(), ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_strlen_zero(), ast_test_flag, and LOG_NOTICE.
Referenced by respprep().
09419 { 09420 int copied = 0; 09421 int start = 0; 09422 09423 for (;;) { 09424 char new[512]; 09425 const char *oh = __get_header(orig, field, &start); 09426 09427 if (ast_strlen_zero(oh)) 09428 break; 09429 09430 if (!copied) { /* Only check for empty rport in topmost via header */ 09431 char leftmost[512], *others, *rport; 09432 09433 /* Only work on leftmost value */ 09434 ast_copy_string(leftmost, oh, sizeof(leftmost)); 09435 others = strchr(leftmost, ','); 09436 if (others) 09437 *others++ = '\0'; 09438 09439 /* Find ;rport; (empty request) */ 09440 rport = strstr(leftmost, ";rport"); 09441 if (rport && *(rport+6) == '=') 09442 rport = NULL; /* We already have a parameter to rport */ 09443 09444 if (((ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT)) || (rport && ast_test_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT)))) { 09445 /* We need to add received port - rport */ 09446 char *end; 09447 09448 rport = strstr(leftmost, ";rport"); 09449 09450 if (rport) { 09451 end = strchr(rport + 1, ';'); 09452 if (end) 09453 memmove(rport, end, strlen(end) + 1); 09454 else 09455 *rport = '\0'; 09456 } 09457 09458 /* Add rport to first VIA header if requested */ 09459 snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s", 09460 leftmost, ast_sockaddr_stringify_addr(&p->recv), 09461 ast_sockaddr_port(&p->recv), 09462 others ? "," : "", others ? others : ""); 09463 } else { 09464 /* We should *always* add a received to the topmost via */ 09465 snprintf(new, sizeof(new), "%s;received=%s%s%s", 09466 leftmost, ast_sockaddr_stringify_addr(&p->recv), 09467 others ? "," : "", others ? others : ""); 09468 } 09469 oh = new; /* the header to copy */ 09470 } /* else add the following via headers untouched */ 09471 add_header(req, field, oh); 09472 copied++; 09473 } 09474 if (!copied) { 09475 ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field); 09476 return -1; 09477 } 09478 return 0; 09479 }
| static int create_addr | ( | struct sip_pvt * | dialog, | |
| const char * | opeer, | |||
| struct ast_sockaddr * | addr, | |||
| int | newdialog, | |||
| struct ast_sockaddr * | remote_address | |||
| ) | [static] |
create address structure from device name Or, if peer not found, find it in the global DNS returns TRUE (-1) on failure, FALSE on success
Definition at line 5149 of file chan_sip.c.
References AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_get_srv(), ast_log(), AST_NONSTANDARD_RAW_ARGS, ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_resolve_first(), ast_sockaddr_set_port, ast_strdupa, ast_string_field_set, bindaddr, create_addr_from_peer(), dialog_initialize_rtp(), FALSE, find_peer(), get_srv_protocol(), get_srv_service(), global_t1, global_timer_b, LOG_WARNING, MAXHOSTNAMELEN, obproxy_get(), ref_peer(), ref_proxy(), service, set_socket_transport(), sip_cfg, TRUE, and unref_peer().
05150 { 05151 struct sip_peer *peer; 05152 char *peername, *peername2, *hostn; 05153 char host[MAXHOSTNAMELEN]; 05154 char service[MAXHOSTNAMELEN]; 05155 int srv_ret = 0; 05156 int tportno; 05157 05158 AST_DECLARE_APP_ARGS(hostport, 05159 AST_APP_ARG(host); 05160 AST_APP_ARG(port); 05161 ); 05162 05163 peername = ast_strdupa(opeer); 05164 peername2 = ast_strdupa(opeer); 05165 AST_NONSTANDARD_RAW_ARGS(hostport, peername2, ':'); 05166 05167 if (hostport.port) 05168 dialog->portinuri = 1; 05169 05170 dialog->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */ 05171 dialog->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */ 05172 peer = find_peer(peername, NULL, TRUE, FINDPEERS, FALSE, 0); 05173 05174 if (peer) { 05175 int res; 05176 if (newdialog) { 05177 set_socket_transport(&dialog->socket, 0); 05178 } 05179 res = create_addr_from_peer(dialog, peer); 05180 if (!ast_sockaddr_isnull(remote_address)) { 05181 ast_sockaddr_copy(&dialog->sa, remote_address); 05182 } 05183 dialog->relatedpeer = ref_peer(peer, "create_addr: setting dialog's relatedpeer pointer"); 05184 unref_peer(peer, "create_addr: unref peer from find_peer hashtab lookup"); 05185 return res; 05186 } 05187 05188 if (dialog_initialize_rtp(dialog)) { 05189 return -1; 05190 } 05191 05192 ast_string_field_set(dialog, tohost, hostport.host); 05193 dialog->allowed_methods &= ~sip_cfg.disallowed_methods; 05194 05195 /* Get the outbound proxy information */ 05196 ref_proxy(dialog, obproxy_get(dialog, NULL)); 05197 05198 if (addr) { 05199 /* This address should be updated using dnsmgr */ 05200 ast_sockaddr_copy(&dialog->sa, addr); 05201 } else { 05202 05203 /* Let's see if we can find the host in DNS. First try DNS SRV records, 05204 then hostname lookup */ 05205 /*! \todo Fix this function. When we ask for SRV, we should check all transports 05206 In the future, we should first check NAPTR to find out transport preference 05207 */ 05208 hostn = peername; 05209 /* Section 4.2 of RFC 3263 specifies that if a port number is specified, then 05210 * an A record lookup should be used instead of SRV. 05211 */ 05212 if (!hostport.port && sip_cfg.srvlookup) { 05213 snprintf(service, sizeof(service), "_%s._%s.%s", 05214 get_srv_service(dialog->socket.type), 05215 get_srv_protocol(dialog->socket.type), peername); 05216 if ((srv_ret = ast_get_srv(NULL, host, sizeof(host), &tportno, 05217 service)) > 0) { 05218 hostn = host; 05219 } 05220 } 05221 05222 if (ast_sockaddr_resolve_first(&dialog->sa, hostn, 0)) { 05223 ast_log(LOG_WARNING, "No such host: %s\n", peername); 05224 } 05225 05226 if (srv_ret > 0) { 05227 ast_sockaddr_set_port(&dialog->sa, tportno); 05228 } 05229 } 05230 05231 if (!dialog->socket.type) 05232 set_socket_transport(&dialog->socket, SIP_TRANSPORT_UDP); 05233 if (!dialog->socket.port) { 05234 dialog->socket.port = htons(ast_sockaddr_port(&bindaddr)); 05235 } 05236 05237 if (!ast_sockaddr_port(&dialog->sa)) { 05238 ast_sockaddr_set_port(&dialog->sa, 05239 (dialog->socket.type == SIP_TRANSPORT_TLS) ? 05240 STANDARD_TLS_PORT : STANDARD_SIP_PORT); 05241 } 05242 ast_sockaddr_copy(&dialog->recv, &dialog->sa); 05243 return 0; 05244 }
| static int create_addr_from_peer | ( | struct sip_pvt * | dialog, | |
| struct sip_peer * | peer | |||
| ) | [static] |
Create address structure from peer reference. This function copies data from peer to the dialog, so we don't have to look up the peer again from memory or database during the life time of the dialog.
Definition at line 5001 of file chan_sip.c.
References accountcode, ao2_t_link, ao2_t_unlink, ast_cc_copy_config_params(), ast_clear_flag, ast_copy_flags, ast_debug, ast_duplicate_ha_list(), ast_rtp_codecs_packetization_set(), AST_RTP_DTMF, ast_rtp_instance_get_codecs(), ast_rtp_instance_set_hold_timeout(), ast_rtp_instance_set_prop(), ast_rtp_instance_set_timeout(), AST_RTP_PROPERTY_DTMF, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_set_flag, ast_sockaddr_isnull(), ast_sockaddr_stringify_host(), ast_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_destroy(), ast_udptl_new_with_bindaddr(), bindaddr, check_request_transport, cid_name, cid_num, context, copy_socket_data(), copy_vars(), dialog_initialize_rtp(), dialogs, global_t1min, io, language, mohinterpret, mohsuggest, obproxy_get(), parkinglot, ref_proxy(), and set_t38_capabilities().
Referenced by create_addr(), and sip_send_mwi_to_peer().
05002 { 05003 /* this checks that the dialog is contacting the peer on a valid 05004 * transport type based on the peers transport configuration, 05005 * otherwise, this function bails out */ 05006 if (dialog->socket.type && check_request_transport(peer, dialog)) 05007 return -1; 05008 copy_socket_data(&dialog->socket, &peer->socket); 05009 05010 if (!(ast_sockaddr_isnull(&peer->addr) && ast_sockaddr_isnull(&peer->defaddr)) && 05011 (!peer->maxms || ((peer->lastms >= 0) && (peer->lastms <= peer->maxms)))) { 05012 dialog->sa = ast_sockaddr_isnull(&peer->addr) ? peer->defaddr : peer->addr; 05013 dialog->recv = dialog->sa; 05014 } else 05015 return -1; 05016 05017 /* XXX TODO: get flags directly from peer only as they are needed using dialog->relatedpeer */ 05018 ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 05019 ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 05020 ast_copy_flags(&dialog->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY); 05021 dialog->capability = peer->capability; 05022 dialog->prefs = peer->prefs; 05023 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT)) { 05024 /* t38pt_udptl was enabled in the peer and not in [general] */ 05025 if (dialog->udptl || (!dialog->udptl && (dialog->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, &bindaddr)))) { 05026 dialog->t38_maxdatagram = peer->t38_maxdatagram; 05027 set_t38_capabilities(dialog); 05028 } else { 05029 /* It is impossible to support T38 without udptl */ 05030 ast_debug(1, "UDPTL creation failed on dialog.\n"); 05031 ast_clear_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT); 05032 } 05033 } else if (dialog->udptl) { 05034 ast_udptl_destroy(dialog->udptl); 05035 dialog->udptl = NULL; 05036 } 05037 05038 ast_string_field_set(dialog, engine, peer->engine); 05039 05040 if (dialog_initialize_rtp(dialog)) { 05041 return -1; 05042 } 05043 05044 if (dialog->rtp) { /* Audio */ 05045 ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 05046 ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 05047 ast_rtp_instance_set_timeout(dialog->rtp, peer->rtptimeout); 05048 ast_rtp_instance_set_hold_timeout(dialog->rtp, peer->rtpholdtimeout); 05049 /* Set Frame packetization */ 05050 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(dialog->rtp), dialog->rtp, &dialog->prefs); 05051 dialog->autoframing = peer->autoframing; 05052 } 05053 if (dialog->vrtp) { /* Video */ 05054 ast_rtp_instance_set_timeout(dialog->vrtp, peer->rtptimeout); 05055 ast_rtp_instance_set_hold_timeout(dialog->vrtp, peer->rtpholdtimeout); 05056 } 05057 if (dialog->trtp) { /* Realtime text */ 05058 ast_rtp_instance_set_timeout(dialog->trtp, peer->rtptimeout); 05059 ast_rtp_instance_set_hold_timeout(dialog->trtp, peer->rtpholdtimeout); 05060 } 05061 05062 /* XXX TODO: get fields directly from peer only as they are needed using dialog->relatedpeer */ 05063 ast_string_field_set(dialog, peername, peer->name); 05064 ast_string_field_set(dialog, authname, peer->username); 05065 ast_string_field_set(dialog, username, peer->username); 05066 ast_string_field_set(dialog, peersecret, peer->secret); 05067 ast_string_field_set(dialog, peermd5secret, peer->md5secret); 05068 ast_string_field_set(dialog, mohsuggest, peer->mohsuggest); 05069 ast_string_field_set(dialog, mohinterpret, peer->mohinterpret); 05070 ast_string_field_set(dialog, tohost, peer->tohost); 05071 ast_string_field_set(dialog, fullcontact, peer->fullcontact); 05072 ast_string_field_set(dialog, accountcode, peer->accountcode); 05073 ast_string_field_set(dialog, context, peer->context); 05074 ast_string_field_set(dialog, cid_num, peer->cid_num); 05075 ast_string_field_set(dialog, cid_name, peer->cid_name); 05076 ast_string_field_set(dialog, cid_tag, peer->cid_tag); 05077 ast_string_field_set(dialog, mwi_from, peer->mwi_from); 05078 if (!ast_strlen_zero(peer->parkinglot)) { 05079 ast_string_field_set(dialog, parkinglot, peer->parkinglot); 05080 } 05081 ast_string_field_set(dialog, engine, peer->engine); 05082 ref_proxy(dialog, obproxy_get(dialog, peer)); 05083 dialog->callgroup = peer->callgroup; 05084 dialog->pickupgroup = peer->pickupgroup; 05085 dialog->allowtransfer = peer->allowtransfer; 05086 dialog->jointnoncodeccapability = dialog->noncodeccapability; 05087 dialog->rtptimeout = peer->rtptimeout; 05088 dialog->peerauth = peer->auth; 05089 dialog->maxcallbitrate = peer->maxcallbitrate; 05090 dialog->disallowed_methods = peer->disallowed_methods; 05091 ast_cc_copy_config_params(dialog->cc_params, peer->cc_params); 05092 if (ast_strlen_zero(dialog->tohost)) 05093 ast_string_field_set(dialog, tohost, ast_sockaddr_stringify_host(&dialog->sa)); 05094 if (!ast_strlen_zero(peer->fromdomain)) { 05095 ast_string_field_set(dialog, fromdomain, peer->fromdomain); 05096 if (!dialog->initreq.headers) { 05097 char *c; 05098 char *tmpcall = ast_strdupa(dialog->callid); 05099 /* this sure looks to me like we are going to change the callid on this dialog!! */ 05100 c = strchr(tmpcall, '@'); 05101 if (c) { 05102 *c = '\0'; 05103 ao2_t_unlink(dialogs, dialog, "About to change the callid -- remove the old name"); 05104 ast_string_field_build(dialog, callid, "%s@%s", tmpcall, peer->fromdomain); 05105 ao2_t_link(dialogs, dialog, "New dialog callid -- inserted back into table"); 05106 } 05107 } 05108 } 05109 if (!ast_strlen_zero(peer->fromuser)) 05110 ast_string_field_set(dialog, fromuser, peer->fromuser); 05111 if (!ast_strlen_zero(peer->language)) 05112 ast_string_field_set(dialog, language, peer->language); 05113 /* Set timer T1 to RTT for this peer (if known by qualify=) */ 05114 /* Minimum is settable or default to 100 ms */ 05115 /* If there is a maxms and lastms from a qualify use that over a manual T1 05116 value. Otherwise, use the peer's T1 value. */ 05117 if (peer->maxms && peer->lastms) 05118 dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 05119 else 05120 dialog->timer_t1 = peer->timer_t1; 05121 05122 /* Set timer B to control transaction timeouts, the peer setting is the default and overrides 05123 the known timer */ 05124 if (peer->timer_b) 05125 dialog->timer_b = peer->timer_b; 05126 else 05127 dialog->timer_b = 64 * dialog->timer_t1; 05128 05129 if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 05130 (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 05131 dialog->noncodeccapability |= AST_RTP_DTMF; 05132 else 05133 dialog->noncodeccapability &= ~AST_RTP_DTMF; 05134 dialog->directmediaha = ast_duplicate_ha_list(peer->directmediaha); 05135 if (peer->call_limit) 05136 ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT); 05137 if (!dialog->portinuri) 05138 dialog->portinuri = peer->portinuri; 05139 dialog->chanvars = copy_vars(peer->chanvars); 05140 if (peer->fromdomainport) 05141 dialog->fromdomainport = peer->fromdomainport; 05142 05143 return 0; 05144 }
| static struct sip_epa_entry* create_epa_entry | ( | const char *const | event_package, | |
| const char *const | destination | |||
| ) | [static] |
Definition at line 904 of file chan_sip.c.
References ao2_t_alloc, ast_copy_string(), and find_static_data().
Referenced by sip_cc_monitor_suspend().
00905 { 00906 struct sip_epa_entry *epa_entry; 00907 const struct epa_static_data *static_data; 00908 00909 if (!(static_data = find_static_data(event_package))) { 00910 return NULL; 00911 } 00912 00913 if (!(epa_entry = ao2_t_alloc(sizeof(*epa_entry), static_data->destructor, "Allocate new EPA entry"))) { 00914 return NULL; 00915 } 00916 00917 epa_entry->static_data = static_data; 00918 ast_copy_string(epa_entry->destination, destination, sizeof(epa_entry->destination)); 00919 return epa_entry; 00920 }
| static struct sip_esc_entry* create_esc_entry | ( | struct event_state_compositor * | esc, | |
| struct sip_request * | req, | |||
| const int | expires | |||
| ) | [static] |
Definition at line 1030 of file chan_sip.c.
References ao2_alloc, ao2_ref, ast_sched_add(), create_new_sip_etag(), esc_entry_destructor(), event_state_compositor::name, publish_expire(), and sched.
Referenced by handle_sip_publish_initial().
01031 { 01032 struct sip_esc_entry *esc_entry; 01033 int expires_ms; 01034 01035 if (!(esc_entry = ao2_alloc(sizeof(*esc_entry), esc_entry_destructor))) { 01036 return NULL; 01037 } 01038 01039 esc_entry->event = esc->name; 01040 01041 expires_ms = expires * 1000; 01042 /* Bump refcount for scheduler */ 01043 ao2_ref(esc_entry, +1); 01044 esc_entry->sched_id = ast_sched_add(sched, expires_ms, publish_expire, esc_entry); 01045 01046 /* Note: This links the esc_entry into the ESC properly */ 01047 create_new_sip_etag(esc_entry, 0); 01048 01049 return esc_entry; 01050 }
| static void create_new_sip_etag | ( | struct sip_esc_entry * | esc_entry, | |
| int | is_linked | |||
| ) | [static] |
Definition at line 1017 of file chan_sip.c.
References ao2_link, ao2_unlink, ast_assert, ast_atomic_fetchadd_int(), event_state_compositor::compositor, and get_esc().
Referenced by create_esc_entry(), and transmit_response_with_sip_etag().
01018 { 01019 int new_etag = ast_atomic_fetchadd_int(&esc_etag_counter, +1); 01020 struct event_state_compositor *esc = get_esc(esc_entry->event); 01021 01022 ast_assert(esc != NULL); 01023 if (is_linked) { 01024 ao2_unlink(esc->compositor, esc_entry); 01025 } 01026 snprintf(esc_entry->entity_tag, sizeof(esc_entry->entity_tag), "%d", new_etag); 01027 ao2_link(esc->compositor, esc_entry); 01028 }
| static void deinit_req | ( | struct sip_request * | req | ) | [static] |
Deinitialize SIP response/request.
Definition at line 9637 of file chan_sip.c.
References ast_free.
Referenced by __sip_destroy(), send_request(), send_response(), sip_park(), sip_park_thread(), and sipsock_read().
09638 { 09639 if (req->data) { 09640 ast_free(req->data); 09641 req->data = NULL; 09642 } 09643 if (req->content) { 09644 ast_free(req->content); 09645 req->content = NULL; 09646 } 09647 }
| static void destroy_association | ( | struct sip_peer * | peer | ) | [static] |
Remove registration data from realtime database or AST/DB when registration expires.
Definition at line 12969 of file chan_sip.c.
References ast_check_realtime(), ast_db_del(), ast_update_realtime(), SENTINEL, and sip_cfg.
Referenced by build_peer(), expire_register(), and parse_register_contact().
12970 { 12971 int realtimeregs = ast_check_realtime("sipregs"); 12972 char *tablename = (realtimeregs) ? "sipregs" : "sippeers"; 12973 12974 if (!sip_cfg.ignore_regexpire) { 12975 if (peer->rt_fromcontact && sip_cfg.peer_rtupdate) { 12976 ast_update_realtime(tablename, "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "regserver", "", "useragent", "", "lastms", "", SENTINEL); 12977 } else { 12978 ast_db_del("SIP/Registry", peer->name); 12979 ast_db_del("SIP/PeerMethods", peer->name); 12980 } 12981 } 12982 }
| static void destroy_escs | ( | void | ) | [static] |
Definition at line 1064 of file chan_sip.c.
References ao2_ref, ARRAY_LEN, and event_state_compositors.
Referenced by unload_module().
01065 { 01066 int i; 01067 for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) { 01068 ao2_ref(event_state_compositors[i].compositor, -1); 01069 } 01070 }
| static void destroy_mailbox | ( | struct sip_mailbox * | mailbox | ) | [static] |
Destroy mailbox subscriptions
Definition at line 4449 of file chan_sip.c.
References ast_event_unsubscribe(), and ast_free.
Referenced by build_peer(), and clear_peer_mailboxes().
04450 { 04451 if (mailbox->event_sub) 04452 ast_event_unsubscribe(mailbox->event_sub); 04453 ast_free(mailbox); 04454 }
| static int determine_firstline_parts | ( | struct sip_request * | req | ) | [static] |
Parse first line of incoming SIP request.
Definition at line 11187 of file chan_sip.c.
References ast_debug, ast_skip_blanks(), ast_skip_nonblanks(), and ast_trim_blanks().
11188 { 11189 char *e = ast_skip_blanks(req->data->str); /* there shouldn't be any */ 11190 char *local_rlPart1; 11191 11192 if (!*e) 11193 return -1; 11194 req->rlPart1 = e - req->data->str; /* method or protocol */ 11195 local_rlPart1 = e; 11196 e = ast_skip_nonblanks(e); 11197 if (*e) 11198 *e++ = '\0'; 11199 /* Get URI or status code */ 11200 e = ast_skip_blanks(e); 11201 if ( !*e ) 11202 return -1; 11203 ast_trim_blanks(e); 11204 11205 if (!strcasecmp(local_rlPart1, "SIP/2.0") ) { /* We have a response */ 11206 if (strlen(e) < 3) /* status code is 3 digits */ 11207 return -1; 11208 req->rlPart2 = e - req->data->str; 11209 } else { /* We have a request */ 11210 if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */ 11211 ast_debug(3, "Oops. Bogus uri in <> %s\n", e); 11212 e++; 11213 if (!*e) 11214 return -1; 11215 } 11216 req->rlPart2 = e - req->data->str; /* URI */ 11217 e = ast_skip_nonblanks(e); 11218 if (*e) 11219 *e++ = '\0'; 11220 e = ast_skip_blanks(e); 11221 if (strcasecmp(e, "SIP/2.0") ) { 11222 ast_debug(3, "Skipping packet - Bad request protocol %s\n", e); 11223 return -1; 11224 } 11225 } 11226 return 1; 11227 }
| 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 22813 of file chan_sip.c.
References ast_assert, ast_strlen_zero(), and DEFAULT_PUBLISH_EXPIRES.
Referenced by handle_request_publish().
22814 { 22815 int etag_present = !ast_strlen_zero(etag); 22816 int body_present = req->lines > 0; 22817 22818 ast_assert(expires_int != NULL); 22819 22820 if (ast_strlen_zero(expires)) { 22821 /* Section 6, item 4, second bullet point of RFC 3903 says to 22822 * use a locally-configured default expiration if none is provided 22823 * in the request 22824 */ 22825 *expires_int = DEFAULT_PUBLISH_EXPIRES; 22826 } else if (sscanf(expires, "%30d", expires_int) != 1) { 22827 return SIP_PUBLISH_UNKNOWN; 22828 } 22829 22830 if (*expires_int == 0) { 22831 return SIP_PUBLISH_REMOVE; 22832 } else if (!etag_present && body_present) { 22833 return SIP_PUBLISH_INITIAL; 22834 } else if (etag_present && !body_present) { 22835 return SIP_PUBLISH_REFRESH; 22836 } else if (etag_present && body_present) { 22837 return SIP_PUBLISH_MODIFY; 22838 } 22839 22840 return SIP_PUBLISH_UNKNOWN; 22841 }
| static int dialog_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 28582 of file chan_sip.c.
References CMP_MATCH, and CMP_STOP.
Referenced by load_module().
28583 { 28584 struct sip_pvt *pvt = obj, *pvt2 = arg; 28585 28586 return !strcasecmp(pvt->callid, pvt2->callid) ? CMP_MATCH | CMP_STOP : 0; 28587 }
| static int dialog_dump_func | ( | void * | userobj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 16061 of file chan_sip.c.
References ao2_t_ref, ast_cli(), and ast_cli_args::fd.
Referenced by sip_show_objects().
16062 { 16063 struct sip_pvt *pvt = userobj; 16064 int refc = ao2_t_ref(userobj, 0, ""); 16065 struct ast_cli_args *a = (struct ast_cli_args *) arg; 16066 16067 ast_cli(a->fd, "name: %s\ntype: dialog\nobjflags: %d\nrefcount: %d\n\n", 16068 pvt->callid, 0, refc); 16069 return 0; 16070 }
| static int dialog_find_multiple | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 28572 of file chan_sip.c.
References CMP_MATCH.
Referenced by find_call().
28573 { 28574 struct sip_pvt *pvt = obj, *pvt2 = arg; 28575 28576 return !strcasecmp(pvt->callid, pvt2->callid) ? CMP_MATCH : 0; 28577 }
| static int dialog_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 28562 of file chan_sip.c.
References ast_str_case_hash().
Referenced by load_module().
28563 { 28564 const struct sip_pvt *pvt = obj; 28565 28566 return ast_str_case_hash(pvt->callid); 28567 }
| static int dialog_initialize_rtp | ( | struct sip_pvt * | dialog | ) | [static] |
Initialize RTP portion of a dialog.
Definition at line 4946 of file chan_sip.c.
References AST_FORMAT_VIDEO_MASK, ast_rtp_instance_new(), ast_rtp_instance_set_hold_timeout(), ast_rtp_instance_set_prop(), ast_rtp_instance_set_qos(), ast_rtp_instance_set_timeout(), AST_RTP_PROPERTY_DTMF, AST_RTP_PROPERTY_DTMF_COMPENSATE, AST_RTP_PROPERTY_RTCP, ast_sockaddr_copy(), ast_test_flag, bindaddr, do_setnat(), global_cos_audio, global_rtpholdtimeout, global_rtptimeout, global_tos_audio, cfsip_methods::need_rtp, and sip_methods.
Referenced by check_peer_ok(), check_user_full(), create_addr(), and create_addr_from_peer().
04947 { 04948 struct ast_sockaddr bindaddr_tmp; 04949 04950 if (!sip_methods[dialog->method].need_rtp) { 04951 return 0; 04952 } 04953 04954 ast_sockaddr_copy(&bindaddr_tmp, &bindaddr); 04955 if (!(dialog->rtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) { 04956 return -1; 04957 } 04958 04959 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS) || 04960 (ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) && (dialog->capability & AST_FORMAT_VIDEO_MASK))) { 04961 if (!(dialog->vrtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) { 04962 return -1; 04963 } 04964 ast_rtp_instance_set_timeout(dialog->vrtp, global_rtptimeout); 04965 ast_rtp_instance_set_hold_timeout(dialog->vrtp, global_rtpholdtimeout); 04966 04967 ast_rtp_instance_set_prop(dialog->vrtp, AST_RTP_PROPERTY_RTCP, 1); 04968 } 04969 04970 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_TEXTSUPPORT)) { 04971 if (!(dialog->trtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) { 04972 return -1; 04973 } 04974 ast_rtp_instance_set_timeout(dialog->trtp, global_rtptimeout); 04975 ast_rtp_instance_set_hold_timeout(dialog->trtp, global_rtpholdtimeout); 04976 04977 ast_rtp_instance_set_prop(dialog->trtp, AST_RTP_PROPERTY_RTCP, 1); 04978 } 04979 04980 ast_rtp_instance_set_timeout(dialog->rtp, global_rtptimeout); 04981 ast_rtp_instance_set_hold_timeout(dialog->rtp, global_rtpholdtimeout); 04982 04983 ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_RTCP, 1); 04984 ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 04985 ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 04986 04987 ast_rtp_instance_set_qos(dialog->rtp, global_tos_audio, global_cos_audio, "SIP RTP"); 04988 04989 do_setnat(dialog); 04990 04991 return 0; 04992 }
| static int dialog_needdestroy | ( | void * | dialogobj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Match dialogs that need to be destroyed.
This is used with ao2_callback to unlink/delete all dialogs that are marked needdestroy. It will return CMP_MATCH for candidates, and they will be unlinked.
Definition at line 16180 of file chan_sip.c.
References ast_debug, ast_rtp_instance_get_bridged(), check_rtp_timeout(), dialog_unlink_all(), FALSE, sip_methods, sip_pvt_trylock, sip_pvt_unlock, cfsip_methods::text, and TRUE.
Referenced by do_monitor().
16181 { 16182 struct sip_pvt *dialog = dialogobj; 16183 time_t *t = arg; 16184 16185 if (sip_pvt_trylock(dialog)) { 16186 /* Don't block the monitor thread. This function is called often enough 16187 * that we can wait for the next time around. */ 16188 return 0; 16189 } 16190 16191 /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */ 16192 if (dialog->rtp && ast_rtp_instance_get_bridged(dialog->rtp)) { 16193 ast_debug(2, "Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text); 16194 sip_pvt_unlock(dialog); 16195 return 0; 16196 } 16197 16198 if (dialog->vrtp && ast_rtp_instance_get_bridged(dialog->vrtp)) { 16199 ast_debug(2, "Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text); 16200 sip_pvt_unlock(dialog); 16201 return 0; 16202 } 16203 16204 /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */ 16205 check_rtp_timeout(dialog, *t); 16206 16207 /* If we have sessions that needs to be destroyed, do it now */ 16208 /* Check if we have outstanding requests not responsed to or an active call 16209 - if that's the case, wait with destruction */ 16210 if (dialog->needdestroy && !dialog->packets && !dialog->owner) { 16211 /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */ 16212 if (dialog->rtp && ast_rtp_instance_get_bridged(dialog->rtp)) { 16213 ast_debug(2, "Bridge still active. Delaying destruction of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text); 16214 sip_pvt_unlock(dialog); 16215 return 0; 16216 } 16217 16218 if (dialog->vrtp && ast_rtp_instance_get_bridged(dialog->vrtp)) { 16219 ast_debug(2, "Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text); 16220 sip_pvt_unlock(dialog); 16221 return 0; 16222 } 16223 16224 sip_pvt_unlock(dialog); 16225 /* no, the unlink should handle this: dialog_unref(dialog, "needdestroy: one more refcount decrement to allow dialog to be destroyed"); */ 16226 /* the CMP_MATCH will unlink this dialog from the dialog hash table */ 16227 dialog_unlink_all(dialog, TRUE, FALSE); 16228 return 0; /* the unlink_all should unlink this from the table, so.... no need to return a match */ 16229 } 16230 16231 sip_pvt_unlock(dialog); 16232 16233 return 0; 16234 }
| struct sip_pvt* dialog_ref_debug | ( | struct sip_pvt * | p, | |
| char * | tag, | |||
| char * | file, | |||
| int | line, | |||
| const char * | func | |||
| ) |
Definition at line 2192 of file chan_sip.c.
References __ao2_ref_debug(), ao2_ref, ast_log(), and LOG_ERROR.
02193 { 02194 if (p) 02195 #ifdef REF_DEBUG 02196 __ao2_ref_debug(p, 1, tag, file, line, func); 02197 #else 02198 ao2_ref(p, 1); 02199 #endif 02200 else 02201 ast_log(LOG_ERROR, "Attempt to Ref a null pointer\n"); 02202 return p; 02203 }
| void* dialog_unlink_all | ( | struct sip_pvt * | dialog, | |
| int | lockowner, | |||
| int | lockdialoglist | |||
| ) |
Unlink a dialog from the dialogs container, as well as any other places that it may be currently stored.
Definition at line 2870 of file chan_sip.c.
References ao2_t_unlink, ast_channel_lock, ast_channel_unlock, ast_debug, ast_extension_state_del(), ast_free, AST_SCHED_DEL, AST_SCHED_DEL_UNREF, dialogs, and registry_unref().
Referenced by __sip_autodestruct(), __sip_subscribe_mwi_do(), dialog_needdestroy(), handle_request_subscribe(), manager_sipnotify(), reload_config(), sip_cli_notify(), sip_destroy_peer(), sip_poke_noanswer(), sip_poke_peer(), sip_registry_destroy(), sip_request_call(), sip_send_mwi_to_peer(), transmit_publish(), transmit_register(), and unload_module().
02871 { 02872 struct sip_pkt *cp; 02873 02874 dialog_ref(dialog, "Let's bump the count in the unlink so it doesn't accidentally become dead before we are done"); 02875 02876 ao2_t_unlink(dialogs, dialog, "unlinking dialog via ao2_unlink"); 02877 02878 /* Unlink us from the owner (channel) if we have one */ 02879 if (dialog->owner) { 02880 if (lockowner) 02881 ast_channel_lock(dialog->owner); 02882 ast_debug(1, "Detaching from channel %s\n", dialog->owner->name); 02883 dialog->owner->tech_pvt = dialog_unref(dialog->owner->tech_pvt, "resetting channel dialog ptr in unlink_all"); 02884 if (lockowner) { 02885 ast_channel_unlock(dialog->owner); 02886 } 02887 } 02888 if (dialog->registry) { 02889 if (dialog->registry->call == dialog) { 02890 dialog->registry->call = dialog_unref(dialog->registry->call, "nulling out the registry's call dialog field in unlink_all"); 02891 } 02892 dialog->registry = registry_unref(dialog->registry, "delete dialog->registry"); 02893 } 02894 if (dialog->stateid > -1) { 02895 ast_extension_state_del(dialog->stateid, NULL); 02896 dialog_unref(dialog, "removing extension_state, should unref the associated dialog ptr that was stored there."); 02897 dialog->stateid = -1; /* shouldn't we 'zero' this out? */ 02898 } 02899 /* Remove link from peer to subscription of MWI */ 02900 if (dialog->relatedpeer && dialog->relatedpeer->mwipvt == dialog) { 02901 dialog->relatedpeer->mwipvt = dialog_unref(dialog->relatedpeer->mwipvt, "delete ->relatedpeer->mwipvt"); 02902 } 02903 if (dialog->relatedpeer && dialog->relatedpeer->call == dialog) { 02904 dialog->relatedpeer->call = dialog_unref(dialog->relatedpeer->call, "unset the relatedpeer->call field in tandem with relatedpeer field itself"); 02905 } 02906 02907 /* remove all current packets in this dialog */ 02908 while((cp = dialog->packets)) { 02909 dialog->packets = dialog->packets->next; 02910 AST_SCHED_DEL(sched, cp->retransid); 02911 dialog_unref(cp->owner, "remove all current packets in this dialog, and the pointer to the dialog too as part of __sip_destroy"); 02912 if (cp->data) { 02913 ast_free(cp->data); 02914 } 02915 ast_free(cp); 02916 } 02917 02918 AST_SCHED_DEL_UNREF(sched, dialog->waitid, dialog_unref(dialog, "when you delete the waitid sched, you should dec the refcount for the stored dialog ptr")); 02919 02920 AST_SCHED_DEL_UNREF(sched, dialog->initid, dialog_unref(dialog, "when you delete the initid sched, you should dec the refcount for the stored dialog ptr")); 02921 02922 if (dialog->autokillid > -1) { 02923 AST_SCHED_DEL_UNREF(sched, dialog->autokillid, dialog_unref(dialog, "when you delete the autokillid sched, you should dec the refcount for the stored dialog ptr")); 02924 } 02925 02926 if (dialog->request_queue_sched_id > -1) { 02927 AST_SCHED_DEL_UNREF(sched, dialog->request_queue_sched_id, dialog_unref(dialog, "when you delete the request_queue_sched_id sched, you should dec the refcount for the stored dialog ptr")); 02928 } 02929 02930 AST_SCHED_DEL_UNREF(sched, dialog->provisional_keepalive_sched_id, dialog_unref(dialog, "when you delete the provisional_keepalive_sched_id, you should dec the refcount for the stored dialog ptr")); 02931 02932 if (dialog->t38id > -1) { 02933 AST_SCHED_DEL_UNREF(sched, dialog->t38id, dialog_unref(dialog, "when you delete the t38id sched, you should dec the refcount for the stored dialog ptr")); 02934 } 02935 02936 dialog_unref(dialog, "Let's unbump the count in the unlink so the poor pvt can disappear if it is time"); 02937 return NULL; 02938 }
| struct sip_pvt* dialog_unref_debug | ( | struct sip_pvt * | p, | |
| char * | tag, | |||
| char * | file, | |||
| int | line, | |||
| const char * | func | |||
| ) |
Definition at line 2205 of file chan_sip.c.
References __ao2_ref_debug(), and ao2_ref.
02206 { 02207 if (p) 02208 #ifdef REF_DEBUG 02209 __ao2_ref_debug(p, -1, tag, file, line, func); 02210 #else 02211 ao2_ref(p, -1); 02212 #endif 02213 return NULL; 02214 }
| static void disable_dsp_detect | ( | struct sip_pvt * | p | ) | [static] |
Definition at line 4156 of file chan_sip.c.
References ast_dsp_free().
Referenced by sip_dtmfmode(), sip_hangup(), and sip_setoption().
04157 { 04158 if (p->dsp) { 04159 ast_dsp_free(p->dsp); 04160 p->dsp = NULL; 04161 } 04162 }
| static int do_magic_pickup | ( | struct ast_channel * | channel, | |
| const char * | extension, | |||
| const char * | context | |||
| ) | [static] |
Definition at line 21038 of file chan_sip.c.
References ast_debug, ast_log(), AST_MAX_CONTEXT, AST_MAX_EXTENSION, ast_str_alloca, ast_str_set(), LOG_ERROR, pbx_exec(), pbx_findapp(), sip_cfg, and str.
Referenced by handle_request_invite().
21039 { 21040 struct ast_str *str = ast_str_alloca(AST_MAX_EXTENSION + AST_MAX_CONTEXT + 2); 21041 struct ast_app *pickup = pbx_findapp("Pickup"); 21042 21043 if (!pickup) { 21044 ast_log(LOG_ERROR, "Unable to perform pickup: Application 'Pickup' not loaded (app_directed_pickup.so).\n"); 21045 return -1; 21046 } 21047 21048 ast_str_set(&str, 0, "%s@%s", extension, sip_cfg.notifycid == IGNORE_CONTEXT ? "PICKUPMARK" : context); 21049 21050 ast_debug(2, "About to call Pickup(%s)\n", str->str); 21051 21052 /* There is no point in capturing the return value since pickup_exec 21053 doesn't return anything meaningful unless the passed data is an empty 21054 string (which in our case it will not be) */ 21055 pbx_exec(channel, pickup, str->str); 21056 21057 return 0; 21058 }
| static void * do_monitor | ( | void * | data | ) | [static] |
The SIP monitoring thread.
Definition at line 24663 of file chan_sip.c.
References ao2_t_callback, ast_debug, ast_io_add(), ast_io_change(), AST_IO_IN, ast_io_remove(), ast_io_wait(), ast_mutex_lock, ast_mutex_unlock, ast_sched_runq(), ast_sched_wait(), ast_verb, dialog_needdestroy(), dialogs, FALSE, io, monlock, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, sip_do_reload(), sip_reload_lock, sip_reloading, sip_reloadreason, sipsock, sipsock_read(), and sipsock_read_id.
24664 { 24665 int res; 24666 time_t t; 24667 int reloading; 24668 24669 /* Add an I/O event to our SIP UDP socket */ 24670 if (sipsock > -1) 24671 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 24672 24673 /* From here on out, we die whenever asked */ 24674 for(;;) { 24675 /* Check for a reload request */ 24676 ast_mutex_lock(&sip_reload_lock); 24677 reloading = sip_reloading; 24678 sip_reloading = FALSE; 24679 ast_mutex_unlock(&sip_reload_lock); 24680 if (reloading) { 24681 ast_verb(1, "Reloading SIP\n"); 24682 sip_do_reload(sip_reloadreason); 24683 24684 /* Change the I/O fd of our UDP socket */ 24685 if (sipsock > -1) { 24686 if (sipsock_read_id) 24687 sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL); 24688 else 24689 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 24690 } else if (sipsock_read_id) { 24691 ast_io_remove(io, sipsock_read_id); 24692 sipsock_read_id = NULL; 24693 } 24694 } 24695 24696 /* Check for dialogs needing to be killed */ 24697 t = time(NULL); 24698 /* don't scan the dialogs list if it hasn't been a reasonable period 24699 of time since the last time we did it (when MWI is being sent, we can 24700 get back to this point every millisecond or less) 24701 */ 24702 ao2_t_callback(dialogs, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, dialog_needdestroy, &t, 24703 "callback to remove dialogs w/needdestroy"); 24704 24705 /* the old methodology would be to restart the search for dialogs to delete with every 24706 dialog that was found and destroyed, probably because the list contents would change, 24707 so we'd need to restart. This isn't the best thing to do with callbacks. */ 24708 24709 /* XXX TODO The scheduler usage in this module does not have sufficient 24710 * synchronization being done between running the scheduler and places 24711 * scheduling tasks. As it is written, any scheduled item may not run 24712 * any sooner than about 1 second, regardless of whether a sooner time 24713 * was asked for. */ 24714 24715 pthread_testcancel(); 24716 /* Wait for sched or io */ 24717 res = ast_sched_wait(sched); 24718 if ((res < 0) || (res > 1000)) 24719 res = 1000; 24720 res = ast_io_wait(io, res); 24721 if (res > 20) 24722 ast_debug(1, "chan_sip: ast_io_wait ran %d all at once\n", res); 24723 ast_mutex_lock(&monlock); 24724 res = ast_sched_runq(sched); 24725 if (res >= 20) 24726 ast_debug(1, "chan_sip: ast_sched_runq ran %d all at once\n", res); 24727 ast_mutex_unlock(&monlock); 24728 } 24729 24730 /* Never reached */ 24731 return NULL; 24732 }
| 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 18252 of file chan_sip.c.
References ast_calloc, ast_debug, auth_headers(), reply_digest(), sip_methods, cfsip_methods::text, and transmit_invite().
Referenced by handle_response(), handle_response_invite(), handle_response_notify(), handle_response_publish(), handle_response_refer(), handle_response_subscribe(), and handle_response_update().
18253 { 18254 char *header, *respheader; 18255 char digest[1024]; 18256 18257 if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options)))) 18258 return -2; 18259 18260 p->authtries++; 18261 auth_headers(code, &header, &respheader); 18262 ast_debug(2, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text); 18263 memset(digest, 0, sizeof(digest)); 18264 if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) { 18265 /* No way to authenticate */ 18266 return -1; 18267 } 18268 /* Now we have a reply digest */ 18269 p->options->auth = digest; 18270 p->options->authheader = respheader; 18271 return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init, NULL); 18272 }
| 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 18228 of file chan_sip.c.
References append_history, ast_verbose, auth_headers(), reply_digest(), sip_debug_test_pvt(), and transmit_register().
Referenced by handle_response_register().
18229 { 18230 char *header, *respheader; 18231 char digest[1024]; 18232 18233 p->authtries++; 18234 auth_headers(code, &header, &respheader); 18235 memset(digest, 0, sizeof(digest)); 18236 if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) { 18237 /* There's nothing to use for authentication */ 18238 /* No digest challenge in request */ 18239 if (sip_debug_test_pvt(p) && p->registry) 18240 ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); 18241 /* No old challenge */ 18242 return -1; 18243 } 18244 if (p->do_history) 18245 append_history(p, "RegistryAuth", "Try: %d", p->authtries); 18246 if (sip_debug_test_pvt(p) && p->registry) 18247 ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); 18248 return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 18249 }
| static void do_setnat | ( | struct sip_pvt * | p | ) | [static] |
Set nat mode on the various data sockets.
Definition at line 4840 of file chan_sip.c.
References ast_debug, ast_rtp_instance_set_prop(), AST_RTP_PROPERTY_NAT, ast_test_flag, and ast_udptl_setnat().
Referenced by check_peer_ok(), dialog_initialize_rtp(), sip_alloc(), and transmit_response_using_temp().
04841 { 04842 const char *mode; 04843 int natflags; 04844 04845 natflags = ast_test_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP); 04846 mode = natflags ? "On" : "Off"; 04847 04848 if (p->rtp) { 04849 ast_debug(1, "Setting NAT on RTP to %s\n", mode); 04850 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_NAT, natflags); 04851 } 04852 if (p->vrtp) { 04853 ast_debug(1, "Setting NAT on VRTP to %s\n", mode); 04854 ast_rtp_instance_set_prop(p->vrtp, AST_RTP_PROPERTY_NAT, natflags); 04855 } 04856 if (p->udptl) { 04857 ast_debug(1, "Setting NAT on UDPTL to %s\n", mode); 04858 ast_udptl_setnat(p->udptl, natflags); 04859 } 04860 if (p->trtp) { 04861 ast_debug(1, "Setting NAT on TRTP to %s\n", mode); 04862 ast_rtp_instance_set_prop(p->trtp, AST_RTP_PROPERTY_NAT, natflags); 04863 } 04864 }
| static const char * domain_mode_to_text | ( | const enum domain_mode | mode | ) | [static] |
Print domain mode to cli.
Definition at line 16389 of file chan_sip.c.
Referenced by sip_show_domains().
16390 { 16391 switch (mode) { 16392 case SIP_DOMAIN_AUTO: 16393 return "[Automatic]"; 16394 case SIP_DOMAIN_CONFIG: 16395 return "[Configured]"; 16396 } 16397 16398 return ""; 16399 }
| static const char * dtmfmode2str | ( | int | mode | ) | const [static] |
Convert DTMF mode to printable string.
Definition at line 16117 of file chan_sip.c.
References dtmfstr, and map_x_s().
Referenced by _sip_show_peer(), sip_show_channel(), and sip_show_settings().
| static void enable_dsp_detect | ( | struct sip_pvt * | p | ) | [static] |
Definition at line 4123 of file chan_sip.c.
References ast_dsp_new(), ast_dsp_set_digitmode(), ast_dsp_set_features(), AST_RTP_DTMF_MODE_INBAND, ast_rtp_instance_dtmf_mode_set(), ast_test_flag, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_RELAXDTMF, DSP_FEATURE_DIGIT_DETECT, DSP_FEATURE_FAX_DETECT, and global_relaxdtmf.
Referenced by sip_dtmfmode(), sip_new(), and sip_setoption().
04124 { 04125 int features = 0; 04126 04127 if (p->dsp) { 04128 return; 04129 } 04130 04131 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || 04132 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) { 04133 if (!p->rtp || ast_rtp_instance_dtmf_mode_set(p->rtp, AST_RTP_DTMF_MODE_INBAND)) { 04134 features |= DSP_FEATURE_DIGIT_DETECT; 04135 } 04136 } 04137 04138 if (ast_test_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_CNG)) { 04139 features |= DSP_FEATURE_FAX_DETECT; 04140 } 04141 04142 if (!features) { 04143 return; 04144 } 04145 04146 if (!(p->dsp = ast_dsp_new())) { 04147 return; 04148 } 04149 04150 ast_dsp_set_features(p->dsp, features); 04151 if (global_relaxdtmf) { 04152 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); 04153 } 04154 }
| static int esc_cmp_fn | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 976 of file chan_sip.c.
References CMP_MATCH, and CMP_STOP.
Referenced by initialize_escs().
00977 { 00978 struct sip_esc_entry *entry1 = obj; 00979 struct sip_esc_entry *entry2 = arg; 00980 00981 return (!strcmp(entry1->entity_tag, entry2->entity_tag)) ? (CMP_MATCH | CMP_STOP) : 0; 00982 }
| static void esc_entry_destructor | ( | void * | obj | ) | [static] |
Definition at line 962 of file chan_sip.c.
References AST_SCHED_DEL, and sched.
Referenced by create_esc_entry().
00963 { 00964 struct sip_esc_entry *esc_entry = obj; 00965 if (esc_entry->sched_id > -1) { 00966 AST_SCHED_DEL(sched, esc_entry->sched_id); 00967 } 00968 }
| static int esc_hash_fn | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 970 of file chan_sip.c.
References ast_str_hash().
Referenced by initialize_escs().
00971 { 00972 const struct sip_esc_entry *entry = obj; 00973 return ast_str_hash(entry->entity_tag); 00974 }
| static int expire_register | ( | const void * | data | ) | [static] |
Expire registration of SIP peer.
Definition at line 12998 of file chan_sip.c.
References ao2_ref, ast_debug, AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_test_flag, destroy_association(), EVENT_FLAG_SYSTEM, FALSE, manager_event, register_peer_exten(), rpeerobjs, set_socket_transport(), unlink_peer_from_tables(), and unref_peer().
Referenced by parse_register_contact(), reg_source_db(), sip_show_sched(), and sip_unregister().
12999 { 13000 struct sip_peer *peer = (struct sip_peer *)data; 13001 13002 if (!peer) { /* Hmmm. We have no peer. Weird. */ 13003 return 0; 13004 } 13005 13006 peer->expire = -1; 13007 peer->portinuri = 0; 13008 13009 destroy_association(peer); /* remove registration data from storage */ 13010 set_socket_transport(&peer->socket, peer->default_outbound_transport); 13011 13012 if (peer->socket.tcptls_session) { 13013 ao2_ref(peer->socket.tcptls_session, -1); 13014 peer->socket.tcptls_session = NULL; 13015 } 13016 13017 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 13018 register_peer_exten(peer, FALSE); /* Remove regexten */ 13019 ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name); 13020 13021 /* Do we need to release this peer from memory? 13022 Only for realtime peers and autocreated peers 13023 */ 13024 if (peer->is_realtime) { 13025 ast_debug(3, "-REALTIME- peer expired registration. Name: %s. Realtime peer objects now %d\n", peer->name, rpeerobjs); 13026 } 13027 13028 if (peer->selfdestruct || 13029 ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 13030 unlink_peer_from_tables(peer); 13031 } 13032 13033 /* Only clear the addr after we check for destruction. The addr must remain 13034 * in order to unlink from the peers_by_ip container correctly */ 13035 memset(&peer->addr, 0, sizeof(peer->addr)); 13036 13037 unref_peer(peer, "removing peer ref for expire_register"); 13038 13039 return 0; 13040 }
| static void extract_uri | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Check Contact: URI of SIP message.
Definition at line 11295 of file chan_sip.c.
References ast_copy_string(), ast_string_field_set, ast_strlen_zero(), get_header(), and remove_uri_parameters().
Referenced by handle_incoming(), and handle_request_invite().
11296 { 11297 char stripped[SIPBUFSIZE]; 11298 char *c; 11299 11300 ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped)); 11301 c = get_in_brackets(stripped); 11302 /* Cut the URI at the at sign after the @, not in the username part */ 11303 c = remove_uri_parameters(c); 11304 if (!ast_strlen_zero(c)) { 11305 ast_string_field_set(p, uri, c); 11306 } 11307 11308 }
| static const char* faxec2str | ( | int | faxec | ) | [static] |
Definition at line 16553 of file chan_sip.c.
References faxecmodes, and map_x_s().
Referenced by _sip_show_peer(), and sip_show_settings().
16554 { 16555 return map_x_s(faxecmodes, faxec, "Unknown"); 16556 }
| static int finalize_content | ( | struct sip_request * | req | ) | [static] |
Add 'Content-Length' header and content to SIP message.
Definition at line 9350 of file chan_sip.c.
References add_header(), ast_log(), ast_str_append(), ast_str_buffer(), ast_str_strlen(), and LOG_WARNING.
Referenced by send_request(), and send_response().
09351 { 09352 char clen[10]; 09353 09354 if (req->lines) { 09355 ast_log(LOG_WARNING, "finalize_content() called on a message that has already been finalized\n"); 09356 return -1; 09357 } 09358 09359 snprintf(clen, sizeof(clen), "%zd", ast_str_strlen(req->content)); 09360 add_header(req, "Content-Length", clen); 09361 09362 if (ast_str_strlen(req->content)) { 09363 ast_str_append(&req->data, 0, "\r\n%s", ast_str_buffer(req->content)); 09364 req->len = ast_str_strlen(req->data); 09365 } 09366 req->lines = ast_str_strlen(req->content) ? 1 : 0; 09367 return 0; 09368 }
| static const char * find_alias | ( | const char * | name, | |
| const char * | _default | |||
| ) | [static] |
Find compressed SIP alias.
Structure for conversion between compressed SIP and "normal" SIP
Definition at line 6949 of file chan_sip.c.
References aliases, and ARRAY_LEN.
06950 { 06951 /*! \brief Structure for conversion between compressed SIP and "normal" SIP */ 06952 static const struct cfalias { 06953 char * const fullname; 06954 char * const shortname; 06955 } aliases[] = { 06956 { "Content-Type", "c" }, 06957 { "Content-Encoding", "e" }, 06958 { "From", "f" }, 06959 { "Call-ID", "i" }, 06960 { "Contact", "m" }, 06961 { "Content-Length", "l" }, 06962 { "Subject", "s" }, 06963 { "To", "t" }, 06964 { "Supported", "k" }, 06965 { "Refer-To", "r" }, 06966 { "Referred-By", "b" }, 06967 { "Allow-Events", "u" }, 06968 { "Event", "o" }, 06969 { "Via", "v" }, 06970 { "Accept-Contact", "a" }, 06971 { "Reject-Contact", "j" }, 06972 { "Request-Disposition", "d" }, 06973 { "Session-Expires", "x" }, 06974 { "Identity", "y" }, 06975 { "Identity-Info", "n" }, 06976 }; 06977 int x; 06978 06979 for (x = 0; x < ARRAY_LEN(aliases); x++) { 06980 if (!strcasecmp(aliases[x].fullname, name)) 06981 return aliases[x].shortname; 06982 } 06983 06984 return _default; 06985 }
| static int find_by_callid_helper | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1656 of file chan_sip.c.
References CMP_MATCH, CMP_STOP, and ast_cc_agent::private_data.
Referenced by find_sip_cc_agent_by_original_callid().
01657 { 01658 struct ast_cc_agent *agent = obj; 01659 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01660 struct sip_pvt *call_pvt = arg; 01661 01662 return !strcmp(agent_pvt->original_callid, call_pvt->callid) ? CMP_MATCH | CMP_STOP : 0; 01663 }
| static int find_by_name | ( | void * | obj, | |
| void * | arg, | |||
| void * | data, | |||
| int | flags | |||
| ) | [static] |
Definition at line 4751 of file chan_sip.c.
References CMP_MATCH, CMP_STOP, and match().
Referenced by ast_setlocale(), find_peer(), and store_by_locale().
04752 { 04753 struct sip_peer *search = obj, *match = arg; 04754 int *which_objects = data; 04755 04756 /* Usernames in SIP uri's are case sensitive. Domains are not */ 04757 if (strcmp(search->name, match->name)) { 04758 return 0; 04759 } 04760 04761 switch (*which_objects) { 04762 case FINDUSERS: 04763 if (!(search->type & SIP_TYPE_USER)) { 04764 return 0; 04765 } 04766 break; 04767 case FINDPEERS: 04768 if (!(search->type & SIP_TYPE_PEER)) { 04769 return 0; 04770 } 04771 break; 04772 case FINDALLDEVICES: 04773 break; 04774 } 04775 04776 return CMP_MATCH | CMP_STOP; 04777 }
| static int find_by_notify_uri_helper | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1626 of file chan_sip.c.
References CMP_MATCH, CMP_STOP, and ast_cc_agent::private_data.
Referenced by find_sip_cc_agent_by_notify_uri().
01627 { 01628 struct ast_cc_agent *agent = obj; 01629 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01630 const char *uri = arg; 01631 01632 return !sip_uri_cmp(agent_pvt->notify_uri, uri) ? CMP_MATCH | CMP_STOP : 0; 01633 }
| static int find_by_subscribe_uri_helper | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1641 of file chan_sip.c.
References CMP_MATCH, CMP_STOP, and ast_cc_agent::private_data.
Referenced by find_sip_cc_agent_by_subscribe_uri().
01642 { 01643 struct ast_cc_agent *agent = obj; 01644 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01645 const char *uri = arg; 01646 01647 return !sip_uri_cmp(agent_pvt->subscribe_uri, uri) ? CMP_MATCH | CMP_STOP : 0; 01648 }
| static struct sip_pvt * find_call | ( | struct sip_request * | req, | |
| struct ast_sockaddr * | addr, | |||
| const int | intended_method | |||
| ) | [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_incoming(), sipsock_read
Definition at line 7603 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_next, ao2_t_callback, ao2_t_find, args, ast_debug, ast_strlen_zero(), dialog_find_multiple(), dialogs, get_header(), gettag(), match_req_to_dialog(), OBJ_MULTIPLE, OBJ_POINTER, sip_alloc(), sip_cfg, sip_methods, sip_pvt_lock, SIP_REQ_LOOP_DETECTED, SIP_REQ_MATCH, SIP_REQ_NOT_MATCH, cfsip_methods::text, and transmit_response_using_temp().
Referenced by handle_request_do().
07604 { 07605 char totag[128]; 07606 char fromtag[128]; 07607 const char *callid = get_header(req, "Call-ID"); 07608 const char *from = get_header(req, "From"); 07609 const char *to = get_header(req, "To"); 07610 const char *cseq = get_header(req, "Cseq"); 07611 struct sip_pvt *sip_pvt_ptr; 07612 unsigned int seqno; 07613 /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */ 07614 /* get_header always returns non-NULL so we must use ast_strlen_zero() */ 07615 if (ast_strlen_zero(callid) || ast_strlen_zero(to) || 07616 ast_strlen_zero(from) || ast_strlen_zero(cseq) || 07617 (sscanf(cseq, "%30u", &seqno) != 1)) { 07618 07619 /* RFC 3261 section 24.4.1. Send a 400 Bad Request if the request is malformed. */ 07620 if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) { 07621 transmit_response_using_temp(callid, addr, 1, intended_method, 07622 req, "400 Bad Request"); 07623 } 07624 return NULL; /* Invalid packet */ 07625 } 07626 07627 if (sip_cfg.pedanticsipchecking) { 07628 /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy 07629 we need more to identify a branch - so we have to check branch, from 07630 and to tags to identify a call leg. 07631 For Asterisk to behave correctly, you need to turn on pedanticsipchecking 07632 in sip.conf 07633 */ 07634 if (gettag(req, "To", totag, sizeof(totag))) 07635 req->has_to_tag = 1; /* Used in handle_request/response */ 07636 gettag(req, "From", fromtag, sizeof(fromtag)); 07637 07638 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); 07639 07640 /* All messages must always have From: tag */ 07641 if (ast_strlen_zero(fromtag)) { 07642 ast_debug(5, "%s request has no from tag, dropping callid: %s from: %s\n", sip_methods[req->method].text , callid, from ); 07643 return NULL; 07644 } 07645 /* reject requests that must always have a To: tag */ 07646 if (ast_strlen_zero(totag) && (req->method == SIP_ACK || req->method == SIP_BYE || req->method == SIP_INFO )) { 07647 ast_debug(5, "%s must have a to tag. dropping callid: %s from: %s\n", sip_methods[req->method].text , callid, from ); 07648 return NULL; 07649 } 07650 } 07651 07652 if (!sip_cfg.pedanticsipchecking) { 07653 struct sip_pvt tmp_dialog = { 07654 .callid = callid, 07655 }; 07656 sip_pvt_ptr = ao2_t_find(dialogs, &tmp_dialog, OBJ_POINTER, "ao2_find in dialogs"); 07657 if (sip_pvt_ptr) { /* well, if we don't find it-- what IS in there? */ 07658 /* Found the call */ 07659 sip_pvt_lock(sip_pvt_ptr); 07660 return sip_pvt_ptr; 07661 } 07662 } else { /* in pedantic mode! -- do the fancy search */ 07663 struct sip_pvt tmp_dialog = { 07664 .callid = callid, 07665 }; 07666 struct match_req_args args = { 0, }; 07667 int found; 07668 struct ao2_iterator *iterator = ao2_t_callback(dialogs, 07669 OBJ_POINTER | OBJ_MULTIPLE, 07670 dialog_find_multiple, 07671 &tmp_dialog, 07672 "pedantic ao2_find in dialogs"); 07673 struct sip_via *via = NULL; 07674 07675 args.method = req->method; 07676 args.callid = NULL; /* we already matched this. */ 07677 args.totag = totag; 07678 args.fromtag = fromtag; 07679 args.seqno = seqno; 07680 07681 /* If this is a Request, set the Via and Authorization header arguments */ 07682 if (req->method != SIP_RESPONSE) { 07683 args.ruri = REQ_OFFSET_TO_STR(req, rlPart2); 07684 via = parse_via(get_header(req, "Via")); 07685 if (via) { 07686 args.viasentby = via->sent_by; 07687 args.viabranch = via->branch; 07688 } 07689 if (!ast_strlen_zero(get_header(req, "Authorization")) || 07690 !ast_strlen_zero(get_header(req, "Proxy-Authorization"))) { 07691 args.authentication_present = 1; 07692 } 07693 } 07694 07695 /* Iterate a list of dialogs already matched by Call-id */ 07696 while (iterator && (sip_pvt_ptr = ao2_iterator_next(iterator))) { 07697 found = match_req_to_dialog(sip_pvt_ptr, &args); 07698 07699 switch (found) { 07700 case SIP_REQ_MATCH: 07701 sip_pvt_lock(sip_pvt_ptr); 07702 ao2_iterator_destroy(iterator); 07703 free_via(via); 07704 return sip_pvt_ptr; /* return pvt with ref */ 07705 case SIP_REQ_LOOP_DETECTED: 07706 /* This is likely a forked Request that somehow resulted in us receiving multiple parts of the fork. 07707 * RFC 3261 section 8.2.2.2, Indicate that we want to merge requests by sending a 482 response. */ 07708 transmit_response_using_temp(callid, addr, 1, intended_method, req, "482 (Loop Detected)"); 07709 dialog_unref(sip_pvt_ptr, "pvt did not match incoming SIP msg, unref from search."); 07710 ao2_iterator_destroy(iterator); 07711 free_via(via); 07712 return NULL; 07713 case SIP_REQ_NOT_MATCH: 07714 default: 07715 dialog_unref(sip_pvt_ptr, "pvt did not match incoming SIP msg, unref from search"); 07716 } 07717 } 07718 if (iterator) { 07719 ao2_iterator_destroy(iterator); 07720 } 07721 07722 free_via(via); 07723 } /* end of pedantic mode Request/Reponse to Dialog matching */ 07724 07725 /* See if the method is capable of creating a dialog */ 07726 if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) { 07727 struct sip_pvt *p = NULL; 07728 07729 if (intended_method == SIP_REFER) { 07730 /* We do support REFER, but not outside of a dialog yet */ 07731 transmit_response_using_temp(callid, addr, 1, intended_method, req, "603 Declined (no dialog)"); 07732 } else { 07733 /* Ok, time to create a new SIP dialog object, a pvt */ 07734 if ((p = sip_alloc(callid, addr, 1, intended_method, req))) { 07735 /* Ok, we've created a dialog, let's go and process it */ 07736 sip_pvt_lock(p); 07737 } else { 07738 /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not 07739 getting a dialog from sip_alloc. 07740 07741 Without a dialog we can't retransmit and handle ACKs and all that, but at least 07742 send an error message. 07743 07744 Sorry, we apologize for the inconvienience 07745 */ 07746 transmit_response_using_temp(callid, addr, 1, intended_method, req, "500 Server internal error"); 07747 ast_debug(4, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n"); 07748 } 07749 } 07750 return p; /* can be NULL */ 07751 } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) { 07752 /* A method we do not support, let's take it on the volley */ 07753 transmit_response_using_temp(callid, addr, 1, intended_method, req, "501 Method Not Implemented"); 07754 ast_debug(2, "Got a request with unsupported SIP method.\n"); 07755 } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) { 07756 /* This is a request outside of a dialog that we don't know about */ 07757 transmit_response_using_temp(callid, addr, 1, intended_method, req, "481 Call leg/transaction does not exist"); 07758 ast_debug(2, "That's odd... Got a request in unknown dialog. Callid %s\n", callid ? callid : "<unknown>"); 07759 } 07760 /* We do not respond to responses for dialogs that we don't know about, we just drop 07761 the session quickly */ 07762 if (intended_method == SIP_RESPONSE) 07763 ast_debug(2, "That's odd... Got a response on a call we don't know about. Callid %s\n", callid ? callid : "<unknown>"); 07764 07765 return NULL; 07766 }
| static int find_calling_channel | ( | void * | obj, | |
| void * | arg, | |||
| void * | data, | |||
| int | flags | |||
| ) | [static] |
Find the channel that is causing the RINGING update.
Definition at line 11841 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, CMP_MATCH, CMP_STOP, ast_channel::context, ast_channel::exten, ast_channel::macroexten, ast_channel::pbx, and sip_cfg.
Referenced by state_notify_build_xml().
11842 { 11843 struct ast_channel *c = obj; 11844 struct sip_pvt *p = data; 11845 int res; 11846 11847 ast_channel_lock(c); 11848 11849 res = (c->pbx && 11850 (!strcasecmp(c->macroexten, p->exten) || !strcasecmp(c->exten, p->exten)) && 11851 (sip_cfg.notifycid == IGNORE_CONTEXT || !strcasecmp(c->context, p->context))); 11852 11853 ast_channel_unlock(c); 11854 11855 return res ? CMP_MATCH | CMP_STOP : 0; 11856 }
| 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 4282 of file chan_sip.c.
Referenced by parse_moved_contact().
04283 { 04284 char last_char = '\0'; 04285 const char *s; 04286 for (s = start; *s && s != lim; last_char = *s++) { 04287 if (*s == '"' && last_char != '\\') 04288 break; 04289 } 04290 return s; 04291 }
| static struct sip_peer * find_peer | ( | const char * | peer, | |
| struct ast_sockaddr * | addr, | |||
| int | realtime, | |||
| int | which_objects, | |||
| int | devstate_only, | |||
| int | transport | |||
| ) | [static] |
Locate device by name or ip address.
| peer,sin,realtime,devstate_only,transport | ||
| which_objects | Define which objects should be matched when doing a lookup by name. Valid options are FINDUSERS, FINDPEERS, or FINDALLDEVICES. Note that this option is not used at all when doing a lookup by IP. |
Definition at line 4792 of file chan_sip.c.
References ao2_t_callback_data, ao2_t_find, ast_copy_string(), ast_set_flag, ast_sockaddr_copy(), find_by_name(), OBJ_POINTER, peers_by_ip, realtime_peer(), and unref_peer().
04793 { 04794 struct sip_peer *p = NULL; 04795 struct sip_peer tmp_peer; 04796 04797 if (peer) { 04798 ast_copy_string(tmp_peer.name, peer, sizeof(tmp_peer.name)); 04799 p = ao2_t_callback_data(peers, OBJ_POINTER, find_by_name, &tmp_peer, &which_objects, "ao2_find in peers table"); 04800 } else if (addr) { /* search by addr? */ 04801 ast_sockaddr_copy(&tmp_peer.addr, addr); 04802 tmp_peer.flags[0].flags = 0; 04803 tmp_peer.transports = transport; 04804 p = ao2_t_find(peers_by_ip, &tmp_peer, OBJ_POINTER, "ao2_find in peers_by_ip table"); /* WAS: p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp); */ 04805 if (!p) { 04806 ast_set_flag(&tmp_peer.flags[0], SIP_INSECURE_PORT); 04807 p = ao2_t_find(peers_by_ip, &tmp_peer, OBJ_POINTER, "ao2_find in peers_by_ip table 2"); /* WAS: p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp); */ 04808 if (p) { 04809 return p; 04810 } 04811 } 04812 } 04813 04814 if (!p && (realtime || devstate_only)) { 04815 p = realtime_peer(peer, addr, devstate_only, which_objects); 04816 if (p) { 04817 switch (which_objects) { 04818 case FINDUSERS: 04819 if (!(p->type & SIP_TYPE_USER)) { 04820 unref_peer(p, "Wrong type of realtime SIP endpoint"); 04821 return NULL; 04822 } 04823 break; 04824 case FINDPEERS: 04825 if (!(p->type & SIP_TYPE_PEER)) { 04826 unref_peer(p, "Wrong type of realtime SIP endpoint"); 04827 return NULL; 04828 } 04829 break; 04830 case FINDALLDEVICES: 04831 break; 04832 } 04833 } 04834 } 04835 04836 return p; 04837 }
| static struct sip_auth * find_realm_authentication | ( | struct sip_auth * | authlist, | |
| const char * | realm | |||
| ) | [static] |
Find authentication for a specific realm.
Definition at line 25857 of file chan_sip.c.
Referenced by build_reply_digest().
25858 { 25859 struct sip_auth *a; 25860 25861 for (a = authlist; a; a = a->next) { 25862 if (!strcasecmp(a->realm, realm)) 25863 break; 25864 } 25865 25866 return a; 25867 }
| static int find_sdp | ( | struct sip_request * | req | ) | [static] |
Determine whether a SIP message contains an SDP in its body.
| req | the SIP request to process |
Definition at line 8117 of file chan_sip.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), FALSE, get_header(), LOG_WARNING, strcasestr(), and TRUE.
Referenced by handle_incoming(), handle_request_invite(), handle_response(), and handle_response_invite().
08118 { 08119 const char *content_type; 08120 const char *content_length; 08121 const char *search; 08122 char *boundary; 08123 unsigned int x; 08124 int boundaryisquoted = FALSE; 08125 int found_application_sdp = FALSE; 08126 int found_end_of_headers = FALSE; 08127 08128 content_length = get_header(req, "Content-Length"); 08129 08130 if (!ast_strlen_zero(content_length)) { 08131 if (sscanf(content_length, "%30u", &x) != 1) { 08132 ast_log(LOG_WARNING, "Invalid Content-Length: %s\n", content_length); 08133 return 0; 08134 } 08135 08136 /* Content-Length of zero means there can't possibly be an 08137 SDP here, even if the Content-Type says there is */ 08138 if (x == 0) 08139 return 0; 08140 } 08141 08142 content_type = get_header(req, "Content-Type"); 08143 08144 /* if the body contains only SDP, this is easy */ 08145 if (!strncasecmp(content_type, "application/sdp", 15)) { 08146 req->sdp_start = 0; 08147 req->sdp_count = req->lines; 08148 return req->lines ? 1 : 0; 08149 } 08150 08151 /* if it's not multipart/mixed, there cannot be an SDP */ 08152 if (strncasecmp(content_type, "multipart/mixed", 15)) 08153 return 0; 08154 08155 /* if there is no boundary marker, it's invalid */ 08156 if ((search = strcasestr(content_type, ";boundary="))) 08157 search += 10; 08158 else if ((search = strcasestr(content_type, "; boundary="))) 08159 search += 11; 08160 else 08161 return 0; 08162 08163 if (ast_strlen_zero(search)) 08164 return 0; 08165 08166 /* If the boundary is quoted with ", remove quote */ 08167 if (*search == '\"') { 08168 search++; 08169 boundaryisquoted = TRUE; 08170 } 08171 08172 /* make a duplicate of the string, with two extra characters 08173 at the beginning */ 08174 boundary = ast_strdupa(search - 2); 08175 boundary[0] = boundary[1] = '-'; 08176 /* Remove final quote */ 08177 if (boundaryisquoted) 08178 boundary[strlen(boundary) - 1] = '\0'; 08179 08180 /* search for the boundary marker, the empty line delimiting headers from 08181 sdp part and the end boundry if it exists */ 08182 08183 for (x = 0; x < (req->lines); x++) { 08184 const char *line = REQ_OFFSET_TO_STR(req, line[x]); 08185 if (!strncasecmp(line, boundary, strlen(boundary))){ 08186 if (found_application_sdp && found_end_of_headers) { 08187 req->sdp_count = (x - 1) - req->sdp_start; 08188 return 1; 08189 } 08190 found_application_sdp = FALSE; 08191 } 08192 if (!strcasecmp(line, "Content-Type: application/sdp")) 08193 found_application_sdp = TRUE; 08194 08195 if (ast_strlen_zero(line)) { 08196 if (found_application_sdp && !found_end_of_headers){ 08197 req->sdp_start = x; 08198 found_end_of_headers = TRUE; 08199 } 08200 } 08201 } 08202 if (found_application_sdp && found_end_of_headers) { 08203 req->sdp_count = x - req->sdp_start; 08204 return TRUE; 08205 } 08206 return FALSE; 08207 }
| static struct ast_cc_agent* find_sip_cc_agent_by_notify_uri | ( | const char *const | uri | ) | [static] |
Definition at line 1635 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().
01636 { 01637 struct ast_cc_agent *agent = ast_cc_agent_callback(0, find_by_notify_uri_helper, (char *)uri, "SIP"); 01638 return agent; 01639 }
| static struct ast_cc_agent* find_sip_cc_agent_by_original_callid | ( | struct sip_pvt * | pvt | ) | [static] |
Definition at line 1665 of file chan_sip.c.
References ast_cc_agent_callback(), and find_by_callid_helper().
Referenced by add_cc_call_info_to_response().
01666 { 01667 struct ast_cc_agent *agent = ast_cc_agent_callback(0, find_by_callid_helper, pvt, "SIP"); 01668 return agent; 01669 }
| static struct ast_cc_agent* find_sip_cc_agent_by_subscribe_uri | ( | const char *const | uri | ) | [static] |
Definition at line 1650 of file chan_sip.c.
References ast_cc_agent_callback(), and find_by_subscribe_uri_helper().
Referenced by handle_cc_subscribe().
01651 { 01652 struct ast_cc_agent *agent = ast_cc_agent_callback(0, find_by_subscribe_uri_helper, (char *)uri, "SIP"); 01653 return agent; 01654 }
| static int find_sip_method | ( | const char * | msg | ) | [static] |
find_sip_method: Find SIP method from header
Definition at line 3080 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().
03081 { 03082 int i, res = 0; 03083 03084 if (ast_strlen_zero(msg)) { 03085 return 0; 03086 } 03087 for (i = 1; i < ARRAY_LEN(sip_methods) && !res; i++) { 03088 if (method_match(i, msg)) { 03089 res = sip_methods[i].id; 03090 } 03091 } 03092 return res; 03093 }
| static int find_sip_monitor_instance_by_subscription_pvt | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1863 of file chan_sip.c.
References CMP_MATCH, and CMP_STOP.
Referenced by handle_cc_notify(), and handle_response().
01864 { 01865 struct sip_monitor_instance *monitor_instance = obj; 01866 return monitor_instance->subscription_pvt == arg ? CMP_MATCH | CMP_STOP : 0; 01867 }
| static int find_sip_monitor_instance_by_suspension_entry | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1869 of file chan_sip.c.
References CMP_MATCH, and CMP_STOP.
Referenced by cc_handle_publish_error().
01870 { 01871 struct sip_monitor_instance *monitor_instance = obj; 01872 return monitor_instance->suspension_entry == arg ? CMP_MATCH | CMP_STOP : 0; 01873 }
| static struct epa_static_data* find_static_data | ( | const char *const | event_package | ) | [static] |
Definition at line 890 of file chan_sip.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, and AST_LIST_UNLOCK.
Referenced by create_epa_entry().
00891 { 00892 const struct epa_backend *backend = NULL; 00893 00894 AST_LIST_LOCK(&epa_static_data_list); 00895 AST_LIST_TRAVERSE(&epa_static_data_list, backend, next) { 00896 if (!strcmp(backend->static_data->name, event_package)) { 00897 break; 00898 } 00899 } 00900 AST_LIST_UNLOCK(&epa_static_data_list); 00901 return backend ? backend->static_data : NULL; 00902 }
| static struct cfsubscription_types * find_subscription_type | ( | enum subscriptiontype | subtype | ) | [static] |
Find subscription type in array.
Definition at line 17398 of file chan_sip.c.
References ARRAY_LEN, subscription_types, and type.
Referenced by transmit_state_notify().
17399 { 17400 int i; 17401 17402 for (i = 1; i < ARRAY_LEN(subscription_types); i++) { 17403 if (subscription_types[i].type == subtype) { 17404 return &subscription_types[i]; 17405 } 17406 } 17407 return &subscription_types[0]; 17408 }
| static void free_old_route | ( | struct sip_route * | route | ) | [static] |
Remove route from route list.
Definition at line 13440 of file chan_sip.c.
References ast_free.
Referenced by __sip_destroy(), and build_route().
13441 { 13442 struct sip_route *next; 13443 13444 while (route) { 13445 next = route->next; 13446 ast_free(route); 13447 route = next; 13448 } 13449 }
| 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 18489 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_strlen_zero(), check_sip_domain(), and LOG_WARNING.
18490 { 18491 if (ast_strlen_zero(data)) { 18492 ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n"); 18493 return -1; 18494 } 18495 if (check_sip_domain(data, NULL, 0)) 18496 ast_copy_string(buf, data, len); 18497 else 18498 buf[0] = '\0'; 18499 return 0; 18500 }
| 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 18430 of file chan_sip.c.
References __get_header(), args, AST_APP_ARG, ast_channel_lock, ast_channel_unlock, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_strlen_zero(), LOG_WARNING, ast_channel::tech, and ast_channel::tech_pvt.
18431 { 18432 struct sip_pvt *p; 18433 const char *content = NULL; 18434 AST_DECLARE_APP_ARGS(args, 18435 AST_APP_ARG(header); 18436 AST_APP_ARG(number); 18437 ); 18438 int i, number, start = 0; 18439 18440 if (ast_strlen_zero(data)) { 18441 ast_log(LOG_WARNING, "This function requires a header name.\n"); 18442 return -1; 18443 } 18444 18445 ast_channel_lock(chan); 18446 if (!IS_SIP_TECH(chan->tech)) { 18447 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 18448 ast_channel_unlock(chan); 18449 return -1; 18450 } 18451 18452 AST_STANDARD_APP_ARGS(args, data); 18453 if (!args.number) { 18454 number = 1; 18455 } else { 18456 sscanf(args.number, "%30d", &number); 18457 if (number < 1) 18458 number = 1; 18459 } 18460 18461 p = chan->tech_pvt; 18462 18463 /* If there is no private structure, this channel is no longer alive */ 18464 if (!p) { 18465 ast_channel_unlock(chan); 18466 return -1; 18467 } 18468 18469 for (i = 0; i < number; i++) 18470 content = __get_header(&p->initreq, args.header, &start); 18471 18472 if (ast_strlen_zero(content)) { 18473 ast_channel_unlock(chan); 18474 return -1; 18475 } 18476 18477 ast_copy_string(buf, content, len); 18478 ast_channel_unlock(chan); 18479 18480 return 0; 18481 }
| static int function_sipchaninfo_read | ( | struct ast_channel * | chan, | |
| const char * | cmd, | |||
| char * | data, | |||
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
${SIPCHANINFO()} Dialplan function - reads sip channel data
Definition at line 18607 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_log(), ast_sockaddr_stringify_addr(), LOG_WARNING, ast_channel::tech, and ast_channel::tech_pvt.
18608 { 18609 struct sip_pvt *p; 18610 static int deprecated = 0; 18611 18612 *buf = 0; 18613 18614 if (!data) { 18615 ast_log(LOG_WARNING, "This function requires a parameter name.\n"); 18616 return -1; 18617 } 18618 18619 ast_channel_lock(chan); 18620 if (!IS_SIP_TECH(chan->tech)) { 18621 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 18622 ast_channel_unlock(chan); 18623 return -1; 18624 } 18625 18626 if (deprecated++ % 20 == 0) { 18627 /* Deprecated in 1.6.1 */ 18628 ast_log(LOG_WARNING, "SIPCHANINFO() is deprecated. Please transition to using CHANNEL().\n"); 18629 } 18630 18631 p = chan->tech_pvt; 18632 18633 /* If there is no private structure, this channel is no longer alive */ 18634 if (!p) { 18635 ast_channel_unlock(chan); 18636 return -1; 18637 } 18638 18639 if (!strcasecmp(data, "peerip")) { 18640 ast_copy_string(buf, ast_sockaddr_stringify_addr(&p->sa), len); 18641 } else if (!strcasecmp(data, "recvip")) { 18642 ast_copy_string(buf, ast_sockaddr_stringify_addr(&p->recv), len); 18643 } else if (!strcasecmp(data, "from")) { 18644 ast_copy_string(buf, p->from, len); 18645 } else if (!strcasecmp(data, "uri")) { 18646 ast_copy_string(buf, p->uri, len); 18647 } else if (!strcasecmp(data, "useragent")) { 18648 ast_copy_string(buf, p->useragent, len); 18649 } else if (!strcasecmp(data, "peername")) { 18650 ast_copy_string(buf, p->peername, len); 18651 } else if (!strcasecmp(data, "t38passthrough")) { 18652 if (p->t38.state == T38_DISABLED) { 18653 ast_copy_string(buf, "0", len); 18654 } else { /* T38 is offered or enabled in this call */ 18655 ast_copy_string(buf, "1", len); 18656 } 18657 } else { 18658 ast_channel_unlock(chan); 18659 return -1; 18660 } 18661 ast_channel_unlock(chan); 18662 18663 return 0; 18664 }
| 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 18508 of file chan_sip.c.
References ast_codec_pref_index(), ast_copy_string(), ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_print_group(), ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_str_alloca, ast_test_flag, chanvar, FALSE, find_peer(), LOG_WARNING, ast_variable::name, ast_variable::next, peer_mailboxes_to_str(), peer_status(), strsep(), TRUE, unref_peer(), and ast_variable::value.
18509 { 18510 struct sip_peer *peer; 18511 char *colname; 18512 18513 if ((colname = strchr(data, ':'))) { /*! \todo Will be deprecated after 1.4 */ 18514 static int deprecation_warning = 0; 18515 *colname++ = '\0'; 18516 if (deprecation_warning++ % 10 == 0) 18517 ast_log(LOG_WARNING, "SIPPEER(): usage of ':' to separate arguments is deprecated. Please use ',' instead.\n"); 18518 } else if ((colname = strchr(data, ','))) 18519 *colname++ = '\0'; 18520 else 18521 colname = "ip"; 18522 18523 if (!(peer = find_peer(data, NULL, TRUE, FINDPEERS, FALSE, 0))) 18524 return -1; 18525 18526 if (!strcasecmp(colname, "ip")) { 18527 ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len); 18528 } else if (!strcasecmp(colname, "port")) { 18529 snprintf(buf, len, "%d", ast_sockaddr_port(&peer->addr)); 18530 } else if (!strcasecmp(colname, "status")) { 18531 peer_status(peer, buf, len); 18532 } else if (!strcasecmp(colname, "language")) { 18533 ast_copy_string(buf, peer->language, len); 18534 } else if (!strcasecmp(colname, "regexten")) { 18535 ast_copy_string(buf, peer->regexten, len); 18536 } else if (!strcasecmp(colname, "limit")) { 18537 snprintf(buf, len, "%d", peer->call_limit); 18538 } else if (!strcasecmp(colname, "busylevel")) { 18539 snprintf(buf, len, "%d", peer->busy_level); 18540 } else if (!strcasecmp(colname, "curcalls")) { 18541 snprintf(buf, len, "%d", peer->inUse); 18542 } else if (!strcasecmp(colname, "maxforwards")) { 18543 snprintf(buf, len, "%d", peer->maxforwards); 18544 } else if (!strcasecmp(colname, "accountcode")) { 18545 ast_copy_string(buf, peer->accountcode, len); 18546 } else if (!strcasecmp(colname, "callgroup")) { 18547 ast_print_group(buf, len, peer->callgroup); 18548 } else if (!strcasecmp(colname, "pickupgroup")) { 18549 ast_print_group(buf, len, peer->pickupgroup); 18550 } else if (!strcasecmp(colname, "useragent")) { 18551 ast_copy_string(buf, peer->useragent, len); 18552 } else if (!strcasecmp(colname, "mailbox")) { 18553 struct ast_str *mailbox_str = ast_str_alloca(512); 18554 peer_mailboxes_to_str(&mailbox_str, peer); 18555 ast_copy_string(buf, mailbox_str->str, len); 18556 } else if (!strcasecmp(colname, "context")) { 18557 ast_copy_string(buf, peer->context, len); 18558 } else if (!strcasecmp(colname, "expire")) { 18559 snprintf(buf, len, "%d", peer->expire); 18560 } else if (!strcasecmp(colname, "dynamic")) { 18561 ast_copy_string(buf, peer->host_dynamic ? "yes" : "no", len); 18562 } else if (!strcasecmp(colname, "callerid_name")) { 18563 ast_copy_string(buf, peer->cid_name, len); 18564 } else if (!strcasecmp(colname, "callerid_num")) { 18565 ast_copy_string(buf, peer->cid_num, len); 18566 } else if (!strcasecmp(colname, "codecs")) { 18567 ast_getformatname_multiple(buf, len -1, peer->capability); 18568 } else if (!strcasecmp(colname, "encryption")) { 18569 snprintf(buf, len, "%d", ast_test_flag(&peer->flags[1], SIP_PAGE2_USE_SRTP)); 18570 } else if (!strncasecmp(colname, "chanvar[", 8)) { 18571 char *chanvar=colname + 8; 18572 struct ast_variable *v; 18573 18574 chanvar = strsep(&chanvar, "]"); 18575 for (v = peer->chanvars ; v ; v = v->next) { 18576 if (!strcasecmp(v->name, chanvar)) { 18577 ast_copy_string(buf, v->value, len); 18578 } 18579 } 18580 } else if (!strncasecmp(colname, "codec[", 6)) { 18581 char *codecnum; 18582 format_t codec = 0; 18583 18584 codecnum = colname + 6; /* move past the '[' */ 18585 codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */ 18586 if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) { 18587 ast_copy_string(buf, ast_getformatname(codec), len); 18588 } else { 18589 buf[0] = '\0'; 18590 } 18591 } else { 18592 buf[0] = '\0'; 18593 } 18594 18595 unref_peer(peer, "unref_peer from function_sippeer, just before return"); 18596 18597 return 0; 18598 }
| static char * generate_random_string | ( | char * | buf, | |
| size_t | size | |||
| ) | [static] |
Generate 32 byte random string for callid's etc.
Definition at line 7166 of file chan_sip.c.
References ast_random().
Referenced by build_callid_pvt(), build_callid_registry(), calendar_query_exec(), construct_pidf_body(), do_notify(), and generate_uri().
07167 { 07168 long val[4]; 07169 int x; 07170 07171 for (x=0; x<4; x++) 07172 val[x] = ast_random(); 07173 snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]); 07174 07175 return buf; 07176 }
| static char* generate_uri | ( | struct sip_pvt * | pvt, | |
| char * | buf, | |||
| size_t | size | |||
| ) | [static] |
Definition at line 7178 of file chan_sip.c.
References ast_copy_string(), ast_sockaddr_stringify(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_set(), and generate_random_string().
Referenced by add_cc_call_info_to_response(), and transmit_cc_notify().
07179 { 07180 struct ast_str *uri = ast_str_alloca(size); 07181 ast_str_set(&uri, 0, "%s", pvt->socket.type == SIP_TRANSPORT_TLS ? "sips:" : "sip:"); 07182 /* Here would be a great place to generate a UUID, but for now we'll 07183 * use the handy random string generation function we already have 07184 */ 07185 ast_str_append(&uri, 0, "%s", generate_random_string(buf, size)); 07186 ast_str_append(&uri, 0, "@%s", ast_sockaddr_stringify(&pvt->ourip)); 07187 ast_copy_string(buf, ast_str_buffer(uri), size); 07188 return buf; 07189 }
| int get_address_family_filter | ( | const struct ast_sockaddr * | addr | ) | [static] |
Helper for dns resolution to filter by address family.
Definition at line 24370 of file chan_sip.c.
References ast_sockaddr_is_any(), ast_sockaddr_is_ipv6(), and ast_sockaddr::ss.
Referenced by __sip_subscribe_mwi_do(), ast_sockaddr_resolve_first(), build_peer(), proxy_update(), realtime_peer(), and transmit_register().
24371 { 24372 if (ast_sockaddr_is_ipv6(addr) && ast_sockaddr_is_any(addr)) { 24373 return 0; 24374 } 24375 24376 return addr->ss.ss_family; 24377 }
| static int get_also_info | ( | struct sip_pvt * | p, | |
| struct sip_request * | oreq | |||
| ) | [static] |
Call transfer support (old way, deprecated by the IETF).
Definition at line 15004 of file chan_sip.c.
References ast_canmatch_extension(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_log(), ast_string_field_set, ast_strlen_zero(), ast_verbose, context, get_header(), LOG_WARNING, pbx_builtin_getvar_helper(), S_OR, sip_cfg, sip_debug_test_pvt(), SIP_PEDANTIC_DECODE, and sip_refer_allocate().
Referenced by handle_request_bye().
15005 { 15006 char tmp[256] = "", *c, *a; 15007 struct sip_request *req = oreq ? oreq : &p->initreq; 15008 struct sip_refer *referdata = NULL; 15009 const char *transfer_context = NULL; 15010 15011 if (!p->refer && !sip_refer_allocate(p)) 15012 return -1; 15013 15014 referdata = p->refer; 15015 15016 ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp)); 15017 c = get_in_brackets(tmp); 15018 15019 if (parse_uri(c, "sip:,sips:", &c, NULL, &a, NULL)) { 15020 ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c); 15021 return -1; 15022 } 15023 15024 SIP_PEDANTIC_DECODE(c); 15025 SIP_PEDANTIC_DECODE(a); 15026 15027 if (!ast_strlen_zero(a)) { 15028 ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain)); 15029 } 15030 15031 if (sip_debug_test_pvt(p)) 15032 ast_verbose("Looking for %s in %s\n", c, p->context); 15033 15034 if (p->owner) /* Mimic behaviour in res_features.c */ 15035 transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT"); 15036 15037 /* By default, use the context in the channel sending the REFER */ 15038 if (ast_strlen_zero(transfer_context)) { 15039 transfer_context = S_OR(p->owner->macrocontext, 15040 S_OR(p->context, sip_cfg.default_context)); 15041 } 15042 if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) { 15043 /* This is a blind transfer */ 15044 ast_debug(1, "SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context); 15045 ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to)); 15046 ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by)); 15047 ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact)); 15048 referdata->refer_call = dialog_unref(referdata->refer_call, "unreffing referdata->refer_call"); 15049 /* Set new context */ 15050 ast_string_field_set(p, context, transfer_context); 15051 return 0; 15052 } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) { 15053 return 1; 15054 } 15055 15056 return -1; 15057 }
| static char* get_body | ( | struct sip_request * | req, | |
| char * | name, | |||
| char | delimiter | |||
| ) | [static] |
Get a specific line from the message body.
Definition at line 6933 of file chan_sip.c.
References get_body_by_line(), and len().
Referenced by handle_cc_notify(), handle_request_info(), and handle_request_notify().
06934 { 06935 int x; 06936 int len = strlen(name); 06937 char *r; 06938 06939 for (x = 0; x < req->lines; x++) { 06940 r = get_body_by_line(REQ_OFFSET_TO_STR(req, line[x]), name, len, delimiter); 06941 if (r[0] != '\0') 06942 return r; 06943 } 06944 06945 return ""; 06946 }
| static char* get_body_by_line | ( | const char * | line, | |
| const char * | name, | |||
| int | nameLen, | |||
| char | delimiter | |||
| ) | [static] |
Reads one line of SIP message body.
Definition at line 6878 of file chan_sip.c.
References ast_skip_blanks().
Referenced by get_body(), and get_sdp_iterate().
06879 { 06880 if (!strncasecmp(line, name, nameLen) && line[nameLen] == delimiter) 06881 return ast_skip_blanks(line + nameLen + 1); 06882 06883 return ""; 06884 }
| static int get_cached_mwi | ( | struct sip_peer * | peer, | |
| int * | new, | |||
| int * | old | |||
| ) | [static] |
Get cached MWI info.
| 0 | At least one message is waiting | |
| 1 | no messages waiting |
Definition at line 24513 of file chan_sip.c.
References ast_event_destroy(), ast_event_get_cached(), ast_event_get_ie_uint(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, AST_LIST_TRAVERSE, mailbox, and S_OR.
Referenced by sip_send_mwi_to_peer().
24514 { 24515 struct sip_mailbox *mailbox; 24516 24517 AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { 24518 struct ast_event *event; 24519 event = ast_event_get_cached(AST_EVENT_MWI, 24520 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox->mailbox, 24521 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, S_OR(mailbox->context, "default"), 24522 AST_EVENT_IE_END); 24523 if (!event) 24524 continue; 24525 *new += ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS); 24526 *old += ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS); 24527 ast_event_destroy(event); 24528 } 24529 24530 return (*new || *old) ? 0 : 1; 24531 }
| static void get_crypto_attrib | ( | struct sip_srtp * | srtp, | |
| const char ** | a_crypto | |||
| ) | [static] |
Definition at line 10670 of file chan_sip.c.
References ast_log(), and LOG_WARNING.
Referenced by add_sdp().
10671 { 10672 /* Set encryption properties */ 10673 if (srtp) { 10674 if (!srtp->crypto) { 10675 srtp->crypto = sdp_crypto_setup(); 10676 } 10677 if (srtp->crypto && (sdp_crypto_offer(srtp->crypto) >= 0)) { 10678 *a_crypto = sdp_crypto_attrib(srtp->crypto); 10679 } 10680 10681 if (!*a_crypto) { 10682 ast_log(LOG_WARNING, "No SRTP key management enabled\n"); 10683 } 10684 } 10685 }
| static enum sip_get_dest_result get_destination | ( | struct sip_pvt * | p, | |
| struct sip_request * | oreq, | |||
| int * | cc_recall_core_id | |||
| ) | [static] |
Find out who the call is for. We use the request uri as a destination. This code assumes authentication has been done, so that the device (peer/user) context is already set.
Definition at line 14573 of file chan_sip.c.
References ao2_ref, ast_canmatch_extension(), ast_cc_agent_recalling(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_get_hint(), AST_LIST_EMPTY, ast_log(), AST_MAX_EXTENSION, ast_pickup_ext(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_verbose, check_sip_domain(), context, ast_cc_agent::core_id, ast_cc_agent::device_name, dummy(), exten, find_sip_cc_agent_by_notify_uri(), get_header(), global_flags, LOG_WARNING, ast_cc_agent::private_data, S_OR, sip_cfg, sip_debug_test_pvt(), sip_methods, SIP_PEDANTIC_DECODE, and cfsip_methods::text.
Referenced by handle_request_invite(), handle_request_options(), and handle_request_subscribe().
14574 { 14575 char tmp[256] = "", *uri, *domain, *dummy = NULL; 14576 char tmpf[256] = "", *from = NULL; 14577 struct sip_request *req; 14578 char *decoded_uri; 14579 14580 req = oreq; 14581 if (!req) { 14582 req = &p->initreq; 14583 } 14584 14585 /* Find the request URI */ 14586 if (req->rlPart2) 14587 ast_copy_string(tmp, REQ_OFFSET_TO_STR(req, rlPart2), sizeof(tmp)); 14588 14589 uri = ast_strdupa(get_in_brackets(tmp)); 14590 14591 if (parse_uri(uri, "sip:,sips:", &uri, &dummy, &domain, NULL)) { 14592 ast_log(LOG_WARNING, "Not a SIP header (%s)?\n", uri); 14593 return SIP_GET_DEST_INVALID_URI; 14594 } 14595 14596 SIP_PEDANTIC_DECODE(domain); 14597 SIP_PEDANTIC_DECODE(uri); 14598 14599 ast_string_field_set(p, domain, domain); 14600 14601 /* Now find the From: caller ID and name */ 14602 /* XXX Why is this done in get_destination? Isn't it already done? 14603 Needs to be checked 14604 */ 14605 ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf)); 14606 if (!ast_strlen_zero(tmpf)) { 14607 from = get_in_brackets(tmpf); 14608 if (parse_uri(from, "sip:,sips:", &from, NULL, &domain, NULL)) { 14609 ast_log(LOG_WARNING, "Not a SIP header (%s)?\n", from); 14610 return SIP_GET_DEST_INVALID_URI; 14611 } 14612 14613 SIP_PEDANTIC_DECODE(from); 14614 SIP_PEDANTIC_DECODE(domain); 14615 14616 ast_string_field_set(p, fromdomain, domain); 14617 } 14618 14619 if (!AST_LIST_EMPTY(&domain_list)) { 14620 char domain_context[AST_MAX_EXTENSION]; 14621 14622 domain_context[0] = '\0'; 14623 if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) { 14624 if (!sip_cfg.allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) { 14625 ast_debug(1, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain); 14626 return SIP_GET_DEST_REFUSED; 14627 } 14628 } 14629 /* If we don't have a peer (i.e. we're a guest call), 14630 * overwrite the original context */ 14631 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_HAVEPEERCONTEXT) && !ast_strlen_zero(domain_context)) { 14632 ast_string_field_set(p, context, domain_context); 14633 } 14634 } 14635 14636 /* If the request coming in is a subscription and subscribecontext has been specified use it */ 14637 if (req->method == SIP_SUBSCRIBE && !ast_strlen_zero(p->subscribecontext)) { 14638 ast_string_field_set(p, context, p->subscribecontext); 14639 } 14640 14641 if (sip_debug_test_pvt(p)) { 14642 ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain); 14643 } 14644 14645 /* Since extensions.conf can have unescaped characters, try matching a 14646 * decoded uri in addition to the non-decoded uri. */ 14647 decoded_uri = ast_strdupa(uri); 14648 ast_uri_decode(decoded_uri); 14649 14650 /* If this is a subscription we actually just need to see if a hint exists for the extension */ 14651 if (req->method == SIP_SUBSCRIBE) { 14652 char hint[AST_MAX_EXTENSION]; 14653 int which = 0; 14654 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, uri) || 14655 (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, decoded_uri) && (which = 1))) { 14656 if (!oreq) { 14657 ast_string_field_set(p, exten, which ? decoded_uri : uri); 14658 } 14659 return SIP_GET_DEST_EXTEN_FOUND; 14660 } else { 14661 return SIP_GET_DEST_EXTEN_NOT_FOUND; 14662 } 14663 } else { 14664 struct ast_cc_agent *agent; 14665 int which = 0; 14666 /* Check the dialplan for the username part of the request URI, 14667 the domain will be stored in the SIPDOMAIN variable 14668 Return 0 if we have a matching extension */ 14669 if (ast_exists_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from)) || 14670 (ast_exists_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from)) && (which = 1)) || 14671 !strcmp(decoded_uri, ast_pickup_ext())) { 14672 if (!oreq) { 14673 ast_string_field_set(p, exten, which ? decoded_uri : uri); 14674 } 14675 return SIP_GET_DEST_EXTEN_FOUND; 14676 } else if ((agent = find_sip_cc_agent_by_notify_uri(tmp))) { 14677 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 14678 /* This is a CC recall. We can set p's extension to the exten from 14679 * the original INVITE 14680 */ 14681 ast_string_field_set(p, exten, agent_pvt->original_exten); 14682 /* And we need to let the CC core know that the caller is attempting 14683 * his recall 14684 */ 14685 ast_cc_agent_recalling(agent->core_id, "SIP caller %s is attempting recall", 14686 agent->device_name); 14687 if (cc_recall_core_id) { 14688 *cc_recall_core_id = agent->core_id; 14689 } 14690 ao2_ref(agent, -1); 14691 return SIP_GET_DEST_EXTEN_FOUND; 14692 } 14693 } 14694 14695 /* Return 1 for pickup extension or overlap dialling support (if we support it) */ 14696 if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) && 14697 ast_canmatch_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from))) || 14698 !strncmp(decoded_uri, ast_pickup_ext(), strlen(decoded_uri))) { 14699 return SIP_GET_DEST_PICKUP_EXTEN_FOUND; 14700 } 14701 14702 return SIP_GET_DEST_EXTEN_NOT_FOUND; 14703 }
| static int get_domain | ( | const char * | str, | |
| char * | domain, | |||
| int | len | |||
| ) | [static] |
Extract domain from SIP To/From header.
Definition at line 10177 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_strlen_zero(), and LOG_WARNING.
Referenced by get_realm().
10178 { 10179 char tmpf[256]; 10180 char *a, *from; 10181 10182 *domain = '\0'; 10183 ast_copy_string(tmpf, str, sizeof(tmpf)); 10184 from = get_in_brackets(tmpf); 10185 if (!ast_strlen_zero(from)) { 10186 if (strncasecmp(from, "sip:", 4)) { 10187 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from); 10188 return -1; 10189 } 10190 from += 4; 10191 } else 10192 from = NULL; 10193 10194 if (from) { 10195 int bracket = 0; 10196 10197 /* Strip any params or options from user */ 10198 if ((a = strchr(from, ';'))) 10199 *a = '\0'; 10200 /* Strip port from domain if present */ 10201 for (a = from; *a != '\0'; ++a) { 10202 if (*a == ':' && bracket == 0) { 10203 *a = '\0'; 10204 break; 10205 } else if (*a == '[') { 10206 ++bracket; 10207 } else if (*a == ']') { 10208 --bracket; 10209 } 10210 } 10211 if ((a = strchr(from, '@'))) { 10212 *a = '\0'; 10213 ast_copy_string(domain, a + 1, len); 10214 } else 10215 ast_copy_string(domain, from, len); 10216 } 10217 10218 return ast_strlen_zero(domain); 10219 }
| static struct event_state_compositor* get_esc | ( | const char *const | event_package | ) | [static] |
Definition at line 984 of file chan_sip.c.
References ARRAY_LEN, event_state_compositors, and name.
Referenced by create_new_sip_etag(), handle_request_publish(), and publish_expire().
00984 { 00985 int i; 00986 for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) { 00987 if (!strcasecmp(event_package, event_state_compositors[i].name)) { 00988 return &event_state_compositors[i]; 00989 } 00990 } 00991 return NULL; 00992 }
| static struct sip_esc_entry* get_esc_entry | ( | const char * | entity_tag, | |
| struct event_state_compositor * | esc | |||
| ) | [static] |
Definition at line 994 of file chan_sip.c.
References ao2_find, ast_copy_string(), event_state_compositor::compositor, and OBJ_POINTER.
Referenced by handle_sip_publish_modify(), handle_sip_publish_refresh(), and handle_sip_publish_remove().
00994 { 00995 struct sip_esc_entry *entry; 00996 struct sip_esc_entry finder; 00997 00998 ast_copy_string(finder.entity_tag, entity_tag, sizeof(finder.entity_tag)); 00999 01000 entry = ao2_find(esc->compositor, &finder, OBJ_POINTER); 01001 01002 return entry; 01003 }
| static const char * get_header | ( | const struct sip_request * | req, | |
| const char * | name | |||
| ) | [static] |
Get header from SIP request.
Definition at line 7026 of file chan_sip.c.
References __get_header().
07027 { 07028 int start = 0; 07029 return __get_header(req, name, &start); 07030 }
| static struct ast_variable * get_insecure_variable_from_config | ( | struct ast_config * | config | ) | [static] |
Definition at line 4531 of file chan_sip.c.
References ast_category_browse(), ast_category_root(), ast_test_flag, ast_variable_retrieve(), ast_flags::flags, set_insecure_flags(), and var.
04532 { 04533 struct ast_variable *var = NULL; 04534 struct ast_flags flags = {0}; 04535 char *cat = NULL; 04536 const char *insecure; 04537 while ((cat = ast_category_browse(cfg, cat))) { 04538 insecure = ast_variable_retrieve(cfg, cat, "insecure"); 04539 set_insecure_flags(&flags, insecure, -1); 04540 if (ast_test_flag(&flags, SIP_INSECURE_PORT)) { 04541 var = ast_category_root(cfg, cat); 04542 break; 04543 } 04544 } 04545 return var; 04546 }
| static int get_ip_and_port_from_sdp | ( | struct sip_request * | req, | |
| const enum media_type | media, | |||
| struct ast_sockaddr * | addr | |||
| ) | [static] |
Definition at line 8239 of file chan_sip.c.
References ast_log(), ast_sockaddr_resolve_first_af(), ast_strlen_zero(), get_sdp_iterate(), len(), and LOG_WARNING.
Referenced by handle_request_invite().
08240 { 08241 const char *m; 08242 const char *c; 08243 int miterator = req->sdp_start; 08244 int citerator = req->sdp_start; 08245 int x = 0; 08246 int numberofports; 08247 int len; 08248 int af; 08249 char proto[4], host[258] = ""; /*Initialize to empty so we will know if we have any input */ 08250 08251 c = get_sdp_iterate(&citerator, req, "c"); 08252 if (sscanf(c, "IN %3s %256s", proto, host) != 2) { 08253 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 08254 /* Continue since there may be a valid host in a c= line specific to the audio stream */ 08255 } 08256 /* We only want the m and c lines for audio */ 08257 for (m = get_sdp_iterate(&miterator, req, "m"); !ast_strlen_zero(m); m = get_sdp_iterate(&miterator, req, "m")) { 08258 if ((media == SDP_AUDIO && ((sscanf(m, "audio %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 08259 (sscanf(m, "audio %30u RTP/AVP %n", &x, &len) == 1 && len > 0))) || 08260 (media == SDP_VIDEO && ((sscanf(m, "video %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 08261 (sscanf(m, "video %30u RTP/AVP %n", &x, &len) == 1 && len > 0)))) { 08262 /* See if there's a c= line for this media stream. 08263 * XXX There is no guarantee that we'll be grabbing the c= line for this 08264 * particular media stream here. However, this is the same logic used in process_sdp. 08265 */ 08266 c = get_sdp_iterate(&citerator, req, "c"); 08267 if (!ast_strlen_zero(c)) { 08268 sscanf(c, "IN %3s %256s", proto, host); 08269 } 08270 break; 08271 } 08272 } 08273 08274 if (!strcmp("IP4", proto)) { 08275 af = AF_INET; 08276 } else if (!strcmp("IP6", proto)) { 08277 af = AF_INET6; 08278 } else { 08279 ast_log(LOG_WARNING, "Unknown protocol '%s'.\n", proto); 08280 return -1; 08281 } 08282 08283 if (ast_strlen_zero(host) || x == 0) { 08284 ast_log(LOG_WARNING, "Failed to read an alternate host or port in SDP. Expect %s problems\n", media == SDP_AUDIO ? "audio" : "video"); 08285 return -1; 08286 } 08287 08288 if (ast_sockaddr_resolve_first_af(addr, host, 0, af)) { 08289 ast_log(LOG_WARNING, "Could not look up IP address of alternate hostname. Expect %s problems\n", media == SDP_AUDIO? "audio" : "video"); 08290 return -1; 08291 } 08292 08293 return 0; 08294 }
| static int get_msg_text | ( | char * | buf, | |
| int | len, | |||
| struct sip_request * | req, | |||
| int | addnewline | |||
| ) | [static] |
Get text out of a SIP MESSAGE packet.
Definition at line 15468 of file chan_sip.c.
Referenced by handle_request_info(), handle_request_notify(), and receive_message().
15469 { 15470 int x; 15471 int y; 15472 15473 buf[0] = '\0'; 15474 /*XXX isn't strlen(buf) going to always be 0? */ 15475 y = len - strlen(buf) - 5; 15476 if (y < 0) 15477 y = 0; 15478 for (x = 0; x < req->lines; x++) { 15479 const char *line = REQ_OFFSET_TO_STR(req, line[x]); 15480 strncat(buf, line, y); /* safe */ 15481 y -= strlen(line) + 1; 15482 if (y < 0) 15483 y = 0; 15484 if (y != 0 && addnewline) 15485 strcat(buf, "\n"); /* safe */ 15486 } 15487 return 0; 15488 }
| static const char * get_name_from_variable | ( | struct ast_variable * | var, | |
| const char * | newpeername | |||
| ) | [static] |
Definition at line 4548 of file chan_sip.c.
References ast_variable::name, ast_variable::next, ast_variable::value, and var.
04549 { 04550 struct ast_variable *tmp; 04551 for (tmp = var; tmp; tmp = tmp->next) { 04552 if (!newpeername && !strcasecmp(tmp->name, "name")) 04553 newpeername = tmp->value; 04554 } 04555 return newpeername; 04556 }
| static void get_our_media_address | ( | struct sip_pvt * | p, | |
| int | needvideo, | |||
| int | needtext, | |||
| struct ast_sockaddr * | addr, | |||
| struct ast_sockaddr * | vaddr, | |||
| struct ast_sockaddr * | taddr, | |||
| struct ast_sockaddr * | dest, | |||
| struct ast_sockaddr * | vdest, | |||
| struct ast_sockaddr * | tdest | |||
| ) | [static] |
Set all IP media addresses for this call.
Definition at line 10577 of file chan_sip.c.
References ast_rtp_instance_get_local_address(), ast_sockaddr_cmp_addr(), ast_sockaddr_copy(), ast_sockaddr_is_any(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_set_port, and media_address.
Referenced by add_sdp().
10581 { 10582 int use_externip = 0; 10583 10584 /* First, get our address */ 10585 ast_rtp_instance_get_local_address(p->rtp, addr); 10586 if (p->vrtp) { 10587 ast_rtp_instance_get_local_address(p->vrtp, vaddr); 10588 } 10589 if (p->trtp) { 10590 ast_rtp_instance_get_local_address(p->trtp, taddr); 10591 } 10592 10593 /* If our real IP differs from the local address returned by the RTP engine, use it. */ 10594 /* The premise is that if we are already using that IP to communicate with the client, */ 10595 /* we should be using it for RTP too. */ 10596 use_externip = ast_sockaddr_cmp_addr(&p->ourip, addr); 10597 10598 /* Now, try to figure out where we want them to send data */ 10599 /* Is this a re-invite to move the media out, then use the original offer from caller */ 10600 if (!ast_sockaddr_isnull(&p->redirip)) { /* If we have a redirection IP, use it */ 10601 ast_sockaddr_copy(dest, &p->redirip); 10602 } else { 10603 /* 10604 * Audio Destination IP: 10605 * 10606 * 1. Specifically configured media address. 10607 * 2. Local address as specified by the RTP engine. 10608 * 3. The local IP as defined by chan_sip. 10609 * 10610 * Audio Destination Port: 10611 * 10612 * 1. Provided by the RTP engine. 10613 */ 10614 ast_sockaddr_copy(dest, 10615 !ast_sockaddr_isnull(&media_address) ? &media_address : 10616 !ast_sockaddr_is_any(addr) && !use_externip ? addr : 10617 &p->ourip); 10618 ast_sockaddr_set_port(dest, ast_sockaddr_port(addr)); 10619 } 10620 10621 if (needvideo) { 10622 /* Determine video destination */ 10623 if (!ast_sockaddr_isnull(&p->vredirip)) { 10624 ast_sockaddr_copy(vdest, &p->vredirip); 10625 } else { 10626 /* 10627 * Video Destination IP: 10628 * 10629 * 1. Specifically configured media address. 10630 * 2. Local address as specified by the RTP engine. 10631 * 3. The local IP as defined by chan_sip. 10632 * 10633 * Video Destination Port: 10634 * 10635 * 1. Provided by the RTP engine. 10636 */ 10637 ast_sockaddr_copy(vdest, 10638 !ast_sockaddr_isnull(&media_address) ? &media_address : 10639 !ast_sockaddr_is_any(vaddr) && !use_externip ? vaddr : 10640 &p->ourip); 10641 ast_sockaddr_set_port(vdest, ast_sockaddr_port(vaddr)); 10642 } 10643 } 10644 10645 if (needtext) { 10646 /* Determine text destination */ 10647 if (!ast_sockaddr_isnull(&p->tredirip)) { 10648 ast_sockaddr_copy(tdest, &p->tredirip); 10649 } else { 10650 /* 10651 * Text Destination IP: 10652 * 10653 * 1. Specifically configured media address. 10654 * 2. Local address as specified by the RTP engine. 10655 * 3. The local IP as defined by chan_sip. 10656 * 10657 * Text Destination Port: 10658 * 10659 * 1. Provided by the RTP engine. 10660 */ 10661 ast_sockaddr_copy(tdest, 10662 !ast_sockaddr_isnull(&media_address) ? &media_address : 10663 !ast_sockaddr_is_any(taddr) && !use_externip ? taddr : 10664 &p->ourip); 10665 ast_sockaddr_set_port(tdest, ast_sockaddr_port(taddr)); 10666 } 10667 } 10668 }
| 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 14294 of file chan_sip.c.
References ast_copy_string(), ast_is_shrinkable_phonenumber(), AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, ast_set_callerid(), ast_shrink_phone_number(), ast_skip_blanks(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), cid_name, cid_num, get_header(), and global_shrinkcallerid.
Referenced by get_rpid().
14295 { 14296 char pai[256]; 14297 char privacy[64]; 14298 char *cid_num = ""; 14299 char *cid_name = ""; 14300 int callingpres = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 14301 char *start = NULL, *end = NULL, *uri = NULL; 14302 14303 ast_copy_string(pai, get_header(req, "P-Asserted-Identity"), sizeof(pai)); 14304 14305 if (ast_strlen_zero(pai)) { 14306 return 0; 14307 } 14308 14309 start = pai; 14310 if (*start == '"') { 14311 *start++ = '\0'; 14312 end = strchr(start, '"'); 14313 if (!end) { 14314 return 0; 14315 } 14316 *end++ = '\0'; 14317 cid_name = start; 14318 start = ast_skip_blanks(end); 14319 } 14320 14321 if (*start != '<') 14322 return 0; 14323 /* At this point, 'start' points to the URI in brackets. 14324 * We need a copy so that our comparison to the anonymous 14325 * URI is valid. 14326 */ 14327 uri = ast_strdupa(start); 14328 *start++ = '\0'; 14329 end = strchr(start, '@'); 14330 if (!end) { 14331 return 0; 14332 } 14333 *end++ = '\0'; 14334 if (!strncasecmp(uri, "sip:anonymous@anonymous.invalid", 31)) { 14335 callingpres = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 14336 /*XXX Assume no change in cid_num. Perhaps it should be 14337 * blanked? 14338 */ 14339 cid_num = (char *)p->cid_num; 14340 } else if (!strncasecmp(start, "sip:", 4)) { 14341 cid_num = start + 4; 14342 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(cid_num)) 14343 ast_shrink_phone_number(cid_num); 14344 start = end; 14345 14346 end = strchr(start, '>'); 14347 if (!end) { 14348 return 0; 14349 } 14350 *end = '\0'; 14351 } else { 14352 return 0; 14353 } 14354 14355 ast_copy_string(privacy, get_header(req, "Privacy"), sizeof(privacy)); 14356 if (!ast_strlen_zero(privacy) && strncmp(privacy, "id", 2)) { 14357 callingpres = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 14358 } 14359 14360 /* Only return true if the supplied caller id is different */ 14361 if (!strcasecmp(p->cid_num, cid_num) && !strcasecmp(p->cid_name, cid_name) && p->callingpres == callingpres) { 14362 return 0; 14363 } 14364 14365 ast_string_field_set(p, cid_num, cid_num); 14366 ast_string_field_set(p, cid_name, cid_name); 14367 p->callingpres = callingpres; 14368 14369 if (p->owner) { 14370 ast_set_callerid(p->owner, cid_num, cid_name, NULL); 14371 p->owner->caller.id.name.presentation = callingpres; 14372 p->owner->caller.id.number.presentation = callingpres; 14373 } 14374 14375 return 1; 14376 }
| static void get_pidf_body | ( | struct sip_request * | req, | |
| char * | pidf_body, | |||
| size_t | size | |||
| ) | [static] |
Definition at line 22844 of file chan_sip.c.
References ast_copy_string(), ast_str_alloca, ast_str_append(), ast_str_buffer(), and str.
Referenced by sip_pidf_validate().
22845 { 22846 int i; 22847 struct ast_str *str = ast_str_alloca(size); 22848 for (i = 0; i < req->lines; ++i) { 22849 ast_str_append(&str, 0, "%s", REQ_OFFSET_TO_STR(req, line[i])); 22850 } 22851 ast_copy_string(pidf_body, ast_str_buffer(str), size); 22852 }
| static int get_rdnis | ( | struct sip_pvt * | p, | |
| struct sip_request * | oreq, | |||
| char ** | name, | |||
| char ** | number, | |||
| int * | reason | |||
| ) | [static] |
Get referring dnis.
Definition at line 14479 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_strdup, ast_strip_quoted(), ast_strlen_zero(), ast_verbose, exten, get_header(), LOG_WARNING, pbx_builtin_setvar_helper(), sip_debug_test_pvt(), sip_reason_str_to_code(), sip_set_redirstr(), strcasestr(), and strsep().
Referenced by change_redirecting_information().
14480 { 14481 char tmp[256], *exten, *rexten, *rdomain, *rname = NULL; 14482 char *params, *reason_param = NULL; 14483 struct sip_request *req; 14484 14485 req = oreq ? oreq : &p->initreq; 14486 14487 ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp)); 14488 if (ast_strlen_zero(tmp)) 14489 return -1; 14490 14491 if ((params = strchr(tmp, '>'))) { 14492 params = strchr(params, ';'); 14493 } 14494 14495 exten = get_in_brackets(tmp); 14496 if (!strncasecmp(exten, "sip:", 4)) { 14497 exten += 4; 14498 } else if (!strncasecmp(exten, "sips:", 5)) { 14499 exten += 5; 14500 } else { 14501 ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", exten); 14502 return -1; 14503 } 14504 14505 /* Get diversion-reason param if present */ 14506 if (params) { 14507 *params = '\0'; /* Cut off parameters */ 14508 params++; 14509 while (*params == ';' || *params == ' ') 14510 params++; 14511 /* Check if we have a reason parameter */ 14512 if ((reason_param = strcasestr(params, "reason="))) { 14513 char *end; 14514 reason_param+=7; 14515 if ((end = strchr(reason_param, ';'))) { 14516 *end = '\0'; 14517 } 14518 /* Remove enclosing double-quotes */ 14519 if (*reason_param == '"') 14520 ast_strip_quoted(reason_param, "\"", "\""); 14521 if (!ast_strlen_zero(reason_param)) { 14522 sip_set_redirstr(p, reason_param); 14523 if (p->owner) { 14524 pbx_builtin_setvar_helper(p->owner, "__PRIREDIRECTREASON", p->redircause); 14525 pbx_builtin_setvar_helper(p->owner, "__SIPREDIRECTREASON", reason_param); 14526 } 14527 } 14528 } 14529 } 14530 14531 rdomain = exten; 14532 rexten = strsep(&rdomain, "@"); /* trim anything after @ */ 14533 if (p->owner) 14534 pbx_builtin_setvar_helper(p->owner, "__SIPRDNISDOMAIN", rdomain); 14535 14536 if (sip_debug_test_pvt(p)) 14537 ast_verbose("RDNIS for this call is %s (reason %s)\n", exten, reason ? reason_param : ""); 14538 14539 /*ast_string_field_set(p, rdnis, rexten);*/ 14540 14541 if (*tmp == '\"') { 14542 char *end_quote; 14543 rname = tmp + 1; 14544 end_quote = strchr(rname, '\"'); 14545 *end_quote = '\0'; 14546 } 14547 14548 if (number) { 14549 *number = ast_strdup(rexten); 14550 } 14551 14552 if (name && rname) { 14553 *name = ast_strdup(rname); 14554 } 14555 14556 if (reason && !ast_strlen_zero(reason_param)) { 14557 *reason = sip_reason_str_to_code(reason_param); 14558 } 14559 14560 return 0; 14561 }
| 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 10225 of file chan_sip.c.
References AST_LIST_EMPTY, ast_string_field_set, ast_strlen_zero(), check_sip_domain(), get_domain(), get_header(), MAXHOSTNAMELEN, and sip_cfg.
Referenced by transmit_response_with_auth().
10226 { 10227 char domain[MAXHOSTNAMELEN]; 10228 10229 if (!ast_strlen_zero(p->realm)) 10230 return; 10231 10232 if (sip_cfg.domainsasrealm && 10233 !AST_LIST_EMPTY(&domain_list)) 10234 { 10235 /* Check From header first */ 10236 if (!get_domain(get_header(req, "From"), domain, sizeof(domain))) { 10237 if (check_sip_domain(domain, NULL, 0)) { 10238 ast_string_field_set(p, realm, domain); 10239 return; 10240 } 10241 } 10242 /* Check To header */ 10243 if (!get_domain(get_header(req, "To"), domain, sizeof(domain))) { 10244 if (check_sip_domain(domain, NULL, 0)) { 10245 ast_string_field_set(p, realm, domain); 10246 return; 10247 } 10248 } 10249 } 10250 10251 /* Use default realm from config file */ 10252 ast_string_field_set(p, realm, sip_cfg.realm); 10253 }
| static int get_refer_info | ( | struct sip_pvt * | transferer, | |
| struct sip_request * | outgoing_req | |||
| ) | [static] |
Call transfer support (the REFER method) Extracts Refer headers into pvt dialog structure.
Definition at line 14797 of file chan_sip.c.
References ast_bridged_channel(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_uri_decode(), ast_verbose, ast_channel::context, get_header(), LOG_WARNING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), S_OR, sip_cfg, sip_debug_test_pvt(), SIP_PEDANTIC_DECODE, and strcasestr().
Referenced by handle_request_refer().
14798 { 14799 14800 const char *p_referred_by = NULL; 14801 char *h_refer_to = NULL; 14802 char *h_referred_by = NULL; 14803 char *refer_to; 14804 const char *p_refer_to; 14805 char *referred_by_uri = NULL; 14806 char *ptr; 14807 struct sip_request *req = NULL; 14808 const char *transfer_context = NULL; 14809 struct sip_refer *referdata; 14810 14811 14812 req = outgoing_req; 14813 referdata = transferer->refer; 14814 14815 if (!req) { 14816 req = &transferer->initreq; 14817 } 14818 14819 p_refer_to = get_header(req, "Refer-To"); 14820 if (ast_strlen_zero(p_refer_to)) { 14821 ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n"); 14822 return -2; /* Syntax error */ 14823 } 14824 h_refer_to = ast_strdupa(p_refer_to); 14825 refer_to = get_in_brackets(h_refer_to); 14826 if (!strncasecmp(refer_to, "sip:", 4)) { 14827 refer_to += 4; /* Skip sip: */ 14828 } else if (!strncasecmp(refer_to, "sips:", 5)) { 14829 refer_to += 5; 14830 } else { 14831 ast_log(LOG_WARNING, "Can't transfer to non-sip: URI. (Refer-to: %s)?\n", refer_to); 14832 return -3; 14833 } 14834 14835 /* Get referred by header if it exists */ 14836 p_referred_by = get_header(req, "Referred-By"); 14837 14838 /* Give useful transfer information to the dialplan */ 14839 if (transferer->owner) { 14840 struct ast_channel *peer = ast_bridged_channel(transferer->owner); 14841 if (peer) { 14842 pbx_builtin_setvar_helper(peer, "SIPREFERRINGCONTEXT", transferer->context); 14843 pbx_builtin_setvar_helper(peer, "SIPREFERREDBYHDR", p_referred_by); 14844 } 14845 } 14846 14847 if (!ast_strlen_zero(p_referred_by)) { 14848 char *lessthan; 14849 h_referred_by = ast_strdupa(p_referred_by); 14850 14851 /* Store referrer's caller ID name */ 14852 ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name)); 14853 if ((lessthan = strchr(referdata->referred_by_name, '<'))) { 14854 *(lessthan - 1) = '\0'; /* Space */ 14855 } 14856 14857 referred_by_uri = get_in_brackets(h_referred_by); 14858 14859 if (!strncasecmp(referred_by_uri, "sip:", 4)) { 14860 referred_by_uri += 4; /* Skip sip: */ 14861 } else if (!strncasecmp(referred_by_uri, "sips:", 5)) { 14862 referred_by_uri += 5; /* Skip sips: */ 14863 } else { 14864 ast_log(LOG_WARNING, "Huh? Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri); 14865 referred_by_uri = NULL; 14866 } 14867 } 14868 14869 /* Check for arguments in the refer_to header */ 14870 if ((ptr = strcasestr(refer_to, "replaces="))) { 14871 char *to = NULL, *from = NULL; 14872 14873 /* This is an attended transfer */ 14874 referdata->attendedtransfer = 1; 14875 ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid)); 14876 ast_uri_decode(referdata->replaces_callid); 14877 if ((ptr = strchr(referdata->replaces_callid, ';'))) /* Find options */ { 14878 *ptr++ = '\0'; 14879 } 14880 14881 if (ptr) { 14882 /* Find the different tags before we destroy the string */ 14883 to = strcasestr(ptr, "to-tag="); 14884 from = strcasestr(ptr, "from-tag="); 14885 } 14886 14887 /* Grab the to header */ 14888 if (to) { 14889 ptr = to + 7; 14890 if ((to = strchr(ptr, '&'))) { 14891 *to = '\0'; 14892 } 14893 if ((to = strchr(ptr, ';'))) { 14894 *to = '\0'; 14895 } 14896 ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag)); 14897 } 14898 14899 if (from) { 14900 ptr = from + 9; 14901 if ((to = strchr(ptr, '&'))) { 14902 *to = '\0'; 14903 } 14904 if ((to = strchr(ptr, ';'))) { 14905 *to = '\0'; 14906 } 14907 ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag)); 14908 } 14909 14910 if (!strcmp(referdata->replaces_callid, transferer->callid) && 14911 (!sip_cfg.pedanticsipchecking || 14912 (!strcmp(referdata->replaces_callid_fromtag, transferer->theirtag) && 14913 !strcmp(referdata->replaces_callid_totag, transferer->tag)))) { 14914 ast_log(LOG_WARNING, "Got an attempt to replace own Call-ID on %s\n", transferer->callid); 14915 return -4; 14916 } 14917 14918 if (!sip_cfg.pedanticsipchecking) { 14919 ast_debug(2, "Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid ); 14920 } else { 14921 ast_debug(2, "Attended transfer: Will use Replace-Call-ID : %s F-tag: %s T-tag: %s\n", referdata->replaces_callid, referdata->replaces_callid_fromtag ? referdata->replaces_callid_fromtag : "<none>", referdata->replaces_callid_totag ? referdata->replaces_callid_totag : "<none>" ); 14922 } 14923 } 14924 14925 if ((ptr = strchr(refer_to, '@'))) { /* Separate domain */ 14926 char *urioption = NULL, *domain; 14927 int bracket = 0; 14928 *ptr++ = '\0'; 14929 14930 if ((urioption = strchr(ptr, ';'))) { /* Separate urioptions */ 14931 *urioption++ = '\0'; 14932 } 14933 14934 domain = ptr; 14935 14936 /* Remove :port */ 14937 for (; *ptr != '\0'; ++ptr) { 14938 if (*ptr == ':' && bracket == 0) { 14939 *ptr = '\0'; 14940 break; 14941 } else if (*ptr == '[') { 14942 ++bracket; 14943 } else if (*ptr == ']') { 14944 --bracket; 14945 } 14946 } 14947 14948 SIP_PEDANTIC_DECODE(domain); 14949 SIP_PEDANTIC_DECODE(urioption); 14950 14951 /* Save the domain for the dial plan */ 14952 ast_copy_string(referdata->refer_to_domain, domain, sizeof(referdata->refer_to_domain)); 14953 if (urioption) { 14954 ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption)); 14955 } 14956 } 14957 14958 if ((ptr = strchr(refer_to, ';'))) /* Remove options */ 14959 *ptr = '\0'; 14960 14961 SIP_PEDANTIC_DECODE(refer_to); 14962 ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to)); 14963 14964 if (referred_by_uri) { 14965 if ((ptr = strchr(referred_by_uri, ';'))) /* Remove options */ 14966 *ptr = '\0'; 14967 SIP_PEDANTIC_DECODE(referred_by_uri); 14968 ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by)); 14969 } else { 14970 referdata->referred_by[0] = '\0'; 14971 } 14972 14973 /* Determine transfer context */ 14974 if (transferer->owner) /* Mimic behaviour in res_features.c */ 14975 transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT"); 14976 14977 /* By default, use the context in the channel sending the REFER */ 14978 if (ast_strlen_zero(transfer_context)) { 14979 transfer_context = S_OR(transferer->owner->macrocontext, 14980 S_OR(transferer->context, sip_cfg.default_context)); 14981 } 14982 14983 ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context)); 14984 14985 /* Either an existing extension or the parking extension */ 14986 if (referdata->attendedtransfer || ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) { 14987 if (sip_debug_test_pvt(transferer)) { 14988 ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri); 14989 } 14990 /* We are ready to transfer to the extension */ 14991 return 0; 14992 } 14993 if (sip_debug_test_pvt(transferer)) 14994 ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context); 14995 14996 /* Failure, we can't find this extension */ 14997 return -1; 14998 }
| 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 14382 of file chan_sip.c.
References ast_copy_string(), ast_is_shrinkable_phonenumber(), AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, ast_set_callerid(), ast_shrink_phone_number(), ast_skip_blanks(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, cid_name, cid_num, get_header(), get_pai(), and global_shrinkcallerid.
Referenced by check_peer_ok(), check_user_full(), handle_request_invite(), handle_request_update(), and handle_response_invite().
14383 { 14384 char tmp[256]; 14385 struct sip_request *req; 14386 char *cid_num = ""; 14387 char *cid_name = ""; 14388 int callingpres = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 14389 char *privacy = ""; 14390 char *screen = ""; 14391 char *start, *end; 14392 14393 if (!ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) 14394 return 0; 14395 req = oreq; 14396 if (!req) 14397 req = &p->initreq; 14398 ast_copy_string(tmp, get_header(req, "Remote-Party-ID"), sizeof(tmp)); 14399 if (ast_strlen_zero(tmp)) { 14400 return get_pai(p, req); 14401 } 14402 14403 start = tmp; 14404 if (*start == '"') { 14405 *start++ = '\0'; 14406 end = strchr(start, '"'); 14407 if (!end) 14408 return 0; 14409 *end++ = '\0'; 14410 cid_name = start; 14411 start = ast_skip_blanks(end); 14412 } 14413 14414 if (*start != '<') 14415 return 0; 14416 *start++ = '\0'; 14417 end = strchr(start, '@'); 14418 if (!end) 14419 return 0; 14420 *end++ = '\0'; 14421 if (strncasecmp(start, "sip:", 4)) 14422 return 0; 14423 cid_num = start + 4; 14424 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(cid_num)) 14425 ast_shrink_phone_number(cid_num); 14426 start = end; 14427 14428 end = strchr(start, '>'); 14429 if (!end) 14430 return 0; 14431 *end++ = '\0'; 14432 if (*end) { 14433 start = end; 14434 if (*start != ';') 14435 return 0; 14436 *start++ = '\0'; 14437 while (!ast_strlen_zero(start)) { 14438 end = strchr(start, ';'); 14439 if (end) 14440 *end++ = '\0'; 14441 if (!strncasecmp(start, "privacy=", 8)) 14442 privacy = start + 8; 14443 else if (!strncasecmp(start, "screen=", 7)) 14444 screen = start + 7; 14445 start = end; 14446 } 14447 14448 if (!strcasecmp(privacy, "full")) { 14449 if (!strcasecmp(screen, "yes")) 14450 callingpres = AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN; 14451 else if (!strcasecmp(screen, "no")) 14452 callingpres = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 14453 } else { 14454 if (!strcasecmp(screen, "yes")) 14455 callingpres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 14456 else if (!strcasecmp(screen, "no")) 14457 callingpres = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 14458 } 14459 } 14460 14461 /* Only return true if the supplied caller id is different */ 14462 if (!strcasecmp(p->cid_num, cid_num) && !strcasecmp(p->cid_name, cid_name) && p->callingpres == callingpres) 14463 return 0; 14464 14465 ast_string_field_set(p, cid_num, cid_num); 14466 ast_string_field_set(p, cid_name, cid_name); 14467 p->callingpres = callingpres; 14468 14469 if (p->owner) { 14470 ast_set_callerid(p->owner, cid_num, cid_name, NULL); 14471 p->owner->caller.id.name.presentation = callingpres; 14472 p->owner->caller.id.number.presentation = callingpres; 14473 } 14474 14475 return 1; 14476 }
| 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 6890 of file chan_sip.c.
References get_body_by_line(), and len().
06891 { 06892 int len = strlen(name); 06893 06894 while (*start < (req->sdp_start + req->sdp_count)) { 06895 const char *r = get_body_by_line(REQ_OFFSET_TO_STR(req, line[(*start)++]), name, len, '='); 06896 if (r[0] != '\0') 06897 return r; 06898 } 06899 06900 /* if the line was not found, ensure that *start points past the SDP */ 06901 (*start)++; 06902 06903 return ""; 06904 }
| 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 6911 of file chan_sip.c.
References ast_skip_blanks(), and type.
Referenced by process_sdp().
06912 { 06913 char type = '\0'; 06914 const char *line = NULL; 06915 06916 if (stop > (req->sdp_start + req->sdp_count)) { 06917 stop = req->sdp_start + req->sdp_count; 06918 } 06919 06920 while (*start < stop) { 06921 line = REQ_OFFSET_TO_STR(req, line[(*start)++]); 06922 if (line[1] == '=') { 06923 type = line[0]; 06924 *value = ast_skip_blanks(line + 2); 06925 break; 06926 } 06927 } 06928 06929 return type; 06930 }
| static struct sip_pvt * get_sip_pvt_byid_locked | ( | const char * | callid, | |
| const char * | totag, | |||
| const char * | fromtag | |||
| ) | [static] |
Lock dialog lock and find matching pvt lock.
Definition at line 14708 of file chan_sip.c.
References ao2_t_find, ast_channel_trylock, ast_debug, ast_strlen_zero(), dialogs, OBJ_POINTER, sip_cfg, sip_pvt_lock, sip_pvt_unlock, and TRUE.
Referenced by handle_request_invite(), and local_attended_transfer().
14709 { 14710 struct sip_pvt *sip_pvt_ptr; 14711 struct sip_pvt tmp_dialog = { 14712 .callid = callid, 14713 }; 14714 14715 if (totag) { 14716 ast_debug(4, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>"); 14717 } 14718 14719 /* Search dialogs and find the match */ 14720 14721 sip_pvt_ptr = ao2_t_find(dialogs, &tmp_dialog, OBJ_POINTER, "ao2_find of dialog in dialogs table"); 14722 if (sip_pvt_ptr) { 14723 /* Go ahead and lock it (and its owner) before returning */ 14724 sip_pvt_lock(sip_pvt_ptr); 14725 if (sip_cfg.pedanticsipchecking) { 14726 unsigned char frommismatch = 0, tomismatch = 0; 14727 14728 if (ast_strlen_zero(fromtag)) { 14729 sip_pvt_unlock(sip_pvt_ptr); 14730 ast_debug(4, "Matched %s call for callid=%s - no from tag specified, pedantic check fails\n", 14731 sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid); 14732 return NULL; 14733 } 14734 14735 if (ast_strlen_zero(totag)) { 14736 sip_pvt_unlock(sip_pvt_ptr); 14737 ast_debug(4, "Matched %s call for callid=%s - no to tag specified, pedantic check fails\n", 14738 sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid); 14739 return NULL; 14740 } 14741 /* RFC 3891 14742 * > 3. User Agent Server Behavior: Receiving a Replaces Header 14743 * > The Replaces header contains information used to match an existing 14744 * > SIP dialog (call-id, to-tag, and from-tag). Upon receiving an INVITE 14745 * > with a Replaces header, the User Agent (UA) attempts to match this 14746 * > information with a confirmed or early dialog. The User Agent Server 14747 * > (UAS) matches the to-tag and from-tag parameters as if they were tags 14748 * > present in an incoming request. In other words, the to-tag parameter 14749 * > is compared to the local tag, and the from-tag parameter is compared 14750 * > to the remote tag. 14751 * 14752 * Thus, the totag is always compared to the local tag, regardless if 14753 * this our call is an incoming or outgoing call. 14754 */ 14755 frommismatch = !!strcmp(fromtag, sip_pvt_ptr->theirtag); 14756 tomismatch = !!strcmp(totag, sip_pvt_ptr->tag); 14757 14758 if (frommismatch || tomismatch) { 14759 sip_pvt_unlock(sip_pvt_ptr); 14760 if (frommismatch) { 14761 ast_debug(4, "Matched %s call for callid=%s - pedantic from tag check fails; their tag is %s our tag is %s\n", 14762 sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid, 14763 fromtag, sip_pvt_ptr->theirtag); 14764 } 14765 if (tomismatch) { 14766 ast_debug(4, "Matched %s call for callid=%s - pedantic to tag check fails; their tag is %s our tag is %s\n", 14767 sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid, 14768 totag, sip_pvt_ptr->tag); 14769 } 14770 return NULL; 14771 } 14772 } 14773 14774 if (totag) 14775 ast_debug(4, "Matched %s call - their tag is %s Our tag is %s\n", 14776 sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", 14777 sip_pvt_ptr->theirtag, sip_pvt_ptr->tag); 14778 14779 /* deadlock avoidance... */ 14780 while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) { 14781 sip_pvt_unlock(sip_pvt_ptr); 14782 usleep(1); 14783 sip_pvt_lock(sip_pvt_ptr); 14784 } 14785 } 14786 14787 return sip_pvt_ptr; 14788 }
| static const char* get_srv_protocol | ( | enum sip_transport | t | ) | [inline, static] |
Return protocol string for srv dns query.
Definition at line 3202 of file chan_sip.c.
Referenced by __sip_subscribe_mwi_do(), build_peer(), create_addr(), and transmit_register().
03203 { 03204 switch (t) { 03205 case SIP_TRANSPORT_UDP: 03206 return "udp"; 03207 case SIP_TRANSPORT_TLS: 03208 case SIP_TRANSPORT_TCP: 03209 return "tcp"; 03210 } 03211 03212 return "udp"; 03213 }
| static const char* get_srv_service | ( | enum sip_transport | t | ) | [inline, static] |
Return service string for srv dns query.
Definition at line 3216 of file chan_sip.c.
Referenced by __sip_subscribe_mwi_do(), build_peer(), create_addr(), and transmit_register().
03217 { 03218 switch (t) { 03219 case SIP_TRANSPORT_TCP: 03220 case SIP_TRANSPORT_UDP: 03221 return "sip"; 03222 case SIP_TRANSPORT_TLS: 03223 return "sips"; 03224 } 03225 return "sip"; 03226 }
| static const char* get_transport | ( | enum sip_transport | t | ) | [inline, static] |
Return transport as string.
Definition at line 3187 of file chan_sip.c.
Referenced by _sip_show_peer(), ast_sip_ouraddrfor(), build_contact(), get_transport_pvt(), handle_request_do(), parse_moved_contact(), sip_show_settings(), sip_show_tcp(), and transmit_notify_with_mwi().
03188 { 03189 switch (t) { 03190 case SIP_TRANSPORT_UDP: 03191 return "UDP"; 03192 case SIP_TRANSPORT_TCP: 03193 return "TCP"; 03194 case SIP_TRANSPORT_TLS: 03195 return "TLS"; 03196 } 03197 03198 return "UNKNOWN"; 03199 }
| static const char* get_transport_list | ( | unsigned int | transports | ) | [inline, static] |
Return configuration of transports for a device.
Definition at line 3166 of file chan_sip.c.
Referenced by _sip_show_peer(), peers_data_provider_get(), and sip_show_settings().
03166 { 03167 switch (transports) { 03168 case SIP_TRANSPORT_UDP: 03169 return "UDP"; 03170 case SIP_TRANSPORT_TCP: 03171 return "TCP"; 03172 case SIP_TRANSPORT_TLS: 03173 return "TLS"; 03174 case SIP_TRANSPORT_UDP | SIP_TRANSPORT_TCP: 03175 return "TCP,UDP"; 03176 case SIP_TRANSPORT_UDP | SIP_TRANSPORT_TLS: 03177 return "TLS,UDP"; 03178 case SIP_TRANSPORT_TCP | SIP_TRANSPORT_TLS: 03179 return "TLS,TCP"; 03180 default: 03181 return transports ? 03182 "TLS,TCP,UDP" : "UNKNOWN"; 03183 } 03184 }
| static const char* get_transport_pvt | ( | struct sip_pvt * | p | ) | [inline, static] |
Return transport of dialog.
Definition at line 3234 of file chan_sip.c.
References get_transport(), and set_socket_transport().
Referenced by __sip_xmit(), and build_via().
03235 { 03236 if (p->outboundproxy && p->outboundproxy->transport) { 03237 set_socket_transport(&p->socket, p->outboundproxy->transport); 03238 } 03239 03240 return get_transport(p->socket.type); 03241 }
| 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 3144 of file chan_sip.c.
References ast_strlen_zero().
Referenced by __set_address_from_contact(), and parse_register_contact().
03145 { 03146 int res = 0; 03147 03148 if (ast_strlen_zero(transport)) { 03149 return res; 03150 } 03151 03152 if (!strcasecmp(transport, "udp")) { 03153 res |= SIP_TRANSPORT_UDP; 03154 } 03155 if (!strcasecmp(transport, "tcp")) { 03156 res |= SIP_TRANSPORT_TCP; 03157 } 03158 if (!strcasecmp(transport, "tls")) { 03159 res |= SIP_TRANSPORT_TLS; 03160 } 03161 03162 return res; 03163 }
| static const char * gettag | ( | const struct sip_request * | req, | |
| const char * | header, | |||
| char * | tagbuf, | |||
| int | tagbufsize | |||
| ) | [static] |
Get tag from packet.
Definition at line 20592 of file chan_sip.c.
References ast_copy_string(), get_header(), strcasestr(), and strsep().
Referenced by find_call(), handle_incoming(), handle_request_subscribe(), and handle_response().
20593 { 20594 const char *thetag; 20595 20596 if (!tagbuf) 20597 return NULL; 20598 tagbuf[0] = '\0'; /* reset the buffer */ 20599 thetag = get_header(req, header); 20600 thetag = strcasestr(thetag, ";tag="); 20601 if (thetag) { 20602 thetag += 5; 20603 ast_copy_string(tagbuf, thetag, tagbufsize); 20604 return strsep(&tagbuf, ";"); 20605 } 20606 return NULL; 20607 }
| static int handle_cc_notify | ( | struct sip_pvt * | pvt, | |
| struct sip_request * | req | |||
| ) | [static] |
Definition at line 20609 of file chan_sip.c.
References ao2_callback, ao2_ref, ast_cc_monitor_callee_available(), ast_cc_monitor_request_acked(), ast_string_field_set, ast_strlen_zero(), construct_pidf_body(), find_sip_monitor_instance_by_subscription_pvt(), get_body(), get_header(), sip_monitor_instances, status, transmit_publish(), and transmit_response().
Referenced by handle_request_notify().
20610 { 20611 struct sip_monitor_instance *monitor_instance = ao2_callback(sip_monitor_instances, 0, 20612 find_sip_monitor_instance_by_subscription_pvt, pvt); 20613 const char *status = get_body(req, "cc-state", ':'); 20614 struct cc_epa_entry *cc_entry; 20615 char *uri; 20616 20617 if (!monitor_instance) { 20618 transmit_response(pvt, "400 Bad Request", req); 20619 return -1; 20620 } 20621 20622 if (ast_strlen_zero(status)) { 20623 ao2_ref(monitor_instance, -1); 20624 transmit_response(pvt, "400 Bad Request", req); 20625 return -1; 20626 } 20627 20628 if (!strcmp(status, "queued")) { 20629 /* We've been told that we're queued. This is the endpoint's way of telling 20630 * us that it has accepted our CC request. We need to alert the core of this 20631 * development 20632 */ 20633 ast_cc_monitor_request_acked(monitor_instance->core_id, "SIP endpoint %s accepted request", monitor_instance->device_name); 20634 transmit_response(pvt, "200 OK", req); 20635 ao2_ref(monitor_instance, -1); 20636 return 0; 20637 } 20638 20639 /* It's open! Yay! */ 20640 uri = get_body(req, "cc-URI", ':'); 20641 if (ast_strlen_zero(uri)) { 20642 uri = get_in_brackets((char *)get_header(req, "From")); 20643 } 20644 20645 ast_string_field_set(monitor_instance, notify_uri, uri); 20646 if (monitor_instance->suspension_entry) { 20647 cc_entry = monitor_instance->suspension_entry->instance_data; 20648 if (cc_entry->current_state == CC_CLOSED) { 20649 /* If we've created a suspension entry and the current state is closed, then that means 20650 * we got a notice from the CC core earlier to suspend monitoring, but because this particular 20651 * call leg had not yet notified us that it was ready for recall, it meant that we 20652 * could not yet send a PUBLISH. Now, however, we can. 20653 */ 20654 construct_pidf_body(CC_CLOSED, monitor_instance->suspension_entry->body, 20655 sizeof(monitor_instance->suspension_entry->body), monitor_instance->peername); 20656 transmit_publish(monitor_instance->suspension_entry, SIP_PUBLISH_INITIAL, monitor_instance->notify_uri); 20657 } else { 20658 ast_cc_monitor_callee_available(monitor_instance->core_id, "SIP monitored callee has become available"); 20659 } 20660 } else { 20661 ast_cc_monitor_callee_available(monitor_instance->core_id, "SIP monitored callee has become available"); 20662 } 20663 ao2_ref(monitor_instance, -1); 20664 transmit_response(pvt, "200 OK", req); 20665 20666 return 0; 20667 }
| static int handle_cc_subscribe | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Definition at line 23315 of file chan_sip.c.
References ao2_ref, ast_cc_agent_accept_request(), ast_cc_failed(), ast_log(), ast_strlen_zero(), ast_cc_agent::core_id, ast_cc_agent::device_name, find_sip_cc_agent_by_subscribe_uri(), get_header(), LOG_WARNING, ast_cc_agent::private_data, and transmit_response().
Referenced by handle_request_subscribe().
23316 { 23317 const char *uri = REQ_OFFSET_TO_STR(req, rlPart2); 23318 char *param_separator; 23319 struct ast_cc_agent *agent; 23320 struct sip_cc_agent_pvt *agent_pvt; 23321 const char *expires_str = get_header(req, "Expires"); 23322 int expires = -1; /* Just need it to be non-zero */ 23323 23324 if (!ast_strlen_zero(expires_str)) { 23325 sscanf(expires_str, "%d", &expires); 23326 } 23327 23328 if ((param_separator = strchr(uri, ';'))) { 23329 *param_separator = '\0'; 23330 } 23331 23332 if (!(agent = find_sip_cc_agent_by_subscribe_uri(uri))) { 23333 if (!expires) { 23334 /* Typically, if a 0 Expires reaches us and we can't find 23335 * the corresponding agent, it means that the CC transaction 23336 * has completed and so the calling side is just trying to 23337 * clean up its subscription. We'll just respond with a 23338 * 200 OK and be done with it 23339 */ 23340 transmit_response(p, "200 OK", req); 23341 return 0; 23342 } 23343 ast_log(LOG_WARNING, "Invalid URI '%s' in CC subscribe\n", uri); 23344 transmit_response(p, "404 Not Found", req); 23345 return -1; 23346 } 23347 23348 agent_pvt = agent->private_data; 23349 23350 if (!expires) { 23351 /* We got sent a SUBSCRIBE and found an agent. This means that CC 23352 * is being canceled. 23353 */ 23354 ast_cc_failed(agent->core_id, "CC is being canceled by %s", agent->device_name); 23355 transmit_response(p, "200 OK", req); 23356 ao2_ref(agent, -1); 23357 return 0; 23358 } 23359 23360 agent_pvt->subscribe_pvt = dialog_ref(p, "SIP CC agent gains reference to subscription dialog"); 23361 ast_cc_agent_accept_request(agent->core_id, "SIP caller %s has requested CC via SUBSCRIBE", 23362 agent->device_name); 23363 p->subscribed = CALL_COMPLETION; 23364 23365 /* We don't send a response here. That is done in the agent's ack callback or in the 23366 * agent destructor, should a failure occur before we have responded 23367 */ 23368 ao2_ref(agent, -1); 23369 return 0; 23370 }
| static int handle_common_options | ( | struct ast_flags * | flags, | |
| struct ast_flags * | mask, | |||
| struct ast_variable * | v | |||
| ) | [static] |
Handle flag-type options common to configuration of devices - peers.
| flags | array of two struct ast_flags | |
| mask | array of two struct ast_flags | |
| v | linked list of config variables to process |
Definition at line 25574 of file chan_sip.c.
References ast_clear_flag, ast_copy_string(), ast_false(), ast_log(), ast_set2_flag, ast_set_flag, ast_strdupa, ast_true(), ast_variable::lineno, LOG_WARNING, ast_variable::name, set_insecure_flags(), strsep(), ast_variable::value, and word.
Referenced by build_peer().
25575 { 25576 int res = 1; 25577 25578 if (!strcasecmp(v->name, "trustrpid")) { 25579 ast_set_flag(&mask[0], SIP_TRUSTRPID); 25580 ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID); 25581 } else if (!strcasecmp(v->name, "sendrpid")) { 25582 ast_set_flag(&mask[0], SIP_SENDRPID); 25583 if (!strcasecmp(v->value, "pai")) { 25584 ast_set_flag(&flags[0], SIP_SENDRPID_PAI); 25585 } else if (!strcasecmp(v->value, "rpid")) { 25586 ast_set_flag(&flags[0], SIP_SENDRPID_RPID); 25587 } else if (ast_true(v->value)) { 25588 ast_set_flag(&flags[0], SIP_SENDRPID_RPID); 25589 } 25590 } else if (!strcasecmp(v->name, "rpid_update")) { 25591 ast_set_flag(&mask[1], SIP_PAGE2_RPID_UPDATE); 25592 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RPID_UPDATE); 25593 } else if (!strcasecmp(v->name, "rpid_immediate")) { 25594 ast_set_flag(&mask[1], SIP_PAGE2_RPID_IMMEDIATE); 25595 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RPID_IMMEDIATE); 25596 } else if (!strcasecmp(v->name, "g726nonstandard")) { 25597 ast_set_flag(&mask[0], SIP_G726_NONSTANDARD); 25598 ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD); 25599 } else if (!strcasecmp(v->name, "useclientcode")) { 25600 ast_set_flag(&mask[0], SIP_USECLIENTCODE); 25601 ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE); 25602 } else if (!strcasecmp(v->name, "dtmfmode")) { 25603 ast_set_flag(&mask[0], SIP_DTMF); 25604 ast_clear_flag(&flags[0], SIP_DTMF); 25605 if (!strcasecmp(v->value, "inband")) 25606 ast_set_flag(&flags[0], SIP_DTMF_INBAND); 25607 else if (!strcasecmp(v->value, "rfc2833")) 25608 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 25609 else if (!strcasecmp(v->value, "info")) 25610 ast_set_flag(&flags[0], SIP_DTMF_INFO); 25611 else if (!strcasecmp(v->value, "shortinfo")) 25612 ast_set_flag(&flags[0], SIP_DTMF_SHORTINFO); 25613 else if (!strcasecmp(v->value, "auto")) 25614 ast_set_flag(&flags[0], SIP_DTMF_AUTO); 25615 else { 25616 ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno); 25617 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 25618 } 25619 } else if (!strcasecmp(v->name, "nat")) { 25620 ast_set_flag(&mask[0], SIP_NAT_FORCE_RPORT); 25621 if (!strcasecmp(v->value, "no")) { 25622 ast_clear_flag(&flags[0], SIP_NAT_FORCE_RPORT); 25623 } else if (!strcasecmp(v->value, "force_rport")) { 25624 ast_set_flag(&flags[0], SIP_NAT_FORCE_RPORT); 25625 } else if (!strcasecmp(v->value, "yes")) { 25626 ast_set_flag(&flags[0], SIP_NAT_FORCE_RPORT); 25627 ast_set_flag(&mask[1], SIP_PAGE2_SYMMETRICRTP); 25628 ast_set_flag(&flags[1], SIP_PAGE2_SYMMETRICRTP); 25629 } else if (!strcasecmp(v->value, "comedia")) { 25630 ast_clear_flag(&flags[0], SIP_NAT_FORCE_RPORT); 25631 ast_set_flag(&mask[1], SIP_PAGE2_SYMMETRICRTP); 25632 ast_set_flag(&flags[1], SIP_PAGE2_SYMMETRICRTP); 25633 } 25634 } else if (!strcasecmp(v->name, "directmedia") || !strcasecmp(v->name, "canreinvite")) { 25635 ast_set_flag(&mask[0], SIP_REINVITE); 25636 ast_clear_flag(&flags[0], SIP_REINVITE); 25637 if (ast_true(v->value)) { 25638 ast_set_flag(&flags[0], SIP_DIRECT_MEDIA | SIP_DIRECT_MEDIA_NAT); 25639 } else if (!ast_false(v->value)) { 25640 char buf[64]; 25641 char *word, *next = buf; 25642 25643 ast_copy_string(buf, v->value, sizeof(buf)); 25644 while ((word = strsep(&next, ","))) { 25645 if (!strcasecmp(word, "update")) { 25646 ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_DIRECT_MEDIA); 25647 } else if (!strcasecmp(word, "nonat")) { 25648 ast_set_flag(&flags[0], SIP_DIRECT_MEDIA); 25649 ast_clear_flag(&flags[0], SIP_DIRECT_MEDIA_NAT); 25650 } else { 25651 ast_log(LOG_WARNING, "Unknown directmedia mode '%s' on line %d\n", v->value, v->lineno); 25652 } 25653 } 25654 } 25655 } else if (!strcasecmp(v->name, "insecure")) { 25656 ast_set_flag(&mask[0], SIP_INSECURE); 25657 ast_clear_flag(&flags[0], SIP_INSECURE); 25658 set_insecure_flags(&flags[0], v->value, v->lineno); 25659 } else if (!strcasecmp(v->name, "progressinband")) { 25660 ast_set_flag(&mask[0], SIP_PROG_INBAND); 25661 ast_clear_flag(&flags[0], SIP_PROG_INBAND); 25662 if (ast_true(v->value)) 25663 ast_set_flag(&flags[0], SIP_PROG_INBAND_YES); 25664 else if (strcasecmp(v->value, "never")) 25665 ast_set_flag(&flags[0], SIP_PROG_INBAND_NO); 25666 } else if (!strcasecmp(v->name, "promiscredir")) { 25667 ast_set_flag(&mask[0], SIP_PROMISCREDIR); 25668 ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR); 25669 } else if (!strcasecmp(v->name, "videosupport")) { 25670 if (!strcasecmp(v->value, "always")) { 25671 ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS); 25672 ast_set_flag(&flags[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS); 25673 } else { 25674 ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT); 25675 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT); 25676 } 25677 } else if (!strcasecmp(v->name, "textsupport")) { 25678 ast_set_flag(&mask[1], SIP_PAGE2_TEXTSUPPORT); 25679 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_TEXTSUPPORT); 25680 res = 1; 25681 } else if (!strcasecmp(v->name, "allowoverlap")) { 25682 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP); 25683 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP); 25684 } else if (!strcasecmp(v->name, "allowsubscribe")) { 25685 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE); 25686 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE); 25687 } else if (!strcasecmp(v->name, "ignoresdpversion")) { 25688 ast_set_flag(&mask[1], SIP_PAGE2_IGNORESDPVERSION); 25689 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_IGNORESDPVERSION); 25690 } else if (!strcasecmp(v->name, "faxdetect")) { 25691 ast_set_flag(&mask[1], SIP_PAGE2_FAX_DETECT); 25692 if (ast_true(v->value)) { 25693 ast_set_flag(&flags[1], SIP_PAGE2_FAX_DETECT_BOTH); 25694 } else if (ast_false(v->value)) { 25695 ast_clear_flag(&flags[1], SIP_PAGE2_FAX_DETECT_BOTH); 25696 } else { 25697 char *buf = ast_strdupa(v->value); 25698 char *word, *next = buf; 25699 25700 while ((word = strsep(&next, ","))) { 25701 if (!strcasecmp(word, "cng")) { 25702 ast_set_flag(&flags[1], SIP_PAGE2_FAX_DETECT_CNG); 25703 } else if (!strcasecmp(word, "t38")) { 25704 ast_set_flag(&flags[1], SIP_PAGE2_FAX_DETECT_T38); 25705 } else { 25706 ast_log(LOG_WARNING, "Unknown faxdetect mode '%s' on line %d.\n", word, v->lineno); 25707 } 25708 } 25709 } 25710 } else if (!strcasecmp(v->name, "rfc2833compensate")) { 25711 ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE); 25712 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE); 25713 } else if (!strcasecmp(v->name, "buggymwi")) { 25714 ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI); 25715 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI); 25716 } else 25717 res = 0; 25718 25719 return res; 25720 }
| 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).
called with p and p->owner locked
Definition at line 23796 of file chan_sip.c.
References __get_header(), __sip_ack(), ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_debug, ast_log(), ast_random(), ast_skip_blanks(), ast_sockaddr_stringify(), ast_string_field_set, ast_strlen_zero(), ast_verbose, check_pendings(), debug, extract_uri(), find_sdp(), get_header(), gettag(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_message(), handle_request_notify(), handle_request_options(), handle_request_publish(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_request_update(), handle_response(), cfsip_methods::id, len(), LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_channel::name, pbx_builtin_setvar_helper(), process_sdp(), pvt_set_needdestroy(), sip_cfg, sip_debug_test_pvt(), sip_methods, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), cfsip_methods::text, transmit_response(), transmit_response_reliable(), transmit_response_with_allow(), and transmit_response_with_retry_after().
Referenced by handle_request_do(), and process_request_queue().
23797 { 23798 /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things 23799 relatively static */ 23800 const char *cmd; 23801 const char *cseq; 23802 const char *useragent; 23803 const char *via; 23804 const char *callid; 23805 int via_pos = 0; 23806 int seqno; 23807 int len; 23808 int respid; 23809 int res = 0; 23810 int debug = sip_debug_test_pvt(p); 23811 const char *e; 23812 int error = 0; 23813 int oldmethod = p->method; 23814 int acked = 0; 23815 23816 /* RFC 3261 - 8.1.1 A valid SIP request must contain To, From, CSeq, Call-ID and Via. 23817 * 8.2.6.2 Response must have To, From, Call-ID CSeq, and Via related to the request, 23818 * so we can check to make sure these fields exist for all requests and responses */ 23819 cseq = get_header(req, "Cseq"); 23820 cmd = REQ_OFFSET_TO_STR(req, header[0]); 23821 /* Save the via_pos so we can check later that responses only have 1 Via header */ 23822 via = __get_header(req, "Via", &via_pos); 23823 /* This must exist already because we've called find_call by now */ 23824 callid = get_header(req, "Call-ID"); 23825 23826 /* Must have Cseq */ 23827 if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq) || ast_strlen_zero(via)) { 23828 ast_log(LOG_ERROR, "Dropping this SIP message with Call-ID '%s', it's incomplete.\n", callid); 23829 error = 1; 23830 } 23831 if (!error && sscanf(cseq, "%30d%n", &seqno, &len) != 1) { 23832 ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd); 23833 error = 1; 23834 } 23835 if (error) { 23836 if (!p->initreq.headers) { /* New call */ 23837 pvt_set_needdestroy(p, "no headers"); 23838 } 23839 return -1; 23840 } 23841 /* Get the command XXX */ 23842 23843 cmd = REQ_OFFSET_TO_STR(req, rlPart1); 23844 e = ast_skip_blanks(REQ_OFFSET_TO_STR(req, rlPart2)); 23845 23846 /* Save useragent of the client */ 23847 useragent = get_header(req, "User-Agent"); 23848 if (!ast_strlen_zero(useragent)) 23849 ast_string_field_set(p, useragent, useragent); 23850 23851 /* Find out SIP method for incoming request */ 23852 if (req->method == SIP_RESPONSE) { /* Response to our request */ 23853 /* ignore means "don't do anything with it" but still have to 23854 * respond appropriately. 23855 * But in this case this is a response already, so we really 23856 * have nothing to do with this message, and even setting the 23857 * ignore flag is pointless. 23858 */ 23859 if (ast_strlen_zero(e)) { 23860 return 0; 23861 } 23862 if (sscanf(e, "%30d %n", &respid, &len) != 1) { 23863 ast_log(LOG_WARNING, "Invalid response: '%s'\n", e); 23864 return 0; 23865 } 23866 if (respid <= 0) { 23867 ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid); 23868 return 0; 23869 } 23870 /* RFC 3261 - 8.1.3.3 If more than one Via header field value is present in a reponse 23871 * the UAC SHOULD discard the message. This is not perfect, as it will not catch multiple 23872 * headers joined with a comma. Fixing that would pretty much involve writing a new parser */ 23873 if (!ast_strlen_zero(__get_header(req, "via", &via_pos))) { 23874 ast_log(LOG_WARNING, "Misrouted SIP response '%s' with Call-ID '%s', too many vias\n", e, callid); 23875 return 0; 23876 } 23877 if (p->ocseq && (p->ocseq < seqno)) { 23878 ast_debug(1, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq); 23879 return -1; 23880 } else { 23881 char causevar[256], causeval[256]; 23882 23883 if ((respid == 200) || ((respid >= 300) && (respid <= 399))) { 23884 extract_uri(p, req); 23885 } 23886 23887 handle_response(p, respid, e + len, req, seqno); 23888 23889 if (p->owner) { 23890 struct ast_channel *owner = p->owner; 23891 23892 snprintf(causevar, sizeof(causevar), "MASTER_CHANNEL(HASH(SIP_CAUSE,%s))", owner->name); 23893 snprintf(causeval, sizeof(causeval), "SIP %s", REQ_OFFSET_TO_STR(req, rlPart2)); 23894 23895 ast_channel_ref(owner); 23896 sip_pvt_unlock(p); 23897 ast_channel_unlock(owner); 23898 *nounlock = 1; 23899 pbx_builtin_setvar_helper(owner, causevar, causeval); 23900 ast_channel_unref(owner); 23901 sip_pvt_lock(p); 23902 } 23903 } 23904 return 0; 23905 } 23906 23907 /* New SIP request coming in 23908 (could be new request in existing SIP dialog as well...) 23909 */ 23910 23911 p->method = req->method; /* Find out which SIP method they are using */ 23912 ast_debug(4, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 23913 23914 if (p->icseq && (p->icseq > seqno) ) { 23915 if (p->pendinginvite && seqno == p->pendinginvite && (req->method == SIP_ACK || req->method == SIP_CANCEL)) { 23916 ast_debug(2, "Got CANCEL or ACK on INVITE with transactions in between.\n"); 23917 } else { 23918 ast_debug(1, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq); 23919 if (req->method == SIP_INVITE) { 23920 unsigned int ran = (ast_random() % 10) + 1; 23921 char seconds[4]; 23922 snprintf(seconds, sizeof(seconds), "%u", ran); 23923 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 */ 23924 } else if (req->method != SIP_ACK) { 23925 transmit_response(p, "500 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */ 23926 } 23927 return -1; 23928 } 23929 } else if (p->icseq && 23930 p->icseq == seqno && 23931 req->method != SIP_ACK && 23932 (p->method != SIP_CANCEL || p->alreadygone)) { 23933 /* ignore means "don't do anything with it" but still have to 23934 respond appropriately. We do this if we receive a repeat of 23935 the last sequence number */ 23936 req->ignore = 1; 23937 ast_debug(3, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno); 23938 } 23939 23940 /* RFC 3261 section 9. "CANCEL has no effect on a request to which a UAS has 23941 * already given a final response." */ 23942 if (!p->pendinginvite && (req->method == SIP_CANCEL)) { 23943 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 23944 return res; 23945 } 23946 23947 if (seqno >= p->icseq) 23948 /* Next should follow monotonically (but not necessarily 23949 incrementally -- thanks again to the genius authors of SIP -- 23950 increasing */ 23951 p->icseq = seqno; 23952 23953 /* Find their tag if we haven't got it */ 23954 if (ast_strlen_zero(p->theirtag)) { 23955 char tag[128]; 23956 23957 gettag(req, "From", tag, sizeof(tag)); 23958 ast_string_field_set(p, theirtag, tag); 23959 } 23960 snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd); 23961 23962 if (sip_cfg.pedanticsipchecking) { 23963 /* If this is a request packet without a from tag, it's not 23964 correct according to RFC 3261 */ 23965 /* Check if this a new request in a new dialog with a totag already attached to it, 23966 RFC 3261 - section 12.2 - and we don't want to mess with recovery */ 23967 if (!p->initreq.headers && req->has_to_tag) { 23968 /* If this is a first request and it got a to-tag, it is not for us */ 23969 if (!req->ignore && req->method == SIP_INVITE) { 23970 transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req); 23971 /* Will cease to exist after ACK */ 23972 } else if (req->method != SIP_ACK) { 23973 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 23974 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23975 } else { 23976 ast_debug(1, "Got ACK for unknown dialog... strange.\n"); 23977 } 23978 return res; 23979 } 23980 } 23981 23982 if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY || p->method == SIP_PUBLISH)) { 23983 transmit_response(p, "400 Bad request", req); 23984 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23985 return -1; 23986 } 23987 23988 /* Handle various incoming SIP methods in requests */ 23989 switch (p->method) { 23990 case SIP_OPTIONS: 23991 res = handle_request_options(p, req, addr, e); 23992 break; 23993 case SIP_INVITE: 23994 res = handle_request_invite(p, req, debug, seqno, addr, recount, e, nounlock); 23995 break; 23996 case SIP_REFER: 23997 res = handle_request_refer(p, req, debug, seqno, nounlock); 23998 break; 23999 case SIP_CANCEL: 24000 res = handle_request_cancel(p, req); 24001 break; 24002 case SIP_BYE: 24003 res = handle_request_bye(p, req); 24004 break; 24005 case SIP_MESSAGE: 24006 res = handle_request_message(p, req); 24007 break; 24008 case SIP_PUBLISH: 24009 res = handle_request_publish(p, req, addr, seqno, e); 24010 break; 24011 case SIP_SUBSCRIBE: 24012 res = handle_request_subscribe(p, req, addr, seqno, e); 24013 break; 24014 case SIP_REGISTER: 24015 res = handle_request_register(p, req, addr, e); 24016 break; 24017 case SIP_INFO: 24018 if (req->debug) 24019 ast_verbose("Receiving INFO!\n"); 24020 if (!req->ignore) 24021 handle_request_info(p, req); 24022 else /* if ignoring, transmit response */ 24023 transmit_response(p, "200 OK", req); 24024 break; 24025 case SIP_NOTIFY: 24026 res = handle_request_notify(p, req, addr, seqno, e); 24027 break; 24028 case SIP_UPDATE: 24029 res = handle_request_update(p, req); 24030 break; 24031 case SIP_ACK: 24032 /* Make sure we don't ignore this */ 24033 if (seqno == p->pendinginvite) { 24034 p->invitestate = INV_TERMINATED; 24035 p->pendinginvite = 0; 24036 acked = __sip_ack(p, seqno, 1 /* response */, 0); 24037 if (find_sdp(req)) { 24038 if (process_sdp(p, req, SDP_T38_NONE)) 24039 return -1; 24040 } 24041 check_pendings(p); 24042 } else if (p->glareinvite == seqno) { 24043 /* handle ack for the 491 pending sent for glareinvite */ 24044 p->glareinvite = 0; 24045 acked = __sip_ack(p, seqno, 1, 0); 24046 } 24047 if (!acked) { 24048 /* Got an ACK that did not match anything. Ignore 24049 * silently and restore previous method */ 24050 p->method = oldmethod; 24051 } 24052 if (!p->lastinvite && ast_strlen_zero(p->randdata)) { 24053 pvt_set_needdestroy(p, "unmatched ACK"); 24054 } 24055 break; 24056 default: 24057 transmit_response_with_allow(p, "501 Method Not Implemented", req, 0); 24058 ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 24059 cmd, ast_sockaddr_stringify(&p->sa)); 24060 /* If this is some new method, and we don't have a call, destroy it now */ 24061 if (!p->initreq.headers) { 24062 pvt_set_needdestroy(p, "unimplemented method"); 24063 } 24064 break; 24065 } 24066 return res; 24067 }
| static int handle_invite_replaces | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| int | debug, | |||
| int | seqno, | |||
| struct ast_sockaddr * | addr, | |||
| int * | nounlock | |||
| ) | [static] |
Handle the transfer part of INVITE with a replaces: header, meaning a target pickup or an attended transfer. Used only once. XXX 'ignore' is unused.
Definition at line 20914 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_lock, ast_channel_masquerade(), ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_debug, ast_do_masquerade(), ast_hangup(), ast_log(), ast_quiet_chan(), ast_set_flag, ast_setstate(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, FALSE, ast_channel::hangupcause, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_channel::name, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), ast_channel::tech_pvt, transmit_response(), transmit_response_reliable(), and transmit_response_with_sdp().
Referenced by handle_request_invite().
20915 { 20916 int earlyreplace = 0; 20917 int oneleggedreplace = 0; /* Call with no bridge, propably IVR or voice message */ 20918 struct ast_channel *c = p->owner; /* Our incoming call */ 20919 struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */ 20920 struct ast_channel *targetcall; /* The bridge to the take-over target */ 20921 20922 /* Check if we're in ring state */ 20923 if (replacecall->_state == AST_STATE_RING) 20924 earlyreplace = 1; 20925 20926 /* Check if we have a bridge */ 20927 if (!(targetcall = ast_bridged_channel(replacecall))) { 20928 /* We have no bridge */ 20929 if (!earlyreplace) { 20930 ast_debug(2, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name); 20931 oneleggedreplace = 1; 20932 } 20933 } 20934 if (targetcall && targetcall->_state == AST_STATE_RINGING) 20935 ast_debug(4, "SIP transfer: Target channel is in ringing state\n"); 20936 20937 if (targetcall) 20938 ast_debug(4, "SIP transfer: Invite Replace incoming channel should bridge to channel %s while hanging up channel %s\n", targetcall->name, replacecall->name); 20939 else 20940 ast_debug(4, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name); 20941 20942 if (req->ignore) { 20943 ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n"); 20944 /* We should answer something here. If we are here, the 20945 call we are replacing exists, so an accepted 20946 can't harm */ 20947 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE, FALSE, FALSE); 20948 /* Do something more clever here */ 20949 if (c) { 20950 *nounlock = 1; 20951 ast_channel_unlock(c); 20952 } 20953 ast_channel_unlock(replacecall); 20954 sip_pvt_unlock(p->refer->refer_call); 20955 return 1; 20956 } 20957 if (!c) { 20958 /* What to do if no channel ??? */ 20959 ast_log(LOG_ERROR, "Unable to create new channel. Invite/replace failed.\n"); 20960 transmit_response_reliable(p, "503 Service Unavailable", req); 20961 append_history(p, "Xfer", "INVITE/Replace Failed. No new channel."); 20962 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 20963 ast_channel_unlock(replacecall); 20964 sip_pvt_unlock(p->refer->refer_call); 20965 return 1; 20966 } 20967 append_history(p, "Xfer", "INVITE/Replace received"); 20968 /* We have three channels to play with 20969 channel c: New incoming call 20970 targetcall: Call from PBX to target 20971 p->refer->refer_call: SIP pvt dialog from transferer to pbx. 20972 replacecall: The owner of the previous 20973 We need to masq C into refer_call to connect to 20974 targetcall; 20975 If we are talking to internal audio stream, target call is null. 20976 */ 20977 20978 /* Fake call progress */ 20979 transmit_response(p, "100 Trying", req); 20980 ast_setstate(c, AST_STATE_RING); 20981 20982 /* Masquerade the new call into the referred call to connect to target call 20983 Targetcall is not touched by the masq */ 20984 20985 /* Answer the incoming call and set channel to UP state */ 20986 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE, FALSE, FALSE); 20987 20988 ast_setstate(c, AST_STATE_UP); 20989 20990 /* Stop music on hold and other generators */ 20991 ast_quiet_chan(replacecall); 20992 ast_quiet_chan(targetcall); 20993 ast_debug(4, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name); 20994 20995 /* Make sure that the masq does not free our PVT for the old call */ 20996 if (! earlyreplace && ! oneleggedreplace ) 20997 ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 20998 20999 /* Prepare the masquerade - if this does not happen, we will be gone */ 21000 if(ast_channel_masquerade(replacecall, c)) 21001 ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n"); 21002 else 21003 ast_debug(4, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name); 21004 21005 /* C should now be in place of replacecall. all channel locks and pvt locks should be removed 21006 * before issuing the masq. Since we are unlocking both the pvt (p) and its owner channel (c) 21007 * it is possible for channel c to be destroyed on us. To prevent this, we must give c a reference 21008 * before any unlocking takes place and remove it only once we are completely done with it */ 21009 ast_channel_ref(c); 21010 ast_channel_unlock(replacecall); 21011 ast_channel_unlock(c); 21012 sip_pvt_unlock(p->refer->refer_call); 21013 sip_pvt_unlock(p); 21014 if (ast_do_masquerade(replacecall)) { 21015 ast_log(LOG_WARNING, "Failed to perform masquerade with INVITE replaces\n"); 21016 } 21017 ast_channel_lock(c); 21018 if (earlyreplace || oneleggedreplace ) { 21019 c->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 21020 } 21021 ast_setstate(c, AST_STATE_DOWN); 21022 ast_channel_unlock(c); 21023 21024 /* The call should be down with no ast_channel, so hang it up */ 21025 c->tech_pvt = dialog_unref(c->tech_pvt, "unref dialog c->tech_pvt"); 21026 21027 /* c and c's tech pvt must be unlocked at this point for ast_hangup */ 21028 ast_hangup(c); 21029 /* this indicates to handle_request_do that the owner channel has already been unlocked */ 21030 *nounlock = 1; 21031 /* lock PVT structure again after hangup */ 21032 sip_pvt_lock(p); 21033 ast_channel_unref(c); 21034 return 0; 21035 }
| static int handle_request_bye | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Handle incoming BYE request.
Definition at line 22653 of file chan_sip.c.
References __sip_pretend_ack(), append_history, ARRAY_LEN, ast_async_goto(), ast_bridged_channel(), AST_CAUSE_PROTOCOL_ERROR, ast_channel_lock, ast_channel_trylock, ast_channel_unlock, ast_clear_flag, AST_CONTROL_UNHOLD, ast_debug, ast_log(), AST_MAX_USER_FIELD, ast_queue_control(), ast_queue_hangup(), ast_queue_hangup_with_cause(), ast_rtp_instance_get_quality(), ast_rtp_instance_set_stats_vars(), AST_RTP_INSTANCE_STAT_FIELD_QUALITY, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_JITTER, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_LOSS, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_RTT, ast_set_hangupsource(), ast_sockaddr_stringify(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_channel::bridge, check_via(), ast_channel::context, context, copy_request(), get_also_info(), get_header(), LOG_NOTICE, LOG_WARNING, pbx_builtin_setvar_helper(), quality, sip_alreadygone(), sip_cfg, sip_methods, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy_final(), stop_media_flows(), stop_session_timer(), ast_channel::tech, ast_channel::tech_pvt, cfsip_methods::text, transmit_response(), transmit_response_reliable(), and transmit_response_with_unsupported().
Referenced by handle_incoming().
22654 { 22655 struct ast_channel *c=NULL; 22656 int res; 22657 struct ast_channel *bridged_to; 22658 const char *required; 22659 22660 /* If we have an INCOMING invite that we haven't answered, terminate that transaction */ 22661 if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !req->ignore) { 22662 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 22663 } 22664 22665 __sip_pretend_ack(p); 22666 22667 p->invitestate = INV_TERMINATED; 22668 22669 copy_request(&p->initreq, req); 22670 if (sipdebug) 22671 ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid); 22672 check_via(p, req); 22673 sip_alreadygone(p); 22674 22675 /* Get RTCP quality before end of call */ 22676 if (p->do_history || p->owner) { 22677 char quality_buf[AST_MAX_USER_FIELD], *quality; 22678 struct ast_channel *bridge = p->owner ? ast_bridged_channel(p->owner) : NULL; 22679 22680 /* We need to get the lock on bridge because ast_rtp_instance_set_stats_vars will attempt 22681 * to lock the bridge. This may get hairy... 22682 */ 22683 while (bridge && ast_channel_trylock(bridge)) { 22684 ast_channel_unlock(p->owner); 22685 do { 22686 /* Can't use DEADLOCK_AVOIDANCE since p is an ao2 object */ 22687 sip_pvt_unlock(p); 22688 usleep(1); 22689 sip_pvt_lock(p); 22690 } while (p->owner && ast_channel_trylock(p->owner)); 22691 bridge = p->owner ? ast_bridged_channel(p->owner) : NULL; 22692 } 22693 22694 22695 if (p->rtp && (quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) { 22696 if (p->do_history) { 22697 append_history(p, "RTCPaudio", "Quality:%s", quality); 22698 22699 if ((quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_JITTER, quality_buf, sizeof(quality_buf)))) { 22700 append_history(p, "RTCPaudioJitter", "Quality:%s", quality); 22701 } 22702 if ((quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_LOSS, quality_buf, sizeof(quality_buf)))) { 22703 append_history(p, "RTCPaudioLoss", "Quality:%s", quality); 22704 } 22705 if ((quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_RTT, quality_buf, sizeof(quality_buf)))) { 22706 append_history(p, "RTCPaudioRTT", "Quality:%s", quality); 22707 } 22708 } 22709 22710 if (p->owner) { 22711 ast_rtp_instance_set_stats_vars(p->owner, p->rtp); 22712 } 22713 22714 } 22715 22716 if (bridge) { 22717 struct sip_pvt *q = bridge->tech_pvt; 22718 22719 if (IS_SIP_TECH(bridge->tech) && q && q->rtp) { 22720 ast_rtp_instance_set_stats_vars(bridge, q->rtp); 22721 } 22722 ast_channel_unlock(bridge); 22723 } 22724 22725 if (p->vrtp && (quality = ast_rtp_instance_get_quality(p->vrtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) { 22726 if (p->do_history) { 22727 append_history(p, "RTCPvideo", "Quality:%s", quality); 22728 } 22729 if (p->owner) { 22730 pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", quality); 22731 } 22732 } 22733 if (p->trtp && (quality = ast_rtp_instance_get_quality(p->trtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) { 22734 if (p->do_history) { 22735 append_history(p, "RTCPtext", "Quality:%s", quality); 22736 } 22737 if (p->owner) { 22738 pbx_builtin_setvar_helper(p->owner, "RTPTEXTQOS", quality); 22739 } 22740 } 22741 } 22742 22743 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 22744 stop_session_timer(p); /* Stop Session-Timer */ 22745 22746 if (!ast_strlen_zero(get_header(req, "Also"))) { 22747 ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n", 22748 ast_sockaddr_stringify(&p->recv)); 22749 if (ast_strlen_zero(p->context)) 22750 ast_string_field_set(p, context, sip_cfg.default_context); 22751 res = get_also_info(p, req); 22752 if (!res) { 22753 c = p->owner; 22754 if (c) { 22755 bridged_to = ast_bridged_channel(c); 22756 if (bridged_to) { 22757 /* Don't actually hangup here... */ 22758 ast_queue_control(c, AST_CONTROL_UNHOLD); 22759 ast_channel_unlock(c); /* async_goto can do a masquerade, no locks can be held during a masq */ 22760 ast_async_goto(bridged_to, p->context, p->refer->refer_to, 1); 22761 ast_channel_lock(c); 22762 } else 22763 ast_queue_hangup(p->owner); 22764 } 22765 } else { 22766 ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_sockaddr_stringify(&p->recv)); 22767 if (p->owner) 22768 ast_queue_hangup_with_cause(p->owner, AST_CAUSE_PROTOCOL_ERROR); 22769 } 22770 } else if (p->owner) { 22771 ast_set_hangupsource(p->owner, p->owner->name, 0); 22772 ast_queue_hangup(p->owner); 22773 sip_scheddestroy_final(p, DEFAULT_TRANS_TIMEOUT); 22774 ast_debug(3, "Received bye, issuing owner hangup\n"); 22775 } else { 22776 sip_scheddestroy_final(p, DEFAULT_TRANS_TIMEOUT); 22777 ast_debug(3, "Received bye, no owner, selfdestruct soon.\n"); 22778 } 22779 ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 22780 22781 /* Find out what they require */ 22782 required = get_header(req, "Require"); 22783 if (!ast_strlen_zero(required)) { 22784 char unsupported[256] = { 0, }; 22785 parse_sip_options(required, unsupported, ARRAY_LEN(unsupported)); 22786 /* If there are any options required that we do not support, 22787 * then send a 420 with only those unsupported options listed */ 22788 if (!ast_strlen_zero(unsupported)) { 22789 transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, unsupported); 22790 ast_log(LOG_WARNING, "Received SIP BYE with unsupported required extension: required:%s unsupported:%s\n", required, unsupported); 22791 } else { 22792 transmit_response(p, "200 OK", req); 22793 } 22794 } else { 22795 transmit_response(p, "200 OK", req); 22796 } 22797 22798 return 1; 22799 }
| static int handle_request_cancel | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Handle incoming CANCEL request.
Definition at line 22588 of file chan_sip.c.
References __sip_pretend_ack(), ast_debug, ast_free, ast_queue_hangup(), AST_SCHED_DEL, ast_set_hangupsource(), AST_STATE_UP, ast_test_flag, check_via(), sip_alreadygone(), sip_scheddestroy(), stop_media_flows(), transmit_response(), transmit_response_reliable(), UNLINK, and update_call_counter().
Referenced by handle_incoming().
22589 { 22590 22591 check_via(p, req); 22592 sip_alreadygone(p); 22593 22594 if (p->owner && p->owner->_state == AST_STATE_UP) { 22595 /* This call is up, cancel is ignored, we need a bye */ 22596 transmit_response(p, "200 OK", req); 22597 ast_debug(1, "Got CANCEL on an answered call. Ignoring... \n"); 22598 return 0; 22599 } 22600 22601 /* At this point, we could have cancelled the invite at the same time 22602 as the other side sends a CANCEL. Our final reply with error code 22603 might not have been received by the other side before the CANCEL 22604 was sent, so let's just give up retransmissions and waiting for 22605 ACK on our error code. The call is hanging up any way. */ 22606 if (p->invitestate == INV_TERMINATED || p->invitestate == INV_COMPLETED) { 22607 __sip_pretend_ack(p); 22608 } 22609 if (p->invitestate != INV_TERMINATED) 22610 p->invitestate = INV_CANCELLED; 22611 22612 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 22613 update_call_counter(p, DEC_CALL_LIMIT); 22614 22615 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 22616 if (p->owner) { 22617 ast_set_hangupsource(p->owner, p->owner->name, 0); 22618 ast_queue_hangup(p->owner); 22619 } 22620 else 22621 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22622 if (p->initreq.len > 0) { 22623 struct sip_pkt *pkt, *prev_pkt; 22624 /* If the CANCEL we are receiving is a retransmission, and we already have scheduled 22625 * a reliable 487, then we don't want to schedule another one on top of the previous 22626 * one. 22627 * 22628 * As odd as this may sound, we can't rely on the previously-transmitted "reliable" 22629 * response in this situation. What if we've sent all of our reliable responses 22630 * already and now all of a sudden, we get this second CANCEL? 22631 * 22632 * The only way to do this correctly is to cancel our previously-scheduled reliably- 22633 * transmitted response and send a new one in its place. 22634 */ 22635 for (pkt = p->packets, prev_pkt = NULL; pkt; prev_pkt = pkt, pkt = pkt->next) { 22636 if (pkt->seqno == p->lastinvite && pkt->response_code == 487) { 22637 AST_SCHED_DEL(sched, pkt->retransid); 22638 UNLINK(pkt, p->packets, prev_pkt); 22639 ast_free(pkt); 22640 break; 22641 } 22642 } 22643 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 22644 transmit_response(p, "200 OK", req); 22645 return 1; 22646 } else { 22647 transmit_response(p, "481 Call Leg Does Not Exist", req); 22648 return 0; 22649 } 22650 }
| 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 24208 of file chan_sip.c.
References ao2_t_ref, append_history, ast_channel_trylock, ast_channel_unlock, ast_debug, AST_LIST_EMPTY, ast_log(), ast_mutex_lock, ast_mutex_unlock, AST_SCHED_DEL_UNREF, ast_sockaddr_copy(), ast_sockaddr_stringify(), ast_str_reset(), ast_update_use_count(), ast_verbose, copy_socket_data(), find_call(), find_sip_method(), get_header(), get_transport(), handle_incoming(), LOG_ERROR, lws2sws(), netlock, parse_request(), process_request_queue(), queue_request(), S_OR, sip_cfg, sip_debug_test_addr(), sip_pvt_unlock, and transmit_response().
Referenced by sipsock_read().
24209 { 24210 struct sip_pvt *p; 24211 int recount = 0; 24212 int nounlock = 0; 24213 int lockretry; 24214 24215 if (sip_debug_test_addr(addr)) /* Set the debug flag early on packet level */ 24216 req->debug = 1; 24217 if (sip_cfg.pedanticsipchecking) 24218 req->len = lws2sws(req->data->str, req->len); /* Fix multiline headers */ 24219 if (req->debug) { 24220 ast_verbose("\n<--- SIP read from %s:%s --->\n%s\n<------------->\n", 24221 get_transport(req->socket.type), ast_sockaddr_stringify(addr), req->data->str); 24222 } 24223 24224 if (parse_request(req) == -1) { /* Bad packet, can't parse */ 24225 ast_str_reset(req->data); /* nulling this out is NOT a good idea here. */ 24226 return 1; 24227 } 24228 req->method = find_sip_method(REQ_OFFSET_TO_STR(req, rlPart1)); 24229 24230 if (req->debug) 24231 ast_verbose("--- (%d headers %d lines)%s ---\n", req->headers, req->lines, (req->headers + req->lines == 0) ? " Nat keepalive" : ""); 24232 24233 if (req->headers < 2) { /* Must have at least two headers */ 24234 ast_str_reset(req->data); /* nulling this out is NOT a good idea here. */ 24235 return 1; 24236 } 24237 24238 /* Process request, with netlock held, and with usual deadlock avoidance */ 24239 for (lockretry = 10; lockretry > 0; lockretry--) { 24240 ast_mutex_lock(&netlock); 24241 24242 /* Find the active SIP dialog or create a new one */ 24243 p = find_call(req, addr, req->method); /* returns p locked */ 24244 if (p == NULL) { 24245 ast_debug(1, "Invalid SIP message - rejected , no callid, len %d\n", req->len); 24246 ast_mutex_unlock(&netlock); 24247 return 1; 24248 } 24249 24250 copy_socket_data(&p->socket, &req->socket); 24251 24252 /* Go ahead and lock the owner if it has one -- we may need it */ 24253 /* becaues this is deadlock-prone, we need to try and unlock if failed */ 24254 if (!p->owner || !ast_channel_trylock(p->owner)) 24255 break; /* locking succeeded */ 24256 24257 if (lockretry != 1) { 24258 sip_pvt_unlock(p); 24259 ao2_t_ref(p, -1, "release p (from find_call) inside lockretry loop"); /* we'll look for it again, but p is dead now */ 24260 ast_mutex_unlock(&netlock); 24261 /* Sleep for a very short amount of time */ 24262 usleep(1); 24263 } 24264 } 24265 ast_sockaddr_copy(&p->recv, addr); 24266 24267 /* if we have an owner, then this request has been authenticated */ 24268 if (p->owner) { 24269 req->authenticated = 1; 24270 } 24271 24272 if (p->do_history) /* This is a request or response, note what it was for */ 24273 append_history(p, "Rx", "%s / %s / %s", req->data->str, get_header(req, "CSeq"), REQ_OFFSET_TO_STR(req, rlPart2)); 24274 24275 if (!lockretry) { 24276 if (!queue_request(p, req)) { 24277 /* the request has been queued for later handling */ 24278 sip_pvt_unlock(p); 24279 ao2_t_ref(p, -1, "release p (from find_call) after queueing request"); 24280 ast_mutex_unlock(&netlock); 24281 return 1; 24282 } 24283 24284 if (p->owner) 24285 ast_log(LOG_ERROR, "Channel lock for %s could not be obtained, and request was unable to be queued.\n", S_OR(p->owner->name, "- no channel name ??? - ")); 24286 ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid); 24287 if (req->method != SIP_ACK) 24288 transmit_response(p, "503 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */ 24289 /* XXX We could add retry-after to make sure they come back */ 24290 append_history(p, "LockFail", "Owner lock failed, transaction failed."); 24291 sip_pvt_unlock(p); 24292 ao2_t_ref(p, -1, "release p (from find_call) at end of lockretry"); /* p is gone after the return */ 24293 ast_mutex_unlock(&netlock); 24294 return 1; 24295 } 24296 24297 /* if there are queued requests on this sip_pvt, process them first, so that everything is 24298 handled in order 24299 */ 24300 if (!AST_LIST_EMPTY(&p->request_queue)) { 24301 AST_SCHED_DEL_UNREF(sched, p->request_queue_sched_id, dialog_unref(p, "when you delete the request_queue_sched_id sched, you should dec the refcount for the stored dialog ptr")); 24302 process_request_queue(p, &recount, &nounlock); 24303 } 24304 24305 if (handle_incoming(p, req, addr, &recount, &nounlock) == -1) { 24306 /* Request failed */ 24307 ast_debug(1, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 24308 } 24309 24310 if (recount) 24311 ast_update_use_count(); 24312 24313 if (p->owner && !nounlock) 24314 ast_channel_unlock(p->owner); 24315 sip_pvt_unlock(p); 24316 ao2_t_ref(p, -1, "throw away dialog ptr from find_call at end of routine"); /* p is gone after the return */ 24317 ast_mutex_unlock(&netlock); 24318 return 1; 24319 }
| static void handle_request_info | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Receive SIP INFO Message.
Definition at line 17858 of file chan_sip.c.
References ast_bridged_channel(), ast_cdr_setuserfield(), AST_CONTROL_FLASH, AST_CONTROL_VIDUPDATE, ast_copy_string(), ast_debug, ast_find_call_feature(), AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_log(), ast_queue_control(), ast_queue_frame(), ast_rdlock_call_features(), ast_strlen_zero(), ast_test_flag, ast_unlock_call_features(), ast_verbose, ast_channel::cdr, ast_call_feature::exten, f, get_body(), get_header(), get_msg_text(), LOG_WARNING, sip_scheddestroy(), transmit_response(), and TRUE.
Referenced by handle_incoming().
17859 { 17860 char buf[1024]; 17861 unsigned int event; 17862 const char *c = get_header(req, "Content-Type"); 17863 17864 /* Need to check the media/type */ 17865 if (!strcasecmp(c, "application/dtmf-relay") || 17866 !strcasecmp(c, "application/vnd.nortelnetworks.digits")) { 17867 unsigned int duration = 0; 17868 17869 if (!p->owner) { /* not a PBX call */ 17870 transmit_response(p, "481 Call leg/transaction does not exist", req); 17871 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 17872 return; 17873 } 17874 17875 /* Try getting the "signal=" part */ 17876 if (ast_strlen_zero(c = get_body(req, "Signal", '=')) && ast_strlen_zero(c = get_body(req, "d", '='))) { 17877 ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid); 17878 transmit_response(p, "200 OK", req); /* Should return error */ 17879 return; 17880 } else { 17881 ast_copy_string(buf, c, sizeof(buf)); 17882 } 17883 17884 if (!ast_strlen_zero((c = get_body(req, "Duration", '=')))) 17885 duration = atoi(c); 17886 if (!duration) 17887 duration = 100; /* 100 ms */ 17888 17889 17890 if (ast_strlen_zero(buf)) { 17891 transmit_response(p, "200 OK", req); 17892 return; 17893 } 17894 17895 if (buf[0] == '*') 17896 event = 10; 17897 else if (buf[0] == '#') 17898 event = 11; 17899 else if ((buf[0] >= 'A') && (buf[0] <= 'D')) 17900 event = 12 + buf[0] - 'A'; 17901 else if (buf[0] == '!') 17902 event = 16; 17903 else 17904 event = atoi(buf); 17905 if (event == 16) { 17906 /* send a FLASH event */ 17907 struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_FLASH, } }; 17908 ast_queue_frame(p->owner, &f); 17909 if (sipdebug) 17910 ast_verbose("* DTMF-relay event received: FLASH\n"); 17911 } else { 17912 /* send a DTMF event */ 17913 struct ast_frame f = { AST_FRAME_DTMF, }; 17914 if (event < 10) { 17915 f.subclass.integer = '0' + event; 17916 } else if (event == 10) { 17917 f.subclass.integer = '*'; 17918 } else if (event == 11) { 17919 f.subclass.integer = '#'; 17920 } else if (event < 16) { 17921 f.subclass.integer = 'A' + (event - 12); 17922 } 17923 f.len = duration; 17924 ast_queue_frame(p->owner, &f); 17925 if (sipdebug) 17926 ast_verbose("* DTMF-relay event received: %c\n", (int) f.subclass.integer); 17927 } 17928 transmit_response(p, "200 OK", req); 17929 return; 17930 } else if (!strcasecmp(c, "application/dtmf")) { 17931 /*! \todo Note: Doesn't read the duration of the DTMF. Should be fixed. */ 17932 unsigned int duration = 0; 17933 17934 if (!p->owner) { /* not a PBX call */ 17935 transmit_response(p, "481 Call leg/transaction does not exist", req); 17936 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 17937 return; 17938 } 17939 17940 get_msg_text(buf, sizeof(buf), req, TRUE); 17941 duration = 100; /* 100 ms */ 17942 17943 if (ast_strlen_zero(buf)) { 17944 transmit_response(p, "200 OK", req); 17945 return; 17946 } 17947 event = atoi(buf); 17948 if (event == 16) { 17949 /* send a FLASH event */ 17950 struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_FLASH }, }; 17951 ast_queue_frame(p->owner, &f); 17952 if (sipdebug) 17953 ast_verbose("* DTMF-relay event received: FLASH\n"); 17954 } else { 17955 /* send a DTMF event */ 17956 struct ast_frame f = { AST_FRAME_DTMF, }; 17957 if (event < 10) { 17958 f.subclass.integer = '0' + event; 17959 } else if (event == 10) { 17960 f.subclass.integer = '*'; 17961 } else if (event == 11) { 17962 f.subclass.integer = '#'; 17963 } else if (event < 16) { 17964 f.subclass.integer = 'A' + (event - 12); 17965 } 17966 f.len = duration; 17967 ast_queue_frame(p->owner, &f); 17968 if (sipdebug) 17969 ast_verbose("* DTMF-relay event received: %c\n", (int) f.subclass.integer); 17970 } 17971 transmit_response(p, "200 OK", req); 17972 return; 17973 17974 } else if (!strcasecmp(c, "application/media_control+xml")) { 17975 /* Eh, we'll just assume it's a fast picture update for now */ 17976 if (p->owner) 17977 ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE); 17978 transmit_response(p, "200 OK", req); 17979 return; 17980 } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) { 17981 /* Client code (from SNOM phone) */ 17982 if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) { 17983 if (p->owner && p->owner->cdr) 17984 ast_cdr_setuserfield(p->owner, c); 17985 if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr) 17986 ast_cdr_setuserfield(ast_bridged_channel(p->owner), c); 17987 transmit_response(p, "200 OK", req); 17988 } else { 17989 transmit_response(p, "403 Forbidden", req); 17990 } 17991 return; 17992 } else if (!ast_strlen_zero(c = get_header(req, "Record"))) { 17993 /* INFO messages generated by some phones to start/stop recording 17994 on phone calls. 17995 OEJ: I think this should be something that is enabled/disabled 17996 per device. I don't want incoming callers to record calls in my 17997 pbx. 17998 */ 17999 /* first, get the feature string, if it exists */ 18000 struct ast_call_feature *feat; 18001 int j; 18002 struct ast_frame f = { AST_FRAME_DTMF, }; 18003 18004 ast_rdlock_call_features(); 18005 feat = ast_find_call_feature("automon"); 18006 if (!feat || ast_strlen_zero(feat->exten)) { 18007 ast_log(LOG_WARNING, "Recording requested, but no One Touch Monitor registered. (See features.conf)\n"); 18008 /* 403 means that we don't support this feature, so don't request it again */ 18009 transmit_response(p, "403 Forbidden", req); 18010 ast_unlock_call_features(); 18011 return; 18012 } 18013 /* Send the feature code to the PBX as DTMF, just like the handset had sent it */ 18014 f.len = 100; 18015 for (j=0; j < strlen(feat->exten); j++) { 18016 f.subclass.integer = feat->exten[j]; 18017 ast_queue_frame(p->owner, &f); 18018 if (sipdebug) 18019 ast_verbose("* DTMF-relay event faked: %c\n", f.subclass.integer); 18020 } 18021 ast_unlock_call_features(); 18022 18023 ast_debug(1, "Got a Request to Record the channel, state %s\n", c); 18024 transmit_response(p, "200 OK", req); 18025 return; 18026 } else if (ast_strlen_zero(c = get_header(req, "Content-Length")) || !strcasecmp(c, "0")) { 18027 /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */ 18028 transmit_response(p, "200 OK", req); 18029 return; 18030 } 18031 18032 /* Other type of INFO message, not really understood by Asterisk */ 18033 /* if (get_msg_text(buf, sizeof(buf), req)) { */ 18034 18035 ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf); 18036 transmit_response(p, "415 Unsupported media type", req); 18037 return; 18038 }
| static int handle_request_invite | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| int | debug, | |||
| int | seqno, | |||
| struct ast_sockaddr * | addr, | |||
| int * | recount, | |||
| const char * | e, | |||
| int * | nounlock | |||
| ) | [static] |
Handle incoming INVITE request.
This is a spiral. What we need to do is to just change the outgoing INVITE so that it now routes to the new Request URI. Since we created the INVITE ourselves that should be all we need to do.
Definition at line 21130 of file chan_sip.c.
References __sip_ack(), ast_channel::_state, append_history, ARRAY_LEN, AST_CAUSE_CALL_REJECTED, AST_CAUSE_NORMAL_CLEARING, ast_cc_agent_set_interfaces_chanvar(), ast_channel_lock, ast_channel_queue_connected_line_update(), ast_channel_set_redirecting(), ast_channel_unlock, ast_clear_flag, AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, AST_CONTROL_BUSY, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, ast_copy_string(), ast_debug, ast_hangup(), ast_log(), AST_MAX_CONTEXT, AST_MAX_EXTENSION, ast_null_frame, ast_party_connected_line_init(), ast_party_redirecting_free(), ast_party_redirecting_init(), AST_PBX_CALL_LIMIT, AST_PBX_FAILED, ast_pbx_start(), AST_PBX_SUCCESS, ast_pickup_call(), ast_pickup_ext(), ast_queue_control(), ast_queue_frame(), ast_rtp_instance_set_alt_remote_address(), ast_rtp_instance_set_prop(), AST_RTP_PROPERTY_DTMF, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_sched_add(), ast_set_flag, ast_setstate(), ast_setup_cc_recall_datastore(), ast_skip_blanks(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_new_with_bindaddr(), ast_uri_decode(), ast_verbose, bindaddr, build_contact(), build_route(), change_hold_state(), change_redirecting_information(), check_user_full(), check_via(), connected, context, copy_request(), do_magic_pickup(), ast_channel::exten, exten, extract_uri(), FALSE, find_sdp(), get_destination(), get_header(), get_ip_and_port_from_sdp(), get_rpid(), get_sip_pvt_byid_locked(), global_max_se, global_t38_maxdatagram, handle_invite_replaces(), ast_channel::hangupcause, io, LOG_ERROR, LOG_NOTICE, LOG_WARNING, make_our_tag(), ast_channel::name, parse_minse(), parse_ok_contact(), parse_session_expires(), process_sdp(), ref_peer(), restart_session_timer(), S_OR, set_pvt_allowed_methods(), set_t38_capabilities(), sip_alreadygone(), sip_cancel_destroy(), sip_cfg, sip_methods, sip_new(), sip_pvt_lock, sip_pvt_unlock, sip_refer_allocate(), sip_scheddestroy(), sip_st_alloc(), sip_t38_abort(), st_get_mode(), st_get_refresher(), st_get_se(), start_session_timer(), strcasestr(), strsep(), cfsip_methods::text, transmit_fake_auth_response(), transmit_provisional_response(), transmit_response(), transmit_response_reliable(), transmit_response_with_minse(), transmit_response_with_sdp(), transmit_response_with_t38_sdp(), transmit_response_with_unsupported(), TRUE, unref_peer(), update_call_counter(), and update_redirecting().
Referenced by handle_incoming().
21131 { 21132 int res = 1; 21133 int gotdest; 21134 const char *p_replaces; 21135 char *replace_id = NULL; 21136 int refer_locked = 0; 21137 const char *required; 21138 unsigned int required_profile = 0; 21139 struct ast_channel *c = NULL; /* New channel */ 21140 struct sip_peer *authpeer = NULL; /* Matching Peer */ 21141 int reinvite = 0; 21142 int rtn; 21143 struct ast_party_redirecting redirecting; 21144 struct ast_set_party_redirecting update_redirecting; 21145 21146 const char *p_uac_se_hdr; /* UAC's Session-Expires header string */ 21147 const char *p_uac_min_se; /* UAC's requested Min-SE interval (char string) */ 21148 int uac_max_se = -1; /* UAC's Session-Expires in integer format */ 21149 int uac_min_se = -1; /* UAC's Min-SE in integer format */ 21150 int st_active = FALSE; /* Session-Timer on/off boolean */ 21151 int st_interval = 0; /* Session-Timer negotiated refresh interval */ 21152 enum st_refresher st_ref; /* Session-Timer session refresher */ 21153 int dlg_min_se = -1; 21154 struct { 21155 char exten[AST_MAX_EXTENSION]; 21156 char context[AST_MAX_CONTEXT]; 21157 } pickup = { 21158 .exten = "", 21159 }; 21160 st_ref = SESSION_TIMER_REFRESHER_AUTO; 21161 21162 /* Find out what they support */ 21163 if (!p->sipoptions) { 21164 const char *supported = get_header(req, "Supported"); 21165 if (!ast_strlen_zero(supported)) { 21166 p->sipoptions = parse_sip_options(supported, NULL, 0); 21167 } 21168 } 21169 21170 /* Find out what they require */ 21171 required = get_header(req, "Require"); 21172 if (!ast_strlen_zero(required)) { 21173 char unsupported[256] = { 0, }; 21174 required_profile = parse_sip_options(required, unsupported, ARRAY_LEN(unsupported)); 21175 21176 /* If there are any options required that we do not support, 21177 * then send a 420 with only those unsupported options listed */ 21178 if (!ast_strlen_zero(unsupported)) { 21179 transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, unsupported); 21180 ast_log(LOG_WARNING, "Received SIP INVITE with unsupported required extension: required:%s unsupported:%s\n", required, unsupported); 21181 p->invitestate = INV_COMPLETED; 21182 if (!p->lastinvite) 21183 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 21184 res = -1; 21185 goto request_invite_cleanup; 21186 } 21187 } 21188 21189 /* The option tags may be present in Supported: or Require: headers. 21190 Include the Require: option tags for further processing as well */ 21191 p->sipoptions |= required_profile; 21192 p->reqsipoptions = required_profile; 21193 21194 /* Check if this is a loop */ 21195 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->invitestate != INV_TERMINATED && p->invitestate != INV_CONFIRMED) && p->owner->_state != AST_STATE_UP) { 21196 /* This is a call to ourself. Send ourselves an error code and stop 21197 processing immediately, as SIP really has no good mechanism for 21198 being able to call yourself */ 21199 /* If pedantic is on, we need to check the tags. If they're different, this is 21200 in fact a forked call through a SIP proxy somewhere. */ 21201 int different; 21202 const char *initial_rlPart2 = REQ_OFFSET_TO_STR(&p->initreq, rlPart2); 21203 const char *this_rlPart2 = REQ_OFFSET_TO_STR(req, rlPart2); 21204 if (sip_cfg.pedanticsipchecking) 21205 different = sip_uri_cmp(initial_rlPart2, this_rlPart2); 21206 else 21207 different = strcmp(initial_rlPart2, this_rlPart2); 21208 if (!different) { 21209 transmit_response(p, "482 Loop Detected", req); 21210 p->invitestate = INV_COMPLETED; 21211 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 21212 res = 0; 21213 goto request_invite_cleanup; 21214 } else { 21215 /*! This is a spiral. What we need to do is to just change the outgoing INVITE 21216 * so that it now routes to the new Request URI. Since we created the INVITE ourselves 21217 * that should be all we need to do. 21218 * 21219 * \todo XXX This needs to be reviewed. YOu don't change the request URI really, you route the packet 21220 * correctly instead... 21221 */ 21222 char *uri = ast_strdupa(this_rlPart2); 21223 char *at = strchr(uri, '@'); 21224 char *peerorhost; 21225 ast_debug(2, "Potential spiral detected. Original RURI was %s, new RURI is %s\n", initial_rlPart2, this_rlPart2); 21226 transmit_response(p, "100 Trying", req); 21227 if (at) { 21228 *at = '\0'; 21229 } 21230 /* Parse out "sip:" */ 21231 if ((peerorhost = strchr(uri, ':'))) { 21232 *peerorhost++ = '\0'; 21233 } 21234 ast_string_field_set(p, theirtag, NULL); 21235 /* Treat this as if there were a call forward instead... 21236 */ 21237 ast_string_field_set(p->owner, call_forward, peerorhost); 21238 ast_queue_control(p->owner, AST_CONTROL_BUSY); 21239 res = 0; 21240 goto request_invite_cleanup; 21241 } 21242 } 21243 21244 if (!req->ignore && p->pendinginvite) { 21245 if (!ast_test_flag(&p->flags[0], SIP_OUTGOING) && (p->invitestate == INV_COMPLETED || p->invitestate == INV_TERMINATED)) { 21246 /* What do these circumstances mean? We have received an INVITE for an "incoming" dialog for which we 21247 * have sent a final response. We have not yet received an ACK, though (which is why p->pendinginvite is non-zero). 21248 * We also know that the INVITE is not a retransmission, because otherwise the "ignore" flag would be set. 21249 * This means that either we are receiving a reinvite for a terminated dialog, or we are receiving an INVITE with 21250 * credentials based on one we challenged earlier. 21251 * 21252 * The action to take in either case is to treat the INVITE as though it contains an implicit ACK for the previous 21253 * transaction. Calling __sip_ack will take care of this by clearing the p->pendinginvite and removing the response 21254 * from the previous transaction from the list of outstanding packets. 21255 */ 21256 __sip_ack(p, p->pendinginvite, 1, 0); 21257 } else { 21258 /* We already have a pending invite. Sorry. You are on hold. */ 21259 p->glareinvite = seqno; 21260 if (p->rtp && find_sdp(req)) { 21261 struct ast_sockaddr addr; 21262 if (get_ip_and_port_from_sdp(req, SDP_AUDIO, &addr)) { 21263 ast_log(LOG_WARNING, "Failed to set an alternate media source on glared reinvite. Audio may not work properly on this call.\n"); 21264 } else { 21265 ast_rtp_instance_set_alt_remote_address(p->rtp, &addr); 21266 } 21267 if (p->vrtp) { 21268 if (get_ip_and_port_from_sdp(req, SDP_VIDEO, &addr)) { 21269 ast_log(LOG_WARNING, "Failed to set an alternate media source on glared reinvite. Video may not work properly on this call.\n"); 21270 } else { 21271 ast_rtp_instance_set_alt_remote_address(p->vrtp, &addr); 21272 } 21273 } 21274 } 21275 transmit_response_reliable(p, "491 Request Pending", req); 21276 ast_debug(1, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid); 21277 /* Don't destroy dialog here */ 21278 res = 0; 21279 goto request_invite_cleanup; 21280 } 21281 } 21282 21283 p_replaces = get_header(req, "Replaces"); 21284 if (!ast_strlen_zero(p_replaces)) { 21285 /* We have a replaces header */ 21286 char *ptr; 21287 char *fromtag = NULL; 21288 char *totag = NULL; 21289 char *start, *to; 21290 int error = 0; 21291 21292 if (p->owner) { 21293 ast_debug(3, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid); 21294 transmit_response_reliable(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 21295 /* Do not destroy existing call */ 21296 res = -1; 21297 goto request_invite_cleanup; 21298 } 21299 21300 if (sipdebug) 21301 ast_debug(3, "INVITE part of call transfer. Replaces [%s]\n", p_replaces); 21302 /* Create a buffer we can manipulate */ 21303 replace_id = ast_strdupa(p_replaces); 21304 ast_uri_decode(replace_id); 21305 21306 if (!p->refer && !sip_refer_allocate(p)) { 21307 transmit_response_reliable(p, "500 Server Internal Error", req); 21308 append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory."); 21309 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 21310 p->invitestate = INV_COMPLETED; 21311 res = -1; 21312 goto request_invite_cleanup; 21313 } 21314 21315 /* Todo: (When we find phones that support this) 21316 if the replaces header contains ";early-only" 21317 we can only replace the call in early 21318 stage, not after it's up. 21319 21320 If it's not in early mode, 486 Busy. 21321 */ 21322 21323 /* Skip leading whitespace */ 21324 replace_id = ast_skip_blanks(replace_id); 21325 21326 start = replace_id; 21327 while ( (ptr = strsep(&start, ";")) ) { 21328 ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */ 21329 if ( (to = strcasestr(ptr, "to-tag=") ) ) 21330 totag = to + 7; /* skip the keyword */ 21331 else if ( (to = strcasestr(ptr, "from-tag=") ) ) { 21332 fromtag = to + 9; /* skip the keyword */ 21333 fromtag = strsep(&fromtag, "&"); /* trim what ? */ 21334 } 21335 } 21336 21337 if (sipdebug) 21338 ast_debug(4, "Invite/replaces: Will use Replace-Call-ID : %s Fromtag: %s Totag: %s\n", 21339 replace_id, 21340 fromtag ? fromtag : "<no from tag>", 21341 totag ? totag : "<no to tag>"); 21342 21343 /* Try to find call that we are replacing. 21344 If we have a Replaces header, we need to cancel that call if we succeed with this call. 21345 First we cheat a little and look for a magic call-id from phones that support 21346 dialog-info+xml so we can do technology independent pickup... */ 21347 if (strncmp(replace_id, "pickup-", 7) == 0) { 21348 struct sip_pvt *subscription = NULL; 21349 replace_id += 7; /* Worst case we are looking at \0 */ 21350 21351 if ((subscription = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) { 21352 ast_log(LOG_NOTICE, "Unable to find subscription with call-id: %s\n", replace_id); 21353 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replaces)", req); 21354 error = 1; 21355 } else { 21356 ast_log(LOG_NOTICE, "Trying to pick up %s@%s\n", subscription->exten, subscription->context); 21357 ast_copy_string(pickup.exten, subscription->exten, sizeof(pickup.exten)); 21358 ast_copy_string(pickup.context, subscription->context, sizeof(pickup.context)); 21359 sip_pvt_unlock(subscription); 21360 if (subscription->owner) { 21361 ast_channel_unlock(subscription->owner); 21362 } 21363 } 21364 } 21365 21366 /* This locks both refer_call pvt and refer_call pvt's owner!!!*/ 21367 if (!error && ast_strlen_zero(pickup.exten) && (p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) { 21368 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id); 21369 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replaces)", req); 21370 error = 1; 21371 } else { 21372 refer_locked = 1; 21373 } 21374 21375 /* The matched call is the call from the transferer to Asterisk . 21376 We want to bridge the bridged part of the call to the 21377 incoming invite, thus taking over the refered call */ 21378 21379 if (p->refer->refer_call == p) { 21380 ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid); 21381 p->refer->refer_call = dialog_unref(p->refer->refer_call, "unref dialog p->refer->refer_call"); 21382 transmit_response_reliable(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 21383 error = 1; 21384 } 21385 21386 if (!error && ast_strlen_zero(pickup.exten) && !p->refer->refer_call->owner) { 21387 /* Oops, someting wrong anyway, no owner, no call */ 21388 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id); 21389 /* Check for better return code */ 21390 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replace)", req); 21391 error = 1; 21392 } 21393 21394 if (!error && ast_strlen_zero(pickup.exten) && p->refer->refer_call->owner->_state != AST_STATE_RINGING && p->refer->refer_call->owner->_state != AST_STATE_RING && p->refer->refer_call->owner->_state != AST_STATE_UP) { 21395 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id); 21396 transmit_response_reliable(p, "603 Declined (Replaces)", req); 21397 error = 1; 21398 } 21399 21400 if (error) { /* Give up this dialog */ 21401 append_history(p, "Xfer", "INVITE/Replace Failed."); 21402 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 21403 sip_pvt_unlock(p); 21404 if (p->refer->refer_call) { 21405 sip_pvt_unlock(p->refer->refer_call); 21406 if (p->refer->refer_call->owner) { 21407 ast_channel_unlock(p->refer->refer_call->owner); 21408 } 21409 } 21410 refer_locked = 0; 21411 p->invitestate = INV_COMPLETED; 21412 res = -1; 21413 goto request_invite_cleanup; 21414 } 21415 } 21416 21417 /* Check if this is an INVITE that sets up a new dialog or 21418 a re-invite in an existing dialog */ 21419 21420 if (!req->ignore) { 21421 int newcall = (p->initreq.headers ? TRUE : FALSE); 21422 21423 if (sip_cancel_destroy(p)) 21424 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 21425 /* This also counts as a pending invite */ 21426 p->pendinginvite = seqno; 21427 check_via(p, req); 21428 21429 copy_request(&p->initreq, req); /* Save this INVITE as the transaction basis */ 21430 if (sipdebug) 21431 ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid); 21432 if (!p->owner) { /* Not a re-invite */ 21433 if (debug) 21434 ast_verbose("Using INVITE request as basis request - %s\n", p->callid); 21435 if (newcall) 21436 append_history(p, "Invite", "New call: %s", p->callid); 21437 parse_ok_contact(p, req); 21438 } else { /* Re-invite on existing call */ 21439 ast_clear_flag(&p->flags[0], SIP_OUTGOING); /* This is now an inbound dialog */ 21440 if (get_rpid(p, req)) { 21441 struct ast_party_connected_line connected; 21442 struct ast_set_party_connected_line update_connected; 21443 21444 ast_party_connected_line_init(&connected); 21445 memset(&update_connected, 0, sizeof(update_connected)); 21446 if (p->cid_num) { 21447 update_connected.id.number = 1; 21448 connected.id.number.valid = 1; 21449 connected.id.number.str = (char *) p->cid_num; 21450 connected.id.number.presentation = p->callingpres; 21451 } 21452 if (p->cid_name) { 21453 update_connected.id.name = 1; 21454 connected.id.name.valid = 1; 21455 connected.id.name.str = (char *) p->cid_name; 21456 connected.id.name.presentation = p->callingpres; 21457 } 21458 connected.id.tag = (char *) p->cid_tag; 21459 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER; 21460 ast_channel_queue_connected_line_update(p->owner, &connected, 21461 &update_connected); 21462 } 21463 /* Handle SDP here if we already have an owner */ 21464 if (find_sdp(req)) { 21465 if (process_sdp(p, req, SDP_T38_INITIATE)) { 21466 if (!ast_strlen_zero(get_header(req, "Content-Encoding"))) { 21467 /* Asterisk does not yet support any Content-Encoding methods. Always 21468 * attempt to process the sdp, but return a 415 if a Content-Encoding header 21469 * was present after processing failed. */ 21470 transmit_response_reliable(p, "415 Unsupported Media type", req); 21471 } else { 21472 transmit_response_reliable(p, "488 Not acceptable here", req); 21473 } 21474 if (!p->lastinvite) 21475 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 21476 res = -1; 21477 goto request_invite_cleanup; 21478 } 21479 ast_queue_control(p->owner, AST_CONTROL_SRCUPDATE); 21480 } else { 21481 p->jointcapability = p->capability; 21482 ast_debug(1, "Hm.... No sdp for the moment\n"); 21483 /* Some devices signal they want to be put off hold by sending a re-invite 21484 *without* an SDP, which is supposed to mean "Go back to your state" 21485 and since they put os on remote hold, we go back to off hold */ 21486 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 21487 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 21488 /* Activate a re-invite */ 21489 ast_queue_frame(p->owner, &ast_null_frame); 21490 change_hold_state(p, req, FALSE, 0); 21491 } 21492 } 21493 if (p->do_history) /* This is a response, note what it was for */ 21494 append_history(p, "ReInv", "Re-invite received"); 21495 } 21496 } else if (debug) 21497 ast_verbose("Ignoring this INVITE request\n"); 21498 21499 if (!p->lastinvite && !req->ignore && !p->owner) { 21500 /* This is a new invite */ 21501 /* Handle authentication if this is our first invite */ 21502 int cc_recall_core_id = -1; 21503 set_pvt_allowed_methods(p, req); 21504 res = check_user_full(p, req, SIP_INVITE, e, XMIT_RELIABLE, addr, &authpeer); 21505 if (res == AUTH_CHALLENGE_SENT) { 21506 p->invitestate = INV_COMPLETED; /* Needs to restart in another INVITE transaction */ 21507 res = 0; 21508 goto request_invite_cleanup; 21509 } 21510 if (res < 0) { /* Something failed in authentication */ 21511 if (res == AUTH_FAKE_AUTH) { 21512 ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", get_header(req, "From")); 21513 transmit_fake_auth_response(p, SIP_INVITE, req, XMIT_RELIABLE); 21514 } else { 21515 ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From")); 21516 transmit_response_reliable(p, "403 Forbidden", req); 21517 } 21518 p->invitestate = INV_COMPLETED; 21519 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 21520 ast_string_field_set(p, theirtag, NULL); 21521 res = 0; 21522 goto request_invite_cleanup; 21523 } 21524 21525 /* Successful authentication and peer matching so record the peer related to this pvt (for easy access to peer settings) */ 21526 if (p->relatedpeer) { 21527 p->relatedpeer = unref_peer(p->relatedpeer,"unsetting the relatedpeer field in the dialog, before it is set to something else."); 21528 } 21529 if (authpeer) { 21530 p->relatedpeer = ref_peer(authpeer, "setting dialog's relatedpeer pointer"); 21531 } 21532 /* If T38 is needed but not present, then make it magically appear */ 21533 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) && !p->udptl) { 21534 if ((p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, &bindaddr))) { 21535 p->t38_maxdatagram = global_t38_maxdatagram; 21536 set_t38_capabilities(p); 21537 } else { 21538 /* udptl creation failed, T38 can not be supported on this dialog */ 21539 ast_debug(1, "UDPTL creation failed on dialog.\n"); 21540 ast_clear_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT); 21541 } 21542 } 21543 21544 req->authenticated = 1; 21545 21546 /* We have a successful authentication, process the SDP portion if there is one */ 21547 if (find_sdp(req)) { 21548 if (process_sdp(p, req, SDP_T38_INITIATE)) { 21549 /* Asterisk does not yet support any Content-Encoding methods. Always 21550 * attempt to process the sdp, but return a 415 if a Content-Encoding header 21551 * was present after processing fails. */ 21552 if (!ast_strlen_zero(get_header(req, "Content-Encoding"))) { 21553 transmit_response_reliable(p, "415 Unsupported Media type", req); 21554 } else { 21555 /* Unacceptable codecs */ 21556 transmit_response_reliable(p, "488 Not acceptable here", req); 21557 } 21558 p->invitestate = INV_COMPLETED; 21559 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 21560 ast_debug(1, "No compatible codecs for this SIP call.\n"); 21561 res = -1; 21562 goto request_invite_cleanup; 21563 } 21564 } else { /* No SDP in invite, call control session */ 21565 p->jointcapability = p->capability; 21566 ast_debug(2, "No SDP in Invite, third party call control\n"); 21567 } 21568 21569 /* Queue NULL frame to prod ast_rtp_bridge if appropriate */ 21570 /* This seems redundant ... see !p-owner above */ 21571 if (p->owner) 21572 ast_queue_frame(p->owner, &ast_null_frame); 21573 21574 21575 /* Initialize the context if it hasn't been already */ 21576 if (ast_strlen_zero(p->context)) 21577 ast_string_field_set(p, context, sip_cfg.default_context); 21578 21579 21580 /* Check number of concurrent calls -vs- incoming limit HERE */ 21581 ast_debug(1, "Checking SIP call limits for device %s\n", p->username); 21582 if ((res = update_call_counter(p, INC_CALL_LIMIT))) { 21583 if (res < 0) { 21584 ast_log(LOG_NOTICE, "Failed to place call for device %s, too many calls\n", p->username); 21585 transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req); 21586 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 21587 p->invitestate = INV_COMPLETED; 21588 } 21589 res = 0; 21590 goto request_invite_cleanup; 21591 } 21592 gotdest = get_destination(p, NULL, &cc_recall_core_id); /* Get destination right away */ 21593 extract_uri(p, req); /* Get the Contact URI */ 21594 build_contact(p); /* Build our contact header */ 21595 21596 if (p->rtp) { 21597 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 21598 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 21599 } 21600 21601 if (!replace_id && (gotdest != SIP_GET_DEST_EXTEN_FOUND)) { /* No matching extension found */ 21602 switch(gotdest) { 21603 case SIP_GET_DEST_INVALID_URI: 21604 transmit_response_reliable(p, "416 Unsupported URI scheme", req); 21605 break; 21606 case SIP_GET_DEST_PICKUP_EXTEN_FOUND: 21607 if (ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) { 21608 transmit_response_reliable(p, "484 Address Incomplete", req); 21609 break; 21610 } 21611 /* INTENTIONAL FALL THROUGH */ 21612 case SIP_GET_DEST_EXTEN_NOT_FOUND: 21613 case SIP_GET_DEST_REFUSED: 21614 default: 21615 { 21616 char *decoded_exten = ast_strdupa(p->exten); 21617 transmit_response_reliable(p, "404 Not Found", req); 21618 ast_uri_decode(decoded_exten); 21619 ast_log(LOG_NOTICE, "Call from '%s' to extension" 21620 " '%s' rejected because extension not found in context '%s'.\n", 21621 S_OR(p->username, p->peername), decoded_exten, p->context); 21622 } 21623 } /* end switch */ 21624 21625 p->invitestate = INV_COMPLETED; 21626 update_call_counter(p, DEC_CALL_LIMIT); 21627 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 21628 res = 0; 21629 goto request_invite_cleanup; 21630 } else { 21631 21632 /* If no extension was specified, use the s one */ 21633 /* Basically for calling to IP/Host name only */ 21634 if (ast_strlen_zero(p->exten)) 21635 ast_string_field_set(p, exten, "s"); 21636 /* Initialize our tag */ 21637 21638 make_our_tag(p->tag, sizeof(p->tag)); 21639 /* First invitation - create the channel. Allocation 21640 * failures are handled below. */ 21641 c = sip_new(p, AST_STATE_DOWN, S_OR(p->peername, NULL), NULL); 21642 if (cc_recall_core_id != -1) { 21643 ast_setup_cc_recall_datastore(c, cc_recall_core_id); 21644 ast_cc_agent_set_interfaces_chanvar(c); 21645 } 21646 *recount = 1; 21647 21648 /* Save Record-Route for any later requests we make on this dialogue */ 21649 build_route(p, req, 0); 21650 21651 if (c) { 21652 ast_party_redirecting_init(&redirecting); 21653 memset(&update_redirecting, 0, sizeof(update_redirecting)); 21654 /* Pre-lock the call */ 21655 ast_channel_lock(c); 21656 change_redirecting_information(p, req, &redirecting, &update_redirecting, 21657 FALSE); /*Will return immediately if no Diversion header is present */ 21658 ast_channel_set_redirecting(c, &redirecting, &update_redirecting); 21659 ast_party_redirecting_free(&redirecting); 21660 } 21661 } 21662 } else { 21663 ast_party_redirecting_init(&redirecting); 21664 memset(&update_redirecting, 0, sizeof(update_redirecting)); 21665 if (sipdebug) { 21666 if (!req->ignore) 21667 ast_debug(2, "Got a SIP re-invite for call %s\n", p->callid); 21668 else 21669 ast_debug(2, "Got a SIP re-transmit of INVITE for call %s\n", p->callid); 21670 } 21671 if (!req->ignore) 21672 reinvite = 1; 21673 c = p->owner; 21674 change_redirecting_information(p, req, &redirecting, &update_redirecting, FALSE); /*Will return immediately if no Diversion header is present */ 21675 if (c) { 21676 ast_channel_set_redirecting(c, &redirecting, &update_redirecting); 21677 } 21678 ast_party_redirecting_free(&redirecting); 21679 } 21680 21681 /* Session-Timers */ 21682 if ((p->sipoptions & SIP_OPT_TIMER) && !ast_strlen_zero(get_header(req, "Session-Expires"))) { 21683 /* The UAC has requested session-timers for this session. Negotiate 21684 the session refresh interval and who will be the refresher */ 21685 ast_debug(2, "Incoming INVITE with 'timer' option supported and \"Session-Expires\" header.\n"); 21686 21687 /* Allocate Session-Timers struct w/in the dialog */ 21688 if (!p->stimer) 21689 sip_st_alloc(p); 21690 21691 /* Parse the Session-Expires header */ 21692 p_uac_se_hdr = get_header(req, "Session-Expires"); 21693 rtn = parse_session_expires(p_uac_se_hdr, &uac_max_se, &st_ref); 21694 if (rtn != 0) { 21695 transmit_response_reliable(p, "400 Session-Expires Invalid Syntax", req); 21696 p->invitestate = INV_COMPLETED; 21697 if (!p->lastinvite) { 21698 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 21699 } 21700 res = -1; 21701 goto request_invite_cleanup; 21702 } 21703 21704 /* Parse the Min-SE header */ 21705 p_uac_min_se = get_header(req, "Min-SE"); 21706 if (!ast_strlen_zero(p_uac_min_se)) { 21707 rtn = parse_minse(p_uac_min_se, &uac_min_se); 21708 if (rtn != 0) { 21709 transmit_response_reliable(p, "400 Min-SE Invalid Syntax", req); 21710 p->invitestate = INV_COMPLETED; 21711 if (!p->lastinvite) { 21712 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 21713 } 21714 res = -1; 21715 goto request_invite_cleanup; 21716 } 21717 } 21718 21719 dlg_min_se = st_get_se(p, FALSE); 21720 switch (st_get_mode(p)) { 21721 case SESSION_TIMER_MODE_ACCEPT: 21722 case SESSION_TIMER_MODE_ORIGINATE: 21723 if (uac_max_se > 0 && uac_max_se < dlg_min_se) { 21724 transmit_response_with_minse(p, "422 Session Interval Too Small", req, dlg_min_se); 21725 p->invitestate = INV_COMPLETED; 21726 if (!p->lastinvite) { 21727 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 21728 } 21729 res = -1; 21730 goto request_invite_cleanup; 21731 } 21732 21733 p->stimer->st_active_peer_ua = TRUE; 21734 st_active = TRUE; 21735 if (st_ref == SESSION_TIMER_REFRESHER_AUTO) { 21736 st_ref = st_get_refresher(p); 21737 } 21738 21739 if (uac_max_se > 0) { 21740 int dlg_max_se = st_get_se(p, TRUE); 21741 if (dlg_max_se >= uac_min_se) { 21742 st_interval = (uac_max_se < dlg_max_se) ? uac_max_se : dlg_max_se; 21743 } else { 21744 st_interval = uac_max_se; 21745 } 21746 } else { 21747 /* Set to default max value */ 21748 st_interval = global_max_se; 21749 } 21750 break; 21751 21752 case SESSION_TIMER_MODE_REFUSE: 21753 if (p->reqsipoptions & SIP_OPT_TIMER) { 21754 transmit_response_with_unsupported(p, "420 Option Disabled", req, required); 21755 ast_log(LOG_WARNING, "Received SIP INVITE with supported but disabled option: %s\n", required); 21756 p->invitestate = INV_COMPLETED; 21757 if (!p->lastinvite) { 21758 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 21759 } 21760 res = -1; 21761 goto request_invite_cleanup; 21762 } 21763 break; 21764 21765 default: 21766 ast_log(LOG_ERROR, "Internal Error %d at %s:%d\n", st_get_mode(p), __FILE__, __LINE__); 21767 break; 21768 } 21769 } else { 21770 /* The UAC did not request session-timers. Asterisk (UAS), will now decide 21771 (based on session-timer-mode in sip.conf) whether to run session-timers for 21772 this session or not. */ 21773 switch (st_get_mode(p)) { 21774 case SESSION_TIMER_MODE_ORIGINATE: 21775 st_active = TRUE; 21776 st_interval = st_get_se(p, TRUE); 21777 st_ref = SESSION_TIMER_REFRESHER_UAS; 21778 p->stimer->st_active_peer_ua = FALSE; 21779 break; 21780 21781 default: 21782 break; 21783 } 21784 } 21785 21786 if (reinvite == 0) { 21787 /* Session-Timers: Start session refresh timer based on negotiation/config */ 21788 if (st_active == TRUE) { 21789 p->stimer->st_active = TRUE; 21790 p->stimer->st_interval = st_interval; 21791 p->stimer->st_ref = st_ref; 21792 start_session_timer(p); 21793 } 21794 } else { 21795 if (p->stimer->st_active == TRUE) { 21796 /* Session-Timers: A re-invite request sent within a dialog will serve as 21797 a refresh request, no matter whether the re-invite was sent for refreshing 21798 the session or modifying it.*/ 21799 ast_debug (2, "Restarting session-timers on a refresh - %s\n", p->callid); 21800 21801 /* The UAC may be adjusting the session-timers mid-session */ 21802 if (st_interval > 0) { 21803 p->stimer->st_interval = st_interval; 21804 p->stimer->st_ref = st_ref; 21805 } 21806 21807 restart_session_timer(p); 21808 if (p->stimer->st_expirys > 0) { 21809 p->stimer->st_expirys--; 21810 } 21811 } 21812 } 21813 21814 if (!req->ignore && p) 21815 p->lastinvite = seqno; 21816 21817 if (c && replace_id) { /* Attended transfer or call pickup - we're the target */ 21818 if (!ast_strlen_zero(pickup.exten)) { 21819 append_history(p, "Xfer", "INVITE/Replace received"); 21820 21821 /* Let the caller know we're giving it a shot */ 21822 transmit_response(p, "100 Trying", req); 21823 p->invitestate = INV_PROCEEDING; 21824 ast_setstate(c, AST_STATE_RING); 21825 21826 /* Do the pickup itself */ 21827 ast_channel_unlock(c); 21828 *nounlock = 1; 21829 21830 /* since p->owner (c) is unlocked, we need to go ahead and unlock pvt for both 21831 * magic pickup and ast_hangup. Both of these functions will attempt to lock 21832 * p->owner again, which can cause a deadlock if we already hold a lock on p. 21833 * Locking order is, channel then pvt. Dead lock avoidance must be used if 21834 * called the other way around. */ 21835 sip_pvt_unlock(p); 21836 do_magic_pickup(c, pickup.exten, pickup.context); 21837 /* Now we're either masqueraded or we failed to pickup, in either case we... */ 21838 ast_hangup(c); 21839 sip_pvt_lock(p); /* pvt is expected to remain locked on return, so re-lock it */ 21840 21841 res = 0; 21842 goto request_invite_cleanup; 21843 } else { 21844 /* Go and take over the target call */ 21845 if (sipdebug) 21846 ast_debug(4, "Sending this call to the invite/replcaes handler %s\n", p->callid); 21847 res = handle_invite_replaces(p, req, debug, seqno, addr, nounlock); 21848 refer_locked = 0; 21849 goto request_invite_cleanup; 21850 } 21851 } 21852 21853 21854 if (c) { /* We have a call -either a new call or an old one (RE-INVITE) */ 21855 enum ast_channel_state c_state = c->_state; 21856 21857 if (c_state != AST_STATE_UP && reinvite && 21858 (p->invitestate == INV_TERMINATED || p->invitestate == INV_CONFIRMED)) { 21859 /* If these conditions are true, and the channel is still in the 'ringing' 21860 * state, then this likely means that we have a situation where the initial 21861 * INVITE transaction has completed *but* the channel's state has not yet been 21862 * changed to UP. The reason this could happen is if the reinvite is received 21863 * on the SIP socket prior to an application calling ast_read on this channel 21864 * to read the answer frame we earlier queued on it. In this case, the reinvite 21865 * is completely legitimate so we need to handle this the same as if the channel 21866 * were already UP. Thus we are purposely falling through to the AST_STATE_UP case. 21867 */ 21868 c_state = AST_STATE_UP; 21869 } 21870 21871 switch(c_state) { 21872 case AST_STATE_DOWN: 21873 ast_debug(2, "%s: New call is still down.... Trying... \n", c->name); 21874 transmit_provisional_response(p, "100 Trying", req, 0); 21875 p->invitestate = INV_PROCEEDING; 21876 ast_setstate(c, AST_STATE_RING); 21877 if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */ 21878 enum ast_pbx_result result; 21879 21880 result = ast_pbx_start(c); 21881 21882 switch(result) { 21883 case AST_PBX_FAILED: 21884 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 21885 p->invitestate = INV_COMPLETED; 21886 transmit_response_reliable(p, "503 Unavailable", req); 21887 break; 21888 case AST_PBX_CALL_LIMIT: 21889 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n"); 21890 p->invitestate = INV_COMPLETED; 21891 transmit_response_reliable(p, "480 Temporarily Unavailable", req); 21892 break; 21893 case AST_PBX_SUCCESS: 21894 /* nothing to do */ 21895 break; 21896 } 21897 21898 if (result) { 21899 21900 /* Unlock locks so ast_hangup can do its magic */ 21901 ast_channel_unlock(c); 21902 sip_pvt_unlock(p); 21903 ast_hangup(c); 21904 sip_pvt_lock(p); 21905 c = NULL; 21906 } 21907 } else { /* Pickup call in call group */ 21908 ast_channel_unlock(c); 21909 *nounlock = 1; 21910 if (ast_pickup_call(c)) { 21911 ast_log(LOG_NOTICE, "Nothing to pick up for %s\n", p->callid); 21912 transmit_response_reliable(p, "503 Unavailable", req); 21913 sip_alreadygone(p); 21914 /* Unlock locks so ast_hangup can do its magic */ 21915 sip_pvt_unlock(p); 21916 c->hangupcause = AST_CAUSE_CALL_REJECTED; 21917 } else { 21918 sip_pvt_unlock(p); 21919 c->hangupcause = AST_CAUSE_NORMAL_CLEARING; 21920 } 21921 p->invitestate = INV_COMPLETED; 21922 ast_hangup(c); 21923 sip_pvt_lock(p); 21924 c = NULL; 21925 } 21926 break; 21927 case AST_STATE_RING: 21928 transmit_provisional_response(p, "100 Trying", req, 0); 21929 p->invitestate = INV_PROCEEDING; 21930 break; 21931 case AST_STATE_RINGING: 21932 transmit_provisional_response(p, "180 Ringing", req, 0); 21933 p->invitestate = INV_PROCEEDING; 21934 break; 21935 case AST_STATE_UP: 21936 ast_debug(2, "%s: This call is UP.... \n", c->name); 21937 21938 transmit_response(p, "100 Trying", req); 21939 21940 if (p->t38.state == T38_PEER_REINVITE) { 21941 p->t38id = ast_sched_add(sched, 5000, sip_t38_abort, dialog_ref(p, "passing dialog ptr into sched structure based on t38id for sip_t38_abort.")); 21942 } else if (p->t38.state == T38_ENABLED) { 21943 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 21944 transmit_response_with_t38_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (req->ignore ? XMIT_UNRELIABLE : XMIT_CRITICAL))); 21945 } else if (p->t38.state == T38_DISABLED) { 21946 /* If this is not a re-invite or something to ignore - it's critical */ 21947 if (p->srtp && !ast_test_flag(p->srtp, SRTP_CRYPTO_OFFER_OK)) { 21948 ast_log(LOG_WARNING, "Target does not support required crypto\n"); 21949 transmit_response_reliable(p, "488 Not Acceptable Here (crypto)", req); 21950 } else { 21951 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 21952 transmit_response_with_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (req->ignore ? XMIT_UNRELIABLE : XMIT_CRITICAL)), p->session_modify == TRUE ? FALSE : TRUE, FALSE); 21953 } 21954 } 21955 21956 p->invitestate = INV_TERMINATED; 21957 break; 21958 default: 21959 ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state); 21960 transmit_response(p, "100 Trying", req); 21961 break; 21962 } 21963 } else { 21964 if (p && (p->autokillid == -1)) { 21965 const char *msg; 21966 21967 if (!p->jointcapability) 21968 msg = "488 Not Acceptable Here (codec error)"; 21969 else { 21970 ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n"); 21971 msg = "503 Unavailable"; 21972 } 21973 transmit_response_reliable(p, msg, req); 21974 p->invitestate = INV_COMPLETED; 21975 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 21976 } 21977 } 21978 21979 request_invite_cleanup: 21980 21981 if (refer_locked && p->refer && p->refer->refer_call) { 21982 sip_pvt_unlock(p->refer->refer_call); 21983 if (p->refer->refer_call->owner) { 21984 ast_channel_unlock(p->refer->refer_call->owner); 21985 } 21986 } 21987 if (authpeer) { 21988 authpeer = unref_peer(authpeer, "unref_peer, from handle_request_invite authpeer"); 21989 } 21990 21991 return res; 21992 }
| static int handle_request_message | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Handle incoming MESSAGE request.
Definition at line 22802 of file chan_sip.c.
References ast_verbose, receive_message(), and transmit_response().
Referenced by handle_incoming().
22803 { 22804 if (!req->ignore) { 22805 if (req->debug) 22806 ast_verbose("Receiving message!\n"); 22807 receive_message(p, req); 22808 } else 22809 transmit_response(p, "202 Accepted", req); 22810 return 1; 22811 }
| static int handle_request_notify | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| struct ast_sockaddr * | addr, | |||
| int | seqno, | |||
| const char * | e | |||
| ) | [static] |
Handle incoming notifications.
Definition at line 20670 of file chan_sip.c.
References AST_CONTROL_TRANSFER, ast_debug, AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, ast_event_new(), ast_event_queue_and_cache(), ast_log(), ast_queue_control_data(), ast_skip_blanks(), ast_strdupa, ast_strlen_zero(), AST_TRANSFER_FAILED, AST_TRANSFER_SUCCESS, FALSE, find_peer(), get_body(), get_header(), get_msg_text(), handle_cc_notify(), LOG_NOTICE, LOG_WARNING, mailbox, sip_scheddestroy(), strsep(), transmit_response(), TRUE, and unref_peer().
Referenced by handle_incoming().
20671 { 20672 /* This is mostly a skeleton for future improvements */ 20673 /* Mostly created to return proper answers on notifications on outbound REFER's */ 20674 int res = 0; 20675 const char *event = get_header(req, "Event"); 20676 char *eventid = NULL; 20677 char *sep; 20678 20679 if( (sep = strchr(event, ';')) ) { /* XXX bug here - overwriting string ? */ 20680 *sep++ = '\0'; 20681 eventid = sep; 20682 } 20683 20684 if (sipdebug) 20685 ast_debug(2, "Got NOTIFY Event: %s\n", event); 20686 20687 if (!strcmp(event, "refer")) { 20688 /* Save nesting depth for now, since there might be other events we will 20689 support in the future */ 20690 20691 /* Handle REFER notifications */ 20692 20693 char buf[1024]; 20694 char *cmd, *code; 20695 int respcode; 20696 int success = TRUE; 20697 20698 /* EventID for each transfer... EventID is basically the REFER cseq 20699 20700 We are getting notifications on a call that we transfered 20701 We should hangup when we are getting a 200 OK in a sipfrag 20702 Check if we have an owner of this event */ 20703 20704 /* Check the content type */ 20705 if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) { 20706 /* We need a sipfrag */ 20707 transmit_response(p, "400 Bad request", req); 20708 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 20709 return -1; 20710 } 20711 20712 /* Get the text of the attachment */ 20713 if (get_msg_text(buf, sizeof(buf), req, TRUE)) { 20714 ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid); 20715 transmit_response(p, "400 Bad request", req); 20716 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 20717 return -1; 20718 } 20719 20720 /* 20721 From the RFC... 20722 A minimal, but complete, implementation can respond with a single 20723 NOTIFY containing either the body: 20724 SIP/2.0 100 Trying 20725 20726 if the subscription is pending, the body: 20727 SIP/2.0 200 OK 20728 if the reference was successful, the body: 20729 SIP/2.0 503 Service Unavailable 20730 if the reference failed, or the body: 20731 SIP/2.0 603 Declined 20732 20733 if the REFER request was accepted before approval to follow the 20734 reference could be obtained and that approval was subsequently denied 20735 (see Section 2.4.7). 20736 20737 If there are several REFERs in the same dialog, we need to 20738 match the ID of the event header... 20739 */ 20740 ast_debug(3, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf); 20741 cmd = ast_skip_blanks(buf); 20742 code = cmd; 20743 /* We are at SIP/2.0 */ 20744 while(*code && (*code > 32)) { /* Search white space */ 20745 code++; 20746 } 20747 *code++ = '\0'; 20748 code = ast_skip_blanks(code); 20749 sep = code; 20750 sep++; 20751 while(*sep && (*sep > 32)) { /* Search white space */ 20752 sep++; 20753 } 20754 *sep++ = '\0'; /* Response string */ 20755 respcode = atoi(code); 20756 switch (respcode) { 20757 case 200: /* OK: The new call is up, hangup this call */ 20758 /* Hangup the call that we are replacing */ 20759 break; 20760 case 301: /* Moved permenantly */ 20761 case 302: /* Moved temporarily */ 20762 /* Do we get the header in the packet in this case? */ 20763 success = FALSE; 20764 break; 20765 case 503: /* Service Unavailable: The new call failed */ 20766 case 603: /* Declined: Not accepted */ 20767 /* Cancel transfer, continue the current call */ 20768 success = FALSE; 20769 break; 20770 case 0: /* Parse error */ 20771 /* Cancel transfer, continue the current call */ 20772 ast_log(LOG_NOTICE, "Error parsing sipfrag in NOTIFY in response to REFER.\n"); 20773 success = FALSE; 20774 break; 20775 default: 20776 if (respcode < 200) { 20777 /* ignore provisional responses */ 20778 success = -1; 20779 } else { 20780 ast_log(LOG_NOTICE, "Got unknown code '%d' in NOTIFY in response to REFER.\n", respcode); 20781 success = FALSE; 20782 } 20783 break; 20784 } 20785 if (success == FALSE) { 20786 ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n"); 20787 } 20788 20789 if (p->owner && success != -1) { 20790 enum ast_control_transfer message = success ? AST_TRANSFER_SUCCESS : AST_TRANSFER_FAILED; 20791 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 20792 } 20793 /* Confirm that we received this packet */ 20794 transmit_response(p, "200 OK", req); 20795 } else if (!strcmp(event, "message-summary")) { 20796 const char *mailbox = NULL; 20797 char *c = ast_strdupa(get_body(req, "Voice-Message", ':')); 20798 20799 if (!p->mwi) { 20800 struct sip_peer *peer = find_peer(NULL, &p->recv, TRUE, FINDPEERS, FALSE, p->socket.type); 20801 20802 if (peer) { 20803 mailbox = ast_strdupa(peer->unsolicited_mailbox); 20804 unref_peer(peer, "removing unsolicited mwi ref"); 20805 } 20806 } else { 20807 mailbox = p->mwi->mailbox; 20808 } 20809 20810 if (!ast_strlen_zero(mailbox) && !ast_strlen_zero(c)) { 20811 char *old = strsep(&c, " "); 20812 char *new = strsep(&old, "/"); 20813 struct ast_event *event; 20814 20815 if ((event = ast_event_new(AST_EVENT_MWI, 20816 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 20817 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, "SIP_Remote", 20818 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, atoi(new), 20819 AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, atoi(old), 20820 AST_EVENT_IE_END))) { 20821 ast_event_queue_and_cache(event); 20822 } 20823 transmit_response(p, "200 OK", req); 20824 } else { 20825 transmit_response(p, "489 Bad event", req); 20826 res = -1; 20827 } 20828 } else if (!strcmp(event, "keep-alive")) { 20829 /* Used by Sipura/Linksys for NAT pinhole, 20830 * just confirm that we received the packet. */ 20831 transmit_response(p, "200 OK", req); 20832 } else if (!strcmp(event, "call-completion")) { 20833 res = handle_cc_notify(p, req); 20834 } else { 20835 /* We don't understand this event. */ 20836 transmit_response(p, "489 Bad event", req); 20837 res = -1; 20838 } 20839 20840 if (!p->lastinvite) 20841 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 20842 20843 return res; 20844 }
| 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 20849 of file chan_sip.c.
References ast_log(), ast_shutting_down(), ast_string_field_set, ast_strlen_zero(), build_contact(), check_user(), context, copy_request(), get_destination(), get_header(), LOG_NOTICE, set_pvt_allowed_methods(), sip_cfg, sip_scheddestroy(), transmit_fake_auth_response(), transmit_response(), and transmit_response_with_allow().
Referenced by handle_incoming().
20850 { 20851 int res; 20852 20853 if (p->lastinvite) { 20854 /* if this is a request in an active dialog, just confirm that the dialog exists. */ 20855 transmit_response_with_allow(p, "200 OK", req, 0); 20856 return 0; 20857 } 20858 20859 if (sip_cfg.auth_options_requests) { 20860 /* Do authentication if this OPTIONS request began the dialog */ 20861 copy_request(&p->initreq, req); 20862 set_pvt_allowed_methods(p, req); 20863 res = check_user(p, req, SIP_OPTIONS, e, XMIT_UNRELIABLE, addr); 20864 if (res == AUTH_CHALLENGE_SENT) { 20865 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 20866 return 0; 20867 } 20868 if (res < 0) { /* Something failed in authentication */ 20869 if (res == AUTH_FAKE_AUTH) { 20870 ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", get_header(req, "From")); 20871 transmit_fake_auth_response(p, SIP_OPTIONS, req, XMIT_UNRELIABLE); 20872 } else { 20873 ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From")); 20874 transmit_response(p, "403 Forbidden", req); 20875 } 20876 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 20877 return 0; 20878 } 20879 } 20880 20881 /* must go through authentication before getting here */ 20882 res = (get_destination(p, req, NULL) == SIP_GET_DEST_EXTEN_FOUND ? 0 : -1); 20883 build_contact(p); 20884 20885 if (ast_strlen_zero(p->context)) 20886 ast_string_field_set(p, context, sip_cfg.default_context); 20887 20888 if (ast_shutting_down()) 20889 transmit_response_with_allow(p, "503 Unavailable", req, 0); 20890 else if (res < 0) 20891 transmit_response_with_allow(p, "404 Not Found", req, 0); 20892 else 20893 transmit_response_with_allow(p, "200 OK", req, 0); 20894 20895 /* Destroy if this OPTIONS was the opening request, but not if 20896 it's in the middle of a normal call flow. */ 20897 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 20898 20899 return res; 20900 }
| static int handle_request_publish | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| struct ast_sockaddr * | addr, | |||
| const int | seqno, | |||
| const char * | uri | |||
| ) | [static] |
Definition at line 23233 of file chan_sip.c.
References __sip_ack(), ast_log(), ast_string_field_set, ast_strlen_zero(), check_user(), determine_sip_publish_type(), get_esc(), get_header(), handle_sip_publish_initial(), handle_sip_publish_modify(), handle_sip_publish_refresh(), handle_sip_publish_remove(), LOG_NOTICE, sip_scheddestroy(), transmit_fake_auth_response(), transmit_response(), and transmit_response_reliable().
Referenced by handle_incoming().
23234 { 23235 const char *etag = get_header(req, "SIP-If-Match"); 23236 const char *event = get_header(req, "Event"); 23237 struct event_state_compositor *esc; 23238 enum sip_publish_type publish_type; 23239 const char *expires_str = get_header(req, "Expires"); 23240 int expires_int; 23241 int auth_result; 23242 int handler_result = -1; 23243 23244 if (ast_strlen_zero(event)) { 23245 transmit_response(p, "489 Bad Event", req); 23246 return -1; 23247 } 23248 23249 if (!(esc = get_esc(event))) { 23250 transmit_response(p, "489 Bad Event", req); 23251 return -1; 23252 } 23253 23254 auth_result = check_user(p, req, SIP_PUBLISH, uri, XMIT_RELIABLE, addr); 23255 if (auth_result == AUTH_CHALLENGE_SENT) { 23256 p->lastinvite = seqno; 23257 return 0; 23258 } else if (auth_result < 0) { 23259 if (auth_result == AUTH_FAKE_AUTH) { 23260 ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", get_header(req, "From")); 23261 transmit_fake_auth_response(p, SIP_INVITE, req, XMIT_RELIABLE); 23262 } else { 23263 ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From")); 23264 transmit_response_reliable(p, "403 Forbidden", req); 23265 } 23266 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23267 ast_string_field_set(p, theirtag, NULL); 23268 return 0; 23269 } else if (auth_result == AUTH_SUCCESSFUL && p->lastinvite) { 23270 /* We need to stop retransmitting the 401 */ 23271 __sip_ack(p, p->lastinvite, 1, 0); 23272 } 23273 23274 publish_type = determine_sip_publish_type(req, event, etag, expires_str, &expires_int); 23275 23276 /* It is the responsibility of these handlers to formulate any response 23277 * sent for a PUBLISH 23278 */ 23279 switch (publish_type) { 23280 case SIP_PUBLISH_UNKNOWN: 23281 transmit_response(p, "400 Bad Request", req); 23282 break; 23283 case SIP_PUBLISH_INITIAL: 23284 handler_result = handle_sip_publish_initial(p, req, esc, expires_int); 23285 break; 23286 case SIP_PUBLISH_REFRESH: 23287 handler_result = handle_sip_publish_refresh(p, req, esc, etag, expires_int); 23288 break; 23289 case SIP_PUBLISH_MODIFY: 23290 handler_result = handle_sip_publish_modify(p, req, esc, etag, expires_int); 23291 break; 23292 case SIP_PUBLISH_REMOVE: 23293 handler_result = handle_sip_publish_remove(p, req, esc, etag); 23294 break; 23295 default: 23296 transmit_response(p, "400 Impossible Condition", req); 23297 break; 23298 } 23299 23300 return handler_result; 23301 }
| static int handle_request_refer | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| int | debug, | |||
| int | seqno, | |||
| int * | nounlock | |||
| ) | [static] |
Definition at line 22257 of file chan_sip.c.
References append_history, ast_async_goto(), ast_bridged_channel(), AST_CAUSE_NORMAL_CLEARING, AST_CEL_ATTENDEDTRANSFER, AST_CEL_BLINDTRANSFER, ast_cel_report_event(), ast_channel_ref, ast_channel_trylock, ast_channel_unlock, ast_channel_unref, ast_clear_flag, AST_CONTROL_UNHOLD, ast_debug, ast_indicate(), AST_LIST_EMPTY, ast_manager_event_multichan, ast_parking_ext_valid(), ast_queue_control(), ast_set_flag, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose, check_sip_domain(), context, copy_request(), EVENT_FLAG_CALL, FALSE, get_refer_info(), local_attended_transfer(), ast_channel::name, pbx_builtin_setvar_helper(), pvt_set_needdestroy(), sip_alreadygone(), sip_cfg, sip_park(), sip_pvt_lock, sip_pvt_unlock, sip_refer_allocate(), transmit_notify_with_sipfrag(), transmit_response(), and TRUE.
Referenced by handle_incoming().
22258 { 22259 struct sip_dual current; /* Chan1: Call between asterisk and transferer */ 22260 /* Chan2: Call between asterisk and transferee */ 22261 22262 int res = 0; 22263 struct ast_channel *chans[2]; 22264 current.req.data = NULL; 22265 22266 if (req->debug) 22267 ast_verbose("Call %s got a SIP call transfer from %s: (REFER)!\n", p->callid, ast_test_flag(&p->flags[0], SIP_OUTGOING) ? "callee" : "caller"); 22268 22269 if (!p->owner) { 22270 /* This is a REFER outside of an existing SIP dialog */ 22271 /* We can't handle that, so decline it */ 22272 ast_debug(3, "Call %s: Declined REFER, outside of dialog...\n", p->callid); 22273 transmit_response(p, "603 Declined (No dialog)", req); 22274 if (!req->ignore) { 22275 append_history(p, "Xfer", "Refer failed. Outside of dialog."); 22276 sip_alreadygone(p); 22277 pvt_set_needdestroy(p, "outside of dialog"); 22278 } 22279 return 0; 22280 } 22281 22282 22283 /* Check if transfer is allowed from this device */ 22284 if (p->allowtransfer == TRANSFER_CLOSED ) { 22285 /* Transfer not allowed, decline */ 22286 transmit_response(p, "603 Declined (policy)", req); 22287 append_history(p, "Xfer", "Refer failed. Allowtransfer == closed."); 22288 /* Do not destroy SIP session */ 22289 return 0; 22290 } 22291 22292 if (!req->ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 22293 /* Already have a pending REFER */ 22294 transmit_response(p, "491 Request pending", req); 22295 append_history(p, "Xfer", "Refer failed. Request pending."); 22296 return 0; 22297 } 22298 22299 /* Allocate memory for call transfer data */ 22300 if (!p->refer && !sip_refer_allocate(p)) { 22301 transmit_response(p, "500 Internal Server Error", req); 22302 append_history(p, "Xfer", "Refer failed. Memory allocation error."); 22303 return -3; 22304 } 22305 22306 res = get_refer_info(p, req); /* Extract headers */ 22307 22308 p->refer->status = REFER_SENT; 22309 22310 if (res != 0) { 22311 switch (res) { 22312 case -2: /* Syntax error */ 22313 transmit_response(p, "400 Bad Request (Refer-to missing)", req); 22314 append_history(p, "Xfer", "Refer failed. Refer-to missing."); 22315 if (req->debug) 22316 ast_debug(1, "SIP transfer to black hole can't be handled (no refer-to: )\n"); 22317 break; 22318 case -3: 22319 transmit_response(p, "603 Declined (Non sip: uri)", req); 22320 append_history(p, "Xfer", "Refer failed. Non SIP uri"); 22321 if (req->debug) 22322 ast_debug(1, "SIP transfer to non-SIP uri denied\n"); 22323 break; 22324 default: 22325 /* Refer-to extension not found, fake a failed transfer */ 22326 transmit_response(p, "202 Accepted", req); 22327 append_history(p, "Xfer", "Refer failed. Bad extension."); 22328 transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE); 22329 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 22330 if (req->debug) 22331 ast_debug(1, "SIP transfer to bad extension: %s\n", p->refer->refer_to); 22332 break; 22333 } 22334 return 0; 22335 } 22336 if (ast_strlen_zero(p->context)) 22337 ast_string_field_set(p, context, sip_cfg.default_context); 22338 22339 /* If we do not support SIP domains, all transfers are local */ 22340 if (sip_cfg.allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 22341 p->refer->localtransfer = 1; 22342 if (sipdebug) 22343 ast_debug(3, "This SIP transfer is local : %s\n", p->refer->refer_to_domain); 22344 } else if (AST_LIST_EMPTY(&domain_list) || check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 22345 /* This PBX doesn't bother with SIP domains or domain is local, so this transfer is local */ 22346 p->refer->localtransfer = 1; 22347 } else if (sipdebug) 22348 ast_debug(3, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain); 22349 22350 /* Is this a repeat of a current request? Ignore it */ 22351 /* Don't know what else to do right now. */ 22352 if (req->ignore) 22353 return res; 22354 22355 /* If this is a blind transfer, we have the following 22356 channels to work with: 22357 - chan1, chan2: The current call between transferer and transferee (2 channels) 22358 - target_channel: A new call from the transferee to the target (1 channel) 22359 We need to stay tuned to what happens in order to be able 22360 to bring back the call to the transferer */ 22361 22362 /* If this is a attended transfer, we should have all call legs within reach: 22363 - chan1, chan2: The call between the transferer and transferee (2 channels) 22364 - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels) 22365 We want to bridge chan2 with targetcall_pvt! 22366 22367 The replaces call id in the refer message points 22368 to the call leg between Asterisk and the transferer. 22369 So we need to connect the target and the transferee channel 22370 and hangup the two other channels silently 22371 22372 If the target is non-local, the call ID could be on a remote 22373 machine and we need to send an INVITE with replaces to the 22374 target. We basically handle this as a blind transfer 22375 and let the sip_call function catch that we need replaces 22376 header in the INVITE. 22377 */ 22378 22379 22380 /* Get the transferer's channel */ 22381 chans[0] = current.chan1 = p->owner; 22382 22383 /* Find the other part of the bridge (2) - transferee */ 22384 chans[1] = current.chan2 = ast_bridged_channel(current.chan1); 22385 22386 if (sipdebug) 22387 ast_debug(3, "SIP %s transfer: Transferer channel %s, transferee channel %s\n", p->refer->attendedtransfer ? "attended" : "blind", current.chan1->name, current.chan2 ? current.chan2->name : "<none>"); 22388 22389 if (!current.chan2 && !p->refer->attendedtransfer) { 22390 /* No bridged channel, propably IVR or echo or similar... */ 22391 /* Guess we should masquerade or something here */ 22392 /* Until we figure it out, refuse transfer of such calls */ 22393 if (sipdebug) 22394 ast_debug(3, "Refused SIP transfer on non-bridged channel.\n"); 22395 p->refer->status = REFER_FAILED; 22396 append_history(p, "Xfer", "Refer failed. Non-bridged channel."); 22397 transmit_response(p, "603 Declined", req); 22398 return -1; 22399 } 22400 22401 if (current.chan2) { 22402 if (sipdebug) 22403 ast_debug(4, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name); 22404 22405 ast_queue_control(current.chan1, AST_CONTROL_UNHOLD); 22406 } 22407 22408 ast_set_flag(&p->flags[0], SIP_GOTREFER); 22409 22410 /* From here on failures will be indicated with NOTIFY requests */ 22411 transmit_response(p, "202 Accepted", req); 22412 22413 /* Attended transfer: Find all call legs and bridge transferee with target*/ 22414 if (p->refer->attendedtransfer) { 22415 if ((res = local_attended_transfer(p, ¤t, req, seqno, nounlock))) 22416 return res; /* We're done with the transfer */ 22417 /* Fall through for remote transfers that we did not find locally */ 22418 if (sipdebug) 22419 ast_debug(4, "SIP attended transfer: Still not our call - generating INVITE with replaces\n"); 22420 /* Fallthrough if we can't find the call leg internally */ 22421 } 22422 22423 /* Must release lock now, because it will not longer 22424 be accessible after the transfer! */ 22425 *nounlock = 1; 22426 /* 22427 * Increase ref count so that we can delay channel destruction until after 22428 * we get a chance to fire off some events. 22429 */ 22430 ast_channel_ref(current.chan1); 22431 sip_pvt_unlock(p); 22432 ast_channel_unlock(current.chan1); 22433 22434 /* Parking a call */ 22435 if (p->refer->localtransfer && ast_parking_ext_valid(p->refer->refer_to, p->owner, p->owner->context)) { 22436 sip_pvt_lock(p); 22437 copy_request(¤t.req, req); 22438 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 22439 p->refer->status = REFER_200OK; 22440 append_history(p, "Xfer", "REFER to call parking."); 22441 ast_manager_event_multichan(EVENT_FLAG_CALL, "Transfer", 2, chans, 22442 "TransferMethod: SIP\r\n" 22443 "TransferType: Blind\r\n" 22444 "Channel: %s\r\n" 22445 "Uniqueid: %s\r\n" 22446 "SIP-Callid: %s\r\n" 22447 "TargetChannel: %s\r\n" 22448 "TargetUniqueid: %s\r\n" 22449 "TransferExten: %s\r\n" 22450 "Transfer2Parking: Yes\r\n", 22451 current.chan1->name, 22452 current.chan1->uniqueid, 22453 p->callid, 22454 current.chan2->name, 22455 current.chan2->uniqueid, 22456 p->refer->refer_to); 22457 if (sipdebug) 22458 ast_debug(4, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name); 22459 if (sip_park(current.chan2, current.chan1, req, seqno, p->refer->refer_to)) { 22460 transmit_notify_with_sipfrag(p, seqno, "500 Internal Server Error", TRUE); 22461 } 22462 ast_channel_unref(current.chan1); 22463 return res; 22464 } 22465 22466 /* Blind transfers and remote attended xfers */ 22467 if (current.chan1 && current.chan2) { 22468 ast_debug(3, "chan1->name: %s\n", current.chan1->name); 22469 pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name); 22470 } 22471 22472 sip_pvt_lock(p); 22473 22474 if (current.chan2) { 22475 pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name); 22476 pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", p->refer->refer_to_domain); 22477 pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes"); 22478 /* One for the new channel */ 22479 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes"); 22480 /* Attended transfer to remote host, prepare headers for the INVITE */ 22481 if (p->refer->referred_by) 22482 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", p->refer->referred_by); 22483 } 22484 /* Generate a Replaces string to be used in the INVITE during attended transfer */ 22485 if (!ast_strlen_zero(p->refer->replaces_callid)) { 22486 char tempheader[SIPBUFSIZE]; 22487 snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid, 22488 p->refer->replaces_callid_totag ? ";to-tag=" : "", 22489 p->refer->replaces_callid_totag, 22490 p->refer->replaces_callid_fromtag ? ";from-tag=" : "", 22491 p->refer->replaces_callid_fromtag); 22492 if (current.chan2) 22493 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader); 22494 } 22495 22496 /* Connect the call */ 22497 22498 /* FAKE ringing if not attended transfer */ 22499 if (!p->refer->attendedtransfer) 22500 transmit_notify_with_sipfrag(p, seqno, "183 Ringing", FALSE); 22501 22502 /* For blind transfer, this will lead to a new call */ 22503 /* For attended transfer to remote host, this will lead to 22504 a new SIP call with a replaces header, if the dial plan allows it 22505 */ 22506 if (!current.chan2) { 22507 /* We have no bridge, so we're talking with Asterisk somehow */ 22508 /* We need to masquerade this call */ 22509 /* What to do to fix this situation: 22510 * Set up the new call in a new channel 22511 * Let the new channel masq into this channel 22512 Please add that code here :-) 22513 */ 22514 p->refer->status = REFER_FAILED; 22515 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE); 22516 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 22517 append_history(p, "Xfer", "Refer failed (only bridged calls)."); 22518 ast_channel_unref(current.chan1); 22519 return -1; 22520 } 22521 ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 22522 22523 22524 /* For blind transfers, move the call to the new extensions. For attended transfers on multiple 22525 servers - generate an INVITE with Replaces. Either way, let the dial plan decided */ 22526 /* indicate before masquerade so the indication actually makes it to the real channel 22527 when using local channels with MOH passthru */ 22528 ast_indicate(current.chan2, AST_CONTROL_UNHOLD); 22529 res = ast_async_goto(current.chan2, p->refer->refer_to_context, p->refer->refer_to, 1); 22530 22531 if (!res) { 22532 ast_manager_event_multichan(EVENT_FLAG_CALL, "Transfer", 2, chans, 22533 "TransferMethod: SIP\r\n" 22534 "TransferType: Blind\r\n" 22535 "Channel: %s\r\n" 22536 "Uniqueid: %s\r\n" 22537 "SIP-Callid: %s\r\n" 22538 "TargetChannel: %s\r\n" 22539 "TargetUniqueid: %s\r\n" 22540 "TransferExten: %s\r\n" 22541 "TransferContext: %s\r\n", 22542 current.chan1->name, 22543 current.chan1->uniqueid, 22544 p->callid, 22545 current.chan2->name, 22546 current.chan2->uniqueid, 22547 p->refer->refer_to, p->refer->refer_to_context); 22548 /* Success - we have a new channel */ 22549 ast_debug(3, "%s transfer succeeded. Telling transferer.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 22550 22551 while (ast_channel_trylock(current.chan1)) { 22552 sip_pvt_unlock(p); 22553 sched_yield(); 22554 sip_pvt_lock(p); 22555 } 22556 22557 /* XXX - what to we put in CEL 'extra' for attended transfers to external systems? NULL for now */ 22558 ast_cel_report_event(current.chan1, p->refer->attendedtransfer? AST_CEL_ATTENDEDTRANSFER : AST_CEL_BLINDTRANSFER, NULL, p->refer->attendedtransfer ? NULL : p->refer->refer_to, current.chan2); 22559 ast_channel_unlock(current.chan1); 22560 22561 transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE); 22562 if (p->refer->localtransfer) 22563 p->refer->status = REFER_200OK; 22564 if (p->owner) 22565 p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING; 22566 append_history(p, "Xfer", "Refer succeeded."); 22567 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 22568 /* Do not hangup call, the other side do that when we say 200 OK */ 22569 /* We could possibly implement a timer here, auto congestion */ 22570 res = 0; 22571 } else { 22572 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */ 22573 ast_debug(3, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 22574 append_history(p, "Xfer", "Refer failed."); 22575 /* Failure of some kind */ 22576 p->refer->status = REFER_FAILED; 22577 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE); 22578 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 22579 res = -1; 22580 } 22581 22582 ast_channel_unref(current.chan1); 22583 22584 return res; 22585 }
| 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 23727 of file chan_sip.c.
References append_history, ast_debug, ast_log(), ast_sockaddr_stringify(), check_via(), copy_request(), get_header(), LOG_NOTICE, LOG_WARNING, register_verify(), sip_methods, sip_scheddestroy(), and cfsip_methods::text.
Referenced by handle_incoming().
23728 { 23729 enum check_auth_result res; 23730 23731 /* If this is not the intial request, and the initial request isn't 23732 * a register, something screwy happened, so bail */ 23733 if (p->initreq.headers && p->initreq.method != SIP_REGISTER) { 23734 ast_log(LOG_WARNING, "Ignoring spurious REGISTER with Call-ID: %s\n", p->callid); 23735 return -1; 23736 } 23737 23738 /* Use this as the basis */ 23739 copy_request(&p->initreq, req); 23740 if (sipdebug) 23741 ast_debug(4, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid); 23742 check_via(p, req); 23743 if ((res = register_verify(p, addr, req, e)) < 0) { 23744 const char *reason; 23745 23746 switch (res) { 23747 case AUTH_SECRET_FAILED: 23748 reason = "Wrong password"; 23749 break; 23750 case AUTH_USERNAME_MISMATCH: 23751 reason = "Username/auth name mismatch"; 23752 break; 23753 case AUTH_NOT_FOUND: 23754 reason = "No matching peer found"; 23755 break; 23756 case AUTH_UNKNOWN_DOMAIN: 23757 reason = "Not a local domain"; 23758 break; 23759 case AUTH_PEER_NOT_DYNAMIC: 23760 reason = "Peer is not supposed to register"; 23761 break; 23762 case AUTH_ACL_FAILED: 23763 reason = "Device does not match ACL"; 23764 break; 23765 case AUTH_BAD_TRANSPORT: 23766 reason = "Device not configured to use this transport type"; 23767 break; 23768 default: 23769 reason = "Unknown failure"; 23770 break; 23771 } 23772 ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n", 23773 get_header(req, "To"), ast_sockaddr_stringify(addr), 23774 reason); 23775 append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason); 23776 } else { 23777 req->authenticated = 1; 23778 append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To")); 23779 } 23780 23781 if (res < 1) { 23782 /* Destroy the session, but keep us around for just a bit in case they don't 23783 get our 200 OK */ 23784 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23785 } 23786 return res; 23787 }
| static int handle_request_subscribe | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| struct ast_sockaddr * | addr, | |||
| int | seqno, | |||
| const char * | e | |||
| ) | [static] |
Handle incoming SUBSCRIBE request.
Definition at line 23373 of file chan_sip.c.
References __get_header(), add_peer_mwi_subs(), ao2_lock, ao2_unlock, append_history, ast_debug, AST_EXTENSION_REMOVED, ast_extension_state(), ast_extension_state2str(), ast_extension_state_add(), ast_extension_state_del(), AST_LIST_EMPTY, ast_log(), ast_set_flag, ast_sockaddr_stringify(), ast_strdupa, ast_string_field_build, ast_strlen_zero(), ast_test_flag, ast_verbose, build_contact(), build_route(), cb_extensionstate(), check_user_full(), check_via(), copy_request(), dialog_unlink_all(), FALSE, get_destination(), get_header(), gettag(), handle_cc_subscribe(), LOG_DEBUG, LOG_NOTICE, LOG_WARNING, make_our_tag(), max_expiry, min_expiry, NONE, option_debug, parse_ok_contact(), pvt_set_needdestroy(), ref_peer(), set_pvt_allowed_methods(), sip_cancel_destroy(), sip_cfg, sip_methods, sip_scheddestroy(), sip_send_mwi_to_peer(), cfsip_methods::text, transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_response_with_minexpires(), transmit_state_notify(), TRUE, and unref_peer().
Referenced by handle_incoming().
23374 { 23375 int gotdest = 0; 23376 int res = 0; 23377 int firststate = AST_EXTENSION_REMOVED; 23378 struct sip_peer *authpeer = NULL; 23379 const char *eventheader = get_header(req, "Event"); /* Get Event package name */ 23380 int resubscribe = (p->subscribed != NONE) && !req->ignore; 23381 char *temp, *event; 23382 23383 if (p->initreq.headers) { 23384 /* We already have a dialog */ 23385 if (p->initreq.method != SIP_SUBSCRIBE) { 23386 /* This is a SUBSCRIBE within another SIP dialog, which we do not support */ 23387 /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */ 23388 transmit_response(p, "403 Forbidden (within dialog)", req); 23389 /* Do not destroy session, since we will break the call if we do */ 23390 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); 23391 return 0; 23392 } else if (req->debug) { 23393 if (resubscribe) 23394 ast_debug(1, "Got a re-subscribe on existing subscription %s\n", p->callid); 23395 else 23396 ast_debug(1, "Got a new subscription %s (possibly with auth) or retransmission\n", p->callid); 23397 } 23398 } 23399 23400 /* Check if we have a global disallow setting on subscriptions. 23401 if so, we don't have to check peer settings after auth, which saves a lot of processing 23402 */ 23403 if (!sip_cfg.allowsubscribe) { 23404 transmit_response(p, "403 Forbidden (policy)", req); 23405 pvt_set_needdestroy(p, "forbidden"); 23406 return 0; 23407 } 23408 23409 if (!req->ignore && !resubscribe) { /* Set up dialog, new subscription */ 23410 const char *to = get_header(req, "To"); 23411 char totag[128]; 23412 set_pvt_allowed_methods(p, req); 23413 23414 /* Check to see if a tag was provided, if so this is actually a resubscription of a dialog we no longer know about */ 23415 if (!ast_strlen_zero(to) && gettag(req, "To", totag, sizeof(totag))) { 23416 if (req->debug) 23417 ast_verbose("Received resubscription for a dialog we no longer know about. Telling remote side to subscribe again.\n"); 23418 transmit_response(p, "481 Subscription does not exist", req); 23419 pvt_set_needdestroy(p, "subscription does not exist"); 23420 return 0; 23421 } 23422 23423 /* Use this as the basis */ 23424 if (req->debug) 23425 ast_verbose("Creating new subscription\n"); 23426 23427 copy_request(&p->initreq, req); 23428 if (sipdebug) 23429 ast_debug(4, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid); 23430 check_via(p, req); 23431 build_route(p, req, 0); 23432 } else if (req->debug && req->ignore) 23433 ast_verbose("Ignoring this SUBSCRIBE request\n"); 23434 23435 /* Find parameters to Event: header value and remove them for now */ 23436 if (ast_strlen_zero(eventheader)) { 23437 transmit_response(p, "489 Bad Event", req); 23438 ast_debug(2, "Received SIP subscribe for unknown event package: <none>\n"); 23439 pvt_set_needdestroy(p, "unknown event package in subscribe"); 23440 return 0; 23441 } 23442 23443 if ( (strchr(eventheader, ';'))) { 23444 event = ast_strdupa(eventheader); /* Since eventheader is a const, we can't change it */ 23445 temp = strchr(event, ';'); 23446 *temp = '\0'; /* Remove any options for now */ 23447 /* We might need to use them later :-) */ 23448 } else 23449 event = (char *) eventheader; /* XXX is this legal ? */ 23450 23451 /* Handle authentication if we're new and not a retransmission. We can't just 23452 * use if !req->ignore, because then we'll end up sending 23453 * a 200 OK if someone retransmits without sending auth */ 23454 if (p->subscribed == NONE || resubscribe) { 23455 res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, addr, &authpeer); 23456 23457 /* if an authentication response was sent, we are done here */ 23458 if (res == AUTH_CHALLENGE_SENT) /* authpeer = NULL here */ 23459 return 0; 23460 if (res < 0) { 23461 if (res == AUTH_FAKE_AUTH) { 23462 ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", get_header(req, "From")); 23463 transmit_fake_auth_response(p, SIP_SUBSCRIBE, req, XMIT_UNRELIABLE); 23464 } else { 23465 ast_log(LOG_NOTICE, "Failed to authenticate device %s for SUBSCRIBE\n", get_header(req, "From")); 23466 transmit_response_reliable(p, "403 Forbidden", req); 23467 } 23468 23469 pvt_set_needdestroy(p, "authentication failed"); 23470 return 0; 23471 } 23472 } 23473 23474 /* At this point, authpeer cannot be NULL. Remember we hold a reference, 23475 * so we must release it when done. 23476 * XXX must remove all the checks for authpeer == NULL. 23477 */ 23478 23479 /* Check if this device is allowed to subscribe at all */ 23480 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) { 23481 transmit_response(p, "403 Forbidden (policy)", req); 23482 pvt_set_needdestroy(p, "subscription not allowed"); 23483 if (authpeer) 23484 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 1)"); 23485 return 0; 23486 } 23487 23488 if (strcmp(event, "message-summary") && strcmp(event, "call-completion")) { 23489 /* Get destination right away */ 23490 gotdest = get_destination(p, NULL, NULL); 23491 } 23492 23493 /* Get full contact header - this needs to be used as a request URI in NOTIFY's */ 23494 parse_ok_contact(p, req); 23495 23496 build_contact(p); 23497 if (gotdest != SIP_GET_DEST_EXTEN_FOUND) { 23498 if (gotdest == SIP_GET_DEST_INVALID_URI) { 23499 transmit_response(p, "416 Unsupported URI scheme", req); 23500 } else { 23501 transmit_response(p, "404 Not Found", req); 23502 } 23503 pvt_set_needdestroy(p, "subscription target not found"); 23504 if (authpeer) 23505 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 2)"); 23506 return 0; 23507 } 23508 23509 /* Initialize tag for new subscriptions */ 23510 if (ast_strlen_zero(p->tag)) 23511 make_our_tag(p->tag, sizeof(p->tag)); 23512 23513 if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */ 23514 unsigned int pidf_xml; 23515 const char *accept; 23516 int start = 0; 23517 enum subscriptiontype subscribed = NONE; 23518 const char *unknown_acceptheader = NULL; 23519 23520 if (authpeer) /* We do not need the authpeer any more */ 23521 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 2)"); 23522 23523 /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */ 23524 accept = __get_header(req, "Accept", &start); 23525 while ((subscribed == NONE) && !ast_strlen_zero(accept)) { 23526 pidf_xml = strstr(accept, "application/pidf+xml") ? 1 : 0; 23527 23528 /* Older versions of Polycom firmware will claim pidf+xml, but really 23529 * they only support xpidf+xml. */ 23530 if (pidf_xml && strstr(p->useragent, "Polycom")) { 23531 subscribed = XPIDF_XML; 23532 } else if (pidf_xml) { 23533 subscribed = PIDF_XML; /* RFC 3863 format */ 23534 } else if (strstr(accept, "application/dialog-info+xml")) { 23535 subscribed = DIALOG_INFO_XML; 23536 /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */ 23537 } else if (strstr(accept, "application/cpim-pidf+xml")) { 23538 subscribed = CPIM_PIDF_XML; /* RFC 3863 format */ 23539 } else if (strstr(accept, "application/xpidf+xml")) { 23540 subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */ 23541 } else { 23542 unknown_acceptheader = accept; 23543 } 23544 /* check to see if there is another Accept header present */ 23545 accept = __get_header(req, "Accept", &start); 23546 } 23547 23548 if (!start) { 23549 if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */ 23550 transmit_response(p, "489 Bad Event", req); 23551 ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: " 23552 "stateid: %d, laststate: %d, dialogver: %d, subscribecont: " 23553 "'%s', subscribeuri: '%s'\n", 23554 p->stateid, 23555 p->laststate, 23556 p->dialogver, 23557 p->subscribecontext, 23558 p->subscribeuri); 23559 pvt_set_needdestroy(p, "no Accept header"); 23560 return 0; 23561 } 23562 /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least. 23563 so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */ 23564 } else if (subscribed == NONE) { 23565 /* Can't find a format for events that we know about */ 23566 char mybuf[200]; 23567 if (!ast_strlen_zero(unknown_acceptheader)) { 23568 snprintf(mybuf, sizeof(mybuf), "489 Bad Event (format %s)", unknown_acceptheader); 23569 } else { 23570 snprintf(mybuf, sizeof(mybuf), "489 Bad Event"); 23571 } 23572 transmit_response(p, mybuf, req); 23573 ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format:" 23574 "'%s' pvt: subscribed: %d, stateid: %d, laststate: %d," 23575 "dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 23576 unknown_acceptheader, 23577 (int)p->subscribed, 23578 p->stateid, 23579 p->laststate, 23580 p->dialogver, 23581 p->subscribecontext, 23582 p->subscribeuri); 23583 pvt_set_needdestroy(p, "unrecognized format"); 23584 return 0; 23585 } else { 23586 p->subscribed = subscribed; 23587 } 23588 } else if (!strcmp(event, "message-summary")) { 23589 int start = 0; 23590 int found_supported = 0; 23591 const char *acceptheader; 23592 23593 acceptheader = __get_header(req, "Accept", &start); 23594 while (!found_supported && !ast_strlen_zero(acceptheader)) { 23595 found_supported = strcmp(acceptheader, "application/simple-message-summary") ? 0 : 1; 23596 if (!found_supported && (option_debug > 2)) { 23597 ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", acceptheader); 23598 } 23599 acceptheader = __get_header(req, "Accept", &start); 23600 } 23601 if (start && !found_supported) { 23602 /* Format requested that we do not support */ 23603 transmit_response(p, "406 Not Acceptable", req); 23604 ast_debug(2, "Received SIP mailbox subscription for unknown format: %s\n", acceptheader); 23605 pvt_set_needdestroy(p, "unknown format"); 23606 if (authpeer) 23607 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 3)"); 23608 return 0; 23609 } 23610 /* Looks like they actually want a mailbox status 23611 This version of Asterisk supports mailbox subscriptions 23612 The subscribed URI needs to exist in the dial plan 23613 In most devices, this is configurable to the voicemailmain extension you use 23614 */ 23615 if (!authpeer || AST_LIST_EMPTY(&authpeer->mailboxes)) { 23616 transmit_response(p, "404 Not found (no mailbox)", req); 23617 pvt_set_needdestroy(p, "received 404 response"); 23618 ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name); 23619 if (authpeer) 23620 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 4)"); 23621 return 0; 23622 } 23623 23624 p->subscribed = MWI_NOTIFICATION; 23625 if (ast_test_flag(&authpeer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY)) { 23626 add_peer_mwi_subs(authpeer); 23627 } 23628 if (authpeer->mwipvt && authpeer->mwipvt != p) { /* Destroy old PVT if this is a new one */ 23629 /* We only allow one subscription per peer */ 23630 dialog_unlink_all(authpeer->mwipvt, TRUE, TRUE); 23631 authpeer->mwipvt = dialog_unref(authpeer->mwipvt, "unref dialog authpeer->mwipvt"); 23632 /* sip_destroy(authpeer->mwipvt); */ 23633 } 23634 if (authpeer->mwipvt) 23635 dialog_unref(authpeer->mwipvt, "Unref previously stored mwipvt dialog pointer"); 23636 authpeer->mwipvt = dialog_ref(p, "setting peers' mwipvt to p"); /* Link from peer to pvt UH- should this be dialog_ref()? */ 23637 if (p->relatedpeer) 23638 unref_peer(p->relatedpeer, "Unref previously stored relatedpeer ptr"); 23639 p->relatedpeer = ref_peer(authpeer, "setting dialog's relatedpeer pointer"); /* already refcounted...Link from pvt to peer UH- should this be dialog_ref()? */ 23640 /* Do not release authpeer here */ 23641 } else if (!strcmp(event, "call-completion")) { 23642 handle_cc_subscribe(p, req); 23643 } else { /* At this point, Asterisk does not understand the specified event */ 23644 transmit_response(p, "489 Bad Event", req); 23645 ast_debug(2, "Received SIP subscribe for unknown event package: %s\n", event); 23646 pvt_set_needdestroy(p, "unknown event package"); 23647 if (authpeer) 23648 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 5)"); 23649 return 0; 23650 } 23651 23652 /* Add subscription for extension state from the PBX core */ 23653 if (p->subscribed != MWI_NOTIFICATION && p->subscribed != CALL_COMPLETION && !resubscribe) { 23654 if (p->stateid > -1) { 23655 ast_extension_state_del(p->stateid, cb_extensionstate); 23656 /* we need to dec the refcount, now that the extensionstate is removed */ 23657 dialog_unref(p, "the extensionstate containing this dialog ptr was deleted"); 23658 } 23659 p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, dialog_ref(p,"copying dialog ptr into extension state struct")); 23660 } 23661 23662 if (!req->ignore && p) 23663 p->lastinvite = seqno; 23664 if (p && !p->needdestroy) { 23665 p->expiry = atoi(get_header(req, "Expires")); 23666 23667 /* check if the requested expiry-time is within the approved limits from sip.conf */ 23668 if (p->expiry > max_expiry) { 23669 p->expiry = max_expiry; 23670 } else if (p->expiry < min_expiry && p->expiry > 0) { 23671 transmit_response_with_minexpires(p, "423 Interval too small", req); 23672 ast_log(LOG_WARNING, "Received subscription for extension \"%s\" context \"%s\" " 23673 "with Expire header less that 'minexpire' limit. Received \"Expire: %d\" min is %d\n", 23674 p->exten, p->context, p->expiry, min_expiry); 23675 p->expiry = min_expiry; 23676 pvt_set_needdestroy(p, "Expires is less that the min expires allowed. "); 23677 return 0; 23678 } 23679 23680 if (sipdebug) { 23681 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) { 23682 ast_debug(2, "Adding subscription for mailbox notification - peer %s\n", p->relatedpeer->name); 23683 } else if (p->subscribed == CALL_COMPLETION) { 23684 ast_debug(2, "Adding CC subscription for peer %s\n", p->username); 23685 } else { 23686 ast_debug(2, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username); 23687 } 23688 } 23689 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 23690 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 23691 if (p->expiry > 0) 23692 sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */ 23693 23694 if (p->subscribed == MWI_NOTIFICATION) { 23695 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 23696 transmit_response(p, "200 OK", req); 23697 if (p->relatedpeer) { /* Send first notification */ 23698 ao2_lock(p->relatedpeer); /* was WRLOCK */ 23699 sip_send_mwi_to_peer(p->relatedpeer, NULL, 0); 23700 ao2_unlock(p->relatedpeer); 23701 } 23702 } else if (p->subscribed != CALL_COMPLETION) { 23703 if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) { 23704 23705 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)); 23706 transmit_response(p, "404 Not found", req); 23707 pvt_set_needdestroy(p, "no extension for SUBSCRIBE"); 23708 return 0; 23709 } 23710 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 23711 transmit_response(p, "200 OK", req); 23712 transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */ 23713 append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate)); 23714 /* hide the 'complete' exten/context in the refer_to field for later display */ 23715 ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context); 23716 /* Deleted the slow iteration of all sip dialogs to find old subscribes from this peer for exten@context */ 23717 23718 } 23719 if (!p->expiry) { 23720 pvt_set_needdestroy(p, "forcing expiration"); 23721 } 23722 } 23723 return 1; 23724 }
| 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 21092 of file chan_sip.c.
References ast_channel_queue_connected_line_update(), AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, ast_party_connected_line_init(), ast_strlen_zero(), connected, get_header(), get_rpid(), and transmit_response().
Referenced by handle_incoming().
21093 { 21094 if (ast_strlen_zero(get_header(req, "X-Asterisk-rpid-update"))) { 21095 transmit_response(p, "501 Method Not Implemented", req); 21096 return 0; 21097 } 21098 if (get_rpid(p, req)) { 21099 struct ast_party_connected_line connected; 21100 struct ast_set_party_connected_line update_connected; 21101 ast_party_connected_line_init(&connected); 21102 memset(&update_connected, 0, sizeof(update_connected)); 21103 if (p->cid_num) { 21104 update_connected.id.number = 1; 21105 connected.id.number.valid = 1; 21106 connected.id.number.str = (char *) p->cid_num; 21107 connected.id.number.presentation = p->callingpres; 21108 } 21109 if (p->cid_name) { 21110 update_connected.id.name = 1; 21111 connected.id.name.valid = 1; 21112 connected.id.name.str = (char *) p->cid_name; 21113 connected.id.name.presentation = p->callingpres; 21114 } 21115 connected.id.tag = (char *) p->cid_tag; 21116 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER; 21117 ast_channel_queue_connected_line_update(p->owner, &connected, &update_connected); 21118 } 21119 transmit_response(p, "200 OK", req); 21120 return 0; 21121 }
| static void handle_response | ( | struct sip_pvt * | p, | |
| int | resp, | |||
| const char * | rest, | |||
| struct sip_request * | req, | |||
| int | seqno | |||
| ) | [static] |
Handle SIP response in dialogue.
Definition at line 19882 of file chan_sip.c.
References __sip_ack(), __sip_semi_ack(), ao2_callback, append_history, AST_CAUSE_PROTOCOL_ERROR, AST_CC_CCBS, ast_cc_monitor_failed(), ast_channel_set_redirecting(), ast_clear_flag, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, ast_debug, ast_log(), ast_party_redirecting_free(), ast_party_redirecting_init(), ast_queue_control(), ast_queue_hangup_with_cause(), ast_set_flag, ast_skip_blanks(), ast_skip_nonblanks(), ast_sockaddr_stringify(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verb, ast_verbose, cb_extensionstate(), change_redirecting_information(), do_proxy_auth(), FALSE, find_sdp(), find_sip_method(), find_sip_monitor_instance_by_subscription_pvt(), get_header(), gettag(), handle_response_invite(), handle_response_notify(), handle_response_peerpoke(), handle_response_publish(), handle_response_refer(), handle_response_register(), handle_response_subscribe(), handle_response_update(), hangup_sip2cause(), ast_channel::hangupcause, LOG_NOTICE, LOG_WARNING, mark_method_allowed(), mark_method_unallowed(), process_sdp(), pvt_set_needdestroy(), rh, sip_alreadygone(), sip_cancel_destroy(), sip_handle_cc(), sip_methods, sip_monitor_instances, stop_media_flows(), transmit_request(), TRUE, and update_redirecting().
19883 { 19884 struct ast_channel *owner; 19885 int sipmethod; 19886 int res = 1; 19887 const char *c = get_header(req, "Cseq"); 19888 /* 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 */ 19889 char *c_copy = ast_strdupa(c); 19890 /* Skip the Cseq and its subsequent spaces */ 19891 const char *msg = ast_skip_blanks(ast_skip_nonblanks(c_copy)); 19892 19893 if (!msg) 19894 msg = ""; 19895 19896 sipmethod = find_sip_method(msg); 19897 19898 owner = p->owner; 19899 if (owner) { 19900 const char *rp = NULL, *rh = NULL; 19901 19902 owner->hangupcause = 0; 19903 if (ast_test_flag(&p->flags[1], SIP_PAGE2_Q850_REASON) && (rh = get_header(req, "Reason"))) { 19904 rh = ast_skip_blanks(rh); 19905 if (!strncasecmp(rh, "Q.850", 5)) { 19906 rp = strstr(rh, "cause="); 19907 if (rp && sscanf(rp + 6, "%30d", &owner->hangupcause) == 1) { 19908 owner->hangupcause &= 0x7f; 19909 if (req->debug) 19910 ast_verbose("Using Reason header for cause code: %d\n", owner->hangupcause); 19911 } 19912 } 19913 } 19914 19915 if (!owner->hangupcause) 19916 owner->hangupcause = hangup_sip2cause(resp); 19917 } 19918 19919 if (p->socket.type == SIP_TRANSPORT_UDP) { 19920 int ack_res = FALSE; 19921 19922 /* Acknowledge whatever it is destined for */ 19923 if ((resp >= 100) && (resp <= 199)) { 19924 /* NON-INVITE messages do not ack a 1XX response. RFC 3261 section 17.1.2.2 */ 19925 if (sipmethod == SIP_INVITE) { 19926 ack_res = __sip_semi_ack(p, seqno, 0, sipmethod); 19927 } 19928 } else { 19929 ack_res = __sip_ack(p, seqno, 0, sipmethod); 19930 } 19931 19932 if (ack_res == FALSE) { 19933 /* RFC 3261 13.2.2.4 and 17.1.1.2 - We must re-send ACKs to re-transmitted final responses */ 19934 if (sipmethod == SIP_INVITE && resp >= 200) { 19935 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, resp < 300 ? TRUE: FALSE); 19936 } 19937 19938 append_history(p, "Ignore", "Ignoring this retransmit\n"); 19939 return; 19940 } 19941 } 19942 19943 /* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */ 19944 if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite) 19945 p->pendinginvite = 0; 19946 19947 /* Get their tag if we haven't already */ 19948 if (ast_strlen_zero(p->theirtag) || (resp >= 200)) { 19949 char tag[128]; 19950 19951 gettag(req, "To", tag, sizeof(tag)); 19952 ast_string_field_set(p, theirtag, tag); 19953 } 19954 /* This needs to be configurable on a channel/peer level, 19955 not mandatory for all communication. Sadly enough, NAT implementations 19956 are not so stable so we can always rely on these headers. 19957 Temporarily disabled, while waiting for fix. 19958 Fix assigned to Rizzo :-) 19959 */ 19960 /* check_via_response(p, req); */ 19961 19962 /* RFC 3261 Section 15 specifies that if we receive a 408 or 481 19963 * in response to a BYE, then we should end the current dialog 19964 * and session. It is known that at least one phone manufacturer 19965 * potentially will send a 404 in response to a BYE, so we'll be 19966 * liberal in what we accept and end the dialog and session if we 19967 * receive any of those responses to a BYE. 19968 */ 19969 if ((resp == 404 || resp == 408 || resp == 481) && sipmethod == SIP_BYE) { 19970 pvt_set_needdestroy(p, "received 4XX response to a BYE"); 19971 return; 19972 } 19973 19974 if (p->relatedpeer && p->method == SIP_OPTIONS) { 19975 /* We don't really care what the response is, just that it replied back. 19976 Well, as long as it's not a 100 response... since we might 19977 need to hang around for something more "definitive" */ 19978 if (resp != 100) 19979 handle_response_peerpoke(p, resp, req); 19980 } else if (sipmethod == SIP_REFER && resp >= 200) { 19981 handle_response_refer(p, resp, rest, req, seqno); 19982 } else if (sipmethod == SIP_PUBLISH) { 19983 /* SIP PUBLISH transcends this morass of doodoo and instead 19984 * we just always call the response handler. Good gravy! 19985 */ 19986 handle_response_publish(p, resp, rest, req, seqno); 19987 } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 19988 switch(resp) { 19989 case 100: /* 100 Trying */ 19990 case 101: /* 101 Dialog establishment */ 19991 case 183: /* 183 Session Progress */ 19992 case 180: /* 180 Ringing */ 19993 case 182: /* 182 Queued */ 19994 case 181: /* 181 Call Is Being Forwarded */ 19995 if (sipmethod == SIP_INVITE) 19996 handle_response_invite(p, resp, rest, req, seqno); 19997 break; 19998 case 200: /* 200 OK */ 19999 p->authtries = 0; /* Reset authentication counter */ 20000 if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) { 20001 /* We successfully transmitted a message 20002 or a video update request in INFO */ 20003 /* Nothing happens here - the message is inside a dialog */ 20004 } else if (sipmethod == SIP_INVITE) { 20005 handle_response_invite(p, resp, rest, req, seqno); 20006 } else if (sipmethod == SIP_NOTIFY) { 20007 handle_response_notify(p, resp, rest, req, seqno); 20008 } else if (sipmethod == SIP_REGISTER) { 20009 res = handle_response_register(p, resp, rest, req, seqno); 20010 } else if (sipmethod == SIP_SUBSCRIBE) { 20011 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 20012 handle_response_subscribe(p, resp, rest, req, seqno); 20013 } else if (sipmethod == SIP_BYE) { /* Ok, we're ready to go */ 20014 pvt_set_needdestroy(p, "received 200 response"); 20015 ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 20016 } 20017 break; 20018 case 401: /* Not www-authorized on SIP method */ 20019 case 407: /* Proxy auth required */ 20020 if (sipmethod == SIP_INVITE) 20021 handle_response_invite(p, resp, rest, req, seqno); 20022 else if (sipmethod == SIP_NOTIFY) 20023 handle_response_notify(p, resp, rest, req, seqno); 20024 else if (sipmethod == SIP_SUBSCRIBE) 20025 handle_response_subscribe(p, resp, rest, req, seqno); 20026 else if (p->registry && sipmethod == SIP_REGISTER) 20027 res = handle_response_register(p, resp, rest, req, seqno); 20028 else if (sipmethod == SIP_UPDATE) { 20029 handle_response_update(p, resp, rest, req, seqno); 20030 } else if (sipmethod == SIP_BYE) { 20031 if (p->options) 20032 p->options->auth_type = resp; 20033 if (ast_strlen_zero(p->authname)) { 20034 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s but we have no matching peer!\n", 20035 msg, ast_sockaddr_stringify(&p->recv)); 20036 pvt_set_needdestroy(p, "unable to authenticate BYE"); 20037 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, resp, sipmethod, 0)) { 20038 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 20039 pvt_set_needdestroy(p, "failed to authenticate BYE"); 20040 } 20041 } else { 20042 ast_log(LOG_WARNING, "Got authentication request (%d) on %s to '%s'\n", resp, sip_methods[sipmethod].text, get_header(req, "To")); 20043 pvt_set_needdestroy(p, "received 407 response"); 20044 } 20045 break; 20046 case 403: /* Forbidden - we failed authentication */ 20047 if (sipmethod == SIP_INVITE) 20048 handle_response_invite(p, resp, rest, req, seqno); 20049 else if (sipmethod == SIP_SUBSCRIBE) 20050 handle_response_subscribe(p, resp, rest, req, seqno); 20051 else if (p->registry && sipmethod == SIP_REGISTER) 20052 res = handle_response_register(p, resp, rest, req, seqno); 20053 else { 20054 ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg); 20055 pvt_set_needdestroy(p, "received 403 response"); 20056 } 20057 break; 20058 case 404: /* Not found */ 20059 if (p->registry && sipmethod == SIP_REGISTER) 20060 res = handle_response_register(p, resp, rest, req, seqno); 20061 else if (sipmethod == SIP_INVITE) 20062 handle_response_invite(p, resp, rest, req, seqno); 20063 else if (sipmethod == SIP_SUBSCRIBE) 20064 handle_response_subscribe(p, resp, rest, req, seqno); 20065 else if (owner) 20066 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 20067 break; 20068 case 423: /* Interval too brief */ 20069 if (sipmethod == SIP_REGISTER) 20070 res = handle_response_register(p, resp, rest, req, seqno); 20071 break; 20072 case 408: /* Request timeout - terminate dialog */ 20073 if (sipmethod == SIP_INVITE) 20074 handle_response_invite(p, resp, rest, req, seqno); 20075 else if (sipmethod == SIP_REGISTER) 20076 res = handle_response_register(p, resp, rest, req, seqno); 20077 else if (sipmethod == SIP_BYE) { 20078 pvt_set_needdestroy(p, "received 408 response"); 20079 ast_debug(4, "Got timeout on bye. Thanks for the answer. Now, kill this call\n"); 20080 } else { 20081 if (owner) 20082 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 20083 pvt_set_needdestroy(p, "received 408 response"); 20084 } 20085 break; 20086 20087 case 422: /* Session-Timers: Session Interval Too Small */ 20088 if (sipmethod == SIP_INVITE) { 20089 handle_response_invite(p, resp, rest, req, seqno); 20090 } 20091 break; 20092 20093 case 481: /* Call leg does not exist */ 20094 if (sipmethod == SIP_INVITE) { 20095 handle_response_invite(p, resp, rest, req, seqno); 20096 } else if (sipmethod == SIP_SUBSCRIBE) { 20097 handle_response_subscribe(p, resp, rest, req, seqno); 20098 } else if (sipmethod == SIP_NOTIFY) { 20099 pvt_set_needdestroy(p, "received 481 response"); 20100 } else if (sipmethod == SIP_BYE) { 20101 /* The other side has no transaction to bye, 20102 just assume it's all right then */ 20103 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 20104 } else if (sipmethod == SIP_CANCEL) { 20105 /* The other side has no transaction to cancel, 20106 just assume it's all right then */ 20107 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 20108 } else { 20109 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 20110 /* Guessing that this is not an important request */ 20111 } 20112 break; 20113 case 487: 20114 if (sipmethod == SIP_INVITE) 20115 handle_response_invite(p, resp, rest, req, seqno); 20116 break; 20117 case 415: /* Unsupported media type */ 20118 case 488: /* Not acceptable here - codec error */ 20119 case 606: /* Not Acceptable */ 20120 if (sipmethod == SIP_INVITE) 20121 handle_response_invite(p, resp, rest, req, seqno); 20122 break; 20123 case 491: /* Pending */ 20124 if (sipmethod == SIP_INVITE) 20125 handle_response_invite(p, resp, rest, req, seqno); 20126 else { 20127 ast_debug(1, "Got 491 on %s, unsupported. Call ID %s\n", sip_methods[sipmethod].text, p->callid); 20128 pvt_set_needdestroy(p, "received 491 response"); 20129 } 20130 break; 20131 case 405: 20132 case 501: /* Not Implemented */ 20133 mark_method_unallowed(&p->allowed_methods, sipmethod); 20134 if (p->relatedpeer) { 20135 mark_method_allowed(&p->relatedpeer->disallowed_methods, sipmethod); 20136 } 20137 if (sipmethod == SIP_INVITE) 20138 handle_response_invite(p, resp, rest, req, seqno); 20139 else 20140 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_sockaddr_stringify(&p->sa), msg); 20141 break; 20142 /* Fallthrough */ 20143 default: 20144 if ((resp >= 300) && (resp < 700)) { 20145 /* Fatal response */ 20146 if ((resp != 487)) 20147 ast_verb(3, "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_sockaddr_stringify(&p->sa)); 20148 20149 if (sipmethod == SIP_INVITE) 20150 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 20151 20152 /* XXX Locking issues?? XXX */ 20153 switch(resp) { 20154 case 300: /* Multiple Choices */ 20155 case 301: /* Moved permanently */ 20156 case 302: /* Moved temporarily */ 20157 case 305: /* Use Proxy */ 20158 if (p->owner) { 20159 struct ast_party_redirecting redirecting; 20160 struct ast_set_party_redirecting update_redirecting; 20161 20162 ast_party_redirecting_init(&redirecting); 20163 change_redirecting_information(p, req, &redirecting, 20164 &update_redirecting, TRUE); 20165 ast_channel_set_redirecting(p->owner, &redirecting, 20166 &update_redirecting); 20167 ast_party_redirecting_free(&redirecting); 20168 } 20169 /* Fall through */ 20170 case 486: /* Busy here */ 20171 case 600: /* Busy everywhere */ 20172 case 603: /* Decline */ 20173 if (p->owner) { 20174 sip_handle_cc(p, req, AST_CC_CCBS); 20175 ast_queue_control(p->owner, AST_CONTROL_BUSY); 20176 } 20177 break; 20178 case 482: /* Loop Detected */ 20179 case 480: /* Temporarily Unavailable */ 20180 case 404: /* Not Found */ 20181 case 410: /* Gone */ 20182 case 400: /* Bad Request */ 20183 case 500: /* Server error */ 20184 if (sipmethod == SIP_SUBSCRIBE) { 20185 handle_response_subscribe(p, resp, rest, req, seqno); 20186 break; 20187 } 20188 /* Fall through */ 20189 case 502: /* Bad gateway */ 20190 case 503: /* Service Unavailable */ 20191 case 504: /* Server Timeout */ 20192 if (owner) 20193 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 20194 break; 20195 default: 20196 /* Send hangup */ 20197 if (owner && sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO && sipmethod != SIP_BYE) 20198 ast_queue_hangup_with_cause(p->owner, AST_CAUSE_PROTOCOL_ERROR); 20199 break; 20200 } 20201 /* ACK on invite */ 20202 if (sipmethod == SIP_INVITE) 20203 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 20204 if (sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO) 20205 sip_alreadygone(p); 20206 if (!p->owner) { 20207 pvt_set_needdestroy(p, "transaction completed"); 20208 } 20209 } else if ((resp >= 100) && (resp < 200)) { 20210 if (sipmethod == SIP_INVITE) { 20211 if (!req->ignore && sip_cancel_destroy(p)) 20212 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 20213 if (find_sdp(req)) 20214 process_sdp(p, req, SDP_T38_NONE); 20215 if (p->owner) { 20216 /* Queue a progress frame */ 20217 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 20218 } 20219 } 20220 } else 20221 ast_log(LOG_NOTICE, "Don't know how to handle a %d %s response from %s\n", resp, rest, p->owner ? p->owner->name : ast_sockaddr_stringify(&p->sa)); 20222 } 20223 } else { 20224 /* Responses to OUTGOING SIP requests on INCOMING calls 20225 get handled here. As well as out-of-call message responses */ 20226 if (req->debug) 20227 ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg); 20228 20229 if (sipmethod == SIP_INVITE && resp == 200) { 20230 /* Tags in early session is replaced by the tag in 200 OK, which is 20231 the final reply to our INVITE */ 20232 char tag[128]; 20233 20234 gettag(req, "To", tag, sizeof(tag)); 20235 ast_string_field_set(p, theirtag, tag); 20236 } 20237 20238 if (sipmethod == SIP_SUBSCRIBE && resp >= 400) { 20239 struct sip_monitor_instance *monitor_instance = ao2_callback(sip_monitor_instances, 20240 0, find_sip_monitor_instance_by_subscription_pvt, p); 20241 if (monitor_instance) { 20242 ast_cc_monitor_failed(monitor_instance->core_id, monitor_instance->device_name, 20243 "Received error response to our SUBSCRIBE"); 20244 return; 20245 } 20246 } 20247 20248 switch(resp) { 20249 case 200: 20250 if (sipmethod == SIP_INVITE) { 20251 handle_response_invite(p, resp, rest, req, seqno); 20252 } else if (sipmethod == SIP_CANCEL) { 20253 ast_debug(1, "Got 200 OK on CANCEL\n"); 20254 20255 /* Wait for 487, then destroy */ 20256 } else if (sipmethod == SIP_NOTIFY) { 20257 /* They got the notify, this is the end */ 20258 if (p->owner) { 20259 if (p->refer) { 20260 ast_debug(1, "Got 200 OK on NOTIFY for transfer\n"); 20261 } else 20262 ast_log(LOG_WARNING, "Notify answer on an owned channel?\n"); 20263 /* ast_queue_hangup(p->owner); Disabled */ 20264 } else { 20265 if (!p->subscribed && !p->refer) { 20266 pvt_set_needdestroy(p, "transaction completed"); 20267 } 20268 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 20269 /* Ready to send the next state we have on queue */ 20270 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 20271 cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p); 20272 } 20273 } 20274 } else if (sipmethod == SIP_BYE) { 20275 pvt_set_needdestroy(p, "transaction completed"); 20276 } else if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) { 20277 /* We successfully transmitted a message or 20278 a video update request in INFO */ 20279 ; 20280 } 20281 break; 20282 case 401: /* www-auth */ 20283 case 407: 20284 if (sipmethod == SIP_INVITE) 20285 handle_response_invite(p, resp, rest, req, seqno); 20286 else if (sipmethod == SIP_BYE) { 20287 if (p->authtries == MAX_AUTHTRIES || do_proxy_auth(p, req, resp, sipmethod, 0)) { 20288 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 20289 pvt_set_needdestroy(p, "failed to authenticate BYE"); 20290 } 20291 } 20292 break; 20293 case 481: /* Call leg does not exist */ 20294 if (sipmethod == SIP_INVITE) { 20295 /* Re-invite failed */ 20296 handle_response_invite(p, resp, rest, req, seqno); 20297 } else if (sipmethod == SIP_BYE) { 20298 pvt_set_needdestroy(p, "received 481 response"); 20299 } else if (sipmethod == SIP_NOTIFY) { 20300 pvt_set_needdestroy(p, "received 481 response"); 20301 } else if (sipdebug) { 20302 ast_debug(1, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid); 20303 } 20304 break; 20305 case 501: /* Not Implemented */ 20306 if (sipmethod == SIP_INVITE) 20307 handle_response_invite(p, resp, rest, req, seqno); 20308 break; 20309 default: /* Errors without handlers */ 20310 if ((resp >= 100) && (resp < 200)) { 20311 if (sipmethod == SIP_INVITE) { /* re-invite */ 20312 if (!req->ignore && sip_cancel_destroy(p)) 20313 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 20314 } 20315 } 20316 if ((resp >= 300) && (resp < 700)) { 20317 if ((resp != 487)) 20318 ast_verb(3, "Incoming call: Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_sockaddr_stringify(&p->sa)); 20319 switch(resp) { 20320 case 415: /* Unsupported media type */ 20321 case 488: /* Not acceptable here - codec error */ 20322 case 603: /* Decline */ 20323 case 500: /* Server error */ 20324 case 502: /* Bad gateway */ 20325 case 503: /* Service Unavailable */ 20326 case 504: /* Server timeout */ 20327 20328 /* re-invite failed */ 20329 if (sipmethod == SIP_INVITE && sip_cancel_destroy(p)) 20330 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 20331 break; 20332 } 20333 } 20334 break; 20335 } 20336 } 20337 }
| static void handle_response_invite | ( | struct sip_pvt * | p, | |
| int | resp, | |||
| const char * | rest, | |||
| struct sip_request * | req, | |||
| int | seqno | |||
| ) | [static] |
Handle SIP response to INVITE dialogue.
Definition at line 19039 of file chan_sip.c.
References append_history, AST_CAUSE_NORMAL_CLEARING, AST_CC_CCNR, ast_channel_queue_connected_line_update(), ast_channel_queue_redirecting_update(), AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER, AST_CONTROL_ANSWER, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, ast_debug, ast_log(), ast_null_frame, ast_party_connected_line_init(), ast_party_redirecting_free(), ast_party_redirecting_init(), ast_queue_control(), ast_queue_frame(), ast_queue_hangup_with_cause(), ast_random(), ast_rtp_instance_activate(), ast_sched_add(), AST_SCHED_DEL_UNREF, ast_set_flag, ast_set_hangupsource(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_string_field_set, ast_strlen_zero(), ast_test_flag, build_route(), change_redirecting_information(), change_t38_state(), check_pendings(), connected, do_proxy_auth(), EVENT_FLAG_SYSTEM, FALSE, find_sdp(), get_header(), get_rpid(), LOG_NOTICE, LOG_WARNING, manager_event, parse_ok_contact(), parse_session_expires(), proc_422_rsp(), process_sdp(), pvt_set_needdestroy(), set_address_from_contact(), set_pvt_allowed_methods(), sip_alreadygone(), sip_cancel_destroy(), sip_cfg, sip_handle_cc(), sip_reinvite_retry(), sip_scheddestroy(), st_get_mode(), start_session_timer(), transmit_reinvite_with_sdp(), transmit_request(), TRUE, update_call_counter(), and update_redirecting().
Referenced by handle_response().
19040 { 19041 int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING); 19042 int res = 0; 19043 int xmitres = 0; 19044 int reinvite = (p->owner && p->owner->_state == AST_STATE_UP); 19045 char *p_hdrval; 19046 int rtn; 19047 struct ast_party_connected_line connected; 19048 struct ast_set_party_connected_line update_connected; 19049 19050 if (reinvite) 19051 ast_debug(4, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid); 19052 else 19053 ast_debug(4, "SIP response %d to standard invite\n", resp); 19054 19055 if (p->alreadygone) { /* This call is already gone */ 19056 ast_debug(1, "Got response on call that is already terminated: %s (ignoring)\n", p->callid); 19057 return; 19058 } 19059 19060 /* Acknowledge sequence number - This only happens on INVITE from SIP-call */ 19061 /* Don't auto congest anymore since we've gotten something useful back */ 19062 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")); 19063 19064 /* RFC3261 says we must treat every 1xx response (but not 100) 19065 that we don't recognize as if it was 183. 19066 */ 19067 if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 181 && resp != 182 && resp != 183) 19068 resp = 183; 19069 19070 /* Any response between 100 and 199 is PROCEEDING */ 19071 if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING) 19072 p->invitestate = INV_PROCEEDING; 19073 19074 /* Final response, not 200 ? */ 19075 if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA )) 19076 p->invitestate = INV_COMPLETED; 19077 19078 /* Final response, clear out pending invite */ 19079 if ((resp == 200 || resp >= 300) && p->pendinginvite && seqno == p->pendinginvite) 19080 p->pendinginvite = 0; 19081 19082 /* If this is a response to our initial INVITE, we need to set what we can use 19083 * for this peer. 19084 */ 19085 if (!reinvite) { 19086 set_pvt_allowed_methods(p, req); 19087 } 19088 19089 switch (resp) { 19090 case 100: /* Trying */ 19091 case 101: /* Dialog establishment */ 19092 if (!req->ignore && p->invitestate != INV_CANCELLED && sip_cancel_destroy(p)) 19093 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 19094 check_pendings(p); 19095 break; 19096 19097 case 180: /* 180 Ringing */ 19098 case 182: /* 182 Queued */ 19099 if (!req->ignore && p->invitestate != INV_CANCELLED && sip_cancel_destroy(p)) 19100 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 19101 if (!req->ignore && p->owner) { 19102 if (get_rpid(p, req)) { 19103 ast_party_connected_line_init(&connected); 19104 memset(&update_connected, 0, sizeof(update_connected)); 19105 if (p->cid_num) { 19106 update_connected.id.number = 1; 19107 connected.id.number.valid = 1; 19108 connected.id.number.str = (char *) p->cid_num; 19109 connected.id.number.presentation = p->callingpres; 19110 } 19111 if (p->cid_name) { 19112 update_connected.id.name = 1; 19113 connected.id.name.valid = 1; 19114 connected.id.name.str = (char *) p->cid_name; 19115 connected.id.name.presentation = p->callingpres; 19116 } 19117 connected.id.tag = (char *) p->cid_tag; 19118 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; 19119 ast_channel_queue_connected_line_update(p->owner, &connected, 19120 &update_connected); 19121 } 19122 sip_handle_cc(p, req, AST_CC_CCNR); 19123 ast_queue_control(p->owner, AST_CONTROL_RINGING); 19124 if (p->owner->_state != AST_STATE_UP) { 19125 ast_setstate(p->owner, AST_STATE_RINGING); 19126 } 19127 } 19128 if (find_sdp(req)) { 19129 if (p->invitestate != INV_CANCELLED) 19130 p->invitestate = INV_EARLY_MEDIA; 19131 res = process_sdp(p, req, SDP_T38_NONE); 19132 if (!req->ignore && p->owner) { 19133 /* Queue a progress frame only if we have SDP in 180 or 182 */ 19134 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 19135 } 19136 ast_rtp_instance_activate(p->rtp); 19137 } 19138 check_pendings(p); 19139 break; 19140 19141 case 181: /* Call Is Being Forwarded */ 19142 if (!req->ignore && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 19143 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 19144 if (!req->ignore && p->owner) { 19145 struct ast_party_redirecting redirecting; 19146 struct ast_set_party_redirecting update_redirecting; 19147 19148 ast_party_redirecting_init(&redirecting); 19149 memset(&update_redirecting, 0, sizeof(update_redirecting)); 19150 change_redirecting_information(p, req, &redirecting, &update_redirecting, 19151 FALSE); 19152 ast_channel_queue_redirecting_update(p->owner, &redirecting, 19153 &update_redirecting); 19154 ast_party_redirecting_free(&redirecting); 19155 sip_handle_cc(p, req, AST_CC_CCNR); 19156 } 19157 check_pendings(p); 19158 break; 19159 19160 case 183: /* Session progress */ 19161 if (!req->ignore && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 19162 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 19163 if (!req->ignore && p->owner) { 19164 if (get_rpid(p, req)) { 19165 /* Queue a connected line update */ 19166 ast_party_connected_line_init(&connected); 19167 memset(&update_connected, 0, sizeof(update_connected)); 19168 if (p->cid_num) { 19169 update_connected.id.number = 1; 19170 connected.id.number.valid = 1; 19171 connected.id.number.str = (char *) p->cid_num; 19172 connected.id.number.presentation = p->callingpres; 19173 } 19174 if (p->cid_name) { 19175 update_connected.id.name = 1; 19176 connected.id.name.valid = 1; 19177 connected.id.name.str = (char *) p->cid_name; 19178 connected.id.name.presentation = p->callingpres; 19179 } 19180 connected.id.tag = (char *) p->cid_tag; 19181 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; 19182 ast_channel_queue_connected_line_update(p->owner, &connected, 19183 &update_connected); 19184 } 19185 sip_handle_cc(p, req, AST_CC_CCNR); 19186 } 19187 if (find_sdp(req)) { 19188 if (p->invitestate != INV_CANCELLED) 19189 p->invitestate = INV_EARLY_MEDIA; 19190 res = process_sdp(p, req, SDP_T38_NONE); 19191 if (!req->ignore && p->owner) { 19192 /* Queue a progress frame */ 19193 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 19194 } 19195 ast_rtp_instance_activate(p->rtp); 19196 } else { 19197 /* Alcatel PBXs are known to send 183s with no SDP after sending 19198 * a 100 Trying response. We're just going to treat this sort of thing 19199 * the same as we would treat a 180 Ringing 19200 */ 19201 if (!req->ignore && p->owner) { 19202 ast_queue_control(p->owner, AST_CONTROL_RINGING); 19203 } 19204 } 19205 check_pendings(p); 19206 break; 19207 19208 case 200: /* 200 OK on invite - someone's answering our call */ 19209 if (!req->ignore && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 19210 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 19211 p->authtries = 0; 19212 if (find_sdp(req)) { 19213 if ((res = process_sdp(p, req, SDP_T38_ACCEPT)) && !req->ignore) 19214 if (!reinvite) 19215 /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */ 19216 /* For re-invites, we try to recover */ 19217 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 19218 ast_rtp_instance_activate(p->rtp); 19219 } 19220 19221 if (!req->ignore && p->owner && (get_rpid(p, req) || !reinvite)) { 19222 /* Queue a connected line update */ 19223 ast_party_connected_line_init(&connected); 19224 memset(&update_connected, 0, sizeof(update_connected)); 19225 if (p->cid_num) { 19226 update_connected.id.number = 1; 19227 connected.id.number.valid = 1; 19228 connected.id.number.str = (char *) p->cid_num; 19229 connected.id.number.presentation = p->callingpres; 19230 } 19231 if (p->cid_name) { 19232 update_connected.id.name = 1; 19233 connected.id.name.valid = 1; 19234 connected.id.name.str = (char *) p->cid_name; 19235 connected.id.name.presentation = p->callingpres; 19236 } 19237 connected.id.tag = (char *) p->cid_tag; 19238 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; 19239 ast_channel_queue_connected_line_update(p->owner, &connected, 19240 &update_connected); 19241 } 19242 19243 /* Parse contact header for continued conversation */ 19244 /* When we get 200 OK, we know which device (and IP) to contact for this call */ 19245 /* This is important when we have a SIP proxy between us and the phone */ 19246 if (outgoing) { 19247 update_call_counter(p, DEC_CALL_RINGING); 19248 parse_ok_contact(p, req); 19249 /* Save Record-Route for any later requests we make on this dialogue */ 19250 if (!reinvite) 19251 build_route(p, req, 1); 19252 19253 if(set_address_from_contact(p)) { 19254 /* Bad contact - we don't know how to reach this device */ 19255 /* We need to ACK, but then send a bye */ 19256 if (!p->route && !req->ignore) 19257 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 19258 } 19259 19260 } 19261 19262 if (!req->ignore && p->owner) { 19263 if (!reinvite) { 19264 ast_queue_control(p->owner, AST_CONTROL_ANSWER); 19265 if (sip_cfg.callevents) 19266 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", 19267 "Channel: %s\r\nChanneltype: %s\r\nUniqueid: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\nPeername: %s\r\n", 19268 p->owner->name, "SIP", p->owner->uniqueid, p->callid, p->fullcontact, p->peername); 19269 } else { /* RE-invite */ 19270 ast_queue_frame(p->owner, &ast_null_frame); 19271 } 19272 } else { 19273 /* It's possible we're getting an 200 OK after we've tried to disconnect 19274 by sending CANCEL */ 19275 /* First send ACK, then send bye */ 19276 if (!req->ignore) 19277 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 19278 } 19279 19280 /* Check for Session-Timers related headers */ 19281 if (st_get_mode(p) != SESSION_TIMER_MODE_REFUSE && p->outgoing_call == TRUE && !reinvite) { 19282 p_hdrval = (char*)get_header(req, "Session-Expires"); 19283 if (!ast_strlen_zero(p_hdrval)) { 19284 /* UAS supports Session-Timers */ 19285 enum st_refresher tmp_st_ref = SESSION_TIMER_REFRESHER_AUTO; 19286 int tmp_st_interval = 0; 19287 rtn = parse_session_expires(p_hdrval, &tmp_st_interval, &tmp_st_ref); 19288 if (rtn != 0) { 19289 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 19290 } 19291 if (tmp_st_ref == SESSION_TIMER_REFRESHER_UAC || 19292 tmp_st_ref == SESSION_TIMER_REFRESHER_UAS) { 19293 p->stimer->st_ref = tmp_st_ref; 19294 } 19295 if (tmp_st_interval) { 19296 p->stimer->st_interval = tmp_st_interval; 19297 } 19298 p->stimer->st_active = TRUE; 19299 p->stimer->st_active_peer_ua = TRUE; 19300 start_session_timer(p); 19301 } else { 19302 /* UAS doesn't support Session-Timers */ 19303 if (st_get_mode(p) == SESSION_TIMER_MODE_ORIGINATE) { 19304 p->stimer->st_ref = SESSION_TIMER_REFRESHER_UAC; 19305 p->stimer->st_active_peer_ua = FALSE; 19306 start_session_timer(p); 19307 } 19308 } 19309 } 19310 19311 19312 /* If I understand this right, the branch is different for a non-200 ACK only */ 19313 p->invitestate = INV_TERMINATED; 19314 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 19315 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE); 19316 check_pendings(p); 19317 break; 19318 19319 case 407: /* Proxy authentication */ 19320 case 401: /* Www auth */ 19321 /* First we ACK */ 19322 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 19323 if (p->options) 19324 p->options->auth_type = resp; 19325 19326 /* Then we AUTH */ 19327 ast_string_field_set(p, theirtag, NULL); /* forget their old tag, so we don't match tags when getting response */ 19328 if (!req->ignore) { 19329 if (p->authtries < MAX_AUTHTRIES) 19330 p->invitestate = INV_CALLING; 19331 if (p->authtries == MAX_AUTHTRIES || do_proxy_auth(p, req, resp, SIP_INVITE, 1)) { 19332 ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); 19333 pvt_set_needdestroy(p, "failed to authenticate on INVITE"); 19334 sip_alreadygone(p); 19335 if (p->owner) 19336 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 19337 } 19338 } 19339 break; 19340 19341 case 403: /* Forbidden */ 19342 /* First we ACK */ 19343 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 19344 ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From")); 19345 if (!req->ignore && p->owner) { 19346 ast_set_hangupsource(p->owner, p->owner->name, 0); 19347 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 19348 } 19349 pvt_set_needdestroy(p, "received 403 response"); 19350 sip_alreadygone(p); 19351 break; 19352 19353 case 404: /* Not found */ 19354 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 19355 if (p->owner && !req->ignore) { 19356 ast_set_hangupsource(p->owner, p->owner->name, 0); 19357 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 19358 } 19359 sip_alreadygone(p); 19360 break; 19361 19362 case 408: /* Request timeout */ 19363 case 481: /* Call leg does not exist */ 19364 /* Could be REFER caused INVITE with replaces */ 19365 ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid); 19366 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 19367 if (p->owner) 19368 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 19369 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 19370 break; 19371 19372 case 422: /* Session-Timers: Session interval too small */ 19373 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 19374 ast_string_field_set(p, theirtag, NULL); 19375 proc_422_rsp(p, req); 19376 break; 19377 19378 case 428: /* Use identity header - rfc 4474 - not supported by Asterisk yet */ 19379 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 19380 append_history(p, "Identity", "SIP identity is required. Not supported by Asterisk."); 19381 ast_log(LOG_WARNING, "SIP identity required by proxy. SIP dialog '%s'. Giving up.\n", p->callid); 19382 if (p->owner) 19383 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 19384 break; 19385 19386 19387 19388 case 487: /* Cancelled transaction */ 19389 /* We have sent CANCEL on an outbound INVITE 19390 This transaction is already scheduled to be killed by sip_hangup(). 19391 */ 19392 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 19393 if (p->owner && !req->ignore) { 19394 ast_queue_hangup_with_cause(p->owner, AST_CAUSE_NORMAL_CLEARING); 19395 append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request"); 19396 } else if (!req->ignore) { 19397 update_call_counter(p, DEC_CALL_LIMIT); 19398 append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog."); 19399 pvt_set_needdestroy(p, "received 487 response"); 19400 sip_alreadygone(p); 19401 } 19402 break; 19403 case 415: /* Unsupported media type */ 19404 case 488: /* Not acceptable here */ 19405 case 606: /* Not Acceptable */ 19406 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 19407 if (p->udptl && p->t38.state == T38_LOCAL_REINVITE) { 19408 change_t38_state(p, T38_DISABLED); 19409 /* Try to reset RTP timers */ 19410 //ast_rtp_set_rtptimers_onhold(p->rtp); 19411 19412 /* Trigger a reinvite back to audio */ 19413 transmit_reinvite_with_sdp(p, FALSE, FALSE); 19414 } else { 19415 /* We can't set up this call, so give up */ 19416 if (p->owner && !req->ignore) 19417 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 19418 pvt_set_needdestroy(p, "received 488 response"); 19419 /* If there's no dialog to end, then mark p as already gone */ 19420 if (!reinvite) 19421 sip_alreadygone(p); 19422 } 19423 break; 19424 case 491: /* Pending */ 19425 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 19426 if (p->owner && !req->ignore) { 19427 if (p->owner->_state != AST_STATE_UP) { 19428 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 19429 pvt_set_needdestroy(p, "received 491 response"); 19430 } else { 19431 /* This is a re-invite that failed. */ 19432 /* Reset the flag after a while 19433 */ 19434 int wait; 19435 /* RFC 3261, if owner of call, wait between 2.1 to 4 seconds, 19436 * if not owner of call, wait 0 to 2 seconds */ 19437 if (p->outgoing_call) { 19438 wait = 2100 + ast_random() % 2000; 19439 } else { 19440 wait = ast_random() % 2000; 19441 } 19442 p->waitid = ast_sched_add(sched, wait, sip_reinvite_retry, dialog_ref(p, "passing dialog ptr into sched structure based on waitid for sip_reinvite_retry.")); 19443 ast_log(LOG_WARNING, "just did sched_add waitid(%d) for sip_reinvite_retry for dialog %s in handle_response_invite\n", p->waitid, p->callid); 19444 ast_debug(2, "Reinvite race. Waiting %d secs before retry\n", wait); 19445 } 19446 } 19447 break; 19448 19449 case 405: /* Not allowed */ 19450 case 501: /* Not implemented */ 19451 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 19452 if (p->owner) 19453 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 19454 break; 19455 } 19456 if (xmitres == XMIT_ERROR) 19457 ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid); 19458 }
| static void handle_response_notify | ( | struct sip_pvt * | p, | |
| int | resp, | |||
| const char * | rest, | |||
| struct sip_request * | req, | |||
| int | seqno | |||
| ) | [static] |
Definition at line 19463 of file chan_sip.c.
References AST_CAUSE_NORMAL_UNSPECIFIED, ast_clear_flag, ast_debug, ast_log(), ast_queue_hangup_with_cause(), ast_sockaddr_stringify(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, cb_extensionstate(), do_proxy_auth(), get_header(), LOG_NOTICE, LOG_WARNING, NONE, and pvt_set_needdestroy().
Referenced by handle_response().
19464 { 19465 switch (resp) { 19466 case 200: /* Notify accepted */ 19467 /* They got the notify, this is the end */ 19468 if (p->owner) { 19469 if (!p->refer) { 19470 ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name); 19471 ast_queue_hangup_with_cause(p->owner, AST_CAUSE_NORMAL_UNSPECIFIED); 19472 } else { 19473 ast_debug(4, "Got OK on REFER Notify message\n"); 19474 } 19475 } else { 19476 if (p->subscribed == NONE) { 19477 ast_debug(4, "Got 200 accepted on NOTIFY\n"); 19478 pvt_set_needdestroy(p, "received 200 response"); 19479 } 19480 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 19481 /* Ready to send the next state we have on queue */ 19482 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 19483 cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p); 19484 } 19485 } 19486 break; 19487 case 401: /* Not www-authorized on SIP method */ 19488 case 407: /* Proxy auth */ 19489 if (!p->notify) { 19490 break; /* Only device notify can use NOTIFY auth */ 19491 } 19492 ast_string_field_set(p, theirtag, NULL); 19493 if (ast_strlen_zero(p->authname)) { 19494 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)); 19495 pvt_set_needdestroy(p, "unable to authenticate NOTIFY"); 19496 } 19497 if (p->authtries > 1 || do_proxy_auth(p, req, resp, SIP_NOTIFY, 0)) { 19498 ast_log(LOG_NOTICE, "Failed to authenticate on NOTIFY to '%s'\n", get_header(&p->initreq, "From")); 19499 pvt_set_needdestroy(p, "failed to authenticate NOTIFY"); 19500 } 19501 break; 19502 } 19503 }
| static void handle_response_peerpoke | ( | struct sip_pvt * | p, | |
| int | resp, | |||
| struct sip_request * | req | |||
| ) | [static] |
Handle qualification responses (OPTIONS).
Definition at line 19812 of file chan_sip.c.
References ast_check_realtime(), AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_log(), AST_SCHED_REPLACE_UNREF, ast_tvdiff_ms(), ast_tvnow(), ast_update_realtime(), DEFAULT_FREQ_NOTOK, EVENT_FLAG_SYSTEM, LOG_NOTICE, manager_event, pvt_set_needdestroy(), ref_peer(), register_peer_exten(), SENTINEL, sip_cfg, sip_poke_peer_s(), TRUE, and unref_peer().
Referenced by handle_response().
19813 { 19814 struct sip_peer *peer = /* ref_peer( */ p->relatedpeer /* , "bump refcount on p, as it is being used in this function(handle_response_peerpoke)")*/ ; /* hope this is already refcounted! */ 19815 int statechanged, is_reachable, was_reachable; 19816 int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps); 19817 19818 /* 19819 * Compute the response time to a ping (goes in peer->lastms.) 19820 * -1 means did not respond, 0 means unknown, 19821 * 1..maxms is a valid response, >maxms means late response. 19822 */ 19823 if (pingtime < 1) /* zero = unknown, so round up to 1 */ 19824 pingtime = 1; 19825 19826 /* Now determine new state and whether it has changed. 19827 * Use some helper variables to simplify the writing 19828 * of the expressions. 19829 */ 19830 was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms; 19831 is_reachable = pingtime <= peer->maxms; 19832 statechanged = peer->lastms == 0 /* yes, unknown before */ 19833 || was_reachable != is_reachable; 19834 19835 peer->lastms = pingtime; 19836 peer->call = dialog_unref(peer->call, "unref dialog peer->call"); 19837 if (statechanged) { 19838 const char *s = is_reachable ? "Reachable" : "Lagged"; 19839 char str_lastms[20]; 19840 snprintf(str_lastms, sizeof(str_lastms), "%d", pingtime); 19841 19842 ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n", 19843 peer->name, s, pingtime, peer->maxms); 19844 ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name); 19845 if (sip_cfg.peer_rtupdate) { 19846 ast_update_realtime(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", "name", peer->name, "lastms", str_lastms, SENTINEL); 19847 } 19848 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 19849 "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n", 19850 peer->name, s, pingtime); 19851 if (is_reachable && sip_cfg.regextenonqualify) 19852 register_peer_exten(peer, TRUE); 19853 } 19854 19855 pvt_set_needdestroy(p, "got OPTIONS response"); 19856 19857 /* Try again eventually */ 19858 AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, 19859 is_reachable ? peer->qualifyfreq : DEFAULT_FREQ_NOTOK, 19860 sip_poke_peer_s, peer, 19861 unref_peer(_data, "removing poke peer ref"), 19862 unref_peer(peer, "removing poke peer ref"), 19863 ref_peer(peer, "adding poke peer ref")); 19864 }
| static void handle_response_publish | ( | struct sip_pvt * | p, | |
| int | resp, | |||
| const char * | rest, | |||
| struct sip_request * | req, | |||
| int | seqno | |||
| ) | [static] |
Definition at line 18988 of file chan_sip.c.
References ast_assert, ast_copy_string(), ast_log(), ast_string_field_set, ast_strlen_zero(), do_proxy_auth(), get_header(), LOG_NOTICE, mark_method_unallowed(), pvt_set_needdestroy(), and sip_alreadygone().
Referenced by handle_response().
18989 { 18990 struct sip_epa_entry *epa_entry = p->epa_entry; 18991 const char *etag = get_header(req, "Sip-ETag"); 18992 18993 ast_assert(epa_entry != NULL); 18994 18995 if (resp == 401 || resp == 407) { 18996 ast_string_field_set(p, theirtag, NULL); 18997 if (p->options) { 18998 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 18999 } 19000 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, resp, SIP_PUBLISH, 0)) { 19001 ast_log(LOG_NOTICE, "Failed to authenticate on PUBLISH to '%s'\n", get_header(&p->initreq, "From")); 19002 pvt_set_needdestroy(p, "Failed to authenticate on PUBLISH"); 19003 sip_alreadygone(p); 19004 } 19005 return; 19006 } 19007 19008 if (resp == 501 || resp == 405) { 19009 mark_method_unallowed(&p->allowed_methods, SIP_PUBLISH); 19010 } 19011 19012 if (resp == 200) { 19013 p->authtries = 0; 19014 /* If I've read section 6, item 6 of RFC 3903 correctly, 19015 * an ESC will only generate a new etag when it sends a 200 OK 19016 */ 19017 if (!ast_strlen_zero(etag)) { 19018 ast_copy_string(epa_entry->entity_tag, etag, sizeof(epa_entry->entity_tag)); 19019 } 19020 /* The nominal case. Everything went well. Everybody is happy. 19021 * Each EPA will have a specific action to take as a result of this 19022 * development, so ... callbacks! 19023 */ 19024 if (epa_entry->static_data->handle_ok) { 19025 epa_entry->static_data->handle_ok(p, req, epa_entry); 19026 } 19027 } else { 19028 /* Rather than try to make individual callbacks for each error 19029 * type, there is just a single error callback. The callback 19030 * can distinguish between error messages and do what it needs to 19031 */ 19032 if (epa_entry->static_data->handle_error) { 19033 epa_entry->static_data->handle_error(p, resp, req, epa_entry); 19034 } 19035 } 19036 }
| static void handle_response_refer | ( | struct sip_pvt * | p, | |
| int | resp, | |||
| const char * | rest, | |||
| struct sip_request * | req, | |||
| int | seqno | |||
| ) | [static] |
Definition at line 19568 of file chan_sip.c.
References AST_CONTROL_CONGESTION, AST_CONTROL_TRANSFER, ast_debug, ast_log(), ast_queue_control(), ast_queue_control_data(), ast_sockaddr_stringify(), ast_strlen_zero(), AST_TRANSFER_FAILED, do_proxy_auth(), get_header(), LOG_NOTICE, LOG_WARNING, and pvt_set_needdestroy().
Referenced by handle_response().
19569 { 19570 enum ast_control_transfer message = AST_TRANSFER_FAILED; 19571 19572 /* If no refer structure exists, then do nothing */ 19573 if (!p->refer) 19574 return; 19575 19576 switch (resp) { 19577 case 202: /* Transfer accepted */ 19578 /* We need to do something here */ 19579 /* The transferee is now sending INVITE to target */ 19580 p->refer->status = REFER_ACCEPTED; 19581 /* Now wait for next message */ 19582 ast_debug(3, "Got 202 accepted on transfer\n"); 19583 /* We should hang along, waiting for NOTIFY's here */ 19584 break; 19585 19586 case 401: /* Not www-authorized on SIP method */ 19587 case 407: /* Proxy auth */ 19588 if (ast_strlen_zero(p->authname)) { 19589 ast_log(LOG_WARNING, "Asked to authenticate REFER to %s but we have no matching peer or realm auth!\n", 19590 ast_sockaddr_stringify(&p->recv)); 19591 if (p->owner) { 19592 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 19593 } 19594 pvt_set_needdestroy(p, "unable to authenticate REFER"); 19595 } 19596 if (p->authtries > 1 || do_proxy_auth(p, req, resp, SIP_REFER, 0)) { 19597 ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From")); 19598 p->refer->status = REFER_NOAUTH; 19599 if (p->owner) { 19600 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 19601 } 19602 pvt_set_needdestroy(p, "failed to authenticate REFER"); 19603 } 19604 break; 19605 19606 case 405: /* Method not allowed */ 19607 /* Return to the current call onhold */ 19608 /* Status flag needed to be reset */ 19609 ast_log(LOG_NOTICE, "SIP transfer to %s failed, REFER not allowed. \n", p->refer->refer_to); 19610 pvt_set_needdestroy(p, "received 405 response"); 19611 p->refer->status = REFER_FAILED; 19612 if (p->owner) { 19613 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 19614 } 19615 break; 19616 19617 case 481: /* Call leg does not exist */ 19618 19619 /* A transfer with Replaces did not work */ 19620 /* OEJ: We should Set flag, cancel the REFER, go back 19621 to original call - but right now we can't */ 19622 ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid); 19623 if (p->owner) 19624 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 19625 pvt_set_needdestroy(p, "received 481 response"); 19626 break; 19627 19628 case 500: /* Server error */ 19629 case 501: /* Method not implemented */ 19630 /* Return to the current call onhold */ 19631 /* Status flag needed to be reset */ 19632 ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to); 19633 pvt_set_needdestroy(p, "received 500/501 response"); 19634 p->refer->status = REFER_FAILED; 19635 if (p->owner) { 19636 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 19637 } 19638 break; 19639 case 603: /* Transfer declined */ 19640 ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to); 19641 p->refer->status = REFER_FAILED; 19642 pvt_set_needdestroy(p, "received 603 response"); 19643 if (p->owner) { 19644 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 19645 } 19646 break; 19647 default: 19648 /* We should treat unrecognized 9xx as 900. 400 is actually 19649 specified as a possible response, but any 4-6xx is 19650 theoretically possible. */ 19651 19652 if (resp < 299) { /* 1xx cases don't get here */ 19653 ast_log(LOG_WARNING, "SIP transfer to %s had unxpected 2xx response (%d), confusion is possible. \n", p->refer->refer_to, resp); 19654 } else { 19655 ast_log(LOG_WARNING, "SIP transfer to %s with response (%d). \n", p->refer->refer_to, resp); 19656 } 19657 19658 p->refer->status = REFER_FAILED; 19659 pvt_set_needdestroy(p, "received failure response"); 19660 if (p->owner) { 19661 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 19662 } 19663 break; 19664 } 19665 }
| static int handle_response_register | ( | struct sip_pvt * | p, | |
| int | resp, | |||
| const char * | rest, | |||
| struct sip_request * | req, | |||
| int | seqno | |||
| ) | [static] |
Handle responses on REGISTER to services.
Definition at line 19668 of file chan_sip.c.
References __get_header(), ast_debug, ast_log(), AST_SCHED_DEL_UNREF, AST_SCHED_REPLACE_UNREF, ast_strlen_zero(), ast_tvnow(), default_expiry, do_register_auth(), EVENT_FLAG_SYSTEM, get_header(), LOG_NOTICE, LOG_WARNING, manager_event, MAX, max_expiry, pvt_set_needdestroy(), REG_STATE_NOAUTH, REG_STATE_REGISTERED, REG_STATE_REJECTED, REG_STATE_UNREGISTERED, registry_addref(), registry_unref(), regstate2str(), S_OR, sip_reregister(), sip_scheddestroy(), strcasestr(), and transmit_register().
Referenced by handle_response().
19669 { 19670 int expires, expires_ms; 19671 struct sip_registry *r; 19672 r=p->registry; 19673 19674 switch (resp) { 19675 case 401: /* Unauthorized */ 19676 if (p->authtries == MAX_AUTHTRIES || do_register_auth(p, req, resp)) { 19677 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries); 19678 pvt_set_needdestroy(p, "failed to authenticate REGISTER"); 19679 } 19680 break; 19681 case 403: /* Forbidden */ 19682 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); 19683 AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 403")); 19684 r->regstate = REG_STATE_NOAUTH; 19685 pvt_set_needdestroy(p, "received 403 response"); 19686 break; 19687 case 404: /* Not found */ 19688 ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username, p->registry->hostname); 19689 pvt_set_needdestroy(p, "received 404 response"); 19690 if (r->call) 19691 r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 404"); 19692 r->regstate = REG_STATE_REJECTED; 19693 AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 404")); 19694 break; 19695 case 407: /* Proxy auth */ 19696 if (p->authtries == MAX_AUTHTRIES || do_register_auth(p, req, resp)) { 19697 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries); 19698 pvt_set_needdestroy(p, "failed to authenticate REGISTER"); 19699 } 19700 break; 19701 case 408: /* Request timeout */ 19702 /* Got a timeout response, so reset the counter of failed responses */ 19703 if (r) { 19704 r->regattempts = 0; 19705 } else { 19706 ast_log(LOG_WARNING, "Got a 408 response to our REGISTER on call %s after we had destroyed the registry object\n", p->callid); 19707 } 19708 break; 19709 case 423: /* Interval too brief */ 19710 r->expiry = atoi(get_header(req, "Min-Expires")); 19711 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); 19712 AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 423")); 19713 if (r->call) { 19714 r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 423"); 19715 pvt_set_needdestroy(p, "received 423 response"); 19716 } 19717 if (r->expiry > max_expiry) { 19718 ast_log(LOG_WARNING, "Required expiration time from %s@%s is too high, giving up\n", p->registry->username, p->registry->hostname); 19719 r->expiry = r->configured_expiry; 19720 r->regstate = REG_STATE_REJECTED; 19721 } else { 19722 r->regstate = REG_STATE_UNREGISTERED; 19723 transmit_register(r, SIP_REGISTER, NULL, NULL); 19724 } 19725 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: SIP\r\nUsername: %s\r\nDomain: %s\r\nStatus: %s\r\n", r->username, r->hostname, regstate2str(r->regstate)); 19726 break; 19727 case 479: /* SER: Not able to process the URI - address is wrong in register*/ 19728 ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username, p->registry->hostname); 19729 pvt_set_needdestroy(p, "received 479 response"); 19730 if (r->call) 19731 r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 479"); 19732 r->regstate = REG_STATE_REJECTED; 19733 AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 479")); 19734 break; 19735 case 200: /* 200 OK */ 19736 if (!r) { 19737 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)); 19738 pvt_set_needdestroy(p, "received erroneous 200 response"); 19739 return 0; 19740 } 19741 19742 r->regstate = REG_STATE_REGISTERED; 19743 r->regtime = ast_tvnow(); /* Reset time of last successful registration */ 19744 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate)); 19745 r->regattempts = 0; 19746 ast_debug(1, "Registration successful\n"); 19747 if (r->timeout > -1) { 19748 ast_debug(1, "Cancelling timeout %d\n", r->timeout); 19749 } 19750 AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 200")); 19751 if (r->call) 19752 r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 200"); 19753 p->registry = registry_unref(p->registry, "unref registry entry p->registry"); 19754 /* Let this one hang around until we have all the responses */ 19755 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 19756 /* p->needdestroy = 1; */ 19757 19758 /* set us up for re-registering 19759 * figure out how long we got registered for 19760 * according to section 6.13 of RFC, contact headers override 19761 * expires headers, so check those first */ 19762 expires = 0; 19763 19764 /* XXX todo: try to save the extra call */ 19765 if (!ast_strlen_zero(get_header(req, "Contact"))) { 19766 const char *contact = NULL; 19767 const char *tmptmp = NULL; 19768 int start = 0; 19769 for(;;) { 19770 contact = __get_header(req, "Contact", &start); 19771 /* this loop ensures we get a contact header about our register request */ 19772 if(!ast_strlen_zero(contact)) { 19773 if( (tmptmp=strstr(contact, p->our_contact))) { 19774 contact=tmptmp; 19775 break; 19776 } 19777 } else 19778 break; 19779 } 19780 tmptmp = strcasestr(contact, "expires="); 19781 if (tmptmp) { 19782 if (sscanf(tmptmp + 8, "%30d;", &expires) != 1) 19783 expires = 0; 19784 } 19785 19786 } 19787 if (!expires) 19788 expires=atoi(get_header(req, "expires")); 19789 if (!expires) 19790 expires=default_expiry; 19791 19792 expires_ms = expires * 1000; 19793 if (expires <= EXPIRY_GUARD_LIMIT) 19794 expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT), EXPIRY_GUARD_MIN); 19795 else 19796 expires_ms -= EXPIRY_GUARD_SECS * 1000; 19797 if (sipdebug) 19798 ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 19799 19800 r->refresh= (int) expires_ms / 1000; 19801 19802 /* Schedule re-registration before we expire */ 19803 AST_SCHED_REPLACE_UNREF(r->expire, sched, expires_ms, sip_reregister, r, 19804 registry_unref(_data,"unref in REPLACE del fail"), 19805 registry_unref(r,"unref in REPLACE add fail"), 19806 registry_addref(r,"The Addition side of REPLACE")); 19807 } 19808 return 1; 19809 }
| static void handle_response_subscribe | ( | struct sip_pvt * | p, | |
| int | resp, | |||
| const char * | rest, | |||
| struct sip_request * | req, | |||
| int | seqno | |||
| ) | [static] |
Definition at line 19506 of file chan_sip.c.
References ast_debug, ast_free, ast_log(), ast_sched_add(), ast_string_field_set, ASTOBJ_REF, ASTOBJ_UNREF, do_proxy_auth(), get_header(), LOG_NOTICE, LOG_WARNING, mwi_expiry, pvt_set_needdestroy(), set_pvt_allowed_methods(), sip_alreadygone(), sip_subscribe_mwi_destroy(), sip_subscribe_mwi_do(), and transmit_response_with_date().
Referenced by handle_response().
19507 { 19508 if (!p->mwi) { 19509 return; 19510 } 19511 19512 switch (resp) { 19513 case 200: /* Subscription accepted */ 19514 ast_debug(3, "Got 200 OK on subscription for MWI\n"); 19515 set_pvt_allowed_methods(p, req); 19516 if (p->options) { 19517 ast_free(p->options); 19518 p->options = NULL; 19519 } 19520 p->mwi->subscribed = 1; 19521 if ((p->mwi->resub = ast_sched_add(sched, mwi_expiry * 1000, sip_subscribe_mwi_do, ASTOBJ_REF(p->mwi))) < 0) { 19522 ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); 19523 } 19524 break; 19525 case 401: 19526 case 407: 19527 ast_string_field_set(p, theirtag, NULL); 19528 if (p->authtries > 1 || do_proxy_auth(p, req, resp, SIP_SUBSCRIBE, 0)) { 19529 ast_log(LOG_NOTICE, "Failed to authenticate on SUBSCRIBE to '%s'\n", get_header(&p->initreq, "From")); 19530 p->mwi->call = NULL; 19531 ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); 19532 pvt_set_needdestroy(p, "failed to authenticate SUBSCRIBE"); 19533 } 19534 break; 19535 case 403: 19536 transmit_response_with_date(p, "200 OK", req); 19537 ast_log(LOG_WARNING, "Authentication failed while trying to subscribe for MWI.\n"); 19538 p->mwi->call = NULL; 19539 ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); 19540 pvt_set_needdestroy(p, "received 403 response"); 19541 sip_alreadygone(p); 19542 break; 19543 case 404: 19544 ast_log(LOG_WARNING, "Subscription failed for MWI. The remote side said that a mailbox may not have been configured.\n"); 19545 p->mwi->call = NULL; 19546 ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); 19547 pvt_set_needdestroy(p, "received 404 response"); 19548 break; 19549 case 481: 19550 ast_log(LOG_WARNING, "Subscription failed for MWI. The remote side said that our dialog did not exist.\n"); 19551 p->mwi->call = NULL; 19552 ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); 19553 pvt_set_needdestroy(p, "received 481 response"); 19554 break; 19555 case 500: 19556 case 501: 19557 ast_log(LOG_WARNING, "Subscription failed for MWI. The remote side may have suffered a heart attack.\n"); 19558 p->mwi->call = NULL; 19559 ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); 19560 pvt_set_needdestroy(p, "received 500/501 response"); 19561 break; 19562 } 19563 }
| static void handle_response_update | ( | struct sip_pvt * | p, | |
| int | resp, | |||
| const char * | rest, | |||
| struct sip_request * | req, | |||
| int | seqno | |||
| ) | [static] |
Handle authentication challenge for SIP UPDATE.
This function is only called upon the receipt of a 401/407 response to an UPDATE.
Definition at line 18928 of file chan_sip.c.
References ast_log(), do_proxy_auth(), get_header(), and LOG_NOTICE.
Referenced by handle_response().
18929 { 18930 if (p->options) { 18931 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 18932 } 18933 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, resp, SIP_UPDATE, 1)) { 18934 ast_log(LOG_NOTICE, "Failed to authenticate on UPDATE to '%s'\n", get_header(&p->initreq, "From")); 18935 } 18936 }
| 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 23127 of file chan_sip.c.
References ao2_ref, event_state_compositor::callbacks, create_esc_entry(), transmit_response(), and transmit_response_with_sip_etag().
Referenced by handle_request_publish().
23128 { 23129 struct sip_esc_entry *esc_entry = create_esc_entry(esc, req, expires); 23130 int res = 0; 23131 23132 if (!esc_entry) { 23133 transmit_response(p, "503 Internal Server Failure", req); 23134 return -1; 23135 } 23136 23137 if (esc->callbacks->initial_handler) { 23138 res = esc->callbacks->initial_handler(p, req, esc, esc_entry); 23139 } 23140 23141 if (!res) { 23142 transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 0); 23143 } 23144 23145 ao2_ref(esc_entry, -1); 23146 return res; 23147 }
| 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 23177 of file chan_sip.c.
References ao2_ref, AST_SCHED_REPLACE_UNREF, event_state_compositor::callbacks, get_esc_entry(), publish_expire(), transmit_response(), and transmit_response_with_sip_etag().
Referenced by handle_request_publish().
23178 { 23179 struct sip_esc_entry *esc_entry = get_esc_entry(etag, esc); 23180 int expires_ms = expires * 1000; 23181 int res = 0; 23182 23183 if (!esc_entry) { 23184 transmit_response(p, "412 Conditional Request Failed", req); 23185 return -1; 23186 } 23187 23188 AST_SCHED_REPLACE_UNREF(esc_entry->sched_id, sched, expires_ms, publish_expire, esc_entry, 23189 ao2_ref(_data, -1), 23190 ao2_ref(esc_entry, -1), 23191 ao2_ref(esc_entry, +1)); 23192 23193 if (esc->callbacks->modify_handler) { 23194 res = esc->callbacks->modify_handler(p, req, esc, esc_entry); 23195 } 23196 23197 if (!res) { 23198 transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 1); 23199 } 23200 23201 ao2_ref(esc_entry, -1); 23202 return res; 23203 }
| 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 23149 of file chan_sip.c.
References ao2_ref, AST_SCHED_REPLACE_UNREF, event_state_compositor::callbacks, get_esc_entry(), publish_expire(), transmit_response(), and transmit_response_with_sip_etag().
Referenced by handle_request_publish().
23150 { 23151 struct sip_esc_entry *esc_entry = get_esc_entry(etag, esc); 23152 int expires_ms = expires * 1000; 23153 int res = 0; 23154 23155 if (!esc_entry) { 23156 transmit_response(p, "412 Conditional Request Failed", req); 23157 return -1; 23158 } 23159 23160 AST_SCHED_REPLACE_UNREF(esc_entry->sched_id, sched, expires_ms, publish_expire, esc_entry, 23161 ao2_ref(_data, -1), 23162 ao2_ref(esc_entry, -1), 23163 ao2_ref(esc_entry, +1)); 23164 23165 if (esc->callbacks->refresh_handler) { 23166 res = esc->callbacks->refresh_handler(p, req, esc, esc_entry); 23167 } 23168 23169 if (!res) { 23170 transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 1); 23171 } 23172 23173 ao2_ref(esc_entry, -1); 23174 return res; 23175 }
| 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 23205 of file chan_sip.c.
References ao2_ref, ao2_unlink, AST_SCHED_DEL, event_state_compositor::callbacks, event_state_compositor::compositor, get_esc_entry(), transmit_response(), and transmit_response_with_sip_etag().
Referenced by handle_request_publish().
23206 { 23207 struct sip_esc_entry *esc_entry = get_esc_entry(etag, esc); 23208 int res = 0; 23209 23210 if (!esc_entry) { 23211 transmit_response(p, "412 Conditional Request Failed", req); 23212 return -1; 23213 } 23214 23215 AST_SCHED_DEL(sched, esc_entry->sched_id); 23216 /* Scheduler's ref of the esc_entry */ 23217 ao2_ref(esc_entry, -1); 23218 23219 if (esc->callbacks->remove_handler) { 23220 res = esc->callbacks->remove_handler(p, req, esc, esc_entry); 23221 } 23222 23223 if (!res) { 23224 transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 1); 23225 } 23226 23227 /* Ref from finding the esc_entry earlier in function */ 23228 ao2_unlink(esc->compositor, esc_entry); 23229 ao2_ref(esc_entry, -1); 23230 return res; 23231 }
| static int handle_t38_options | ( | struct ast_flags * | flags, | |
| struct ast_flags * | mask, | |||
| struct ast_variable * | v, | |||
| int * | maxdatagram | |||
| ) | [static] |
Handle T.38 configuration options common to users and peers.
Definition at line 25529 of file chan_sip.c.
References ast_clear_flag, ast_log(), ast_set2_flag, ast_set_flag, ast_strdupa, ast_true(), config, global_t38_maxdatagram, ast_variable::lineno, LOG_WARNING, ast_variable::name, strsep(), ast_variable::value, and word.
Referenced by build_peer().
25531 { 25532 int res = 1; 25533 25534 if (!strcasecmp(v->name, "t38pt_udptl")) { 25535 char *buf = ast_strdupa(v->value); 25536 char *word, *next = buf; 25537 25538 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT); 25539 25540 while ((word = strsep(&next, ","))) { 25541 if (ast_true(word) || !strcasecmp(word, "fec")) { 25542 ast_clear_flag(&flags[1], SIP_PAGE2_T38SUPPORT); 25543 ast_set_flag(&flags[1], SIP_PAGE2_T38SUPPORT_UDPTL_FEC); 25544 } else if (!strcasecmp(word, "redundancy")) { 25545 ast_clear_flag(&flags[1], SIP_PAGE2_T38SUPPORT); 25546 ast_set_flag(&flags[1], SIP_PAGE2_T38SUPPORT_UDPTL_REDUNDANCY); 25547 } else if (!strcasecmp(word, "none")) { 25548 ast_clear_flag(&flags[1], SIP_PAGE2_T38SUPPORT); 25549 ast_set_flag(&flags[1], SIP_PAGE2_T38SUPPORT_UDPTL); 25550 } else if (!strncasecmp(word, "maxdatagram=", 12)) { 25551 if (sscanf(&word[12], "%30u", maxdatagram) != 1) { 25552 ast_log(LOG_WARNING, "Invalid maxdatagram '%s' at line %d of %s\n", v->value, v->lineno, config); 25553 *maxdatagram = global_t38_maxdatagram; 25554 } 25555 } 25556 } 25557 } else if (!strcasecmp(v->name, "t38pt_usertpsource")) { 25558 ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION); 25559 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION); 25560 } else { 25561 res = 0; 25562 } 25563 25564 return res; 25565 }
| 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 5896 of file chan_sip.c.
References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_CALL_REJECTED, AST_CAUSE_CHAN_NOT_IMPLEMENTED, AST_CAUSE_CONGESTION, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_FACILITY_REJECTED, AST_CAUSE_FAILURE, AST_CAUSE_INVALID_NUMBER_FORMAT, AST_CAUSE_NO_ANSWER, AST_CAUSE_NO_ROUTE_DESTINATION, AST_CAUSE_NO_ROUTE_TRANSIT_NET, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_NORMAL_UNSPECIFIED, AST_CAUSE_NOTDEFINED, AST_CAUSE_NUMBER_CHANGED, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNALLOCATED, AST_CAUSE_UNREGISTERED, AST_CAUSE_USER_BUSY, and ast_debug.
Referenced by sip_hangup().
05897 { 05898 switch (cause) { 05899 case AST_CAUSE_UNALLOCATED: /* 1 */ 05900 case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */ 05901 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */ 05902 return "404 Not Found"; 05903 case AST_CAUSE_CONGESTION: /* 34 */ 05904 case AST_CAUSE_SWITCH_CONGESTION: /* 42 */ 05905 return "503 Service Unavailable"; 05906 case AST_CAUSE_NO_USER_RESPONSE: /* 18 */ 05907 return "408 Request Timeout"; 05908 case AST_CAUSE_NO_ANSWER: /* 19 */ 05909 case AST_CAUSE_UNREGISTERED: /* 20 */ 05910 return "480 Temporarily unavailable"; 05911 case AST_CAUSE_CALL_REJECTED: /* 21 */ 05912 return "403 Forbidden"; 05913 case AST_CAUSE_NUMBER_CHANGED: /* 22 */ 05914 return "410 Gone"; 05915 case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */ 05916 return "480 Temporarily unavailable"; 05917 case AST_CAUSE_INVALID_NUMBER_FORMAT: 05918 return "484 Address incomplete"; 05919 case AST_CAUSE_USER_BUSY: 05920 return "486 Busy here"; 05921 case AST_CAUSE_FAILURE: 05922 return "500 Server internal failure"; 05923 case AST_CAUSE_FACILITY_REJECTED: /* 29 */ 05924 return "501 Not Implemented"; 05925 case AST_CAUSE_CHAN_NOT_IMPLEMENTED: 05926 return "503 Service Unavailable"; 05927 /* Used in chan_iax2 */ 05928 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 05929 return "502 Bad Gateway"; 05930 case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */ 05931 return "488 Not Acceptable Here"; 05932 05933 case AST_CAUSE_NOTDEFINED: 05934 default: 05935 ast_debug(1, "AST hangup cause %d (no match found in SIP)\n", cause); 05936 return NULL; 05937 } 05938 05939 /* Never reached */ 05940 return 0; 05941 }
| int hangup_sip2cause | ( | int | cause | ) |
Convert SIP hangup causes to Asterisk hangup causes.
Definition at line 5774 of file chan_sip.c.
References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CALL_REJECTED, AST_CAUSE_CONGESTION, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_FACILITY_REJECTED, AST_CAUSE_FAILURE, AST_CAUSE_INTERWORKING, AST_CAUSE_INVALID_NUMBER_FORMAT, AST_CAUSE_NO_ANSWER, AST_CAUSE_NO_ROUTE_DESTINATION, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_NORMAL, AST_CAUSE_NORMAL_TEMPORARY_FAILURE, AST_CAUSE_NUMBER_CHANGED, AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE, AST_CAUSE_UNALLOCATED, and AST_CAUSE_USER_BUSY.
Referenced by __transmit_response(), and handle_response().
05775 { 05776 /* Possible values taken from causes.h */ 05777 05778 switch(cause) { 05779 case 401: /* Unauthorized */ 05780 return AST_CAUSE_CALL_REJECTED; 05781 case 403: /* Not found */ 05782 return AST_CAUSE_CALL_REJECTED; 05783 case 404: /* Not found */ 05784 return AST_CAUSE_UNALLOCATED; 05785 case 405: /* Method not allowed */ 05786 return AST_CAUSE_INTERWORKING; 05787 case 407: /* Proxy authentication required */ 05788 return AST_CAUSE_CALL_REJECTED; 05789 case 408: /* No reaction */ 05790 return AST_CAUSE_NO_USER_RESPONSE; 05791 case 409: /* Conflict */ 05792 return AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 05793 case 410: /* Gone */ 05794 return AST_CAUSE_NUMBER_CHANGED; 05795 case 411: /* Length required */ 05796 return AST_CAUSE_INTERWORKING; 05797 case 413: /* Request entity too large */ 05798 return AST_CAUSE_INTERWORKING; 05799 case 414: /* Request URI too large */ 05800 return AST_CAUSE_INTERWORKING; 05801 case 415: /* Unsupported media type */ 05802 return AST_CAUSE_INTERWORKING; 05803 case 420: /* Bad extension */ 05804 return AST_CAUSE_NO_ROUTE_DESTINATION; 05805 case 480: /* No answer */ 05806 return AST_CAUSE_NO_ANSWER; 05807 case 481: /* No answer */ 05808 return AST_CAUSE_INTERWORKING; 05809 case 482: /* Loop detected */ 05810 return AST_CAUSE_INTERWORKING; 05811 case 483: /* Too many hops */ 05812 return AST_CAUSE_NO_ANSWER; 05813 case 484: /* Address incomplete */ 05814 return AST_CAUSE_INVALID_NUMBER_FORMAT; 05815 case 485: /* Ambiguous */ 05816 return AST_CAUSE_UNALLOCATED; 05817 case 486: /* Busy everywhere */ 05818 return AST_CAUSE_BUSY; 05819 case 487: /* Request terminated */ 05820 return AST_CAUSE_INTERWORKING; 05821 case 488: /* No codecs approved */ 05822 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 05823 case 491: /* Request pending */ 05824 return AST_CAUSE_INTERWORKING; 05825 case 493: /* Undecipherable */ 05826 return AST_CAUSE_INTERWORKING; 05827 case 500: /* Server internal failure */ 05828 return AST_CAUSE_FAILURE; 05829 case 501: /* Call rejected */ 05830 return AST_CAUSE_FACILITY_REJECTED; 05831 case 502: 05832 return AST_CAUSE_DESTINATION_OUT_OF_ORDER; 05833 case 503: /* Service unavailable */ 05834 return AST_CAUSE_CONGESTION; 05835 case 504: /* Gateway timeout */ 05836 return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE; 05837 case 505: /* SIP version not supported */ 05838 return AST_CAUSE_INTERWORKING; 05839 case 600: /* Busy everywhere */ 05840 return AST_CAUSE_USER_BUSY; 05841 case 603: /* Decline */ 05842 return AST_CAUSE_CALL_REJECTED; 05843 case 604: /* Does not exist anywhere */ 05844 return AST_CAUSE_UNALLOCATED; 05845 case 606: /* Not acceptable */ 05846 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 05847 default: 05848 if (cause < 500 && cause >= 400) { 05849 /* 4xx class error that is unknown - someting wrong with our request */ 05850 return AST_CAUSE_INTERWORKING; 05851 } else if (cause < 600 && cause >= 500) { 05852 /* 5xx class error - problem in the remote end */ 05853 return AST_CAUSE_CONGESTION; 05854 } else if (cause < 700 && cause >= 600) { 05855 /* 6xx - global errors in the 4xx class */ 05856 return AST_CAUSE_INTERWORKING; 05857 } 05858 return AST_CAUSE_NORMAL; 05859 } 05860 /* Never reached */ 05861 return 0; 05862 }
| static int init_req | ( | struct sip_request * | req, | |
| int | sipmethod, | |||
| const char * | recip | |||
| ) | [static] |
Initialize SIP request.
Definition at line 9614 of file chan_sip.c.
References ast_free, ast_str_create(), ast_str_set(), ast_str_strlen(), sip_methods, and cfsip_methods::text.
09615 { 09616 /* Initialize a request */ 09617 memset(req, 0, sizeof(*req)); 09618 if (!(req->data = ast_str_create(SIP_MIN_PACKET))) 09619 goto e_return; 09620 if (!(req->content = ast_str_create(SIP_MIN_PACKET))) 09621 goto e_free_data; 09622 req->method = sipmethod; 09623 req->header[0] = 0; 09624 ast_str_set(&req->data, 0, "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip); 09625 req->len = ast_str_strlen(req->data); 09626 req->headers++; 09627 return 0; 09628 09629 e_free_data: 09630 ast_free(req->data); 09631 req->data = NULL; 09632 e_return: 09633 return -1; 09634 }
| static int init_resp | ( | struct sip_request * | resp, | |
| const char * | msg | |||
| ) | [static] |
Initialize SIP response, based on SIP request.
Definition at line 9591 of file chan_sip.c.
References ast_free, ast_str_create(), and ast_str_set().
09592 { 09593 /* Initialize a response */ 09594 memset(resp, 0, sizeof(*resp)); 09595 resp->method = SIP_RESPONSE; 09596 if (!(resp->data = ast_str_create(SIP_MIN_PACKET))) 09597 goto e_return; 09598 if (!(resp->content = ast_str_create(SIP_MIN_PACKET))) 09599 goto e_free_data; 09600 resp->header[0] = 0; 09601 ast_str_set(&resp->data, 0, "SIP/2.0 %s\r\n", msg); 09602 resp->len = resp->data->used; 09603 resp->headers++; 09604 return 0; 09605 09606 e_free_data: 09607 ast_free(resp->data); 09608 resp->data = NULL; 09609 e_return: 09610 return -1; 09611 }
| static int initialize_escs | ( | void | ) | [static] |
Definition at line 1052 of file chan_sip.c.
References ao2_container_alloc, ARRAY_LEN, esc_cmp_fn(), esc_hash_fn(), and event_state_compositors.
Referenced by load_module().
01053 { 01054 int i, res = 0; 01055 for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) { 01056 if (!((event_state_compositors[i].compositor) = 01057 ao2_container_alloc(ESC_MAX_BUCKETS, esc_hash_fn, esc_cmp_fn))) { 01058 res = -1; 01059 } 01060 } 01061 return res; 01062 }
| 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 2983 of file chan_sip.c.
References ast_debug, ast_verbose, copy_request(), parse_request(), sip_methods, and cfsip_methods::text.
Referenced by transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_reinvite_with_sdp(), and update_connectedline().
02984 { 02985 if (p->initreq.headers) { 02986 ast_debug(1, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid); 02987 } else { 02988 ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid); 02989 } 02990 /* Use this as the basis */ 02991 copy_request(&p->initreq, req); 02992 parse_request(&p->initreq); 02993 if (req->debug) { 02994 ast_verbose("Initreq: %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 02995 } 02996 }
| static void initreqprep | ( | struct sip_request * | req, | |
| struct sip_pvt * | p, | |||
| int | sipmethod, | |||
| const char *const | explicit_uri | |||
| ) | [static] |
Initiate new SIP request to peer/user.
Definition at line 11327 of file chan_sip.c.
References add_header(), add_header_max_forwards(), add_route(), AST_DIGIT_ANYNUM, ast_party_id_presentation(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, ast_sockaddr_port, ast_sockaddr_stringify_host(), ast_str_alloca, ast_str_append(), ast_str_set(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_encode(), build_contact(), default_callerid, exten, global_useragent, init_req(), ourport, S_OR, sip_cfg, sip_methods, sip_standard_port(), and cfsip_methods::text.
Referenced by transmit_invite(), and transmit_notify_with_mwi().
11328 { 11329 struct ast_str *invite = ast_str_alloca(256); 11330 char from[256]; 11331 char to[256]; 11332 char tmp_n[SIPBUFSIZE/2]; /* build a local copy of 'n' if needed */ 11333 char tmp_l[SIPBUFSIZE/2]; /* build a local copy of 'l' if needed */ 11334 const char *l = NULL; /* XXX what is this, exactly ? */ 11335 const char *n = NULL; /* XXX what is this, exactly ? */ 11336 const char *d = NULL; /* domain in from header */ 11337 const char *urioptions = ""; 11338 int ourport; 11339 11340 if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) { 11341 const char *s = p->username; /* being a string field, cannot be NULL */ 11342 11343 /* Test p->username against allowed characters in AST_DIGIT_ANY 11344 If it matches the allowed characters list, then sipuser = ";user=phone" 11345 If not, then sipuser = "" 11346 */ 11347 /* + is allowed in first position in a tel: uri */ 11348 if (*s == '+') 11349 s++; 11350 for (; *s; s++) { 11351 if (!strchr(AST_DIGIT_ANYNUM, *s) ) 11352 break; 11353 } 11354 /* If we have only digits, add ;user=phone to the uri */ 11355 if (!*s) 11356 urioptions = ";user=phone"; 11357 } 11358 11359 11360 snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text); 11361 11362 d = S_OR(p->fromdomain, ast_sockaddr_stringify_host(&p->ourip)); 11363 if (p->owner) { 11364 if ((ast_party_id_presentation(&p->owner->connected.id) & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED) { 11365 l = p->owner->connected.id.number.valid ? p->owner->connected.id.number.str : NULL; 11366 n = p->owner->connected.id.name.valid ? p->owner->connected.id.name.str : NULL; 11367 } else if (!ast_test_flag(&p->flags[0], SIP_SENDRPID)) { 11368 /* if we are not sending RPID and user wants his callerid restricted */ 11369 l = CALLERID_UNKNOWN; 11370 n = l; 11371 d = FROMDOMAIN_INVALID; 11372 } 11373 } 11374 11375 /* Hey, it's a NOTIFY! See if they've configured a mwi_from. 11376 * XXX Right now, this logic works because the only place that mwi_from 11377 * is set on the sip_pvt is in sip_send_mwi_to_peer. If things changed, then 11378 * we might end up putting the mwi_from setting into other types of NOTIFY 11379 * messages as well. 11380 */ 11381 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->mwi_from)) { 11382 l = p->mwi_from; 11383 } 11384 11385 if (ast_strlen_zero(l)) 11386 l = default_callerid; 11387 if (ast_strlen_zero(n)) 11388 n = l; 11389 /* Allow user to be overridden */ 11390 if (!ast_strlen_zero(p->fromuser)) 11391 l = p->fromuser; 11392 else /* Save for any further attempts */ 11393 ast_string_field_set(p, fromuser, l); 11394 11395 /* Allow user to be overridden */ 11396 if (!ast_strlen_zero(p->fromname)) 11397 n = p->fromname; 11398 else /* Save for any further attempts */ 11399 ast_string_field_set(p, fromname, n); 11400 11401 if (sip_cfg.pedanticsipchecking) { 11402 ast_uri_encode(n, tmp_n, sizeof(tmp_n), 0); 11403 n = tmp_n; 11404 ast_uri_encode(l, tmp_l, sizeof(tmp_l), 0); 11405 l = tmp_l; 11406 } 11407 11408 ourport = (p->fromdomainport) ? p->fromdomainport : ast_sockaddr_port(&p->ourip); 11409 if (!sip_standard_port(p->socket.type, ourport)) { 11410 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%s", n, l, d, ourport, p->tag); 11411 } else { 11412 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, d, p->tag); 11413 } 11414 11415 if (!ast_strlen_zero(explicit_uri)) { 11416 ast_str_set(&invite, 0, "%s", explicit_uri); 11417 } else { 11418 /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */ 11419 if (!ast_strlen_zero(p->fullcontact)) { 11420 /* If we have full contact, trust it */ 11421 ast_str_append(&invite, 0, "%s", p->fullcontact); 11422 } else { 11423 /* Otherwise, use the username while waiting for registration */ 11424 ast_str_append(&invite, 0, "sip:"); 11425 if (!ast_strlen_zero(p->username)) { 11426 n = p->username; 11427 if (sip_cfg.pedanticsipchecking) { 11428 ast_uri_encode(n, tmp_n, sizeof(tmp_n), 0); 11429 n = tmp_n; 11430 } 11431 ast_str_append(&invite, 0, "%s@", n); 11432 } 11433 ast_str_append(&invite, 0, "%s", p->tohost); 11434 if (p->portinuri) { 11435 ast_str_append(&invite, 0, ":%d", ast_sockaddr_port(&p->sa)); 11436 } 11437 ast_str_append(&invite, 0, "%s", urioptions); 11438 } 11439 } 11440 11441 /* If custom URI options have been provided, append them */ 11442 if (p->options && !ast_strlen_zero(p->options->uri_options)) 11443 ast_str_append(&invite, 0, ";%s", p->options->uri_options); 11444 11445 /* This is the request URI, which is the next hop of the call 11446 which may or may not be the destination of the call 11447 */ 11448 ast_string_field_set(p, uri, invite->str); 11449 11450 if (!ast_strlen_zero(p->todnid)) { 11451 /*! \todo Need to add back the VXML URL here at some point, possibly use build_string for all this junk */ 11452 if (!strchr(p->todnid, '@')) { 11453 /* We have no domain in the dnid */ 11454 snprintf(to, sizeof(to), "<sip:%s@%s>%s%s", p->todnid, p->tohost, ast_strlen_zero(p->theirtag) ? "" : ";tag=", p->theirtag); 11455 } else { 11456 snprintf(to, sizeof(to), "<sip:%s>%s%s", p->todnid, ast_strlen_zero(p->theirtag) ? "" : ";tag=", p->theirtag); 11457 } 11458 } else { 11459 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 11460 /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ 11461 snprintf(to, sizeof(to), "<%s%s>;tag=%s", (strncasecmp(p->uri, "sip:", 4) ? "sip:" : ""), p->uri, p->theirtag); 11462 } else if (p->options && p->options->vxml_url) { 11463 /* If there is a VXML URL append it to the SIP URL */ 11464 snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); 11465 } else { 11466 snprintf(to, sizeof(to), "<%s>", p->uri); 11467 } 11468 } 11469 11470 init_req(req, sipmethod, p->uri); 11471 /* now tmp_n is available so reuse it to build the CSeq */ 11472 snprintf(tmp_n, sizeof(tmp_n), "%d %s", ++p->ocseq, sip_methods[sipmethod].text); 11473 11474 add_header(req, "Via", p->via); 11475 add_header_max_forwards(p, req); 11476 /* This will be a no-op most of the time. However, under certain circumstances, 11477 * NOTIFY messages will use this function for preparing the request and should 11478 * have Route headers present. 11479 */ 11480 add_route(req, p->route); 11481 11482 add_header(req, "From", from); 11483 add_header(req, "To", to); 11484 ast_string_field_set(p, exten, l); 11485 build_contact(p); 11486 add_header(req, "Contact", p->our_contact); 11487 add_header(req, "Call-ID", p->callid); 11488 add_header(req, "CSeq", tmp_n); 11489 if (!ast_strlen_zero(global_useragent)) { 11490 add_header(req, "User-Agent", global_useragent); 11491 } 11492 }
| static const char * insecure2str | ( | int | mode | ) | const [static] |
Convert Insecure setting to printable string.
Definition at line 16137 of file chan_sip.c.
References insecurestr, and map_x_s().
Referenced by _sip_show_peer().
16138 { 16139 return map_x_s(insecurestr, mode, "<error>"); 16140 }
| 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 6426 of file chan_sip.c.
References AST_CONTROL_T38_PARAMETERS, ast_queue_control_data(), AST_SCHED_DEL, AST_SCHED_DEL_UNREF, ast_set_flag, AST_T38_NEGOTIATED, AST_T38_REFUSED, AST_T38_REQUEST_NEGOTIATE, AST_T38_REQUEST_PARMS, AST_T38_REQUEST_TERMINATE, AST_T38_TERMINATED, ast_test_flag, ast_udptl_get_far_max_ifp(), ast_udptl_set_local_max_ifp(), change_t38_state(), FALSE, ast_control_t38_parameters::fill_bit_removal, ast_control_t38_parameters::max_ifp, MIN, ast_control_t38_parameters::request_response, transmit_reinvite_with_sdp(), transmit_response_reliable(), transmit_response_with_t38_sdp(), and TRUE.
Referenced by sip_indicate().
06427 { 06428 int res = 0; 06429 06430 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) || !p->udptl) { 06431 return -1; 06432 } 06433 switch (parameters->request_response) { 06434 case AST_T38_NEGOTIATED: 06435 case AST_T38_REQUEST_NEGOTIATE: /* Request T38 */ 06436 /* Negotiation can not take place without a valid max_ifp value. */ 06437 if (!parameters->max_ifp) { 06438 change_t38_state(p, T38_DISABLED); 06439 if (p->t38.state == T38_PEER_REINVITE) { 06440 AST_SCHED_DEL_UNREF(sched, p->t38id, dialog_unref(p, "when you delete the t38id sched, you should dec the refcount for the stored dialog ptr")); 06441 transmit_response_reliable(p, "488 Not acceptable here", &p->initreq); 06442 } 06443 break; 06444 } else if (p->t38.state == T38_PEER_REINVITE) { 06445 AST_SCHED_DEL_UNREF(sched, p->t38id, dialog_unref(p, "when you delete the t38id sched, you should dec the refcount for the stored dialog ptr")); 06446 p->t38.our_parms = *parameters; 06447 /* modify our parameters to conform to the peer's parameters, 06448 * based on the rules in the ITU T.38 recommendation 06449 */ 06450 if (!p->t38.their_parms.fill_bit_removal) { 06451 p->t38.our_parms.fill_bit_removal = FALSE; 06452 } 06453 if (!p->t38.their_parms.transcoding_mmr) { 06454 p->t38.our_parms.transcoding_mmr = FALSE; 06455 } 06456 if (!p->t38.their_parms.transcoding_jbig) { 06457 p->t38.our_parms.transcoding_jbig = FALSE; 06458 } 06459 p->t38.our_parms.version = MIN(p->t38.our_parms.version, p->t38.their_parms.version); 06460 p->t38.our_parms.rate_management = p->t38.their_parms.rate_management; 06461 ast_udptl_set_local_max_ifp(p->udptl, p->t38.our_parms.max_ifp); 06462 change_t38_state(p, T38_ENABLED); 06463 transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 06464 } else if (p->t38.state != T38_ENABLED) { 06465 p->t38.our_parms = *parameters; 06466 ast_udptl_set_local_max_ifp(p->udptl, p->t38.our_parms.max_ifp); 06467 change_t38_state(p, T38_LOCAL_REINVITE); 06468 if (!p->pendinginvite) { 06469 transmit_reinvite_with_sdp(p, TRUE, FALSE); 06470 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 06471 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 06472 } 06473 } 06474 break; 06475 case AST_T38_TERMINATED: 06476 case AST_T38_REFUSED: 06477 case AST_T38_REQUEST_TERMINATE: /* Shutdown T38 */ 06478 if (p->t38.state == T38_PEER_REINVITE) { 06479 AST_SCHED_DEL_UNREF(sched, p->t38id, dialog_unref(p, "when you delete the t38id sched, you should dec the refcount for the stored dialog ptr")); 06480 change_t38_state(p, T38_DISABLED); 06481 transmit_response_reliable(p, "488 Not acceptable here", &p->initreq); 06482 } else if (p->t38.state == T38_ENABLED) 06483 transmit_reinvite_with_sdp(p, FALSE, FALSE); 06484 break; 06485 case AST_T38_REQUEST_PARMS: { /* Application wants remote's parameters re-sent */ 06486 struct ast_control_t38_parameters parameters = p->t38.their_parms; 06487 06488 if (p->t38.state == T38_PEER_REINVITE) { 06489 AST_SCHED_DEL(sched, p->t38id); 06490 parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl); 06491 parameters.request_response = AST_T38_REQUEST_NEGOTIATE; 06492 ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, ¶meters, sizeof(parameters)); 06493 /* we need to return a positive value here, so that applications that 06494 * send this request can determine conclusively whether it was accepted or not... 06495 * older versions of chan_sip would just silently accept it and return zero. 06496 */ 06497 res = AST_T38_REQUEST_PARMS; 06498 } 06499 break; 06500 } 06501 default: 06502 res = -1; 06503 break; 06504 } 06505 06506 return res; 06507 }
| 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 7883 of file chan_sip.c.
Referenced by sip_sendtext(), and update_connectedline().
| static void list_route | ( | struct sip_route * | route | ) | [static] |
List all routes - mostly for debugging.
Definition at line 13452 of file chan_sip.c.
References ast_verbose.
Referenced by build_route().
13453 { 13454 if (!route) { 13455 ast_verbose("list_route: no route\n"); 13456 } else { 13457 for (;route; route = route->next) 13458 ast_verbose("list_route: hop: <%s>\n", route->hop); 13459 } 13460 }
| static int load_module | ( | void | ) | [static] |
PBX load module - initialization.
Definition at line 29012 of file chan_sip.c.
References ao2_container_alloc, ao2_t_container_alloc, ARRAY_LEN, ast_cc_agent_register(), ast_cc_monitor_register(), ast_channel_register(), ast_check_realtime(), ast_cli_register_multiple(), ast_custom_function_register, ast_data_register_multiple, ast_log(), ast_manager_register_xml, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_realtime_require_field(), ast_register_application_xml, ast_rtp_glue_register, AST_TEST_REGISTER, ast_udptl_proto_register(), ast_verbose, ASTOBJ_CONTAINER_INIT, can_parse_xml, cc_epa_static_data, CHANNEL_MODULE_LOAD, checksipdomain_function, cli_sip, dialog_cmp_cb(), dialog_hash_cb(), dialogs, EVENT_FLAG_REPORTING, EVENT_FLAG_SYSTEM, HASH_DIALOG_SIZE, HASH_PEER_SIZE, initialize_escs(), io, io_context_create(), io_context_destroy(), LOG_ERROR, manager_show_registry(), manager_sip_qualify_peer(), manager_sip_show_peer(), manager_sip_show_peers(), manager_sipnotify(), network_change_event_subscribe(), peer_cmp_cb(), peer_hash_cb(), peer_ipcmp_cb(), peer_iphash_cb(), peers_by_ip, regl, reload_config(), restart_monitor(), RQ_CHAR, RQ_INTEGER4, RQ_UINTEGER2, sched_context_create(), sched_context_destroy(), ast_channel_tech::send_digit_begin, SENTINEL, sip_addheader(), sip_cc_agent_callbacks, sip_cc_monitor_callbacks, sip_data_providers, sip_dtmfmode(), sip_epa_register(), sip_header_function, sip_is_xml_parsable(), sip_monitor_instance_cmp_fn(), sip_monitor_instance_hash_fn(), sip_monitor_instances, sip_poke_all_peers(), sip_register_tests(), sip_reloadreason, sip_removeheader(), sip_rtp_glue, sip_send_all_mwi_subscriptions(), sip_send_all_registers(), sip_tech, sip_tech_info, sip_udptl, sipchaninfo_function, sippeer_function, submwil, threadt, threadt_cmp_cb(), and threadt_hash_cb().
29013 { 29014 ast_verbose("SIP channel loading...\n"); 29015 /* the fact that ao2_containers can't resize automatically is a major worry! */ 29016 /* if the number of objects gets above MAX_XXX_BUCKETS, things will slow down */ 29017 peers = ao2_t_container_alloc(HASH_PEER_SIZE, peer_hash_cb, peer_cmp_cb, "allocate peers"); 29018 peers_by_ip = ao2_t_container_alloc(HASH_PEER_SIZE, peer_iphash_cb, peer_ipcmp_cb, "allocate peers_by_ip"); 29019 dialogs = ao2_t_container_alloc(HASH_DIALOG_SIZE, dialog_hash_cb, dialog_cmp_cb, "allocate dialogs"); 29020 threadt = ao2_t_container_alloc(HASH_DIALOG_SIZE, threadt_hash_cb, threadt_cmp_cb, "allocate threadt table"); 29021 29022 ASTOBJ_CONTAINER_INIT(®l); /* Registry object list -- not searched for anything */ 29023 ASTOBJ_CONTAINER_INIT(&submwil); /* MWI subscription object list */ 29024 29025 if (!(sched = sched_context_create())) { 29026 ast_log(LOG_ERROR, "Unable to create scheduler context\n"); 29027 return AST_MODULE_LOAD_FAILURE; 29028 } 29029 29030 if (!(io = io_context_create())) { 29031 ast_log(LOG_ERROR, "Unable to create I/O context\n"); 29032 sched_context_destroy(sched); 29033 return AST_MODULE_LOAD_FAILURE; 29034 } 29035 29036 sip_reloadreason = CHANNEL_MODULE_LOAD; 29037 29038 can_parse_xml = sip_is_xml_parsable(); 29039 if(reload_config(sip_reloadreason)) { /* Load the configuration from sip.conf */ 29040 return AST_MODULE_LOAD_DECLINE; 29041 } 29042 29043 /* Prepare the version that does not require DTMF BEGIN frames. 29044 * We need to use tricks such as memcpy and casts because the variable 29045 * has const fields. 29046 */ 29047 memcpy(&sip_tech_info, &sip_tech, sizeof(sip_tech)); 29048 memset((void *) &sip_tech_info.send_digit_begin, 0, sizeof(sip_tech_info.send_digit_begin)); 29049 29050 /* Make sure we can register our sip channel type */ 29051 if (ast_channel_register(&sip_tech)) { 29052 ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n"); 29053 io_context_destroy(io); 29054 sched_context_destroy(sched); 29055 return AST_MODULE_LOAD_FAILURE; 29056 } 29057 29058 #ifdef TEST_FRAMEWORK 29059 AST_TEST_REGISTER(test_sip_peers_get); 29060 AST_TEST_REGISTER(test_sip_mwi_subscribe_parse); 29061 #endif 29062 29063 /* Register AstData providers */ 29064 ast_data_register_multiple(sip_data_providers, ARRAY_LEN(sip_data_providers)); 29065 29066 /* Register all CLI functions for SIP */ 29067 ast_cli_register_multiple(cli_sip, ARRAY_LEN(cli_sip)); 29068 29069 /* Tell the UDPTL subdriver that we're here */ 29070 ast_udptl_proto_register(&sip_udptl); 29071 29072 /* Tell the RTP engine about our RTP glue */ 29073 ast_rtp_glue_register(&sip_rtp_glue); 29074 29075 /* Register dialplan applications */ 29076 ast_register_application_xml(app_dtmfmode, sip_dtmfmode); 29077 ast_register_application_xml(app_sipaddheader, sip_addheader); 29078 ast_register_application_xml(app_sipremoveheader, sip_removeheader); 29079 29080 /* Register dialplan functions */ 29081 ast_custom_function_register(&sip_header_function); 29082 ast_custom_function_register(&sippeer_function); 29083 ast_custom_function_register(&sipchaninfo_function); 29084 ast_custom_function_register(&checksipdomain_function); 29085 29086 /* Register manager commands */ 29087 ast_manager_register_xml("SIPpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_sip_show_peers); 29088 ast_manager_register_xml("SIPshowpeer", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_sip_show_peer); 29089 ast_manager_register_xml("SIPqualifypeer", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_sip_qualify_peer); 29090 ast_manager_register_xml("SIPshowregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_show_registry); 29091 ast_manager_register_xml("SIPnotify", EVENT_FLAG_SYSTEM, manager_sipnotify); 29092 sip_poke_all_peers(); 29093 sip_send_all_registers(); 29094 sip_send_all_mwi_subscriptions(); 29095 initialize_escs(); 29096 29097 if (sip_epa_register(&cc_epa_static_data)) { 29098 return AST_MODULE_LOAD_DECLINE; 29099 } 29100 29101 if (sip_reqresp_parser_init() == -1) { 29102 ast_log(LOG_ERROR, "Unable to initialize the SIP request and response parser\n"); 29103 return AST_MODULE_LOAD_DECLINE; 29104 } 29105 29106 if (can_parse_xml) { 29107 /* SIP CC agents require the ability to parse XML PIDF bodies 29108 * in incoming PUBLISH requests 29109 */ 29110 if (ast_cc_agent_register(&sip_cc_agent_callbacks)) { 29111 return AST_MODULE_LOAD_DECLINE; 29112 } 29113 } 29114 if (ast_cc_monitor_register(&sip_cc_monitor_callbacks)) { 29115 return AST_MODULE_LOAD_DECLINE; 29116 } 29117 if (!(sip_monitor_instances = ao2_container_alloc(37, sip_monitor_instance_hash_fn, sip_monitor_instance_cmp_fn))) { 29118 return AST_MODULE_LOAD_DECLINE; 29119 } 29120 29121 /* And start the monitor for the first time */ 29122 restart_monitor(); 29123 29124 ast_realtime_require_field(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", 29125 "name", RQ_CHAR, 10, 29126 "ipaddr", RQ_CHAR, INET6_ADDRSTRLEN - 1, 29127 "port", RQ_UINTEGER2, 5, 29128 "regseconds", RQ_INTEGER4, 11, 29129 "defaultuser", RQ_CHAR, 10, 29130 "fullcontact", RQ_CHAR, 35, 29131 "regserver", RQ_CHAR, 20, 29132 "useragent", RQ_CHAR, 20, 29133 "lastms", RQ_INTEGER4, 11, 29134 SENTINEL); 29135 29136 29137 sip_register_tests(); 29138 network_change_event_subscribe(); 29139 29140 return AST_MODULE_LOAD_SUCCESS; 29141 }
| static int local_attended_transfer | ( | struct sip_pvt * | transferer, | |
| struct sip_dual * | current, | |||
| struct sip_request * | req, | |||
| int | seqno, | |||
| int * | nounlock | |||
| ) | [static] |
Find all call legs and bridge transferee with target called from handle_request_refer.
Definition at line 22007 of file chan_sip.c.
References ao2_t_ref, append_history, ast_bridged_channel(), AST_CEL_ATTENDEDTRANSFER, ast_cel_report_event(), ast_channel_queue_connected_line_update(), ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_clear_flag, ast_connected_line_build_data(), AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, AST_CONTROL_READ_ACTION, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, ast_copy_string(), ast_debug, ast_do_masquerade(), AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO, ast_indicate(), ast_manager_event_multichan, ast_party_connected_line_copy(), ast_party_connected_line_free(), ast_party_connected_line_init(), ast_queue_control_data(), ast_set_flag, ast_state2str(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_streamfile(), ast_strlen_zero(), ast_waitstream(), attempt_transfer(), EVENT_FLAG_CALL, frame_size, get_sip_pvt_byid_locked(), ast_channel::name, ast_control_read_action_payload::payload_size, pbx_builtin_getvar_helper(), sip_pvt_lock, sip_pvt_unlock, ast_party_connected_line::source, transmit_notify_with_sipfrag(), TRUE, and xfersound.
Referenced by handle_request_refer().
22008 { 22009 struct sip_dual target; /* Chan 1: Call from tranferer to Asterisk */ 22010 /* Chan 2: Call from Asterisk to target */ 22011 int res = 0; 22012 struct sip_pvt *targetcall_pvt; 22013 struct ast_party_connected_line connected_to_transferee; 22014 struct ast_party_connected_line connected_to_target; 22015 char transferer_linkedid[32]; 22016 struct ast_channel *chans[2]; 22017 22018 /* Check if the call ID of the replaces header does exist locally */ 22019 if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 22020 transferer->refer->replaces_callid_fromtag))) { 22021 if (transferer->refer->localtransfer) { 22022 /* We did not find the refered call. Sorry, can't accept then */ 22023 /* Let's fake a response from someone else in order 22024 to follow the standard */ 22025 transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE); 22026 append_history(transferer, "Xfer", "Refer failed"); 22027 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 22028 transferer->refer->status = REFER_FAILED; 22029 return -1; 22030 } 22031 /* Fall through for remote transfers that we did not find locally */ 22032 ast_debug(3, "SIP attended transfer: Not our call - generating INVITE with replaces\n"); 22033 return 0; 22034 } 22035 22036 /* Ok, we can accept this transfer */ 22037 append_history(transferer, "Xfer", "Refer accepted"); 22038 if (!targetcall_pvt->owner) { /* No active channel */ 22039 ast_debug(4, "SIP attended transfer: Error: No owner of target call\n"); 22040 /* Cancel transfer */ 22041 transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE); 22042 append_history(transferer, "Xfer", "Refer failed"); 22043 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 22044 transferer->refer->status = REFER_FAILED; 22045 sip_pvt_unlock(targetcall_pvt); 22046 if (targetcall_pvt) 22047 ao2_t_ref(targetcall_pvt, -1, "Drop targetcall_pvt pointer"); 22048 return -1; 22049 } 22050 22051 /* We have a channel, find the bridge */ 22052 target.chan1 = targetcall_pvt->owner; /* Transferer to Asterisk */ 22053 target.chan2 = ast_bridged_channel(targetcall_pvt->owner); /* Asterisk to target */ 22054 22055 if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) { 22056 /* Wrong state of new channel */ 22057 if (target.chan2) 22058 ast_debug(4, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state)); 22059 else if (target.chan1->_state != AST_STATE_RING) 22060 ast_debug(4, "SIP attended transfer: Error: No target channel\n"); 22061 else 22062 ast_debug(4, "SIP attended transfer: Attempting transfer in ringing state\n"); 22063 } 22064 22065 /* Transfer */ 22066 if (sipdebug) { 22067 if (current->chan2) /* We have two bridges */ 22068 ast_debug(4, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name); 22069 else /* One bridge, propably transfer of IVR/voicemail etc */ 22070 ast_debug(4, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name); 22071 } 22072 22073 ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 22074 22075 ast_copy_string(transferer_linkedid, transferer->owner->linkedid, sizeof(transferer_linkedid)); 22076 22077 /* Perform the transfer */ 22078 chans[0] = transferer->owner; 22079 chans[1] = target.chan1; 22080 ast_manager_event_multichan(EVENT_FLAG_CALL, "Transfer", 2, chans, 22081 "TransferMethod: SIP\r\n" 22082 "TransferType: Attended\r\n" 22083 "Channel: %s\r\n" 22084 "Uniqueid: %s\r\n" 22085 "SIP-Callid: %s\r\n" 22086 "TargetChannel: %s\r\n" 22087 "TargetUniqueid: %s\r\n", 22088 transferer->owner->name, 22089 transferer->owner->uniqueid, 22090 transferer->callid, 22091 target.chan1->name, 22092 target.chan1->uniqueid); 22093 ast_party_connected_line_init(&connected_to_transferee); 22094 ast_party_connected_line_init(&connected_to_target); 22095 /* No need to lock current->chan1 here since it was locked in sipsock_read */ 22096 ast_party_connected_line_copy(&connected_to_transferee, ¤t->chan1->connected); 22097 /* No need to lock target.chan1 here since it was locked in get_sip_pvt_byid_locked */ 22098 ast_party_connected_line_copy(&connected_to_target, &target.chan1->connected); 22099 connected_to_target.source = connected_to_transferee.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER; 22100 res = attempt_transfer(current, &target); 22101 if (res) { 22102 /* Failed transfer */ 22103 transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE); 22104 append_history(transferer, "Xfer", "Refer failed"); 22105 ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); 22106 /* if transfer failed, go ahead and unlock targetcall_pvt and it's owner channel */ 22107 sip_pvt_unlock(targetcall_pvt); 22108 ast_channel_unlock(target.chan1); 22109 } else { 22110 /* Transfer succeeded! */ 22111 const char *xfersound = pbx_builtin_getvar_helper(target.chan1, "ATTENDED_TRANSFER_COMPLETE_SOUND"); 22112 22113 /* target.chan1 was locked in get_sip_pvt_byid_locked, do not unlock target.chan1 before this */ 22114 ast_cel_report_event(target.chan1, AST_CEL_ATTENDEDTRANSFER, NULL, transferer_linkedid, target.chan2); 22115 22116 /* Tell transferer that we're done. */ 22117 transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE); 22118 append_history(transferer, "Xfer", "Refer succeeded"); 22119 transferer->refer->status = REFER_200OK; 22120 if (target.chan2 && !ast_strlen_zero(xfersound) && ast_streamfile(target.chan2, xfersound, target.chan2->language) >= 0) { 22121 ast_waitstream(target.chan2, ""); 22122 } 22123 22124 /* By forcing the masquerade, we know that target.chan1 and target.chan2 are bridged. We then 22125 * can queue connected line updates where they need to go. 22126 * 22127 * before a masquerade, all channel and pvt locks must be unlocked. Any recursive 22128 * channel locks held before this function invalidates channel container locking order. 22129 * Since we are unlocking both the pvt (transferer) and its owner channel (current.chan1) 22130 * it is possible for current.chan1 to be destroyed in the pbx thread. To prevent this 22131 * we must give c a reference before any unlocking takes place. 22132 */ 22133 22134 ast_channel_ref(current->chan1); 22135 ast_channel_unlock(current->chan1); /* current.chan1 is p->owner before the masq, it was locked by socket_read()*/ 22136 ast_channel_unlock(target.chan1); 22137 *nounlock = 1; /* we just unlocked the dialog's channel and have no plans of locking it again. */ 22138 sip_pvt_unlock(targetcall_pvt); 22139 sip_pvt_unlock(transferer); 22140 22141 ast_do_masquerade(target.chan1); 22142 22143 sip_pvt_lock(transferer); /* the transferer pvt is expected to remain locked on return */ 22144 22145 ast_indicate(target.chan1, AST_CONTROL_UNHOLD); 22146 22147 if (current->chan2 && current->chan2->_state == AST_STATE_RING) { 22148 ast_indicate(target.chan1, AST_CONTROL_RINGING); 22149 } 22150 22151 if (target.chan2) { 22152 ast_channel_queue_connected_line_update(target.chan1, &connected_to_transferee, NULL); 22153 ast_channel_queue_connected_line_update(target.chan2, &connected_to_target, NULL); 22154 } else { 22155 /* Since target.chan1 isn't actually connected to another channel, there is no way for us 22156 * to queue a frame so that its connected line status will be updated. 22157 * 22158 * Instead, we use the somewhat hackish approach of using a special control frame type that 22159 * instructs ast_read to perform a specific action. In this case, the frame we queue tells 22160 * ast_read to call the connected line interception macro configured for target.chan1. 22161 */ 22162 struct ast_control_read_action_payload *frame_payload; 22163 int payload_size; 22164 int frame_size; 22165 unsigned char connected_line_data[1024]; 22166 payload_size = ast_connected_line_build_data(connected_line_data, 22167 sizeof(connected_line_data), &connected_to_target, NULL); 22168 frame_size = payload_size + sizeof(*frame_payload); 22169 if (payload_size != -1 && (frame_payload = alloca(frame_size))) { 22170 frame_payload->payload_size = payload_size; 22171 memcpy(frame_payload->payload, connected_line_data, payload_size); 22172 frame_payload->action = AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO; 22173 ast_queue_control_data(target.chan1, AST_CONTROL_READ_ACTION, frame_payload, frame_size); 22174 } 22175 /* In addition to queueing the read action frame so that target.chan1's connected line info 22176 * will be updated, we also are going to queue a plain old connected line update on target.chan1. This 22177 * way, either Dial or Queue can apply this connected line update to the outgoing ringing channel. 22178 */ 22179 ast_channel_queue_connected_line_update(target.chan1, &connected_to_transferee, NULL); 22180 22181 } 22182 ast_channel_unref(current->chan1); 22183 } 22184 22185 /* at this point if the transfer is successful only the transferer pvt should be locked. */ 22186 ast_party_connected_line_free(&connected_to_target); 22187 ast_party_connected_line_free(&connected_to_transferee); 22188 if (targetcall_pvt) 22189 ao2_t_ref(targetcall_pvt, -1, "drop targetcall_pvt"); 22190 return 1; 22191 }
| static int lws2sws | ( | char * | msgbuf, | |
| int | len | |||
| ) | [static] |
Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled.
Definition at line 7971 of file chan_sip.c.
Referenced by handle_request_do().
07972 { 07973 int h = 0, t = 0; 07974 int lws = 0; 07975 07976 for (; h < len;) { 07977 /* Eliminate all CRs */ 07978 if (msgbuf[h] == '\r') { 07979 h++; 07980 continue; 07981 } 07982 /* Check for end-of-line */ 07983 if (msgbuf[h] == '\n') { 07984 /* Check for end-of-message */ 07985 if (h + 1 == len) 07986 break; 07987 /* Check for a continuation line */ 07988 if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 07989 /* Merge continuation line */ 07990 h++; 07991 continue; 07992 } 07993 /* Propagate LF and start new line */ 07994 msgbuf[t++] = msgbuf[h++]; 07995 lws = 0; 07996 continue; 07997 } 07998 if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 07999 if (lws) { 08000 h++; 08001 continue; 08002 } 08003 msgbuf[t++] = msgbuf[h++]; 08004 lws = 1; 08005 continue; 08006 } 08007 msgbuf[t++] = msgbuf[h++]; 08008 if (lws) 08009 lws = 0; 08010 } 08011 msgbuf[t] = '\0'; 08012 return t; 08013 }
| static void make_our_tag | ( | char * | tagbuf, | |
| size_t | len | |||
| ) | [static] |
Make our SIP dialog tag.
Definition at line 7213 of file chan_sip.c.
References ast_random().
Referenced by handle_request_invite(), handle_request_subscribe(), sip_alloc(), transmit_register(), and transmit_response_using_temp().
07214 { 07215 snprintf(tagbuf, len, "as%08lx", ast_random()); 07216 }
| static int manager_show_registry | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Show SIP registrations in the manager API.
Definition at line 15775 of file chan_sip.c.
References ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_listack(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, regl, regstate2str(), S_OR, and total.
Referenced by load_module().
15776 { 15777 const char *id = astman_get_header(m, "ActionID"); 15778 char idtext[256] = ""; 15779 int total = 0; 15780 15781 if (!ast_strlen_zero(id)) 15782 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 15783 15784 astman_send_listack(s, m, "Registrations will follow", "start"); 15785 15786 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 15787 ASTOBJ_RDLOCK(iterator); 15788 astman_append(s, 15789 "Event: RegistryEntry\r\n" 15790 "%s" 15791 "Host: %s\r\n" 15792 "Port: %d\r\n" 15793 "Username: %s\r\n" 15794 "Domain: %s\r\n" 15795 "DomainPort: %d\r\n" 15796 "Refresh: %d\r\n" 15797 "State: %s\r\n" 15798 "RegistrationTime: %ld\r\n" 15799 "\r\n", 15800 idtext, 15801 iterator->hostname, 15802 iterator->portno ? iterator->portno : STANDARD_SIP_PORT, 15803 iterator->username, 15804 S_OR(iterator->regdomain,iterator->hostname), 15805 iterator->regdomainport ? iterator->regdomainport : STANDARD_SIP_PORT, 15806 iterator->refresh, 15807 regstate2str(iterator->regstate), 15808 (long) iterator->regtime.tv_sec); 15809 ASTOBJ_UNLOCK(iterator); 15810 total++; 15811 } while(0)); 15812 15813 astman_append(s, 15814 "Event: RegistrationsComplete\r\n" 15815 "EventList: Complete\r\n" 15816 "ListItems: %d\r\n" 15817 "%s" 15818 "\r\n", total, idtext); 15819 15820 return 0; 15821 }
| static int manager_sip_qualify_peer | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Qualify SIP peers in the manager API.
Definition at line 16495 of file chan_sip.c.
References _sip_qualify_peer(), ast_strlen_zero(), astman_append(), astman_get_header(), and astman_send_error().
Referenced by load_module().
16496 { 16497 const char *a[4]; 16498 const char *peer; 16499 16500 peer = astman_get_header(m, "Peer"); 16501 if (ast_strlen_zero(peer)) { 16502 astman_send_error(s, m, "Peer: <name> missing."); 16503 return 0; 16504 } 16505 a[0] = "sip"; 16506 a[1] = "qualify"; 16507 a[2] = "peer"; 16508 a[3] = peer; 16509 16510 _sip_qualify_peer(1, -1, s, m, 4, a); 16511 astman_append(s, "\r\n\r\n" ); 16512 return 0; 16513 }
| static int manager_sip_show_peer | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Show SIP peers in the manager API.
Definition at line 16436 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().
16437 { 16438 const char *a[4]; 16439 const char *peer; 16440 16441 peer = astman_get_header(m, "Peer"); 16442 if (ast_strlen_zero(peer)) { 16443 astman_send_error(s, m, "Peer: <name> missing."); 16444 return 0; 16445 } 16446 a[0] = "sip"; 16447 a[1] = "show"; 16448 a[2] = "peer"; 16449 a[3] = peer; 16450 16451 _sip_show_peer(1, -1, s, m, 4, a); 16452 astman_append(s, "\r\n\r\n" ); 16453 return 0; 16454 }
| static int manager_sip_show_peers | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Show SIP peers in the manager API.
Definition at line 15825 of file chan_sip.c.
References _sip_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_listack(), and total.
Referenced by load_module().
15826 { 15827 const char *id = astman_get_header(m, "ActionID"); 15828 const char *a[] = {"sip", "show", "peers"}; 15829 char idtext[256] = ""; 15830 int total = 0; 15831 15832 if (!ast_strlen_zero(id)) 15833 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 15834 15835 astman_send_listack(s, m, "Peer status list will follow", "start"); 15836 /* List the peers in separate manager events */ 15837 _sip_show_peers(-1, &total, s, m, 3, a); 15838 /* Send final confirmation */ 15839 astman_append(s, 15840 "Event: PeerlistComplete\r\n" 15841 "EventList: Complete\r\n" 15842 "ListItems: %d\r\n" 15843 "%s" 15844 "\r\n", total, idtext); 15845 return 0; 15846 }
| static int manager_sipnotify | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 12225 of file chan_sip.c.
References ast_log(), ast_set_flag, ast_str_append(), ast_str_strlen(), ast_strlen_zero(), ast_variable_new(), astman_get_header(), astman_get_variables(), astman_send_error(), create_addr(), dialog_unlink_all(), LOG_WARNING, sip_alloc(), sip_notify_allocate(), TRUE, and var.
Referenced by load_module().
12226 { 12227 const char *channame = astman_get_header(m, "Channel"); 12228 struct ast_variable *vars = astman_get_variables(m); 12229 struct sip_pvt *p; 12230 struct ast_variable *header, *var; 12231 12232 if (ast_strlen_zero(channame)) { 12233 astman_send_error(s, m, "SIPNotify requires a channel name"); 12234 return 0; 12235 } 12236 12237 if (!strncasecmp(channame, "sip/", 4)) { 12238 channame += 4; 12239 } 12240 12241 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) { 12242 astman_send_error(s, m, "Unable to build sip pvt data for notify (memory/socket error)"); 12243 return 0; 12244 } 12245 12246 if (create_addr(p, channame, NULL, 0, NULL)) { 12247 /* Maybe they're not registered, etc. */ 12248 dialog_unlink_all(p, TRUE, TRUE); 12249 dialog_unref(p, "unref dialog inside for loop" ); 12250 /* sip_destroy(p); */ 12251 astman_send_error(s, m, "Could not create address"); 12252 return 0; 12253 } 12254 12255 /* Notify is outgoing call */ 12256 ast_set_flag(&p->flags[0], SIP_OUTGOING); 12257 sip_notify_allocate(p); 12258 12259 p->notify->headers = header = ast_variable_new("Subscription-State", "terminated", ""); 12260 12261 for (var = vars; var; var = var->next) { 12262 if (!strcasecmp(var->name, "Content")) { 12263 if (ast_str_strlen(p->notify->content)) 12264 ast_str_append(&p->notify->content, 0, "\r\n"); 12265 ast_str_append(&p->notify->content, 0, "%s", var->value); 12266 } else if (!strcasecmp(var->name, "Content-Length")) { 12267 ast_log(LOG_WARNING, "it is not necessary to specify Content-Length, ignoring"); 12268 } else { 12269 header->next = ast_variable_new(var->name, var->value, ""); 12270 header = header->next; 12271 } 12272 } 12273 12274 dialog_ref(p, "bump the count of p, which transmit_sip_request will decrement."); 12275 sip_scheddestroy(p, SIP_TRANS_TIMEOUT); 12276 transmit_invite(p, SIP_NOTIFY, 0, 2, NULL); 12277 12278 astman_send_ack(s, m, "Notify Sent"); 12279 ast_variables_destroy(vars); 12280 return 0; 12281 }
| 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 2232 of file chan_sip.c.
References table.
Referenced by str2dtmfmode(), str2stmode(), and str2strefresher().
02233 { 02234 const struct _map_x_s *cur; 02235 02236 for (cur = table; cur->s; cur++) 02237 if (!strcasecmp(cur->s, s)) 02238 return cur->x; 02239 return errorvalue; 02240 }
| 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 2219 of file chan_sip.c.
References table.
Referenced by dtmfmode2str(), faxec2str(), insecure2str(), referstatus2str(), regstate2str(), stmode2str(), and strefresher2str().
02220 { 02221 const struct _map_x_s *cur; 02222 02223 for (cur = table; cur->s; cur++) 02224 if (cur->x == x) 02225 return cur->s; 02226 return errorstring; 02227 }
| static void mark_method_allowed | ( | unsigned int * | allowed_methods, | |
| enum sipmethod | method | |||
| ) | [static] |
Definition at line 7872 of file chan_sip.c.
Referenced by handle_response(), mark_parsed_methods(), and set_pvt_allowed_methods().
| static void mark_method_unallowed | ( | unsigned int * | allowed_methods, | |
| enum sipmethod | method | |||
| ) | [static] |
Definition at line 7877 of file chan_sip.c.
Referenced by handle_response(), and handle_response_publish().
| static void mark_parsed_methods | ( | unsigned int * | methods, | |
| char * | methods_str | |||
| ) | [static] |
Definition at line 7888 of file chan_sip.c.
References ast_skip_blanks(), ast_strlen_zero(), find_sip_method(), mark_method_allowed(), and strsep().
Referenced by build_peer(), and parse_allowed_methods().
07889 { 07890 char *method; 07891 for (method = strsep(&methods_str, ","); !ast_strlen_zero(method); method = strsep(&methods_str, ",")) { 07892 int id = find_sip_method(ast_skip_blanks(method)); 07893 if (id == SIP_UNKNOWN) { 07894 continue; 07895 } 07896 mark_method_allowed(methods, id); 07897 } 07898 }
| static enum match_req_res match_req_to_dialog | ( | struct sip_pvt * | sip_pvt_ptr, | |
| struct match_req_args * | arg | |||
| ) | [static] |
Definition at line 7471 of file chan_sip.c.
References ast_strlen_zero(), ast_test_flag, match_req_args::authentication_present, match_req_args::callid, match_req_args::fromtag, match_req_args::method, match_req_args::ruri, match_req_args::seqno, SIP_REQ_LOOP_DETECTED, SIP_REQ_MATCH, SIP_REQ_NOT_MATCH, match_req_args::totag, match_req_args::viabranch, and match_req_args::viasentby.
Referenced by find_call().
07472 { 07473 const char *init_ruri = NULL; 07474 if (sip_pvt_ptr->initreq.headers) { 07475 init_ruri = REQ_OFFSET_TO_STR(&sip_pvt_ptr->initreq, rlPart2); 07476 } 07477 07478 /* 07479 * Match Tags and call-id to Dialog 07480 */ 07481 if (!ast_strlen_zero(arg->callid) && strcmp(sip_pvt_ptr->callid, arg->callid)) { 07482 /* call-id does not match. */ 07483 return SIP_REQ_NOT_MATCH; 07484 } 07485 if (arg->method == SIP_RESPONSE) { 07486 /* Verify totag if we have one stored for this dialog, but never be strict about this for 07487 * a response until the dialog is established */ 07488 if (!ast_strlen_zero(sip_pvt_ptr->theirtag) && ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) { 07489 if (ast_strlen_zero(arg->totag)) { 07490 /* missing totag when they already gave us one earlier */ 07491 return SIP_REQ_NOT_MATCH; 07492 } 07493 if (strcmp(arg->totag, sip_pvt_ptr->theirtag)) { 07494 /* The totag of the response does not match the one we have stored */ 07495 return SIP_REQ_NOT_MATCH; 07496 } 07497 } 07498 /* Verify fromtag of response matches the tag we gave them. */ 07499 if (strcmp(arg->fromtag, sip_pvt_ptr->tag)) { 07500 /* fromtag from response does not match our tag */ 07501 return SIP_REQ_NOT_MATCH; 07502 } 07503 } else { 07504 /* Verify the fromtag of Request matches the tag they provided earlier. 07505 * If this is a Request with authentication credentials, forget their old 07506 * tag as it is not valid after the 401 or 407 response. */ 07507 if (!arg->authentication_present && strcmp(arg->fromtag, sip_pvt_ptr->theirtag)) { 07508 /* their tag does not match the one was have stored for them */ 07509 return SIP_REQ_NOT_MATCH; 07510 } 07511 /* Verify if totag is present in Request, that it matches what we gave them as our tag earlier */ 07512 if (!ast_strlen_zero(arg->totag) && (strcmp(arg->totag, sip_pvt_ptr->tag))) { 07513 /* totag from Request does not match our tag */ 07514 return SIP_REQ_NOT_MATCH; 07515 } 07516 } 07517 07518 /* 07519 * Compare incoming request against initial transaction. 07520 * 07521 * This is a best effort attempt at distinguishing forked requests from 07522 * our initial transaction. If all the elements are NOT in place to evaluate 07523 * this, this block is ignored and the dialog match is made regardless. 07524 * Once the totag is established after the dialog is confirmed, this is not necessary. 07525 * 07526 * CRITERIA required for initial transaction matching. 07527 * 07528 * 1. Is a Request 07529 * 2. Callid and theirtag match (this is done in the dialog matching block) 07530 * 3. totag is NOT present 07531 * 4. CSeq matchs our initial transaction's cseq number 07532 * 5. pvt has init via branch parameter stored 07533 */ 07534 if ((arg->method != SIP_RESPONSE) && /* must be a Request */ 07535 ast_strlen_zero(arg->totag) && /* must not have a totag */ 07536 (sip_pvt_ptr->init_icseq == arg->seqno) && /* the cseq must be the same as this dialogs initial cseq */ 07537 !ast_strlen_zero(sip_pvt_ptr->initviabranch) && /* The dialog must have started with a RFC3261 compliant branch tag */ 07538 init_ruri) { /* the dialog must have an initial request uri associated with it */ 07539 /* This Request matches all the criteria required for Loop/Merge detection. 07540 * Now we must go down the path of comparing VIA's and RURIs. */ 07541 if (ast_strlen_zero(arg->viabranch) || 07542 strcmp(arg->viabranch, sip_pvt_ptr->initviabranch) || 07543 ast_strlen_zero(arg->viasentby) || 07544 strcmp(arg->viasentby, sip_pvt_ptr->initviasentby)) { 07545 /* At this point, this request does not match this Dialog.*/ 07546 07547 /* if methods are different this is just a mismatch */ 07548 if ((sip_pvt_ptr->method != arg->method)) { 07549 return SIP_REQ_NOT_MATCH; 07550 } 07551 07552 /* If RUIs are different, this is a forked request to a separate URI. 07553 * Returning a mismatch allows this Request to be processed separately. */ 07554 if (sip_uri_cmp(init_ruri, arg->ruri)) { 07555 /* not a match, request uris are different */ 07556 return SIP_REQ_NOT_MATCH; 07557 } 07558 07559 /* Loop/Merge Detected 07560 * 07561 * ---Current Matches to Initial Request--- 07562 * request uri 07563 * Call-id 07564 * their-tag 07565 * no totag present 07566 * method 07567 * cseq 07568 * 07569 * --- Does not Match Initial Request --- 07570 * Top Via 07571 * 07572 * Without the same Via, this can not match our initial transaction for this dialog, 07573 * but given that this Request matches everything else associated with that initial 07574 * Request this is most certainly a Forked request in which we have already received 07575 * part of the fork. 07576 */ 07577 return SIP_REQ_LOOP_DETECTED; 07578 } 07579 } /* end of Request Via check */ 07580 07581 /* Match Authentication Request. 07582 * 07583 * A Request with an Authentication header must come back with the 07584 * same Request URI. Otherwise it is not a match. 07585 */ 07586 if ((arg->method != SIP_RESPONSE) && /* Must be a Request type to even begin checking this */ 07587 ast_strlen_zero(arg->totag) && /* no totag is present to match */ 07588 arg->authentication_present && /* Authentication header is present in Request */ 07589 sip_uri_cmp(init_ruri, arg->ruri)) { /* Compare the Request URI of both the last Request and this new one */ 07590 07591 /* Authentication was provided, but the Request URI did not match the last one on this dialog. */ 07592 return SIP_REQ_NOT_MATCH; 07593 } 07594 07595 return SIP_REQ_MATCH; 07596 }
| 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 3070 of file chan_sip.c.
References len(), sip_methods, and text.
Referenced by __sip_autodestruct(), __sip_semi_ack(), and find_sip_method().
03071 { 03072 int len = strlen(sip_methods[id].text); 03073 int l_name = name ? strlen(name) : 0; 03074 /* true if the string is long enough, and ends with whitespace, and matches */ 03075 return (l_name >= len && name[len] < 33 && 03076 !strncasecmp(sip_methods[id].text, name, len)); 03077 }
| static void mwi_event_cb | ( | const struct ast_event * | , | |
| void * | ||||
| ) | [static] |
Receive MWI events that we have subscribed to.
Definition at line 13793 of file chan_sip.c.
References ao2_lock, ao2_unlock, and sip_send_mwi_to_peer().
13794 { 13795 struct sip_peer *peer = userdata; 13796 13797 ao2_lock(peer); 13798 sip_send_mwi_to_peer(peer, event, 0); 13799 ao2_unlock(peer); 13800 }
| static void network_change_event_cb | ( | const struct ast_event * | , | |
| void * | ||||
| ) | [static] |
Definition at line 13827 of file chan_sip.c.
References ast_debug, ast_sched_add(), network_change_event_sched_cb(), and network_change_event_sched_id.
13828 { 13829 ast_debug(1, "SIP, got a network change event, renewing all SIP registrations.\n"); 13830 if (network_change_event_sched_id == -1) { 13831 network_change_event_sched_id = ast_sched_add(sched, 1000, network_change_event_sched_cb, NULL); 13832 } 13833 }
| static int network_change_event_sched_cb | ( | const void * | data | ) | [static] |
Definition at line 13819 of file chan_sip.c.
References network_change_event_sched_id, sip_send_all_mwi_subscriptions(), and sip_send_all_registers().
13820 { 13821 network_change_event_sched_id = -1; 13822 sip_send_all_registers(); 13823 sip_send_all_mwi_subscriptions(); 13824 return 0; 13825 }
| static void network_change_event_subscribe | ( | void | ) | [static] |
Definition at line 13802 of file chan_sip.c.
References AST_EVENT_IE_END, AST_EVENT_NETWORK_CHANGE, ast_event_subscribe(), network_change_event_cb(), and network_change_event_subscription.
13803 { 13804 if (!network_change_event_subscription) { 13805 network_change_event_subscription = ast_event_subscribe(AST_EVENT_NETWORK_CHANGE, 13806 network_change_event_cb, 13807 "SIP Network Change ", 13808 NULL, AST_EVENT_IE_END); 13809 } 13810 }
| static void network_change_event_unsubscribe | ( | void | ) | [static] |
Definition at line 13812 of file chan_sip.c.
References ast_event_unsubscribe(), and network_change_event_subscription.
13813 { 13814 if (network_change_event_subscription) { 13815 network_change_event_subscription = ast_event_unsubscribe(network_change_event_subscription); 13816 } 13817 }
| 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 3042 of file chan_sip.c.
References append_history, ast_debug, sip_cfg, and sipdebug.
Referenced by __sip_subscribe_mwi_do(), create_addr(), and create_addr_from_peer().
03043 { 03044 if (peer && peer->outboundproxy) { 03045 if (sipdebug) { 03046 ast_debug(1, "OBPROXY: Applying peer OBproxy to this call\n"); 03047 } 03048 append_history(dialog, "OBproxy", "Using peer obproxy %s", peer->outboundproxy->name); 03049 return peer->outboundproxy; 03050 } 03051 if (sip_cfg.outboundproxy.name[0]) { 03052 if (sipdebug) { 03053 ast_debug(1, "OBPROXY: Applying global OBproxy to this call\n"); 03054 } 03055 append_history(dialog, "OBproxy", "Using global obproxy %s", sip_cfg.outboundproxy.name); 03056 return &sip_cfg.outboundproxy; 03057 } 03058 if (sipdebug) { 03059 ast_debug(1, "OBPROXY: Not applying OBproxy to this call\n"); 03060 } 03061 return NULL; 03062 }
| static unsigned int parse_allowed_methods | ( | struct sip_request * | req | ) | [static] |
parse the Allow header to see what methods the endpoint we are communicating with allows.
We parse the allow header on incoming Registrations and save the result to the SIP peer that is registering. When the registration expires, we clear what we know about the peer's allowed methods. When the peer re-registers, we once again parse to see if the list of allowed methods has changed.
For peers that do not register, we parse the first message we receive during a call to see what is allowed, and save the information for the duration of the call.
| req | The SIP request we are parsing |
| The | methods allowed |
Definition at line 7915 of file chan_sip.c.
References ast_strdupa, ast_strip_quoted(), ast_strlen_zero(), get_header(), and mark_parsed_methods().
Referenced by set_pvt_allowed_methods().
07916 { 07917 char *allow = ast_strdupa(get_header(req, "Allow")); 07918 unsigned int allowed_methods = SIP_UNKNOWN; 07919 07920 if (ast_strlen_zero(allow)) { 07921 /* I have witnessed that REGISTER requests from Polycom phones do not 07922 * place the phone's allowed methods in an Allow header. Instead, they place the 07923 * allowed methods in a methods= parameter in the Contact header. 07924 */ 07925 char *contact = ast_strdupa(get_header(req, "Contact")); 07926 char *methods = strstr(contact, ";methods="); 07927 07928 if (ast_strlen_zero(methods)) { 07929 /* RFC 3261 states: 07930 * 07931 * "The absence of an Allow header field MUST NOT be 07932 * interpreted to mean that the UA sending the message supports no 07933 * methods. Rather, it implies that the UA is not providing any 07934 * information on what methods it supports." 07935 * 07936 * For simplicity, we'll assume that the peer allows all known 07937 * SIP methods if they have no Allow header. We can then clear out the necessary 07938 * bits if the peer lets us know that we have sent an unsupported method. 07939 */ 07940 return UINT_MAX; 07941 } 07942 allow = ast_strip_quoted(methods + 9, "\"", "\""); 07943 } 07944 mark_parsed_methods(&allowed_methods, allow); 07945 return allowed_methods; 07946 }
| static void parse_copy | ( | struct sip_request * | dst, | |
| const struct sip_request * | src | |||
| ) | [static] |
Copy SIP request, parse it.
Definition at line 3993 of file chan_sip.c.
References copy_request(), and parse_request().
Referenced by send_request(), and send_response().
03994 { 03995 copy_request(dst, src); 03996 parse_request(dst); 03997 }
| int parse_minse | ( | const char * | p_hdrval, | |
| int *const | p_interval | |||
| ) | [static] |
Session-Timers: Function for parsing Min-SE header.
Definition at line 24896 of file chan_sip.c.
References ast_debug, ast_log(), ast_skip_blanks(), ast_strlen_zero(), and LOG_WARNING.
Referenced by handle_request_invite(), and proc_422_rsp().
24897 { 24898 if (ast_strlen_zero(p_hdrval)) { 24899 ast_log(LOG_WARNING, "Null Min-SE header\n"); 24900 return -1; 24901 } 24902 24903 *p_interval = 0; 24904 p_hdrval = ast_skip_blanks(p_hdrval); 24905 if (!sscanf(p_hdrval, "%30d", p_interval)) { 24906 ast_log(LOG_WARNING, "Parsing of Min-SE header failed %s\n", p_hdrval); 24907 return -1; 24908 } 24909 24910 ast_debug(2, "Received Min-SE: %d\n", *p_interval); 24911 return 0; 24912 }
| static void parse_moved_contact | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| char ** | name, | |||
| char ** | number, | |||
| int | set_call_forward | |||
| ) | [static] |
Parse 302 Moved temporalily response.
Definition at line 18749 of file chan_sip.c.
References ao2_ref, ast_copy_string(), ast_debug, ast_log(), ast_strdup, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), find_closing_quote(), get_header(), get_transport(), LOG_NOTICE, pbx_builtin_setvar_helper(), remove_uri_parameters(), set_socket_transport(), and strcasestr().
Referenced by change_redirecting_information().
18750 { 18751 char contact[SIPBUFSIZE]; 18752 char *contact_name = NULL; 18753 char *contact_number = NULL; 18754 char *separator, *trans; 18755 char *domain; 18756 enum sip_transport transport = SIP_TRANSPORT_UDP; 18757 18758 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 18759 if ((separator = strchr(contact, ','))) 18760 *separator = '\0'; 18761 18762 contact_number = get_in_brackets(contact); 18763 if ((trans = strcasestr(contact_number, ";transport="))) { 18764 trans += 11; 18765 18766 if ((separator = strchr(trans, ';'))) 18767 *separator = '\0'; 18768 18769 if (!strncasecmp(trans, "tcp", 3)) 18770 transport = SIP_TRANSPORT_TCP; 18771 else if (!strncasecmp(trans, "tls", 3)) 18772 transport = SIP_TRANSPORT_TLS; 18773 else { 18774 if (strncasecmp(trans, "udp", 3)) 18775 ast_debug(1, "received contact with an invalid transport, '%s'\n", contact_number); 18776 /* This will assume UDP for all unknown transports */ 18777 transport = SIP_TRANSPORT_UDP; 18778 } 18779 } 18780 contact_number = remove_uri_parameters(contact_number); 18781 18782 if (p->socket.tcptls_session) { 18783 ao2_ref(p->socket.tcptls_session, -1); 18784 p->socket.tcptls_session = NULL; 18785 } 18786 18787 set_socket_transport(&p->socket, transport); 18788 18789 if (set_call_forward && ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) { 18790 char *host = NULL; 18791 if (!strncasecmp(contact_number, "sip:", 4)) 18792 contact_number += 4; 18793 else if (!strncasecmp(contact_number, "sips:", 5)) 18794 contact_number += 5; 18795 separator = strchr(contact_number, '/'); 18796 if (separator) 18797 *separator = '\0'; 18798 if ((host = strchr(contact_number, '@'))) { 18799 *host++ = '\0'; 18800 ast_debug(2, "Found promiscuous redirection to 'SIP/%s::::%s@%s'\n", contact_number, get_transport(transport), host); 18801 if (p->owner) 18802 ast_string_field_build(p->owner, call_forward, "SIP/%s::::%s@%s", contact_number, get_transport(transport), host); 18803 } else { 18804 ast_debug(2, "Found promiscuous redirection to 'SIP/::::%s@%s'\n", get_transport(transport), contact_number); 18805 if (p->owner) 18806 ast_string_field_build(p->owner, call_forward, "SIP/::::%s@%s", get_transport(transport), contact_number); 18807 } 18808 } else { 18809 separator = strchr(contact, '@'); 18810 if (separator) { 18811 *separator++ = '\0'; 18812 domain = separator; 18813 } else { 18814 /* No username part */ 18815 domain = contact; 18816 } 18817 separator = strchr(contact, '/'); /* WHEN do we hae a forward slash in the URI? */ 18818 if (separator) 18819 *separator = '\0'; 18820 18821 if (!strncasecmp(contact_number, "sip:", 4)) 18822 contact_number += 4; 18823 else if (!strncasecmp(contact_number, "sips:", 5)) 18824 contact_number += 5; 18825 separator = strchr(contact_number, ';'); /* And username ; parameters? */ 18826 if (separator) 18827 *separator = '\0'; 18828 ast_uri_decode(contact_number); 18829 if (set_call_forward) { 18830 ast_debug(2, "Received 302 Redirect to extension '%s' (domain %s)\n", contact_number, domain); 18831 if (p->owner) { 18832 pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain); 18833 ast_string_field_set(p->owner, call_forward, contact_number); 18834 } 18835 } 18836 } 18837 18838 /* We've gotten the number for the contact, now get the name */ 18839 18840 if (*contact == '\"') { 18841 contact_name = contact + 1; 18842 if (!(separator = (char *)find_closing_quote(contact_name, NULL))) { 18843 ast_log(LOG_NOTICE, "No closing quote on name in Contact header? %s\n", contact); 18844 } 18845 *separator = '\0'; 18846 } 18847 18848 if (name && !ast_strlen_zero(contact_name)) { 18849 *name = ast_strdup(contact_name); 18850 } 18851 if (number) { 18852 *number = ast_strdup(contact_number); 18853 } 18854 }
| 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 13131 of file chan_sip.c.
References ast_copy_string(), ast_string_field_set, get_header(), and TRUE.
Referenced by handle_request_invite(), handle_request_subscribe(), and handle_response_invite().
13132 { 13133 char contact[SIPBUFSIZE]; 13134 char *c; 13135 13136 /* Look for brackets */ 13137 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 13138 c = get_in_brackets(contact); 13139 13140 /* Save full contact to call pvt for later bye or re-invite */ 13141 ast_string_field_set(pvt, fullcontact, c); 13142 13143 /* Save URI for later ACKs, BYE or RE-invites */ 13144 ast_string_field_set(pvt, okcontacturi, c); 13145 13146 /* We should return false for URI:s we can't handle, 13147 like tel:, mailto:,ldap: etc */ 13148 return TRUE; 13149 }
| static enum parse_register_result parse_register_contact | ( | struct sip_pvt * | pvt, | |
| struct sip_peer * | p, | |||
| struct sip_request * | req | |||
| ) | [static] |
Parse contact header and save registration (peer registration).
Definition at line 13213 of file chan_sip.c.
References __get_header(), ao2_t_link, ao2_t_unlink, ast_apply_ha(), ast_copy_string(), ast_db_put(), ast_debug, ast_log(), ast_sched_add(), AST_SCHED_DEL_UNREF, ast_sched_when(), AST_SENSE_ALLOW, ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_resolve_first(), ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verb, ast_verbose, copy_socket_data(), default_expiry, destroy_association(), EVENT_FLAG_SYSTEM, expire_register(), FALSE, get_header(), get_transport_str2enum(), LOG_NOTICE, LOG_WARNING, manager_event, max_expiry, min_expiry, peers_by_ip, ref_peer(), register_peer_exten(), set_socket_transport(), sip_cfg, sip_poke_peer(), strcasestr(), strsep(), TRUE, unref_peer(), VERBOSE_PREFIX_3, and VERBOSITY_ATLEAST.
Referenced by register_verify().
13214 { 13215 char contact[SIPBUFSIZE]; 13216 char data[SIPBUFSIZE]; 13217 const char *expires = get_header(req, "Expires"); 13218 int expire = atoi(expires); 13219 char *curi, *domain, *transport; 13220 int transport_type; 13221 const char *useragent; 13222 struct ast_sockaddr oldsin, testsa; 13223 char *firstcuri = NULL; 13224 int start = 0; 13225 int wildcard_found = 0; 13226 int single_binding_found = 0; 13227 13228 ast_copy_string(contact, __get_header(req, "Contact", &start), sizeof(contact)); 13229 13230 if (ast_strlen_zero(expires)) { /* No expires header, try look in Contact: */ 13231 char *s = strcasestr(contact, ";expires="); 13232 if (s) { 13233 expires = strsep(&s, ";"); /* trim ; and beyond */ 13234 if (sscanf(expires + 9, "%30d", &expire) != 1) { 13235 expire = default_expiry; 13236 } 13237 } else { 13238 /* Nothing has been specified */ 13239 expire = default_expiry; 13240 } 13241 } 13242 13243 copy_socket_data(&pvt->socket, &req->socket); 13244 13245 do { 13246 /* Look for brackets */ 13247 curi = contact; 13248 if (strchr(contact, '<') == NULL) /* No <, check for ; and strip it */ 13249 strsep(&curi, ";"); /* This is Header options, not URI options */ 13250 curi = get_in_brackets(contact); 13251 if (!firstcuri) { 13252 firstcuri = ast_strdupa(curi); 13253 } 13254 13255 if (!strcasecmp(curi, "*")) { 13256 wildcard_found = 1; 13257 } else { 13258 single_binding_found = 1; 13259 } 13260 13261 if (wildcard_found && (ast_strlen_zero(expires) || expire != 0 || single_binding_found)) { 13262 /* Contact header parameter "*" detected, so punt if: Expires header is missing, 13263 * Expires value is not zero, or another Contact header is present. */ 13264 return PARSE_REGISTER_FAILED; 13265 } 13266 13267 ast_copy_string(contact, __get_header(req, "Contact", &start), sizeof(contact)); 13268 } while (!ast_strlen_zero(contact)); 13269 curi = firstcuri; 13270 13271 /* if they did not specify Contact: or Expires:, they are querying 13272 what we currently have stored as their contact address, so return 13273 it 13274 */ 13275 if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) { 13276 /* If we have an active registration, tell them when the registration is going to expire */ 13277 if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact)) { 13278 pvt->expiry = ast_sched_when(sched, peer->expire); 13279 } 13280 return PARSE_REGISTER_QUERY; 13281 } else if (!strcasecmp(curi, "*") || !expire) { /* Unregister this peer */ 13282 /* This means remove all registrations and return OK */ 13283 memset(&peer->addr, 0, sizeof(peer->addr)); 13284 set_socket_transport(&peer->socket, peer->default_outbound_transport); 13285 13286 AST_SCHED_DEL_UNREF(sched, peer->expire, 13287 unref_peer(peer, "remove register expire ref")); 13288 13289 destroy_association(peer); 13290 13291 register_peer_exten(peer, FALSE); /* Remove extension from regexten= setting in sip.conf */ 13292 ast_string_field_set(peer, fullcontact, ""); 13293 ast_string_field_set(peer, useragent, ""); 13294 peer->sipoptions = 0; 13295 peer->lastms = 0; 13296 peer->portinuri = 0; 13297 pvt->expiry = 0; 13298 13299 ast_verb(3, "Unregistered SIP '%s'\n", peer->name); 13300 13301 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name); 13302 return PARSE_REGISTER_UPDATE; 13303 } 13304 13305 /* Store whatever we got as a contact from the client */ 13306 ast_string_field_set(peer, fullcontact, curi); 13307 13308 /* For the 200 OK, we should use the received contact */ 13309 ast_string_field_build(pvt, our_contact, "<%s>", curi); 13310 13311 /* Make sure it's a SIP URL */ 13312 if (parse_uri(curi, "sip:,sips:", &curi, NULL, &domain, &transport)) { 13313 ast_log(LOG_NOTICE, "Not a valid SIP contact (missing sip:/sips:) trying to use anyway\n"); 13314 } 13315 13316 /* handle the transport type specified in Contact header. */ 13317 if (!(transport_type = get_transport_str2enum(transport))) { 13318 transport_type = pvt->socket.type; 13319 } 13320 13321 /* if the peer's socket type is different than the Registration 13322 * transport type, change it. If it got this far, it is a 13323 * supported type, but check just in case */ 13324 if ((peer->socket.type != transport_type) && (peer->transports & transport_type)) { 13325 set_socket_transport(&peer->socket, transport_type); 13326 } 13327 13328 oldsin = peer->addr; 13329 13330 /* If we were already linked into the peers_by_ip container unlink ourselves so nobody can find us */ 13331 if (!ast_sockaddr_isnull(&peer->addr)) { 13332 ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table"); 13333 } 13334 13335 if (!ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) && !ast_test_flag(&peer->flags[0], SIP_NAT_RPORT_PRESENT)) { 13336 /* use the data provided in the Contact header for call routing */ 13337 ast_debug(1, "Store REGISTER's Contact header for call routing.\n"); 13338 /* XXX This could block for a long time XXX */ 13339 /*! \todo Check NAPTR/SRV if we have not got a port in the URI */ 13340 if (ast_sockaddr_resolve_first(&testsa, domain, 0)) { 13341 ast_log(LOG_WARNING, "Invalid domain '%s'\n", domain); 13342 ast_string_field_set(peer, fullcontact, ""); 13343 ast_string_field_set(pvt, our_contact, ""); 13344 return PARSE_REGISTER_FAILED; 13345 } 13346 13347 /* If we have a port number in the given URI, make sure we do remember to not check for NAPTR/SRV records. 13348 The domain part is actually a host. */ 13349 peer->portinuri = ast_sockaddr_port(&testsa) ? TRUE : FALSE; 13350 13351 if (!ast_sockaddr_port(&testsa)) { 13352 ast_sockaddr_set_port(&testsa, 13353 transport_type == SIP_TRANSPORT_TLS ? 13354 STANDARD_TLS_PORT : STANDARD_SIP_PORT); 13355 } 13356 13357 ast_sockaddr_copy(&peer->addr, &testsa); 13358 } else { 13359 /* Don't trust the contact field. Just use what they came to us 13360 with */ 13361 ast_debug(1, "Store REGISTER's src-IP:port for call routing.\n"); 13362 peer->addr = pvt->recv; 13363 } 13364 13365 /* Check that they're allowed to register at this IP */ 13366 if (ast_apply_ha(sip_cfg.contact_ha, &peer->addr) != AST_SENSE_ALLOW || 13367 ast_apply_ha(peer->contactha, &peer->addr) != AST_SENSE_ALLOW) { 13368 ast_log(LOG_WARNING, "Domain '%s' disallowed by contact ACL (violating IP %s)\n", domain, 13369 ast_sockaddr_stringify_addr(&testsa)); 13370 ast_string_field_set(peer, fullcontact, ""); 13371 ast_string_field_set(pvt, our_contact, ""); 13372 return PARSE_REGISTER_DENIED; 13373 } 13374 13375 /* if the Contact header information copied into peer->addr matches the 13376 * received address, and the transport types are the same, then copy socket 13377 * data into the peer struct */ 13378 if ((peer->socket.type == pvt->socket.type) && 13379 !ast_sockaddr_cmp(&peer->addr, &pvt->recv)) { 13380 copy_socket_data(&peer->socket, &pvt->socket); 13381 } 13382 13383 /* Now that our address has been updated put ourselves back into the container for lookups */ 13384 ao2_t_link(peers_by_ip, peer, "ao2_link into peers_by_ip table"); 13385 13386 /* Save SIP options profile */ 13387 peer->sipoptions = pvt->sipoptions; 13388 13389 if (!ast_strlen_zero(curi) && ast_strlen_zero(peer->username)) { 13390 ast_string_field_set(peer, username, curi); 13391 } 13392 13393 AST_SCHED_DEL_UNREF(sched, peer->expire, 13394 unref_peer(peer, "remove register expire ref")); 13395 13396 if (expire > max_expiry) { 13397 expire = max_expiry; 13398 } 13399 if (expire < min_expiry) { 13400 expire = min_expiry; 13401 } 13402 if (peer->is_realtime && !ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 13403 peer->expire = -1; 13404 } else { 13405 peer->expire = ast_sched_add(sched, (expire + 10) * 1000, expire_register, 13406 ref_peer(peer, "add registration ref")); 13407 if (peer->expire == -1) { 13408 unref_peer(peer, "remote registration ref"); 13409 } 13410 } 13411 pvt->expiry = expire; 13412 snprintf(data, sizeof(data), "%s:%d:%s:%s", ast_sockaddr_stringify(&peer->addr), 13413 expire, peer->username, peer->fullcontact); 13414 /* Saving TCP connections is useless, we won't be able to reconnect 13415 XXX WHY???? XXX 13416 \todo Fix this immediately. 13417 */ 13418 if (!peer->rt_fromcontact && (peer->socket.type & SIP_TRANSPORT_UDP)) 13419 ast_db_put("SIP/Registry", peer->name, data); 13420 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Registered\r\nAddress: %s\r\n", peer->name, ast_sockaddr_stringify(&peer->addr)); 13421 13422 /* Is this a new IP address for us? */ 13423 if (VERBOSITY_ATLEAST(2) && ast_sockaddr_cmp(&peer->addr, &oldsin)) { 13424 ast_verbose(VERBOSE_PREFIX_3 "Registered SIP '%s' at %s\n", peer->name, 13425 ast_sockaddr_stringify(&peer->addr)); 13426 } 13427 sip_poke_peer(peer, 0); 13428 register_peer_exten(peer, 1); 13429 13430 /* Save User agent */ 13431 useragent = get_header(req, "User-Agent"); 13432 if (strcasecmp(useragent, peer->useragent)) { 13433 ast_string_field_set(peer, useragent, useragent); 13434 ast_verb(4, "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name); 13435 } 13436 return PARSE_REGISTER_UPDATE; 13437 }
| static int parse_request | ( | struct sip_request * | req | ) | [static] |
Parse a SIP message.
Definition at line 8018 of file chan_sip.c.
References ast_debug, ast_strlen_zero(), and sipdebug.
Referenced by handle_request_do(), initialize_initreq(), and parse_copy().
08019 { 08020 char *c = req->data->str; 08021 ptrdiff_t *dst = req->header; 08022 int i = 0, lim = SIP_MAX_HEADERS - 1; 08023 unsigned int skipping_headers = 0; 08024 ptrdiff_t current_header_offset = 0; 08025 char *previous_header = ""; 08026 08027 req->header[0] = 0; 08028 req->headers = -1; /* mark that we are working on the header */ 08029 for (; *c; c++) { 08030 if (*c == '\r') { /* remove \r */ 08031 *c = '\0'; 08032 } else if (*c == '\n') { /* end of this line */ 08033 *c = '\0'; 08034 current_header_offset = (c + 1) - req->data->str; 08035 previous_header = req->data->str + dst[i]; 08036 if (skipping_headers) { 08037 /* check to see if this line is blank; if so, turn off 08038 the skipping flag, so the next line will be processed 08039 as a body line */ 08040 if (ast_strlen_zero(previous_header)) { 08041 skipping_headers = 0; 08042 } 08043 dst[i] = current_header_offset; /* record start of next line */ 08044 continue; 08045 } 08046 if (sipdebug) { 08047 ast_debug(4, "%7s %2d [%3d]: %s\n", 08048 req->headers < 0 ? "Header" : "Body", 08049 i, (int) strlen(previous_header), previous_header); 08050 } 08051 if (ast_strlen_zero(previous_header) && req->headers < 0) { 08052 req->headers = i; /* record number of header lines */ 08053 dst = req->line; /* start working on the body */ 08054 i = 0; 08055 lim = SIP_MAX_LINES - 1; 08056 } else { /* move to next line, check for overflows */ 08057 if (i++ == lim) { 08058 /* if we're processing headers, then skip any remaining 08059 headers and move on to processing the body, otherwise 08060 we're done */ 08061 if (req->headers != -1) { 08062 break; 08063 } else { 08064 req->headers = i; 08065 dst = req->line; 08066 i = 0; 08067 lim = SIP_MAX_LINES - 1; 08068 skipping_headers = 1; 08069 } 08070 } 08071 } 08072 dst[i] = current_header_offset; /* record start of next line */ 08073 } 08074 } 08075 08076 /* Check for last header or body line without CRLF. The RFC for SDP requires CRLF, 08077 but since some devices send without, we'll be generous in what we accept. However, 08078 if we've already reached the maximum number of lines for portion of the message 08079 we were parsing, we can't accept any more, so just ignore it. 08080 */ 08081 previous_header = req->data->str + dst[i]; 08082 if ((i < lim) && !ast_strlen_zero(previous_header)) { 08083 if (sipdebug) { 08084 ast_debug(4, "%7s %2d [%3d]: %s\n", 08085 req->headers < 0 ? "Header" : "Body", 08086 i, (int) strlen(previous_header), previous_header ); 08087 } 08088 i++; 08089 } 08090 08091 /* update count of header or body lines */ 08092 if (req->headers >= 0) { /* we are in the body */ 08093 req->lines = i; 08094 } else { /* no body */ 08095 req->headers = i; 08096 req->lines = 0; 08097 /* req->data->used will be a NULL byte */ 08098 req->line[0] = ast_str_strlen(req->data); 08099 } 08100 08101 if (*c) { 08102 ast_log(LOG_WARNING, "Too many lines, skipping <%s>\n", c); 08103 } 08104 08105 /* Split up the first line parts */ 08106 return determine_firstline_parts(req); 08107 }
| int parse_session_expires | ( | const char * | p_hdrval, | |
| int *const | p_interval, | |||
| enum st_refresher *const | p_ref | |||
| ) | [static] |
Session-Timers: Function for parsing Session-Expires header.
Definition at line 24916 of file chan_sip.c.
References ast_debug, ast_log(), ast_skip_blanks(), ast_strdupa, ast_strlen_zero(), LOG_WARNING, and strsep().
Referenced by handle_request_invite(), and handle_response_invite().
24917 { 24918 char *p_token; 24919 int ref_idx; 24920 char *p_se_hdr; 24921 24922 if (ast_strlen_zero(p_hdrval)) { 24923 ast_log(LOG_WARNING, "Null Session-Expires header\n"); 24924 return -1; 24925 } 24926 24927 *p_ref = SESSION_TIMER_REFRESHER_AUTO; 24928 *p_interval = 0; 24929 24930 p_se_hdr = ast_strdupa(p_hdrval); 24931 p_se_hdr = ast_skip_blanks(p_se_hdr); 24932 24933 while ((p_token = strsep(&p_se_hdr, ";"))) { 24934 p_token = ast_skip_blanks(p_token); 24935 if (!sscanf(p_token, "%30d", p_interval)) { 24936 ast_log(LOG_WARNING, "Parsing of Session-Expires failed\n"); 24937 return -1; 24938 } 24939 24940 ast_debug(2, "Session-Expires: %d\n", *p_interval); 24941 24942 if (!p_se_hdr) 24943 continue; 24944 24945 p_se_hdr = ast_skip_blanks(p_se_hdr); 24946 ref_idx = strlen("refresher="); 24947 if (!strncasecmp(p_se_hdr, "refresher=", ref_idx)) { 24948 p_se_hdr += ref_idx; 24949 p_se_hdr = ast_skip_blanks(p_se_hdr); 24950 24951 if (!strncasecmp(p_se_hdr, "uac", strlen("uac"))) { 24952 *p_ref = SESSION_TIMER_REFRESHER_UAC; 24953 ast_debug(2, "Refresher: UAC\n"); 24954 } else if (!strncasecmp(p_se_hdr, "uas", strlen("uas"))) { 24955 *p_ref = SESSION_TIMER_REFRESHER_UAS; 24956 ast_debug(2, "Refresher: UAS\n"); 24957 } else { 24958 ast_log(LOG_WARNING, "Invalid refresher value %s\n", p_se_hdr); 24959 return -1; 24960 } 24961 break; 24962 } 24963 } 24964 return 0; 24965 }
| static int peer_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
| static int peer_dump_func | ( | void * | userobj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 16050 of file chan_sip.c.
References ao2_t_ref, ast_cli(), and ast_cli_args::fd.
Referenced by sip_show_objects().
16051 { 16052 struct sip_peer *peer = userobj; 16053 int refc = ao2_t_ref(userobj, 0, ""); 16054 struct ast_cli_args *a = (struct ast_cli_args *) arg; 16055 16056 ast_cli(a->fd, "name: %s\ntype: peer\nobjflags: %d\nrefcount: %d\n\n", 16057 peer->name, 0, refc); 16058 return 0; 16059 }
| static int peer_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 28461 of file chan_sip.c.
References ast_str_case_hash().
28462 { 28463 const struct sip_peer *peer = obj; 28464 28465 return ast_str_case_hash(peer->name); 28466 }
| static int peer_ipcmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Match Peers by IP and Port number.
This function has two modes.
This callback will be used twice when doing peer matching. There is a first pass for full IP+port matching, and a second pass in case there is a match that meets the insecure=port criteria.
the peer's addr struct provides to fields combined to make a key: the sin_addr.s_addr and sin_port fields.
Definition at line 28519 of file chan_sip.c.
References ast_sockaddr_cmp_addr(), ast_sockaddr_port, ast_test_flag, CMP_MATCH, and CMP_STOP.
Referenced by load_module().
28520 { 28521 struct sip_peer *peer = obj, *peer2 = arg; 28522 28523 if (ast_sockaddr_cmp_addr(&peer->addr, &peer2->addr)) { 28524 /* IP doesn't match */ 28525 return 0; 28526 } 28527 28528 /* We matched the IP, check to see if we need to match by port as well. */ 28529 if ((peer->transports & peer2->transports) & (SIP_TRANSPORT_TLS | SIP_TRANSPORT_TCP)) { 28530 /* peer matching on port is not possible with TCP/TLS */ 28531 return CMP_MATCH | CMP_STOP; 28532 } else if (ast_test_flag(&peer2->flags[0], SIP_INSECURE_PORT)) { 28533 /* We are allowing match without port for peers configured that 28534 * way in this pass through the peers. */ 28535 return ast_test_flag(&peer->flags[0], SIP_INSECURE_PORT) ? 28536 (CMP_MATCH | CMP_STOP) : 0; 28537 } 28538 28539 /* Now only return a match if the port matches, as well. */ 28540 return ast_sockaddr_port(&peer->addr) == ast_sockaddr_port(&peer2->addr) ? 28541 (CMP_MATCH | CMP_STOP) : 0; 28542 }
| static int peer_iphash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Hash function based on the the peer's ip address. For IPv6, we use the end of the address.
Definition at line 28483 of file chan_sip.c.
References ast_log(), ast_sockaddr_hash(), ast_sockaddr_isnull(), and LOG_ERROR.
Referenced by load_module().
28484 { 28485 const struct sip_peer *peer = obj; 28486 int ret = 0; 28487 28488 if (ast_sockaddr_isnull(&peer->addr)) { 28489 ast_log(LOG_ERROR, "Empty address\n"); 28490 } 28491 28492 ret = ast_sockaddr_hash(&peer->addr); 28493 28494 if (ret < 0) { 28495 ret = -ret; 28496 } 28497 28498 return ret; 28499 }
| static int peer_is_marked | ( | void * | peerobj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 2792 of file chan_sip.c.
References AST_SCHED_DEL, and CMP_MATCH.
Referenced by unlink_marked_peers_from_tables().
02793 { 02794 struct sip_peer *peer = peerobj; 02795 if (peer->the_mark && peer->pokeexpire != -1) { 02796 AST_SCHED_DEL(sched, peer->pokeexpire); 02797 } 02798 return peer->the_mark ? CMP_MATCH : 0; 02799 }
| static void peer_mailboxes_to_str | ( | struct ast_str ** | mailbox_str, | |
| struct sip_peer * | peer | |||
| ) | [static] |
list peer mailboxes to CLI
Definition at line 16533 of file chan_sip.c.
References AST_LIST_NEXT, AST_LIST_TRAVERSE, ast_str_append(), ast_strlen_zero(), mailbox, and S_OR.
Referenced by _sip_show_peer(), function_sippeer(), show_channels_cb(), and sip_send_mwi_to_peer().
16534 { 16535 struct sip_mailbox *mailbox; 16536 16537 AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { 16538 ast_str_append(mailbox_str, 0, "%s%s%s%s", 16539 mailbox->mailbox, 16540 ast_strlen_zero(mailbox->context) ? "" : "@", 16541 S_OR(mailbox->context, ""), 16542 AST_LIST_NEXT(mailbox, entry) ? "," : ""); 16543 } 16544 }
| static int peer_markall_func | ( | void * | device, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
| static int peer_status | ( | struct sip_peer * | peer, | |
| char * | status, | |||
| int | statuslen | |||
| ) | [static] |
Definition at line 15640 of file chan_sip.c.
References ast_copy_string().
15641 { 15642 int res = 0; 15643 if (peer->maxms) { 15644 if (peer->lastms < 0) { 15645 ast_copy_string(status, "UNREACHABLE", statuslen); 15646 } else if (peer->lastms > peer->maxms) { 15647 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 15648 res = 1; 15649 } else if (peer->lastms) { 15650 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 15651 res = 1; 15652 } else { 15653 ast_copy_string(status, "UNKNOWN", statuslen); 15654 } 15655 } else { 15656 ast_copy_string(status, "Unmonitored", statuslen); 15657 /* Checking if port is 0 */ 15658 res = -1; 15659 } 15660 return res; 15661 }
| int peercomparefunc | ( | const void * | a, | |
| const void * | b | |||
| ) |
Definition at line 15868 of file chan_sip.c.
Referenced by _sip_show_peers().
15869 { 15870 struct sip_peer **ap = (struct sip_peer **)a; 15871 struct sip_peer **bp = (struct sip_peer **)b; 15872 return strcmp((*ap)->name, (*bp)->name); 15873 }
| static int peers_data_provider_get | ( | const struct ast_data_search * | search, | |
| struct ast_data * | data_root | |||
| ) | [static] |
Definition at line 28900 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, ARRAY_LEN, ast_cdr_flags2str(), ast_data_add_bool(), ast_data_add_codecs(), ast_data_add_int(), ast_data_add_node(), ast_data_add_str(), ast_data_add_structure, ast_data_remove_node(), ast_data_search_match(), ast_describe_caller_presentation(), AST_LIST_TRAVERSE, get_transport_list(), mailbox, and transfermode2str().
28902 { 28903 struct sip_peer *peer; 28904 struct ao2_iterator i; 28905 struct ast_data *data_peer, *data_peer_mailboxes = NULL, *data_peer_mailbox, *enum_node; 28906 struct ast_data *data_sip_options; 28907 int total_mailboxes, x; 28908 struct sip_mailbox *mailbox; 28909 28910 i = ao2_iterator_init(peers, 0); 28911 while ((peer = ao2_iterator_next(&i))) { 28912 ao2_lock(peer); 28913 28914 data_peer = ast_data_add_node(data_root, "peer"); 28915 if (!data_peer) { 28916 ao2_unlock(peer); 28917 ao2_ref(peer, -1); 28918 continue; 28919 } 28920 28921 ast_data_add_structure(sip_peer, data_peer, peer); 28922 28923 /* transfer mode */ 28924 enum_node = ast_data_add_node(data_peer, "allowtransfer"); 28925 if (!enum_node) { 28926 continue; 28927 } 28928 ast_data_add_str(enum_node, "text", transfermode2str(peer->allowtransfer)); 28929 ast_data_add_int(enum_node, "value", peer->allowtransfer); 28930 28931 /* transports */ 28932 ast_data_add_str(data_peer, "transports", get_transport_list(peer->transports)); 28933 28934 /* peer type */ 28935 if ((peer->type & SIP_TYPE_USER) && (peer->type & SIP_TYPE_PEER)) { 28936 ast_data_add_str(data_peer, "type", "friend"); 28937 } else if (peer->type & SIP_TYPE_PEER) { 28938 ast_data_add_str(data_peer, "type", "peer"); 28939 } else if (peer->type & SIP_TYPE_USER) { 28940 ast_data_add_str(data_peer, "type", "user"); 28941 } 28942 28943 /* mailboxes */ 28944 total_mailboxes = 0; 28945 AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { 28946 if (!total_mailboxes) { 28947 data_peer_mailboxes = ast_data_add_node(data_peer, "mailboxes"); 28948 if (!data_peer_mailboxes) { 28949 break; 28950 } 28951 total_mailboxes++; 28952 } 28953 28954 data_peer_mailbox = ast_data_add_node(data_peer_mailboxes, "mailbox"); 28955 if (!data_peer_mailbox) { 28956 continue; 28957 } 28958 ast_data_add_str(data_peer_mailbox, "mailbox", mailbox->mailbox); 28959 ast_data_add_str(data_peer_mailbox, "context", mailbox->context); 28960 } 28961 28962 /* amaflags */ 28963 enum_node = ast_data_add_node(data_peer, "amaflags"); 28964 if (!enum_node) { 28965 continue; 28966 } 28967 ast_data_add_int(enum_node, "value", peer->amaflags); 28968 ast_data_add_str(enum_node, "text", ast_cdr_flags2str(peer->amaflags)); 28969 28970 /* sip options */ 28971 data_sip_options = ast_data_add_node(data_peer, "sipoptions"); 28972 if (!data_sip_options) { 28973 continue; 28974 } 28975 for (x = 0 ; x < ARRAY_LEN(sip_options); x++) { 28976 ast_data_add_bool(data_sip_options, sip_options[x].text, peer->sipoptions & sip_options[x].id); 28977 } 28978 28979 /* callingpres */ 28980 enum_node = ast_data_add_node(data_peer, "callingpres"); 28981 if (!enum_node) { 28982 continue; 28983 } 28984 ast_data_add_int(enum_node, "value", peer->callingpres); 28985 ast_data_add_str(enum_node, "text", ast_describe_caller_presentation(peer->callingpres)); 28986 28987 /* codecs */ 28988 ast_data_add_codecs(data_peer, "codecs", peer->capability); 28989 28990 if (!ast_data_search_match(search, data_peer)) { 28991 ast_data_remove_node(data_root, data_peer); 28992 } 28993 28994 ao2_unlock(peer); 28995 ao2_ref(peer, -1); 28996 } 28997 ao2_iterator_destroy(&i); 28998 28999 return 0; 29000 }
| static int pidf_validate_presence | ( | struct ast_xml_doc * | doc | ) | [static] |
Definition at line 22894 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, pidf_validate_tuple(), and TRUE.
Referenced by sip_pidf_validate().
22895 { 22896 struct ast_xml_node *presence_node = ast_xml_get_root(doc); 22897 struct ast_xml_node *child_nodes; 22898 struct ast_xml_node *node_iterator; 22899 struct ast_xml_ns *ns; 22900 const char *entity; 22901 const char *namespace; 22902 const char presence_namespace[] = "urn:ietf:params:xml:ns:pidf"; 22903 22904 if (!presence_node) { 22905 ast_log(LOG_WARNING, "Unable to retrieve root node of the XML document\n"); 22906 return FALSE; 22907 } 22908 /* Okay, we managed to open the document! YAY! Now, let's start making sure it's all PIDF-ified 22909 * correctly. 22910 */ 22911 if (strcmp(ast_xml_node_get_name(presence_node), "presence")) { 22912 ast_log(LOG_WARNING, "Root node of PIDF document is not 'presence'. Invalid\n"); 22913 return FALSE; 22914 } 22915 22916 /* The presence element must have an entity attribute and an xmlns attribute. Furthermore 22917 * the xmlns attribute must be "urn:ietf:params:xml:ns:pidf" 22918 */ 22919 if (!(entity = ast_xml_get_attribute(presence_node, "entity"))) { 22920 ast_log(LOG_WARNING, "Presence element of PIDF document has no 'entity' attribute\n"); 22921 return FALSE; 22922 } 22923 /* We're not interested in what the entity is, just that it exists */ 22924 ast_xml_free_attr(entity); 22925 22926 if (!(ns = ast_xml_find_namespace(doc, presence_node, NULL))) { 22927 ast_log(LOG_WARNING, "Couldn't find default namespace...\n"); 22928 return FALSE; 22929 } 22930 22931 namespace = ast_xml_get_ns_href(ns); 22932 if (ast_strlen_zero(namespace) || strcmp(namespace, presence_namespace)) { 22933 ast_log(LOG_WARNING, "PIDF document has invalid namespace value %s\n", namespace); 22934 return FALSE; 22935 } 22936 22937 if (!(child_nodes = ast_xml_node_get_children(presence_node))) { 22938 ast_log(LOG_WARNING, "PIDF document has no elements as children of 'presence'. Invalid\n"); 22939 return FALSE; 22940 } 22941 22942 /* Check for tuple elements. RFC 3863 says that PIDF documents can have any number of 22943 * tuples, including 0. The big thing here is that if there are tuple elements present, 22944 * they have to have a single status element within. 22945 * 22946 * The RFC is worded such that tuples should appear as the first elements as children of 22947 * the presence element. However, we'll be accepting of documents which may place other elements 22948 * before the tuple(s). 22949 */ 22950 for (node_iterator = child_nodes; node_iterator; 22951 node_iterator = ast_xml_node_get_next(node_iterator)) { 22952 if (strcmp(ast_xml_node_get_name(node_iterator), "tuple")) { 22953 /* Not a tuple. We don't give a rat's hind quarters */ 22954 continue; 22955 } 22956 if (pidf_validate_tuple(node_iterator) == FALSE) { 22957 ast_log(LOG_WARNING, "Unable to validate tuple\n"); 22958 return FALSE; 22959 } 22960 } 22961 22962 return TRUE; 22963 }
| static int pidf_validate_tuple | ( | struct ast_xml_node * | tuple_node | ) | [static] |
Definition at line 22854 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().
22855 { 22856 const char *id; 22857 int status_found = FALSE; 22858 struct ast_xml_node *tuple_children; 22859 struct ast_xml_node *tuple_children_iterator; 22860 /* Tuples have to have an id attribute or they're invalid */ 22861 if (!(id = ast_xml_get_attribute(tuple_node, "id"))) { 22862 ast_log(LOG_WARNING, "Tuple XML element has no attribute 'id'\n"); 22863 return FALSE; 22864 } 22865 /* We don't care what it actually is, just that it's there */ 22866 ast_xml_free_attr(id); 22867 /* This is a tuple. It must have a status element */ 22868 if (!(tuple_children = ast_xml_node_get_children(tuple_node))) { 22869 /* The tuple has no children. It sucks */ 22870 ast_log(LOG_WARNING, "Tuple XML element has no child elements\n"); 22871 return FALSE; 22872 } 22873 for (tuple_children_iterator = tuple_children; tuple_children_iterator; 22874 tuple_children_iterator = ast_xml_node_get_next(tuple_children_iterator)) { 22875 /* Similar to the wording used regarding tuples, the status element should appear 22876 * first. However, we will once again relax things and accept the status at any 22877 * position. We will enforce that only a single status element can be present. 22878 */ 22879 if (strcmp(ast_xml_node_get_name(tuple_children_iterator), "status")) { 22880 /* Not the status, we don't care */ 22881 continue; 22882 } 22883 if (status_found == TRUE) { 22884 /* THERE CAN BE ONLY ONE!!! */ 22885 ast_log(LOG_WARNING, "Multiple status elements found in tuple. Only one allowed\n"); 22886 return FALSE; 22887 } 22888 status_found = TRUE; 22889 } 22890 return status_found; 22891 }
| unsigned int port_str2int | ( | const char * | pt, | |
| unsigned int | standard | |||
| ) |
converts ascii port to int representation. If no pt buffer is provided or the pt has errors when being converted to an int value, the port provided as the standard is used.
Definition at line 3031 of file chan_sip.c.
References ast_strlen_zero().
Referenced by build_peer().
03032 { 03033 int port = standard; 03034 if (ast_strlen_zero(pt) || (sscanf(pt, "%30d", &port) != 1) || (port < 1) || (port > 65535)) { 03035 port = standard; 03036 } 03037 03038 return port; 03039 }
| static void print_codec_to_cli | ( | int | fd, | |
| struct ast_codec_pref * | pref | |||
| ) | [static] |
Print codec list from preference to CLI/manager.
Definition at line 16370 of file chan_sip.c.
References ast_cli(), ast_codec_pref_index(), ast_getformatname(), and ast_codec_pref::framing.
Referenced by _sip_show_peer(), _skinny_show_line(), sip_show_settings(), and sip_show_user().
16371 { 16372 int x; 16373 format_t codec; 16374 16375 for(x = 0; x < 64 ; x++) { 16376 codec = ast_codec_pref_index(pref, x); 16377 if (!codec) 16378 break; 16379 ast_cli(fd, "%s", ast_getformatname(codec)); 16380 ast_cli(fd, ":%d", pref->framing[x]); 16381 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 16382 ast_cli(fd, ","); 16383 } 16384 if (!x) 16385 ast_cli(fd, "none"); 16386 }
| static void print_group | ( | int | fd, | |
| ast_group_t | group, | |||
| int | crlf | |||
| ) | [static] |
Print call group and pickup group.
Definition at line 16100 of file chan_sip.c.
References ast_cli(), and ast_print_group().
Referenced by _sip_show_peer(), and sip_show_user().
16101 { 16102 char buf[256]; 16103 ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) ); 16104 }
| 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 24975 of file chan_sip.c.
References ast_log(), ast_strlen_zero(), get_header(), LOG_WARNING, parse_minse(), and transmit_invite().
Referenced by handle_response_invite().
24976 { 24977 int rtn; 24978 const char *p_hdrval; 24979 int minse; 24980 24981 p_hdrval = get_header(rsp, "Min-SE"); 24982 if (ast_strlen_zero(p_hdrval)) { 24983 ast_log(LOG_WARNING, "422 response without a Min-SE header %s\n", p_hdrval); 24984 return; 24985 } 24986 rtn = parse_minse(p_hdrval, &minse); 24987 if (rtn != 0) { 24988 ast_log(LOG_WARNING, "Parsing of Min-SE header failed %s\n", p_hdrval); 24989 return; 24990 } 24991 p->stimer->st_interval = minse; 24992 transmit_invite(p, SIP_INVITE, 1, 2, NULL); 24993 }
| static int proc_session_timer | ( | const void * | vp | ) | [static] |
Session-Timers: Process session refresh timeout event.
Definition at line 24815 of file chan_sip.c.
References ast_channel_trylock, ast_channel_unlock, ast_debug, ast_log(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, FALSE, LOG_ERROR, LOG_WARNING, sip_pvt_lock, sip_pvt_unlock, stop_session_timer(), transmit_reinvite_with_sdp(), and TRUE.
Referenced by start_session_timer().
24816 { 24817 struct sip_pvt *p = (struct sip_pvt *) vp; 24818 int sendreinv = FALSE; 24819 int res = 0; 24820 24821 if (!p->stimer) { 24822 ast_log(LOG_WARNING, "Null stimer in proc_session_timer - %s\n", p->callid); 24823 goto return_unref; 24824 } 24825 24826 ast_debug(2, "Session timer expired: %d - %s\n", p->stimer->st_schedid, p->callid); 24827 24828 if (!p->owner) { 24829 goto return_unref; 24830 } 24831 24832 if ((p->stimer->st_active != TRUE) || (p->owner->_state != AST_STATE_UP)) { 24833 goto return_unref; 24834 } 24835 24836 switch (p->stimer->st_ref) { 24837 case SESSION_TIMER_REFRESHER_UAC: 24838 if (p->outgoing_call == TRUE) { 24839 sendreinv = TRUE; 24840 } 24841 break; 24842 case SESSION_TIMER_REFRESHER_UAS: 24843 if (p->outgoing_call != TRUE) { 24844 sendreinv = TRUE; 24845 } 24846 break; 24847 default: 24848 ast_log(LOG_ERROR, "Unknown session refresher %d\n", p->stimer->st_ref); 24849 goto return_unref; 24850 } 24851 24852 if (sendreinv == TRUE) { 24853 res = 1; 24854 transmit_reinvite_with_sdp(p, FALSE, TRUE); 24855 } else { 24856 p->stimer->st_expirys++; 24857 if (p->stimer->st_expirys >= 2) { 24858 if (p->stimer->quit_flag) { 24859 goto return_unref; 24860 } 24861 ast_log(LOG_WARNING, "Session-Timer expired - %s\n", p->callid); 24862 sip_pvt_lock(p); 24863 while (p->owner && ast_channel_trylock(p->owner)) { 24864 sip_pvt_unlock(p); 24865 usleep(1); 24866 if (p->stimer && p->stimer->quit_flag) { 24867 goto return_unref; 24868 } 24869 sip_pvt_lock(p); 24870 } 24871 24872 ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV); 24873 ast_channel_unlock(p->owner); 24874 sip_pvt_unlock(p); 24875 } 24876 } 24877 24878 return_unref: 24879 if (!res) { 24880 /* An error occurred. Stop session timer processing */ 24881 if (p->stimer) { 24882 p->stimer->st_schedid = -1; 24883 stop_session_timer(p); 24884 } 24885 24886 /* If we are not asking to be rescheduled, then we need to release our 24887 * reference to the dialog. */ 24888 dialog_unref(p, "removing session timer ref"); 24889 } 24890 24891 return res; 24892 }
| static int process_crypto | ( | struct sip_pvt * | p, | |
| struct ast_rtp_instance * | rtp, | |||
| struct sip_srtp ** | srtp, | |||
| const char * | a | |||
| ) | [static] |
Definition at line 28322 of file chan_sip.c.
References ast_debug, ast_log(), ast_set_flag, ast_test_flag, FALSE, LOG_WARNING, setup_srtp(), and TRUE.
Referenced by process_sdp().
28323 { 28324 if (strncasecmp(a, "crypto:", 7)) { 28325 return FALSE; 28326 } 28327 if (!*srtp) { 28328 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 28329 ast_log(LOG_WARNING, "Ignoring unexpected crypto attribute in SDP answer\n"); 28330 return FALSE; 28331 } 28332 28333 if (setup_srtp(srtp) < 0) { 28334 return FALSE; 28335 } 28336 } 28337 28338 /* For now, when we receive an INVITE just take the first successful crypto line */ 28339 if ((*srtp)->crypto && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 28340 ast_debug(3, "We've already processed a crypto attribute, skipping '%s'\n", a); 28341 return FALSE; 28342 } 28343 28344 if (!(*srtp)->crypto && !((*srtp)->crypto = sdp_crypto_setup())) { 28345 return FALSE; 28346 } 28347 28348 if (sdp_crypto_process((*srtp)->crypto, a, rtp) < 0) { 28349 return FALSE; 28350 } 28351 28352 ast_set_flag(*srtp, SRTP_CRYPTO_OFFER_OK); 28353 28354 return TRUE; 28355 }
| static void process_request_queue | ( | struct sip_pvt * | p, | |
| int * | recount, | |||
| int * | nounlock | |||
| ) | [static] |
Definition at line 24069 of file chan_sip.c.
References ast_debug, ast_free, AST_LIST_REMOVE_HEAD, and handle_incoming().
Referenced by handle_request_do().
24070 { 24071 struct sip_request *req; 24072 24073 while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) { 24074 if (handle_incoming(p, req, &p->recv, recount, nounlock) == -1) { 24075 /* Request failed */ 24076 ast_debug(1, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 24077 } 24078 ast_free(req); 24079 } 24080 }
| static int process_sdp | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| int | t38action | |||
| ) | [static] |
Process SIP SDP offer, select formats and activate RTP channels If offer is rejected, we will not change any properties of the call Return 0 on success, a negative value on errors. Must be called after find_sdp().
< RTP Audio host IP
< RTP video host IP
< RTP text host IP
< UDPTL host ip
< RTP Audio port number
< RTP Video port number
< RTP Text port number
< UDPTL Image port number
Definition at line 8301 of file chan_sip.c.
References ast_async_goto(), ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_codec_choose(), AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, ast_copy_string(), ast_debug, ast_exists_extension(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_T140RED, ast_getformatname_multiple(), ast_log(), ast_null_frame, ast_queue_control(), ast_queue_control_data(), ast_queue_frame(), ast_rtp_codecs_payload_formats(), ast_rtp_codecs_payloads_clear(), ast_rtp_codecs_payloads_copy(), ast_rtp_codecs_payloads_set_m_type(), AST_RTP_DTMF, ast_rtp_instance_get_codecs(), ast_rtp_instance_get_remote_address(), ast_rtp_instance_set_prop(), ast_rtp_instance_set_remote_address(), ast_rtp_instance_stop(), ast_rtp_lookup_mime_multiple2(), AST_RTP_PROPERTY_DTMF, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_rtp_red_init(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), ast_skip_blanks(), ast_sockaddr_isnull(), ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_str_alloca, ast_strlen_zero(), ast_test_flag, ast_udptl_get_far_max_datagram(), ast_udptl_set_error_correction_scheme(), ast_udptl_set_far_max_datagram(), ast_udptl_set_peer(), ast_udptl_stop(), ast_verbose, change_hold_state(), change_t38_state(), debug, FALSE, get_sdp_iterate(), get_sdp_line(), len(), LOG_ERROR, LOG_NOTICE, LOG_WARNING, pbx_builtin_setvar_helper(), process_crypto(), process_sdp_a_audio(), process_sdp_a_image(), process_sdp_a_sendonly(), process_sdp_a_text(), process_sdp_a_video(), process_sdp_c(), process_sdp_o(), S_COR, S_OR, sip_debug_test_pvt(), text, TRUE, type, UDPTL_ERROR_CORRECTION_NONE, value, and VERBOSE_PREFIX_2.
08302 { 08303 /* Iterators for SDP parsing */ 08304 int start = req->sdp_start; 08305 int next = start; 08306 int iterator = start; 08307 08308 /* Temporary vars for SDP parsing */ 08309 char type = '\0'; 08310 const char *value = NULL; 08311 const char *m = NULL; /* SDP media offer */ 08312 const char *nextm = NULL; 08313 int len = -1; 08314 08315 /* Host information */ 08316 struct ast_sockaddr sessionsa; 08317 struct ast_sockaddr audiosa; 08318 struct ast_sockaddr videosa; 08319 struct ast_sockaddr textsa; 08320 struct ast_sockaddr imagesa; 08321 struct ast_sockaddr *sa = NULL; /*!< RTP Audio host IP */ 08322 struct ast_sockaddr *vsa = NULL; /*!< RTP video host IP */ 08323 struct ast_sockaddr *tsa = NULL; /*!< RTP text host IP */ 08324 struct ast_sockaddr *isa = NULL; /*!< UDPTL host ip */ 08325 int portno = -1; /*!< RTP Audio port number */ 08326 int vportno = -1; /*!< RTP Video port number */ 08327 int tportno = -1; /*!< RTP Text port number */ 08328 int udptlportno = -1; /*!< UDPTL Image port number */ 08329 08330 /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */ 08331 format_t peercapability = 0, vpeercapability = 0, tpeercapability = 0; 08332 int peernoncodeccapability = 0, vpeernoncodeccapability = 0, tpeernoncodeccapability = 0; 08333 08334 struct ast_rtp_codecs newaudiortp, newvideortp, newtextrtp; 08335 format_t newjointcapability; /* Negotiated capability */ 08336 format_t newpeercapability; 08337 int newnoncodeccapability; 08338 08339 const char *codecs; 08340 int codec; 08341 08342 /* SRTP */ 08343 int secure_audio = FALSE; 08344 int secure_video = FALSE; 08345 08346 /* Others */ 08347 int sendonly = -1; 08348 int vsendonly = -1; 08349 int numberofports; 08350 int numberofmediastreams = 0; 08351 int last_rtpmap_codec = 0; 08352 int red_data_pt[10]; /* For T.140 red */ 08353 int red_num_gen = 0; /* For T.140 red */ 08354 char red_fmtp[100] = "empty"; /* For T.140 red */ 08355 int debug = sip_debug_test_pvt(p); 08356 08357 /* START UNKNOWN */ 08358 char buf[SIPBUFSIZE]; 08359 /* END UNKNOWN */ 08360 08361 /* Initial check */ 08362 if (!p->rtp) { 08363 ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n"); 08364 return -1; 08365 } 08366 08367 /* Make sure that the codec structures are all cleared out */ 08368 ast_rtp_codecs_payloads_clear(&newaudiortp, NULL); 08369 ast_rtp_codecs_payloads_clear(&newvideortp, NULL); 08370 ast_rtp_codecs_payloads_clear(&newtextrtp, NULL); 08371 08372 /* Update our last rtprx when we receive an SDP, too */ 08373 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 08374 08375 memset(p->offered_media, 0, sizeof(p->offered_media)); 08376 08377 08378 /* default: novideo and notext set */ 08379 p->novideo = TRUE; 08380 p->notext = TRUE; 08381 08382 if (p->vrtp) { 08383 ast_rtp_codecs_payloads_clear(&newvideortp, NULL); 08384 } 08385 08386 if (p->trtp) { 08387 ast_rtp_codecs_payloads_clear(&newtextrtp, NULL); 08388 } 08389 08390 /* Scan for the first media stream (m=) line to limit scanning of globals */ 08391 nextm = get_sdp_iterate(&next, req, "m"); 08392 if (ast_strlen_zero(nextm)) { 08393 ast_log(LOG_WARNING, "Insufficient information for SDP (m= not found)\n"); 08394 return -1; 08395 } 08396 08397 /* Scan session level SDP parameters (lines before first media stream) */ 08398 while ((type = get_sdp_line(&iterator, next - 1, req, &value)) != '\0') { 08399 int processed = FALSE; 08400 switch (type) { 08401 case 'o': 08402 /* If we end up receiving SDP that doesn't actually modify the session we don't want to treat this as a fatal 08403 * error. We just want to ignore the SDP and let the rest of the packet be handled as normal. 08404 */ 08405 if (!process_sdp_o(value, p)) 08406 return (p->session_modify == FALSE) ? 0 : -1; 08407 break; 08408 case 'c': 08409 if (process_sdp_c(value, &sessionsa)) { 08410 processed = TRUE; 08411 sa = &sessionsa; 08412 vsa = sa; 08413 tsa = sa; 08414 isa = sa; 08415 } 08416 break; 08417 case 'a': 08418 if (process_sdp_a_sendonly(value, &sendonly)) { 08419 processed = TRUE; 08420 vsendonly = sendonly; 08421 } 08422 else if (process_sdp_a_audio(value, p, &newaudiortp, &last_rtpmap_codec)) 08423 processed = TRUE; 08424 else if (process_sdp_a_video(value, p, &newvideortp, &last_rtpmap_codec)) 08425 processed = TRUE; 08426 else if (process_sdp_a_text(value, p, &newtextrtp, red_fmtp, &red_num_gen, red_data_pt, &last_rtpmap_codec)) 08427 processed = TRUE; 08428 else if (process_sdp_a_image(value, p)) 08429 processed = TRUE; 08430 break; 08431 } 08432 08433 ast_debug(3, "Processing session-level SDP %c=%s... %s\n", type, value, (processed == TRUE)? "OK." : "UNSUPPORTED."); 08434 } 08435 08436 08437 08438 /* Scan media stream (m=) specific parameters loop */ 08439 while (!ast_strlen_zero(nextm)) { 08440 int audio = FALSE; 08441 int video = FALSE; 08442 int image = FALSE; 08443 int text = FALSE; 08444 char protocol[5] = {0,}; 08445 int x; 08446 08447 numberofports = 1; 08448 len = -1; 08449 start = next; 08450 m = nextm; 08451 iterator = next; 08452 nextm = get_sdp_iterate(&next, req, "m"); 08453 08454 /* Search for audio media definition */ 08455 if ((sscanf(m, "audio %30u/%30u RTP/%4s %n", &x, &numberofports, protocol, &len) == 3 && len > 0) || 08456 (sscanf(m, "audio %30u RTP/%4s %n", &x, protocol, &len) == 2 && len > 0)) { 08457 if (!strcmp(protocol, "SAVP")) { 08458 secure_audio = 1; 08459 } else if (strcmp(protocol, "AVP")) { 08460 ast_log(LOG_WARNING, "unknown SDP media protocol in offer: %s\n", protocol); 08461 continue; 08462 } 08463 audio = TRUE; 08464 p->offered_media[SDP_AUDIO].offered = TRUE; 08465 numberofmediastreams++; 08466 portno = x; 08467 08468 /* Scan through the RTP payload types specified in a "m=" line: */ 08469 codecs = m + len; 08470 ast_copy_string(p->offered_media[SDP_AUDIO].codecs, codecs, sizeof(p->offered_media[SDP_AUDIO].codecs)); 08471 for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 08472 if (sscanf(codecs, "%30u%n", &codec, &len) != 1) { 08473 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 08474 return -1; 08475 } 08476 if (debug) 08477 ast_verbose("Found RTP audio format %d\n", codec); 08478 08479 ast_rtp_codecs_payloads_set_m_type(&newaudiortp, NULL, codec); 08480 } 08481 /* Search for video media definition */ 08482 } else if ((sscanf(m, "video %30u/%30u RTP/%4s %n", &x, &numberofports, protocol, &len) == 3 && len > 0) || 08483 (sscanf(m, "video %30u RTP/%4s %n", &x, protocol, &len) == 2 && len >= 0)) { 08484 if (!strcmp(protocol, "SAVP")) { 08485 secure_video = 1; 08486 } else if (strcmp(protocol, "AVP")) { 08487 ast_log(LOG_WARNING, "unknown SDP media protocol in offer: %s\n", protocol); 08488 continue; 08489 } 08490 video = TRUE; 08491 p->novideo = FALSE; 08492 p->offered_media[SDP_VIDEO].offered = TRUE; 08493 numberofmediastreams++; 08494 vportno = x; 08495 08496 /* Scan through the RTP payload types specified in a "m=" line: */ 08497 codecs = m + len; 08498 ast_copy_string(p->offered_media[SDP_VIDEO].codecs, codecs, sizeof(p->offered_media[SDP_VIDEO].codecs)); 08499 for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 08500 if (sscanf(codecs, "%30u%n", &codec, &len) != 1) { 08501 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 08502 return -1; 08503 } 08504 if (debug) 08505 ast_verbose("Found RTP video format %d\n", codec); 08506 ast_rtp_codecs_payloads_set_m_type(&newvideortp, NULL, codec); 08507 } 08508 /* Search for text media definition */ 08509 } else if ((sscanf(m, "text %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 08510 (sscanf(m, "text %30u RTP/AVP %n", &x, &len) == 1 && len > 0)) { 08511 text = TRUE; 08512 p->notext = FALSE; 08513 p->offered_media[SDP_TEXT].offered = TRUE; 08514 numberofmediastreams++; 08515 tportno = x; 08516 08517 /* Scan through the RTP payload types specified in a "m=" line: */ 08518 codecs = m + len; 08519 ast_copy_string(p->offered_media[SDP_TEXT].codecs, codecs, sizeof(p->offered_media[SDP_TEXT].codecs)); 08520 for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 08521 if (sscanf(codecs, "%30u%n", &codec, &len) != 1) { 08522 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 08523 return -1; 08524 } 08525 if (debug) 08526 ast_verbose("Found RTP text format %d\n", codec); 08527 ast_rtp_codecs_payloads_set_m_type(&newtextrtp, NULL, codec); 08528 } 08529 /* Search for image media definition */ 08530 } else if (p->udptl && ((sscanf(m, "image %30u udptl t38%n", &x, &len) == 1 && len > 0) || 08531 (sscanf(m, "image %30u UDPTL t38%n", &x, &len) == 1 && len > 0) )) { 08532 image = TRUE; 08533 if (debug) 08534 ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid); 08535 p->offered_media[SDP_IMAGE].offered = TRUE; 08536 udptlportno = x; 08537 numberofmediastreams++; 08538 08539 if (p->t38.state != T38_ENABLED) { 08540 memset(&p->t38.their_parms, 0, sizeof(p->t38.their_parms)); 08541 08542 /* default EC to none, the remote end should 08543 * respond with the EC they want to use */ 08544 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 08545 } 08546 } else { 08547 ast_log(LOG_WARNING, "Unsupported SDP media type in offer: %s\n", m); 08548 continue; 08549 } 08550 08551 /* Check for number of ports */ 08552 if (numberofports > 1) 08553 ast_log(LOG_WARNING, "SDP offered %d ports for media, not supported by Asterisk. Will try anyway...\n", numberofports); 08554 08555 /* Media stream specific parameters */ 08556 while ((type = get_sdp_line(&iterator, next - 1, req, &value)) != '\0') { 08557 int processed = FALSE; 08558 08559 switch (type) { 08560 case 'c': 08561 if (audio) { 08562 if (process_sdp_c(value, &audiosa)) { 08563 processed = TRUE; 08564 sa = &audiosa; 08565 } 08566 } else if (video) { 08567 if (process_sdp_c(value, &videosa)) { 08568 processed = TRUE; 08569 vsa = &videosa; 08570 } 08571 } else if (text) { 08572 if (process_sdp_c(value, &textsa)) { 08573 processed = TRUE; 08574 tsa = &textsa; 08575 } 08576 } else if (image) { 08577 if (process_sdp_c(value, &imagesa)) { 08578 processed = TRUE; 08579 isa = &imagesa; 08580 } 08581 } 08582 break; 08583 case 'a': 08584 /* Audio specific scanning */ 08585 if (audio) { 08586 if (process_sdp_a_sendonly(value, &sendonly)) 08587 processed = TRUE; 08588 else if (process_crypto(p, p->rtp, &p->srtp, value)) 08589 processed = TRUE; 08590 else if (process_sdp_a_audio(value, p, &newaudiortp, &last_rtpmap_codec)) 08591 processed = TRUE; 08592 } 08593 /* Video specific scanning */ 08594 else if (video) { 08595 if (process_sdp_a_sendonly(value, &vsendonly)) 08596 processed = TRUE; 08597 else if (process_crypto(p, p->vrtp, &p->vsrtp, value)) 08598 processed = TRUE; 08599 else if (process_sdp_a_video(value, p, &newvideortp, &last_rtpmap_codec)) 08600 processed = TRUE; 08601 } 08602 /* Text (T.140) specific scanning */ 08603 else if (text) { 08604 if (process_sdp_a_text(value, p, &newtextrtp, red_fmtp, &red_num_gen, red_data_pt, &last_rtpmap_codec)) 08605 processed = TRUE; 08606 else if (process_crypto(p, p->trtp, &p->tsrtp, value)) 08607 processed = TRUE; 08608 } 08609 /* Image (T.38 FAX) specific scanning */ 08610 else if (image) { 08611 if (process_sdp_a_image(value, p)) 08612 processed = TRUE; 08613 } 08614 break; 08615 } 08616 08617 ast_debug(3, "Processing media-level (%s) SDP %c=%s... %s\n", 08618 (audio == TRUE)? "audio" : (video == TRUE)? "video" : "image", 08619 type, value, 08620 (processed == TRUE)? "OK." : "UNSUPPORTED."); 08621 } 08622 } 08623 08624 08625 /* Sanity checks */ 08626 if (!sa && !vsa && !tsa && !isa) { 08627 ast_log(LOG_WARNING, "Insufficient information in SDP (c=)...\n"); 08628 return -1; 08629 } 08630 08631 if (portno == -1 && vportno == -1 && udptlportno == -1 && tportno == -1) { 08632 /* No acceptable offer found in SDP - we have no ports */ 08633 /* Do not change RTP or VRTP if this is a re-invite */ 08634 ast_log(LOG_WARNING, "Failing due to no acceptable offer found\n"); 08635 return -2; 08636 } 08637 08638 if (numberofmediastreams > 3) { 08639 /* We have too many fax, audio and/or video and/or text media streams, fail this offer */ 08640 ast_log(LOG_WARNING, "Faling due to too many media streams\n"); 08641 return -3; 08642 } 08643 08644 if (secure_audio && !(p->srtp && (ast_test_flag(p->srtp, SRTP_CRYPTO_OFFER_OK)))) { 08645 ast_log(LOG_WARNING, "Can't provide secure audio requested in SDP offer\n"); 08646 return -4; 08647 } 08648 08649 if (!secure_audio && p->srtp) { 08650 ast_log(LOG_WARNING, "We are requesting SRTP, but they responded without it!\n"); 08651 return -4; 08652 } 08653 08654 if (secure_video && !(p->vsrtp && (ast_test_flag(p->vsrtp, SRTP_CRYPTO_OFFER_OK)))) { 08655 ast_log(LOG_WARNING, "Can't provide secure video requested in SDP offer\n"); 08656 return -4; 08657 } 08658 08659 if (!p->novideo && !secure_video && p->vsrtp) { 08660 ast_log(LOG_WARNING, "We are requesting SRTP, but they responded without it!\n"); 08661 return -4; 08662 } 08663 08664 if (!(secure_audio || secure_video) && ast_test_flag(&p->flags[1], SIP_PAGE2_USE_SRTP)) { 08665 ast_log(LOG_WARNING, "Matched device setup to use SRTP, but request was not!\n"); 08666 return -4; 08667 } 08668 08669 if (udptlportno == -1) { 08670 change_t38_state(p, T38_DISABLED); 08671 } 08672 08673 /* Now gather all of the codecs that we are asked for: */ 08674 ast_rtp_codecs_payload_formats(&newaudiortp, &peercapability, &peernoncodeccapability); 08675 ast_rtp_codecs_payload_formats(&newvideortp, &vpeercapability, &vpeernoncodeccapability); 08676 ast_rtp_codecs_payload_formats(&newtextrtp, &tpeercapability, &tpeernoncodeccapability); 08677 08678 newjointcapability = p->capability & (peercapability | vpeercapability | tpeercapability); 08679 newpeercapability = (peercapability | vpeercapability | tpeercapability); 08680 newnoncodeccapability = p->noncodeccapability & peernoncodeccapability; 08681 08682 if (debug) { 08683 /* shame on whoever coded this.... */ 08684 char s1[SIPBUFSIZE], s2[SIPBUFSIZE], s3[SIPBUFSIZE], s4[SIPBUFSIZE], s5[SIPBUFSIZE]; 08685 08686 ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s/text=%s, combined - %s\n", 08687 ast_getformatname_multiple(s1, SIPBUFSIZE, p->capability), 08688 ast_getformatname_multiple(s2, SIPBUFSIZE, peercapability), 08689 ast_getformatname_multiple(s3, SIPBUFSIZE, vpeercapability), 08690 ast_getformatname_multiple(s4, SIPBUFSIZE, tpeercapability), 08691 ast_getformatname_multiple(s5, SIPBUFSIZE, newjointcapability)); 08692 } 08693 if (debug) { 08694 struct ast_str *s1 = ast_str_alloca(SIPBUFSIZE); 08695 struct ast_str *s2 = ast_str_alloca(SIPBUFSIZE); 08696 struct ast_str *s3 = ast_str_alloca(SIPBUFSIZE); 08697 08698 ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n", 08699 ast_rtp_lookup_mime_multiple2(s1, p->noncodeccapability, 0, 0), 08700 ast_rtp_lookup_mime_multiple2(s2, peernoncodeccapability, 0, 0), 08701 ast_rtp_lookup_mime_multiple2(s3, newnoncodeccapability, 0, 0)); 08702 } 08703 if (!newjointcapability && (portno != -1)) { 08704 ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n"); 08705 /* Do NOT Change current setting */ 08706 return -1; 08707 } 08708 08709 /* Setup audio address and port */ 08710 if (p->rtp) { 08711 if (portno > 0) { 08712 ast_sockaddr_set_port(sa, portno); 08713 ast_rtp_instance_set_remote_address(p->rtp, sa); 08714 if (debug) { 08715 ast_verbose("Peer audio RTP is at port %s\n", 08716 ast_sockaddr_stringify(sa)); 08717 } 08718 /* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since 08719 they are acceptable */ 08720 p->jointcapability = newjointcapability; /* Our joint codec profile for this call */ 08721 p->peercapability = newpeercapability; /* The other sides capability in latest offer */ 08722 p->jointnoncodeccapability = newnoncodeccapability; /* DTMF capabilities */ 08723 08724 if (ast_test_flag(&p->flags[1], SIP_PAGE2_PREFERRED_CODEC)) { /* respond with single most preferred joint codec, limiting the other side's choice */ 08725 p->jointcapability = ast_codec_choose(&p->prefs, p->jointcapability, 1); 08726 } 08727 08728 ast_rtp_codecs_payloads_copy(&newaudiortp, ast_rtp_instance_get_codecs(p->rtp), p->rtp); 08729 08730 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) { 08731 ast_clear_flag(&p->flags[0], SIP_DTMF); 08732 if (newnoncodeccapability & AST_RTP_DTMF) { 08733 /* XXX Would it be reasonable to drop the DSP at this point? XXX */ 08734 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 08735 /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */ 08736 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF, 1); 08737 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 08738 } else { 08739 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 08740 } 08741 } 08742 } else if (udptlportno > 0) { 08743 if (debug) 08744 ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session.\n"); 08745 } else { 08746 ast_rtp_instance_stop(p->rtp); 08747 if (debug) 08748 ast_verbose("Peer doesn't provide audio\n"); 08749 } 08750 } 08751 08752 /* Setup video address and port */ 08753 if (p->vrtp) { 08754 if (vportno > 0) { 08755 ast_sockaddr_set_port(vsa, vportno); 08756 ast_rtp_instance_set_remote_address(p->vrtp, vsa); 08757 if (debug) { 08758 ast_verbose("Peer video RTP is at port %s\n", 08759 ast_sockaddr_stringify(vsa)); 08760 } 08761 ast_rtp_codecs_payloads_copy(&newvideortp, ast_rtp_instance_get_codecs(p->vrtp), p->vrtp); 08762 } else { 08763 ast_rtp_instance_stop(p->vrtp); 08764 if (debug) 08765 ast_verbose("Peer doesn't provide video\n"); 08766 } 08767 } 08768 08769 /* Setup text address and port */ 08770 if (p->trtp) { 08771 if (tportno > 0) { 08772 ast_sockaddr_set_port(tsa, tportno); 08773 ast_rtp_instance_set_remote_address(p->trtp, tsa); 08774 if (debug) { 08775 ast_verbose("Peer T.140 RTP is at port %s\n", 08776 ast_sockaddr_stringify(tsa)); 08777 } 08778 if ((p->jointcapability & AST_FORMAT_T140RED)) { 08779 p->red = 1; 08780 ast_rtp_red_init(p->trtp, 300, red_data_pt, 2); 08781 } else { 08782 p->red = 0; 08783 } 08784 ast_rtp_codecs_payloads_copy(&newtextrtp, ast_rtp_instance_get_codecs(p->trtp), p->trtp); 08785 } else { 08786 ast_rtp_instance_stop(p->trtp); 08787 if (debug) 08788 ast_verbose("Peer doesn't provide T.140\n"); 08789 } 08790 } 08791 /* Setup image address and port */ 08792 if (p->udptl) { 08793 if (udptlportno > 0) { 08794 if (ast_test_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP) && ast_test_flag(&p->flags[1], SIP_PAGE2_UDPTL_DESTINATION)) { 08795 ast_rtp_instance_get_remote_address(p->rtp, isa); 08796 if (!ast_sockaddr_isnull(isa) && debug) { 08797 ast_debug(1, "Peer T.38 UDPTL is set behind NAT and with destination, destination address now %s\n", ast_sockaddr_stringify(isa)); 08798 } 08799 } 08800 ast_sockaddr_set_port(isa, udptlportno); 08801 ast_udptl_set_peer(p->udptl, isa); 08802 if (debug) 08803 ast_debug(1,"Peer T.38 UDPTL is at port %s\n", ast_sockaddr_stringify(isa)); 08804 08805 /* verify the far max ifp can be calculated. this requires far max datagram to be set. */ 08806 if (!ast_udptl_get_far_max_datagram(p->udptl)) { 08807 /* setting to zero will force a default if none was provided by the SDP */ 08808 ast_udptl_set_far_max_datagram(p->udptl, 0); 08809 } 08810 08811 /* Remote party offers T38, we need to update state */ 08812 if ((t38action == SDP_T38_ACCEPT) && 08813 (p->t38.state == T38_LOCAL_REINVITE)) { 08814 change_t38_state(p, T38_ENABLED); 08815 } else if ((t38action == SDP_T38_INITIATE) && 08816 p->owner && p->lastinvite) { 08817 change_t38_state(p, T38_PEER_REINVITE); /* T38 Offered in re-invite from remote party */ 08818 /* If fax detection is enabled then send us off to the fax extension */ 08819 if (ast_test_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_T38)) { 08820 ast_channel_lock(p->owner); 08821 if (strcmp(p->owner->exten, "fax")) { 08822 const char *target_context = S_OR(p->owner->macrocontext, p->owner->context); 08823 ast_channel_unlock(p->owner); 08824 if (ast_exists_extension(p->owner, target_context, "fax", 1, 08825 S_COR(p->owner->caller.id.number.valid, p->owner->caller.id.number.str, NULL))) { 08826 ast_verbose(VERBOSE_PREFIX_2 "Redirecting '%s' to fax extension due to peer T.38 re-INVITE\n", p->owner->name); 08827 pbx_builtin_setvar_helper(p->owner, "FAXEXTEN", p->owner->exten); 08828 if (ast_async_goto(p->owner, target_context, "fax", 1)) { 08829 ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", p->owner->name, target_context); 08830 } 08831 } else { 08832 ast_log(LOG_NOTICE, "T.38 re-INVITE detected but no fax extension\n"); 08833 } 08834 } else { 08835 ast_channel_unlock(p->owner); 08836 } 08837 } 08838 } 08839 } else { 08840 ast_udptl_stop(p->udptl); 08841 if (debug) 08842 ast_debug(1, "Peer doesn't provide T.38 UDPTL\n"); 08843 } 08844 } 08845 08846 if ((portno == -1) && (p->t38.state != T38_DISABLED)) { 08847 ast_debug(3, "Have T.38 but no audio, accepting offer anyway\n"); 08848 return 0; 08849 } 08850 08851 /* Ok, we're going with this offer */ 08852 ast_debug(2, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, p->jointcapability)); 08853 08854 if (!p->owner) /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */ 08855 return 0; 08856 08857 ast_debug(4, "We have an owner, now see if we need to change this call\n"); 08858 08859 if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 08860 if (debug) { 08861 char s1[SIPBUFSIZE], s2[SIPBUFSIZE]; 08862 ast_debug(1, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n", 08863 ast_getformatname_multiple(s1, SIPBUFSIZE, p->jointcapability), 08864 ast_getformatname_multiple(s2, SIPBUFSIZE, p->owner->nativeformats)); 08865 } 08866 p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability) | (p->capability & tpeercapability); 08867 ast_set_read_format(p->owner, p->owner->readformat); 08868 ast_set_write_format(p->owner, p->owner->writeformat); 08869 } 08870 08871 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)) { 08872 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 08873 /* Activate a re-invite */ 08874 ast_queue_frame(p->owner, &ast_null_frame); 08875 change_hold_state(p, req, FALSE, sendonly); 08876 } else if ((ast_sockaddr_isnull(sa) && ast_sockaddr_isnull(vsa) && ast_sockaddr_isnull(tsa) && ast_sockaddr_isnull(isa)) || (sendonly && sendonly != -1)) { 08877 ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 08878 S_OR(p->mohsuggest, NULL), 08879 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 08880 if (sendonly) 08881 ast_rtp_instance_stop(p->rtp); 08882 /* RTCP needs to go ahead, even if we're on hold!!! */ 08883 /* Activate a re-invite */ 08884 ast_queue_frame(p->owner, &ast_null_frame); 08885 change_hold_state(p, req, TRUE, sendonly); 08886 } 08887 08888 return 0; 08889 }
| 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 9017 of file chan_sip.c.
References ast_codec_pref_setsize(), ast_debug, AST_FORMAT_G719, AST_FORMAT_SIREN14, AST_FORMAT_SIREN7, ast_getformatname(), ast_log(), ast_rtp_codecs_packetization_set(), ast_rtp_codecs_payload_lookup(), ast_rtp_codecs_payloads_set_rtpmap_type_rate(), ast_rtp_codecs_payloads_unset(), ast_rtp_instance_get_codecs(), AST_RTP_MAX_PT, AST_RTP_OPT_G726_NONSTANDARD, ast_test_flag, ast_verbose, debug, FALSE, format, LOG_WARNING, ast_rtp_codecs::pref, sip_debug_test_pvt(), and TRUE.
Referenced by process_sdp().
09018 { 09019 int found = FALSE; 09020 int codec; 09021 char mimeSubtype[128]; 09022 char fmtp_string[64]; 09023 unsigned int sample_rate; 09024 int debug = sip_debug_test_pvt(p); 09025 09026 if (!strncasecmp(a, "ptime", 5)) { 09027 char *tmp = strrchr(a, ':'); 09028 long int framing = 0; 09029 if (tmp) { 09030 tmp++; 09031 framing = strtol(tmp, NULL, 10); 09032 if (framing == LONG_MIN || framing == LONG_MAX) { 09033 framing = 0; 09034 ast_debug(1, "Can't read framing from SDP: %s\n", a); 09035 } 09036 } 09037 if (framing && p->autoframing) { 09038 struct ast_codec_pref *pref = &ast_rtp_instance_get_codecs(p->rtp)->pref; 09039 int codec_n; 09040 for (codec_n = 0; codec_n < AST_RTP_MAX_PT; codec_n++) { 09041 struct ast_rtp_payload_type format = ast_rtp_codecs_payload_lookup(ast_rtp_instance_get_codecs(p->rtp), codec_n); 09042 if (!format.asterisk_format || !format.code) /* non-codec or not found */ 09043 continue; 09044 ast_debug(1, "Setting framing for %s to %ld\n", ast_getformatname(format.code), framing); 09045 ast_codec_pref_setsize(pref, format.code, framing); 09046 } 09047 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, pref); 09048 } 09049 found = TRUE; 09050 } else if (sscanf(a, "rtpmap: %30u %127[^/]/%30u", &codec, mimeSubtype, &sample_rate) == 3) { 09051 /* We have a rtpmap to handle */ 09052 if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 09053 if (ast_rtp_codecs_payloads_set_rtpmap_type_rate(newaudiortp, NULL, codec, "audio", mimeSubtype, 09054 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0, sample_rate) != -1) { 09055 if (debug) 09056 ast_verbose("Found audio description format %s for ID %d\n", mimeSubtype, codec); 09057 //found_rtpmap_codecs[last_rtpmap_codec] = codec; 09058 (*last_rtpmap_codec)++; 09059 found = TRUE; 09060 } else { 09061 ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec); 09062 if (debug) 09063 ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec); 09064 } 09065 } else { 09066 if (debug) 09067 ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec); 09068 } 09069 } else if (sscanf(a, "fmtp: %30u %63s", &codec, fmtp_string) == 2) { 09070 struct ast_rtp_payload_type payload; 09071 09072 payload = ast_rtp_codecs_payload_lookup(newaudiortp, codec); 09073 if (payload.code && payload.asterisk_format) { 09074 unsigned int bit_rate; 09075 09076 switch (payload.code) { 09077 case AST_FORMAT_SIREN7: 09078 if (sscanf(fmtp_string, "bitrate=%30u", &bit_rate) == 1) { 09079 if (bit_rate != 32000) { 09080 ast_log(LOG_WARNING, "Got Siren7 offer at %d bps, but only 32000 bps supported; ignoring.\n", bit_rate); 09081 ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec); 09082 } else { 09083 found = TRUE; 09084 } 09085 } 09086 break; 09087 case AST_FORMAT_SIREN14: 09088 if (sscanf(fmtp_string, "bitrate=%30u", &bit_rate) == 1) { 09089 if (bit_rate != 48000) { 09090 ast_log(LOG_WARNING, "Got Siren14 offer at %d bps, but only 48000 bps supported; ignoring.\n", bit_rate); 09091 ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec); 09092 } else { 09093 found = TRUE; 09094 } 09095 } 09096 break; 09097 case AST_FORMAT_G719: 09098 if (sscanf(fmtp_string, "bitrate=%30u", &bit_rate) == 1) { 09099 if (bit_rate != 64000) { 09100 ast_log(LOG_WARNING, "Got G.719 offer at %d bps, but only 64000 bps supported; ignoring.\n", bit_rate); 09101 ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec); 09102 } else { 09103 found = TRUE; 09104 } 09105 } 09106 } 09107 } 09108 } 09109 09110 return found; 09111 }
| static int process_sdp_a_image | ( | const char * | a, | |
| struct sip_pvt * | p | |||
| ) | [static] |
Definition at line 9196 of file chan_sip.c.
References ast_debug, AST_T38_RATE_12000, AST_T38_RATE_14400, AST_T38_RATE_2400, AST_T38_RATE_4800, AST_T38_RATE_7200, AST_T38_RATE_9600, AST_T38_RATE_MANAGEMENT_LOCAL_TCF, AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF, ast_udptl_set_error_correction_scheme(), ast_udptl_set_far_max_datagram(), FALSE, TRUE, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, and UDPTL_ERROR_CORRECTION_REDUNDANCY.
Referenced by process_sdp().
09197 { 09198 int found = FALSE; 09199 char s[256]; 09200 unsigned int x; 09201 09202 if ((sscanf(a, "T38FaxMaxBuffer:%30u", &x) == 1)) { 09203 ast_debug(3, "MaxBufferSize:%d\n", x); 09204 found = TRUE; 09205 } else if ((sscanf(a, "T38MaxBitRate:%30u", &x) == 1) || (sscanf(a, "T38FaxMaxRate:%30u", &x) == 1)) { 09206 ast_debug(3, "T38MaxBitRate: %d\n", x); 09207 switch (x) { 09208 case 14400: 09209 p->t38.their_parms.rate = AST_T38_RATE_14400; 09210 break; 09211 case 12000: 09212 p->t38.their_parms.rate = AST_T38_RATE_12000; 09213 break; 09214 case 9600: 09215 p->t38.their_parms.rate = AST_T38_RATE_9600; 09216 break; 09217 case 7200: 09218 p->t38.their_parms.rate = AST_T38_RATE_7200; 09219 break; 09220 case 4800: 09221 p->t38.their_parms.rate = AST_T38_RATE_4800; 09222 break; 09223 case 2400: 09224 p->t38.their_parms.rate = AST_T38_RATE_2400; 09225 break; 09226 } 09227 found = TRUE; 09228 } else if ((sscanf(a, "T38FaxVersion:%30u", &x) == 1)) { 09229 ast_debug(3, "FaxVersion: %u\n", x); 09230 p->t38.their_parms.version = x; 09231 found = TRUE; 09232 } else if ((sscanf(a, "T38FaxMaxDatagram:%30u", &x) == 1) || (sscanf(a, "T38MaxDatagram:%30u", &x) == 1)) { 09233 /* override the supplied value if the configuration requests it */ 09234 if (((signed int) p->t38_maxdatagram >= 0) && ((unsigned int) p->t38_maxdatagram > x)) { 09235 ast_debug(1, "Overriding T38FaxMaxDatagram '%d' with '%d'\n", x, p->t38_maxdatagram); 09236 x = p->t38_maxdatagram; 09237 } 09238 ast_debug(3, "FaxMaxDatagram: %u\n", x); 09239 ast_udptl_set_far_max_datagram(p->udptl, x); 09240 found = TRUE; 09241 } else if ((strncmp(a, "T38FaxFillBitRemoval", 20) == 0)) { 09242 if (sscanf(a, "T38FaxFillBitRemoval:%30u", &x) == 1) { 09243 ast_debug(3, "FillBitRemoval: %d\n", x); 09244 if (x == 1) { 09245 p->t38.their_parms.fill_bit_removal = TRUE; 09246 } 09247 } else { 09248 ast_debug(3, "FillBitRemoval\n"); 09249 p->t38.their_parms.fill_bit_removal = TRUE; 09250 } 09251 found = TRUE; 09252 } else if ((strncmp(a, "T38FaxTranscodingMMR", 20) == 0)) { 09253 if (sscanf(a, "T38FaxTranscodingMMR:%30u", &x) == 1) { 09254 ast_debug(3, "Transcoding MMR: %d\n", x); 09255 if (x == 1) { 09256 p->t38.their_parms.transcoding_mmr = TRUE; 09257 } 09258 } else { 09259 ast_debug(3, "Transcoding MMR\n"); 09260 p->t38.their_parms.transcoding_mmr = TRUE; 09261 } 09262 found = TRUE; 09263 } else if ((strncmp(a, "T38FaxTranscodingJBIG", 21) == 0)) { 09264 if (sscanf(a, "T38FaxTranscodingJBIG:%30u", &x) == 1) { 09265 ast_debug(3, "Transcoding JBIG: %d\n", x); 09266 if (x == 1) { 09267 p->t38.their_parms.transcoding_jbig = TRUE; 09268 } 09269 } else { 09270 ast_debug(3, "Transcoding JBIG\n"); 09271 p->t38.their_parms.transcoding_jbig = TRUE; 09272 } 09273 found = TRUE; 09274 } else if ((sscanf(a, "T38FaxRateManagement:%255s", s) == 1)) { 09275 ast_debug(3, "RateManagement: %s\n", s); 09276 if (!strcasecmp(s, "localTCF")) 09277 p->t38.their_parms.rate_management = AST_T38_RATE_MANAGEMENT_LOCAL_TCF; 09278 else if (!strcasecmp(s, "transferredTCF")) 09279 p->t38.their_parms.rate_management = AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF; 09280 found = TRUE; 09281 } else if ((sscanf(a, "T38FaxUdpEC:%255s", s) == 1)) { 09282 ast_debug(3, "UDP EC: %s\n", s); 09283 if (!strcasecmp(s, "t38UDPRedundancy")) { 09284 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY); 09285 } else if (!strcasecmp(s, "t38UDPFEC")) { 09286 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC); 09287 } else { 09288 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 09289 } 09290 found = TRUE; 09291 } 09292 09293 return found; 09294 }
| static int process_sdp_a_sendonly | ( | const char * | a, | |
| int * | sendonly | |||
| ) | [static] |
Definition at line 8997 of file chan_sip.c.
Referenced by process_sdp().
08998 { 08999 int found = FALSE; 09000 09001 if (!strcasecmp(a, "sendonly")) { 09002 if (*sendonly == -1) 09003 *sendonly = 1; 09004 found = TRUE; 09005 } else if (!strcasecmp(a, "inactive")) { 09006 if (*sendonly == -1) 09007 *sendonly = 2; 09008 found = TRUE; 09009 } else if (!strcasecmp(a, "sendrecv")) { 09010 if (*sendonly == -1) 09011 *sendonly = 0; 09012 found = TRUE; 09013 } 09014 return found; 09015 }
| 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 9147 of file chan_sip.c.
References AST_RED_MAX_GENERATION, ast_rtp_codecs_payloads_set_rtpmap_type_rate(), ast_verbose, debug, FALSE, sip_debug_test_pvt(), and TRUE.
Referenced by process_sdp().
09148 { 09149 int found = FALSE; 09150 int codec; 09151 char mimeSubtype[128]; 09152 unsigned int sample_rate; 09153 char *red_cp; 09154 int debug = sip_debug_test_pvt(p); 09155 09156 if (sscanf(a, "rtpmap: %30u %127[^/]/%30u", &codec, mimeSubtype, &sample_rate) == 3) { 09157 /* We have a rtpmap to handle */ 09158 if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 09159 if (!strncasecmp(mimeSubtype, "T140", 4)) { /* Text */ 09160 if (p->trtp) { 09161 /* ast_verbose("Adding t140 mimeSubtype to textrtp struct\n"); */ 09162 ast_rtp_codecs_payloads_set_rtpmap_type_rate(newtextrtp, NULL, codec, "text", mimeSubtype, 0, sample_rate); 09163 found = TRUE; 09164 } 09165 } else if (!strncasecmp(mimeSubtype, "RED", 3)) { /* Text with Redudancy */ 09166 if (p->trtp) { 09167 ast_rtp_codecs_payloads_set_rtpmap_type_rate(newtextrtp, NULL, codec, "text", mimeSubtype, 0, sample_rate); 09168 sprintf(red_fmtp, "fmtp:%d ", codec); 09169 if (debug) 09170 ast_verbose("RED submimetype has payload type: %d\n", codec); 09171 found = TRUE; 09172 } 09173 } 09174 } else { 09175 if (debug) 09176 ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec); 09177 } 09178 } else if (!strncmp(a, red_fmtp, strlen(red_fmtp))) { 09179 /* count numbers of generations in fmtp */ 09180 red_cp = &red_fmtp[strlen(red_fmtp)]; 09181 strncpy(red_fmtp, a, 100); 09182 09183 sscanf(red_cp, "%30u", &red_data_pt[*red_num_gen]); 09184 red_cp = strtok(red_cp, "/"); 09185 while (red_cp && (*red_num_gen)++ < AST_RED_MAX_GENERATION) { 09186 sscanf(red_cp, "%30u", &red_data_pt[*red_num_gen]); 09187 red_cp = strtok(NULL, "/"); 09188 } 09189 red_cp = red_fmtp; 09190 found = TRUE; 09191 } 09192 09193 return found; 09194 }
| 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 9113 of file chan_sip.c.
References ast_rtp_codecs_payloads_set_rtpmap_type_rate(), ast_rtp_codecs_payloads_unset(), ast_verbose, debug, FALSE, sip_debug_test_pvt(), and TRUE.
Referenced by process_sdp().
09114 { 09115 int found = FALSE; 09116 int codec; 09117 char mimeSubtype[128]; 09118 unsigned int sample_rate; 09119 int debug = sip_debug_test_pvt(p); 09120 09121 if (sscanf(a, "rtpmap: %30u %127[^/]/%30u", &codec, mimeSubtype, &sample_rate) == 3) { 09122 /* We have a rtpmap to handle */ 09123 if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 09124 /* Note: should really look at the '#chans' params too */ 09125 if (!strncasecmp(mimeSubtype, "H26", 3) || !strncasecmp(mimeSubtype, "MP4", 3)) { 09126 if (ast_rtp_codecs_payloads_set_rtpmap_type_rate(newvideortp, NULL, codec, "video", mimeSubtype, 0, sample_rate) != -1) { 09127 if (debug) 09128 ast_verbose("Found video description format %s for ID %d\n", mimeSubtype, codec); 09129 //found_rtpmap_codecs[last_rtpmap_codec] = codec; 09130 (*last_rtpmap_codec)++; 09131 found = TRUE; 09132 } else { 09133 ast_rtp_codecs_payloads_unset(newvideortp, NULL, codec); 09134 if (debug) 09135 ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec); 09136 } 09137 } 09138 } else { 09139 if (debug) 09140 ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec); 09141 } 09142 } 09143 09144 return found; 09145 }
| static int process_sdp_c | ( | const char * | c, | |
| struct ast_sockaddr * | addr | |||
| ) | [static] |
Definition at line 8970 of file chan_sip.c.
References ast_log(), ast_sockaddr_resolve_first_af(), FALSE, LOG_WARNING, and TRUE.
Referenced by process_sdp().
08971 { 08972 char proto[4], host[258]; 08973 int af; 08974 08975 /* Check for Media-description-level-address */ 08976 if (sscanf(c, "IN %3s %255s", proto, host) == 2) { 08977 if (!strcmp("IP4", proto)) { 08978 af = AF_INET; 08979 } else if (!strcmp("IP6", proto)) { 08980 af = AF_INET6; 08981 } else { 08982 ast_log(LOG_WARNING, "Unknown protocol '%s'.\n", proto); 08983 return FALSE; 08984 } 08985 if (ast_sockaddr_resolve_first_af(addr, host, 0, af)) { 08986 ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in c= line, '%s'\n", c); 08987 return FALSE; 08988 } 08989 return TRUE; 08990 } else { 08991 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 08992 return FALSE; 08993 } 08994 return FALSE; 08995 }
| static int process_sdp_o | ( | const char * | o, | |
| struct sip_pvt * | p | |||
| ) | [static] |
Definition at line 8891 of file chan_sip.c.
References ast_debug, ast_log(), ast_strdupa, ast_strlen_zero(), ast_test_flag, FALSE, LOG_WARNING, strsep(), and TRUE.
Referenced by process_sdp().
08892 { 08893 char *o_copy; 08894 char *token; 08895 int64_t rua_version; 08896 08897 /* Store the SDP version number of remote UA. This will allow us to 08898 distinguish between session modifications and session refreshes. If 08899 the remote UA does not send an incremented SDP version number in a 08900 subsequent RE-INVITE then that means its not changing media session. 08901 The RE-INVITE may have been sent to update connected party, remote 08902 target or to refresh the session (Session-Timers). Asterisk must not 08903 change media session and increment its own version number in answer 08904 SDP in this case. */ 08905 08906 p->session_modify = TRUE; 08907 08908 if (ast_strlen_zero(o)) { 08909 ast_log(LOG_WARNING, "SDP syntax error. SDP without an o= line\n"); 08910 return FALSE; 08911 } 08912 08913 o_copy = ast_strdupa(o); 08914 token = strsep(&o_copy, " "); /* Skip username */ 08915 if (!o_copy) { 08916 ast_log(LOG_WARNING, "SDP syntax error in o= line username\n"); 08917 return FALSE; 08918 } 08919 token = strsep(&o_copy, " "); /* Skip session-id */ 08920 if (!o_copy) { 08921 ast_log(LOG_WARNING, "SDP syntax error in o= line session-id\n"); 08922 return FALSE; 08923 } 08924 token = strsep(&o_copy, " "); /* Version */ 08925 if (!o_copy) { 08926 ast_log(LOG_WARNING, "SDP syntax error in o= line\n"); 08927 return FALSE; 08928 } 08929 if (!sscanf(token, "%30" SCNd64, &rua_version)) { 08930 ast_log(LOG_WARNING, "SDP syntax error in o= line version\n"); 08931 return FALSE; 08932 } 08933 08934 /* we need to check the SDP version number the other end sent us; 08935 * our rules for deciding what to accept are a bit complex. 08936 * 08937 * 1) if 'ignoresdpversion' has been set for this dialog, then 08938 * we will just accept whatever they sent and assume it is 08939 * a modification of the session, even if it is not 08940 * 2) otherwise, if this is the first SDP we've seen from them 08941 * we accept it 08942 * 3) otherwise, if the new SDP version number is higher than the 08943 * old one, we accept it 08944 * 4) otherwise, if this SDP is in response to us requesting a switch 08945 * to T.38, we accept the SDP, but also generate a warning message 08946 * that this peer should have the 'ignoresdpversion' option set, 08947 * because it is not following the SDP offer/answer RFC; if we did 08948 * not request a switch to T.38, then we stop parsing the SDP, as it 08949 * has not changed from the previous version 08950 */ 08951 08952 if (ast_test_flag(&p->flags[1], SIP_PAGE2_IGNORESDPVERSION) || 08953 (p->sessionversion_remote < 0) || 08954 (p->sessionversion_remote < rua_version)) { 08955 p->sessionversion_remote = rua_version; 08956 } else { 08957 if (p->t38.state == T38_LOCAL_REINVITE) { 08958 p->sessionversion_remote = rua_version; 08959 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); 08960 } else { 08961 p->session_modify = FALSE; 08962 ast_debug(2, "Call %s responded to our reinvite without changing SDP version; ignoring SDP.\n", p->callid); 08963 return FALSE; 08964 } 08965 } 08966 08967 return TRUE; 08968 }
| static int process_via | ( | struct sip_pvt * | p, | |
| const struct sip_request * | req | |||
| ) | [static] |
Process the Via header according to RFC 3261 section 18.2.2.
| p | a sip_pvt structure that will be modified according to the received header | |
| req | a sip request with a Via header to process |
| -1 | error | |
| 0 | success |
Definition at line 7415 of file chan_sip.c.
References addr_is_multicast(), ast_log(), ast_sockaddr_resolve_first(), ast_sockaddr_set_port, get_header(), LOG_ERROR, LOG_WARNING, PARSE_PORT_FORBID, and sipsock.
Referenced by respprep().
07416 { 07417 struct sip_via *via = parse_via(get_header(req, "Via")); 07418 07419 if (!via) { 07420 ast_log(LOG_ERROR, "error processing via header\n"); 07421 return -1; 07422 } 07423 07424 if (via->maddr) { 07425 if (ast_sockaddr_resolve_first(&p->sa, via->maddr, PARSE_PORT_FORBID)) { 07426 ast_log(LOG_WARNING, "Can't find address for maddr '%s'\n", via->maddr); 07427 ast_log(LOG_ERROR, "error processing via header\n"); 07428 free_via(via); 07429 return -1; 07430 } 07431 07432 if (addr_is_multicast(&p->sa)) { 07433 setsockopt(sipsock, IPPROTO_IP, IP_MULTICAST_TTL, &via->ttl, sizeof(via->ttl)); 07434 } 07435 } 07436 07437 ast_sockaddr_set_port(&p->sa, via->port ? via->port : STANDARD_SIP_PORT); 07438 07439 free_via(via); 07440 return 0; 07441 }
| static int proxy_update | ( | struct sip_proxy * | proxy | ) | [static] |
Resolve DNS srv name or host name in a sip_proxy structure
Definition at line 3006 of file chan_sip.c.
References ast_get_ip_or_srv(), ast_log(), ast_sockaddr_parse(), ast_sockaddr_set_port, bindaddr, FALSE, get_address_family_filter(), LOG_WARNING, sip_cfg, and TRUE.
Referenced by build_peer().
03007 { 03008 /* if it's actually an IP address and not a name, 03009 there's no need for a managed lookup */ 03010 if (!ast_sockaddr_parse(&proxy->ip, proxy->name, 0)) { 03011 /* Ok, not an IP address, then let's check if it's a domain or host */ 03012 /* XXX Todo - if we have proxy port, don't do SRV */ 03013 proxy->ip.ss.ss_family = get_address_family_filter(&bindaddr); /* Filter address family */ 03014 if (ast_get_ip_or_srv(&proxy->ip, proxy->name, sip_cfg.srvlookup ? "_sip._udp" : NULL) < 0) { 03015 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", proxy->name); 03016 return FALSE; 03017 } 03018 03019 } 03020 03021 ast_sockaddr_set_port(&proxy->ip, proxy->port); 03022 03023 proxy->last_dnsupdate = time(NULL); 03024 return TRUE; 03025 }
| static int publish_expire | ( | const void * | data | ) | [static] |
Definition at line 1005 of file chan_sip.c.
References ao2_ref, ao2_unlink, ast_assert, event_state_compositor::compositor, and get_esc().
Referenced by create_esc_entry(), handle_sip_publish_modify(), and handle_sip_publish_refresh().
01006 { 01007 struct sip_esc_entry *esc_entry = (struct sip_esc_entry *) data; 01008 struct event_state_compositor *esc = get_esc(esc_entry->event); 01009 01010 ast_assert(esc != NULL); 01011 01012 ao2_unlink(esc->compositor, esc_entry); 01013 ao2_ref(esc_entry, -1); 01014 return 0; 01015 }
| static void pvt_set_needdestroy | ( | struct sip_pvt * | pvt, | |
| const char * | reason | |||
| ) | [inline, static] |
Definition at line 2971 of file chan_sip.c.
References append_history.
Referenced by __sip_autodestruct(), handle_incoming(), handle_request_refer(), handle_request_subscribe(), handle_response(), handle_response_invite(), handle_response_notify(), handle_response_peerpoke(), handle_response_publish(), handle_response_refer(), handle_response_register(), handle_response_subscribe(), retrans_pkt(), sip_hangup(), and sip_reg_timeout().
02972 { 02973 if (pvt->final_destruction_scheduled) { 02974 return; /* This is already scheduled for final destruction, let the scheduler take care of it. */ 02975 } 02976 append_history(pvt, "NeedDestroy", "Setting needdestroy because %s", reason); 02977 pvt->needdestroy = 1; 02978 }
| static int queue_request | ( | struct sip_pvt * | p, | |
| const struct sip_request * | req | |||
| ) | [static] |
Definition at line 24137 of file chan_sip.c.
References ast_calloc, AST_LIST_INSERT_TAIL, ast_sched_add(), copy_request(), and scheduler_process_request_queue().
Referenced by handle_request_do().
24138 { 24139 struct sip_request *newreq; 24140 24141 if (!(newreq = ast_calloc(1, sizeof(*newreq)))) { 24142 return -1; 24143 } 24144 24145 copy_request(newreq, req); 24146 AST_LIST_INSERT_TAIL(&p->request_queue, newreq, next); 24147 if (p->request_queue_sched_id == -1) { 24148 if ((p->request_queue_sched_id = ast_sched_add(sched, 10, scheduler_process_request_queue, dialog_ref(p, "Increment refcount to pass dialog pointer to sched callback"))) == -1) { 24149 dialog_unref(p, "Decrement refcount due to sched_add failure"); 24150 } 24151 } 24152 24153 return 0; 24154 }
| static struct sip_peer * realtime_peer | ( | const char * | peername, | |
| struct ast_sockaddr * | sin, | |||
| 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.
Definition at line 4564 of file chan_sip.c.
References ast_check_realtime(), ast_free, ast_load_realtime(), ast_sockaddr_cmp(), ast_sockaddr_resolve(), ast_sockaddr_stringify_addr(), ast_variables_destroy(), bindaddr, get_address_family_filter(), ipaddr, ast_variable::name, ast_variable::next, PARSE_PORT_FORBID, SENTINEL, ast_variable::value, and var.
04565 { 04566 struct sip_peer *peer; 04567 struct ast_variable *var = NULL; 04568 struct ast_variable *varregs = NULL; 04569 struct ast_variable *tmp; 04570 struct ast_config *peerlist = NULL; 04571 char ipaddr[INET6_ADDRSTRLEN]; 04572 char portstring[6]; /*up to 5 digits plus null terminator*/ 04573 char *cat = NULL; 04574 int realtimeregs = ast_check_realtime("sipregs"); 04575 04576 /* First check on peer name */ 04577 if (newpeername) { 04578 if (realtimeregs) 04579 varregs = ast_load_realtime("sipregs", "name", newpeername, SENTINEL); 04580 04581 var = ast_load_realtime("sippeers", "name", newpeername, "host", "dynamic", SENTINEL); 04582 if (!var && addr) { 04583 var = ast_load_realtime("sippeers", "name", newpeername, "host", ast_sockaddr_stringify_addr(addr), SENTINEL); 04584 } 04585 if (!var) { 04586 var = ast_load_realtime("sippeers", "name", newpeername, SENTINEL); 04587 /*!\note 04588 * If this one loaded something, then we need to ensure that the host 04589 * field matched. The only reason why we can't have this as a criteria 04590 * is because we only have the IP address and the host field might be 04591 * set as a name (and the reverse PTR might not match). 04592 */ 04593 if (var && addr) { 04594 for (tmp = var; tmp; tmp = tmp->next) { 04595 if (!strcasecmp(tmp->name, "host")) { 04596 struct ast_sockaddr *addrs = NULL; 04597 04598 if (ast_sockaddr_resolve(&addrs, 04599 tmp->value, 04600 PARSE_PORT_FORBID, 04601 get_address_family_filter(&bindaddr)) <= 0 || 04602 ast_sockaddr_cmp(&addrs[0], addr)) { 04603 /* No match */ 04604 ast_variables_destroy(var); 04605 var = NULL; 04606 } 04607 ast_free(addrs); 04608 break; 04609 } 04610 } 04611 } 04612 } 04613 } 04614 04615 if (!var && addr) { /* Then check on IP address for dynamic peers */ 04616 ast_copy_string(ipaddr, ast_sockaddr_stringify_addr(addr), sizeof(ipaddr)); 04617 ast_copy_string(portstring, ast_sockaddr_stringify_port(addr), sizeof(portstring)); 04618 var = ast_load_realtime("sippeers", "host", ipaddr, "port", portstring, SENTINEL); /* First check for fixed IP hosts */ 04619 if (var) { 04620 if (realtimeregs) { 04621 newpeername = get_name_from_variable(var, newpeername); 04622 varregs = ast_load_realtime("sipregs", "name", newpeername, SENTINEL); 04623 } 04624 } else { 04625 if (realtimeregs) 04626 varregs = ast_load_realtime("sipregs", "ipaddr", ipaddr, "port", portstring, SENTINEL); /* Then check for registered hosts */ 04627 else 04628 var = ast_load_realtime("sippeers", "ipaddr", ipaddr, "port", portstring, SENTINEL); /* Then check for registered hosts */ 04629 if (varregs) { 04630 newpeername = get_name_from_variable(varregs, newpeername); 04631 var = ast_load_realtime("sippeers", "name", newpeername, SENTINEL); 04632 } 04633 } 04634 if (!var) { /*We couldn't match on ipaddress and port, so we need to check if port is insecure*/ 04635 peerlist = ast_load_realtime_multientry("sippeers", "host", ipaddr, SENTINEL); 04636 if (peerlist) { 04637 var = get_insecure_variable_from_config(peerlist); 04638 if(var) { 04639 if (realtimeregs) { 04640 newpeername = get_name_from_variable(var, newpeername); 04641 varregs = ast_load_realtime("sipregs", "name", newpeername, SENTINEL); 04642 } 04643 } else { /*var wasn't found in the list of "hosts", so try "ipaddr"*/ 04644 peerlist = NULL; 04645 cat = NULL; 04646 peerlist = ast_load_realtime_multientry("sippeers", "ipaddr", ipaddr, SENTINEL); 04647 if(peerlist) { 04648 var = get_insecure_variable_from_config(peerlist); 04649 if(var) { 04650 if (realtimeregs) { 04651 newpeername = get_name_from_variable(var, newpeername); 04652 varregs = ast_load_realtime("sipregs", "name", newpeername, SENTINEL); 04653 } 04654 } 04655 } 04656 } 04657 } else { 04658 if (realtimeregs) { 04659 peerlist = ast_load_realtime_multientry("sipregs", "ipaddr", ipaddr, SENTINEL); 04660 if (peerlist) { 04661 varregs = get_insecure_variable_from_config(peerlist); 04662 if (varregs) { 04663 newpeername = get_name_from_variable(varregs, newpeername); 04664 var = ast_load_realtime("sippeers", "name", newpeername, SENTINEL); 04665 } 04666 } 04667 } else { 04668 peerlist = ast_load_realtime_multientry("sippeers", "ipaddr", ipaddr, SENTINEL); 04669 if (peerlist) { 04670 var = get_insecure_variable_from_config(peerlist); 04671 if (var) { 04672 newpeername = get_name_from_variable(var, newpeername); 04673 varregs = ast_load_realtime("sipregs", "name", newpeername, SENTINEL); 04674 } 04675 } 04676 } 04677 } 04678 } 04679 } 04680 04681 if (!var) { 04682 if (peerlist) 04683 ast_config_destroy(peerlist); 04684 return NULL; 04685 } 04686 04687 for (tmp = var; tmp; tmp = tmp->next) { 04688 if (!strcasecmp(tmp->name, "type") && (!strcasecmp(tmp->value, "peer") && which_objects == FINDUSERS)) { 04689 if (peerlist) { 04690 ast_config_destroy(peerlist); 04691 } else { 04692 ast_variables_destroy(var); 04693 ast_variables_destroy(varregs); 04694 } 04695 return NULL; 04696 } else if (!newpeername && !strcasecmp(tmp->name, "name")) { 04697 newpeername = tmp->value; 04698 } 04699 } 04700 04701 if (!newpeername) { /* Did not find peer in realtime */ 04702 ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", ipaddr); 04703 if(peerlist) 04704 ast_config_destroy(peerlist); 04705 else 04706 ast_variables_destroy(var); 04707 return NULL; 04708 } 04709 04710 04711 /* Peer found in realtime, now build it in memory */ 04712 peer = build_peer(newpeername, var, varregs, TRUE, devstate_only); 04713 if (!peer) { 04714 if(peerlist) 04715 ast_config_destroy(peerlist); 04716 else { 04717 ast_variables_destroy(var); 04718 ast_variables_destroy(varregs); 04719 } 04720 return NULL; 04721 } 04722 04723 ast_debug(3, "-REALTIME- loading peer from database to memory. Name: %s. Peer objects: %d\n", peer->name, rpeerobjs); 04724 04725 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && !devstate_only) { 04726 /* Cache peer */ 04727 ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS); 04728 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 04729 AST_SCHED_REPLACE_UNREF(peer->expire, sched, sip_cfg.rtautoclear * 1000, expire_register, peer, 04730 unref_peer(_data, "remove registration ref"), 04731 unref_peer(peer, "remove registration ref"), 04732 ref_peer(peer, "add registration ref")); 04733 } 04734 ao2_t_link(peers, peer, "link peer into peers table"); 04735 if (!ast_sockaddr_isnull(&peer->addr)) { 04736 ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table"); 04737 } 04738 } 04739 peer->is_realtime = 1; 04740 if (peerlist) 04741 ast_config_destroy(peerlist); 04742 else { 04743 ast_variables_destroy(var); 04744 ast_variables_destroy(varregs); 04745 } 04746 04747 return peer; 04748 }
| static void realtime_update_peer | ( | const char * | peername, | |
| struct ast_sockaddr * | addr, | |||
| const char * | username, | |||
| const char * | fullcontact, | |||
| const char * | useragent, | |||
| int | expirey, | |||
| unsigned short | deprecated_username, | |||
| int | lastms | |||
| ) | [static] |
Update peer object in realtime storage If the Asterisk system name is set in asterisk.conf, we will use that name and store that in the "regserver" field in the sippeers table to facilitate multi-server setups.
Definition at line 4361 of file chan_sip.c.
References ast_check_realtime(), ast_config_AST_SYSTEM_NAME, ast_copy_string(), ast_sockaddr_stringify_addr(), ast_sockaddr_stringify_port(), ast_strlen_zero(), ast_update_realtime(), ipaddr, SENTINEL, and sip_cfg.
04362 { 04363 char port[10]; 04364 char ipaddr[INET6_ADDRSTRLEN]; 04365 char regseconds[20]; 04366 char *tablename = NULL; 04367 char str_lastms[20]; 04368 04369 const char *sysname = ast_config_AST_SYSTEM_NAME; 04370 char *syslabel = NULL; 04371 04372 time_t nowtime = time(NULL) + expirey; 04373 const char *fc = fullcontact ? "fullcontact" : NULL; 04374 04375 int realtimeregs = ast_check_realtime("sipregs"); 04376 04377 tablename = realtimeregs ? "sipregs" : "sippeers"; 04378 04379 04380 snprintf(str_lastms, sizeof(str_lastms), "%d", lastms); 04381 snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); /* Expiration time */ 04382 ast_copy_string(ipaddr, ast_sockaddr_stringify_addr(addr), sizeof(ipaddr)); 04383 ast_copy_string(port, ast_sockaddr_stringify_port(addr), sizeof(port)); 04384 04385 if (ast_strlen_zero(sysname)) /* No system name, disable this */ 04386 sysname = NULL; 04387 else if (sip_cfg.rtsave_sysname) 04388 syslabel = "regserver"; 04389 04390 /* XXX IMPORTANT: Anytime you add a new parameter to be updated, you 04391 * must also add it to contrib/scripts/asterisk.ldap-schema, 04392 * contrib/scripts/asterisk.ldif, 04393 * and to configs/res_ldap.conf.sample as described in 04394 * bugs 15156 and 15895 04395 */ 04396 if (fc) { 04397 ast_update_realtime(tablename, "name", peername, "ipaddr", ipaddr, 04398 "port", port, "regseconds", regseconds, 04399 deprecated_username ? "username" : "defaultuser", defaultuser, 04400 "useragent", useragent, "lastms", str_lastms, 04401 fc, fullcontact, syslabel, sysname, SENTINEL); /* note fc and syslabel _can_ be NULL */ 04402 } else { 04403 ast_update_realtime(tablename, "name", peername, "ipaddr", ipaddr, 04404 "port", port, "regseconds", regseconds, 04405 "useragent", useragent, "lastms", str_lastms, 04406 deprecated_username ? "username" : "defaultuser", defaultuser, 04407 syslabel, sysname, SENTINEL); /* note syslabel _can_ be NULL */ 04408 } 04409 }
| static void receive_message | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Receive SIP MESSAGE method messages.
Definition at line 15494 of file chan_sip.c.
References AST_FRAME_TEXT, ast_log(), ast_queue_frame(), ast_verbose, f, FALSE, get_header(), get_msg_text(), LOG_WARNING, sip_debug_test_pvt(), sip_scheddestroy(), and transmit_response().
Referenced by handle_request_message().
15495 { 15496 char buf[1400]; 15497 struct ast_frame f; 15498 const char *content_type = get_header(req, "Content-Type"); 15499 15500 if (strncmp(content_type, "text/plain", strlen("text/plain"))) { /* No text/plain attachment */ 15501 transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */ 15502 if (!p->owner) 15503 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15504 return; 15505 } 15506 15507 if (get_msg_text(buf, sizeof(buf), req, FALSE)) { 15508 ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); 15509 transmit_response(p, "202 Accepted", req); 15510 if (!p->owner) 15511 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15512 return; 15513 } 15514 15515 if (p->owner) { 15516 if (sip_debug_test_pvt(p)) 15517 ast_verbose("SIP Text message received: '%s'\n", buf); 15518 memset(&f, 0, sizeof(f)); 15519 f.frametype = AST_FRAME_TEXT; 15520 f.subclass.integer = 0; 15521 f.offset = 0; 15522 f.data.ptr = buf; 15523 f.datalen = strlen(buf) + 1; 15524 ast_queue_frame(p->owner, &f); 15525 transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */ 15526 return; 15527 } 15528 15529 /* Message outside of a call, we do not support that */ 15530 ast_log(LOG_WARNING, "Received message to %s from %s, dropped it...\n Content-Type:%s\n Message: %s\n", get_header(req, "To"), get_header(req, "From"), content_type, buf); 15531 transmit_response(p, "405 Method Not Allowed", req); 15532 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15533 return; 15534 }
| static struct sip_peer* ref_peer | ( | struct sip_peer * | peer, | |
| char * | tag | |||
| ) | [static] |
Definition at line 2831 of file chan_sip.c.
References ao2_t_ref.
Referenced by build_peer(), create_addr(), handle_request_invite(), handle_request_subscribe(), handle_response_peerpoke(), parse_register_contact(), reg_source_db(), sip_poke_all_peers(), sip_poke_noanswer(), sip_poke_peer(), sip_unregister(), and update_call_counter().
02832 { 02833 ao2_t_ref(peer, 1, tag); 02834 return peer; 02835 }
| static void ref_proxy | ( | struct sip_pvt * | pvt, | |
| struct sip_proxy * | proxy | |||
| ) | [static] |
maintain proper refcounts for a sip_pvt's outboundproxy
This function sets pvt's outboundproxy pointer to the one referenced by the proxy parameter. Because proxy may be a refcounted object, and because pvt's old outboundproxy may also be a refcounted object, we need to maintain the proper refcounts.
| pvt | The sip_pvt for which we wish to set the outboundproxy | |
| proxy | The sip_proxy which we will point pvt towards. |
Definition at line 2848 of file chan_sip.c.
References ao2_ref, and sip_cfg.
Referenced by __sip_ack(), __sip_subscribe_mwi_do(), create_addr(), and create_addr_from_peer().
02849 { 02850 struct sip_proxy *old_obproxy = pvt->outboundproxy; 02851 /* The sip_cfg.outboundproxy is statically allocated, and so 02852 * we don't ever need to adjust refcounts for it 02853 */ 02854 if (proxy && proxy != &sip_cfg.outboundproxy) { 02855 ao2_ref(proxy, +1); 02856 } 02857 pvt->outboundproxy = proxy; 02858 if (old_obproxy && old_obproxy != &sip_cfg.outboundproxy) { 02859 ao2_ref(old_obproxy, -1); 02860 } 02861 }
| static const char * referstatus2str | ( | enum referstatus | rstatus | ) | [static] |
Convert transfer status to string.
Definition at line 2966 of file chan_sip.c.
References map_x_s(), and referstatusstrings.
Referenced by show_channels_cb().
02967 { 02968 return map_x_s(referstatusstrings, rstatus, ""); 02969 }
| static void reg_source_db | ( | struct sip_peer * | peer | ) | [static] |
Get registration details from Asterisk DB.
Definition at line 13068 of file chan_sip.c.
References args, AST_APP_ARG, ast_db_get(), ast_debug, AST_DECLARE_APP_ARGS, AST_NONSTANDARD_RAW_ARGS, ast_random(), AST_SCHED_REPLACE_UNREF, ast_sockaddr_copy(), ast_sockaddr_parse(), ast_sockaddr_stringify_host(), ast_string_field_set, expire_register(), ref_peer(), register_peer_exten(), sip_poke_peer(), sip_poke_peer_s(), sipsock, TRUE, and unref_peer().
13069 { 13070 char data[256]; 13071 struct ast_sockaddr sa; 13072 int expire; 13073 char full_addr[128]; 13074 AST_DECLARE_APP_ARGS(args, 13075 AST_APP_ARG(addr); 13076 AST_APP_ARG(port); 13077 AST_APP_ARG(expiry_str); 13078 AST_APP_ARG(username); 13079 AST_APP_ARG(contact); 13080 ); 13081 13082 if (peer->rt_fromcontact) { 13083 return; 13084 } 13085 if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) { 13086 return; 13087 } 13088 13089 AST_NONSTANDARD_RAW_ARGS(args, data, ':'); 13090 13091 snprintf(full_addr, sizeof(full_addr), "%s:%s", args.addr, args.port); 13092 13093 if (!ast_sockaddr_parse(&sa, full_addr, 0)) { 13094 return; 13095 } 13096 13097 if (args.expiry_str) { 13098 expire = atoi(args.expiry_str); 13099 } else { 13100 return; 13101 } 13102 13103 if (args.username) { 13104 ast_string_field_set(peer, username, args.username); 13105 } 13106 if (args.contact) { 13107 ast_string_field_set(peer, fullcontact, args.contact); 13108 } 13109 13110 ast_debug(2, "SIP Seeding peer from astdb: '%s' at %s@%s for %d\n", 13111 peer->name, peer->username, ast_sockaddr_stringify_host(&sa), expire); 13112 13113 ast_sockaddr_copy(&peer->addr, &sa); 13114 if (sipsock < 0) { 13115 /* SIP isn't up yet, so schedule a poke only, pretty soon */ 13116 AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, ast_random() % 5000 + 1, sip_poke_peer_s, peer, 13117 unref_peer(_data, "removing poke peer ref"), 13118 unref_peer(peer, "removing poke peer ref"), 13119 ref_peer(peer, "adding poke peer ref")); 13120 } else { 13121 sip_poke_peer(peer, 0); 13122 } 13123 AST_SCHED_REPLACE_UNREF(peer->expire, sched, (expire + 10) * 1000, expire_register, peer, 13124 unref_peer(_data, "remove registration ref"), 13125 unref_peer(peer, "remove registration ref"), 13126 ref_peer(peer, "add registration ref")); 13127 register_peer_exten(peer, TRUE); 13128 }
| static void register_peer_exten | ( | struct sip_peer * | peer, | |
| int | onoff | |||
| ) | [static] |
Automatically add peer extension to dial plan.
Definition at line 4412 of file chan_sip.c.
References ast_add_extension(), ast_context_find(), ast_context_remove_extension(), ast_copy_string(), ast_exists_extension(), ast_free_ptr, ast_log(), ast_strdup, ast_strlen_zero(), context, E_MATCH, ext, LOG_WARNING, pbx_find_extension(), S_OR, sip_cfg, pbx_find_info::stacklen, and strsep().
04413 { 04414 char multi[256]; 04415 char *stringp, *ext, *context; 04416 struct pbx_find_info q = { .stacklen = 0 }; 04417 04418 /* XXX note that sip_cfg.regcontext is both a global 'enable' flag and 04419 * the name of the global regexten context, if not specified 04420 * individually. 04421 */ 04422 if (ast_strlen_zero(sip_cfg.regcontext)) 04423 return; 04424 04425 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 04426 stringp = multi; 04427 while ((ext = strsep(&stringp, "&"))) { 04428 if ((context = strchr(ext, '@'))) { 04429 *context++ = '\0'; /* split ext@context */ 04430 if (!ast_context_find(context)) { 04431 ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context); 04432 continue; 04433 } 04434 } else { 04435 context = sip_cfg.regcontext; 04436 } 04437 if (onoff) { 04438 if (!ast_exists_extension(NULL, context, ext, 1, NULL)) { 04439 ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop", 04440 ast_strdup(peer->name), ast_free_ptr, "SIP"); 04441 } 04442 } else if (pbx_find_extension(NULL, NULL, &q, context, ext, 1, NULL, "", E_MATCH)) { 04443 ast_context_remove_extension(context, ext, 1, NULL); 04444 } 04445 } 04446 }
| static enum check_auth_result register_verify | ( | struct sip_pvt * | p, | |
| struct ast_sockaddr * | addr, | |||
| struct sip_request * | req, | |||
| const char * | uri | |||
| ) | [static] |
Verify registration of user
Definition at line 13998 of file chan_sip.c.
References ao2_lock, ao2_t_link, ao2_unlock, ast_apply_ha(), ast_copy_flags, ast_copy_string(), AST_DEVICE_UNKNOWN, ast_devstate_changed(), AST_LIST_EMPTY, ast_log(), ast_set_flag, ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_sockaddr_stringify_port(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, build_contact(), check_auth(), check_request_transport, check_sip_domain(), dummy(), EVENT_FLAG_SYSTEM, exten, FALSE, find_peer(), get_header(), global_authfailureevents, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event, name, parse_register_contact(), peers_by_ip, remove_uri_parameters(), sip_cancel_destroy(), sip_cfg, SIP_PEDANTIC_DECODE, strcasestr(), temp_peer(), terminate_uri(), transmit_fake_auth_response(), transmit_response(), transmit_response_with_date(), TRUE, unref_peer(), and update_peer().
14000 { 14001 enum check_auth_result res = AUTH_NOT_FOUND; 14002 struct sip_peer *peer; 14003 char tmp[256]; 14004 char *name = NULL, *c, *domain = NULL, *dummy = NULL; 14005 char *uri2 = ast_strdupa(uri); 14006 14007 terminate_uri(uri2); 14008 14009 ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp)); 14010 14011 c = get_in_brackets(tmp); 14012 c = remove_uri_parameters(c); 14013 14014 if (parse_uri(c, "sip:,sips:", &name, &dummy, &domain, NULL)) { 14015 ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_sockaddr_stringify_addr(addr)); 14016 return -1; 14017 } 14018 14019 SIP_PEDANTIC_DECODE(name); 14020 SIP_PEDANTIC_DECODE(domain); 14021 14022 /*! \todo XXX here too we interpret a missing @domain as a name-only 14023 * URI, whereas the RFC says this is a domain-only uri. 14024 */ 14025 if (!ast_strlen_zero(domain) && !AST_LIST_EMPTY(&domain_list)) { 14026 if (!check_sip_domain(domain, NULL, 0)) { 14027 transmit_response(p, "404 Not found (unknown domain)", &p->initreq); 14028 return AUTH_UNKNOWN_DOMAIN; 14029 } 14030 } 14031 14032 ast_string_field_set(p, exten, name); 14033 build_contact(p); 14034 if (req->ignore) { 14035 /* Expires is a special case, where we only want to load the peer if this isn't a deregistration attempt */ 14036 const char *expires = get_header(req, "Expires"); 14037 int expire = atoi(expires); 14038 14039 if (ast_strlen_zero(expires)) { /* No expires header; look in Contact */ 14040 if ((expires = strcasestr(get_header(req, "Contact"), ";expires="))) { 14041 expire = atoi(expires + 9); 14042 } 14043 } 14044 if (!ast_strlen_zero(expires) && expire == 0) { 14045 transmit_response_with_date(p, "200 OK", req); 14046 return 0; 14047 } 14048 } 14049 peer = find_peer(name, NULL, TRUE, FINDPEERS, FALSE, 0); 14050 14051 if (!(peer && ast_apply_ha(peer->ha, addr))) { 14052 /* Peer fails ACL check */ 14053 if (peer) { 14054 unref_peer(peer, "register_verify: unref_peer: from find_peer operation"); 14055 peer = NULL; 14056 res = AUTH_ACL_FAILED; 14057 } else { 14058 res = AUTH_NOT_FOUND; 14059 } 14060 } 14061 14062 if (peer) { 14063 ao2_lock(peer); 14064 if (!peer->host_dynamic) { 14065 ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name); 14066 res = AUTH_PEER_NOT_DYNAMIC; 14067 } else { 14068 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT_FORCE_RPORT); 14069 if (ast_test_flag(&p->flags[1], SIP_PAGE2_REGISTERTRYING)) 14070 transmit_response(p, "100 Trying", req); 14071 if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri2, XMIT_UNRELIABLE, req->ignore))) { 14072 if (sip_cancel_destroy(p)) 14073 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 14074 14075 if (check_request_transport(peer, req)) { 14076 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 14077 transmit_response_with_date(p, "403 Forbidden", req); 14078 res = AUTH_BAD_TRANSPORT; 14079 } else { 14080 14081 /* We have a successful registration attempt with proper authentication, 14082 now, update the peer */ 14083 switch (parse_register_contact(p, peer, req)) { 14084 case PARSE_REGISTER_DENIED: 14085 ast_log(LOG_WARNING, "Registration denied because of contact ACL\n"); 14086 transmit_response_with_date(p, "603 Denied", req); 14087 peer->lastmsgssent = -1; 14088 res = 0; 14089 break; 14090 case PARSE_REGISTER_FAILED: 14091 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 14092 transmit_response_with_date(p, "400 Bad Request", req); 14093 peer->lastmsgssent = -1; 14094 res = 0; 14095 break; 14096 case PARSE_REGISTER_QUERY: 14097 ast_string_field_set(p, fullcontact, peer->fullcontact); 14098 transmit_response_with_date(p, "200 OK", req); 14099 peer->lastmsgssent = -1; 14100 res = 0; 14101 break; 14102 case PARSE_REGISTER_UPDATE: 14103 ast_string_field_set(p, fullcontact, peer->fullcontact); 14104 update_peer(peer, p->expiry); 14105 /* Say OK and ask subsystem to retransmit msg counter */ 14106 transmit_response_with_date(p, "200 OK", req); 14107 if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY)) 14108 peer->lastmsgssent = -1; 14109 res = 0; 14110 break; 14111 } 14112 } 14113 14114 } 14115 } 14116 ao2_unlock(peer); 14117 } 14118 if (!peer && sip_cfg.autocreatepeer) { 14119 /* Create peer if we have autocreate mode enabled */ 14120 peer = temp_peer(name); 14121 if (peer) { 14122 ao2_t_link(peers, peer, "link peer into peer table"); 14123 if (!ast_sockaddr_isnull(&peer->addr)) { 14124 ao2_t_link(peers_by_ip, peer, "link peer into peers-by-ip table"); 14125 } 14126 ao2_lock(peer); 14127 if (sip_cancel_destroy(p)) 14128 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 14129 switch (parse_register_contact(p, peer, req)) { 14130 case PARSE_REGISTER_DENIED: 14131 ast_log(LOG_WARNING, "Registration denied because of contact ACL\n"); 14132 transmit_response_with_date(p, "403 Forbidden (ACL)", req); 14133 peer->lastmsgssent = -1; 14134 res = 0; 14135 break; 14136 case PARSE_REGISTER_FAILED: 14137 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 14138 transmit_response_with_date(p, "400 Bad Request", req); 14139 peer->lastmsgssent = -1; 14140 res = 0; 14141 break; 14142 case PARSE_REGISTER_QUERY: 14143 ast_string_field_set(p, fullcontact, peer->fullcontact); 14144 transmit_response_with_date(p, "200 OK", req); 14145 peer->lastmsgssent = -1; 14146 res = 0; 14147 break; 14148 case PARSE_REGISTER_UPDATE: 14149 ast_string_field_set(p, fullcontact, peer->fullcontact); 14150 /* Say OK and ask subsystem to retransmit msg counter */ 14151 transmit_response_with_date(p, "200 OK", req); 14152 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Registered\r\nAddress: %s\r\n", peer->name, ast_sockaddr_stringify(addr)); 14153 peer->lastmsgssent = -1; 14154 res = 0; 14155 break; 14156 } 14157 ao2_unlock(peer); 14158 } 14159 } 14160 if (!peer && sip_cfg.alwaysauthreject) { 14161 /* If we found a peer, we transmit a 100 Trying. Therefore, if we're 14162 * trying to avoid leaking information, we MUST also transmit the same 14163 * response when we DON'T find a peer. */ 14164 transmit_response(p, "100 Trying", req); 14165 /* Insert a fake delay between the 100 and the subsequent failure. */ 14166 sched_yield(); 14167 } 14168 if (!res) { 14169 ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name); 14170 } 14171 if (res < 0) { 14172 switch (res) { 14173 case AUTH_SECRET_FAILED: 14174 /* Wrong password in authentication. Go away, don't try again until you fixed it */ 14175 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 14176 if (global_authfailureevents) { 14177 const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr)); 14178 const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr)); 14179 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 14180 "ChannelType: SIP\r\n" 14181 "Peer: SIP/%s\r\n" 14182 "PeerStatus: Rejected\r\n" 14183 "Cause: AUTH_SECRET_FAILED\r\n" 14184 "Address: %s\r\n" 14185 "Port: %s\r\n", 14186 name, peer_addr, peer_port); 14187 } 14188 break; 14189 case AUTH_USERNAME_MISMATCH: 14190 /* Username and digest username does not match. 14191 Asterisk uses the From: username for authentication. We need the 14192 devices to use the same authentication user name until we support 14193 proper authentication by digest auth name */ 14194 case AUTH_NOT_FOUND: 14195 case AUTH_PEER_NOT_DYNAMIC: 14196 case AUTH_ACL_FAILED: 14197 if (sip_cfg.alwaysauthreject) { 14198 transmit_fake_auth_response(p, SIP_REGISTER, &p->initreq, XMIT_UNRELIABLE); 14199 if (global_authfailureevents) { 14200 const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr)); 14201 const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr)); 14202 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 14203 "ChannelType: SIP\r\n" 14204 "Peer: SIP/%s\r\n" 14205 "PeerStatus: Rejected\r\n" 14206 "Cause: %s\r\n" 14207 "Address: %s\r\n" 14208 "Port: %s\r\n", 14209 name, 14210 res == AUTH_PEER_NOT_DYNAMIC ? "AUTH_PEER_NOT_DYNAMIC" : "URI_NOT_FOUND", 14211 peer_addr, peer_port); 14212 } 14213 } else { 14214 /* URI not found */ 14215 if (res == AUTH_PEER_NOT_DYNAMIC) { 14216 transmit_response(p, "403 Forbidden", &p->initreq); 14217 if (global_authfailureevents) { 14218 const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr)); 14219 const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr)); 14220 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 14221 "ChannelType: SIP\r\n" 14222 "Peer: SIP/%s\r\n" 14223 "PeerStatus: Rejected\r\n" 14224 "Cause: AUTH_PEER_NOT_DYNAMIC\r\n" 14225 "Address: %s\r\n" 14226 "Port: %s\r\n", 14227 name, peer_addr, peer_port); 14228 } 14229 } else { 14230 transmit_response(p, "404 Not found", &p->initreq); 14231 if (global_authfailureevents) { 14232 const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr)); 14233 const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr)); 14234 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 14235 "ChannelType: SIP\r\n" 14236 "Peer: SIP/%s\r\n" 14237 "PeerStatus: Rejected\r\n" 14238 "Cause: %s\r\n" 14239 "Address: %s\r\n" 14240 "Port: %s\r\n", 14241 name, 14242 (res == AUTH_USERNAME_MISMATCH) ? "AUTH_USERNAME_MISMATCH" : "URI_NOT_FOUND", 14243 peer_addr, peer_port); 14244 } 14245 } 14246 } 14247 break; 14248 case AUTH_BAD_TRANSPORT: 14249 default: 14250 break; 14251 } 14252 } 14253 if (peer) { 14254 unref_peer(peer, "register_verify: unref_peer: tossing stack peer pointer at end of func"); 14255 } 14256 14257 return res; 14258 }
| static struct sip_registry* registry_addref | ( | struct sip_registry * | reg, | |
| char * | tag | |||
| ) | [static] |
Add object reference to SIP registry.
Definition at line 2948 of file chan_sip.c.
References ast_debug, and ASTOBJ_REF.
Referenced by handle_response_register(), sip_send_all_registers(), and transmit_register().
02949 { 02950 ast_debug(3, "SIP Registry %s: refcount now %d\n", reg->hostname, reg->refcount + 1); 02951 return ASTOBJ_REF(reg); /* Add pointer to registry in packet */ 02952 }
| void * registry_unref | ( | struct sip_registry * | reg, | |
| char * | tag | |||
| ) | [static] |
Definition at line 2940 of file chan_sip.c.
References ast_debug, ASTOBJ_UNREF, and sip_registry_destroy().
Referenced by __sip_destroy(), dialog_unlink_all(), handle_response_register(), reload_config(), sip_reg_timeout(), sip_register(), sip_registry_destroy(), sip_reregister(), sip_send_all_registers(), and transmit_register().
02941 { 02942 ast_debug(3, "SIP Registry %s: refcount now %d\n", reg->hostname, reg->refcount - 1); 02943 ASTOBJ_UNREF(reg, sip_registry_destroy); 02944 return NULL; 02945 }
| static const char * regstate2str | ( | enum sipregistrystate | regstate | ) | const [static] |
Convert registration state status to string.
Definition at line 12376 of file chan_sip.c.
References map_x_s(), and regstatestrings.
12377 { 12378 return map_x_s(regstatestrings, regstate, "Unknown"); 12379 }
| static int reload | ( | void | ) | [static] |
Part of Asterisk module interface.
Definition at line 28417 of file chan_sip.c.
References sip_reload().
28418 { 28419 if (sip_reload(0, 0, NULL)) 28420 return 0; 28421 return 1; 28422 }
| static int reload_config | ( | enum channelreloadreason | reason | ) | [static] |
Re-read SIP.conf config file.
< Don't force proxy usage, use route: headers
< Reset default transport to zero here, default value later on
< Reset default primary transport to zero here, default value later on
< 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
Definition at line 26698 of file chan_sip.c.
References ast_clear_flag, ast_config_destroy(), ast_config_load, ast_debug, ast_free_ha(), ast_log(), AST_MAX_CONTEXT, AST_SCHED_DEL_UNREF, ast_test_flag, ast_unload_realtime(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, authl, bindaddr, CHANNEL_MODULE_LOAD, clear_realm_authentication(), clear_sip_domains(), config, CONFIG_FLAG_FILEUNCHANGED, config_flags, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, context, default_tls_cfg, dialog_unlink_all(), dummy(), ast_tls_config::enabled, FALSE, global_flags, LOG_ERROR, LOG_NOTICE, registry_unref(), regl, sip_cfg, and TRUE.
26699 { 26700 struct ast_config *cfg, *ucfg; 26701 struct ast_variable *v; 26702 struct sip_peer *peer; 26703 char *cat, *stringp, *context, *oldregcontext; 26704 char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT]; 26705 struct ast_flags dummy[2]; 26706 struct ast_flags config_flags = { reason == CHANNEL_MODULE_LOAD ? 0 : ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? 0 : CONFIG_FLAG_FILEUNCHANGED }; 26707 int auto_sip_domains = FALSE; 26708 struct ast_sockaddr old_bindaddr = bindaddr; 26709 int registry_count = 0, peer_count = 0, timerb_set = 0, timert1_set = 0; 26710 int subscribe_network_change = 1; 26711 time_t run_start, run_end; 26712 int bindport = 0; 26713 26714 run_start = time(0); 26715 ast_unload_realtime("sipregs"); 26716 ast_unload_realtime("sippeers"); 26717 cfg = ast_config_load(config, config_flags); 26718 26719 /* We *must* have a config file otherwise stop immediately */ 26720 if (!cfg) { 26721 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 26722 return -1; 26723 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 26724 ucfg = ast_config_load("users.conf", config_flags); 26725 if (ucfg == CONFIG_STATUS_FILEUNCHANGED) { 26726 return 1; 26727 } else if (ucfg == CONFIG_STATUS_FILEINVALID) { 26728 ast_log(LOG_ERROR, "Contents of users.conf are invalid and cannot be parsed\n"); 26729 return 1; 26730 } 26731 /* Must reread both files, because one changed */ 26732 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 26733 if ((cfg = ast_config_load(config, config_flags)) == CONFIG_STATUS_FILEINVALID) { 26734 ast_log(LOG_ERROR, "Contents of %s are invalid and cannot be parsed\n", config); 26735 ast_config_destroy(ucfg); 26736 return 1; 26737 } 26738 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 26739 ast_log(LOG_ERROR, "Contents of %s are invalid and cannot be parsed\n", config); 26740 return 1; 26741 } else { 26742 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 26743 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 26744 ast_log(LOG_ERROR, "Contents of users.conf are invalid and cannot be parsed\n"); 26745 ast_config_destroy(cfg); 26746 return 1; 26747 } 26748 } 26749 26750 ast_free_ha(sip_cfg.contact_ha); 26751 sip_cfg.contact_ha = NULL; 26752 26753 default_tls_cfg.enabled = FALSE; /* Default: Disable TLS */ 26754 26755 if (reason != CHANNEL_MODULE_LOAD) { 26756 ast_debug(4, "--------------- SIP reload started\n"); 26757 26758 clear_realm_authentication(authl); 26759 clear_sip_domains(); 26760 authl = NULL; 26761 26762 /* First, destroy all outstanding registry calls */ 26763 /* This is needed, since otherwise active registry entries will not be destroyed */ 26764 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { /* regl is locked */ 26765 26766 ASTOBJ_RDLOCK(iterator); /* now regl is locked, and the object is also locked */ 26767 if (iterator->call) { 26768 ast_debug(3, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname); 26769 /* This will also remove references to the registry */ 26770 dialog_unlink_all(iterator->call, TRUE, TRUE); 26771 iterator->call = dialog_unref(iterator->call, "remove iterator->call from registry traversal"); 26772 } 26773 if (iterator->expire > -1) { 26774 AST_SCHED_DEL_UNREF(sched, iterator->expire, registry_unref(iterator, "reg ptr unref from reload config")); 26775 } 26776 if (iterator->timeout > -1) { 26777 AST_SCHED_DEL_UNREF(sched, iterator->timeout, registry_unref(iterator, "reg ptr unref from reload config")); 26778 } 26779 ASTOBJ_UNLOCK(iterator); 26780 } while(0)); 26781 26782 /* Then, actually destroy users and registry */ 26783 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 26784 ast_debug(4, "--------------- Done destroying registry list\n"); 26785 ao2_t_callback(peers, OBJ_NODATA, peer_markall_func, NULL, "callback to mark all peers"); 26786 } 26787 26788 /* Reset certificate handling for TLS sessions */ 26789 if (reason != CHANNEL_MODULE_LOAD) { 26790 ast_free(default_tls_cfg.certfile); 26791 ast_free(default_tls_cfg.pvtfile); 26792 ast_free(default_tls_cfg.cipher); 26793 ast_free(default_tls_cfg.cafile); 26794 ast_free(default_tls_cfg.capath); 26795 } 26796 default_tls_cfg.certfile = ast_strdup(AST_CERTFILE); /*XXX Not sure if this is useful */ 26797 default_tls_cfg.pvtfile = ast_strdup(""); 26798 default_tls_cfg.cipher = ast_strdup(""); 26799 default_tls_cfg.cafile = ast_strdup(""); 26800 default_tls_cfg.capath = ast_strdup(""); 26801 26802 /* Initialize copy of current sip_cfg.regcontext for later use in removing stale contexts */ 26803 ast_copy_string(oldcontexts, sip_cfg.regcontext, sizeof(oldcontexts)); 26804 oldregcontext = oldcontexts; 26805 26806 /* Clear all flags before setting default values */ 26807 /* Preserve debugging settings for console */ 26808 sipdebug &= sip_debug_console; 26809 ast_clear_flag(&global_flags[0], AST_FLAGS_ALL); 26810 ast_clear_flag(&global_flags[1], AST_FLAGS_ALL); 26811 26812 /* Reset IP addresses */ 26813 ast_sockaddr_parse(&bindaddr, "0.0.0.0:0", 0); 26814 memset(&internip, 0, sizeof(internip)); 26815 26816 /* Free memory for local network address mask */ 26817 ast_free_ha(localaddr); 26818 memset(&localaddr, 0, sizeof(localaddr)); 26819 memset(&externaddr, 0, sizeof(externaddr)); 26820 memset(&media_address, 0, sizeof(media_address)); 26821 memset(&default_prefs, 0 , sizeof(default_prefs)); 26822 memset(&sip_cfg.outboundproxy, 0, sizeof(struct sip_proxy)); 26823 sip_cfg.outboundproxy.force = FALSE; /*!< Don't force proxy usage, use route: headers */ 26824 default_transports = 0; /*!< Reset default transport to zero here, default value later on */ 26825 default_primary_transport = 0; /*!< Reset default primary transport to zero here, default value later on */ 26826 ourport_tcp = STANDARD_SIP_PORT; 26827 ourport_tls = STANDARD_TLS_PORT; 26828 externtcpport = STANDARD_SIP_PORT; 26829 externtlsport = STANDARD_TLS_PORT; 26830 sip_cfg.srvlookup = DEFAULT_SRVLOOKUP; 26831 global_tos_sip = DEFAULT_TOS_SIP; 26832 global_tos_audio = DEFAULT_TOS_AUDIO; 26833 global_tos_video = DEFAULT_TOS_VIDEO; 26834 global_tos_text = DEFAULT_TOS_TEXT; 26835 global_cos_sip = DEFAULT_COS_SIP; 26836 global_cos_audio = DEFAULT_COS_AUDIO; 26837 global_cos_video = DEFAULT_COS_VIDEO; 26838 global_cos_text = DEFAULT_COS_TEXT; 26839 26840 externhost[0] = '\0'; /* External host name (for behind NAT DynDNS support) */ 26841 externexpire = 0; /* Expiration for DNS re-issuing */ 26842 externrefresh = 10; 26843 26844 /* Reset channel settings to default before re-configuring */ 26845 sip_cfg.allow_external_domains = DEFAULT_ALLOW_EXT_DOM; /* Allow external invites */ 26846 sip_cfg.regcontext[0] = '\0'; 26847 sip_cfg.capability = DEFAULT_CAPABILITY; 26848 sip_cfg.regextenonqualify = DEFAULT_REGEXTENONQUALIFY; 26849 sip_cfg.notifyringing = DEFAULT_NOTIFYRINGING; 26850 sip_cfg.notifycid = DEFAULT_NOTIFYCID; 26851 sip_cfg.notifyhold = FALSE; /*!< Keep track of hold status for a peer */ 26852 sip_cfg.directrtpsetup = FALSE; /* Experimental feature, disabled by default */ 26853 sip_cfg.alwaysauthreject = DEFAULT_ALWAYSAUTHREJECT; 26854 sip_cfg.auth_options_requests = DEFAULT_AUTH_OPTIONS; 26855 sip_cfg.allowsubscribe = FALSE; 26856 sip_cfg.disallowed_methods = SIP_UNKNOWN; 26857 sip_cfg.contact_ha = NULL; /* Reset the contact ACL */ 26858 snprintf(global_useragent, sizeof(global_useragent), "%s %s", DEFAULT_USERAGENT, ast_get_version()); 26859 snprintf(global_sdpsession, sizeof(global_sdpsession), "%s %s", DEFAULT_SDPSESSION, ast_get_version()); 26860 snprintf(global_sdpowner, sizeof(global_sdpowner), "%s", DEFAULT_SDPOWNER); 26861 global_prematuremediafilter = TRUE; 26862 ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime)); 26863 ast_copy_string(sip_cfg.realm, S_OR(ast_config_AST_SYSTEM_NAME, DEFAULT_REALM), sizeof(sip_cfg.realm)); 26864 sip_cfg.domainsasrealm = DEFAULT_DOMAINSASREALM; 26865 ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid)); 26866 ast_copy_string(default_mwi_from, DEFAULT_MWI_FROM, sizeof(default_mwi_from)); 26867 sip_cfg.compactheaders = DEFAULT_COMPACTHEADERS; 26868 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 26869 global_regattempts_max = 0; 26870 sip_cfg.pedanticsipchecking = DEFAULT_PEDANTIC; 26871 sip_cfg.autocreatepeer = DEFAULT_AUTOCREATEPEER; 26872 global_autoframing = 0; 26873 sip_cfg.allowguest = DEFAULT_ALLOWGUEST; 26874 global_callcounter = DEFAULT_CALLCOUNTER; 26875 global_match_auth_username = FALSE; /*!< Match auth username if available instead of From: Default off. */ 26876 global_rtptimeout = 0; 26877 global_rtpholdtimeout = 0; 26878 global_rtpkeepalive = DEFAULT_RTPKEEPALIVE; 26879 sip_cfg.allowtransfer = TRANSFER_OPENFORALL; /* Merrily accept all transfers by default */ 26880 sip_cfg.rtautoclear = 120; 26881 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE); /* Default for all devices: TRUE */ 26882 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP); /* Default for all devices: TRUE */ 26883 sip_cfg.peer_rtupdate = TRUE; 26884 global_dynamic_exclude_static = 0; /* Exclude static peers */ 26885 sip_cfg.tcp_enabled = FALSE; 26886 26887 /* Session-Timers */ 26888 global_st_mode = SESSION_TIMER_MODE_ACCEPT; 26889 global_st_refresher = SESSION_TIMER_REFRESHER_UAS; 26890 global_min_se = DEFAULT_MIN_SE; 26891 global_max_se = DEFAULT_MAX_SE; 26892 26893 /* Peer poking settings */ 26894 global_qualify_gap = DEFAULT_QUALIFY_GAP; 26895 global_qualify_peers = DEFAULT_QUALIFY_PEERS; 26896 26897 /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for devices */ 26898 ast_copy_string(sip_cfg.default_context, DEFAULT_CONTEXT, sizeof(sip_cfg.default_context)); 26899 sip_cfg.default_subscribecontext[0] = '\0'; 26900 sip_cfg.default_max_forwards = DEFAULT_MAX_FORWARDS; 26901 default_language[0] = '\0'; 26902 default_fromdomain[0] = '\0'; 26903 default_fromdomainport = 0; 26904 default_qualify = DEFAULT_QUALIFY; 26905 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 26906 ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret)); 26907 ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest)); 26908 ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten)); 26909 ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */ 26910 ast_set_flag(&global_flags[0], SIP_DIRECT_MEDIA); /*!< Allow re-invites */ 26911 ast_copy_string(default_engine, DEFAULT_ENGINE, sizeof(default_engine)); 26912 ast_copy_string(default_parkinglot, DEFAULT_PARKINGLOT, sizeof(default_parkinglot)); 26913 26914 /* Debugging settings, always default to off */ 26915 dumphistory = FALSE; 26916 recordhistory = FALSE; 26917 sipdebug &= ~sip_debug_config; 26918 26919 /* Misc settings for the channel */ 26920 global_relaxdtmf = FALSE; 26921 sip_cfg.callevents = DEFAULT_CALLEVENTS; 26922 global_authfailureevents = FALSE; 26923 global_t1 = DEFAULT_TIMER_T1; 26924 global_timer_b = 64 * DEFAULT_TIMER_T1; 26925 global_t1min = DEFAULT_T1MIN; 26926 global_qualifyfreq = DEFAULT_QUALIFYFREQ; 26927 global_t38_maxdatagram = -1; 26928 global_shrinkcallerid = 1; 26929 authlimit = DEFAULT_AUTHLIMIT; 26930 authtimeout = DEFAULT_AUTHTIMEOUT; 26931 26932 sip_cfg.matchexternaddrlocally = DEFAULT_MATCHEXTERNADDRLOCALLY; 26933 26934 /* Copy the default jb config over global_jbconf */ 26935 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 26936 26937 ast_clear_flag(&global_flags[1], SIP_PAGE2_FAX_DETECT); 26938 ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT | SIP_PAGE2_VIDEOSUPPORT_ALWAYS); 26939 ast_clear_flag(&global_flags[1], SIP_PAGE2_TEXTSUPPORT); 26940 ast_clear_flag(&global_flags[1], SIP_PAGE2_IGNORESDPVERSION); 26941 26942 26943 /* Read the [general] config section of sip.conf (or from realtime config) */ 26944 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) { 26945 if (handle_common_options(&global_flags[0], &dummy[0], v)) { 26946 continue; 26947 } 26948 if (handle_t38_options(&global_flags[0], &dummy[0], v, &global_t38_maxdatagram)) { 26949 continue; 26950 } 26951 /* handle jb conf */ 26952 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 26953 continue; 26954 26955 /* handle tls conf */ 26956 if (!ast_tls_read_conf(&default_tls_cfg, &sip_tls_desc, v->name, v->value)) { 26957 continue; 26958 } 26959 26960 if (!strcasecmp(v->name, "context")) { 26961 ast_copy_string(sip_cfg.default_context, v->value, sizeof(sip_cfg.default_context)); 26962 } else if (!strcasecmp(v->name, "subscribecontext")) { 26963 ast_copy_string(sip_cfg.default_subscribecontext, v->value, sizeof(sip_cfg.default_subscribecontext)); 26964 } else if (!strcasecmp(v->name, "callcounter")) { 26965 global_callcounter = ast_true(v->value) ? 1 : 0; 26966 } else if (!strcasecmp(v->name, "allowguest")) { 26967 sip_cfg.allowguest = ast_true(v->value) ? 1 : 0; 26968 } else if (!strcasecmp(v->name, "realm")) { 26969 ast_copy_string(sip_cfg.realm, v->value, sizeof(sip_cfg.realm)); 26970 } else if (!strcasecmp(v->name, "domainsasrealm")) { 26971 sip_cfg.domainsasrealm = ast_true(v->value); 26972 } else if (!strcasecmp(v->name, "useragent")) { 26973 ast_copy_string(global_useragent, v->value, sizeof(global_useragent)); 26974 ast_debug(1, "Setting SIP channel User-Agent Name to %s\n", global_useragent); 26975 } else if (!strcasecmp(v->name, "sdpsession")) { 26976 ast_copy_string(global_sdpsession, v->value, sizeof(global_sdpsession)); 26977 } else if (!strcasecmp(v->name, "sdpowner")) { 26978 /* Field cannot contain spaces */ 26979 if (!strstr(v->value, " ")) { 26980 ast_copy_string(global_sdpowner, v->value, sizeof(global_sdpowner)); 26981 } else { 26982 ast_log(LOG_WARNING, "'%s' must not contain spaces at line %d. Using default.\n", v->value, v->lineno); 26983 } 26984 } else if (!strcasecmp(v->name, "allowtransfer")) { 26985 sip_cfg.allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 26986 } else if (!strcasecmp(v->name, "rtcachefriends")) { 26987 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 26988 } else if (!strcasecmp(v->name, "rtsavesysname")) { 26989 sip_cfg.rtsave_sysname = ast_true(v->value); 26990 } else if (!strcasecmp(v->name, "rtupdate")) { 26991 sip_cfg.peer_rtupdate = ast_true(v->value); 26992 } else if (!strcasecmp(v->name, "ignoreregexpire")) { 26993 sip_cfg.ignore_regexpire = ast_true(v->value); 26994 } else if (!strcasecmp(v->name, "timert1")) { 26995 /* Defaults to 500ms, but RFC 3261 states that it is recommended 26996 * for the value to be set higher, though a lower value is only 26997 * allowed on private networks unconnected to the Internet. */ 26998 global_t1 = atoi(v->value); 26999 } else if (!strcasecmp(v->name, "timerb")) { 27000 int tmp = atoi(v->value); 27001 if (tmp < 500) { 27002 global_timer_b = global_t1 * 64; 27003 ast_log(LOG_WARNING, "Invalid value for timerb ('%s'). Setting to default ('%d').\n", v->value, global_timer_b); 27004 } 27005 timerb_set = 1; 27006 } else if (!strcasecmp(v->name, "t1min")) { 27007 global_t1min = atoi(v->value); 27008 } else if (!strcasecmp(v->name, "transport") && !ast_strlen_zero(v->value)) { 27009 char *val = ast_strdupa(v->value); 27010 char *trans; 27011 27012 while ((trans = strsep(&val, ","))) { 27013 trans = ast_skip_blanks(trans); 27014 27015 if (!strncasecmp(trans, "udp", 3)) { 27016 default_transports |= SIP_TRANSPORT_UDP; 27017 } else if (!strncasecmp(trans, "tcp", 3)) { 27018 default_transports |= SIP_TRANSPORT_TCP; 27019 } else if (!strncasecmp(trans, "tls", 3)) { 27020 default_transports |= SIP_TRANSPORT_TLS; 27021 } else { 27022 ast_log(LOG_NOTICE, "'%s' is not a valid transport type. if no other is specified, udp will be used.\n", trans); 27023 } 27024 if (default_primary_transport == 0) { 27025 default_primary_transport = default_transports; 27026 } 27027 } 27028 } else if (!strcasecmp(v->name, "tcpenable")) { 27029 if (!ast_false(v->value)) { 27030 ast_debug(2, "Enabling TCP socket for listening\n"); 27031 sip_cfg.tcp_enabled = TRUE; 27032 } 27033 } else if (!strcasecmp(v->name, "tcpbindaddr")) { 27034 if (ast_parse_arg(v->value, PARSE_ADDR, 27035 &sip_tcp_desc.local_address)) { 27036 ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n", 27037 v->name, v->value, v->lineno, config); 27038 } 27039 ast_debug(2, "Setting TCP socket address to %s\n", 27040 ast_sockaddr_stringify(&sip_tcp_desc.local_address)); 27041 } else if (!strcasecmp(v->name, "dynamic_exclude_static") || !strcasecmp(v->name, "dynamic_excludes_static")) { 27042 global_dynamic_exclude_static = ast_true(v->value); 27043 } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) { 27044 int ha_error = 0; 27045 sip_cfg.contact_ha = ast_append_ha(v->name + 7, v->value, sip_cfg.contact_ha, &ha_error); 27046 if (ha_error) { 27047 ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value); 27048 } 27049 } else if (!strcasecmp(v->name, "rtautoclear")) { 27050 int i = atoi(v->value); 27051 if (i > 0) { 27052 sip_cfg.rtautoclear = i; 27053 } else { 27054 i = 0; 27055 } 27056 ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR); 27057 } else if (!strcasecmp(v->name, "usereqphone")) { 27058 ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE); 27059 } else if (!strcasecmp(v->name, "prematuremedia")) { 27060 global_prematuremediafilter = ast_true(v->value); 27061 } else if (!strcasecmp(v->name, "relaxdtmf")) { 27062 global_relaxdtmf = ast_true(v->value); 27063 } else if (!strcasecmp(v->name, "vmexten")) { 27064 ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten)); 27065 } else if (!strcasecmp(v->name, "rtptimeout")) { 27066 if ((sscanf(v->value, "%30d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) { 27067 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 27068 global_rtptimeout = 0; 27069 } 27070 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 27071 if ((sscanf(v->value, "%30d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) { 27072 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 27073 global_rtpholdtimeout = 0; 27074 } 27075 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 27076 if ((sscanf(v->value, "%30d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) { 27077 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 27078 global_rtpkeepalive = DEFAULT_RTPKEEPALIVE; 27079 } 27080 } else if (!strcasecmp(v->name, "compactheaders")) { 27081 sip_cfg.compactheaders = ast_true(v->value); 27082 } else if (!strcasecmp(v->name, "notifymimetype")) { 27083 ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime)); 27084 } else if (!strcasecmp(v->name, "directrtpsetup")) { 27085 sip_cfg.directrtpsetup = ast_true(v->value); 27086 } else if (!strcasecmp(v->name, "notifyringing")) { 27087 sip_cfg.notifyringing = ast_true(v->value); 27088 } else if (!strcasecmp(v->name, "notifyhold")) { 27089 sip_cfg.notifyhold = ast_true(v->value); 27090 } else if (!strcasecmp(v->name, "notifycid")) { 27091 if (!strcasecmp(v->value, "ignore-context")) { 27092 sip_cfg.notifycid = IGNORE_CONTEXT; 27093 } else { 27094 sip_cfg.notifycid = ast_true(v->value); 27095 } 27096 } else if (!strcasecmp(v->name, "alwaysauthreject")) { 27097 sip_cfg.alwaysauthreject = ast_true(v->value); 27098 } else if (!strcasecmp(v->name, "auth_options_requests")) { 27099 if (ast_true(v->value)) { 27100 sip_cfg.auth_options_requests = 1; 27101 } 27102 } else if (!strcasecmp(v->name, "mohinterpret")) { 27103 ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret)); 27104 } else if (!strcasecmp(v->name, "mohsuggest")) { 27105 ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest)); 27106 } else if (!strcasecmp(v->name, "language")) { 27107 ast_copy_string(default_language, v->value, sizeof(default_language)); 27108 } else if (!strcasecmp(v->name, "regcontext")) { 27109 ast_copy_string(newcontexts, v->value, sizeof(newcontexts)); 27110 stringp = newcontexts; 27111 /* Let's remove any contexts that are no longer defined in regcontext */ 27112 cleanup_stale_contexts(stringp, oldregcontext); 27113 /* Create contexts if they don't exist already */ 27114 while ((context = strsep(&stringp, "&"))) { 27115 ast_copy_string(used_context, context, sizeof(used_context)); 27116 ast_context_find_or_create(NULL, NULL, context, "SIP"); 27117 } 27118 ast_copy_string(sip_cfg.regcontext, v->value, sizeof(sip_cfg.regcontext)); 27119 } else if (!strcasecmp(v->name, "regextenonqualify")) { 27120 sip_cfg.regextenonqualify = ast_true(v->value); 27121 } else if (!strcasecmp(v->name, "callerid")) { 27122 ast_copy_string(default_callerid, v->value, sizeof(default_callerid)); 27123 } else if (!strcasecmp(v->name, "mwi_from")) { 27124 ast_copy_string(default_mwi_from, v->value, sizeof(default_mwi_from)); 27125 } else if (!strcasecmp(v->name, "fromdomain")) { 27126 char *fromdomainport; 27127 ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain)); 27128 if ((fromdomainport = strchr(default_fromdomain, ':'))) { 27129 *fromdomainport++ = '\0'; 27130 if (!(default_fromdomainport = port_str2int(fromdomainport, 0))) { 27131 ast_log(LOG_NOTICE, "'%s' is not a valid port number for fromdomain.\n",fromdomainport); 27132 } 27133 } else { 27134 default_fromdomainport = STANDARD_SIP_PORT; 27135 } 27136 } else if (!strcasecmp(v->name, "outboundproxy")) { 27137 char *tok, *proxyname; 27138 27139 if (ast_strlen_zero(v->value)) { 27140 ast_log(LOG_WARNING, "no value given for outbound proxy on line %d of sip.conf.", v->lineno); 27141 continue; 27142 } 27143 27144 tok = ast_skip_blanks(strtok(ast_strdupa(v->value), ",")); 27145 27146 sip_parse_host(tok, v->lineno, &proxyname, 27147 &sip_cfg.outboundproxy.port, 27148 &sip_cfg.outboundproxy.transport); 27149 27150 if ((tok = strtok(NULL, ","))) { 27151 sip_cfg.outboundproxy.force = !strncasecmp(ast_skip_blanks(tok), "force", 5); 27152 } else { 27153 sip_cfg.outboundproxy.force = FALSE; 27154 } 27155 27156 if (ast_strlen_zero(proxyname)) { 27157 ast_log(LOG_WARNING, "you must specify a name for the outboundproxy on line %d of sip.conf.", v->lineno); 27158 sip_cfg.outboundproxy.name[0] = '\0'; 27159 continue; 27160 } 27161 27162 ast_copy_string(sip_cfg.outboundproxy.name, proxyname, sizeof(sip_cfg.outboundproxy.name)); 27163 27164 proxy_update(&sip_cfg.outboundproxy); 27165 } else if (!strcasecmp(v->name, "autocreatepeer")) { 27166 sip_cfg.autocreatepeer = ast_true(v->value); 27167 } else if (!strcasecmp(v->name, "match_auth_username")) { 27168 global_match_auth_username = ast_true(v->value); 27169 } else if (!strcasecmp(v->name, "srvlookup")) { 27170 sip_cfg.srvlookup = ast_true(v->value); 27171 } else if (!strcasecmp(v->name, "pedantic")) { 27172 sip_cfg.pedanticsipchecking = ast_true(v->value); 27173 } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) { 27174 max_expiry = atoi(v->value); 27175 if (max_expiry < 1) { 27176 max_expiry = DEFAULT_MAX_EXPIRY; 27177 } 27178 } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) { 27179 min_expiry = atoi(v->value); 27180 if (min_expiry < 1) { 27181 min_expiry = DEFAULT_MIN_EXPIRY; 27182 } 27183 } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) { 27184 default_expiry = atoi(v->value); 27185 if (default_expiry < 1) { 27186 default_expiry = DEFAULT_DEFAULT_EXPIRY; 27187 } 27188 } else if (!strcasecmp(v->name, "mwiexpiry") || !strcasecmp(v->name, "mwiexpirey")) { 27189 mwi_expiry = atoi(v->value); 27190 if (mwi_expiry < 1) { 27191 mwi_expiry = DEFAULT_MWI_EXPIRY; 27192 } 27193 } else if (!strcasecmp(v->name, "tcpauthtimeout")) { 27194 if (ast_parse_arg(v->value, PARSE_INT32|PARSE_DEFAULT|PARSE_IN_RANGE, 27195 &authtimeout, DEFAULT_AUTHTIMEOUT, 1, INT_MAX)) { 27196 ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n", 27197 v->name, v->value, v->lineno, config); 27198 } 27199 } else if (!strcasecmp(v->name, "tcpauthlimit")) { 27200 if (ast_parse_arg(v->value, PARSE_INT32|PARSE_DEFAULT|PARSE_IN_RANGE, 27201 &authlimit, DEFAULT_AUTHLIMIT, 1, INT_MAX)) { 27202 ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n", 27203 v->name, v->value, v->lineno, config); 27204 } 27205 } else if (!strcasecmp(v->name, "sipdebug")) { 27206 if (ast_true(v->value)) 27207 sipdebug |= sip_debug_config; 27208 } else if (!strcasecmp(v->name, "dumphistory")) { 27209 dumphistory = ast_true(v->value); 27210 } else if (!strcasecmp(v->name, "recordhistory")) { 27211 recordhistory = ast_true(v->value); 27212 } else if (!strcasecmp(v->name, "registertimeout")) { 27213 global_reg_timeout = atoi(v->value); 27214 if (global_reg_timeout < 1) { 27215 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 27216 } 27217 } else if (!strcasecmp(v->name, "registerattempts")) { 27218 global_regattempts_max = atoi(v->value); 27219 } else if (!strcasecmp(v->name, "bindaddr") || !strcasecmp(v->name, "udpbindaddr")) { 27220 if (ast_parse_arg(v->value, PARSE_ADDR, &bindaddr)) { 27221 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 27222 } 27223 } else if (!strcasecmp(v->name, "localnet")) { 27224 struct ast_ha *na; 27225 int ha_error = 0; 27226 27227 if (!(na = ast_append_ha("d", v->value, localaddr, &ha_error))) { 27228 ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value); 27229 } else { 27230 localaddr = na; 27231 } 27232 if (ha_error) { 27233 ast_log(LOG_ERROR, "Bad localnet configuration value line %d : %s\n", v->lineno, v->value); 27234 } 27235 } else if (!strcasecmp(v->name, "media_address")) { 27236 if (ast_parse_arg(v->value, PARSE_ADDR, &media_address)) 27237 ast_log(LOG_WARNING, "Invalid address for media_address keyword: %s\n", v->value); 27238 } else if (!strcasecmp(v->name, "externaddr") || !strcasecmp(v->name, "externip")) { 27239 if (ast_parse_arg(v->value, PARSE_ADDR, &externaddr)) { 27240 ast_log(LOG_WARNING, 27241 "Invalid address for externaddr keyword: %s\n", 27242 v->value); 27243 } 27244 externexpire = 0; 27245 } else if (!strcasecmp(v->name, "externhost")) { 27246 ast_copy_string(externhost, v->value, sizeof(externhost)); 27247 if (ast_sockaddr_resolve_first(&externaddr, externhost, 0)) { 27248 ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost); 27249 } 27250 externexpire = time(NULL); 27251 } else if (!strcasecmp(v->name, "externrefresh")) { 27252 if (sscanf(v->value, "%30d", &externrefresh) != 1) { 27253 ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno); 27254 externrefresh = 10; 27255 } 27256 } else if (!strcasecmp(v->name, "externtcpport")) { 27257 if (!(externtcpport = port_str2int(v->value, 0))) { 27258 ast_log(LOG_WARNING, "Invalid externtcpport value, must be a positive integer between 1 and 65535 at line %d\n", v->lineno); 27259 externtcpport = 0; 27260 } 27261 } else if (!strcasecmp(v->name, "externtlsport")) { 27262 if (!(externtlsport = port_str2int(v->value, STANDARD_TLS_PORT))) { 27263 ast_log(LOG_WARNING, "Invalid externtlsport value, must be a positive integer between 1 and 65535 at line %d\n", v->lineno); 27264 } 27265 } else if (!strcasecmp(v->name, "allow")) { 27266 int error = ast_parse_allow_disallow(&default_prefs, &sip_cfg.capability, v->value, TRUE); 27267 if (error) { 27268 ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value); 27269 } 27270 } else if (!strcasecmp(v->name, "disallow")) { 27271 int error = ast_parse_allow_disallow(&default_prefs, &sip_cfg.capability, v->value, FALSE); 27272 if (error) { 27273 ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value); 27274 } 27275 } else if (!strcasecmp(v->name, "preferred_codec_only")) { 27276 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_PREFERRED_CODEC); 27277 } else if (!strcasecmp(v->name, "autoframing")) { 27278 global_autoframing = ast_true(v->value); 27279 } else if (!strcasecmp(v->name, "allowexternaldomains")) { 27280 sip_cfg.allow_external_domains = ast_true(v->value); 27281 } else if (!strcasecmp(v->name, "autodomain")) { 27282 auto_sip_domains = ast_true(v->value); 27283 } else if (!strcasecmp(v->name, "domain")) { 27284 char *domain = ast_strdupa(v->value); 27285 char *cntx = strchr(domain, ','); 27286 27287 if (cntx) { 27288 *cntx++ = '\0'; 27289 } 27290 27291 if (ast_strlen_zero(cntx)) { 27292 ast_debug(1, "No context specified at line %d for domain '%s'\n", v->lineno, domain); 27293 } 27294 if (ast_strlen_zero(domain)) { 27295 ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno); 27296 } else { 27297 add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, cntx ? ast_strip(cntx) : ""); 27298 } 27299 } else if (!strcasecmp(v->name, "register")) { 27300 if (sip_register(v->value, v->lineno) == 0) { 27301 registry_count++; 27302 } 27303 } else if (!strcasecmp(v->name, "mwi")) { 27304 sip_subscribe_mwi(v->value, v->lineno); 27305 } else if (!strcasecmp(v->name, "tos_sip")) { 27306 if (ast_str2tos(v->value, &global_tos_sip)) { 27307 ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, refer to QoS documentation\n", v->lineno); 27308 } 27309 } else if (!strcasecmp(v->name, "tos_audio")) { 27310 if (ast_str2tos(v->value, &global_tos_audio)) { 27311 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, refer to QoS documentation\n", v->lineno); 27312 } 27313 } else if (!strcasecmp(v->name, "tos_video")) { 27314 if (ast_str2tos(v->value, &global_tos_video)) { 27315 ast_log(LOG_WARNING, "Invalid tos_video value at line %d, refer to QoS documentation\n", v->lineno); 27316 } 27317 } else if (!strcasecmp(v->name, "tos_text")) { 27318 if (ast_str2tos(v->value, &global_tos_text)) { 27319 ast_log(LOG_WARNING, "Invalid tos_text value at line %d, refer to QoS documentation\n", v->lineno); 27320 } 27321 } else if (!strcasecmp(v->name, "cos_sip")) { 27322 if (ast_str2cos(v->value, &global_cos_sip)) { 27323 ast_log(LOG_WARNING, "Invalid cos_sip value at line %d, refer to QoS documentation\n", v->lineno); 27324 } 27325 } else if (!strcasecmp(v->name, "cos_audio")) { 27326 if (ast_str2cos(v->value, &global_cos_audio)) { 27327 ast_log(LOG_WARNING, "Invalid cos_audio value at line %d, refer to QoS documentation\n", v->lineno); 27328 } 27329 } else if (!strcasecmp(v->name, "cos_video")) { 27330 if (ast_str2cos(v->value, &global_cos_video)) { 27331 ast_log(LOG_WARNING, "Invalid cos_video value at line %d, refer to QoS documentation\n", v->lineno); 27332 } 27333 } else if (!strcasecmp(v->name, "cos_text")) { 27334 if (ast_str2cos(v->value, &global_cos_text)) { 27335 ast_log(LOG_WARNING, "Invalid cos_text value at line %d, refer to QoS documentation\n", v->lineno); 27336 } 27337 } else if (!strcasecmp(v->name, "bindport")) { 27338 if (sscanf(v->value, "%5d", &bindport) != 1) { 27339 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 27340 } 27341 } else if (!strcasecmp(v->name, "qualify")) { 27342 if (!strcasecmp(v->value, "no")) { 27343 default_qualify = 0; 27344 } else if (!strcasecmp(v->value, "yes")) { 27345 default_qualify = DEFAULT_MAXMS; 27346 } else if (sscanf(v->value, "%30d", &default_qualify) != 1) { 27347 ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno); 27348 default_qualify = 0; 27349 } 27350 } else if (!strcasecmp(v->name, "qualifyfreq")) { 27351 int i; 27352 if (sscanf(v->value, "%30d", &i) == 1) { 27353 global_qualifyfreq = i * 1000; 27354 } else { 27355 ast_log(LOG_WARNING, "Invalid qualifyfreq number '%s' at line %d of %s\n", v->value, v->lineno, config); 27356 global_qualifyfreq = DEFAULT_QUALIFYFREQ; 27357 } 27358 } else if (!strcasecmp(v->name, "callevents")) { 27359 sip_cfg.callevents = ast_true(v->value); 27360 } else if (!strcasecmp(v->name, "authfailureevents")) { 27361 global_authfailureevents = ast_true(v->value); 27362 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 27363 default_maxcallbitrate = atoi(v->value); 27364 if (default_maxcallbitrate < 0) 27365 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 27366 } else if (!strcasecmp(v->name, "matchexternaddrlocally") || !strcasecmp(v->name, "matchexterniplocally")) { 27367 sip_cfg.matchexternaddrlocally = ast_true(v->value); 27368 } else if (!strcasecmp(v->name, "session-timers")) { 27369 int i = (int) str2stmode(v->value); 27370 if (i < 0) { 27371 ast_log(LOG_WARNING, "Invalid session-timers '%s' at line %d of %s\n", v->value, v->lineno, config); 27372 global_st_mode = SESSION_TIMER_MODE_ACCEPT; 27373 } else { 27374 global_st_mode = i; 27375 } 27376 } else if (!strcasecmp(v->name, "session-expires")) { 27377 if (sscanf(v->value, "%30d", &global_max_se) != 1) { 27378 ast_log(LOG_WARNING, "Invalid session-expires '%s' at line %d of %s\n", v->value, v->lineno, config); 27379 global_max_se = DEFAULT_MAX_SE; 27380 } 27381 } else if (!strcasecmp(v->name, "session-minse")) { 27382 if (sscanf(v->value, "%30d", &global_min_se) != 1) { 27383 ast_log(LOG_WARNING, "Invalid session-minse '%s' at line %d of %s\n", v->value, v->lineno, config); 27384 global_min_se = DEFAULT_MIN_SE; 27385 } 27386 if (global_min_se < 90) { 27387 ast_log(LOG_WARNING, "session-minse '%s' at line %d of %s is not allowed to be < 90 secs\n", v->value, v->lineno, config); 27388 global_min_se = DEFAULT_MIN_SE; 27389 } 27390 } else if (!strcasecmp(v->name, "session-refresher")) { 27391 int i = (int) str2strefresher(v->value); 27392 if (i < 0) { 27393 ast_log(LOG_WARNING, "Invalid session-refresher '%s' at line %d of %s\n", v->value, v->lineno, config); 27394 global_st_refresher = SESSION_TIMER_REFRESHER_UAS; 27395 } else { 27396 global_st_refresher = i; 27397 } 27398 } else if (!strcasecmp(v->name, "qualifygap")) { 27399 if (sscanf(v->value, "%30d", &global_qualify_gap) != 1) { 27400 ast_log(LOG_WARNING, "Invalid qualifygap '%s' at line %d of %s\n", v->value, v->lineno, config); 27401 global_qualify_gap = DEFAULT_QUALIFY_GAP; 27402 } 27403 } else if (!strcasecmp(v->name, "qualifypeers")) { 27404 if (sscanf(v->value, "%30d", &global_qualify_peers) != 1) { 27405 ast_log(LOG_WARNING, "Invalid pokepeers '%s' at line %d of %s\n", v->value, v->lineno, config); 27406 global_qualify_peers = DEFAULT_QUALIFY_PEERS; 27407 } 27408 } else if (!strcasecmp(v->name, "disallowed_methods")) { 27409 char *disallow = ast_strdupa(v->value); 27410 mark_parsed_methods(&sip_cfg.disallowed_methods, disallow); 27411 } else if (!strcasecmp(v->name, "shrinkcallerid")) { 27412 if (ast_true(v->value)) { 27413 global_shrinkcallerid = 1; 27414 } else if (ast_false(v->value)) { 27415 global_shrinkcallerid = 0; 27416 } else { 27417 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno); 27418 } 27419 } else if (!strcasecmp(v->name, "use_q850_reason")) { 27420 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_Q850_REASON); 27421 } else if (!strcasecmp(v->name, "maxforwards")) { 27422 if ((sscanf(v->value, "%30d", &sip_cfg.default_max_forwards) != 1) || (sip_cfg.default_max_forwards < 1)) { 27423 ast_log(LOG_WARNING, "'%s' is not a valid maxforwards value at line %d. Using default.\n", v->value, v->lineno); 27424 sip_cfg.default_max_forwards = DEFAULT_MAX_FORWARDS; 27425 } 27426 } else if (!strcasecmp(v->name, "subscribe_network_change_event")) { 27427 if (ast_true(v->value)) { 27428 subscribe_network_change = 1; 27429 } else if (ast_false(v->value)) { 27430 subscribe_network_change = 0; 27431 } else { 27432 ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno); 27433 } 27434 } else if (!strcasecmp(v->name, "snom_aoc_enabled")) { 27435 ast_set2_flag(&global_flags[2], ast_true(v->value), SIP_PAGE3_SNOM_AOC); 27436 } else if (!strcasecmp(v->name, "parkinglot")) { 27437 ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot)); 27438 } 27439 } 27440 27441 if (subscribe_network_change) { 27442 network_change_event_subscribe(); 27443 } else { 27444 network_change_event_unsubscribe(); 27445 } 27446 27447 if (global_t1 < global_t1min) { 27448 ast_log(LOG_WARNING, "'t1min' (%d) cannot be greater than 't1timer' (%d). Resetting 't1timer' to the value of 't1min'\n", global_t1min, global_t1); 27449 global_t1 = global_t1min; 27450 } 27451 27452 if (global_timer_b < global_t1 * 64) { 27453 if (timerb_set && timert1_set) { 27454 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); 27455 } else if (timerb_set) { 27456 if ((global_t1 = global_timer_b / 64) < global_t1min) { 27457 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); 27458 global_t1 = global_t1min; 27459 global_timer_b = global_t1 * 64; 27460 } 27461 } else { 27462 global_timer_b = global_t1 * 64; 27463 } 27464 } 27465 if (!sip_cfg.allow_external_domains && AST_LIST_EMPTY(&domain_list)) { 27466 ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n"); 27467 sip_cfg.allow_external_domains = 1; 27468 } 27469 /* If not configured, set default transports */ 27470 if (default_transports == 0) { 27471 default_transports = default_primary_transport = SIP_TRANSPORT_UDP; 27472 } 27473 27474 /* Build list of authentication to various SIP realms, i.e. service providers */ 27475 for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) { 27476 /* Format for authentication is auth = username:password@realm */ 27477 if (!strcasecmp(v->name, "auth")) { 27478 authl = add_realm_authentication(authl, v->value, v->lineno); 27479 } 27480 } 27481 27482 if (bindport) { 27483 if (ast_sockaddr_port(&bindaddr)) { 27484 ast_log(LOG_WARNING, "bindport is also specified in bindaddr. " 27485 "Using %d.\n", bindport); 27486 } 27487 ast_sockaddr_set_port(&bindaddr, bindport); 27488 } 27489 27490 if (!ast_sockaddr_port(&bindaddr)) { 27491 ast_sockaddr_set_port(&bindaddr, STANDARD_SIP_PORT); 27492 } 27493 27494 /* Set UDP address and open socket */ 27495 ast_sockaddr_copy(&internip, &bindaddr); 27496 if (ast_find_ourip(&internip, &bindaddr, 0)) { 27497 ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n"); 27498 ast_config_destroy(cfg); 27499 return 0; 27500 } 27501 27502 ast_mutex_lock(&netlock); 27503 if ((sipsock > -1) && (ast_sockaddr_cmp(&old_bindaddr, &bindaddr))) { 27504 close(sipsock); 27505 sipsock = -1; 27506 } 27507 if (sipsock < 0) { 27508 sipsock = socket(ast_sockaddr_is_ipv6(&bindaddr) ? 27509 AF_INET6 : AF_INET, SOCK_DGRAM, 0); 27510 if (sipsock < 0) { 27511 ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno)); 27512 ast_config_destroy(cfg); 27513 ast_mutex_unlock(&netlock); 27514 return -1; 27515 } else { 27516 /* Allow SIP clients on the same host to access us: */ 27517 const int reuseFlag = 1; 27518 27519 setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR, 27520 (const char*)&reuseFlag, 27521 sizeof reuseFlag); 27522 27523 ast_enable_packet_fragmentation(sipsock); 27524 27525 if (ast_bind(sipsock, &bindaddr) < 0) { 27526 ast_log(LOG_WARNING, "Failed to bind to %s: %s\n", 27527 ast_sockaddr_stringify(&bindaddr), strerror(errno)); 27528 close(sipsock); 27529 sipsock = -1; 27530 } else { 27531 ast_verb(2, "SIP Listening on %s\n", ast_sockaddr_stringify(&bindaddr)); 27532 ast_set_qos(sipsock, global_tos_sip, global_cos_sip, "SIP"); 27533 } 27534 } 27535 } else { 27536 ast_set_qos(sipsock, global_tos_sip, global_cos_sip, "SIP"); 27537 } 27538 ast_mutex_unlock(&netlock); 27539 27540 /* Start TCP server */ 27541 if (sip_cfg.tcp_enabled) { 27542 if (ast_sockaddr_isnull(&sip_tcp_desc.local_address)) { 27543 ast_sockaddr_copy(&sip_tcp_desc.local_address, &bindaddr); 27544 } 27545 if (!ast_sockaddr_port(&sip_tcp_desc.local_address)) { 27546 ast_sockaddr_set_port(&sip_tcp_desc.local_address, STANDARD_SIP_PORT); 27547 } 27548 } else { 27549 ast_sockaddr_setnull(&sip_tcp_desc.local_address); 27550 } 27551 ast_tcptls_server_start(&sip_tcp_desc); 27552 if (sip_cfg.tcp_enabled && sip_tcp_desc.accept_fd == -1) { 27553 /* TCP server start failed. Tell the admin */ 27554 ast_log(LOG_ERROR, "SIP TCP Server start failed. Not listening on TCP socket.\n"); 27555 } else { 27556 ast_debug(2, "SIP TCP server started\n"); 27557 } 27558 27559 /* Start TLS server if needed */ 27560 memcpy(sip_tls_desc.tls_cfg, &default_tls_cfg, sizeof(default_tls_cfg)); 27561 27562 if (ast_ssl_setup(sip_tls_desc.tls_cfg)) { 27563 if (ast_sockaddr_isnull(&sip_tls_desc.local_address)) { 27564 ast_sockaddr_copy(&sip_tls_desc.local_address, &bindaddr); 27565 ast_sockaddr_set_port(&sip_tls_desc.local_address, 27566 STANDARD_TLS_PORT); 27567 } 27568 if (!ast_sockaddr_port(&sip_tls_desc.local_address)) { 27569 ast_sockaddr_set_port(&sip_tls_desc.local_address, 27570 STANDARD_TLS_PORT); 27571 } 27572 ast_tcptls_server_start(&sip_tls_desc); 27573 if (default_tls_cfg.enabled && sip_tls_desc.accept_fd == -1) { 27574 ast_log(LOG_ERROR, "TLS Server start failed. Not listening on TLS socket.\n"); 27575 sip_tls_desc.tls_cfg = NULL; 27576 } 27577 } else if (sip_tls_desc.tls_cfg->enabled) { 27578 sip_tls_desc.tls_cfg = NULL; 27579 ast_log(LOG_WARNING, "SIP TLS server did not load because of errors.\n"); 27580 } 27581 27582 if (ucfg) { 27583 struct ast_variable *gen; 27584 int genhassip, genregistersip; 27585 const char *hassip, *registersip; 27586 27587 genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip")); 27588 genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip")); 27589 gen = ast_variable_browse(ucfg, "general"); 27590 cat = ast_category_browse(ucfg, NULL); 27591 while (cat) { 27592 if (strcasecmp(cat, "general")) { 27593 hassip = ast_variable_retrieve(ucfg, cat, "hassip"); 27594 registersip = ast_variable_retrieve(ucfg, cat, "registersip"); 27595 if (ast_true(hassip) || (!hassip && genhassip)) { 27596 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0, 0); 27597 if (peer) { 27598 /* user.conf entries are always of type friend */ 27599 peer->type = SIP_TYPE_USER | SIP_TYPE_PEER; 27600 ao2_t_link(peers, peer, "link peer into peer table"); 27601 if ((peer->type & SIP_TYPE_PEER) && !ast_sockaddr_isnull(&peer->addr)) { 27602 ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table"); 27603 } 27604 27605 unref_peer(peer, "unref_peer: from reload_config"); 27606 peer_count++; 27607 } 27608 } 27609 if (ast_true(registersip) || (!registersip && genregistersip)) { 27610 char tmp[256]; 27611 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 27612 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 27613 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 27614 const char *contact = ast_variable_retrieve(ucfg, cat, "contact"); 27615 const char *authuser = ast_variable_retrieve(ucfg, cat, "authuser"); 27616 if (!host) { 27617 host = ast_variable_retrieve(ucfg, "general", "host"); 27618 } 27619 if (!username) { 27620 username = ast_variable_retrieve(ucfg, "general", "username"); 27621 } 27622 if (!secret) { 27623 secret = ast_variable_retrieve(ucfg, "general", "secret"); 27624 } 27625 if (!contact) { 27626 contact = "s"; 27627 } 27628 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 27629 if (!ast_strlen_zero(secret)) { 27630 if (!ast_strlen_zero(authuser)) { 27631 snprintf(tmp, sizeof(tmp), "%s?%s:%s:%s@%s/%s", cat, username, secret, authuser, host, contact); 27632 } else { 27633 snprintf(tmp, sizeof(tmp), "%s?%s:%s@%s/%s", cat, username, secret, host, contact); 27634 } 27635 } else if (!ast_strlen_zero(authuser)) { 27636 snprintf(tmp, sizeof(tmp), "%s?%s::%s@%s/%s", cat, username, authuser, host, contact); 27637 } else { 27638 snprintf(tmp, sizeof(tmp), "%s?%s@%s/%s", cat, username, host, contact); 27639 } 27640 if (sip_register(tmp, 0) == 0) { 27641 registry_count++; 27642 } 27643 } 27644 } 27645 } 27646 cat = ast_category_browse(ucfg, cat); 27647 } 27648 ast_config_destroy(ucfg); 27649 } 27650 27651 /* Load peers, users and friends */ 27652 cat = NULL; 27653 while ( (cat = ast_category_browse(cfg, cat)) ) { 27654 const char *utype; 27655 if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication")) 27656 continue; 27657 utype = ast_variable_retrieve(cfg, cat, "type"); 27658 if (!utype) { 27659 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 27660 continue; 27661 } else { 27662 if (!strcasecmp(utype, "user")) { 27663 ; 27664 } else if (!strcasecmp(utype, "friend")) { 27665 ; 27666 } else if (!strcasecmp(utype, "peer")) { 27667 ; 27668 } else { 27669 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf"); 27670 continue; 27671 } 27672 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0, 0); 27673 if (peer) { 27674 ao2_t_link(peers, peer, "link peer into peers table"); 27675 if ((peer->type & SIP_TYPE_PEER) && !ast_sockaddr_isnull(&peer->addr)) { 27676 ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table"); 27677 } 27678 unref_peer(peer, "unref the result of the build_peer call. Now, the links from the tables are the only ones left."); 27679 peer_count++; 27680 } 27681 } 27682 } 27683 27684 /* Add default domains - host name, IP address and IP:port 27685 * Only do this if user added any sip domain with "localdomains" 27686 * In order to *not* break backwards compatibility 27687 * Some phones address us at IP only, some with additional port number 27688 */ 27689 if (auto_sip_domains) { 27690 char temp[MAXHOSTNAMELEN]; 27691 27692 /* First our default IP address */ 27693 if (!ast_sockaddr_isnull(&bindaddr) && !ast_sockaddr_is_any(&bindaddr)) { 27694 add_sip_domain(ast_sockaddr_stringify_addr(&bindaddr), 27695 SIP_DOMAIN_AUTO, NULL); 27696 } else if (!ast_sockaddr_isnull(&internip) && !ast_sockaddr_is_any(&internip)) { 27697 /* Our internal IP address, if configured */ 27698 add_sip_domain(ast_sockaddr_stringify_addr(&internip), 27699 SIP_DOMAIN_AUTO, NULL); 27700 } else { 27701 ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n"); 27702 } 27703 27704 /* If TCP is running on a different IP than UDP, then add it too */ 27705 if (!ast_sockaddr_isnull(&sip_tcp_desc.local_address) && 27706 !ast_sockaddr_cmp(&bindaddr, &sip_tcp_desc.local_address)) { 27707 add_sip_domain(ast_sockaddr_stringify_addr(&sip_tcp_desc.local_address), 27708 SIP_DOMAIN_AUTO, NULL); 27709 } 27710 27711 /* If TLS is running on a different IP than UDP and TCP, then add that too */ 27712 if (!ast_sockaddr_isnull(&sip_tls_desc.local_address) && 27713 !ast_sockaddr_cmp(&bindaddr, &sip_tls_desc.local_address) && 27714 !ast_sockaddr_cmp(&sip_tcp_desc.local_address, 27715 &sip_tls_desc.local_address)) { 27716 add_sip_domain(ast_sockaddr_stringify_addr(&sip_tcp_desc.local_address), 27717 SIP_DOMAIN_AUTO, NULL); 27718 } 27719 27720 /* Our extern IP address, if configured */ 27721 if (!ast_sockaddr_isnull(&externaddr)) { 27722 add_sip_domain(ast_sockaddr_stringify_addr(&externaddr), 27723 SIP_DOMAIN_AUTO, NULL); 27724 } 27725 27726 /* Extern host name (NAT traversal support) */ 27727 if (!ast_strlen_zero(externhost)) { 27728 add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL); 27729 } 27730 27731 /* Our host name */ 27732 if (!gethostname(temp, sizeof(temp))) { 27733 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 27734 } 27735 } 27736 27737 /* Release configuration from memory */ 27738 ast_config_destroy(cfg); 27739 27740 /* Load the list of manual NOTIFY types to support */ 27741 if (notify_types) 27742 ast_config_destroy(notify_types); 27743 if ((notify_types = ast_config_load(notify_config, config_flags)) == CONFIG_STATUS_FILEINVALID) { 27744 ast_log(LOG_ERROR, "Contents of %s are invalid and cannot be parsed.\n", notify_config); 27745 notify_types = NULL; 27746 } 27747 27748 /* Done, tell the manager */ 27749 manager_event(EVENT_FLAG_SYSTEM, "ChannelReload", "ChannelType: SIP\r\nReloadReason: %s\r\nRegistry_Count: %d\r\nPeer_Count: %d\r\n", channelreloadreason2txt(reason), registry_count, peer_count); 27750 run_end = time(0); 27751 ast_debug(4, "SIP reload_config done...Runtime= %d sec\n", (int)(run_end-run_start)); 27752 27753 return 0; 27754 }
| static char * remove_uri_parameters | ( | char * | uri | ) | [static] |
Definition at line 11281 of file chan_sip.c.
Referenced by extract_uri(), parse_moved_contact(), register_verify(), reqprep(), and transmit_state_notify().
11282 { 11283 char *atsign; 11284 atsign = strchr(uri, '@'); /* First, locate the at sign */ 11285 if (!atsign) { 11286 atsign = uri; /* Ok hostname only, let's stick with the rest */ 11287 } 11288 atsign = strchr(atsign, ';'); /* Locate semi colon */ 11289 if (atsign) 11290 *atsign = '\0'; /* Kill at the semi colon */ 11291 return uri; 11292 }
| static int reply_digest | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| char * | header, | |||
| int | sipmethod, | |||
| char * | digest, | |||
| int | digest_len | |||
| ) | [static] |
reply to authentication for outbound registrations
Definition at line 18278 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_skip_blanks(), ast_string_field_ptr_set, ast_string_field_set, ast_strlen_zero(), build_reply_digest(), get_header(), LOG_WARNING, and strsep().
Referenced by do_proxy_auth(), and do_register_auth().
18279 { 18280 char tmp[512]; 18281 char *c; 18282 char oldnonce[256]; 18283 18284 /* table of recognised keywords, and places where they should be copied */ 18285 const struct x { 18286 const char *key; 18287 const ast_string_field *field; 18288 } *i, keys[] = { 18289 { "realm=", &p->realm }, 18290 { "nonce=", &p->nonce }, 18291 { "opaque=", &p->opaque }, 18292 { "qop=", &p->qop }, 18293 { "domain=", &p->domain }, 18294 { NULL, 0 }, 18295 }; 18296 18297 ast_copy_string(tmp, get_header(req, header), sizeof(tmp)); 18298 if (ast_strlen_zero(tmp)) 18299 return -1; 18300 if (strncasecmp(tmp, "Digest ", strlen("Digest "))) { 18301 ast_log(LOG_WARNING, "missing Digest.\n"); 18302 return -1; 18303 } 18304 c = tmp + strlen("Digest "); 18305 ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce)); 18306 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 18307 for (i = keys; i->key != NULL; i++) { 18308 char *src, *separator; 18309 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 18310 continue; 18311 /* Found. Skip keyword, take text in quotes or up to the separator. */ 18312 c += strlen(i->key); 18313 if (*c == '"') { 18314 src = ++c; 18315 separator = "\""; 18316 } else { 18317 src = c; 18318 separator = ","; 18319 } 18320 strsep(&c, separator); /* clear separator and move ptr */ 18321 ast_string_field_ptr_set(p, i->field, src); 18322 break; 18323 } 18324 if (i->key == NULL) /* not found, try ',' */ 18325 strsep(&c, ","); 18326 } 18327 /* Reset nonce count */ 18328 if (strcmp(p->nonce, oldnonce)) 18329 p->noncecount = 0; 18330 18331 /* Save auth data for following registrations */ 18332 if (p->registry) { 18333 struct sip_registry *r = p->registry; 18334 18335 if (strcmp(r->nonce, p->nonce)) { 18336 ast_string_field_set(r, realm, p->realm); 18337 ast_string_field_set(r, nonce, p->nonce); 18338 ast_string_field_set(r, authdomain, p->domain); 18339 ast_string_field_set(r, opaque, p->opaque); 18340 ast_string_field_set(r, qop, p->qop); 18341 r->noncecount = 0; 18342 } 18343 } 18344 return build_reply_digest(p, sipmethod, digest, digest_len); 18345 }
| static int reqprep | ( | struct sip_request * | req, | |
| struct sip_pvt * | p, | |||
| int | sipmethod, | |||
| int | seqno, | |||
| int | newbranch | |||
| ) | [static] |
Initialize a SIP request message (not the initial one in a dialog).
< Strict routing flag
Definition at line 9788 of file chan_sip.c.
References add_header(), add_header_max_forwards(), add_route(), ast_copy_string(), ast_debug, ast_random(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, build_via(), copy_header(), FALSE, get_header(), global_useragent, init_req(), remove_uri_parameters(), set_destination(), sip_methods, st_get_se(), strcasestr(), strefresher2str(), text, cfsip_methods::text, TRUE, and url.
09789 { 09790 struct sip_request *orig = &p->initreq; 09791 char stripped[80]; 09792 char tmp[80]; 09793 char newto[256]; 09794 const char *c; 09795 const char *ot, *of; 09796 int is_strict = FALSE; /*!< Strict routing flag */ 09797 int is_outbound = ast_test_flag(&p->flags[0], SIP_OUTGOING); /* Session direction */ 09798 09799 memset(req, 0, sizeof(struct sip_request)); 09800 09801 snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text); 09802 09803 if (!seqno) { 09804 p->ocseq++; 09805 seqno = p->ocseq; 09806 } 09807 09808 /* A CANCEL must have the same branch as the INVITE that it is canceling. */ 09809 if (sipmethod == SIP_CANCEL) { 09810 p->branch = p->invite_branch; 09811 build_via(p); 09812 } else if (newbranch && (sipmethod == SIP_INVITE)) { 09813 p->branch ^= ast_random(); 09814 p->invite_branch = p->branch; 09815 build_via(p); 09816 } else if (newbranch) { 09817 p->branch ^= ast_random(); 09818 build_via(p); 09819 } 09820 09821 /* Check for strict or loose router */ 09822 if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop, ";lr") == NULL) { 09823 is_strict = TRUE; 09824 if (sipdebug) 09825 ast_debug(1, "Strict routing enforced for session %s\n", p->callid); 09826 } 09827 09828 if (sipmethod == SIP_CANCEL) 09829 c = REQ_OFFSET_TO_STR(&p->initreq, rlPart2); /* Use original URI */ 09830 else if (sipmethod == SIP_ACK) { 09831 /* Use URI from Contact: in 200 OK (if INVITE) 09832 (we only have the contacturi on INVITEs) */ 09833 if (!ast_strlen_zero(p->okcontacturi)) 09834 c = is_strict ? p->route->hop : p->okcontacturi; 09835 else 09836 c = REQ_OFFSET_TO_STR(&p->initreq, rlPart2); 09837 } else if (!ast_strlen_zero(p->okcontacturi)) 09838 c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */ 09839 else if (!ast_strlen_zero(p->uri)) 09840 c = p->uri; 09841 else { 09842 char *n; 09843 /* We have no URI, use To: or From: header as URI (depending on direction) */ 09844 ast_copy_string(stripped, get_header(orig, is_outbound ? "To" : "From"), 09845 sizeof(stripped)); 09846 n = get_in_brackets(stripped); 09847 c = remove_uri_parameters(n); 09848 } 09849 init_req(req, sipmethod, c); 09850 09851 snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text); 09852 09853 add_header(req, "Via", p->via); 09854 if (p->route) { 09855 set_destination(p, p->route->hop); 09856 add_route(req, is_strict ? p->route->next : p->route); 09857 } 09858 add_header_max_forwards(p, req); 09859 09860 ot = get_header(orig, "To"); 09861 of = get_header(orig, "From"); 09862 09863 /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly 09864 as our original request, including tag (or presumably lack thereof) */ 09865 if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) { 09866 /* Add the proper tag if we don't have it already. If they have specified 09867 their tag, use it. Otherwise, use our own tag */ 09868 if (is_outbound && !ast_strlen_zero(p->theirtag)) 09869 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 09870 else if (!is_outbound) 09871 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 09872 else 09873 snprintf(newto, sizeof(newto), "%s", ot); 09874 ot = newto; 09875 } 09876 09877 if (is_outbound) { 09878 add_header(req, "From", of); 09879 add_header(req, "To", ot); 09880 } else { 09881 add_header(req, "From", ot); 09882 add_header(req, "To", of); 09883 } 09884 /* Do not add Contact for MESSAGE, BYE and Cancel requests */ 09885 if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE) 09886 add_header(req, "Contact", p->our_contact); 09887 09888 copy_header(req, orig, "Call-ID"); 09889 add_header(req, "CSeq", tmp); 09890 09891 if (!ast_strlen_zero(global_useragent)) 09892 add_header(req, "User-Agent", global_useragent); 09893 09894 if (!ast_strlen_zero(p->url)) { 09895 add_header(req, "Access-URL", p->url); 09896 ast_string_field_set(p, url, NULL); 09897 } 09898 09899 /* Add Session-Timers related headers if the feature is active for this session. 09900 An exception to this behavior is the ACK request. Since Asterisk never requires 09901 session-timers support from a remote end-point (UAS) in an INVITE, it must 09902 not send 'Require: timer' header in the ACK request. 09903 This should only be added in the INVITE transactions, not MESSAGE or REFER or other 09904 in-dialog messages. 09905 */ 09906 if (p->stimer && p->stimer->st_active == TRUE && p->stimer->st_active_peer_ua == TRUE 09907 && sipmethod == SIP_INVITE) { 09908 char se_hdr[256]; 09909 snprintf(se_hdr, sizeof(se_hdr), "%d;refresher=%s", p->stimer->st_interval, 09910 strefresher2str(p->stimer->st_ref)); 09911 add_header(req, "Require", "timer"); 09912 add_header(req, "Session-Expires", se_hdr); 09913 snprintf(se_hdr, sizeof(se_hdr), "%d", st_get_se(p, FALSE)); 09914 add_header(req, "Min-SE", se_hdr); 09915 } 09916 09917 return 0; 09918 }
| static int resp_needs_contact | ( | const char * | msg, | |
| enum sipmethod | method | |||
| ) | [inline, static] |
Test if this response needs a contact header.
Definition at line 9651 of file chan_sip.c.
Referenced by respprep().
09651 { 09652 /* Requirements for Contact header inclusion in responses generated 09653 * from the header tables found in the following RFCs. Where the 09654 * Contact header was marked mandatory (m) or optional (o) this 09655 * function returns 1. 09656 * 09657 * - RFC 3261 (ACK, BYE, CANCEL, INVITE, OPTIONS, REGISTER) 09658 * - RFC 2976 (INFO) 09659 * - RFC 3262 (PRACK) 09660 * - RFC 3265 (SUBSCRIBE, NOTIFY) 09661 * - RFC 3311 (UPDATE) 09662 * - RFC 3428 (MESSAGE) 09663 * - RFC 3515 (REFER) 09664 * - RFC 3903 (PUBLISH) 09665 */ 09666 09667 switch (method) { 09668 /* 1xx, 2xx, 3xx, 485 */ 09669 case SIP_INVITE: 09670 case SIP_UPDATE: 09671 case SIP_SUBSCRIBE: 09672 case SIP_NOTIFY: 09673 if ((msg[0] >= '1' && msg[0] <= '3') || !strncmp(msg, "485", 3)) 09674 return 1; 09675 break; 09676 09677 /* 2xx, 3xx, 485 */ 09678 case SIP_REGISTER: 09679 case SIP_OPTIONS: 09680 if (msg[0] == '2' || msg[0] == '3' || !strncmp(msg, "485", 3)) 09681 return 1; 09682 break; 09683 09684 /* 3xx, 485 */ 09685 case SIP_BYE: 09686 case SIP_PRACK: 09687 case SIP_MESSAGE: 09688 case SIP_PUBLISH: 09689 if (msg[0] == '3' || !strncmp(msg, "485", 3)) 09690 return 1; 09691 break; 09692 09693 /* 2xx, 3xx, 4xx, 5xx, 6xx */ 09694 case SIP_REFER: 09695 if (msg[0] >= '2' && msg[0] <= '6') 09696 return 1; 09697 break; 09698 09699 /* contact will not be included for everything else */ 09700 case SIP_ACK: 09701 case SIP_CANCEL: 09702 case SIP_INFO: 09703 case SIP_PING: 09704 default: 09705 return 0; 09706 } 09707 return 0; 09708 }
| 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 9711 of file chan_sip.c.
References add_header(), add_supported_header(), ast_copy_string(), ast_log(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, copy_all_header(), copy_header(), copy_via_headers(), get_header(), global_useragent, init_resp(), LOG_WARNING, process_via(), resp_needs_contact(), strcasestr(), strefresher2str(), TRUE, and url.
09712 { 09713 char newto[256]; 09714 const char *ot; 09715 09716 init_resp(resp, msg); 09717 copy_via_headers(p, resp, req, "Via"); 09718 if (msg[0] == '1' || msg[0] == '2') 09719 copy_all_header(resp, req, "Record-Route"); 09720 copy_header(resp, req, "From"); 09721 ot = get_header(req, "To"); 09722 if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) { 09723 /* Add the proper tag if we don't have it already. If they have specified 09724 their tag, use it. Otherwise, use our own tag */ 09725 if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING)) 09726 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 09727 else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) 09728 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 09729 else 09730 ast_copy_string(newto, ot, sizeof(newto)); 09731 ot = newto; 09732 } 09733 add_header(resp, "To", ot); 09734 copy_header(resp, req, "Call-ID"); 09735 copy_header(resp, req, "CSeq"); 09736 if (!ast_strlen_zero(global_useragent)) 09737 add_header(resp, "Server", global_useragent); 09738 add_header(resp, "Allow", ALLOWED_METHODS); 09739 add_supported_header(p, resp); 09740 09741 /* If this is an invite, add Session-Timers related headers if the feature is active for this session */ 09742 if (p->method == SIP_INVITE && p->stimer && p->stimer->st_active == TRUE && p->stimer->st_active_peer_ua == TRUE) { 09743 char se_hdr[256]; 09744 snprintf(se_hdr, sizeof(se_hdr), "%d;refresher=%s", p->stimer->st_interval, 09745 strefresher2str(p->stimer->st_ref)); 09746 add_header(resp, "Session-Expires", se_hdr); 09747 } 09748 09749 if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) { 09750 /* For registration responses, we also need expiry and 09751 contact info */ 09752 char tmp[256]; 09753 09754 snprintf(tmp, sizeof(tmp), "%d", p->expiry); 09755 add_header(resp, "Expires", tmp); 09756 if (p->expiry) { /* Only add contact if we have an expiry time */ 09757 char contact[SIPBUFSIZE]; 09758 const char *contact_uri = p->method == SIP_SUBSCRIBE ? p->our_contact : p->fullcontact; 09759 char *brackets = strchr(contact_uri, '<'); 09760 snprintf(contact, sizeof(contact), "%s%s%s;expires=%d", brackets ? "" : "<", contact_uri, brackets ? "" : ">", p->expiry); 09761 add_header(resp, "Contact", contact); /* Not when we unregister */ 09762 } 09763 } else if (!ast_strlen_zero(p->our_contact) && resp_needs_contact(msg, p->method)) { 09764 add_header(resp, "Contact", p->our_contact); 09765 } 09766 09767 if (!ast_strlen_zero(p->url)) { 09768 add_header(resp, "Access-URL", p->url); 09769 ast_string_field_set(p, url, NULL); 09770 } 09771 09772 /* default to routing the response to the address where the request 09773 * came from. Since we don't have a transport layer, we do this here. 09774 * The process_via() function will update the port to either the port 09775 * specified in the via header or the default port later on (per RFC 09776 * 3261 section 18.2.2). 09777 */ 09778 p->sa = p->recv; 09779 09780 if (process_via(p, req)) { 09781 ast_log(LOG_WARNING, "error processing via header, will send response to originating address\n"); 09782 } 09783 09784 return 0; 09785 }
| static int restart_monitor | ( | void | ) | [static] |
Start the channel monitor thread.
Definition at line 24735 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, and monlock.
24736 { 24737 /* If we're supposed to be stopped -- stay stopped */ 24738 if (monitor_thread == AST_PTHREADT_STOP) 24739 return 0; 24740 ast_mutex_lock(&monlock); 24741 if (monitor_thread == pthread_self()) { 24742 ast_mutex_unlock(&monlock); 24743 ast_log(LOG_WARNING, "Cannot kill myself\n"); 24744 return -1; 24745 } 24746 if (monitor_thread != AST_PTHREADT_NULL) { 24747 /* Wake up the thread */ 24748 pthread_kill(monitor_thread, SIGURG); 24749 } else { 24750 /* Start a new monitor */ 24751 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 24752 ast_mutex_unlock(&monlock); 24753 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 24754 return -1; 24755 } 24756 } 24757 ast_mutex_unlock(&monlock); 24758 return 0; 24759 }
| static void restart_session_timer | ( | struct sip_pvt * | p | ) | [static] |
Session-Timers: Restart session timer.
Definition at line 24763 of file chan_sip.c.
References ast_debug, ast_log(), AST_SCHED_DEL_UNREF, LOG_WARNING, start_session_timer(), and TRUE.
Referenced by handle_request_invite().
24764 { 24765 if (!p->stimer) { 24766 ast_log(LOG_WARNING, "Null stimer in restart_session_timer - %s\n", p->callid); 24767 return; 24768 } 24769 24770 if (p->stimer->st_active == TRUE) { 24771 AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid, 24772 dialog_unref(p, "Removing session timer ref")); 24773 ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid); 24774 start_session_timer(p); 24775 } 24776 }
| static int retrans_pkt | ( | const void * | data | ) | [static] |
Retransmit SIP message if no answer (Called from scheduler).
Definition at line 3460 of file chan_sip.c.
References __sip_xmit(), append_history, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_PROTOCOL_ERROR, ast_channel_trylock, ast_channel_unlock, ast_debug, ast_free, ast_log(), ast_queue_hangup_with_cause(), ast_sockaddr_stringify(), ast_test_flag, ast_tvdiff_ms(), ast_tvnow(), ast_verbose, DEFAULT_RETRANS, LOG_WARNING, pvt_set_needdestroy(), sip_alreadygone(), sip_debug_test_pvt(), sip_methods, sip_nat_mode(), sip_pvt_lock, sip_pvt_unlock, sip_real_dst(), sipdebug, cfsip_methods::text, and UNLINK.
03461 { 03462 struct sip_pkt *pkt = (struct sip_pkt *)data, *prev, *cur = NULL; 03463 int reschedule = DEFAULT_RETRANS; 03464 int xmitres = 0; 03465 /* how many ms until retrans timeout is reached */ 03466 int64_t diff = pkt->retrans_stop_time - ast_tvdiff_ms(ast_tvnow(), pkt->time_sent); 03467 03468 /* Do not retransmit if time out is reached. This will be negative if the time between 03469 * the first transmission and now is larger than our timeout period. This is a fail safe 03470 * check in case the scheduler gets behind or the clock is changed. */ 03471 if ((diff <= 0) || (diff > pkt->retrans_stop_time)) { 03472 pkt->retrans_stop = 1; 03473 } 03474 03475 /* Lock channel PVT */ 03476 sip_pvt_lock(pkt->owner); 03477 03478 if (!pkt->retrans_stop) { 03479 pkt->retrans++; 03480 if (!pkt->timer_t1) { /* Re-schedule using timer_a and timer_t1 */ 03481 if (sipdebug) { 03482 ast_debug(4, "SIP TIMER: Not rescheduling id #%d:%s (Method %d) (No timer T1)\n", 03483 pkt->retransid, 03484 sip_methods[pkt->method].text, 03485 pkt->method); 03486 } 03487 } else { 03488 int siptimer_a; 03489 03490 if (sipdebug) { 03491 ast_debug(4, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", 03492 pkt->retransid, 03493 pkt->retrans, 03494 sip_methods[pkt->method].text, 03495 pkt->method); 03496 } 03497 if (!pkt->timer_a) { 03498 pkt->timer_a = 2 ; 03499 } else { 03500 pkt->timer_a = 2 * pkt->timer_a; 03501 } 03502 03503 /* For non-invites, a maximum of 4 secs */ 03504 siptimer_a = pkt->timer_t1 * pkt->timer_a; /* Double each time */ 03505 if (pkt->method != SIP_INVITE && siptimer_a > 4000) { 03506 siptimer_a = 4000; 03507 } 03508 03509 /* Reschedule re-transmit */ 03510 reschedule = siptimer_a; 03511 ast_debug(4, "** SIP timers: Rescheduling retransmission %d to %d ms (t1 %d ms (Retrans id #%d)) \n", 03512 pkt->retrans + 1, 03513 siptimer_a, 03514 pkt->timer_t1, 03515 pkt->retransid); 03516 } 03517 03518 if (sip_debug_test_pvt(pkt->owner)) { 03519 const struct ast_sockaddr *dst = sip_real_dst(pkt->owner); 03520 ast_verbose("Retransmitting #%d (%s) to %s:\n%s\n---\n", 03521 pkt->retrans, sip_nat_mode(pkt->owner), 03522 ast_sockaddr_stringify(dst), 03523 pkt->data->str); 03524 } 03525 03526 append_history(pkt->owner, "ReTx", "%d %s", reschedule, pkt->data->str); 03527 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); 03528 03529 /* If there was no error during the network transmission, schedule the next retransmission, 03530 * but if the next retransmission is going to be beyond our timeout period, mark the packet's 03531 * stop_retrans value and set the next retransmit to be the exact time of timeout. This will 03532 * allow any responses to the packet to be processed before the packet is destroyed on the next 03533 * call to this function by the scheduler. */ 03534 if (xmitres != XMIT_ERROR) { 03535 if (reschedule >= diff) { 03536 pkt->retrans_stop = 1; 03537 reschedule = diff; 03538 } 03539 sip_pvt_unlock(pkt->owner); 03540 return reschedule; 03541 } 03542 } 03543 03544 /* At this point, either the packet's retransmission timed out, or there was a 03545 * transmission error, either way destroy the scheduler item and this packet. */ 03546 03547 pkt->retransid = -1; /* Kill this scheduler item */ 03548 03549 if (pkt->owner && pkt->method != SIP_OPTIONS && xmitres == 0) { 03550 if (pkt->is_fatal || sipdebug) { /* Tell us if it's critical or if we're debugging */ 03551 ast_log(LOG_WARNING, "Retransmission timeout reached on transmission %s for seqno %d (%s %s) -- See https://wiki.asterisk.org/wiki/display/AST/SIP+Retransmissions\n" 03552 "Packet timed out after %dms with no response\n", 03553 pkt->owner->callid, 03554 pkt->seqno, 03555 pkt->is_fatal ? "Critical" : "Non-critical", 03556 pkt->is_resp ? "Response" : "Request", 03557 (int) ast_tvdiff_ms(ast_tvnow(), pkt->time_sent)); 03558 } 03559 } else if (pkt->method == SIP_OPTIONS && sipdebug) { 03560 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); 03561 } 03562 03563 if (xmitres == XMIT_ERROR) { 03564 ast_log(LOG_WARNING, "Transmit error :: Cancelling transmission on Call ID %s\n", pkt->owner->callid); 03565 append_history(pkt->owner, "XmitErr", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)"); 03566 } else { 03567 append_history(pkt->owner, "MaxRetries", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)"); 03568 } 03569 03570 if (pkt->is_fatal) { 03571 while(pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) { 03572 sip_pvt_unlock(pkt->owner); /* SIP_PVT, not channel */ 03573 usleep(1); 03574 sip_pvt_lock(pkt->owner); 03575 } 03576 if (pkt->owner->owner && !pkt->owner->owner->hangupcause) { 03577 pkt->owner->owner->hangupcause = AST_CAUSE_NO_USER_RESPONSE; 03578 } 03579 if (pkt->owner->owner) { 03580 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); 03581 03582 if (pkt->is_resp && 03583 (pkt->response_code >= 200) && 03584 (pkt->response_code < 300) && 03585 pkt->owner->pendinginvite && 03586 ast_test_flag(&pkt->owner->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) { 03587 /* This is a timeout of the 2XX response to a pending INVITE. In this case terminate the INVITE 03588 * transaction just as if we received the ACK, but immediately hangup with a BYE (sip_hangup 03589 * will send the BYE as long as the dialog is not set as "alreadygone") 03590 * RFC 3261 section 13.3.1.4. 03591 * "If the server retransmits the 2xx response for 64*T1 seconds without receiving 03592 * an ACK, the dialog is confirmed, but the session SHOULD be terminated. This is 03593 * accomplished with a BYE, as described in Section 15." */ 03594 pkt->owner->invitestate = INV_TERMINATED; 03595 pkt->owner->pendinginvite = 0; 03596 } else { 03597 /* there is nothing left to do, mark the dialog as gone */ 03598 sip_alreadygone(pkt->owner); 03599 } 03600 ast_queue_hangup_with_cause(pkt->owner->owner, AST_CAUSE_PROTOCOL_ERROR); 03601 ast_channel_unlock(pkt->owner->owner); 03602 } else { 03603 /* If no channel owner, destroy now */ 03604 03605 /* Let the peerpoke system expire packets when the timer expires for poke_noanswer */ 03606 if (pkt->method != SIP_OPTIONS && pkt->method != SIP_REGISTER) { 03607 pvt_set_needdestroy(pkt->owner, "no response to critical packet"); 03608 sip_alreadygone(pkt->owner); 03609 append_history(pkt->owner, "DialogKill", "Killing this failed dialog immediately"); 03610 } 03611 } 03612 } 03613 03614 if (pkt->method == SIP_BYE) { 03615 /* We're not getting answers on SIP BYE's. Tear down the call anyway. */ 03616 sip_alreadygone(pkt->owner); 03617 if (pkt->owner->owner) { 03618 ast_channel_unlock(pkt->owner->owner); 03619 } 03620 append_history(pkt->owner, "ByeFailure", "Remote peer doesn't respond to bye. Destroying call anyway."); 03621 pvt_set_needdestroy(pkt->owner, "no response to BYE"); 03622 } 03623 03624 /* Remove the packet */ 03625 for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) { 03626 if (cur == pkt) { 03627 UNLINK(cur, pkt->owner->packets, prev); 03628 sip_pvt_unlock(pkt->owner); 03629 if (pkt->owner) { 03630 pkt->owner = dialog_unref(pkt->owner,"pkt is being freed, its dialog ref is dead now"); 03631 } 03632 if (pkt->data) { 03633 ast_free(pkt->data); 03634 } 03635 pkt->data = NULL; 03636 ast_free(pkt); 03637 return 0; 03638 } 03639 } 03640 /* error case */ 03641 ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n"); 03642 sip_pvt_unlock(pkt->owner); 03643 return 0; 03644 }
| static int scheduler_process_request_queue | ( | const void * | data | ) | [static] |
Definition at line 24082 of file chan_sip.c.
References ast_channel_trylock, sip_pvt_lock, and sip_pvt_unlock.
Referenced by queue_request().
24083 { 24084 struct sip_pvt *p = (struct sip_pvt *) data; 24085 int recount = 0; 24086 int nounlock = 0; 24087 int lockretry; 24088 24089 for (lockretry = 10; lockretry > 0; lockretry--) { 24090 sip_pvt_lock(p); 24091 24092 /* lock the owner if it has one -- we may need it */ 24093 /* because this is deadlock-prone, we need to try and unlock if failed */ 24094 if (!p->owner || !ast_channel_trylock(p->owner)) { 24095 break; /* locking succeeded */ 24096 } 24097 24098 if (lockretry != 1) { 24099 sip_pvt_unlock(p); 24100 /* Sleep for a very short amount of time */ 24101 usleep(1); 24102 } 24103 } 24104 24105 if (!lockretry) { 24106 int retry = !AST_LIST_EMPTY(&p->request_queue); 24107 24108 /* we couldn't get the owner lock, which is needed to process 24109 the queued requests, so return a non-zero value, which will 24110 cause the scheduler to run this request again later if there 24111 still requests to be processed 24112 */ 24113 sip_pvt_unlock(p); 24114 if (!retry) { 24115 dialog_unref(p, "The ref to a dialog passed to this sched callback is going out of scope; unref it."); 24116 } 24117 return retry; 24118 }; 24119 24120 process_request_queue(p, &recount, &nounlock); 24121 p->request_queue_sched_id = -1; 24122 24123 if (p->owner && !nounlock) { 24124 ast_channel_unlock(p->owner); 24125 } 24126 sip_pvt_unlock(p); 24127 24128 if (recount) { 24129 ast_update_use_count(); 24130 } 24131 24132 dialog_unref(p, "The ref to a dialog passed to this sched callback is going out of scope; unref it."); 24133 24134 return 0; 24135 }
| static int send_provisional_keepalive | ( | const void * | data | ) | [static] |
Definition at line 4029 of file chan_sip.c.
References send_provisional_keepalive_full().
Referenced by update_provisional_keepalive().
04029 { 04030 struct sip_pvt *pvt = (struct sip_pvt *) data; 04031 04032 return send_provisional_keepalive_full(pvt, 0); 04033 }
| static int send_provisional_keepalive_full | ( | struct sip_pvt * | pvt, | |
| int | with_sdp | |||
| ) | [static] |
Definition at line 4009 of file chan_sip.c.
References FALSE, S_OR, transmit_response(), and transmit_response_with_sdp().
Referenced by send_provisional_keepalive(), and send_provisional_keepalive_with_sdp().
04010 { 04011 const char *msg = NULL; 04012 04013 if (!pvt->last_provisional || !strncasecmp(pvt->last_provisional, "100", 3)) { 04014 msg = "183 Session Progress"; 04015 } 04016 04017 if (pvt->invitestate < INV_COMPLETED) { 04018 if (with_sdp) { 04019 transmit_response_with_sdp(pvt, S_OR(msg, pvt->last_provisional), &pvt->initreq, XMIT_UNRELIABLE, FALSE, FALSE); 04020 } else { 04021 transmit_response(pvt, S_OR(msg, pvt->last_provisional), &pvt->initreq); 04022 } 04023 return PROVIS_KEEPALIVE_TIMEOUT; 04024 } 04025 04026 return 0; 04027 }
| static int send_provisional_keepalive_with_sdp | ( | const void * | data | ) | [static] |
Definition at line 4035 of file chan_sip.c.
References send_provisional_keepalive_full().
Referenced by update_provisional_keepalive().
04035 { 04036 struct sip_pvt *pvt = (void *)data; 04037 04038 return send_provisional_keepalive_full(pvt, 1); 04039 }
| static int send_request | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| enum xmittype | reliable, | |||
| int | seqno | |||
| ) | [static] |
Send SIP Request to the other part of the dialogue.
Definition at line 4090 of file chan_sip.c.
References __sip_reliable_xmit(), __sip_xmit(), add_blank(), append_history, ast_sockaddr_stringify(), ast_test_flag, ast_verbose, deinit_req(), finalize_content(), get_header(), parse_copy(), sip_debug_test_pvt(), sip_methods, and cfsip_methods::text.
04091 { 04092 int res; 04093 04094 /* If we have an outbound proxy, reset peer address 04095 Only do this once. 04096 */ 04097 if (p->outboundproxy) { 04098 p->sa = p->outboundproxy->ip; 04099 } 04100 04101 finalize_content(req); 04102 add_blank(req); 04103 if (sip_debug_test_pvt(p)) { 04104 if (ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT)) { 04105 ast_verbose("%sTransmitting (NAT) to %s:\n%s\n---\n", reliable ? "Reliably " : "", ast_sockaddr_stringify(&p->recv), req->data->str); 04106 } else { 04107 ast_verbose("%sTransmitting (no NAT) to %s:\n%s\n---\n", reliable ? "Reliably " : "", ast_sockaddr_stringify(&p->sa), req->data->str); 04108 } 04109 } 04110 if (p->do_history) { 04111 struct sip_request tmp = { .rlPart1 = 0, }; 04112 parse_copy(&tmp, req); 04113 append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", tmp.data->str, get_header(&tmp, "CSeq"), sip_methods[tmp.method].text); 04114 deinit_req(&tmp); 04115 } 04116 res = (reliable) ? 04117 __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 04118 __sip_xmit(p, req->data, req->len); 04119 deinit_req(req); 04120 return res; 04121 }
| static int send_response | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| enum xmittype | reliable, | |||
| int | seqno | |||
| ) | [static] |
Transmit response on SIP request.
Definition at line 4050 of file chan_sip.c.
References __sip_reliable_xmit(), __sip_xmit(), add_blank(), append_history, AST_SCHED_DEL_UNREF, ast_sockaddr_stringify(), ast_verbose, deinit_req(), finalize_content(), get_header(), parse_copy(), sip_debug_test_pvt(), sip_methods, sip_nat_mode(), sip_real_dst(), and cfsip_methods::text.
04051 { 04052 int res; 04053 04054 finalize_content(req); 04055 add_blank(req); 04056 if (sip_debug_test_pvt(p)) { 04057 const struct ast_sockaddr *dst = sip_real_dst(p); 04058 04059 ast_verbose("\n<--- %sTransmitting (%s) to %s --->\n%s\n<------------>\n", 04060 reliable ? "Reliably " : "", sip_nat_mode(p), 04061 ast_sockaddr_stringify(dst), 04062 req->data->str); 04063 } 04064 if (p->do_history) { 04065 struct sip_request tmp = { .rlPart1 = 0, }; 04066 parse_copy(&tmp, req); 04067 append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", tmp.data->str, get_header(&tmp, "CSeq"), 04068 (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? REQ_OFFSET_TO_STR(&tmp, rlPart2) : sip_methods[tmp.method].text); 04069 deinit_req(&tmp); 04070 } 04071 04072 /* If we are sending a final response to an INVITE, stop retransmitting provisional responses */ 04073 if (p->initreq.method == SIP_INVITE && reliable == XMIT_CRITICAL) { 04074 AST_SCHED_DEL_UNREF(sched, p->provisional_keepalive_sched_id, dialog_unref(p, "when you delete the provisional_keepalive_sched_id, you should dec the refcount for the stored dialog ptr")); 04075 } 04076 04077 res = (reliable) ? 04078 __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 04079 __sip_xmit(p, req->data, req->len); 04080 deinit_req(req); 04081 if (res > 0) { 04082 return 0; 04083 } 04084 return res; 04085 }
| static enum ast_cc_service_type service_string_to_service_type | ( | const char *const | service_string | ) | [static] |
Definition at line 837 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().
00838 { 00839 enum ast_cc_service_type service; 00840 for (service = AST_CC_CCBS; service <= AST_CC_CCNL; ++service) { 00841 if (!strcasecmp(service_string, sip_cc_service_map[service].service_string)) { 00842 return service; 00843 } 00844 } 00845 return AST_CC_NONE; 00846 }
| static int set_address_from_contact | ( | struct sip_pvt * | pvt | ) | [static] |
Change the other partys IP address based on given contact.
Definition at line 13199 of file chan_sip.c.
References __set_address_from_contact(), and ast_test_flag.
Referenced by handle_response_invite().
13200 { 13201 if (ast_test_flag(&pvt->flags[0], SIP_NAT_FORCE_RPORT)) { 13202 /* NAT: Don't trust the contact field. Just use what they came to us 13203 with. */ 13204 /*! \todo We need to save the TRANSPORT here too */ 13205 pvt->sa = pvt->recv; 13206 return 0; 13207 } 13208 13209 return __set_address_from_contact(pvt->fullcontact, &pvt->sa, pvt->socket.type == SIP_TRANSPORT_TLS ? 1 : 0); 13210 }
| static void set_destination | ( | struct sip_pvt * | p, | |
| char * | uri | |||
| ) | [static] |
Set destination from SIP URI.
Parse uri to h (host) and port - uri is already just the part inside the <> general form we are expecting is sip[s]:username[:password][;parameter][:port][;...] If there's a port given, turn NAPTR/SRV off. NAPTR might indicate SIPS preference even for SIP: uri's
If there's a sips: uri scheme, TLS will be required.
Definition at line 9518 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_sockaddr_port, ast_sockaddr_resolve_first(), ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_verbose, debug, FALSE, hostname, LOG_WARNING, PARSE_PORT_FORBID, sip_debug_test_pvt(), and TRUE.
Referenced by reqprep().
09519 { 09520 char *h, *maddr, hostname[256]; 09521 int hn; 09522 int debug=sip_debug_test_pvt(p); 09523 int tls_on = FALSE; 09524 09525 if (debug) 09526 ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri); 09527 09528 /* Find and parse hostname */ 09529 h = strchr(uri, '@'); 09530 if (h) 09531 ++h; 09532 else { 09533 h = uri; 09534 if (!strncasecmp(h, "sip:", 4)) { 09535 h += 4; 09536 } else if (!strncasecmp(h, "sips:", 5)) { 09537 h += 5; 09538 tls_on = TRUE; 09539 } 09540 } 09541 hn = strcspn(h, ";>") + 1; 09542 if (hn > sizeof(hostname)) 09543 hn = sizeof(hostname); 09544 ast_copy_string(hostname, h, hn); 09545 /* XXX bug here if string has been trimmed to sizeof(hostname) */ 09546 h += hn - 1; 09547 09548 /*! \todo XXX If we have sip_cfg.srvlookup on, then look for NAPTR/SRV, 09549 * otherwise, just look for A records */ 09550 if (ast_sockaddr_resolve_first(&p->sa, hostname, 0)) { 09551 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 09552 return; 09553 } 09554 09555 /* Got the hostname - but maybe there's a "maddr=" to override address? */ 09556 maddr = strstr(h, "maddr="); 09557 if (maddr) { 09558 int port; 09559 09560 maddr += 6; 09561 hn = strspn(maddr, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 09562 "0123456789-.:[]") + 1; 09563 if (hn > sizeof(hostname)) 09564 hn = sizeof(hostname); 09565 ast_copy_string(hostname, maddr, hn); 09566 09567 port = ast_sockaddr_port(&p->sa); 09568 09569 /*! \todo XXX If we have sip_cfg.srvlookup on, then look for 09570 * NAPTR/SRV, otherwise, just look for A records */ 09571 if (ast_sockaddr_resolve_first(&p->sa, hostname, PARSE_PORT_FORBID)) { 09572 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 09573 return; 09574 } 09575 09576 ast_sockaddr_set_port(&p->sa, port); 09577 } 09578 09579 if (!ast_sockaddr_port(&p->sa)) { 09580 ast_sockaddr_set_port(&p->sa, tls_on ? 09581 STANDARD_TLS_PORT : STANDARD_SIP_PORT); 09582 } 09583 09584 if (debug) { 09585 ast_verbose("set_destination: set destination to %s\n", 09586 ast_sockaddr_stringify(&p->sa)); 09587 } 09588 }
| 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 25503 of file chan_sip.c.
References ast_copy_string(), ast_false(), ast_log(), ast_set_flag, ast_strlen_zero(), LOG_WARNING, strsep(), and word.
Referenced by get_insecure_variable_from_config(), and handle_common_options().
25504 { 25505 if (ast_strlen_zero(value)) 25506 return; 25507 25508 if (!ast_false(value)) { 25509 char buf[64]; 25510 char *word, *next; 25511 25512 ast_copy_string(buf, value, sizeof(buf)); 25513 next = buf; 25514 while ((word = strsep(&next, ","))) { 25515 if (!strcasecmp(word, "port")) 25516 ast_set_flag(&flags[0], SIP_INSECURE_PORT); 25517 else if (!strcasecmp(word, "invite")) 25518 ast_set_flag(&flags[0], SIP_INSECURE_INVITE); 25519 else 25520 ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno); 25521 } 25522 } 25523 }
| static void set_nonce_randdata | ( | struct sip_pvt * | p, | |
| int | forceupdate | |||
| ) | [static] |
builds the sip_pvt's randdata field which is used for the nonce challenge. When forceupdate is not set, the nonce is only updated if the current one is stale. In this case, a stalenonce is one which has already received a response, if a nonce has not received a response it is not always necessary or beneficial to create a new one.
Definition at line 13576 of file chan_sip.c.
References ast_random(), ast_string_field_build, and ast_strlen_zero().
Referenced by check_auth(), and transmit_fake_auth_response().
13577 { 13578 if (p->stalenonce || forceupdate || ast_strlen_zero(p->randdata)) { 13579 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 13580 p->stalenonce = 0; 13581 } 13582 }
| static void set_peer_defaults | ( | struct sip_peer * | peer | ) | [static] |
Set peer defaults before configuring specific configurations.
Definition at line 25888 of file chan_sip.c.
References ast_copy_flags, ast_sockaddr_setnull(), ast_string_field_set, cid_name, cid_num, clear_peer_mailboxes(), context, default_engine, default_language, default_maxcallbitrate, default_mohinterpret, default_mohsuggest, default_prefs, default_primary_transport, default_qualify, default_transports, default_vmexten, global_autoframing, global_callcounter, global_flags, 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, language, mohinterpret, mohsuggest, secret, set_socket_transport(), and sip_cfg.
Referenced by build_peer(), and temp_peer().
25889 { 25890 if (peer->expire == 0) { 25891 /* Don't reset expire or port time during reload 25892 if we have an active registration 25893 */ 25894 peer->expire = -1; 25895 peer->pokeexpire = -1; 25896 set_socket_transport(&peer->socket, SIP_TRANSPORT_UDP); 25897 } 25898 peer->type = SIP_TYPE_PEER; 25899 ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 25900 ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 25901 ast_copy_flags(&peer->flags[2], &global_flags[2], SIP_PAGE3_FLAGS_TO_COPY); 25902 ast_string_field_set(peer, context, sip_cfg.default_context); 25903 ast_string_field_set(peer, subscribecontext, sip_cfg.default_subscribecontext); 25904 ast_string_field_set(peer, language, default_language); 25905 ast_string_field_set(peer, mohinterpret, default_mohinterpret); 25906 ast_string_field_set(peer, mohsuggest, default_mohsuggest); 25907 ast_string_field_set(peer, engine, default_engine); 25908 ast_sockaddr_setnull(&peer->addr); 25909 ast_sockaddr_setnull(&peer->defaddr); 25910 peer->capability = sip_cfg.capability; 25911 peer->maxcallbitrate = default_maxcallbitrate; 25912 peer->rtptimeout = global_rtptimeout; 25913 peer->rtpholdtimeout = global_rtpholdtimeout; 25914 peer->rtpkeepalive = global_rtpkeepalive; 25915 peer->allowtransfer = sip_cfg.allowtransfer; 25916 peer->autoframing = global_autoframing; 25917 peer->t38_maxdatagram = global_t38_maxdatagram; 25918 peer->qualifyfreq = global_qualifyfreq; 25919 if (global_callcounter) 25920 peer->call_limit=INT_MAX; 25921 ast_string_field_set(peer, vmexten, default_vmexten); 25922 ast_string_field_set(peer, secret, ""); 25923 ast_string_field_set(peer, remotesecret, ""); 25924 ast_string_field_set(peer, md5secret, ""); 25925 ast_string_field_set(peer, cid_num, ""); 25926 ast_string_field_set(peer, cid_name, ""); 25927 ast_string_field_set(peer, cid_tag, ""); 25928 ast_string_field_set(peer, fromdomain, ""); 25929 ast_string_field_set(peer, fromuser, ""); 25930 ast_string_field_set(peer, regexten, ""); 25931 peer->callgroup = 0; 25932 peer->pickupgroup = 0; 25933 peer->maxms = default_qualify; 25934 peer->prefs = default_prefs; 25935 peer->stimer.st_mode_oper = global_st_mode; /* Session-Timers */ 25936 peer->stimer.st_ref = global_st_refresher; 25937 peer->stimer.st_min_se = global_min_se; 25938 peer->stimer.st_max_se = global_max_se; 25939 peer->timer_t1 = global_t1; 25940 peer->timer_b = global_timer_b; 25941 clear_peer_mailboxes(peer); 25942 peer->disallowed_methods = sip_cfg.disallowed_methods; 25943 peer->transports = default_transports; 25944 peer->default_outbound_transport = default_primary_transport; 25945 }
| static unsigned int set_pvt_allowed_methods | ( | struct sip_pvt * | pvt, | |
| struct sip_request * | req | |||
| ) | [static] |
A wrapper for parse_allowed_methods geared toward sip_pvts
This function, in addition to setting the allowed methods for a sip_pvt also will take into account the setting of the SIP_PAGE2_RPID_UPDATE flag.
| pvt | The sip_pvt we are setting the allowed_methods for | |
| req | The request which we are parsing |
| The | methods alloweded by the sip_pvt |
Definition at line 7957 of file chan_sip.c.
References ast_test_flag, mark_method_allowed(), and parse_allowed_methods().
Referenced by check_peer_ok(), handle_request_invite(), handle_request_options(), handle_request_subscribe(), handle_response_invite(), and handle_response_subscribe().
07958 { 07959 pvt->allowed_methods = parse_allowed_methods(req); 07960 07961 if (ast_test_flag(&pvt->flags[1], SIP_PAGE2_RPID_UPDATE)) { 07962 mark_method_allowed(&pvt->allowed_methods, SIP_UPDATE); 07963 } 07964 pvt->allowed_methods &= ~(pvt->disallowed_methods); 07965 07966 return pvt->allowed_methods; 07967 }
| static void set_socket_transport | ( | struct sip_socket * | socket, | |
| int | transport | |||
| ) | [static] |
Definition at line 12984 of file chan_sip.c.
References ao2_ref.
Referenced by __sip_subscribe_mwi_do(), build_peer(), create_addr(), expire_register(), get_transport_pvt(), parse_moved_contact(), parse_register_contact(), set_peer_defaults(), sip_alloc(), sip_request_call(), sip_send_mwi_to_peer(), sipsock_read(), and transmit_register().
12985 { 12986 /* if the transport type changes, clear all socket data */ 12987 if (socket->type != transport) { 12988 socket->fd = -1; 12989 socket->type = transport; 12990 if (socket->tcptls_session) { 12991 ao2_ref(socket->tcptls_session, -1); 12992 socket->tcptls_session = NULL; 12993 } 12994 } 12995 }
| static void set_t38_capabilities | ( | struct sip_pvt * | p | ) | [static] |
Set the global T38 capabilities on a SIP dialog structure.
Definition at line 4916 of file chan_sip.c.
References ast_test_flag, ast_udptl_set_error_correction_scheme(), UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, and UDPTL_ERROR_CORRECTION_REDUNDANCY.
Referenced by check_peer_ok(), create_addr_from_peer(), handle_request_invite(), and sip_alloc().
04917 { 04918 if (p->udptl) { 04919 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) == SIP_PAGE2_T38SUPPORT_UDPTL_REDUNDANCY) { 04920 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY); 04921 } else if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) == SIP_PAGE2_T38SUPPORT_UDPTL_FEC) { 04922 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC); 04923 } else if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) == SIP_PAGE2_T38SUPPORT_UDPTL) { 04924 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 04925 } 04926 } 04927 }
| static int setup_srtp | ( | struct sip_srtp ** | srtp | ) | [static] |
Definition at line 28308 of file chan_sip.c.
References ast_log(), ast_rtp_engine_srtp_is_registered(), and LOG_ERROR.
Referenced by process_crypto(), and sip_call().
28309 { 28310 if (!ast_rtp_engine_srtp_is_registered()) { 28311 ast_log(LOG_ERROR, "No SRTP module loaded, can't setup SRTP session.\n"); 28312 return -1; 28313 } 28314 28315 if (!(*srtp = sip_srtp_alloc())) { /* Allocate SRTP data structure */ 28316 return -1; 28317 } 28318 28319 return 0; 28320 }
| static int show_channels_cb | ( | void * | __cur, | |
| void * | __arg, | |||
| int | flags | |||
| ) | [static] |
callback for show channel|subscription
Definition at line 17423 of file chan_sip.c.
References ast_cli(), AST_CLI_YESNO, ast_extension_state2str(), ast_getformatname_multiple(), ast_sockaddr_stringify_addr(), ast_str_alloca, ast_test_flag, FORMAT, FORMAT4, NONE, peer_mailboxes_to_str(), referstatus2str(), S_OR, sip_real_dst(), and subscription_type2str().
Referenced by sip_show_channels().
17424 { 17425 struct sip_pvt *cur = __cur; 17426 struct __show_chan_arg *arg = __arg; 17427 const struct ast_sockaddr *dst = sip_real_dst(cur); 17428 17429 /* XXX indentation preserved to reduce diff. Will be fixed later */ 17430 if (cur->subscribed == NONE && !arg->subscriptions) { 17431 /* set if SIP transfer in progress */ 17432 const char *referstatus = cur->refer ? referstatus2str(cur->refer->status) : ""; 17433 char formatbuf[SIPBUFSIZE/2]; 17434 17435 ast_cli(arg->fd, FORMAT, ast_sockaddr_stringify_addr(dst), 17436 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 17437 cur->callid, 17438 ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0), 17439 AST_CLI_YESNO(ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD)), 17440 cur->needdestroy ? "(d)" : "", 17441 cur->lastmsg , 17442 referstatus, 17443 cur->relatedpeer ? cur->relatedpeer->name : "<guest>" 17444 ); 17445 arg->numchans++; 17446 } 17447 if (cur->subscribed != NONE && arg->subscriptions) { 17448 struct ast_str *mailbox_str = ast_str_alloca(512); 17449 if (cur->subscribed == MWI_NOTIFICATION && cur->relatedpeer) 17450 peer_mailboxes_to_str(&mailbox_str, cur->relatedpeer); 17451 ast_cli(arg->fd, FORMAT4, ast_sockaddr_stringify_addr(dst), 17452 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 17453 cur->callid, 17454 /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */ 17455 cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri, 17456 cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 17457 subscription_type2str(cur->subscribed), 17458 cur->subscribed == MWI_NOTIFICATION ? S_OR(mailbox_str->str, "<none>") : "<none>", 17459 cur->expiry 17460 ); 17461 arg->numchans++; 17462 } 17463 return 0; /* don't care, we scan all channels */ 17464 }
| static int show_chanstats_cb | ( | void * | __cur, | |
| void * | __arg, | |||
| int | flags | |||
| ) | [static] |
Callback for show_chanstats.
Definition at line 17066 of file chan_sip.c.
References ast_cli(), ast_rtp_instance_get_stats(), AST_RTP_INSTANCE_STAT_ALL, ast_sockaddr_stringify_addr(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), ast_channel::cdr, invstate2stringtable::desc, FORMAT, invitestate2string, NONE, ast_rtp_instance_stats::rxcount, ast_rtp_instance_stats::rxjitter, ast_rtp_instance_stats::rxploss, ast_cdr::start, ast_rtp_instance_stats::txcount, ast_rtp_instance_stats::txjitter, and ast_rtp_instance_stats::txploss.
Referenced by sip_show_channelstats().
17067 { 17068 #define FORMAT2 "%-15.15s %-11.11s %-8.8s %-10.10s %-10.10s ( %%) %-6.6s %-10.10s %-10.10s ( %%) %-6.6s\n" 17069 #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" 17070 struct sip_pvt *cur = __cur; 17071 struct ast_rtp_instance_stats stats; 17072 char durbuf[10]; 17073 int duration; 17074 int durh, durm, durs; 17075 struct ast_channel *c = cur->owner; 17076 struct __show_chan_arg *arg = __arg; 17077 int fd = arg->fd; 17078 17079 17080 if (cur->subscribed != NONE) /* Subscriptions */ 17081 return 0; /* don't care, we scan all channels */ 17082 17083 if (!cur->rtp) { 17084 if (sipdebug) { 17085 ast_cli(fd, "%-15.15s %-11.11s (inv state: %s) -- %s\n", 17086 ast_sockaddr_stringify_addr(&cur->sa), cur->callid, 17087 invitestate2string[cur->invitestate].desc, 17088 "-- No RTP active"); 17089 } 17090 return 0; /* don't care, we scan all channels */ 17091 } 17092 17093 ast_rtp_instance_get_stats(cur->rtp, &stats, AST_RTP_INSTANCE_STAT_ALL); 17094 17095 if (c && c->cdr && !ast_tvzero(c->cdr->start)) { 17096 duration = (int)(ast_tvdiff_ms(ast_tvnow(), c->cdr->start) / 1000); 17097 durh = duration / 3600; 17098 durm = (duration % 3600) / 60; 17099 durs = duration % 60; 17100 snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs); 17101 } else { 17102 durbuf[0] = '\0'; 17103 } 17104 17105 ast_cli(fd, FORMAT, 17106 ast_sockaddr_stringify_addr(&cur->sa), 17107 cur->callid, 17108 durbuf, 17109 stats.rxcount > (unsigned int) 100000 ? (unsigned int) (stats.rxcount)/(unsigned int) 1000 : stats.rxcount, 17110 stats.rxcount > (unsigned int) 100000 ? "K":" ", 17111 stats.rxploss, 17112 (stats.rxcount + stats.rxploss) > 0 ? (double) stats.rxploss / (stats.rxcount + stats.rxploss) * 100 : 0, 17113 stats.rxjitter, 17114 stats.txcount > (unsigned int) 100000 ? (unsigned int) (stats.txcount)/(unsigned int) 1000 : stats.txcount, 17115 stats.txcount > (unsigned int) 100000 ? "K":" ", 17116 stats.txploss, 17117 stats.txcount > 0 ? (double) stats.txploss / stats.txcount * 100 : 0, 17118 stats.txjitter 17119 ); 17120 arg->numchans++; 17121 17122 return 0; /* don't care, we scan all channels */ 17123 }
| static int sip_addheader | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Add a SIP header to an outbound INVITE.
Definition at line 28100 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_debug, ast_get_encoded_str(), ast_log(), ast_strlen_zero(), FALSE, inbuf(), len(), LOG_WARNING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), and TRUE.
Referenced by load_module().
28101 { 28102 int no = 0; 28103 int ok = FALSE; 28104 char varbuf[30]; 28105 const char *inbuf = data; 28106 char *subbuf; 28107 28108 if (ast_strlen_zero(inbuf)) { 28109 ast_log(LOG_WARNING, "This application requires the argument: Header\n"); 28110 return 0; 28111 } 28112 ast_channel_lock(chan); 28113 28114 /* Check for headers */ 28115 while (!ok && no <= 50) { 28116 no++; 28117 snprintf(varbuf, sizeof(varbuf), "__SIPADDHEADER%.2d", no); 28118 28119 /* Compare without the leading underscores */ 28120 if ((pbx_builtin_getvar_helper(chan, (const char *) varbuf + 2) == (const char *) NULL)) { 28121 ok = TRUE; 28122 } 28123 } 28124 if (ok) { 28125 size_t len = strlen(inbuf); 28126 subbuf = alloca(len + 1); 28127 ast_get_encoded_str(inbuf, subbuf, len + 1); 28128 pbx_builtin_setvar_helper(chan, varbuf, subbuf); 28129 if (sipdebug) { 28130 ast_debug(1, "SIP Header added \"%s\" as %s\n", inbuf, varbuf); 28131 } 28132 } else { 28133 ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n"); 28134 } 28135 ast_channel_unlock(chan); 28136 return 0; 28137 }
| struct sip_pvt* sip_alloc | ( | ast_string_field | callid, | |
| struct ast_sockaddr * | addr, | |||
| int | useglobal_nat, | |||
| const int | intended_method, | |||
| struct sip_request * | req | |||
| ) |
Allocate sip_pvt structure, set defaults and link in the container. Returns a reference to the object so whoever uses it later must remember to release the reference.
Definition at line 7242 of file chan_sip.c.
References ao2_t_alloc, ao2_t_link, ao2_t_ref, ast_cc_config_params_init, ast_clear_flag, ast_copy_flags, ast_debug, AST_LIST_HEAD_INIT_NOLOCK, ast_log(), 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_udptl_new_with_bindaddr(), ast_udptl_setqos(), bindaddr, build_callid_pvt(), build_via(), context, default_engine, default_fromdomain, default_fromdomainport, default_maxcallbitrate, default_mohinterpret, default_mohsuggest, default_parkinglot, default_prefs, dialogs, do_setnat(), get_header(), global_autoframing, global_cos_audio, global_flags, global_t1, global_t38_maxdatagram, global_timer_b, global_tos_audio, internip, io, LOG_ERROR, make_our_tag(), mohinterpret, mohsuggest, NONE, parkinglot, recordhistory, set_socket_transport(), set_t38_capabilities(), sip_cfg, sip_destroy_fn(), sip_methods, cfsip_methods::text, and TRUE.
Referenced by __sip_subscribe_mwi_do(), find_call(), manager_sipnotify(), sip_cc_monitor_request_cc(), sip_cli_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_publish(), and transmit_register().
07244 { 07245 struct sip_pvt *p; 07246 07247 if (!(p = ao2_t_alloc(sizeof(*p), sip_destroy_fn, "allocate a dialog(pvt) struct"))) 07248 return NULL; 07249 07250 if (ast_string_field_init(p, 512)) { 07251 ao2_t_ref(p, -1, "failed to string_field_init, drop p"); 07252 return NULL; 07253 } 07254 07255 if (!(p->cc_params = ast_cc_config_params_init())) { 07256 ao2_t_ref(p, -1, "Yuck, couldn't allocate cc_params struct. Get rid o' p"); 07257 return NULL; 07258 } 07259 07260 /* If this dialog is created as the result of an incoming Request. Lets store 07261 * some information about that request */ 07262 if (req) { 07263 struct sip_via *via; 07264 const char *cseq = get_header(req, "Cseq"); 07265 unsigned int seqno; 07266 07267 /* get branch parameter from initial Request that started this dialog */ 07268 via = parse_via(get_header(req, "Via")); 07269 if (via) { 07270 /* only store the branch if it begins with the magic prefix "z9hG4bK", otherwise 07271 * it is not useful to us to have it */ 07272 if (!ast_strlen_zero(via->branch) && !strncasecmp(via->branch, "z9hG4bK", 7)) { 07273 ast_string_field_set(p, initviabranch, via->branch); 07274 ast_string_field_set(p, initviasentby, via->sent_by); 07275 } 07276 free_via(via); 07277 } 07278 07279 /* Store initial incoming cseq. An error in sscanf here is ignored. There is no approperiate 07280 * except not storing the number. CSeq validation must take place before dialog creation in find_call */ 07281 if (!ast_strlen_zero(cseq) && (sscanf(cseq, "%30u", &seqno) == 1)) { 07282 p->init_icseq = seqno; 07283 } 07284 /* Later in ast_sip_ouraddrfor we need this to choose the right ip and port for the specific transport */ 07285 set_socket_transport(&p->socket, req->socket.type); 07286 } else { 07287 set_socket_transport(&p->socket, SIP_TRANSPORT_UDP); 07288 } 07289 07290 p->socket.fd = -1; 07291 p->method = intended_method; 07292 p->initid = -1; 07293 p->waitid = -1; 07294 p->autokillid = -1; 07295 p->request_queue_sched_id = -1; 07296 p->provisional_keepalive_sched_id = -1; 07297 p->t38id = -1; 07298 p->subscribed = NONE; 07299 p->stateid = -1; 07300 p->sessionversion_remote = -1; 07301 p->session_modify = TRUE; 07302 p->stimer = NULL; 07303 p->prefs = default_prefs; /* Set default codecs for this call */ 07304 p->maxforwards = sip_cfg.default_max_forwards; 07305 07306 if (intended_method != SIP_OPTIONS) { /* Peerpoke has it's own system */ 07307 p->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */ 07308 p->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */ 07309 } 07310 07311 if (!addr) { 07312 p->ourip = internip; 07313 } else { 07314 ast_sockaddr_copy(&p->sa, addr); 07315 ast_sip_ouraddrfor(&p->sa, &p->ourip, p); 07316 } 07317 07318 /* Copy global flags to this PVT at setup. */ 07319 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 07320 ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 07321 ast_copy_flags(&p->flags[2], &global_flags[2], SIP_PAGE3_FLAGS_TO_COPY); 07322 07323 p->do_history = recordhistory; 07324 07325 p->branch = ast_random(); 07326 make_our_tag(p->tag, sizeof(p->tag)); 07327 p->ocseq = INITIAL_CSEQ; 07328 p->allowed_methods = UINT_MAX; 07329 07330 if (sip_methods[intended_method].need_rtp) { 07331 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) { 07332 if ((p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, &bindaddr))) { 07333 ast_udptl_setqos(p->udptl, global_tos_audio, global_cos_audio); 07334 p->t38_maxdatagram = global_t38_maxdatagram; 07335 } else { 07336 /* udptl creation failed, T38 can not be supported on this dialog */ 07337 ast_log(LOG_ERROR, "UDPTL creation failed\n"); 07338 ast_clear_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT); 07339 } 07340 } 07341 p->maxcallbitrate = default_maxcallbitrate; 07342 p->autoframing = global_autoframing; 07343 } 07344 07345 if (useglobal_nat && addr) { 07346 /* Setup NAT structure according to global settings if we have an address */ 07347 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT_FORCE_RPORT); 07348 ast_sockaddr_copy(&p->recv, addr); 07349 07350 do_setnat(p); 07351 } 07352 07353 if (p->method != SIP_REGISTER) { 07354 ast_string_field_set(p, fromdomain, default_fromdomain); 07355 p->fromdomainport = default_fromdomainport; 07356 } 07357 build_via(p); 07358 if (!callid) 07359 build_callid_pvt(p); 07360 else 07361 ast_string_field_set(p, callid, callid); 07362 /* Assign default music on hold class */ 07363 ast_string_field_set(p, mohinterpret, default_mohinterpret); 07364 ast_string_field_set(p, mohsuggest, default_mohsuggest); 07365 p->capability = sip_cfg.capability; 07366 p->allowtransfer = sip_cfg.allowtransfer; 07367 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 07368 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 07369 p->noncodeccapability |= AST_RTP_DTMF; 07370 if (p->udptl) { 07371 p->t38_maxdatagram = global_t38_maxdatagram; 07372 set_t38_capabilities(p); 07373 } 07374 ast_string_field_set(p, context, sip_cfg.default_context); 07375 ast_string_field_set(p, parkinglot, default_parkinglot); 07376 ast_string_field_set(p, engine, default_engine); 07377 07378 AST_LIST_HEAD_INIT_NOLOCK(&p->request_queue); 07379 07380 /* Add to active dialog list */ 07381 07382 ao2_t_link(dialogs, p, "link pvt into dialogs table"); 07383 07384 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"); 07385 return p; 07386 }
| 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 2999 of file chan_sip.c.
References ast_debug.
Referenced by handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), handle_response_publish(), handle_response_subscribe(), retrans_pkt(), sip_indicate(), and sip_sipredirect().
03000 { 03001 ast_debug(3, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid); 03002 dialog->alreadygone = 1; 03003 }
| 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 6184 of file chan_sip.c.
References ast_channel::_state, ast_debug, ast_rtp_instance_update_source(), ast_set_flag, ast_setstate(), AST_STATE_UP, FALSE, ast_channel::name, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, transmit_response_with_sdp(), TRUE, and try_suggested_sip_codec().
06185 { 06186 int res = 0; 06187 struct sip_pvt *p = ast->tech_pvt; 06188 06189 sip_pvt_lock(p); 06190 if (ast->_state != AST_STATE_UP) { 06191 try_suggested_sip_codec(p); 06192 06193 ast_setstate(ast, AST_STATE_UP); 06194 ast_debug(1, "SIP answering channel: %s\n", ast->name); 06195 ast_rtp_instance_update_source(p->rtp); 06196 res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL, FALSE, TRUE); 06197 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 06198 } 06199 sip_pvt_unlock(p); 06200 return res; 06201 }
| static int sip_call | ( | struct ast_channel * | ast, | |
| char * | dest, | |||
| int | timeout | |||
| ) | [static] |
Initiate SIP call from PBX used from the dial() application.
Definition at line 5274 of file chan_sip.c.
References ast_channel::_state, ao2_t_ref, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_USER_BUSY, ast_cc_get_monitor_by_recall_core_id(), ast_cc_is_recall(), ast_channel_get_device_name(), AST_CHANNEL_NAME, ast_clear_flag, ast_copy_string(), ast_debug, AST_FORMAT_AUDIO_MASK, AST_LIST_TRAVERSE, ast_log(), ast_party_id_presentation(), ast_rtp_instance_available_formats(), AST_SCHED_REPLACE_UNREF, ast_set_flag, AST_STATE_DOWN, AST_STATE_RESERVED, ast_string_field_set, ast_test_flag, ast_var_name(), ast_var_value(), auto_congest(), ast_channel::caller, cid_name, ast_channel::hangupcause, ast_party_caller::id, LOG_WARNING, ast_channel::name, ast_cc_monitor::private_data, setup_srtp(), sip_pvt_lock, sip_pvt_unlock, sipdebug, ast_channel::tech_pvt, transmit_invite(), update_call_counter(), and ast_channel::varshead.
05275 { 05276 int res; 05277 struct sip_pvt *p = ast->tech_pvt; /* chan is locked, so the reference cannot go away */ 05278 struct varshead *headp; 05279 struct ast_var_t *current; 05280 const char *referer = NULL; /* SIP referrer */ 05281 int cc_core_id; 05282 char uri[SIPBUFSIZE] = ""; 05283 05284 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 05285 ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name); 05286 return -1; 05287 } 05288 05289 if (ast_cc_is_recall(ast, &cc_core_id, "SIP")) { 05290 char device_name[AST_CHANNEL_NAME]; 05291 struct ast_cc_monitor *recall_monitor; 05292 struct sip_monitor_instance *monitor_instance; 05293 ast_channel_get_device_name(ast, device_name, sizeof(device_name)); 05294 if ((recall_monitor = ast_cc_get_monitor_by_recall_core_id(cc_core_id, device_name))) { 05295 monitor_instance = recall_monitor->private_data; 05296 ast_copy_string(uri, monitor_instance->notify_uri, sizeof(uri)); 05297 ao2_t_ref(recall_monitor, -1, "Got the URI we need so unreffing monitor"); 05298 } 05299 } 05300 05301 /* Check whether there is vxml_url, distinctive ring variables */ 05302 headp=&ast->varshead; 05303 AST_LIST_TRAVERSE(headp, current, entries) { 05304 /* Check whether there is a VXML_URL variable */ 05305 if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) { 05306 p->options->vxml_url = ast_var_value(current); 05307 } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) { 05308 p->options->uri_options = ast_var_value(current); 05309 } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 05310 /* Check whether there is a variable with a name starting with SIPADDHEADER */ 05311 p->options->addsipheaders = 1; 05312 } else if (!strcasecmp(ast_var_name(current), "SIPFROMDOMAIN")) { 05313 ast_string_field_set(p, fromdomain, ast_var_value(current)); 05314 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) { 05315 /* This is a transfered call */ 05316 p->options->transfer = 1; 05317 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) { 05318 /* This is the referrer */ 05319 referer = ast_var_value(current); 05320 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) { 05321 /* We're replacing a call. */ 05322 p->options->replaces = ast_var_value(current); 05323 } else if (!strcasecmp(ast_var_name(current), "SIP_MAX_FORWARDS")) { 05324 if (sscanf(ast_var_value(current), "%d", &(p->maxforwards)) != 1) { 05325 ast_log(LOG_WARNING, "The SIP_MAX_FORWARDS channel variable is not a valid integer."); 05326 } 05327 } 05328 } 05329 05330 /* Check to see if we should try to force encryption */ 05331 if (p->req_secure_signaling && p->socket.type != SIP_TRANSPORT_TLS) { 05332 ast_log(LOG_WARNING, "Encrypted signaling is required\n"); 05333 ast->hangupcause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 05334 return -1; 05335 } 05336 05337 if (ast_test_flag(&p->flags[1], SIP_PAGE2_USE_SRTP)) { 05338 if (ast_test_flag(&p->flags[0], SIP_REINVITE)) { 05339 ast_debug(1, "Direct media not possible when using SRTP, ignoring canreinvite setting\n"); 05340 ast_clear_flag(&p->flags[0], SIP_REINVITE); 05341 } 05342 05343 if (p->rtp && !p->srtp && setup_srtp(&p->srtp) < 0) { 05344 ast_log(LOG_WARNING, "SRTP audio setup failed\n"); 05345 return -1; 05346 } 05347 05348 if (p->vrtp && !p->vsrtp && setup_srtp(&p->vsrtp) < 0) { 05349 ast_log(LOG_WARNING, "SRTP video setup failed\n"); 05350 return -1; 05351 } 05352 05353 if (p->trtp && !p->vsrtp && setup_srtp(&p->tsrtp) < 0) { 05354 ast_log(LOG_WARNING, "SRTP text setup failed\n"); 05355 return -1; 05356 } 05357 } 05358 05359 res = 0; 05360 ast_set_flag(&p->flags[0], SIP_OUTGOING); 05361 05362 /* T.38 re-INVITE FAX detection should never be done for outgoing calls, 05363 * so ensure it is disabled. 05364 */ 05365 ast_clear_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_T38); 05366 05367 if (p->options->transfer) { 05368 char buf[SIPBUFSIZE/2]; 05369 05370 if (referer) { 05371 if (sipdebug) 05372 ast_debug(3, "Call for %s transfered by %s\n", p->username, referer); 05373 snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer); 05374 } else 05375 snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name); 05376 ast_string_field_set(p, cid_name, buf); 05377 } 05378 ast_debug(1, "Outgoing Call for %s\n", p->username); 05379 05380 res = update_call_counter(p, INC_CALL_RINGING); 05381 05382 if (res == -1) { 05383 ast->hangupcause = AST_CAUSE_USER_BUSY; 05384 return res; 05385 } 05386 p->callingpres = ast_party_id_presentation(&ast->caller.id); 05387 p->jointcapability = ast_rtp_instance_available_formats(p->rtp, p->capability, p->prefcodec); 05388 p->jointnoncodeccapability = p->noncodeccapability; 05389 05390 /* If there are no audio formats left to offer, punt */ 05391 if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 05392 ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username); 05393 res = -1; 05394 } else { 05395 int xmitres; 05396 05397 sip_pvt_lock(p); 05398 xmitres = transmit_invite(p, SIP_INVITE, 1, 2, uri); 05399 sip_pvt_unlock(p); 05400 if (xmitres == XMIT_ERROR) 05401 return -1; 05402 p->invitestate = INV_CALLING; 05403 05404 /* Initialize auto-congest time */ 05405 AST_SCHED_REPLACE_UNREF(p->initid, sched, p->timer_b, auto_congest, p, 05406 dialog_unref(_data, "dialog ptr dec when SCHED_REPLACE del op succeeded"), 05407 dialog_unref(p, "dialog ptr dec when SCHED_REPLACE add failed"), 05408 dialog_ref(p, "dialog ptr inc when SCHED_REPLACE add succeeded") ); 05409 } 05410 return res; 05411 }
| int sip_cancel_destroy | ( | struct sip_pvt * | p | ) |
Cancel destruction of SIP dialog. Be careful as this also absorbs the reference - if you call it from within the scheduler, this might be the last reference.
Definition at line 3863 of file chan_sip.c.
References append_history, and ast_sched_del().
Referenced by handle_request_invite(), handle_request_subscribe(), handle_response(), handle_response_invite(), register_verify(), sip_hangup(), and sip_scheddestroy().
03864 { 03865 int res = 0; 03866 03867 if (p->final_destruction_scheduled) { 03868 return res; 03869 } 03870 03871 if (p->autokillid > -1) { 03872 int res3; 03873 03874 if (!(res3 = ast_sched_del(sched, p->autokillid))) { 03875 append_history(p, "CancelDestroy", ""); 03876 p->autokillid = -1; 03877 dialog_unref(p, "dialog unrefd because autokillid is de-sched'd"); 03878 } 03879 } 03880 return res; 03881 }
| static void sip_cc_agent_destructor | ( | struct ast_cc_agent * | agent | ) | [static] |
Definition at line 1784 of file chan_sip.c.
References ast_free, ast_test_flag, ast_cc_agent::private_data, sip_cc_agent_stop_offer_timer(), sip_pvt_lock, sip_pvt_unlock, and transmit_response().
01785 { 01786 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01787 01788 if (!agent_pvt) { 01789 /* The agent constructor probably failed. */ 01790 return; 01791 } 01792 01793 sip_cc_agent_stop_offer_timer(agent); 01794 if (agent_pvt->subscribe_pvt) { 01795 sip_pvt_lock(agent_pvt->subscribe_pvt); 01796 if (!ast_test_flag(&agent_pvt->subscribe_pvt->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) { 01797 /* If we haven't sent a 200 OK for the SUBSCRIBE dialog yet, then we need to send a response letting 01798 * the subscriber know something went wrong 01799 */ 01800 transmit_response(agent_pvt->subscribe_pvt, "500 Internal Server Error", &agent_pvt->subscribe_pvt->initreq); 01801 } 01802 sip_pvt_unlock(agent_pvt->subscribe_pvt); 01803 agent_pvt->subscribe_pvt = dialog_unref(agent_pvt->subscribe_pvt, "SIP CC agent destructor: Remove ref to subscription"); 01804 } 01805 ast_free(agent_pvt); 01806 }
| static int sip_cc_agent_init | ( | struct ast_cc_agent * | agent, | |
| struct ast_channel * | chan | |||
| ) | [static] |
Definition at line 1671 of file chan_sip.c.
References ast_assert, ast_calloc, ast_copy_string(), ast_set_flag, ast_cc_agent::private_data, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech, ast_channel::tech_pvt, and ast_channel_tech::type.
01672 { 01673 struct sip_cc_agent_pvt *agent_pvt = ast_calloc(1, sizeof(*agent_pvt)); 01674 struct sip_pvt *call_pvt = chan->tech_pvt; 01675 01676 if (!agent_pvt) { 01677 return -1; 01678 } 01679 01680 ast_assert(!strcmp(chan->tech->type, "SIP")); 01681 01682 ast_copy_string(agent_pvt->original_callid, call_pvt->callid, sizeof(agent_pvt->original_callid)); 01683 ast_copy_string(agent_pvt->original_exten, call_pvt->exten, sizeof(agent_pvt->original_exten)); 01684 agent_pvt->offer_timer_id = -1; 01685 agent->private_data = agent_pvt; 01686 sip_pvt_lock(call_pvt); 01687 ast_set_flag(&call_pvt->flags[0], SIP_OFFER_CC); 01688 sip_pvt_unlock(call_pvt); 01689 return 0; 01690 }
| static int sip_cc_agent_recall | ( | struct ast_cc_agent * | agent | ) | [static] |
Definition at line 1764 of file chan_sip.c.
References ast_cc_agent_caller_busy(), ast_cc_agent::core_id, ast_cc_agent::device_name, ast_cc_agent::private_data, sip_pvt_lock, sip_pvt_unlock, and transmit_cc_notify().
01765 { 01766 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01767 /* If we have received a PUBLISH beforehand stating that the caller in question 01768 * is not available, we can save ourself a bit of effort here and just report 01769 * the caller as busy 01770 */ 01771 if (!agent_pvt->is_available) { 01772 return ast_cc_agent_caller_busy(agent->core_id, "Caller %s is busy, reporting to the core", 01773 agent->device_name); 01774 } 01775 /* Otherwise, we transmit a NOTIFY to the caller and await either 01776 * a PUBLISH or an INVITE 01777 */ 01778 sip_pvt_lock(agent_pvt->subscribe_pvt); 01779 transmit_cc_notify(agent, agent_pvt->subscribe_pvt, CC_READY); 01780 sip_pvt_unlock(agent_pvt->subscribe_pvt); 01781 return 0; 01782 }
| static void sip_cc_agent_respond | ( | struct ast_cc_agent * | agent, | |
| enum ast_cc_agent_response_reason | reason | |||
| ) | [static] |
Definition at line 1720 of file chan_sip.c.
References AST_CC_AGENT_RESPONSE_SUCCESS, ast_set_flag, ast_strlen_zero(), ast_cc_agent::private_data, sip_pvt_lock, sip_pvt_unlock, transmit_cc_notify(), transmit_response(), and TRUE.
01721 { 01722 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01723 01724 sip_pvt_lock(agent_pvt->subscribe_pvt); 01725 ast_set_flag(&agent_pvt->subscribe_pvt->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 01726 if (reason == AST_CC_AGENT_RESPONSE_SUCCESS || !ast_strlen_zero(agent_pvt->notify_uri)) { 01727 /* The second half of this if statement may be a bit hard to grasp, 01728 * so here's an explanation. When a subscription comes into 01729 * chan_sip, as long as it is not malformed, it will be passed 01730 * to the CC core. If the core senses an out-of-order state transition, 01731 * then the core will call this callback with the "reason" set to a 01732 * failure condition. 01733 * However, an out-of-order state transition will occur during a resubscription 01734 * for CC. In such a case, we can see that we have already generated a notify_uri 01735 * and so we can detect that this isn't a *real* failure. Rather, it is just 01736 * something the core doesn't recognize as a legitimate SIP state transition. 01737 * Thus we respond with happiness and flowers. 01738 */ 01739 transmit_response(agent_pvt->subscribe_pvt, "200 OK", &agent_pvt->subscribe_pvt->initreq); 01740 transmit_cc_notify(agent, agent_pvt->subscribe_pvt, CC_QUEUED); 01741 } else { 01742 transmit_response(agent_pvt->subscribe_pvt, "500 Internal Error", &agent_pvt->subscribe_pvt->initreq); 01743 } 01744 sip_pvt_unlock(agent_pvt->subscribe_pvt); 01745 agent_pvt->is_available = TRUE; 01746 }
| static int sip_cc_agent_start_monitoring | ( | struct ast_cc_agent * | agent | ) | [static] |
Definition at line 1755 of file chan_sip.c.
01756 { 01757 /* To start monitoring just means to wait for an incoming PUBLISH 01758 * to tell us that the caller has become available again. No special 01759 * action is needed 01760 */ 01761 return 0; 01762 }
| static int sip_cc_agent_start_offer_timer | ( | struct ast_cc_agent * | agent | ) | [static] |
Definition at line 1702 of file chan_sip.c.
References ast_get_cc_offer_timer(), ast_sched_add(), ast_cc_agent::cc_params, ast_cc_agent::private_data, sched, and sip_offer_timer_expire().
01703 { 01704 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01705 int when; 01706 01707 when = ast_get_cc_offer_timer(agent->cc_params) * 1000; 01708 agent_pvt->offer_timer_id = ast_sched_add(sched, when, sip_offer_timer_expire, agent); 01709 return 0; 01710 }
| static int sip_cc_agent_status_request | ( | struct ast_cc_agent * | agent | ) | [static] |
Definition at line 1748 of file chan_sip.c.
References ast_cc_agent_status_response(), AST_DEVICE_INUSE, AST_DEVICE_NOT_INUSE, ast_device_state(), ast_cc_agent::core_id, and ast_cc_agent::private_data.
01749 { 01750 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01751 enum ast_device_state state = agent_pvt->is_available ? AST_DEVICE_NOT_INUSE : AST_DEVICE_INUSE; 01752 return ast_cc_agent_status_response(agent->core_id, state); 01753 }
| static int sip_cc_agent_stop_offer_timer | ( | struct ast_cc_agent * | agent | ) | [static] |
Definition at line 1712 of file chan_sip.c.
References AST_SCHED_DEL, ast_cc_agent::private_data, and sched.
Referenced by sip_cc_agent_destructor().
01713 { 01714 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01715 01716 AST_SCHED_DEL(sched, agent_pvt->offer_timer_id); 01717 return 0; 01718 }
| static int sip_cc_monitor_cancel_available_timer | ( | struct ast_cc_monitor * | monitor, | |
| int * | sched_id | |||
| ) | [static] |
Definition at line 2022 of file chan_sip.c.
References ao2_t_ref, AST_SCHED_DEL, monitor, and sched.
02023 { 02024 if (*sched_id != -1) { 02025 AST_SCHED_DEL(sched, *sched_id); 02026 ao2_t_ref(monitor, -1, "Removing scheduler's reference to the monitor"); 02027 } 02028 return 0; 02029 }
| static void sip_cc_monitor_destructor | ( | void * | private_data | ) | [static] |
Definition at line 2031 of file chan_sip.c.
References ao2_unlink, ast_module_unref(), and sip_monitor_instances.
02032 { 02033 struct sip_monitor_instance *monitor_instance = private_data; 02034 ao2_unlink(sip_monitor_instances, monitor_instance); 02035 ast_module_unref(ast_module_info->self); 02036 }
| static int sip_cc_monitor_request_cc | ( | struct ast_cc_monitor * | monitor, | |
| int * | available_timer_id | |||
| ) | [static] |
Definition at line 1890 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_sip_ouraddrfor(), create_addr(), FALSE, monitor, sched, service, sip_alloc(), sip_pvt_lock, sip_pvt_unlock, and transmit_invite().
01891 { 01892 struct sip_monitor_instance *monitor_instance = monitor->private_data; 01893 enum ast_cc_service_type service = monitor->service_offered; 01894 int when; 01895 01896 if (!monitor_instance) { 01897 return -1; 01898 } 01899 01900 if (!(monitor_instance->subscription_pvt = sip_alloc(NULL, NULL, 0, SIP_SUBSCRIBE, NULL))) { 01901 return -1; 01902 } 01903 01904 when = service == AST_CC_CCBS ? ast_get_ccbs_available_timer(monitor->interface->config_params) : 01905 ast_get_ccnr_available_timer(monitor->interface->config_params); 01906 01907 sip_pvt_lock(monitor_instance->subscription_pvt); 01908 create_addr(monitor_instance->subscription_pvt, monitor_instance->peername, 0, 1, NULL); 01909 ast_sip_ouraddrfor(&monitor_instance->subscription_pvt->sa, &monitor_instance->subscription_pvt->ourip, monitor_instance->subscription_pvt); 01910 monitor_instance->subscription_pvt->subscribed = CALL_COMPLETION; 01911 monitor_instance->subscription_pvt->expiry = when; 01912 01913 transmit_invite(monitor_instance->subscription_pvt, SIP_SUBSCRIBE, FALSE, 2, monitor_instance->subscribe_uri); 01914 sip_pvt_unlock(monitor_instance->subscription_pvt); 01915 01916 ao2_t_ref(monitor, +1, "Adding a ref to the monitor for the scheduler"); 01917 *available_timer_id = ast_sched_add(sched, when * 1000, ast_cc_available_timer_expire, monitor); 01918 return 0; 01919 }
| static int sip_cc_monitor_suspend | ( | struct ast_cc_monitor * | monitor | ) | [static] |
Definition at line 1947 of file chan_sip.c.
References ao2_ref, ast_calloc, ast_log(), ast_strlen_zero(), construct_pidf_body(), create_epa_entry(), LOG_WARNING, monitor, and transmit_publish().
01948 { 01949 struct sip_monitor_instance *monitor_instance = monitor->private_data; 01950 enum sip_publish_type publish_type; 01951 struct cc_epa_entry *cc_entry; 01952 01953 if (!monitor_instance) { 01954 return -1; 01955 } 01956 01957 if (!monitor_instance->suspension_entry) { 01958 /* We haven't yet allocated the suspension entry, so let's give it a shot */ 01959 if (!(monitor_instance->suspension_entry = create_epa_entry("call-completion", monitor_instance->peername))) { 01960 ast_log(LOG_WARNING, "Unable to allocate sip EPA entry for call-completion\n"); 01961 ao2_ref(monitor_instance, -1); 01962 return -1; 01963 } 01964 if (!(cc_entry = ast_calloc(1, sizeof(*cc_entry)))) { 01965 ast_log(LOG_WARNING, "Unable to allocate space for instance data of EPA entry for call-completion\n"); 01966 ao2_ref(monitor_instance, -1); 01967 return -1; 01968 } 01969 cc_entry->core_id = monitor->core_id; 01970 monitor_instance->suspension_entry->instance_data = cc_entry; 01971 publish_type = SIP_PUBLISH_INITIAL; 01972 } else { 01973 publish_type = SIP_PUBLISH_MODIFY; 01974 cc_entry = monitor_instance->suspension_entry->instance_data; 01975 } 01976 01977 cc_entry->current_state = CC_CLOSED; 01978 01979 if (ast_strlen_zero(monitor_instance->notify_uri)) { 01980 /* If we have no set notify_uri, then what this means is that we have 01981 * not received a NOTIFY from this destination stating that he is 01982 * currently available. 01983 * 01984 * This situation can arise when the core calls the suspend callbacks 01985 * of multiple destinations. If one of the other destinations aside 01986 * from this one notified Asterisk that he is available, then there 01987 * is no reason to take any suspension action on this device. Rather, 01988 * we should return now and if we receive a NOTIFY while monitoring 01989 * is still "suspended" then we can immediately respond with the 01990 * proper PUBLISH to let this endpoint know what is going on. 01991 */ 01992 return 0; 01993 } 01994 construct_pidf_body(CC_CLOSED, monitor_instance->suspension_entry->body, sizeof(monitor_instance->suspension_entry->body), monitor_instance->peername); 01995 return transmit_publish(monitor_instance->suspension_entry, publish_type, monitor_instance->notify_uri); 01996 }
| static int sip_cc_monitor_unsuspend | ( | struct ast_cc_monitor * | monitor | ) | [static] |
Definition at line 1998 of file chan_sip.c.
References ast_assert, ast_strlen_zero(), construct_pidf_body(), monitor, and transmit_publish().
01999 { 02000 struct sip_monitor_instance *monitor_instance = monitor->private_data; 02001 struct cc_epa_entry *cc_entry; 02002 02003 if (!monitor_instance) { 02004 return -1; 02005 } 02006 02007 ast_assert(monitor_instance->suspension_entry != NULL); 02008 02009 cc_entry = monitor_instance->suspension_entry->instance_data; 02010 cc_entry->current_state = CC_OPEN; 02011 if (ast_strlen_zero(monitor_instance->notify_uri)) { 02012 /* This means we are being asked to unsuspend a call leg we never 02013 * sent a PUBLISH on. As such, there is no reason to send another 02014 * PUBLISH at this point either. We can just return instead. 02015 */ 02016 return 0; 02017 } 02018 construct_pidf_body(CC_OPEN, monitor_instance->suspension_entry->body, sizeof(monitor_instance->suspension_entry->body), monitor_instance->peername); 02019 return transmit_publish(monitor_instance->suspension_entry, SIP_PUBLISH_MODIFY, monitor_instance->notify_uri); 02020 }
| static int sip_check_authtimeout | ( | time_t | start | ) | [static] |
Check if the authtimeout has expired.
| start | the time when the session started |
| 0 | the timeout has expired | |
| -1 | error |
Definition at line 2452 of file chan_sip.c.
References ast_log(), authtimeout, errno, and LOG_ERROR.
Referenced by _sip_tcp_helper_thread().
02453 { 02454 int timeout; 02455 time_t now; 02456 if(time(&now) == -1) { 02457 ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno)); 02458 return -1; 02459 } 02460 02461 timeout = (authtimeout - (now - start)) * 1000; 02462 if (timeout < 0) { 02463 /* we have timed out */ 02464 return 0; 02465 } 02466 02467 return timeout; 02468 }
| 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 18115 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_str_append(), ast_str_strlen(), ast_unescape_semicolon(), ast_variable_browse(), ast_variable_new(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, ast_cli_entry::command, complete_sipnotify(), create_addr(), dialog_unlink_all(), ast_cli_args::fd, ast_cli_args::line, LOG_WARNING, ast_cli_args::n, notify_config, notify_types, ast_cli_args::pos, sip_alloc(), sip_notify_allocate(), TRUE, ast_cli_entry::usage, var, and ast_cli_args::word.
18116 { 18117 struct ast_variable *varlist; 18118 int i; 18119 18120 switch (cmd) { 18121 case CLI_INIT: 18122 e->command = "sip notify"; 18123 e->usage = 18124 "Usage: sip notify <type> <peer> [<peer>...]\n" 18125 " Send a NOTIFY message to a SIP peer or peers\n" 18126 " Message types are defined in sip_notify.conf\n"; 18127 return NULL; 18128 case CLI_GENERATE: 18129 return complete_sipnotify(a->line, a->word, a->pos, a->n); 18130 } 18131 18132 if (a->argc < 4) 18133 return CLI_SHOWUSAGE; 18134 18135 if (!notify_types) { 18136 ast_cli(a->fd, "No %s file found, or no types listed there\n", notify_config); 18137 return CLI_FAILURE; 18138 } 18139 18140 varlist = ast_variable_browse(notify_types, a->argv[2]); 18141 18142 if (!varlist) { 18143 ast_cli(a->fd, "Unable to find notify type '%s'\n", a->argv[2]); 18144 return CLI_FAILURE; 18145 } 18146 18147 for (i = 3; i < a->argc; i++) { 18148 struct sip_pvt *p; 18149 char buf[512]; 18150 struct ast_variable *header, *var; 18151 18152 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) { 18153 ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n"); 18154 return CLI_FAILURE; 18155 } 18156 18157 if (create_addr(p, a->argv[i], NULL, 1, NULL)) { 18158 /* Maybe they're not registered, etc. */ 18159 dialog_unlink_all(p, TRUE, TRUE); 18160 dialog_unref(p, "unref dialog inside for loop" ); 18161 /* sip_destroy(p); */ 18162 ast_cli(a->fd, "Could not create address for '%s'\n", a->argv[i]); 18163 continue; 18164 } 18165 18166 /* Notify is outgoing call */ 18167 ast_set_flag(&p->flags[0], SIP_OUTGOING); 18168 sip_notify_allocate(p); 18169 p->notify->headers = header = ast_variable_new("Subscription-State", "terminated", ""); 18170 18171 for (var = varlist; var; var = var->next) { 18172 ast_copy_string(buf, var->value, sizeof(buf)); 18173 ast_unescape_semicolon(buf); 18174 18175 if (!strcasecmp(var->name, "Content")) { 18176 if (ast_str_strlen(p->notify->content)) 18177 ast_str_append(&p->notify->content, 0, "\r\n"); 18178 ast_str_append(&p->notify->content, 0, "%s", buf); 18179 } else if (!strcasecmp(var->name, "Content-Length")) { 18180 ast_log(LOG_WARNING, "it is not necessary to specify Content-Length in sip_notify.conf, ignoring"); 18181 } else { 18182 header->next = ast_variable_new(var->name, buf, ""); 18183 header = header->next; 18184 } 18185 } 18186 18187 /* Recalculate our side, and recalculate Call ID */ 18188 ast_cli(a->fd, "Sending NOTIFY of type '%s' to '%s'\n", a->argv[2], a->argv[i]); 18189 dialog_ref(p, "bump the count of p, which transmit_sip_request will decrement."); 18190 sip_scheddestroy(p, SIP_TRANS_TIMEOUT); 18191 transmit_invite(p, SIP_NOTIFY, 0, 2, NULL); 18192 } 18193 18194 return CLI_SUCCESS; 18195 }
| static int sip_debug_test_addr | ( | const struct ast_sockaddr * | addr | ) | [inline, static] |
See if we pass debug IP filter.
Definition at line 3096 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().
03097 { 03098 /* Can't debug if sipdebug is not enabled */ 03099 if (!sipdebug) { 03100 return 0; 03101 } 03102 03103 /* A null debug_addr means we'll debug any address */ 03104 if (ast_sockaddr_isnull(&debugaddr)) { 03105 return 1; 03106 } 03107 03108 /* If no port was specified for a debug address, just compare the 03109 * addresses, otherwise compare the address and port 03110 */ 03111 if (ast_sockaddr_port(&debugaddr)) { 03112 return !ast_sockaddr_cmp(&debugaddr, addr); 03113 } else { 03114 return !ast_sockaddr_cmp_addr(&debugaddr, addr); 03115 } 03116 }
| static int sip_debug_test_pvt | ( | struct sip_pvt * | p | ) | [inline, static] |
Test PVT for debugging output.
Definition at line 3135 of file chan_sip.c.
References sip_debug_test_addr(), sip_real_dst(), and sipdebug.
Referenced by __sip_destroy(), add_sdp(), build_route(), check_via(), do_register_auth(), get_also_info(), get_destination(), get_rdnis(), get_refer_info(), handle_incoming(), process_sdp(), process_sdp_a_audio(), process_sdp_a_text(), process_sdp_a_video(), receive_message(), retrans_pkt(), send_request(), send_response(), set_destination(), sip_scheddestroy(), sip_sendhtml(), sip_sendtext(), and transmit_register().
03136 { 03137 if (!sipdebug) { 03138 return 0; 03139 } 03140 return sip_debug_test_addr(sip_real_dst(p)); 03141 }
| struct sip_pvt* sip_destroy | ( | struct sip_pvt * | p | ) |
Destroy SIP call structure. Make it return NULL so the caller can do things like foo = sip_destroy(foo); and reduce the chance of bugs due to dangling pointers.
Definition at line 5766 of file chan_sip.c.
References __sip_destroy(), ast_debug, and TRUE.
Referenced by sip_destroy_fn(), and sip_subscribe_mwi_destroy().
05767 { 05768 ast_debug(3, "Destroying SIP dialog %s\n", p->callid); 05769 __sip_destroy(p, TRUE, TRUE); 05770 return NULL; 05771 }
| static void sip_destroy_fn | ( | void * | p | ) | [static] |
Definition at line 5756 of file chan_sip.c.
References sip_destroy().
Referenced by sip_alloc().
05757 { 05758 sip_destroy(p); 05759 }
| static void sip_destroy_peer | ( | struct sip_peer * | peer | ) | [static] |
Destroy peer object from memory.
Definition at line 4471 of file chan_sip.c.
References ao2_ref, apeerobjs, ast_atomic_fetchadd_int(), ast_cc_config_params_destroy(), ast_debug, ast_dnsmgr_release(), ast_free_ha(), ast_string_field_free_memory, ast_variables_destroy(), clear_peer_mailboxes(), clear_realm_authentication(), dialog_unlink_all(), FALSE, register_peer_exten(), rpeerobjs, speerobjs, and TRUE.
Referenced by sip_destroy_peer_fn().
04472 { 04473 ast_debug(3, "Destroying SIP peer %s\n", peer->name); 04474 if (peer->outboundproxy) 04475 ao2_ref(peer->outboundproxy, -1); 04476 peer->outboundproxy = NULL; 04477 04478 /* Delete it, it needs to disappear */ 04479 if (peer->call) { 04480 dialog_unlink_all(peer->call, TRUE, TRUE); 04481 peer->call = dialog_unref(peer->call, "peer->call is being unset"); 04482 } 04483 04484 04485 if (peer->mwipvt) { /* We have an active subscription, delete it */ 04486 dialog_unlink_all(peer->mwipvt, TRUE, TRUE); 04487 peer->mwipvt = dialog_unref(peer->mwipvt, "unreffing peer->mwipvt"); 04488 } 04489 04490 if (peer->chanvars) { 04491 ast_variables_destroy(peer->chanvars); 04492 peer->chanvars = NULL; 04493 } 04494 04495 register_peer_exten(peer, FALSE); 04496 ast_free_ha(peer->ha); 04497 ast_free_ha(peer->directmediaha); 04498 if (peer->selfdestruct) 04499 ast_atomic_fetchadd_int(&apeerobjs, -1); 04500 else if (peer->is_realtime) { 04501 ast_atomic_fetchadd_int(&rpeerobjs, -1); 04502 ast_debug(3, "-REALTIME- peer Destroyed. Name: %s. Realtime Peer objects: %d\n", peer->name, rpeerobjs); 04503 } else 04504 ast_atomic_fetchadd_int(&speerobjs, -1); 04505 clear_realm_authentication(peer->auth); 04506 peer->auth = NULL; 04507 if (peer->dnsmgr) 04508 ast_dnsmgr_release(peer->dnsmgr); 04509 clear_peer_mailboxes(peer); 04510 04511 if (peer->socket.tcptls_session) { 04512 ao2_ref(peer->socket.tcptls_session, -1); 04513 peer->socket.tcptls_session = NULL; 04514 } 04515 04516 ast_cc_config_params_destroy(peer->cc_params); 04517 04518 ast_string_field_free_memory(peer); 04519 }
| static void sip_destroy_peer_fn | ( | void * | peer | ) | [static] |
Definition at line 4465 of file chan_sip.c.
References sip_destroy_peer().
Referenced by build_peer(), and temp_peer().
04466 { 04467 sip_destroy_peer(peer); 04468 }
| static int sip_devicestate | ( | void * | data | ) | [static] |
Part of PBX channel interface.
For peers with call limit:
For peers without call limit:
Peers that does not have a known call and can't be reached by OPTIONS
If we return AST_DEVICE_UNKNOWN, the device state engine will try to find out a state by walking the channel list.
The queue system (app_queue.c) treats a member as "active" if devicestate is != AST_DEVICE_UNAVAILBALE && != AST_DEVICE_INVALID
When placing a call to the queue member, queue system sets a member to busy if != AST_DEVICE_NOT_INUSE and != AST_DEVICE_UNKNOWN
Definition at line 25225 of file chan_sip.c.
References ast_debug, AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, AST_DEVICE_ONHOLD, AST_DEVICE_RINGING, AST_DEVICE_RINGINUSE, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_sockaddr_isnull(), ast_strdupa, FALSE, find_peer(), TRUE, and unref_peer().
25226 { 25227 char *host; 25228 char *tmp; 25229 struct sip_peer *p; 25230 25231 int res = AST_DEVICE_INVALID; 25232 25233 /* make sure data is not null. Maybe unnecessary, but better be safe */ 25234 host = ast_strdupa(data ? data : ""); 25235 if ((tmp = strchr(host, '@'))) 25236 host = tmp + 1; 25237 25238 ast_debug(3, "Checking device state for peer %s\n", host); 25239 25240 /* If find_peer asks for a realtime peer, then this breaks rtautoclear. This 25241 * is because when a peer tries to autoexpire, the last thing it does is to 25242 * queue up an event telling the system that the devicestate has changed 25243 * (presumably to unavailable). If we ask for a realtime peer here, this would 25244 * load it BACK into memory, thus defeating the point of trying to clear dead 25245 * hosts out of memory. 25246 */ 25247 if ((p = find_peer(host, NULL, FALSE, FINDALLDEVICES, TRUE, 0))) { 25248 if (!(ast_sockaddr_isnull(&p->addr) && ast_sockaddr_isnull(&p->defaddr))) { 25249 /* we have an address for the peer */ 25250 25251 /* Check status in this order 25252 - Hold 25253 - Ringing 25254 - Busy (enforced only by call limit) 25255 - Inuse (we have a call) 25256 - Unreachable (qualify) 25257 If we don't find any of these state, report AST_DEVICE_NOT_INUSE 25258 for registered devices */ 25259 25260 if (p->onHold) 25261 /* First check for hold or ring states */ 25262 res = AST_DEVICE_ONHOLD; 25263 else if (p->inRinging) { 25264 if (p->inRinging == p->inUse) 25265 res = AST_DEVICE_RINGING; 25266 else 25267 res = AST_DEVICE_RINGINUSE; 25268 } else if (p->call_limit && (p->inUse == p->call_limit)) 25269 /* check call limit */ 25270 res = AST_DEVICE_BUSY; 25271 else if (p->call_limit && p->busy_level && p->inUse >= p->busy_level) 25272 /* We're forcing busy before we've reached the call limit */ 25273 res = AST_DEVICE_BUSY; 25274 else if (p->call_limit && p->inUse) 25275 /* Not busy, but we do have a call */ 25276 res = AST_DEVICE_INUSE; 25277 else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0))) 25278 /* We don't have a call. Are we reachable at all? Requires qualify= */ 25279 res = AST_DEVICE_UNAVAILABLE; 25280 else /* Default reply if we're registered and have no other data */ 25281 res = AST_DEVICE_NOT_INUSE; 25282 } else { 25283 /* there is no address, it's unavailable */ 25284 res = AST_DEVICE_UNAVAILABLE; 25285 } 25286 unref_peer(p, "unref_peer, from sip_devicestate, release ref from find_peer"); 25287 } else { 25288 res = AST_DEVICE_UNKNOWN; 25289 } 25290 25291 return res; 25292 }
| static char * sip_do_debug | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Turn on SIP debugging (CLI command).
Definition at line 18072 of file chan_sip.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sip_peer(), debugaddr, ast_cli_args::fd, ast_cli_args::n, ast_cli_args::pos, sip_do_debug_ip(), sip_do_debug_peer(), sipdebug_text, ast_cli_entry::usage, and ast_cli_args::word.
18073 { 18074 int oldsipdebug = sipdebug & sip_debug_console; 18075 const char *what; 18076 18077 if (cmd == CLI_INIT) { 18078 e->command = "sip set debug {on|off|ip|peer}"; 18079 e->usage = 18080 "Usage: sip set debug {off|on|ip addr[:port]|peer peername}\n" 18081 " Globally disables dumping of SIP packets,\n" 18082 " or enables it either globally or for a (single)\n" 18083 " IP address or registered peer.\n"; 18084 return NULL; 18085 } else if (cmd == CLI_GENERATE) { 18086 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer")) 18087 return complete_sip_peer(a->word, a->n, 0); 18088 return NULL; 18089 } 18090 18091 what = a->argv[e->args-1]; /* guaranteed to exist */ 18092 if (a->argc == e->args) { /* on/off */ 18093 if (!strcasecmp(what, "on")) { 18094 sipdebug |= sip_debug_console; 18095 sipdebug_text = 1; /*! \note this can be a special debug command - "sip debug text" or something */ 18096 memset(&debugaddr, 0, sizeof(debugaddr)); 18097 ast_cli(a->fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 18098 return CLI_SUCCESS; 18099 } else if (!strcasecmp(what, "off")) { 18100 sipdebug &= ~sip_debug_console; 18101 sipdebug_text = 0; 18102 ast_cli(a->fd, "SIP Debugging Disabled\n"); 18103 return CLI_SUCCESS; 18104 } 18105 } else if (a->argc == e->args +1) {/* ip/peer */ 18106 if (!strcasecmp(what, "ip")) 18107 return sip_do_debug_ip(a->fd, a->argv[e->args]); 18108 else if (!strcasecmp(what, "peer")) 18109 return sip_do_debug_peer(a->fd, a->argv[e->args]); 18110 } 18111 return CLI_SHOWUSAGE; /* default, failure */ 18112 }
| static char * sip_do_debug_ip | ( | int | fd, | |
| const char * | arg | |||
| ) | [static] |
Enable SIP Debugging for a single IP.
Definition at line 18041 of file chan_sip.c.
References ast_cli(), ast_sockaddr_resolve_first(), ast_sockaddr_stringify_addr(), CLI_SHOWUSAGE, CLI_SUCCESS, and debugaddr.
Referenced by sip_do_debug().
18042 { 18043 if (ast_sockaddr_resolve_first(&debugaddr, arg, 0)) { 18044 return CLI_SHOWUSAGE; 18045 } 18046 18047 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_sockaddr_stringify_addr(&debugaddr)); 18048 sipdebug |= sip_debug_console; 18049 18050 return CLI_SUCCESS; 18051 }
| static char * sip_do_debug_peer | ( | int | fd, | |
| const char * | arg | |||
| ) | [static] |
Turn on SIP debugging for a given peer.
Definition at line 18054 of file chan_sip.c.
References ast_cli(), ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_stringify_addr(), CLI_SUCCESS, debugaddr, FALSE, find_peer(), TRUE, and unref_peer().
Referenced by sip_do_debug().
18055 { 18056 struct sip_peer *peer = find_peer(arg, NULL, TRUE, FINDPEERS, FALSE, 0); 18057 if (!peer) 18058 ast_cli(fd, "No such peer '%s'\n", arg); 18059 else if (ast_sockaddr_isnull(&peer->addr)) 18060 ast_cli(fd, "Unable to get IP address of peer '%s'\n", arg); 18061 else { 18062 ast_sockaddr_copy(&debugaddr, &peer->addr); 18063 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_sockaddr_stringify_addr(&debugaddr)); 18064 sipdebug |= sip_debug_console; 18065 } 18066 if (peer) 18067 unref_peer(peer, "sip_do_debug_peer: unref_peer, from find_peer call"); 18068 return CLI_SUCCESS; 18069 }
| static int sip_do_reload | ( | enum channelreloadreason | reason | ) | [static] |
Reload module.
Definition at line 28358 of file chan_sip.c.
References ast_debug, ast_sched_dump(), reload_config(), sip_poke_all_peers(), sip_send_all_mwi_subscriptions(), sip_send_all_registers(), and unlink_marked_peers_from_tables().
Referenced by do_monitor().
28359 { 28360 time_t start_poke, end_poke; 28361 28362 reload_config(reason); 28363 ast_sched_dump(sched); 28364 28365 start_poke = time(0); 28366 /* Prune peers who still are supposed to be deleted */ 28367 unlink_marked_peers_from_tables(); 28368 28369 ast_debug(4, "--------------- Done destroying pruned peers\n"); 28370 28371 /* Send qualify (OPTIONS) to all peers */ 28372 sip_poke_all_peers(); 28373 28374 /* Register with all services */ 28375 sip_send_all_registers(); 28376 28377 sip_send_all_mwi_subscriptions(); 28378 28379 end_poke = time(0); 28380 28381 ast_debug(4, "do_reload finished. peer poke/prune reg contact time = %d sec.\n", (int)(end_poke-start_poke)); 28382 28383 ast_debug(4, "--------------- SIP reload done\n"); 28384 28385 return 0; 28386 }
| static int sip_dtmfmode | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Set the DTMFmode for an outbound SIP call (application).
Definition at line 28046 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_log(), AST_RTP_DTMF, ast_rtp_instance_set_prop(), AST_RTP_PROPERTY_DTMF, ast_set_flag, ast_test_flag, disable_dsp_detect(), enable_dsp_detect(), LOG_WARNING, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech, and ast_channel::tech_pvt.
Referenced by load_module().
28047 { 28048 struct sip_pvt *p; 28049 const char *mode = data; 28050 28051 if (!data) { 28052 ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n"); 28053 return 0; 28054 } 28055 ast_channel_lock(chan); 28056 if (!IS_SIP_TECH(chan->tech)) { 28057 ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n"); 28058 ast_channel_unlock(chan); 28059 return 0; 28060 } 28061 p = chan->tech_pvt; 28062 if (!p) { 28063 ast_channel_unlock(chan); 28064 return 0; 28065 } 28066 sip_pvt_lock(p); 28067 if (!strcasecmp(mode, "info")) { 28068 ast_clear_flag(&p->flags[0], SIP_DTMF); 28069 ast_set_flag(&p->flags[0], SIP_DTMF_INFO); 28070 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 28071 } else if (!strcasecmp(mode, "shortinfo")) { 28072 ast_clear_flag(&p->flags[0], SIP_DTMF); 28073 ast_set_flag(&p->flags[0], SIP_DTMF_SHORTINFO); 28074 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 28075 } else if (!strcasecmp(mode, "rfc2833")) { 28076 ast_clear_flag(&p->flags[0], SIP_DTMF); 28077 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 28078 p->jointnoncodeccapability |= AST_RTP_DTMF; 28079 } else if (!strcasecmp(mode, "inband")) { 28080 ast_clear_flag(&p->flags[0], SIP_DTMF); 28081 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 28082 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 28083 } else { 28084 ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n", mode); 28085 } 28086 if (p->rtp) 28087 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 28088 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || 28089 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) { 28090 enable_dsp_detect(p); 28091 } else { 28092 disable_dsp_detect(p); 28093 } 28094 sip_pvt_unlock(p); 28095 ast_channel_unlock(chan); 28096 return 0; 28097 }
| 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 17826 of file chan_sip.c.
References ast_debug, AST_LIST_TRAVERSE, ast_log(), LOG_NOTICE, and option_debug.
Referenced by __sip_destroy().
17827 { 17828 int x = 0; 17829 struct sip_history *hist; 17830 static int errmsg = 0; 17831 17832 if (!dialog) 17833 return; 17834 17835 if (!option_debug && !sipdebug) { 17836 if (!errmsg) { 17837 ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n"); 17838 errmsg = 1; 17839 } 17840 return; 17841 } 17842 17843 ast_debug(1, "\n---------- SIP HISTORY for '%s' \n", dialog->callid); 17844 if (dialog->subscribed) 17845 ast_debug(1, " * Subscription\n"); 17846 else 17847 ast_debug(1, " * SIP Call\n"); 17848 if (dialog->history) 17849 AST_LIST_TRAVERSE(dialog->history, hist, list) 17850 ast_debug(1, " %-3.3d. %s\n", ++x, hist->event); 17851 if (!x) 17852 ast_debug(1, "Call '%s' has no history\n", dialog->callid); 17853 ast_debug(1, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid); 17854 }
| static int sip_epa_register | ( | const struct epa_static_data * | static_data | ) | [static] |
Definition at line 858 of file chan_sip.c.
References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, and AST_LIST_UNLOCK.
Referenced by load_module().
00859 { 00860 struct epa_backend *backend = ast_calloc(1, sizeof(*backend)); 00861 00862 if (!backend) { 00863 return -1; 00864 } 00865 00866 backend->static_data = static_data; 00867 00868 AST_LIST_LOCK(&epa_static_data_list); 00869 AST_LIST_INSERT_TAIL(&epa_static_data_list, backend, next); 00870 AST_LIST_UNLOCK(&epa_static_data_list); 00871 return 0; 00872 }
| 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 6311 of file chan_sip.c.
References append_history, ast_debug, AST_FLAG_ZOMBIE, ast_log(), ast_test_flag, LOG_WARNING, ast_channel::name, sip_pvt_lock, sip_pvt_unlock, sip_set_rtp_peer(), and ast_channel::tech_pvt.
06312 { 06313 int ret = -1; 06314 struct sip_pvt *p; 06315 06316 if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE)) 06317 ast_debug(1, "New channel is zombie\n"); 06318 if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE)) 06319 ast_debug(1, "Old channel is zombie\n"); 06320 06321 if (!newchan || !newchan->tech_pvt) { 06322 if (!newchan) 06323 ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name); 06324 else 06325 ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name); 06326 return -1; 06327 } 06328 p = newchan->tech_pvt; 06329 06330 sip_pvt_lock(p); 06331 append_history(p, "Masq", "Old channel: %s\n", oldchan->name); 06332 append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name); 06333 if (p->owner != oldchan) 06334 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner); 06335 else { 06336 p->owner = newchan; 06337 /* Re-invite RTP back to Asterisk. Needed if channel is masqueraded out of a native 06338 RTP bridge (i.e., RTP not going through Asterisk): RTP bridge code might not be 06339 able to do this if the masquerade happens before the bridge breaks (e.g., AMI 06340 redirect of both channels). Note that a channel can not be masqueraded *into* 06341 a native bridge. So there is no danger that this breaks a native bridge that 06342 should stay up. */ 06343 sip_set_rtp_peer(newchan, NULL, NULL, 0, 0, 0); 06344 ret = 0; 06345 } 06346 ast_debug(3, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name); 06347 06348 sip_pvt_unlock(p); 06349 return ret; 06350 }
| static const char * sip_get_callid | ( | struct ast_channel * | chan | ) | [static] |
Deliver SIP call ID for the call.
Definition at line 4328 of file chan_sip.c.
References ast_channel::tech_pvt.
| static int sip_get_cc_information | ( | struct sip_request * | req, | |
| char * | subscribe_uri, | |||
| size_t | size, | |||
| enum ast_cc_service_type * | service | |||
| ) | [static] |
Definition at line 2038 of file chan_sip.c.
References AST_CC_NONE, ast_copy_string(), ast_strdupa, ast_strlen_zero(), get_header(), service_string_to_service_type(), and strsep().
Referenced by sip_handle_cc().
02039 { 02040 char *call_info = ast_strdupa(get_header(req, "Call-Info")); 02041 char *uri; 02042 char *purpose; 02043 char *service_str; 02044 static const char cc_purpose[] = "purpose=call-completion"; 02045 static const int cc_purpose_len = sizeof(cc_purpose) - 1; 02046 02047 if (ast_strlen_zero(call_info)) { 02048 /* No Call-Info present. Definitely no CC offer */ 02049 return -1; 02050 } 02051 02052 uri = strsep(&call_info, ";"); 02053 02054 while ((purpose = strsep(&call_info, ";"))) { 02055 if (!strncmp(purpose, cc_purpose, cc_purpose_len)) { 02056 break; 02057 } 02058 } 02059 if (!purpose) { 02060 /* We didn't find the appropriate purpose= parameter. Oh well */ 02061 return -1; 02062 } 02063 02064 /* Okay, call-completion has been offered. Let's figure out what type of service this is */ 02065 while ((service_str = strsep(&call_info, ";"))) { 02066 if (!strncmp(service_str, "m=", 2)) { 02067 break; 02068 } 02069 } 02070 if (!service_str) { 02071 /* So they didn't offer a particular service, We'll just go with CCBS since it really 02072 * doesn't matter anyway 02073 */ 02074 service_str = "BS"; 02075 } else { 02076 /* We already determined that there is an "m=" so no need to check 02077 * the result of this strsep 02078 */ 02079 strsep(&service_str, "="); 02080 } 02081 02082 if ((*service = service_string_to_service_type(service_str)) == AST_CC_NONE) { 02083 /* Invalid service offered */ 02084 return -1; 02085 } 02086 02087 ast_copy_string(subscribe_uri, get_in_brackets(uri), size); 02088 02089 return 0; 02090 }
| static format_t sip_get_codec | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 28026 of file chan_sip.c.
References ast_channel::tech_pvt.
28027 { 28028 struct sip_pvt *p = chan->tech_pvt; 28029 return p->peercapability ? p->peercapability : p->capability; 28030 }
| static enum ast_rtp_glue_result sip_get_rtp_peer | ( | struct ast_channel * | chan, | |
| struct ast_rtp_instance ** | instance | |||
| ) | [static] |
Definition at line 27840 of file chan_sip.c.
References ao2_ref, apply_directmedia_ha(), AST_JB_FORCED, AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_LOCAL, AST_RTP_GLUE_RESULT_REMOTE, ast_test_flag, global_jbconf, sip_pvt_lock, sip_pvt_unlock, and ast_channel::tech_pvt.
27841 { 27842 struct sip_pvt *p = NULL; 27843 enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_LOCAL; 27844 27845 if (!(p = chan->tech_pvt)) { 27846 return AST_RTP_GLUE_RESULT_FORBID; 27847 } 27848 27849 sip_pvt_lock(p); 27850 if (!(p->rtp)) { 27851 sip_pvt_unlock(p); 27852 return AST_RTP_GLUE_RESULT_FORBID; 27853 } 27854 27855 ao2_ref(p->rtp, +1); 27856 *instance = p->rtp; 27857 27858 if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) { 27859 res = AST_RTP_GLUE_RESULT_REMOTE; 27860 if (!apply_directmedia_ha(p, "audio")) { 27861 res = AST_RTP_GLUE_RESULT_FORBID; 27862 } 27863 } else if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA_NAT)) { 27864 res = AST_RTP_GLUE_RESULT_REMOTE; 27865 } else if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) { 27866 res = AST_RTP_GLUE_RESULT_FORBID; 27867 } 27868 27869 if (p->srtp) { 27870 res = AST_RTP_GLUE_RESULT_FORBID; 27871 } 27872 27873 sip_pvt_unlock(p); 27874 27875 return res; 27876 }
| static enum ast_rtp_glue_result sip_get_trtp_peer | ( | struct ast_channel * | chan, | |
| struct ast_rtp_instance ** | instance | |||
| ) | [static] |
Definition at line 27908 of file chan_sip.c.
References ao2_ref, apply_directmedia_ha(), AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_REMOTE, ast_test_flag, sip_pvt_lock, sip_pvt_unlock, and ast_channel::tech_pvt.
27909 { 27910 struct sip_pvt *p = NULL; 27911 enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_FORBID; 27912 27913 if (!(p = chan->tech_pvt)) { 27914 return AST_RTP_GLUE_RESULT_FORBID; 27915 } 27916 27917 sip_pvt_lock(p); 27918 if (!(p->trtp)) { 27919 sip_pvt_unlock(p); 27920 return AST_RTP_GLUE_RESULT_FORBID; 27921 } 27922 27923 ao2_ref(p->trtp, +1); 27924 *instance = p->trtp; 27925 27926 if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) { 27927 res = AST_RTP_GLUE_RESULT_REMOTE; 27928 if (!apply_directmedia_ha(p, "text")) { 27929 res = AST_RTP_GLUE_RESULT_FORBID; 27930 } 27931 } 27932 27933 sip_pvt_unlock(p); 27934 27935 return res; 27936 }
| static struct ast_udptl * sip_get_udptl_peer | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 27775 of file chan_sip.c.
References apply_directmedia_ha(), ast_test_flag, sip_pvt_lock, sip_pvt_unlock, and ast_channel::tech_pvt.
27776 { 27777 struct sip_pvt *p; 27778 struct ast_udptl *udptl = NULL; 27779 27780 p = chan->tech_pvt; 27781 if (!p) { 27782 return NULL; 27783 } 27784 27785 sip_pvt_lock(p); 27786 if (p->udptl && ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) { 27787 if (apply_directmedia_ha(p, "UDPTL T.38 data")) { 27788 udptl = p->udptl; 27789 } 27790 } 27791 sip_pvt_unlock(p); 27792 return udptl; 27793 }
| static enum ast_rtp_glue_result sip_get_vrtp_peer | ( | struct ast_channel * | chan, | |
| struct ast_rtp_instance ** | instance | |||
| ) | [static] |
Definition at line 27878 of file chan_sip.c.
References ao2_ref, apply_directmedia_ha(), AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_REMOTE, ast_test_flag, sip_pvt_lock, sip_pvt_unlock, and ast_channel::tech_pvt.
27879 { 27880 struct sip_pvt *p = NULL; 27881 enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_FORBID; 27882 27883 if (!(p = chan->tech_pvt)) { 27884 return AST_RTP_GLUE_RESULT_FORBID; 27885 } 27886 27887 sip_pvt_lock(p); 27888 if (!(p->vrtp)) { 27889 sip_pvt_unlock(p); 27890 return AST_RTP_GLUE_RESULT_FORBID; 27891 } 27892 27893 ao2_ref(p->vrtp, +1); 27894 *instance = p->vrtp; 27895 27896 if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) { 27897 res = AST_RTP_GLUE_RESULT_REMOTE; 27898 if (!apply_directmedia_ha(p, "video")) { 27899 res = AST_RTP_GLUE_RESULT_FORBID; 27900 } 27901 } 27902 27903 sip_pvt_unlock(p); 27904 27905 return res; 27906 }
| static void sip_handle_cc | ( | struct sip_pvt * | pvt, | |
| struct sip_request * | req, | |||
| enum ast_cc_service_type | service | |||
| ) | [static] |
Definition at line 2109 of file chan_sip.c.
References ao2_ref, AST_CC_GENERIC_MONITOR_TYPE, ast_cc_get_current_core_id(), AST_CC_MONITOR_ALWAYS, AST_CC_MONITOR_GENERIC, AST_CC_MONITOR_NATIVE, AST_CC_MONITOR_NEVER, ast_channel_get_device_name(), AST_CHANNEL_NAME, ast_get_cc_monitor_policy(), ast_module_ref(), ast_queue_cc_frame(), sip_get_cc_information(), and sip_monitor_instance_init().
Referenced by handle_response(), and handle_response_invite().
02110 { 02111 enum ast_cc_monitor_policies monitor_policy = ast_get_cc_monitor_policy(pvt->cc_params); 02112 int core_id; 02113 char interface_name[AST_CHANNEL_NAME]; 02114 02115 if (monitor_policy == AST_CC_MONITOR_NEVER) { 02116 /* Don't bother, just return */ 02117 return; 02118 } 02119 02120 if ((core_id = ast_cc_get_current_core_id(pvt->owner)) == -1) { 02121 /* For some reason, CC is invalid, so don't try it! */ 02122 return; 02123 } 02124 02125 ast_channel_get_device_name(pvt->owner, interface_name, sizeof(interface_name)); 02126 02127 if (monitor_policy == AST_CC_MONITOR_ALWAYS || monitor_policy == AST_CC_MONITOR_NATIVE) { 02128 char subscribe_uri[SIPBUFSIZE]; 02129 char device_name[AST_CHANNEL_NAME]; 02130 enum ast_cc_service_type offered_service; 02131 struct sip_monitor_instance *monitor_instance; 02132 if (sip_get_cc_information(req, subscribe_uri, sizeof(subscribe_uri), &offered_service)) { 02133 /* If CC isn't being offered to us, or for some reason the CC offer is 02134 * not formatted correctly, then it may still be possible to use generic 02135 * call completion since the monitor policy may be "always" 02136 */ 02137 goto generic; 02138 } 02139 ast_channel_get_device_name(pvt->owner, device_name, sizeof(device_name)); 02140 if (!(monitor_instance = sip_monitor_instance_init(core_id, subscribe_uri, pvt->peername, device_name))) { 02141 /* Same deal. We can try using generic still */ 02142 goto generic; 02143 } 02144 /* We bump the refcount of chan_sip because once we queue this frame, the CC core 02145 * will have a reference to callbacks in this module. We decrement the module 02146 * refcount once the monitor destructor is called 02147 */ 02148 ast_module_ref(ast_module_info->self); 02149 ast_queue_cc_frame(pvt->owner, "SIP", pvt->dialstring, offered_service, monitor_instance); 02150 ao2_ref(monitor_instance, -1); 02151 return; 02152 } 02153 02154 generic: 02155 if (monitor_policy == AST_CC_MONITOR_GENERIC || monitor_policy == AST_CC_MONITOR_ALWAYS) { 02156 ast_queue_cc_frame(pvt->owner, AST_CC_GENERIC_MONITOR_TYPE, interface_name, service, NULL); 02157 } 02158 }
| 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 5945 of file chan_sip.c.
References __sip_semi_ack(), ast_channel::_state, append_history, ast_bridged_channel(), ast_cause2str(), AST_CAUSE_ANSWERED_ELSEWHERE, ast_channel_trylock, ast_channel_unlock, ast_clear_flag, ast_debug, AST_FLAG_ANSWERED_ELSEWHERE, AST_FLAG_ZOMBIE, 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_DEL_UNREF, ast_set_flag, ast_state2str(), AST_STATE_UP, ast_strlen_zero(), ast_test_flag, ast_channel::bridge, CHANNEL_DEADLOCK_AVOIDANCE, disable_dsp_detect(), FALSE, find_sip_method(), hangup_cause2sip(), ast_channel::hangupcause, LOG_WARNING, ast_channel::name, pbx_builtin_setvar_helper(), pvt_set_needdestroy(), quality, sip_cancel_destroy(), sip_pvt_lock, sip_pvt_trylock, sip_pvt_unlock, sip_scheddestroy(), sipdebug, stop_media_flows(), stop_session_timer(), ast_channel::tech, ast_channel::tech_pvt, transmit_request(), transmit_request_with_auth(), transmit_response_reliable(), TRUE, and update_call_counter().
05946 { 05947 struct sip_pvt *p = ast->tech_pvt; 05948 int needcancel = FALSE; 05949 int needdestroy = 0; 05950 struct ast_channel *oldowner = ast; 05951 05952 if (!p) { 05953 ast_debug(1, "Asked to hangup channel that was not connected\n"); 05954 return 0; 05955 } 05956 if (ast_test_flag(ast, AST_FLAG_ANSWERED_ELSEWHERE) || ast->hangupcause == AST_CAUSE_ANSWERED_ELSEWHERE) { 05957 ast_debug(1, "This call was answered elsewhere"); 05958 if (ast->hangupcause == AST_CAUSE_ANSWERED_ELSEWHERE) { 05959 ast_debug(1, "####### It's the cause code, buddy. The cause code!!!\n"); 05960 } 05961 append_history(p, "Cancel", "Call answered elsewhere"); 05962 p->answered_elsewhere = TRUE; 05963 } 05964 05965 /* Store hangupcause locally in PVT so we still have it before disconnect */ 05966 if (p->owner) 05967 p->hangupcause = p->owner->hangupcause; 05968 05969 if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 05970 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 05971 if (sipdebug) 05972 ast_debug(1, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 05973 update_call_counter(p, DEC_CALL_LIMIT); 05974 } 05975 ast_debug(4, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid); 05976 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 05977 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */ 05978 p->needdestroy = 0; 05979 p->owner->tech_pvt = dialog_unref(p->owner->tech_pvt, "unref p->owner->tech_pvt"); 05980 sip_pvt_lock(p); 05981 p->owner = NULL; /* Owner will be gone after we return, so take it away */ 05982 sip_pvt_unlock(p); 05983 ast_module_unref(ast_module_info->self); 05984 return 0; 05985 } 05986 05987 if (ast_test_flag(ast, AST_FLAG_ZOMBIE)) { 05988 if (p->refer) 05989 ast_debug(1, "SIP Transfer: Hanging up Zombie channel %s after transfer ... Call-ID: %s\n", ast->name, p->callid); 05990 else 05991 ast_debug(1, "Hanging up zombie call. Be scared.\n"); 05992 } else 05993 ast_debug(1, "Hangup call %s, SIP callid %s\n", ast->name, p->callid); 05994 05995 sip_pvt_lock(p); 05996 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 05997 if (sipdebug) 05998 ast_debug(1, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 05999 update_call_counter(p, DEC_CALL_LIMIT); 06000 } 06001 06002 /* Determine how to disconnect */ 06003 if (p->owner != ast) { 06004 ast_log(LOG_WARNING, "Huh? We aren't the owner? Can't hangup call.\n"); 06005 sip_pvt_unlock(p); 06006 return 0; 06007 } 06008 /* If the call is not UP, we need to send CANCEL instead of BYE */ 06009 /* In case of re-invites, the call might be UP even though we have an incomplete invite transaction */ 06010 if (p->invitestate < INV_COMPLETED && p->owner->_state != AST_STATE_UP) { 06011 needcancel = TRUE; 06012 ast_debug(4, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state)); 06013 } 06014 06015 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 06016 06017 append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", p->owner ? ast_cause2str(p->hangupcause) : "Unknown"); 06018 06019 /* Disconnect */ 06020 disable_dsp_detect(p); 06021 06022 p->owner = NULL; 06023 ast->tech_pvt = dialog_unref(ast->tech_pvt, "unref ast->tech_pvt"); 06024 06025 ast_module_unref(ast_module_info->self); 06026 /* Do not destroy this pvt until we have timeout or 06027 get an answer to the BYE or INVITE/CANCEL 06028 If we get no answer during retransmit period, drop the call anyway. 06029 (Sorry, mother-in-law, you can't deny a hangup by sending 06030 603 declined to BYE...) 06031 */ 06032 if (p->alreadygone) 06033 needdestroy = 1; /* Set destroy flag at end of this function */ 06034 else if (p->invitestate != INV_CALLING) 06035 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 06036 06037 /* Start the process if it's not already started */ 06038 if (!p->alreadygone && p->initreq.data && !ast_strlen_zero(p->initreq.data->str)) { 06039 if (needcancel) { /* Outgoing call, not up */ 06040 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06041 /* if we can't send right now, mark it pending */ 06042 if (p->invitestate == INV_CALLING) { 06043 /* We can't send anything in CALLING state */ 06044 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 06045 /* 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. */ 06046 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 06047 append_history(p, "DELAY", "Not sending cancel, waiting for timeout"); 06048 } else { 06049 struct sip_pkt *cur; 06050 06051 for (cur = p->packets; cur; cur = cur->next) { 06052 __sip_semi_ack(p, cur->seqno, cur->is_resp, cur->method ? cur->method : find_sip_method(cur->data->str)); 06053 } 06054 p->invitestate = INV_CANCELLED; 06055 /* Send a new request: CANCEL */ 06056 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 06057 /* Actually don't destroy us yet, wait for the 487 on our original 06058 INVITE, but do set an autodestruct just in case we never get it. */ 06059 needdestroy = 0; 06060 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 06061 } 06062 } else { /* Incoming call, not up */ 06063 const char *res; 06064 AST_SCHED_DEL_UNREF(sched, p->provisional_keepalive_sched_id, dialog_unref(p, "when you delete the provisional_keepalive_sched_id, you should dec the refcount for the stored dialog ptr")); 06065 if (p->hangupcause && (res = hangup_cause2sip(p->hangupcause))) 06066 transmit_response_reliable(p, res, &p->initreq); 06067 else 06068 transmit_response_reliable(p, "603 Declined", &p->initreq); 06069 p->invitestate = INV_TERMINATED; 06070 } 06071 } else { /* Call is in UP state, send BYE */ 06072 if (p->stimer->st_active == TRUE) { 06073 stop_session_timer(p); 06074 } 06075 06076 if (!p->pendinginvite) { 06077 struct ast_channel *bridge = ast_bridged_channel(oldowner); 06078 char quality_buf[AST_MAX_USER_FIELD], *quality; 06079 06080 /* We need to get the lock on bridge because ast_rtp_instance_set_stats_vars will attempt 06081 * to lock the bridge. This may get hairy... 06082 */ 06083 while (bridge && ast_channel_trylock(bridge)) { 06084 sip_pvt_unlock(p); 06085 do { 06086 CHANNEL_DEADLOCK_AVOIDANCE(oldowner); 06087 } while (sip_pvt_trylock(p)); 06088 bridge = ast_bridged_channel(oldowner); 06089 } 06090 06091 if (p->rtp) { 06092 ast_rtp_instance_set_stats_vars(oldowner, p->rtp); 06093 } 06094 06095 if (bridge) { 06096 struct sip_pvt *q = bridge->tech_pvt; 06097 06098 if (IS_SIP_TECH(bridge->tech) && q && q->rtp) { 06099 ast_rtp_instance_set_stats_vars(bridge, q->rtp); 06100 } 06101 ast_channel_unlock(bridge); 06102 } 06103 06104 if (p->do_history || oldowner) { 06105 if (p->rtp && (quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) { 06106 if (p->do_history) { 06107 append_history(p, "RTCPaudio", "Quality:%s", quality); 06108 } 06109 if (oldowner) { 06110 pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", quality); 06111 } 06112 } 06113 if (p->vrtp && (quality = ast_rtp_instance_get_quality(p->vrtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) { 06114 if (p->do_history) { 06115 append_history(p, "RTCPvideo", "Quality:%s", quality); 06116 } 06117 if (oldowner) { 06118 pbx_builtin_setvar_helper(oldowner, "RTPVIDEOQOS", quality); 06119 } 06120 } 06121 if (p->trtp && (quality = ast_rtp_instance_get_quality(p->trtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) { 06122 if (p->do_history) { 06123 append_history(p, "RTCPtext", "Quality:%s", quality); 06124 } 06125 if (oldowner) { 06126 pbx_builtin_setvar_helper(oldowner, "RTPTEXTQOS", quality); 06127 } 06128 } 06129 } 06130 06131 /* Send a hangup */ 06132 if (oldowner->_state == AST_STATE_UP) { 06133 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 06134 } 06135 06136 } else { 06137 /* Note we will need a BYE when this all settles out 06138 but we can't send one while we have "INVITE" outstanding. */ 06139 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 06140 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 06141 AST_SCHED_DEL_UNREF(sched, p->waitid, dialog_unref(p, "when you delete the waitid sched, you should dec the refcount for the stored dialog ptr")); 06142 if (sip_cancel_destroy(p)) 06143 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 06144 } 06145 } 06146 } 06147 if (needdestroy) { 06148 pvt_set_needdestroy(p, "hangup"); 06149 } 06150 sip_pvt_unlock(p); 06151 return 0; 06152 }
| static int sip_indicate | ( | struct ast_channel * | ast, | |
| int | condition, | |||
| const void * | data, | |||
| size_t | datalen | |||
| ) | [static] |
Play indication to user With SIP a lot of indications is sent as messages, letting the device play the indication - busy signal, congestion etc.
Definition at line 6514 of file chan_sip.c.
References ast_channel::_state, AST_AOC_D, ast_aoc_decode(), ast_aoc_destroy_decoded(), AST_AOC_E, ast_aoc_get_msg_type(), ast_aoc_get_termination_request(), AST_AOC_REQUEST, AST_AOC_S, AST_CONTROL_AOC, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_debug, ast_log(), ast_moh_start(), ast_moh_stop(), ast_rtp_instance_change_source(), ast_rtp_instance_update_source(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_UP, ast_test_flag, interpret_t38_parameters(), LOG_ERROR, LOG_WARNING, sip_alreadygone(), sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, transmit_info_with_aoc(), transmit_info_with_vidupdate(), transmit_provisional_response(), transmit_response(), transmit_response_reliable(), TRUE, update_connectedline(), and update_redirecting().
06515 { 06516 struct sip_pvt *p = ast->tech_pvt; 06517 int res = 0; 06518 06519 sip_pvt_lock(p); 06520 switch(condition) { 06521 case AST_CONTROL_RINGING: 06522 if (ast->_state == AST_STATE_RING) { 06523 p->invitestate = INV_EARLY_MEDIA; 06524 if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) || 06525 (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) { 06526 /* Send 180 ringing if out-of-band seems reasonable */ 06527 transmit_provisional_response(p, "180 Ringing", &p->initreq, 0); 06528 ast_set_flag(&p->flags[0], SIP_RINGING); 06529 if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES) 06530 break; 06531 } else { 06532 /* Well, if it's not reasonable, just send in-band */ 06533 } 06534 } 06535 res = -1; 06536 break; 06537 case AST_CONTROL_BUSY: 06538 if (ast->_state != AST_STATE_UP) { 06539 transmit_response_reliable(p, "486 Busy Here", &p->initreq); 06540 p->invitestate = INV_COMPLETED; 06541 sip_alreadygone(p); 06542 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 06543 break; 06544 } 06545 res = -1; 06546 break; 06547 case AST_CONTROL_CONGESTION: 06548 if (ast->_state != AST_STATE_UP) { 06549 transmit_response_reliable(p, "503 Service Unavailable", &p->initreq); 06550 p->invitestate = INV_COMPLETED; 06551 sip_alreadygone(p); 06552 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 06553 break; 06554 } 06555 res = -1; 06556 break; 06557 case AST_CONTROL_PROCEEDING: 06558 if ((ast->_state != AST_STATE_UP) && 06559 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 06560 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06561 transmit_response(p, "100 Trying", &p->initreq); 06562 p->invitestate = INV_PROCEEDING; 06563 break; 06564 } 06565 res = -1; 06566 break; 06567 case AST_CONTROL_PROGRESS: 06568 if ((ast->_state != AST_STATE_UP) && 06569 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 06570 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06571 p->invitestate = INV_EARLY_MEDIA; 06572 transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE); 06573 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 06574 break; 06575 } 06576 res = -1; 06577 break; 06578 case AST_CONTROL_HOLD: 06579 ast_rtp_instance_update_source(p->rtp); 06580 ast_moh_start(ast, data, p->mohinterpret); 06581 break; 06582 case AST_CONTROL_UNHOLD: 06583 ast_rtp_instance_update_source(p->rtp); 06584 ast_moh_stop(ast); 06585 break; 06586 case AST_CONTROL_VIDUPDATE: /* Request a video frame update */ 06587 if (p->vrtp && !p->novideo) { 06588 transmit_info_with_vidupdate(p); 06589 /* ast_rtcp_send_h261fur(p->vrtp); */ 06590 } else 06591 res = -1; 06592 break; 06593 case AST_CONTROL_T38_PARAMETERS: 06594 if (datalen != sizeof(struct ast_control_t38_parameters)) { 06595 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); 06596 res = -1; 06597 } else { 06598 const struct ast_control_t38_parameters *parameters = data; 06599 res = interpret_t38_parameters(p, parameters); 06600 } 06601 break; 06602 case AST_CONTROL_SRCUPDATE: 06603 ast_rtp_instance_update_source(p->rtp); 06604 break; 06605 case AST_CONTROL_SRCCHANGE: 06606 ast_rtp_instance_change_source(p->rtp); 06607 break; 06608 case AST_CONTROL_CONNECTED_LINE: 06609 update_connectedline(p, data, datalen); 06610 break; 06611 case AST_CONTROL_REDIRECTING: 06612 update_redirecting(p, data, datalen); 06613 break; 06614 case AST_CONTROL_AOC: 06615 { 06616 struct ast_aoc_decoded *decoded = ast_aoc_decode((struct ast_aoc_encoded *) data, datalen, ast); 06617 if (!decoded) { 06618 ast_log(LOG_ERROR, "Error decoding indicated AOC data\n"); 06619 res = -1; 06620 break; 06621 } 06622 switch (ast_aoc_get_msg_type(decoded)) { 06623 case AST_AOC_REQUEST: 06624 if (ast_aoc_get_termination_request(decoded)) { 06625 /* TODO, once there is a way to get AOC-E on hangup, attempt that here 06626 * before hanging up the channel.*/ 06627 06628 /* The other side has already initiated the hangup. This frame 06629 * just says they are waiting to get AOC-E before completely tearing 06630 * the call down. Since SIP does not support this at the moment go 06631 * ahead and terminate the call here to avoid an unnecessary timeout. */ 06632 ast_debug(1, "AOC-E termination request received on %s. This is not yet supported on sip. Continue with hangup \n", p->owner->name); 06633 ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV); 06634 } 06635 break; 06636 case AST_AOC_D: 06637 case AST_AOC_E: 06638 if (ast_test_flag(&p->flags[2], SIP_PAGE3_SNOM_AOC)) { 06639 transmit_info_with_aoc(p, decoded); 06640 } 06641 break; 06642 case AST_AOC_S: /* S not supported yet */ 06643 default: 06644 break; 06645 } 06646 ast_aoc_destroy_decoded(decoded); 06647 } 06648 break; 06649 case -1: 06650 res = -1; 06651 break; 06652 default: 06653 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition); 06654 res = -1; 06655 break; 06656 } 06657 sip_pvt_unlock(p); 06658 return res; 06659 }
| static int sip_is_xml_parsable | ( | void | ) | [static] |
Definition at line 28231 of file chan_sip.c.
Referenced by load_module().
28232 { 28233 #ifdef HAVE_LIBXML2 28234 return TRUE; 28235 #else 28236 return FALSE; 28237 #endif 28238 }
| static int sip_monitor_instance_cmp_fn | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1816 of file chan_sip.c.
References CMP_MATCH, and CMP_STOP.
Referenced by load_module().
01817 { 01818 struct sip_monitor_instance *monitor_instance1 = obj; 01819 struct sip_monitor_instance *monitor_instance2 = arg; 01820 01821 return monitor_instance1->core_id == monitor_instance2->core_id ? CMP_MATCH | CMP_STOP : 0; 01822 }
| static void sip_monitor_instance_destructor | ( | void * | data | ) | [static] |
Definition at line 1824 of file chan_sip.c.
References ao2_t_ref, ast_string_field_free_memory, FALSE, sip_pvt_lock, sip_pvt_unlock, transmit_invite(), and transmit_publish().
Referenced by sip_monitor_instance_init().
01825 { 01826 struct sip_monitor_instance *monitor_instance = data; 01827 if (monitor_instance->subscription_pvt) { 01828 sip_pvt_lock(monitor_instance->subscription_pvt); 01829 monitor_instance->subscription_pvt->expiry = 0; 01830 transmit_invite(monitor_instance->subscription_pvt, SIP_SUBSCRIBE, FALSE, 0, monitor_instance->subscribe_uri); 01831 sip_pvt_unlock(monitor_instance->subscription_pvt); 01832 dialog_unref(monitor_instance->subscription_pvt, "Unref monitor instance ref of subscription pvt"); 01833 } 01834 if (monitor_instance->suspension_entry) { 01835 monitor_instance->suspension_entry->body[0] = '\0'; 01836 transmit_publish(monitor_instance->suspension_entry, SIP_PUBLISH_REMOVE ,monitor_instance->notify_uri); 01837 ao2_t_ref(monitor_instance->suspension_entry, -1, "Decrementing suspension entry refcount in sip_monitor_instance_destructor"); 01838 } 01839 ast_string_field_free_memory(monitor_instance); 01840 }
| static int sip_monitor_instance_hash_fn | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 1810 of file chan_sip.c.
Referenced by load_module().
01811 { 01812 const struct sip_monitor_instance *monitor_instance = obj; 01813 return monitor_instance->core_id; 01814 }
| 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 1842 of file chan_sip.c.
References ao2_alloc, ao2_link, ao2_ref, ast_string_field_init, ast_string_field_set, sip_monitor_instance_destructor(), and sip_monitor_instances.
Referenced by sip_handle_cc().
01843 { 01844 struct sip_monitor_instance *monitor_instance = ao2_alloc(sizeof(*monitor_instance), sip_monitor_instance_destructor); 01845 01846 if (!monitor_instance) { 01847 return NULL; 01848 } 01849 01850 if (ast_string_field_init(monitor_instance, 256)) { 01851 ao2_ref(monitor_instance, -1); 01852 return NULL; 01853 } 01854 01855 ast_string_field_set(monitor_instance, subscribe_uri, subscribe_uri); 01856 ast_string_field_set(monitor_instance, peername, peername); 01857 ast_string_field_set(monitor_instance, device_name, device_name); 01858 monitor_instance->core_id = core_id; 01859 ao2_link(sip_monitor_instances, monitor_instance); 01860 return monitor_instance; 01861 }
| static const char * sip_nat_mode | ( | const struct sip_pvt * | p | ) | [static] |
Display SIP nat mode.
Definition at line 3129 of file chan_sip.c.
References ast_test_flag.
Referenced by check_via(), retrans_pkt(), and send_response().
03130 { 03131 return ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT) ? "NAT" : "no NAT"; 03132 }
| static struct ast_channel* sip_new | ( | struct sip_pvt * | i, | |
| int | state, | |||
| const char * | title, | |||
| const char * | linkedid | |||
| ) | [static] |
Initiate a call in the SIP channel called from sip_request_call (calls from the pbx ) for outbound channels and from handle_request_invite for inbound channels.
Definition at line 6666 of file chan_sip.c.
References accountcode, ast_channel::adsicpe, ast_channel::amaflags, ast_party_caller::ani, append_history, AST_ADSI_UNAVAILABLE, ast_atomic_fetchadd_int(), ast_best_codec(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_alloc, ast_channel_cc_params_init(), ast_channel_lock, ast_channel_set_fd(), ast_channel_unlock, ast_codec_choose(), ast_copy_string(), ast_debug, ast_exists_extension(), AST_FORMAT_TEXT_MASK, AST_FORMAT_VIDEO_MASK, ast_get_encoded_str(), ast_getformatname_multiple(), ast_hangup(), ast_jb_configure(), ast_log(), ast_module_ref(), ast_pbx_start(), AST_RTP_DTMF_MODE_INBAND, AST_RTP_DTMF_MODE_RFC2833, ast_rtp_instance_dtmf_mode_set(), ast_rtp_instance_fd(), ast_rtp_instance_set_read_format(), ast_rtp_instance_set_write_format(), AST_STATE_DOWN, AST_STATE_RING, ast_strdup, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_fd(), ast_uri_decode(), ast_channel::caller, ast_channel::callgroup, chan_idx, ast_channel::context, ast_channel::dialed, enable_dsp_detect(), EVENT_FLAG_SYSTEM, ast_channel::exten, ast_party_redirecting::from, global_jbconf, ast_channel::hangupcause, ast_party_caller::id, language, LOG_WARNING, manager_event, ast_channel::name, ast_variable::name, ast_party_id::name, ast_channel::nativeformats, ast_variable::next, ast_party_dialed::number, ast_party_id::number, parkinglot, pbx_builtin_setvar_helper(), ast_channel::pickupgroup, ast_party_number::presentation, ast_party_name::presentation, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::redirecting, ast_channel::rings, sip_cfg, sip_pvt_lock, sip_pvt_unlock, sip_tech, sip_tech_info, ast_party_dialed::str, ast_party_number::str, ast_party_id::tag, ast_channel::tech, ast_channel::tech_pvt, text, ast_channel::uniqueid, ast_party_number::valid, ast_variable::value, and ast_channel::writeformat.
Referenced by handle_request_invite(), and sip_request_call().
06667 { 06668 struct ast_channel *tmp; 06669 struct ast_variable *v = NULL; 06670 format_t fmt; 06671 format_t what; 06672 format_t video; 06673 format_t text; 06674 format_t needvideo = 0; 06675 int needtext = 0; 06676 char buf[SIPBUFSIZE]; 06677 char *decoded_exten; 06678 06679 { 06680 const char *my_name; /* pick a good name */ 06681 06682 if (title) { 06683 my_name = title; 06684 } else { 06685 my_name = ast_strdupa(i->fromdomain); 06686 } 06687 06688 sip_pvt_unlock(i); 06689 /* Don't hold a sip pvt lock while we allocate a channel */ 06690 tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, linkedid, i->amaflags, "SIP/%s-%08x", my_name, ast_atomic_fetchadd_int((int *)&chan_idx, +1)); 06691 } 06692 if (!tmp) { 06693 ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n"); 06694 sip_pvt_lock(i); 06695 return NULL; 06696 } 06697 ast_channel_lock(tmp); 06698 sip_pvt_lock(i); 06699 ast_channel_cc_params_init(tmp, i->cc_params); 06700 tmp->caller.id.tag = ast_strdup(i->cid_tag); 06701 ast_channel_unlock(tmp); 06702 06703 tmp->tech = ( ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO || ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_SHORTINFO) ? &sip_tech_info : &sip_tech; 06704 06705 /* Select our native format based on codec preference until we receive 06706 something from another device to the contrary. */ 06707 if (i->jointcapability) { /* The joint capabilities of us and peer */ 06708 what = i->jointcapability; 06709 video = i->jointcapability & AST_FORMAT_VIDEO_MASK; 06710 text = i->jointcapability & AST_FORMAT_TEXT_MASK; 06711 } else if (i->capability) { /* Our configured capability for this peer */ 06712 what = i->capability; 06713 video = i->capability & AST_FORMAT_VIDEO_MASK; 06714 text = i->capability & AST_FORMAT_TEXT_MASK; 06715 } else { 06716 what = sip_cfg.capability; /* Global codec support */ 06717 video = sip_cfg.capability & AST_FORMAT_VIDEO_MASK; 06718 text = sip_cfg.capability & AST_FORMAT_TEXT_MASK; 06719 } 06720 06721 /* Set the native formats for audio and merge in video */ 06722 tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | video | text; 06723 ast_debug(3, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, tmp->nativeformats)); 06724 ast_debug(3, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->jointcapability)); 06725 ast_debug(3, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->capability)); 06726 ast_debug(3, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, ast_codec_choose(&i->prefs, what, 1))); 06727 if (i->prefcodec) 06728 ast_debug(3, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->prefcodec)); 06729 06730 /* XXX Why are we choosing a codec from the native formats?? */ 06731 fmt = ast_best_codec(tmp->nativeformats); 06732 06733 /* If we have a prefcodec setting, we have an inbound channel that set a 06734 preferred format for this call. Otherwise, we check the jointcapability 06735 We also check for vrtp. If it's not there, we are not allowed do any video anyway. 06736 */ 06737 if (i->vrtp) { 06738 if (ast_test_flag(&i->flags[1], SIP_PAGE2_VIDEOSUPPORT)) 06739 needvideo = AST_FORMAT_VIDEO_MASK; 06740 else if (i->prefcodec) 06741 needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK; /* Outbound call */ 06742 else 06743 needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK; /* Inbound call */ 06744 } 06745 06746 if (i->trtp) { 06747 if (i->prefcodec) 06748 needtext = i->prefcodec & AST_FORMAT_TEXT_MASK; /* Outbound call */ 06749 else 06750 needtext = i->jointcapability & AST_FORMAT_TEXT_MASK; /* Inbound call */ 06751 } 06752 06753 if (needvideo) 06754 ast_debug(3, "This channel can handle video! HOLLYWOOD next!\n"); 06755 else 06756 ast_debug(3, "This channel will not be able to handle video.\n"); 06757 06758 enable_dsp_detect(i); 06759 06760 if ((ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || 06761 (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) { 06762 if (!i->rtp || ast_rtp_instance_dtmf_mode_set(i->rtp, AST_RTP_DTMF_MODE_INBAND)) { 06763 enable_dsp_detect(i); 06764 } 06765 } else if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) { 06766 if (i->rtp) { 06767 ast_rtp_instance_dtmf_mode_set(i->rtp, AST_RTP_DTMF_MODE_RFC2833); 06768 } 06769 } 06770 06771 /* Set file descriptors for audio, video, realtime text and UDPTL as needed */ 06772 if (i->rtp) { 06773 ast_channel_set_fd(tmp, 0, ast_rtp_instance_fd(i->rtp, 0)); 06774 ast_channel_set_fd(tmp, 1, ast_rtp_instance_fd(i->rtp, 1)); 06775 } 06776 if (needvideo && i->vrtp) { 06777 ast_channel_set_fd(tmp, 2, ast_rtp_instance_fd(i->vrtp, 0)); 06778 ast_channel_set_fd(tmp, 3, ast_rtp_instance_fd(i->vrtp, 1)); 06779 } 06780 if (needtext && i->trtp) 06781 ast_channel_set_fd(tmp, 4, ast_rtp_instance_fd(i->trtp, 0)); 06782 if (i->udptl) 06783 ast_channel_set_fd(tmp, 5, ast_udptl_fd(i->udptl)); 06784 06785 if (state == AST_STATE_RING) 06786 tmp->rings = 1; 06787 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 06788 06789 tmp->writeformat = fmt; 06790 tmp->rawwriteformat = fmt; 06791 ast_rtp_instance_set_write_format(i->rtp, fmt); 06792 06793 tmp->readformat = fmt; 06794 tmp->rawreadformat = fmt; 06795 ast_rtp_instance_set_read_format(i->rtp, fmt); 06796 06797 tmp->tech_pvt = dialog_ref(i, "sip_new: set chan->tech_pvt to i"); 06798 06799 tmp->callgroup = i->callgroup; 06800 tmp->pickupgroup = i->pickupgroup; 06801 tmp->caller.id.name.presentation = i->callingpres; 06802 tmp->caller.id.number.presentation = i->callingpres; 06803 if (!ast_strlen_zero(i->parkinglot)) 06804 ast_string_field_set(tmp, parkinglot, i->parkinglot); 06805 if (!ast_strlen_zero(i->accountcode)) 06806 ast_string_field_set(tmp, accountcode, i->accountcode); 06807 if (i->amaflags) 06808 tmp->amaflags = i->amaflags; 06809 if (!ast_strlen_zero(i->language)) 06810 ast_string_field_set(tmp, language, i->language); 06811 i->owner = tmp; 06812 ast_module_ref(ast_module_info->self); 06813 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 06814 /*Since it is valid to have extensions in the dialplan that have unescaped characters in them 06815 * we should decode the uri before storing it in the channel, but leave it encoded in the sip_pvt 06816 * structure so that there aren't issues when forming URI's 06817 */ 06818 if (ast_exists_extension(NULL, i->context, i->exten, 1, i->cid_num)) { 06819 /* encoded in dialplan, so keep extension encoded */ 06820 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 06821 } else { 06822 decoded_exten = ast_strdupa(i->exten); 06823 ast_uri_decode(decoded_exten); 06824 ast_copy_string(tmp->exten, decoded_exten, sizeof(tmp->exten)); 06825 } 06826 06827 /* Don't use ast_set_callerid() here because it will 06828 * generate an unnecessary NewCallerID event */ 06829 if (!ast_strlen_zero(i->cid_num)) { 06830 tmp->caller.ani.number.valid = 1; 06831 tmp->caller.ani.number.str = ast_strdup(i->cid_num); 06832 } 06833 if (!ast_strlen_zero(i->rdnis)) { 06834 tmp->redirecting.from.number.valid = 1; 06835 tmp->redirecting.from.number.str = ast_strdup(i->rdnis); 06836 } 06837 06838 if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) { 06839 tmp->dialed.number.str = ast_strdup(i->exten); 06840 } 06841 06842 tmp->priority = 1; 06843 if (!ast_strlen_zero(i->uri)) 06844 pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri); 06845 if (!ast_strlen_zero(i->domain)) 06846 pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain); 06847 if (!ast_strlen_zero(i->callid)) 06848 pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid); 06849 if (i->rtp) 06850 ast_jb_configure(tmp, &global_jbconf); 06851 06852 /* Set channel variables for this call from configuration */ 06853 for (v = i->chanvars ; v ; v = v->next) { 06854 char valuebuf[1024]; 06855 pbx_builtin_setvar_helper(tmp, v->name, ast_get_encoded_str(v->value, valuebuf, sizeof(valuebuf))); 06856 } 06857 06858 if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) { 06859 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 06860 tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 06861 ast_hangup(tmp); 06862 tmp = NULL; 06863 } 06864 06865 if (i->do_history) 06866 append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid); 06867 06868 /* Inform manager user about new channel and their SIP call ID */ 06869 if (sip_cfg.callevents) 06870 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", 06871 "Channel: %s\r\nUniqueid: %s\r\nChanneltype: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\n", 06872 tmp->name, tmp->uniqueid, "SIP", i->callid, i->fullcontact); 06873 06874 return tmp; 06875 }
| static int sip_notify_allocate | ( | struct sip_pvt * | p | ) | [static] |
Allocate SIP refer structure.
Definition at line 12737 of file chan_sip.c.
References ast_calloc, and ast_str_create().
Referenced by manager_sipnotify(), and sip_cli_notify().
12738 { 12739 p->notify = ast_calloc(1, sizeof(struct sip_notify)); 12740 if (p->notify) { 12741 p->notify->content = ast_str_create(128); 12742 } 12743 return p->notify ? 1 : 0; 12744 }
| static int sip_offer_timer_expire | ( | const void * | data | ) | [static] |
Definition at line 1692 of file chan_sip.c.
References ast_cc_failed(), ast_cc_agent::core_id, ast_cc_agent::device_name, and ast_cc_agent::private_data.
Referenced by sip_cc_agent_start_offer_timer().
01693 { 01694 struct ast_cc_agent *agent = (struct ast_cc_agent *) data; 01695 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01696 01697 agent_pvt->offer_timer_id = -1; 01698 01699 return ast_cc_failed(agent->core_id, "SIP agent %s's offer timer expired", agent->device_name); 01700 }
| static int sip_park | ( | struct ast_channel * | chan1, | |
| struct ast_channel * | chan2, | |||
| struct sip_request * | req, | |||
| int | seqno, | |||
| char * | parkexten | |||
| ) | [static] |
Park a call using the subsystem in res_features.c This is executed in a separate thread.
Definition at line 20410 of file chan_sip.c.
References ast_channel::accountcode, ast_channel::amaflags, ast_calloc, AST_CAUSE_SWITCH_CONGESTION, ast_channel_alloc, ast_channel_masquerade(), ast_channel_trylock, ast_channel_unlock, ast_copy_string(), ast_debug, ast_do_masquerade(), ast_free, ast_hangup(), ast_log(), ast_pthread_create_detached_background, AST_STATE_DOWN, ast_string_field_set, ast_strlen_zero(), ast_channel::context, copy_request(), deinit_req(), ast_channel::exten, ast_channel::hangupcause, ast_channel::linkedid, LOG_WARNING, ast_channel::name, parkinglot, ast_channel::parkinglot, ast_channel::priority, ast_channel::readformat, sip_park_thread(), sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, and ast_channel::writeformat.
Referenced by handle_request_refer().
20411 { 20412 struct sip_dual *d; 20413 struct ast_channel *transferee, *transferer; 20414 /* Chan2m: The transferer, chan1m: The transferee */ 20415 pthread_t th; 20416 20417 transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->linkedid, chan1->amaflags, "Parking/%s", chan1->name); 20418 transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->linkedid, chan2->amaflags, "SIPPeer/%s", chan2->name); 20419 if ((!transferer) || (!transferee)) { 20420 if (transferee) { 20421 transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 20422 ast_hangup(transferee); 20423 } 20424 if (transferer) { 20425 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 20426 ast_hangup(transferer); 20427 } 20428 return -1; 20429 } 20430 20431 /* Make formats okay */ 20432 transferee->readformat = chan1->readformat; 20433 transferee->writeformat = chan1->writeformat; 20434 20435 /* Prepare for taking over the channel */ 20436 ast_channel_masquerade(transferee, chan1); 20437 20438 /* Setup the extensions and such */ 20439 ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context)); 20440 ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten)); 20441 transferee->priority = chan1->priority; 20442 20443 /* We make a clone of the peer channel too, so we can play 20444 back the announcement */ 20445 20446 /* Make formats okay */ 20447 transferer->readformat = chan2->readformat; 20448 transferer->writeformat = chan2->writeformat; 20449 if (!ast_strlen_zero(chan2->parkinglot)) 20450 ast_string_field_set(transferer, parkinglot, chan2->parkinglot); 20451 20452 /* Prepare for taking over the channel. Go ahead and grab this channel 20453 * lock here to avoid a deadlock with callbacks into the channel driver 20454 * that hold the channel lock and want the pvt lock. */ 20455 while (ast_channel_trylock(chan2)) { 20456 struct sip_pvt *pvt = chan2->tech_pvt; 20457 sip_pvt_unlock(pvt); 20458 usleep(1); 20459 sip_pvt_lock(pvt); 20460 } 20461 ast_channel_masquerade(transferer, chan2); 20462 ast_channel_unlock(chan2); 20463 20464 /* Setup the extensions and such */ 20465 ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context)); 20466 ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten)); 20467 transferer->priority = chan2->priority; 20468 20469 if (ast_do_masquerade(transferer)) { 20470 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 20471 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 20472 ast_hangup(transferer); 20473 return -1; 20474 } 20475 if (!transferer || !transferee) { 20476 if (!transferer) { 20477 ast_debug(1, "No transferer channel, giving up parking\n"); 20478 } 20479 if (!transferee) { 20480 ast_debug(1, "No transferee channel, giving up parking\n"); 20481 } 20482 return -1; 20483 } 20484 if (!(d = ast_calloc(1, sizeof(*d)))) { 20485 return -1; 20486 } 20487 20488 /* Save original request for followup */ 20489 copy_request(&d->req, req); 20490 d->chan1 = transferee; /* Transferee */ 20491 d->chan2 = transferer; /* Transferer */ 20492 d->seqno = seqno; 20493 d->parkexten = parkexten; 20494 if (ast_pthread_create_detached_background(&th, NULL, sip_park_thread, d) < 0) { 20495 /* Could not start thread */ 20496 deinit_req(&d->req); 20497 ast_free(d); /* We don't need it anymore. If thread is created, d will be free'd 20498 by sip_park_thread() */ 20499 return -1; 20500 } 20501 return 0; 20502 }
| static void * sip_park_thread | ( | void * | stuff | ) | [static] |
Park SIP call support function Starts in a new thread, then parks the call XXX Should we add a wait period after streaming audio and before hangup?? Sometimes the audio can't be heard before hangup.
Definition at line 20345 of file chan_sip.c.
References append_history, AST_CAUSE_NORMAL_CLEARING, ast_debug, ast_do_masquerade(), ast_free, ast_hangup(), ast_log(), ast_park_call(), copy_request(), deinit_req(), ext, ast_channel::hangupcause, LOG_ERROR, LOG_WARNING, ast_channel::name, ast_channel::tech_pvt, transmit_message_with_text(), transmit_notify_with_sipfrag(), transmit_response(), and TRUE.
Referenced by sip_park().
20346 { 20347 struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */ 20348 struct sip_dual *d; 20349 struct sip_request req = {0,}; 20350 int ext; 20351 int res; 20352 20353 d = stuff; 20354 transferee = d->chan1; 20355 transferer = d->chan2; 20356 copy_request(&req, &d->req); 20357 20358 if (!transferee || !transferer) { 20359 ast_log(LOG_ERROR, "Missing channels for parking! Transferer %s Transferee %s\n", transferer ? "<available>" : "<missing>", transferee ? "<available>" : "<missing>" ); 20360 deinit_req(&d->req); 20361 ast_free(d); 20362 return NULL; 20363 } 20364 ast_debug(4, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name); 20365 20366 if (ast_do_masquerade(transferee)) { 20367 ast_log(LOG_WARNING, "Masquerade failed.\n"); 20368 transmit_response(transferer->tech_pvt, "503 Internal error", &req); 20369 deinit_req(&d->req); 20370 ast_free(d); 20371 return NULL; 20372 } 20373 20374 res = ast_park_call(transferee, transferer, 0, d->parkexten, &ext); 20375 20376 20377 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE 20378 if (!res) { 20379 transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n"); 20380 } else { 20381 /* Then tell the transferer what happened */ 20382 sprintf(buf, "Call parked on extension '%d'", ext); 20383 transmit_message_with_text(transferer->tech_pvt, buf); 20384 } 20385 #endif 20386 20387 /* Any way back to the current call??? */ 20388 /* Transmit response to the REFER request */ 20389 if (!res) { 20390 /* Transfer succeeded */ 20391 append_history(transferer->tech_pvt, "SIPpark", "Parked call on %d", ext); 20392 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE); 20393 transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING; 20394 ast_hangup(transferer); /* This will cause a BYE */ 20395 ast_debug(1, "SIP Call parked on extension '%d'\n", ext); 20396 } else { 20397 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE); 20398 append_history(transferer->tech_pvt, "SIPpark", "Parking failed\n"); 20399 ast_debug(1, "SIP Call parked failed \n"); 20400 /* Do not hangup call */ 20401 } 20402 deinit_req(&d->req); 20403 ast_free(d); 20404 return NULL; 20405 }
| 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 13777 of file chan_sip.c.
References ast_atomic_fetchadd_int(), AST_DEVICE_UNKNOWN, and ast_devstate_changed().
Referenced by change_hold_state(), and update_call_counter().
13778 { 13779 if (!p->relatedpeer) { 13780 return; 13781 } 13782 13783 /* If they put someone on hold, increment the value... otherwise decrement it */ 13784 ast_atomic_fetchadd_int(&p->relatedpeer->onHold, (hold ? +1 : -1)); 13785 13786 /* Request device state update */ 13787 ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", p->relatedpeer->name); 13788 13789 return; 13790 }
| 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.
| req | The SIP request to check | |
| [out] | pidf_doc | The validated PIDF doc. |
| FALSE | The XML was malformed or the basic PIDF structure was marred | |
| TRUE | The PIDF document is of a valid format |
Definition at line 22980 of file chan_sip.c.
References ast_log(), ast_strlen_zero(), ast_xml_close(), ast_xml_read_memory(), FALSE, get_header(), get_pidf_body(), LOG_WARNING, pidf_validate_presence(), and TRUE.
Referenced by cc_esc_publish_handler().
22981 { 22982 struct ast_xml_doc *doc; 22983 int content_length; 22984 const char *content_length_str = get_header(req, "Content-Length"); 22985 const char *content_type = get_header(req, "Content-Type"); 22986 char pidf_body[SIPBUFSIZE]; 22987 int res; 22988 22989 if (ast_strlen_zero(content_type) || strcmp(content_type, "application/pidf+xml")) { 22990 ast_log(LOG_WARNING, "Content type is not PIDF\n"); 22991 return FALSE; 22992 } 22993 22994 if (ast_strlen_zero(content_length_str)) { 22995 ast_log(LOG_WARNING, "No content length. Can't determine bounds of PIDF document\n"); 22996 return FALSE; 22997 } 22998 22999 if (sscanf(content_length_str, "%30d", &content_length) != 1) { 23000 ast_log(LOG_WARNING, "Invalid content length provided\n"); 23001 return FALSE; 23002 } 23003 23004 if (content_length > sizeof(pidf_body)) { 23005 ast_log(LOG_WARNING, "Content length of PIDF document truncated to %d bytes\n", (int) sizeof(pidf_body)); 23006 content_length = sizeof(pidf_body); 23007 } 23008 23009 get_pidf_body(req, pidf_body, content_length); 23010 23011 if (!(doc = ast_xml_read_memory(pidf_body, content_length))) { 23012 ast_log(LOG_WARNING, "Unable to open XML PIDF document. Is it malformed?\n"); 23013 return FALSE; 23014 } 23015 23016 res = pidf_validate_presence(doc); 23017 if (res == TRUE) { 23018 *pidf_doc = doc; 23019 } else { 23020 ast_xml_close(doc); 23021 } 23022 return res; 23023 }
| static void sip_poke_all_peers | ( | void | ) | [static] |
Send a poke to all known peers.
Definition at line 28241 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, ref_peer(), sip_poke_peer_s(), speerobjs, and unref_peer().
Referenced by load_module(), and sip_do_reload().
28242 { 28243 int ms = 0, num = 0; 28244 struct ao2_iterator i; 28245 struct sip_peer *peer; 28246 28247 if (!speerobjs) { /* No peers, just give up */ 28248 return; 28249 } 28250 28251 i = ao2_iterator_init(peers, 0); 28252 while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) { 28253 ao2_lock(peer); 28254 if (num == global_qualify_peers) { 28255 ms += global_qualify_gap; 28256 num = 0; 28257 } else { 28258 num++; 28259 } 28260 AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, ms, sip_poke_peer_s, peer, 28261 unref_peer(_data, "removing poke peer ref"), 28262 unref_peer(peer, "removing poke peer ref"), 28263 ref_peer(peer, "adding poke peer ref")); 28264 ao2_unlock(peer); 28265 unref_peer(peer, "toss iterator peer ptr"); 28266 } 28267 ao2_iterator_destroy(&i); 28268 }
| static int sip_poke_noanswer | ( | const void * | data | ) | [static] |
React to lack of answer to Qualify poke.
Definition at line 25066 of file chan_sip.c.
References ast_check_realtime(), AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_log(), AST_SCHED_REPLACE_UNREF, ast_update_realtime(), DEFAULT_FREQ_NOTOK, dialog_unlink_all(), EVENT_FLAG_SYSTEM, FALSE, LOG_NOTICE, manager_event, ref_peer(), register_peer_exten(), SENTINEL, sip_cfg, sip_poke_peer_s(), TRUE, and unref_peer().
Referenced by sip_poke_peer(), and sip_show_sched().
25067 { 25068 struct sip_peer *peer = (struct sip_peer *)data; 25069 25070 peer->pokeexpire = -1; 25071 25072 if (peer->lastms > -1) { 25073 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms); 25074 if (sip_cfg.peer_rtupdate) { 25075 ast_update_realtime(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", "name", peer->name, "lastms", "-1", SENTINEL); 25076 } 25077 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1); 25078 if (sip_cfg.regextenonqualify) { 25079 register_peer_exten(peer, FALSE); 25080 } 25081 } 25082 25083 if (peer->call) { 25084 dialog_unlink_all(peer->call, TRUE, TRUE); 25085 peer->call = dialog_unref(peer->call, "unref dialog peer->call"); 25086 /* peer->call = sip_destroy(peer->call);*/ 25087 } 25088 25089 /* Don't send a devstate change if nothing changed. */ 25090 if (peer->lastms > -1) { 25091 peer->lastms = -1; 25092 ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name); 25093 } 25094 25095 /* Try again quickly */ 25096 AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, 25097 DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer, 25098 unref_peer(_data, "removing poke peer ref"), 25099 unref_peer(peer, "removing poke peer ref"), 25100 ref_peer(peer, "adding poke peer ref")); 25101 25102 /* Release the ref held by the running scheduler entry */ 25103 unref_peer(peer, "release peer poke noanswer ref"); 25104 25105 return 0; 25106 }
| static int sip_poke_peer | ( | struct sip_peer * | peer, | |
| int | force | |||
| ) | [static] |
Check availability of peer, also keep NAT open.
Definition at line 25113 of file chan_sip.c.
References ao2_t_link, ao2_t_unlink, 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(), ast_string_field_set, ast_strlen_zero(), ast_tvnow(), build_callid_pvt(), build_via(), copy_socket_data(), dialog_unlink_all(), dialogs, LOG_NOTICE, ref_peer(), sip_alloc(), sip_poke_noanswer(), transmit_invite(), TRUE, and unref_peer().
Referenced by _sip_qualify_peer(), build_peer(), parse_register_contact(), reg_source_db(), and sip_poke_peer_s().
25114 { 25115 struct sip_pvt *p; 25116 int xmitres = 0; 25117 25118 if ((!peer->maxms && !force) || ast_sockaddr_isnull(&peer->addr)) { 25119 /* IF we have no IP, or this isn't to be monitored, return 25120 immediately after clearing things out */ 25121 AST_SCHED_DEL_UNREF(sched, peer->pokeexpire, 25122 unref_peer(peer, "removing poke peer ref")); 25123 25124 peer->lastms = 0; 25125 if (peer->call) { 25126 peer->call = dialog_unref(peer->call, "unref dialog peer->call"); 25127 } 25128 return 0; 25129 } 25130 if (peer->call) { 25131 if (sipdebug) { 25132 ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n"); 25133 } 25134 dialog_unlink_all(peer->call, TRUE, TRUE); 25135 peer->call = dialog_unref(peer->call, "unref dialog peer->call"); 25136 /* peer->call = sip_destroy(peer->call); */ 25137 } 25138 if (!(p = sip_alloc(NULL, NULL, 0, SIP_OPTIONS, NULL))) { 25139 return -1; 25140 } 25141 peer->call = dialog_ref(p, "copy sip alloc from p to peer->call"); 25142 25143 p->sa = peer->addr; 25144 p->recv = peer->addr; 25145 copy_socket_data(&p->socket, &peer->socket); 25146 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 25147 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 25148 ast_copy_flags(&p->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY); 25149 25150 /* Send OPTIONs to peer's fullcontact */ 25151 if (!ast_strlen_zero(peer->fullcontact)) 25152 ast_string_field_set(p, fullcontact, peer->fullcontact); 25153 25154 if (!ast_strlen_zero(peer->tohost)) 25155 ast_string_field_set(p, tohost, peer->tohost); 25156 else 25157 ast_string_field_set(p, tohost, ast_sockaddr_stringify_host(&peer->addr)); 25158 25159 /* Recalculate our side, and recalculate Call ID */ 25160 ast_sip_ouraddrfor(&p->sa, &p->ourip, p); 25161 build_via(p); 25162 ao2_t_unlink(dialogs, p, "About to change the callid -- remove the old name"); 25163 build_callid_pvt(p); 25164 ao2_t_link(dialogs, p, "Linking in under new name"); 25165 25166 AST_SCHED_DEL_UNREF(sched, peer->pokeexpire, 25167 unref_peer(peer, "removing poke peer ref")); 25168 25169 if (p->relatedpeer) 25170 p->relatedpeer = unref_peer(p->relatedpeer,"unsetting the relatedpeer field in the dialog, before it is set to something else."); 25171 p->relatedpeer = ref_peer(peer, "setting the relatedpeer field in the dialog"); 25172 ast_set_flag(&p->flags[0], SIP_OUTGOING); 25173 #ifdef VOCAL_DATA_HACK 25174 ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username)); 25175 xmitres = transmit_invite(p, SIP_INVITE, 0, 2, NULL); /* sinks the p refcount */ 25176 #else 25177 xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2, NULL); /* sinks the p refcount */ 25178 #endif 25179 peer->ps = ast_tvnow(); 25180 if (xmitres == XMIT_ERROR) { 25181 sip_poke_noanswer(peer); /* Immediately unreachable, network problems */ 25182 } else if (!force) { 25183 AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, peer->maxms * 2, sip_poke_noanswer, peer, 25184 unref_peer(_data, "removing poke peer ref"), 25185 unref_peer(peer, "removing poke peer ref"), 25186 ref_peer(peer, "adding poke peer ref")); 25187 } 25188 dialog_unref(p, "unref dialog at end of sip_poke_peer, obtained from sip_alloc, just before it goes out of scope"); 25189 return 0; 25190 }
| 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 13043 of file chan_sip.c.
References ao2_find, OBJ_POINTER, sip_poke_peer(), and unref_peer().
Referenced by handle_response_peerpoke(), reg_source_db(), sip_poke_all_peers(), sip_poke_noanswer(), and sip_show_sched().
13044 { 13045 struct sip_peer *peer = (struct sip_peer *)data; 13046 struct sip_peer *foundpeer; 13047 13048 peer->pokeexpire = -1; 13049 13050 foundpeer = ao2_find(peers, peer, OBJ_POINTER); 13051 if (!foundpeer) { 13052 unref_peer(peer, "removing poke peer ref"); 13053 return 0; 13054 } else if (foundpeer->name != peer->name) { 13055 unref_peer(foundpeer, "removing above peer ref"); 13056 unref_peer(peer, "removing poke peer ref"); 13057 return 0; 13058 } 13059 13060 unref_peer(foundpeer, "removing above peer ref"); 13061 sip_poke_peer(peer, 0); 13062 unref_peer(peer, "removing poke peer ref"); 13063 13064 return 0; 13065 }
| static int sip_prepare_socket | ( | struct sip_pvt * | p | ) | [static] |
Definition at line 24380 of file chan_sip.c.
References ao2_alloc, ao2_ref, ao2_t_ref, ao2_t_unlink, ast_calloc, ast_copy_string(), ast_debug, ast_pthread_create_background, ast_sockaddr_copy(), ast_strdup, ast_strlen_zero(), ast_tcptls_client_create(), ast_tls_config::cafile, ast_tls_config::capath, ast_tls_config::certfile, ast_tls_config::cipher, default_tls_cfg, ast_tcptls_session_instance::fd, name, ast_tls_config::pvtfile, sip_real_dst(), sip_tcp_locate(), sip_tcp_worker_fn(), sip_tcptls_client_args_destructor(), sip_threadinfo_create(), sipsock, and threadt.
Referenced by __sip_xmit().
24381 { 24382 struct sip_socket *s = &p->socket; 24383 static const char name[] = "SIP socket"; 24384 struct sip_threadinfo *th = NULL; 24385 struct ast_tcptls_session_instance *tcptls_session; 24386 struct ast_tcptls_session_args *ca; 24387 struct ast_sockaddr sa_tmp; 24388 24389 /* check to see if a socket is already active */ 24390 if ((s->fd != -1) && (s->type == SIP_TRANSPORT_UDP)) { 24391 return s->fd; 24392 } 24393 if ((s->type & (SIP_TRANSPORT_TCP | SIP_TRANSPORT_TLS)) && 24394 (s->tcptls_session) && 24395 (s->tcptls_session->fd != -1)) { 24396 return s->tcptls_session->fd; 24397 } 24398 24399 /*! \todo Check this... This might be wrong, depending on the proxy configuration 24400 If proxy is in "force" mode its correct. 24401 */ 24402 if (p->outboundproxy && p->outboundproxy->transport) { 24403 s->type = p->outboundproxy->transport; 24404 } 24405 24406 if (s->type == SIP_TRANSPORT_UDP) { 24407 s->fd = sipsock; 24408 return s->fd; 24409 } 24410 24411 /* At this point we are dealing with a TCP/TLS connection 24412 * 1. We need to check to see if a connectin thread exists 24413 * for this address, if so use that. 24414 * 2. If a thread does not exist for this address, but the tcptls_session 24415 * exists on the socket, the connection was closed. 24416 * 3. If no tcptls_session thread exists for the address, and no tcptls_session 24417 * already exists on the socket, create a new one and launch a new thread. 24418 */ 24419 24420 /* 1. check for existing threads */ 24421 ast_sockaddr_copy(&sa_tmp, sip_real_dst(p)); 24422 if ((tcptls_session = sip_tcp_locate(&sa_tmp))) { 24423 s->fd = tcptls_session->fd; 24424 if (s->tcptls_session) { 24425 ao2_ref(s->tcptls_session, -1); 24426 s->tcptls_session = NULL; 24427 } 24428 s->tcptls_session = tcptls_session; 24429 return s->fd; 24430 /* 2. Thread not found, if tcptls_session already exists, it once had a thread and is now terminated */ 24431 } else if (s->tcptls_session) { 24432 return s->fd; /* XXX whether reconnection is ever necessary here needs to be investigated further */ 24433 } 24434 24435 /* 3. Create a new TCP/TLS client connection */ 24436 /* create new session arguments for the client connection */ 24437 if (!(ca = ao2_alloc(sizeof(*ca), sip_tcptls_client_args_destructor)) || 24438 !(ca->name = ast_strdup(name))) { 24439 goto create_tcptls_session_fail; 24440 } 24441 ca->accept_fd = -1; 24442 ast_sockaddr_copy(&ca->remote_address,sip_real_dst(p)); 24443 /* if type is TLS, we need to create a tls cfg for this session arg */ 24444 if (s->type == SIP_TRANSPORT_TLS) { 24445 if (!(ca->tls_cfg = ast_calloc(1, sizeof(*ca->tls_cfg)))) { 24446 goto create_tcptls_session_fail; 24447 } 24448 memcpy(ca->tls_cfg, &default_tls_cfg, sizeof(*ca->tls_cfg)); 24449 24450 if (!(ca->tls_cfg->certfile = ast_strdup(default_tls_cfg.certfile)) || 24451 !(ca->tls_cfg->pvtfile = ast_strdup(default_tls_cfg.pvtfile)) || 24452 !(ca->tls_cfg->cipher = ast_strdup(default_tls_cfg.cipher)) || 24453 !(ca->tls_cfg->cafile = ast_strdup(default_tls_cfg.cafile)) || 24454 !(ca->tls_cfg->capath = ast_strdup(default_tls_cfg.capath))) { 24455 24456 goto create_tcptls_session_fail; 24457 } 24458 24459 /* this host is used as the common name in ssl/tls */ 24460 if (!ast_strlen_zero(p->tohost)) { 24461 ast_copy_string(ca->hostname, p->tohost, sizeof(ca->hostname)); 24462 } 24463 } 24464 24465 /* Create a client connection for address, this does not start the connection, just sets it up. */ 24466 if (!(s->tcptls_session = ast_tcptls_client_create(ca))) { 24467 goto create_tcptls_session_fail; 24468 } 24469 24470 s->fd = s->tcptls_session->fd; 24471 24472 /* client connections need to have the sip_threadinfo object created before 24473 * the thread is detached. This ensures the alert_pipe is up before it will 24474 * be used. Note that this function links the new threadinfo object into the 24475 * threadt container. */ 24476 if (!(th = sip_threadinfo_create(s->tcptls_session, s->type))) { 24477 goto create_tcptls_session_fail; 24478 } 24479 24480 /* Give the new thread a reference to the tcptls_session */ 24481 ao2_ref(s->tcptls_session, +1); 24482 24483 if (ast_pthread_create_background(&ca->master, NULL, sip_tcp_worker_fn, s->tcptls_session)) { 24484 ast_debug(1, "Unable to launch '%s'.", ca->name); 24485 ao2_ref(s->tcptls_session, -1); /* take away the thread ref we just gave it */ 24486 goto create_tcptls_session_fail; 24487 } 24488 24489 return s->fd; 24490 24491 create_tcptls_session_fail: 24492 if (ca) { 24493 ao2_t_ref(ca, -1, "failed to create client, getting rid of client tcptls_session arguments"); 24494 } 24495 if (s->tcptls_session) { 24496 close(tcptls_session->fd); 24497 s->fd = tcptls_session->fd = -1; 24498 ao2_ref(s->tcptls_session, -1); 24499 s->tcptls_session = NULL; 24500 } 24501 if (th) { 24502 ao2_t_unlink(threadt, th, "Removing tcptls thread info object, thread failed to open"); 24503 } 24504 24505 return -1; 24506 }
| static char * sip_prune_realtime | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Remove temporary realtime objects from memory (CLI).
Definition at line 16238 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_find, ao2_t_iterator_next, ao2_t_link, ao2_t_unlink, ao2_unlock, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_cli_complete(), ast_copy_string(), ast_sockaddr_isnull(), ast_test_flag, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sip_peer(), FALSE, ast_cli_args::fd, ast_cli_args::n, name, OBJ_POINTER, OBJ_UNLINK, peers_by_ip, ast_cli_args::pos, TRUE, unlink_marked_peers_from_tables(), unref_peer(), ast_cli_entry::usage, and ast_cli_args::word.
16239 { 16240 struct sip_peer *peer, *pi; 16241 int prunepeer = FALSE; 16242 int multi = FALSE; 16243 const char *name = NULL; 16244 regex_t regexbuf; 16245 struct ao2_iterator i; 16246 static const char * const choices[] = { "all", "like", NULL }; 16247 char *cmplt; 16248 16249 if (cmd == CLI_INIT) { 16250 e->command = "sip prune realtime [peer|all]"; 16251 e->usage = 16252 "Usage: sip prune realtime [peer [<name>|all|like <pattern>]|all]\n" 16253 " Prunes object(s) from the cache.\n" 16254 " Optional regular expression pattern is used to filter the objects.\n"; 16255 return NULL; 16256 } else if (cmd == CLI_GENERATE) { 16257 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer")) { 16258 cmplt = ast_cli_complete(a->word, choices, a->n); 16259 if (!cmplt) 16260 cmplt = complete_sip_peer(a->word, a->n - sizeof(choices), SIP_PAGE2_RTCACHEFRIENDS); 16261 return cmplt; 16262 } 16263 if (a->pos == 5 && !strcasecmp(a->argv[4], "like")) 16264 return complete_sip_peer(a->word, a->n, SIP_PAGE2_RTCACHEFRIENDS); 16265 return NULL; 16266 } 16267 switch (a->argc) { 16268 case 4: 16269 name = a->argv[3]; 16270 /* we accept a name in position 3, but keywords are not good. */ 16271 if (!strcasecmp(name, "peer") || !strcasecmp(name, "like")) 16272 return CLI_SHOWUSAGE; 16273 prunepeer = TRUE; 16274 if (!strcasecmp(name, "all")) { 16275 multi = TRUE; 16276 name = NULL; 16277 } 16278 /* else a single name, already set */ 16279 break; 16280 case 5: 16281 /* sip prune realtime {peer|like} name */ 16282 name = a->argv[4]; 16283 if (!strcasecmp(a->argv[3], "peer")) 16284 prunepeer = TRUE; 16285 else if (!strcasecmp(a->argv[3], "like")) { 16286 prunepeer = TRUE; 16287 multi = TRUE; 16288 } else 16289 return CLI_SHOWUSAGE; 16290 if (!strcasecmp(name, "like")) 16291 return CLI_SHOWUSAGE; 16292 if (!multi && !strcasecmp(name, "all")) { 16293 multi = TRUE; 16294 name = NULL; 16295 } 16296 break; 16297 case 6: 16298 name = a->argv[5]; 16299 multi = TRUE; 16300 /* sip prune realtime {peer} like name */ 16301 if (strcasecmp(a->argv[4], "like")) 16302 return CLI_SHOWUSAGE; 16303 if (!strcasecmp(a->argv[3], "peer")) { 16304 prunepeer = TRUE; 16305 } else 16306 return CLI_SHOWUSAGE; 16307 break; 16308 default: 16309 return CLI_SHOWUSAGE; 16310 } 16311 16312 if (multi && name) { 16313 if (regcomp(®exbuf, name, REG_EXTENDED | REG_NOSUB)) 16314 return CLI_SHOWUSAGE; 16315 } 16316 16317 if (multi) { 16318 if (prunepeer) { 16319 int pruned = 0; 16320 16321 i = ao2_iterator_init(peers, 0); 16322 while ((pi = ao2_t_iterator_next(&i, "iterate thru peers table"))) { 16323 ao2_lock(pi); 16324 if (name && regexec(®exbuf, pi->name, 0, NULL, 0)) { 16325 unref_peer(pi, "toss iterator peer ptr before continue"); 16326 ao2_unlock(pi); 16327 continue; 16328 }; 16329 if (ast_test_flag(&pi->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 16330 pi->the_mark = 1; 16331 pruned++; 16332 } 16333 ao2_unlock(pi); 16334 unref_peer(pi, "toss iterator peer ptr"); 16335 } 16336 ao2_iterator_destroy(&i); 16337 if (pruned) { 16338 unlink_marked_peers_from_tables(); 16339 ast_cli(a->fd, "%d peers pruned.\n", pruned); 16340 } else 16341 ast_cli(a->fd, "No peers found to prune.\n"); 16342 } 16343 } else { 16344 if (prunepeer) { 16345 struct sip_peer tmp; 16346 ast_copy_string(tmp.name, name, sizeof(tmp.name)); 16347 if ((peer = ao2_t_find(peers, &tmp, OBJ_POINTER | OBJ_UNLINK, "finding to unlink from peers"))) { 16348 if (!ast_sockaddr_isnull(&peer->addr)) { 16349 ao2_t_unlink(peers_by_ip, peer, "unlinking peer from peers_by_ip also"); 16350 } 16351 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 16352 ast_cli(a->fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name); 16353 /* put it back! */ 16354 ao2_t_link(peers, peer, "link peer into peer table"); 16355 if (!ast_sockaddr_isnull(&peer->addr)) { 16356 ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table"); 16357 } 16358 } else 16359 ast_cli(a->fd, "Peer '%s' pruned.\n", name); 16360 unref_peer(peer, "sip_prune_realtime: unref_peer: tossing temp peer ptr"); 16361 } else 16362 ast_cli(a->fd, "Peer '%s' not found.\n", name); 16363 } 16364 } 16365 16366 return CLI_SUCCESS; 16367 }
| 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 16516 of file chan_sip.c.
References _sip_qualify_peer(), ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, complete_sip_show_peer(), ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.
16517 { 16518 switch (cmd) { 16519 case CLI_INIT: 16520 e->command = "sip qualify peer"; 16521 e->usage = 16522 "Usage: sip qualify peer <name> [load]\n" 16523 " Requests a response from one SIP peer and the current status.\n" 16524 " Option \"load\" forces lookup of peer in realtime storage.\n"; 16525 return NULL; 16526 case CLI_GENERATE: 16527 return complete_sip_show_peer(a->line, a->word, a->pos, a->n); 16528 } 16529 return _sip_qualify_peer(0, a->fd, NULL, NULL, a->argc, (const char **) a->argv); 16530 }
| 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 4210 of file chan_sip.c.
References ast_copy_string(), ast_debug, ast_log(), AST_OPTION_DEVICE_NAME, AST_OPTION_DIGIT_DETECT, AST_OPTION_SECURE_MEDIA, AST_OPTION_SECURE_SIGNALING, AST_OPTION_T38_STATE, ast_test_flag, LOG_ERROR, ast_channel::name, sip_pvt_lock, sip_pvt_unlock, T38_STATE_NEGOTIATED, T38_STATE_NEGOTIATING, T38_STATE_UNAVAILABLE, T38_STATE_UNKNOWN, and ast_channel::tech_pvt.
04211 { 04212 int res = -1; 04213 enum ast_t38_state state = T38_STATE_UNAVAILABLE; 04214 struct sip_pvt *p = (struct sip_pvt *) chan->tech_pvt; 04215 char *cp; 04216 04217 switch (option) { 04218 case AST_OPTION_T38_STATE: 04219 /* Make sure we got an ast_t38_state enum passed in */ 04220 if (*datalen != sizeof(enum ast_t38_state)) { 04221 ast_log(LOG_ERROR, "Invalid datalen for AST_OPTION_T38_STATE option. Expected %d, got %d\n", (int)sizeof(enum ast_t38_state), *datalen); 04222 return -1; 04223 } 04224 04225 sip_pvt_lock(p); 04226 04227 /* 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 */ 04228 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) { 04229 switch (p->t38.state) { 04230 case T38_LOCAL_REINVITE: 04231 case T38_PEER_REINVITE: 04232 state = T38_STATE_NEGOTIATING; 04233 break; 04234 case T38_ENABLED: 04235 state = T38_STATE_NEGOTIATED; 04236 break; 04237 default: 04238 state = T38_STATE_UNKNOWN; 04239 } 04240 } 04241 04242 sip_pvt_unlock(p); 04243 04244 *((enum ast_t38_state *) data) = state; 04245 res = 0; 04246 04247 break; 04248 case AST_OPTION_DIGIT_DETECT: 04249 cp = (char *) data; 04250 *cp = p->dsp ? 1 : 0; 04251 ast_debug(1, "Reporting digit detection %sabled on %s\n", *cp ? "en" : "dis", chan->name); 04252 break; 04253 case AST_OPTION_SECURE_SIGNALING: 04254 *((unsigned int *) data) = p->req_secure_signaling; 04255 res = 0; 04256 break; 04257 case AST_OPTION_SECURE_MEDIA: 04258 *((unsigned int *) data) = ast_test_flag(&p->flags[1], SIP_PAGE2_USE_SRTP) ? 1 : 0; 04259 res = 0; 04260 break; 04261 case AST_OPTION_DEVICE_NAME: 04262 if (p && p->outgoing_call) { 04263 cp = (char *) data; 04264 ast_copy_string(cp, p->dialstring, *datalen); 04265 res = 0; 04266 } 04267 /* We purposely break with a return of -1 in the 04268 * implied else case here 04269 */ 04270 break; 04271 default: 04272 break; 04273 } 04274 04275 return res; 04276 }
| static struct ast_frame * sip_read | ( | struct ast_channel * | ast | ) | [static] |
Read SIP RTP from channel.
Definition at line 7122 of file chan_sip.c.
References ast_channel::_state, ast_async_goto(), ast_channel_lock, ast_channel_unlock, ast_exists_extension(), AST_FRAME_VOICE, ast_log(), ast_null_frame, AST_STATE_UP, ast_test_flag, ast_verbose, FALSE, ast_frame::frametype, LOG_NOTICE, pbx_builtin_setvar_helper(), S_COR, S_OR, sip_pvt_lock, sip_pvt_unlock, sip_rtp_read(), ast_channel::tech_pvt, and VERBOSE_PREFIX_2.
07123 { 07124 struct ast_frame *fr; 07125 struct sip_pvt *p = ast->tech_pvt; 07126 int faxdetected = FALSE; 07127 07128 sip_pvt_lock(p); 07129 fr = sip_rtp_read(ast, p, &faxdetected); 07130 p->lastrtprx = time(NULL); 07131 07132 /* If we detect a CNG tone and fax detection is enabled then send us off to the fax extension */ 07133 if (faxdetected && ast_test_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_CNG)) { 07134 ast_channel_lock(ast); 07135 if (strcmp(ast->exten, "fax")) { 07136 const char *target_context = S_OR(ast->macrocontext, ast->context); 07137 ast_channel_unlock(ast); 07138 if (ast_exists_extension(ast, target_context, "fax", 1, 07139 S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, NULL))) { 07140 ast_verbose(VERBOSE_PREFIX_2 "Redirecting '%s' to fax extension due to CNG detection\n", ast->name); 07141 pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten); 07142 if (ast_async_goto(ast, target_context, "fax", 1)) { 07143 ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context); 07144 } 07145 fr = &ast_null_frame; 07146 } else { 07147 ast_log(LOG_NOTICE, "FAX CNG detected but no fax extension\n"); 07148 } 07149 } else { 07150 ast_channel_unlock(ast); 07151 } 07152 } 07153 07154 /* Only allow audio through if they sent progress with SDP, or if the channel is actually answered */ 07155 if (fr && fr->frametype == AST_FRAME_VOICE && p->invitestate != INV_EARLY_MEDIA && ast->_state != AST_STATE_UP) { 07156 fr = &ast_null_frame; 07157 } 07158 07159 sip_pvt_unlock(p); 07160 07161 return fr; 07162 }
| static struct ast_sockaddr * sip_real_dst | ( | const struct sip_pvt * | p | ) | [static] |
The real destination address for a write.
Definition at line 3119 of file chan_sip.c.
References ast_test_flag.
Referenced by __sip_xmit(), check_via(), retrans_pkt(), send_response(), show_channels_cb(), sip_debug_test_pvt(), and sip_prepare_socket().
03120 { 03121 if (p->outboundproxy) { 03122 return &p->outboundproxy->ip; 03123 } 03124 03125 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; 03126 }
| static const char* sip_reason_code_to_str | ( | enum AST_REDIRECTING_REASON | code | ) | [static] |
Definition at line 2257 of file chan_sip.c.
References ARRAY_LEN, sip_reason_table, and sip_reasons::text.
Referenced by add_diversion_header().
02258 { 02259 if (code >= 0 && code < ARRAY_LEN(sip_reason_table)) { 02260 return sip_reason_table[code].text; 02261 } 02262 02263 return "unknown"; 02264 }
| static enum AST_REDIRECTING_REASON sip_reason_str_to_code | ( | const char * | text | ) | [static] |
Definition at line 2242 of file chan_sip.c.
References ARRAY_LEN, AST_REDIRECTING_REASON_UNKNOWN, sip_reasons::code, and sip_reason_table.
Referenced by get_rdnis().
02243 { 02244 enum AST_REDIRECTING_REASON ast = AST_REDIRECTING_REASON_UNKNOWN; 02245 int i; 02246 02247 for (i = 0; i < ARRAY_LEN(sip_reason_table); ++i) { 02248 if (!strcasecmp(text, sip_reason_table[i].text)) { 02249 ast = sip_reason_table[i].code; 02250 break; 02251 } 02252 } 02253 02254 return ast; 02255 }
| static int sip_refer_allocate | ( | struct sip_pvt * | p | ) | [static] |
Allocate SIP refer structure.
Definition at line 12730 of file chan_sip.c.
References ast_calloc.
Referenced by get_also_info(), handle_request_invite(), handle_request_refer(), and transmit_refer().
12731 { 12732 p->refer = ast_calloc(1, sizeof(struct sip_refer)); 12733 return p->refer ? 1 : 0; 12734 }
| static int sip_reg_timeout | ( | const void * | data | ) | [static] |
Registration timeout, register again Registered as a timeout handler during transmit_register(), to retransmit the packet if a reply does not come back. This is called by the scheduler so the event is not pending anymore when we are called.
Definition at line 12430 of file chan_sip.c.
References __sip_pretend_ack(), ast_dnsmgr_refresh(), ast_log(), EVENT_FLAG_SYSTEM, global_regattempts_max, LOG_NOTICE, manager_event, pvt_set_needdestroy(), REG_STATE_UNREGISTERED, registry_unref(), regstate2str(), sip_pvt_lock, sip_pvt_unlock, and transmit_register().
Referenced by sip_show_sched(), and transmit_register().
12431 { 12432 12433 /* if we are here, our registration timed out, so we'll just do it over */ 12434 struct sip_registry *r = (struct sip_registry *)data; /* the ref count should have been bumped when the sched item was added */ 12435 struct sip_pvt *p; 12436 int res; 12437 12438 /* if we couldn't get a reference to the registry object, punt */ 12439 if (!r) { 12440 return 0; 12441 } 12442 12443 if (r->dnsmgr) { 12444 /* If the registration has timed out, maybe the IP changed. Force a refresh. */ 12445 ast_dnsmgr_refresh(r->dnsmgr); 12446 } 12447 12448 /* If the initial tranmission failed, we may not have an existing dialog, 12449 * so it is possible that r->call == NULL. 12450 * Otherwise destroy it, as we have a timeout so we don't want it. 12451 */ 12452 if (r->call) { 12453 /* Unlink us, destroy old call. Locking is not relevant here because all this happens 12454 in the single SIP manager thread. */ 12455 p = r->call; 12456 sip_pvt_lock(p); 12457 pvt_set_needdestroy(p, "registration timeout"); 12458 /* Pretend to ACK anything just in case */ 12459 __sip_pretend_ack(p); 12460 sip_pvt_unlock(p); 12461 12462 /* decouple the two objects */ 12463 /* p->registry == r, so r has 2 refs, and the unref won't take the object away */ 12464 if (p->registry) { 12465 p->registry = registry_unref(p->registry, "p->registry unreffed"); 12466 } 12467 r->call = dialog_unref(r->call, "unrefing r->call"); 12468 } 12469 /* If we have a limit, stop registration and give up */ 12470 r->timeout = -1; 12471 if (global_regattempts_max && r->regattempts >= global_regattempts_max) { 12472 /* Ok, enough is enough. Don't try any more */ 12473 /* We could add an external notification here... 12474 steal it from app_voicemail :-) */ 12475 ast_log(LOG_NOTICE, " -- Last Registration Attempt #%d failed, Giving up forever trying to register '%s@%s'\n", r->regattempts, r->username, r->hostname); 12476 r->regstate = REG_STATE_FAILED; 12477 } else { 12478 r->regstate = REG_STATE_UNREGISTERED; 12479 res = transmit_register(r, SIP_REGISTER, NULL, NULL); 12480 ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 12481 } 12482 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: SIP\r\nUsername: %s\r\nDomain: %s\r\nStatus: %s\r\n", r->username, r->hostname, regstate2str(r->regstate)); 12483 registry_unref(r, "unreffing registry_unref r"); 12484 return 0; 12485 }
| 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 7769 of file chan_sip.c.
References ast_atomic_fetchadd_int(), ast_calloc_with_stringfields, ast_log(), ASTOBJ_CONTAINER_LINK, ASTOBJ_INIT, default_expiry, LOG_ERROR, registry_unref(), regl, and regobjs.
Referenced by build_peer().
07770 { 07771 struct sip_registry *reg; 07772 07773 if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) { 07774 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n"); 07775 return -1; 07776 } 07777 07778 ast_atomic_fetchadd_int(®objs, 1); 07779 ASTOBJ_INIT(reg); 07780 07781 if (sip_parse_register_line(reg, default_expiry, value, lineno)) { 07782 registry_unref(reg, "failure to parse, unref the reg pointer"); 07783 return -1; 07784 } 07785 07786 /* set default expiry if necessary */ 07787 if (reg->refresh && !reg->expiry && !reg->configured_expiry) { 07788 reg->refresh = reg->expiry = reg->configured_expiry = default_expiry; 07789 } 07790 07791 /* Add the new registry entry to the list */ 07792 ASTOBJ_CONTAINER_LINK(®l, reg); 07793 07794 /* release the reference given by ASTOBJ_INIT. The container has another reference */ 07795 registry_unref(reg, "unref the reg pointer"); 07796 07797 return 0; 07798 }
| static void sip_register_tests | ( | void | ) | [static] |
SIP test registration.
Definition at line 28617 of file chan_sip.c.
Referenced by load_module().
28618 { 28619 sip_config_parser_register_tests(); 28620 sip_request_parser_register_tests(); 28621 sip_dialplan_function_register_tests(); 28622 }
| static void sip_registry_destroy | ( | struct sip_registry * | reg | ) | [static] |
Destroy registry object Objects created with the register= statement in static configuration.
Definition at line 5415 of file chan_sip.c.
References ast_atomic_fetchadd_int(), ast_debug, ast_dnsmgr_release(), ast_free, AST_SCHED_DEL, ast_string_field_free_memory, dialog_unlink_all(), registry_unref(), regobjs, and TRUE.
Referenced by registry_unref(), and unload_module().
05416 { 05417 /* Really delete */ 05418 ast_debug(3, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname); 05419 05420 if (reg->call) { 05421 /* Clear registry before destroying to ensure 05422 we don't get reentered trying to grab the registry lock */ 05423 reg->call->registry = registry_unref(reg->call->registry, "destroy reg->call->registry"); 05424 ast_debug(3, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname); 05425 dialog_unlink_all(reg->call, TRUE, TRUE); 05426 reg->call = dialog_unref(reg->call, "unref reg->call"); 05427 /* reg->call = sip_destroy(reg->call); */ 05428 } 05429 AST_SCHED_DEL(sched, reg->expire); 05430 AST_SCHED_DEL(sched, reg->timeout); 05431 05432 ast_string_field_free_memory(reg); 05433 ast_atomic_fetchadd_int(®objs, -1); 05434 ast_dnsmgr_release(reg->dnsmgr); 05435 ast_free(reg); 05436 }
| static int sip_reinvite_retry | ( | const void * | data | ) | [static] |
Reset the NEEDREINVITE flag after waiting when we get 491 on a Re-invite to avoid race conditions between asterisk servers. Called from the scheduler.
Definition at line 18901 of file chan_sip.c.
References ast_channel_trylock, ast_channel_unlock, ast_set_flag, check_pendings(), sip_pvt_lock, and sip_pvt_unlock.
Referenced by handle_response_invite(), and sip_show_sched().
18902 { 18903 struct sip_pvt *p = (struct sip_pvt *) data; 18904 struct ast_channel *owner; 18905 18906 sip_pvt_lock(p); /* called from schedule thread which requires a lock */ 18907 while ((owner = p->owner) && ast_channel_trylock(owner)) { 18908 sip_pvt_unlock(p); 18909 usleep(1); 18910 sip_pvt_lock(p); 18911 } 18912 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 18913 p->waitid = -1; 18914 check_pendings(p); 18915 sip_pvt_unlock(p); 18916 if (owner) { 18917 ast_channel_unlock(owner); 18918 } 18919 dialog_unref(p, "unref the dialog ptr from sip_reinvite_retry, because it held a dialog ptr"); 18920 return 0; 18921 }
| 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 28389 of file chan_sip.c.
References ast_mutex_lock, ast_mutex_unlock, ast_verbose, CHANNEL_CLI_RELOAD, CHANNEL_MODULE_RELOAD, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, restart_monitor(), sip_reload_lock, sip_reloading, sip_reloadreason, TRUE, and ast_cli_entry::usage.
Referenced by reload().
28390 { 28391 28392 switch (cmd) { 28393 case CLI_INIT: 28394 e->command = "sip reload"; 28395 e->usage = 28396 "Usage: sip reload\n" 28397 " Reloads SIP configuration from sip.conf\n"; 28398 return NULL; 28399 case CLI_GENERATE: 28400 return NULL; 28401 } 28402 28403 ast_mutex_lock(&sip_reload_lock); 28404 if (sip_reloading) { 28405 ast_verbose("Previous SIP reload not yet done\n"); 28406 } else { 28407 sip_reloading = TRUE; 28408 sip_reloadreason = (a && a->fd) ? CHANNEL_CLI_RELOAD : CHANNEL_MODULE_RELOAD; 28409 } 28410 ast_mutex_unlock(&sip_reload_lock); 28411 restart_monitor(); 28412 28413 return CLI_SUCCESS; 28414 }
| static int sip_removeheader | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Remove SIP headers added previously with SipAddHeader application.
Definition at line 28140 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_debug, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_strlen_zero(), ast_var_delete(), ast_var_name(), ast_var_value(), inbuf(), and ast_channel::varshead.
Referenced by load_module().
28141 { 28142 struct ast_var_t *newvariable; 28143 struct varshead *headp; 28144 int removeall = 0; 28145 char *inbuf = (char *) data; 28146 28147 if (ast_strlen_zero(inbuf)) { 28148 removeall = 1; 28149 } 28150 ast_channel_lock(chan); 28151 28152 headp=&chan->varshead; 28153 AST_LIST_TRAVERSE_SAFE_BEGIN (headp, newvariable, entries) { 28154 if (strncasecmp(ast_var_name(newvariable), "SIPADDHEADER", strlen("SIPADDHEADER")) == 0) { 28155 if (removeall || (!strncasecmp(ast_var_value(newvariable),inbuf,strlen(inbuf)))) { 28156 if (sipdebug) 28157 ast_debug(1,"removing SIP Header \"%s\" as %s\n", 28158 ast_var_value(newvariable), 28159 ast_var_name(newvariable)); 28160 AST_LIST_REMOVE_CURRENT(entries); 28161 ast_var_delete(newvariable); 28162 } 28163 } 28164 } 28165 AST_LIST_TRAVERSE_SAFE_END; 28166 28167 ast_channel_unlock(chan); 28168 return 0; 28169 }
| static struct ast_channel * sip_request_call | ( | const char * | type, | |
| format_t | format, | |||
| const struct ast_channel * | requestor, | |||
| void * | data, | |||
| int * | cause | |||
| ) | [static] |
PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here.
* SIP Dial string syntax * SIP/exten@host!dnid * or SIP/host/exten!dnid * or SIP/host!dnid *
Definition at line 25304 of file chan_sip.c.
References ao2_t_link, ao2_t_unlink, args, AST_APP_ARG, ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_CHANNEL_UNACCEPTABLE, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNREGISTERED, ast_copy_string(), ast_debug, AST_DECLARE_APP_ARGS, AST_FORMAT_AUDIO_MASK, ast_getformatname(), ast_getformatname_multiple(), ast_log(), AST_NONSTANDARD_APP_ARGS, ast_sip_ouraddrfor(), ast_sockaddr_port, ast_sockaddr_resolve_first(), ast_sockaddr_set_port, AST_STATE_DOWN, ast_string_field_set, ast_strlen_zero(), ast_update_use_count(), build_callid_pvt(), build_via(), create_addr(), dialog_unlink_all(), dialogs, EVENT_FLAG_SYSTEM, ext, exten, ast_channel::linkedid, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event, restart_monitor(), secret, set_socket_transport(), sip_alloc(), sip_cfg, sip_new(), sip_pvt_lock, sip_pvt_unlock, and TRUE.
25305 { 25306 struct sip_pvt *p; 25307 struct ast_channel *tmpc = NULL; 25308 char *ext = NULL, *host; 25309 char tmp[256]; 25310 char *dest = data; 25311 char *dnid; 25312 char *secret = NULL; 25313 char *md5secret = NULL; 25314 char *authname = NULL; 25315 char *trans = NULL; 25316 char dialstring[256]; 25317 char *remote_address; 25318 enum sip_transport transport = 0; 25319 struct ast_sockaddr remote_address_sa = { {0,} }; 25320 format_t oldformat = format; 25321 AST_DECLARE_APP_ARGS(args, 25322 AST_APP_ARG(peerorhost); 25323 AST_APP_ARG(exten); 25324 AST_APP_ARG(remote_address); 25325 ); 25326 25327 /* mask request with some set of allowed formats. 25328 * XXX this needs to be fixed. 25329 * The original code uses AST_FORMAT_AUDIO_MASK, but it is 25330 * unclear what to use here. We have global_capabilities, which is 25331 * configured from sip.conf, and sip_tech.capabilities, which is 25332 * hardwired to all audio formats. 25333 */ 25334 format &= AST_FORMAT_AUDIO_MASK; 25335 if (!format) { 25336 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format %s while capability is %s\n", ast_getformatname(oldformat), ast_getformatname(sip_cfg.capability)); 25337 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; /* Can't find codec to connect to host */ 25338 return NULL; 25339 } 25340 ast_debug(1, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat)); 25341 25342 if (ast_strlen_zero(dest)) { 25343 ast_log(LOG_ERROR, "Unable to create channel with empty destination.\n"); 25344 *cause = AST_CAUSE_CHANNEL_UNACCEPTABLE; 25345 return NULL; 25346 } 25347 25348 if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE, NULL))) { 25349 ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", dest); 25350 *cause = AST_CAUSE_SWITCH_CONGESTION; 25351 return NULL; 25352 } 25353 25354 p->outgoing_call = TRUE; 25355 25356 snprintf(dialstring, sizeof(dialstring), "%s/%s", type, dest); 25357 ast_string_field_set(p, dialstring, dialstring); 25358 25359 if (!(p->options = ast_calloc(1, sizeof(*p->options)))) { 25360 dialog_unlink_all(p, TRUE, TRUE); 25361 dialog_unref(p, "unref dialog p from mem fail"); 25362 /* sip_destroy(p); */ 25363 ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n"); 25364 *cause = AST_CAUSE_SWITCH_CONGESTION; 25365 return NULL; 25366 } 25367 25368 /* Save the destination, the SIP dial string */ 25369 ast_copy_string(tmp, dest, sizeof(tmp)); 25370 25371 /* Find DNID and take it away */ 25372 dnid = strchr(tmp, '!'); 25373 if (dnid != NULL) { 25374 *dnid++ = '\0'; 25375 ast_string_field_set(p, todnid, dnid); 25376 } 25377 25378 /* Divvy up the items separated by slashes */ 25379 AST_NONSTANDARD_APP_ARGS(args, tmp, '/'); 25380 25381 /* Find at sign - @ */ 25382 host = strchr(args.peerorhost, '@'); 25383 if (host) { 25384 *host++ = '\0'; 25385 ext = args.peerorhost; 25386 secret = strchr(ext, ':'); 25387 } 25388 if (secret) { 25389 *secret++ = '\0'; 25390 md5secret = strchr(secret, ':'); 25391 } 25392 if (md5secret) { 25393 *md5secret++ = '\0'; 25394 authname = strchr(md5secret, ':'); 25395 } 25396 if (authname) { 25397 *authname++ = '\0'; 25398 trans = strchr(authname, ':'); 25399 } 25400 if (trans) { 25401 *trans++ = '\0'; 25402 if (!strcasecmp(trans, "tcp")) 25403 transport = SIP_TRANSPORT_TCP; 25404 else if (!strcasecmp(trans, "tls")) 25405 transport = SIP_TRANSPORT_TLS; 25406 else { 25407 if (strcasecmp(trans, "udp")) 25408 ast_log(LOG_WARNING, "'%s' is not a valid transport option to Dial() for SIP calls, using udp by default.\n", trans); 25409 transport = SIP_TRANSPORT_UDP; 25410 } 25411 } else { /* use default */ 25412 transport = SIP_TRANSPORT_UDP; 25413 } 25414 25415 if (!host) { 25416 ext = args.exten; 25417 host = args.peerorhost; 25418 remote_address = args.remote_address; 25419 } else { 25420 remote_address = args.remote_address; 25421 if (!ast_strlen_zero(args.exten)) { 25422 ast_log(LOG_NOTICE, "Conflicting extension values given. Using '%s' and not '%s'\n", ext, args.exten); 25423 } 25424 } 25425 25426 if (!ast_strlen_zero(remote_address)) { 25427 if (ast_sockaddr_resolve_first(&remote_address_sa, remote_address, 0)) { 25428 ast_log(LOG_WARNING, "Unable to find IP address for host %s. We will not use this remote IP address\n", remote_address); 25429 } else { 25430 if (!ast_sockaddr_port(&remote_address_sa)) { 25431 ast_sockaddr_set_port(&remote_address_sa, 25432 transport & SIP_TRANSPORT_TLS ? 25433 STANDARD_TLS_PORT : 25434 STANDARD_SIP_PORT); 25435 } 25436 } 25437 } 25438 25439 set_socket_transport(&p->socket, transport); 25440 25441 /* We now have 25442 host = peer name, DNS host name or DNS domain (for SRV) 25443 ext = extension (user part of URI) 25444 dnid = destination of the call (applies to the To: header) 25445 */ 25446 if (create_addr(p, host, NULL, 1, &remote_address_sa)) { 25447 *cause = AST_CAUSE_UNREGISTERED; 25448 ast_debug(3, "Cant create SIP call - target device not registered\n"); 25449 dialog_unlink_all(p, TRUE, TRUE); 25450 dialog_unref(p, "unref dialog p UNREGISTERED"); 25451 /* sip_destroy(p); */ 25452 return NULL; 25453 } 25454 if (ast_strlen_zero(p->peername) && ext) 25455 ast_string_field_set(p, peername, ext); 25456 /* Recalculate our side, and recalculate Call ID */ 25457 ast_sip_ouraddrfor(&p->sa, &p->ourip, p); 25458 build_via(p); 25459 ao2_t_unlink(dialogs, p, "About to change the callid -- remove the old name"); 25460 build_callid_pvt(p); 25461 ao2_t_link(dialogs, p, "Linking in under new name"); 25462 25463 /* We have an extension to call, don't use the full contact here */ 25464 /* This to enable dialing registered peers with extension dialling, 25465 like SIP/peername/extension 25466 SIP/peername will still use the full contact 25467 */ 25468 if (ext) { 25469 ast_string_field_set(p, username, ext); 25470 ast_string_field_set(p, fullcontact, NULL); 25471 } 25472 if (secret && !ast_strlen_zero(secret)) 25473 ast_string_field_set(p, peersecret, secret); 25474 25475 if (md5secret && !ast_strlen_zero(md5secret)) 25476 ast_string_field_set(p, peermd5secret, md5secret); 25477 25478 if (authname && !ast_strlen_zero(authname)) 25479 ast_string_field_set(p, authname, authname); 25480 #if 0 25481 printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host); 25482 #endif 25483 p->prefcodec = oldformat; /* Format for this call */ 25484 p->jointcapability = oldformat & p->capability; 25485 sip_pvt_lock(p); 25486 tmpc = sip_new(p, AST_STATE_DOWN, host, requestor ? requestor->linkedid : NULL); /* Place the call */ 25487 if (sip_cfg.callevents) 25488 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", 25489 "Channel: %s\r\nChanneltype: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\nPeername: %s\r\n", 25490 p->owner? p->owner->name : "", "SIP", p->callid, p->fullcontact, p->peername); 25491 sip_pvt_unlock(p); 25492 if (!tmpc) { 25493 dialog_unlink_all(p, TRUE, TRUE); 25494 /* sip_destroy(p); */ 25495 } 25496 dialog_unref(p, "toss pvt ptr at end of sip_request_call"); 25497 ast_update_use_count(); 25498 restart_monitor(); 25499 return tmpc; 25500 }
| static int sip_reregister | ( | const void * | data | ) | [static] |
Update registration with SIP Proxy. Called from the scheduler when the previous registration expires, so we don't have to cancel the pending event. We assume the reference so the sip_registry is valid, since it is stored in the scheduled event anyways.
Definition at line 12387 of file chan_sip.c.
References __sip_do_register(), append_history, ast_log(), LOG_NOTICE, registry_unref(), and sipdebug.
Referenced by handle_response_register(), sip_send_all_registers(), and sip_show_sched().
12388 { 12389 /* if we are here, we know that we need to reregister. */ 12390 struct sip_registry *r = (struct sip_registry *) data; 12391 12392 /* if we couldn't get a reference to the registry object, punt */ 12393 if (!r) { 12394 return 0; 12395 } 12396 12397 if (r->call && r->call->do_history) { 12398 append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname); 12399 } 12400 /* Since registry's are only added/removed by the the monitor thread, this 12401 may be overkill to reference/dereference at all here */ 12402 if (sipdebug) { 12403 ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname); 12404 } 12405 12406 r->expire = -1; 12407 r->expiry = r->configured_expiry; 12408 __sip_do_register(r); 12409 registry_unref(r, "unref the re-register scheduled event"); 12410 return 0; 12411 }
| 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 7033 of file chan_sip.c.
References ast_debug, ast_dsp_free(), ast_dsp_process(), ast_dsp_set_features(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_TEXT_MASK, AST_FORMAT_VIDEO_MASK, AST_FRAME_DTMF, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_VOICE, ast_getformatname(), ast_null_frame, ast_rtp_instance_read(), ast_set_read_format(), ast_set_write_format(), ast_test_flag, ast_udptl_read(), ast_verbose, DSP_FEATURE_DIGIT_DETECT, f, ast_channel::fdno, ast_channel::name, and sipdebug_text.
Referenced by sip_read().
07034 { 07035 /* Retrieve audio/etc from channel. Assumes p->lock is already held. */ 07036 struct ast_frame *f; 07037 07038 if (!p->rtp) { 07039 /* We have no RTP allocated for this channel */ 07040 return &ast_null_frame; 07041 } 07042 07043 switch(ast->fdno) { 07044 case 0: 07045 f = ast_rtp_instance_read(p->rtp, 0); /* RTP Audio */ 07046 break; 07047 case 1: 07048 f = ast_rtp_instance_read(p->rtp, 1); /* RTCP Control Channel */ 07049 break; 07050 case 2: 07051 f = ast_rtp_instance_read(p->vrtp, 0); /* RTP Video */ 07052 break; 07053 case 3: 07054 f = ast_rtp_instance_read(p->vrtp, 1); /* RTCP Control Channel for video */ 07055 break; 07056 case 4: 07057 f = ast_rtp_instance_read(p->trtp, 0); /* RTP Text */ 07058 if (sipdebug_text) { 07059 int i; 07060 unsigned char* arr = f->data.ptr; 07061 for (i=0; i < f->datalen; i++) 07062 ast_verbose("%c", (arr[i] > ' ' && arr[i] < '}') ? arr[i] : '.'); 07063 ast_verbose(" -> "); 07064 for (i=0; i < f->datalen; i++) 07065 ast_verbose("%02X ", arr[i]); 07066 ast_verbose("\n"); 07067 } 07068 break; 07069 case 5: 07070 f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */ 07071 break; 07072 default: 07073 f = &ast_null_frame; 07074 } 07075 /* Don't forward RFC2833 if we're not supposed to */ 07076 if (f && (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END) && 07077 (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833)) { 07078 ast_debug(1, "Ignoring DTMF (%c) RTP frame because dtmfmode is not RFC2833\n", f->subclass.integer); 07079 return &ast_null_frame; 07080 } 07081 07082 /* We already hold the channel lock */ 07083 if (!p->owner || (f && f->frametype != AST_FRAME_VOICE)) 07084 return f; 07085 07086 if (f && f->subclass.codec != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) { 07087 if (!(f->subclass.codec & p->jointcapability)) { 07088 ast_debug(1, "Bogus frame of format '%s' received from '%s'!\n", 07089 ast_getformatname(f->subclass.codec), p->owner->name); 07090 return &ast_null_frame; 07091 } 07092 ast_debug(1, "Oooh, format changed to %s\n", 07093 ast_getformatname(f->subclass.codec)); 07094 p->owner->nativeformats = (p->owner->nativeformats & (AST_FORMAT_VIDEO_MASK | AST_FORMAT_TEXT_MASK)) | f->subclass.codec; 07095 ast_set_read_format(p->owner, p->owner->readformat); 07096 ast_set_write_format(p->owner, p->owner->writeformat); 07097 } 07098 07099 if (f && p->dsp) { 07100 f = ast_dsp_process(p->owner, p->dsp, f); 07101 if (f && f->frametype == AST_FRAME_DTMF) { 07102 if (f->subclass.integer == 'f') { 07103 ast_debug(1, "Fax CNG detected on %s\n", ast->name); 07104 *faxdetect = 1; 07105 /* If we only needed this DSP for fax detection purposes we can just drop it now */ 07106 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 07107 ast_dsp_set_features(p->dsp, DSP_FEATURE_DIGIT_DETECT); 07108 } else { 07109 ast_dsp_free(p->dsp); 07110 p->dsp = NULL; 07111 } 07112 } else { 07113 ast_debug(1, "* Detected inband DTMF '%c'\n", f->subclass.integer); 07114 } 07115 } 07116 } 07117 07118 return f; 07119 }
| void sip_scheddestroy | ( | struct sip_pvt * | p, | |
| int | ms | |||
| ) |
Schedule destruction of SIP dialog.
Definition at line 3827 of file chan_sip.c.
References __sip_autodestruct(), append_history, ast_log(), ast_sched_add(), ast_verbose, global_t1, global_timer_b, LOG_WARNING, sip_cancel_destroy(), sip_debug_test_pvt(), sip_methods, stop_session_timer(), cfsip_methods::text, and TRUE.
Referenced by __sip_autodestruct(), auto_congest(), cb_extensionstate(), check_auth(), check_pendings(), handle_incoming(), handle_invite_replaces(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_options(), handle_request_publish(), handle_request_register(), handle_request_subscribe(), handle_response_invite(), handle_response_register(), receive_message(), sip_hangup(), sip_scheddestroy_final(), sip_send_mwi_to_peer(), sip_sipredirect(), transmit_fake_auth_response(), and transmit_publish().
03828 { 03829 if (p->final_destruction_scheduled) { 03830 return; /* already set final destruction */ 03831 } 03832 03833 if (ms < 0) { 03834 if (p->timer_t1 == 0) { 03835 p->timer_t1 = global_t1; /* Set timer T1 if not set (RFC 3261) */ 03836 } 03837 if (p->timer_b == 0) { 03838 p->timer_b = global_timer_b; /* Set timer B if not set (RFC 3261) */ 03839 } 03840 ms = p->timer_t1 * 64; 03841 } 03842 if (sip_debug_test_pvt(p)) { 03843 ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text); 03844 } 03845 if (sip_cancel_destroy(p)) { 03846 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 03847 } 03848 03849 if (p->do_history) { 03850 append_history(p, "SchedDestroy", "%d ms", ms); 03851 } 03852 p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, dialog_ref(p, "setting ref as passing into ast_sched_add for __sip_autodestruct")); 03853 03854 if (p->stimer && p->stimer->st_active == TRUE && p->stimer->st_schedid > 0) { 03855 stop_session_timer(p); 03856 } 03857 }
| void sip_scheddestroy_final | ( | struct sip_pvt * | p, | |
| int | ms | |||
| ) |
Schedule final destruction of SIP dialog. This can not be canceled. This function is used to keep a dialog around for a period of time in order to properly respond to any retransmits.
Definition at line 3814 of file chan_sip.c.
References sip_scheddestroy().
Referenced by handle_request_bye().
03815 { 03816 if (p->final_destruction_scheduled) { 03817 return; /* already set final destruction */ 03818 } 03819 03820 sip_scheddestroy(p, ms); 03821 if (p->autokillid != -1) { 03822 p->final_destruction_scheduled = 1; 03823 } 03824 }
| static void sip_send_all_mwi_subscriptions | ( | void | ) | [static] |
Send all MWI subscriptions.
Definition at line 28295 of file chan_sip.c.
References ast_sched_add(), AST_SCHED_DEL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_REF, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, sip_subscribe_mwi_destroy(), sip_subscribe_mwi_do(), and submwil.
Referenced by load_module(), network_change_event_sched_cb(), and sip_do_reload().
28296 { 28297 ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do { 28298 ASTOBJ_WRLOCK(iterator); 28299 AST_SCHED_DEL(sched, iterator->resub); 28300 if ((iterator->resub = ast_sched_add(sched, 1, sip_subscribe_mwi_do, ASTOBJ_REF(iterator))) < 0) { 28301 ASTOBJ_UNREF(iterator, sip_subscribe_mwi_destroy); 28302 } 28303 ASTOBJ_UNLOCK(iterator); 28304 } while (0)); 28305 }
| static void sip_send_all_registers | ( | void | ) | [static] |
Send all known registrations.
Definition at line 28271 of file chan_sip.c.
References AST_SCHED_REPLACE_UNREF, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, default_expiry, registry_addref(), registry_unref(), regl, regobjs, and sip_reregister().
Referenced by load_module(), network_change_event_sched_cb(), and sip_do_reload().
28272 { 28273 int ms; 28274 int regspacing; 28275 if (!regobjs) 28276 return; 28277 regspacing = default_expiry * 1000/regobjs; 28278 if (regspacing > 100) { 28279 regspacing = 100; 28280 } 28281 ms = regspacing; 28282 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 28283 ASTOBJ_WRLOCK(iterator); 28284 ms += regspacing; 28285 AST_SCHED_REPLACE_UNREF(iterator->expire, sched, ms, sip_reregister, iterator, 28286 registry_unref(_data, "REPLACE sched del decs the refcount"), 28287 registry_unref(iterator, "REPLACE sched add failure decs the refcount"), 28288 registry_addref(iterator, "REPLACE sched add incs the refcount")); 28289 ASTOBJ_UNLOCK(iterator); 28290 } while (0) 28291 ); 28292 }
| static int sip_send_mwi_to_peer | ( | struct sip_peer * | peer, | |
| const struct ast_event * | event, | |||
| int | cache_only | |||
| ) | [static] |
Send message waiting indication to alert peer that they've got voicemail.
Definition at line 24534 of file chan_sip.c.
References ao2_t_link, ao2_t_unlink, ast_app_inboxcount(), ast_event_get_ie_uint(), AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, ast_set_flag, ast_sip_ouraddrfor(), ast_sockaddr_isnull(), ast_str_alloca, ast_string_field_set, ast_strlen_zero(), ast_test_flag, build_callid_pvt(), build_via(), create_addr_from_peer(), default_mwi_from, dialog_unlink_all(), dialogs, get_cached_mwi(), peer_mailboxes_to_str(), set_socket_transport(), sip_alloc(), sip_scheddestroy(), transmit_notify_with_mwi(), and TRUE.
Referenced by build_peer(), handle_request_subscribe(), and mwi_event_cb().
24535 { 24536 /* Called with peerl lock, but releases it */ 24537 struct sip_pvt *p; 24538 int newmsgs = 0, oldmsgs = 0; 24539 24540 if (ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY) && !peer->mwipvt) 24541 return 0; 24542 24543 /* Do we have an IP address? If not, skip this peer */ 24544 if (ast_sockaddr_isnull(&peer->addr) && ast_sockaddr_isnull(&peer->defaddr)) 24545 return 0; 24546 24547 if (event) { 24548 newmsgs = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS); 24549 oldmsgs = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS); 24550 } else if (!cache_only) { /* Fall back to manually checking the mailbox */ 24551 struct ast_str *mailbox_str = ast_str_alloca(512); 24552 peer_mailboxes_to_str(&mailbox_str, peer); 24553 ast_app_inboxcount(mailbox_str->str, &newmsgs, &oldmsgs); 24554 } else { 24555 get_cached_mwi(peer, &newmsgs, &oldmsgs); 24556 } 24557 24558 if (peer->mwipvt) { 24559 /* Base message on subscription */ 24560 p = dialog_ref(peer->mwipvt, "sip_send_mwi_to_peer: Setting dialog ptr p from peer->mwipvt-- should this be done?"); 24561 } else { 24562 /* Build temporary dialog for this message */ 24563 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) 24564 return -1; 24565 /* If we don't set the socket type to 0, then create_addr_from_peer will fail immediately if the peer 24566 * uses any transport other than UDP. We set the type to 0 here and then let create_addr_from_peer copy 24567 * the peer's socket information to the sip_pvt we just allocated 24568 */ 24569 set_socket_transport(&p->socket, 0); 24570 if (create_addr_from_peer(p, peer)) { 24571 /* Maybe they're not registered, etc. */ 24572 dialog_unlink_all(p, TRUE, TRUE); 24573 dialog_unref(p, "unref dialog p just created via sip_alloc"); 24574 /* sip_destroy(p); */ 24575 return 0; 24576 } 24577 /* Recalculate our side, and recalculate Call ID */ 24578 ast_sip_ouraddrfor(&p->sa, &p->ourip, p); 24579 build_via(p); 24580 ao2_t_unlink(dialogs, p, "About to change the callid -- remove the old name"); 24581 build_callid_pvt(p); 24582 if (!ast_strlen_zero(peer->mwi_from)) { 24583 ast_string_field_set(p, mwi_from, peer->mwi_from); 24584 } else if (!ast_strlen_zero(default_mwi_from)) { 24585 ast_string_field_set(p, mwi_from, default_mwi_from); 24586 } 24587 ao2_t_link(dialogs, p, "Linking in under new name"); 24588 /* Destroy this session after 32 secs */ 24589 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 24590 } 24591 24592 /* Send MWI */ 24593 ast_set_flag(&p->flags[0], SIP_OUTGOING); 24594 /* the following will decrement the refcount on p as it finishes */ 24595 transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten); 24596 dialog_unref(p, "unref dialog ptr p just before it goes out of scope at the end of sip_send_mwi_to_peer."); 24597 return 0; 24598 }
| static int sip_senddigit_begin | ( | struct ast_channel * | ast, | |
| char | digit | |||
| ) | [static] |
Definition at line 6352 of file chan_sip.c.
References AST_RTP_DTMF_MODE_INBAND, ast_rtp_instance_dtmf_begin(), ast_rtp_instance_dtmf_mode_get(), ast_test_flag, sip_pvt_lock, sip_pvt_unlock, and ast_channel::tech_pvt.
06353 { 06354 struct sip_pvt *p = ast->tech_pvt; 06355 int res = 0; 06356 06357 sip_pvt_lock(p); 06358 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 06359 case SIP_DTMF_INBAND: 06360 if (p->rtp && ast_rtp_instance_dtmf_mode_get(p->rtp) == AST_RTP_DTMF_MODE_INBAND) { 06361 ast_rtp_instance_dtmf_begin(p->rtp, digit); 06362 } else { 06363 res = -1; /* Tell Asterisk to generate inband indications */ 06364 } 06365 break; 06366 case SIP_DTMF_RFC2833: 06367 if (p->rtp) 06368 ast_rtp_instance_dtmf_begin(p->rtp, digit); 06369 break; 06370 default: 06371 break; 06372 } 06373 sip_pvt_unlock(p); 06374 06375 return res; 06376 }
| 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 6380 of file chan_sip.c.
References AST_RTP_DTMF_MODE_INBAND, ast_rtp_instance_dtmf_end(), ast_rtp_instance_dtmf_end_with_duration(), ast_rtp_instance_dtmf_mode_get(), ast_test_flag, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, and transmit_info_with_digit().
06381 { 06382 struct sip_pvt *p = ast->tech_pvt; 06383 int res = 0; 06384 06385 sip_pvt_lock(p); 06386 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 06387 case SIP_DTMF_INFO: 06388 case SIP_DTMF_SHORTINFO: 06389 transmit_info_with_digit(p, digit, duration); 06390 break; 06391 case SIP_DTMF_RFC2833: 06392 if (p->rtp) 06393 ast_rtp_instance_dtmf_end_with_duration(p->rtp, digit, duration); 06394 break; 06395 case SIP_DTMF_INBAND: 06396 if (p->rtp && ast_rtp_instance_dtmf_mode_get(p->rtp) == AST_RTP_DTMF_MODE_INBAND) { 06397 ast_rtp_instance_dtmf_end(p->rtp, digit); 06398 } else { 06399 res = -1; /* Tell Asterisk to stop inband indications */ 06400 } 06401 break; 06402 } 06403 sip_pvt_unlock(p); 06404 06405 return res; 06406 }
| 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 4294 of file chan_sip.c.
References ast_channel::_state, ast_debug, AST_HTML_URL, ast_log(), ast_set_flag, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_string_field_build, ast_test_flag, FALSE, LOG_WARNING, sip_debug_test_pvt(), ast_channel::tech_pvt, transmit_reinvite_with_sdp(), transmit_response(), and url.
04295 { 04296 struct sip_pvt *p = chan->tech_pvt; 04297 04298 if (subclass != AST_HTML_URL) 04299 return -1; 04300 04301 ast_string_field_build(p, url, "<%s>;mode=active", data); 04302 04303 if (sip_debug_test_pvt(p)) 04304 ast_debug(1, "Send URL %s, state = %d!\n", data, chan->_state); 04305 04306 switch (chan->_state) { 04307 case AST_STATE_RING: 04308 transmit_response(p, "100 Trying", &p->initreq); 04309 break; 04310 case AST_STATE_RINGING: 04311 transmit_response(p, "180 Ringing", &p->initreq); 04312 break; 04313 case AST_STATE_UP: 04314 if (!p->pendinginvite) { /* We are up, and have no outstanding invite */ 04315 transmit_reinvite_with_sdp(p, FALSE, FALSE); 04316 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 04317 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 04318 } 04319 break; 04320 default: 04321 ast_log(LOG_WARNING, "Don't know how to send URI when state is %d!\n", chan->_state); 04322 } 04323 04324 return 0; 04325 }
| static int sip_sendtext | ( | struct ast_channel * | ast, | |
| const char * | text | |||
| ) | [static] |
Send SIP MESSAGE text within a call Called from PBX core sendtext() application.
Definition at line 4335 of file chan_sip.c.
References ast_debug, ast_verbose, debug, is_method_allowed(), ast_channel::name, sip_debug_test_pvt(), ast_channel::tech_pvt, and transmit_message_with_text().
04336 { 04337 struct sip_pvt *dialog = ast->tech_pvt; 04338 int debug = sip_debug_test_pvt(dialog); 04339 04340 if (!dialog) 04341 return -1; 04342 /* NOT ast_strlen_zero, because a zero-length message is specifically 04343 * allowed by RFC 3428 (See section 10, Examples) */ 04344 if (!text) 04345 return 0; 04346 if(!is_method_allowed(&dialog->allowed_methods, SIP_MESSAGE)) { 04347 ast_debug(2, "Trying to send MESSAGE to device that does not support it.\n"); 04348 return(0); 04349 } 04350 if (debug) 04351 ast_verbose("Sending text %s on %s\n", text, ast->name); 04352 transmit_message_with_text(dialog, text); 04353 return 0; 04354 }
| 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 18198 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, recordhistory, TRUE, and ast_cli_entry::usage.
18199 { 18200 switch (cmd) { 18201 case CLI_INIT: 18202 e->command = "sip set history {on|off}"; 18203 e->usage = 18204 "Usage: sip set history {on|off}\n" 18205 " Enables/Disables recording of SIP dialog history for debugging purposes.\n" 18206 " Use 'sip show history' to view the history of a call number.\n"; 18207 return NULL; 18208 case CLI_GENERATE: 18209 return NULL; 18210 } 18211 18212 if (a->argc != e->args) 18213 return CLI_SHOWUSAGE; 18214 18215 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) { 18216 recordhistory = TRUE; 18217 ast_cli(a->fd, "SIP History Recording Enabled (use 'sip show history')\n"); 18218 } else if (!strncasecmp(a->argv[e->args - 1], "off", 3)) { 18219 recordhistory = FALSE; 18220 ast_cli(a->fd, "SIP History Recording Disabled\n"); 18221 } else { 18222 return CLI_SHOWUSAGE; 18223 } 18224 return CLI_SUCCESS; 18225 }
| static void sip_set_redirstr | ( | struct sip_pvt * | p, | |
| char * | reason | |||
| ) | [static] |
Translate referring cause.
Definition at line 14261 of file chan_sip.c.
References ast_string_field_set.
Referenced by get_rdnis().
14261 { 14262 14263 if (!strcmp(reason, "unknown")) { 14264 ast_string_field_set(p, redircause, "UNKNOWN"); 14265 } else if (!strcmp(reason, "user-busy")) { 14266 ast_string_field_set(p, redircause, "BUSY"); 14267 } else if (!strcmp(reason, "no-answer")) { 14268 ast_string_field_set(p, redircause, "NOANSWER"); 14269 } else if (!strcmp(reason, "unavailable")) { 14270 ast_string_field_set(p, redircause, "UNREACHABLE"); 14271 } else if (!strcmp(reason, "unconditional")) { 14272 ast_string_field_set(p, redircause, "UNCONDITIONAL"); 14273 } else if (!strcmp(reason, "time-of-day")) { 14274 ast_string_field_set(p, redircause, "UNKNOWN"); 14275 } else if (!strcmp(reason, "do-not-disturb")) { 14276 ast_string_field_set(p, redircause, "UNKNOWN"); 14277 } else if (!strcmp(reason, "deflection")) { 14278 ast_string_field_set(p, redircause, "UNKNOWN"); 14279 } else if (!strcmp(reason, "follow-me")) { 14280 ast_string_field_set(p, redircause, "UNKNOWN"); 14281 } else if (!strcmp(reason, "out-of-service")) { 14282 ast_string_field_set(p, redircause, "UNREACHABLE"); 14283 } else if (!strcmp(reason, "away")) { 14284 ast_string_field_set(p, redircause, "UNREACHABLE"); 14285 } else { 14286 ast_string_field_set(p, redircause, "UNKNOWN"); 14287 } 14288 }
| static int sip_set_rtp_peer | ( | struct ast_channel * | chan, | |
| struct ast_rtp_instance * | instance, | |||
| struct ast_rtp_instance * | vinstance, | |||
| struct ast_rtp_instance * | tinstance, | |||
| format_t | codecs, | |||
| int | nat_active | |||
| ) | [static] |
Definition at line 27938 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), ast_channel_trylock, ast_channel_unlock, ast_debug, ast_rtp_instance_get_and_cmp_remote_address(), ast_set_flag, ast_sockaddr_isnull(), ast_sockaddr_stringify(), AST_STATE_UP, ast_test_flag, FALSE, sip_cfg, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, and transmit_reinvite_with_sdp().
Referenced by sip_fixup().
27939 { 27940 struct sip_pvt *p; 27941 int changed = 0; 27942 27943 p = chan->tech_pvt; 27944 if (!p) { 27945 return -1; 27946 } 27947 27948 /* Disable early RTP bridge */ 27949 if (!ast_bridged_channel(chan) && !sip_cfg.directrtpsetup) /* We are in early state */ 27950 return 0; 27951 27952 /* 27953 * Lock both the pvt and it's owner safely. 27954 */ 27955 sip_pvt_lock(p); 27956 while (p->owner && ast_channel_trylock(p->owner)) { 27957 sip_pvt_unlock(p); 27958 usleep(1); 27959 sip_pvt_lock(p); 27960 } 27961 27962 if (!p->owner) { 27963 sip_pvt_unlock(p); 27964 return 0; 27965 } 27966 27967 if (p->alreadygone) { 27968 /* If we're destroyed, don't bother */ 27969 ast_channel_unlock(p->owner); 27970 sip_pvt_unlock(p); 27971 return 0; 27972 } 27973 27974 /* if this peer cannot handle reinvites of the media stream to devices 27975 that are known to be behind a NAT, then stop the process now 27976 */ 27977 if (nat_active && !ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA_NAT)) { 27978 ast_channel_unlock(p->owner); 27979 sip_pvt_unlock(p); 27980 return 0; 27981 } 27982 27983 if (instance) { 27984 changed |= ast_rtp_instance_get_and_cmp_remote_address(instance, &p->redirip); 27985 } else if (!ast_sockaddr_isnull(&p->redirip)) { 27986 memset(&p->redirip, 0, sizeof(p->redirip)); 27987 changed = 1; 27988 } 27989 if (vinstance) { 27990 changed |= ast_rtp_instance_get_and_cmp_remote_address(vinstance, &p->vredirip); 27991 } else if (!ast_sockaddr_isnull(&p->vredirip)) { 27992 memset(&p->vredirip, 0, sizeof(p->vredirip)); 27993 changed = 1; 27994 } 27995 if (tinstance) { 27996 changed |= ast_rtp_instance_get_and_cmp_remote_address(tinstance, &p->tredirip); 27997 } else if (!ast_sockaddr_isnull(&p->tredirip)) { 27998 memset(&p->tredirip, 0, sizeof(p->tredirip)); 27999 changed = 1; 28000 } 28001 if (codecs && (p->redircodecs != codecs)) { 28002 p->redircodecs = codecs; 28003 changed = 1; 28004 } 28005 if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 28006 if (chan->_state != AST_STATE_UP) { /* We are in early state */ 28007 if (p->do_history) 28008 append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal."); 28009 ast_debug(1, "Early remote bridge setting SIP '%s' - Sending media to %s\n", p->callid, ast_sockaddr_stringify(instance ? &p->redirip : &p->ourip)); 28010 } else if (!p->pendinginvite) { /* We are up, and have no outstanding invite */ 28011 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)); 28012 transmit_reinvite_with_sdp(p, FALSE, FALSE); 28013 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 28014 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)); 28015 /* We have a pending Invite. Send re-invite when we're done with the invite */ 28016 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 28017 } 28018 } 28019 /* Reset lastrtprx timer */ 28020 p->lastrtprx = p->lastrtptx = time(NULL); 28021 ast_channel_unlock(p->owner); 28022 sip_pvt_unlock(p); 28023 return 0; 28024 }
| static int sip_set_udptl_peer | ( | struct ast_channel * | chan, | |
| struct ast_udptl * | udptl | |||
| ) | [static] |
Definition at line 27795 of file chan_sip.c.
References ast_channel_trylock, ast_channel_unlock, ast_debug, ast_set_flag, ast_sockaddr_stringify(), ast_test_flag, ast_udptl_get_peer(), FALSE, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), and TRUE.
27796 { 27797 struct sip_pvt *p; 27798 27799 p = chan->tech_pvt; 27800 if (!p) { 27801 return -1; 27802 } 27803 /* 27804 * Lock both the pvt and it's owner safely. 27805 */ 27806 sip_pvt_lock(p); 27807 while (p->owner && ast_channel_trylock(p->owner)) { 27808 sip_pvt_unlock(p); 27809 usleep(1); 27810 sip_pvt_lock(p); 27811 } 27812 27813 if (!p->owner) { 27814 sip_pvt_unlock(p); 27815 return 0; 27816 } 27817 if (udptl) { 27818 ast_udptl_get_peer(udptl, &p->udptlredirip); 27819 } else { 27820 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 27821 } 27822 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 27823 if (!p->pendinginvite) { 27824 ast_debug(3, "Sending reinvite on SIP '%s' - It's UDPTL soon redirected to IP %s\n", 27825 p->callid, ast_sockaddr_stringify(udptl ? &p->udptlredirip : &p->ourip)); 27826 transmit_reinvite_with_sdp(p, TRUE, FALSE); 27827 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 27828 ast_debug(3, "Deferring reinvite on SIP '%s' - It's UDPTL will be redirected to IP %s\n", 27829 p->callid, ast_sockaddr_stringify(udptl ? &p->udptlredirip : &p->ourip)); 27830 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 27831 } 27832 } 27833 /* Reset lastrtprx timer */ 27834 p->lastrtprx = p->lastrtptx = time(NULL); 27835 ast_channel_unlock(p->owner); 27836 sip_pvt_unlock(p); 27837 return 0; 27838 }
| 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 4165 of file chan_sip.c.
References ast_debug, AST_OPTION_DIGIT_DETECT, AST_OPTION_FORMAT_READ, AST_OPTION_FORMAT_WRITE, AST_OPTION_MAKE_COMPATIBLE, AST_OPTION_SECURE_MEDIA, AST_OPTION_SECURE_SIGNALING, ast_rtp_instance_make_compatible(), ast_rtp_instance_set_read_format(), ast_rtp_instance_set_write_format(), ast_set2_flag, ast_test_flag, disable_dsp_detect(), enable_dsp_detect(), ast_channel::name, and ast_channel::tech_pvt.
04166 { 04167 int res = -1; 04168 struct sip_pvt *p = chan->tech_pvt; 04169 04170 switch (option) { 04171 case AST_OPTION_FORMAT_READ: 04172 res = ast_rtp_instance_set_read_format(p->rtp, *(int *) data); 04173 break; 04174 case AST_OPTION_FORMAT_WRITE: 04175 res = ast_rtp_instance_set_write_format(p->rtp, *(int *) data); 04176 break; 04177 case AST_OPTION_MAKE_COMPATIBLE: 04178 res = ast_rtp_instance_make_compatible(chan, p->rtp, (struct ast_channel *) data); 04179 break; 04180 case AST_OPTION_DIGIT_DETECT: 04181 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || 04182 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) { 04183 char *cp = (char *) data; 04184 04185 ast_debug(1, "%sabling digit detection on %s\n", *cp ? "En" : "Dis", chan->name); 04186 if (*cp) { 04187 enable_dsp_detect(p); 04188 } else { 04189 disable_dsp_detect(p); 04190 } 04191 res = 0; 04192 } 04193 break; 04194 case AST_OPTION_SECURE_SIGNALING: 04195 p->req_secure_signaling = *(unsigned int *) data; 04196 res = 0; 04197 break; 04198 case AST_OPTION_SECURE_MEDIA: 04199 ast_set2_flag(&p->flags[1], *(unsigned int *) data, SIP_PAGE2_USE_SRTP); 04200 res = 0; 04201 break; 04202 default: 04203 break; 04204 } 04205 04206 return res; 04207 }
| 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 17650 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ao2_t_ref, ast_cli_args::argc, ast_cli_args::argv, ARRAY_LEN, ast_cli(), AST_CLI_YESNO, ast_getformatname_multiple(), ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_strlen_zero(), ast_test_flag, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sipch(), dialogs, dtmfmode2str(), ast_cli_args::fd, len(), ast_cli_args::line, ast_cli_args::n, NONE, ast_cli_args::pos, sip_pvt_lock, sip_pvt_unlock, stmode2str(), strefresher2str(), subscription_type2str(), transfermode2str(), TRUE, ast_cli_entry::usage, and ast_cli_args::word.
17651 { 17652 struct sip_pvt *cur; 17653 size_t len; 17654 int found = 0; 17655 struct ao2_iterator i; 17656 17657 switch (cmd) { 17658 case CLI_INIT: 17659 e->command = "sip show channel"; 17660 e->usage = 17661 "Usage: sip show channel <call-id>\n" 17662 " Provides detailed status on a given SIP dialog (identified by SIP call-id).\n"; 17663 return NULL; 17664 case CLI_GENERATE: 17665 return complete_sipch(a->line, a->word, a->pos, a->n); 17666 } 17667 17668 if (a->argc != 4) 17669 return CLI_SHOWUSAGE; 17670 len = strlen(a->argv[3]); 17671 17672 i = ao2_iterator_init(dialogs, 0); 17673 while ((cur = ao2_t_iterator_next(&i, "iterate thru dialogs"))) { 17674 sip_pvt_lock(cur); 17675 17676 if (!strncasecmp(cur->callid, a->argv[3], len)) { 17677 char formatbuf[SIPBUFSIZE/2]; 17678 ast_cli(a->fd, "\n"); 17679 if (cur->subscribed != NONE) 17680 ast_cli(a->fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); 17681 else 17682 ast_cli(a->fd, " * SIP Call\n"); 17683 ast_cli(a->fd, " Curr. trans. direction: %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming"); 17684 ast_cli(a->fd, " Call-ID: %s\n", cur->callid); 17685 ast_cli(a->fd, " Owner channel ID: %s\n", cur->owner ? cur->owner->name : "<none>"); 17686 ast_cli(a->fd, " Our Codec Capability: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->capability)); 17687 ast_cli(a->fd, " Non-Codec Capability (DTMF): %d\n", cur->noncodeccapability); 17688 ast_cli(a->fd, " Their Codec Capability: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->peercapability)); 17689 ast_cli(a->fd, " Joint Codec Capability: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->jointcapability)); 17690 ast_cli(a->fd, " Format: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) ); 17691 ast_cli(a->fd, " T.38 support %s\n", AST_CLI_YESNO(cur->udptl != NULL)); 17692 ast_cli(a->fd, " Video support %s\n", AST_CLI_YESNO(cur->vrtp != NULL)); 17693 ast_cli(a->fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate); 17694 ast_cli(a->fd, " Theoretical Address: %s\n", ast_sockaddr_stringify(&cur->sa)); 17695 ast_cli(a->fd, " Received Address: %s\n", ast_sockaddr_stringify(&cur->recv)); 17696 ast_cli(a->fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer)); 17697 ast_cli(a->fd, " Force rport: %s\n", AST_CLI_YESNO(ast_test_flag(&cur->flags[0], SIP_NAT_FORCE_RPORT))); 17698 if (ast_sockaddr_isnull(&cur->redirip)) { 17699 ast_cli(a->fd, 17700 " Audio IP: %s (local)\n", 17701 ast_sockaddr_stringify_addr(&cur->ourip)); 17702 } else { 17703 ast_cli(a->fd, 17704 " Audio IP: %s (Outside bridge)\n", 17705 ast_sockaddr_stringify_addr(&cur->redirip)); 17706 } 17707 ast_cli(a->fd, " Our Tag: %s\n", cur->tag); 17708 ast_cli(a->fd, " Their Tag: %s\n", cur->theirtag); 17709 ast_cli(a->fd, " SIP User agent: %s\n", cur->useragent); 17710 if (!ast_strlen_zero(cur->username)) 17711 ast_cli(a->fd, " Username: %s\n", cur->username); 17712 if (!ast_strlen_zero(cur->peername)) 17713 ast_cli(a->fd, " Peername: %s\n", cur->peername); 17714 if (!ast_strlen_zero(cur->uri)) 17715 ast_cli(a->fd, " Original uri: %s\n", cur->uri); 17716 if (!ast_strlen_zero(cur->cid_num)) 17717 ast_cli(a->fd, " Caller-ID: %s\n", cur->cid_num); 17718 ast_cli(a->fd, " Need Destroy: %s\n", AST_CLI_YESNO(cur->needdestroy)); 17719 ast_cli(a->fd, " Last Message: %s\n", cur->lastmsg); 17720 ast_cli(a->fd, " Promiscuous Redir: %s\n", AST_CLI_YESNO(ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR))); 17721 ast_cli(a->fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); 17722 ast_cli(a->fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF))); 17723 ast_cli(a->fd, " SIP Options: "); 17724 if (cur->sipoptions) { 17725 int x; 17726 for (x = 0 ; x < ARRAY_LEN(sip_options); x++) { 17727 if (cur->sipoptions & sip_options[x].id) 17728 ast_cli(a->fd, "%s ", sip_options[x].text); 17729 } 17730 ast_cli(a->fd, "\n"); 17731 } else 17732 ast_cli(a->fd, "(none)\n"); 17733 17734 if (!cur->stimer) 17735 ast_cli(a->fd, " Session-Timer: Uninitiallized\n"); 17736 else { 17737 ast_cli(a->fd, " Session-Timer: %s\n", cur->stimer->st_active ? "Active" : "Inactive"); 17738 if (cur->stimer->st_active == TRUE) { 17739 ast_cli(a->fd, " S-Timer Interval: %d\n", cur->stimer->st_interval); 17740 ast_cli(a->fd, " S-Timer Refresher: %s\n", strefresher2str(cur->stimer->st_ref)); 17741 ast_cli(a->fd, " S-Timer Expirys: %d\n", cur->stimer->st_expirys); 17742 ast_cli(a->fd, " S-Timer Sched Id: %d\n", cur->stimer->st_schedid); 17743 ast_cli(a->fd, " S-Timer Peer Sts: %s\n", cur->stimer->st_active_peer_ua ? "Active" : "Inactive"); 17744 ast_cli(a->fd, " S-Timer Cached Min-SE: %d\n", cur->stimer->st_cached_min_se); 17745 ast_cli(a->fd, " S-Timer Cached SE: %d\n", cur->stimer->st_cached_max_se); 17746 ast_cli(a->fd, " S-Timer Cached Ref: %s\n", strefresher2str(cur->stimer->st_cached_ref)); 17747 ast_cli(a->fd, " S-Timer Cached Mode: %s\n", stmode2str(cur->stimer->st_cached_mode)); 17748 } 17749 } 17750 17751 ast_cli(a->fd, "\n\n"); 17752 17753 found++; 17754 } 17755 17756 sip_pvt_unlock(cur); 17757 17758 ao2_t_ref(cur, -1, "toss dialog ptr set by iterator_next"); 17759 } 17760 ao2_iterator_destroy(&i); 17761 17762 if (!found) 17763 ast_cli(a->fd, "No such SIP Call ID starting with '%s'\n", a->argv[3]); 17764 17765 return CLI_SUCCESS; 17766 }
| 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 17471 of file chan_sip.c.
References ao2_t_callback, ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, dialogs, ESS, ast_cli_args::fd, FORMAT2, FORMAT3, OBJ_NODATA, show_channels_cb(), and ast_cli_entry::usage.
17472 { 17473 struct __show_chan_arg arg = { .fd = a->fd, .numchans = 0 }; 17474 17475 17476 if (cmd == CLI_INIT) { 17477 e->command = "sip show {channels|subscriptions}"; 17478 e->usage = 17479 "Usage: sip show channels\n" 17480 " Lists all currently active SIP calls (dialogs).\n" 17481 "Usage: sip show subscriptions\n" 17482 " Lists active SIP subscriptions.\n"; 17483 return NULL; 17484 } else if (cmd == CLI_GENERATE) 17485 return NULL; 17486 17487 if (a->argc != e->args) 17488 return CLI_SHOWUSAGE; 17489 arg.subscriptions = !strcasecmp(a->argv[e->args - 1], "subscriptions"); 17490 if (!arg.subscriptions) 17491 ast_cli(arg.fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Format", "Hold", "Last Message", "Expiry", "Peer"); 17492 else 17493 ast_cli(arg.fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox", "Expiry"); 17494 17495 /* iterate on the container and invoke the callback on each item */ 17496 ao2_t_callback(dialogs, OBJ_NODATA, show_channels_cb, &arg, "callback to show channels"); 17497 17498 /* print summary information */ 17499 ast_cli(arg.fd, "%d active SIP %s%s\n", arg.numchans, 17500 (arg.subscriptions ? "subscription" : "dialog"), 17501 ESS(arg.numchans)); /* ESS(n) returns an "s" if n>1 */ 17502 return CLI_SUCCESS; 17503 #undef FORMAT 17504 #undef FORMAT2 17505 #undef FORMAT3 17506 }
| 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 17126 of file chan_sip.c.
References ao2_t_callback, ast_cli_args::argc, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, dialogs, ast_cli_args::fd, FORMAT2, OBJ_NODATA, show_chanstats_cb(), and ast_cli_entry::usage.
17127 { 17128 struct __show_chan_arg arg = { .fd = a->fd, .numchans = 0 }; 17129 17130 switch (cmd) { 17131 case CLI_INIT: 17132 e->command = "sip show channelstats"; 17133 e->usage = 17134 "Usage: sip show channelstats\n" 17135 " Lists all currently active SIP channel's RTCP statistics.\n" 17136 " Note that calls in the much optimized RTP P2P bridge mode will not show any packets here."; 17137 return NULL; 17138 case CLI_GENERATE: 17139 return NULL; 17140 } 17141 17142 if (a->argc != 3) 17143 return CLI_SHOWUSAGE; 17144 17145 ast_cli(a->fd, FORMAT2, "Peer", "Call ID", "Duration", "Recv: Pack", "Lost", "Jitter", "Send: Pack", "Lost", "Jitter"); 17146 /* iterate on the container and invoke the callback on each item */ 17147 ao2_t_callback(dialogs, OBJ_NODATA, show_chanstats_cb, &arg, "callback to sip show chanstats"); 17148 ast_cli(a->fd, "%d active SIP channel%s\n", arg.numchans, (arg.numchans != 1) ? "s" : ""); 17149 return CLI_SUCCESS; 17150 }
| 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 16402 of file chan_sip.c.
References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, domain_mode_to_text(), ast_cli_args::fd, FORMAT, S_OR, and ast_cli_entry::usage.
16403 { 16404 struct domain *d; 16405 #define FORMAT "%-40.40s %-20.20s %-16.16s\n" 16406 16407 switch (cmd) { 16408 case CLI_INIT: 16409 e->command = "sip show domains"; 16410 e->usage = 16411 "Usage: sip show domains\n" 16412 " Lists all configured SIP local domains.\n" 16413 " Asterisk only responds to SIP messages to local domains.\n"; 16414 return NULL; 16415 case CLI_GENERATE: 16416 return NULL; 16417 } 16418 16419 if (AST_LIST_EMPTY(&domain_list)) { 16420 ast_cli(a->fd, "SIP Domain support not enabled.\n\n"); 16421 return CLI_SUCCESS; 16422 } else { 16423 ast_cli(a->fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); 16424 AST_LIST_LOCK(&domain_list); 16425 AST_LIST_TRAVERSE(&domain_list, d, list) 16426 ast_cli(a->fd, FORMAT, d->domain, S_OR(d->context, "(default)"), 16427 domain_mode_to_text(d->mode)); 16428 AST_LIST_UNLOCK(&domain_list); 16429 ast_cli(a->fd, "\n"); 16430 return CLI_SUCCESS; 16431 } 16432 }
| 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 17769 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ao2_t_ref, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_LIST_TRAVERSE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sip_show_history(), dialogs, ast_cli_args::fd, len(), ast_cli_args::line, ast_cli_args::n, NONE, ast_cli_args::pos, recordhistory, sip_pvt_lock, sip_pvt_unlock, ast_cli_entry::usage, and ast_cli_args::word.
17770 { 17771 struct sip_pvt *cur; 17772 size_t len; 17773 int found = 0; 17774 struct ao2_iterator i; 17775 17776 switch (cmd) { 17777 case CLI_INIT: 17778 e->command = "sip show history"; 17779 e->usage = 17780 "Usage: sip show history <call-id>\n" 17781 " Provides detailed dialog history on a given SIP call (specified by call-id).\n"; 17782 return NULL; 17783 case CLI_GENERATE: 17784 return complete_sip_show_history(a->line, a->word, a->pos, a->n); 17785 } 17786 17787 if (a->argc != 4) 17788 return CLI_SHOWUSAGE; 17789 17790 if (!recordhistory) 17791 ast_cli(a->fd, "\n***Note: History recording is currently DISABLED. Use 'sip set history on' to ENABLE.\n"); 17792 17793 len = strlen(a->argv[3]); 17794 17795 i = ao2_iterator_init(dialogs, 0); 17796 while ((cur = ao2_t_iterator_next(&i, "iterate thru dialogs"))) { 17797 sip_pvt_lock(cur); 17798 if (!strncasecmp(cur->callid, a->argv[3], len)) { 17799 struct sip_history *hist; 17800 int x = 0; 17801 17802 ast_cli(a->fd, "\n"); 17803 if (cur->subscribed != NONE) 17804 ast_cli(a->fd, " * Subscription\n"); 17805 else 17806 ast_cli(a->fd, " * SIP Call\n"); 17807 if (cur->history) 17808 AST_LIST_TRAVERSE(cur->history, hist, list) 17809 ast_cli(a->fd, "%d. %s\n", ++x, hist->event); 17810 if (x == 0) 17811 ast_cli(a->fd, "Call '%s' has no history\n", cur->callid); 17812 found++; 17813 } 17814 sip_pvt_unlock(cur); 17815 ao2_t_ref(cur, -1, "toss dialog ptr from iterator_next"); 17816 } 17817 ao2_iterator_destroy(&i); 17818 17819 if (!found) 17820 ast_cli(a->fd, "No such SIP Call ID starting with '%s'\n", a->argv[3]); 17821 17822 return CLI_SUCCESS; 17823 }
| 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 15537 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_iterator_next, ao2_unlock, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_copy_string(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, FALSE, ast_cli_args::fd, FORMAT, FORMAT2, TRUE, unref_peer(), and ast_cli_entry::usage.
15538 { 15539 #define FORMAT "%-25.25s %-15.15s %-15.15s \n" 15540 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" 15541 char ilimits[40]; 15542 char iused[40]; 15543 int showall = FALSE; 15544 struct ao2_iterator i; 15545 struct sip_peer *peer; 15546 15547 switch (cmd) { 15548 case CLI_INIT: 15549 e->command = "sip show inuse"; 15550 e->usage = 15551 "Usage: sip show inuse [all]\n" 15552 " List all SIP devices usage counters and limits.\n" 15553 " Add option \"all\" to show all devices, not only those with a limit.\n"; 15554 return NULL; 15555 case CLI_GENERATE: 15556 return NULL; 15557 } 15558 15559 if (a->argc < 3) 15560 return CLI_SHOWUSAGE; 15561 15562 if (a->argc == 4 && !strcmp(a->argv[3], "all")) 15563 showall = TRUE; 15564 15565 ast_cli(a->fd, FORMAT, "* Peer name", "In use", "Limit"); 15566 15567 i = ao2_iterator_init(peers, 0); 15568 while ((peer = ao2_t_iterator_next(&i, "iterate thru peer table"))) { 15569 ao2_lock(peer); 15570 if (peer->call_limit) 15571 snprintf(ilimits, sizeof(ilimits), "%d", peer->call_limit); 15572 else 15573 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 15574 snprintf(iused, sizeof(iused), "%d/%d/%d", peer->inUse, peer->inRinging, peer->onHold); 15575 if (showall || peer->call_limit) 15576 ast_cli(a->fd, FORMAT2, peer->name, iused, ilimits); 15577 ao2_unlock(peer); 15578 unref_peer(peer, "toss iterator pointer"); 15579 } 15580 ao2_iterator_destroy(&i); 15581 15582 return CLI_SUCCESS; 15583 #undef FORMAT 15584 #undef FORMAT2 15585 }
| static char * sip_show_mwi | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 17354 of file chan_sip.c.
References ast_cli(), AST_CLI_YESNO, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, FORMAT, submwil, and ast_cli_entry::usage.
17355 { 17356 #define FORMAT "%-30.30s %-12.12s %-10.10s %-10.10s\n" 17357 char host[80]; 17358 17359 switch (cmd) { 17360 case CLI_INIT: 17361 e->command = "sip show mwi"; 17362 e->usage = 17363 "Usage: sip show mwi\n" 17364 " Provides a list of MWI subscriptions and status.\n"; 17365 return NULL; 17366 case CLI_GENERATE: 17367 return NULL; 17368 } 17369 17370 ast_cli(a->fd, FORMAT, "Host", "Username", "Mailbox", "Subscribed"); 17371 17372 ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do { 17373 ASTOBJ_RDLOCK(iterator); 17374 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); 17375 ast_cli(a->fd, FORMAT, host, iterator->username, iterator->mailbox, AST_CLI_YESNO(iterator->subscribed)); 17376 ASTOBJ_UNLOCK(iterator); 17377 } while(0)); 17378 17379 return CLI_SUCCESS; 17380 #undef FORMAT 17381 }
| 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 16074 of file chan_sip.c.
References ao2_t_callback, apeerobjs, ast_cli_args::argc, ast_cli(), ASTOBJ_CONTAINER_DUMP, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, dialog_dump_func(), dialogs, ast_cli_args::fd, OBJ_NODATA, peer_dump_func(), regl, regobjs, rpeerobjs, speerobjs, and ast_cli_entry::usage.
16075 { 16076 char tmp[256]; 16077 16078 switch (cmd) { 16079 case CLI_INIT: 16080 e->command = "sip show objects"; 16081 e->usage = 16082 "Usage: sip show objects\n" 16083 " Lists status of known SIP objects\n"; 16084 return NULL; 16085 case CLI_GENERATE: 16086 return NULL; 16087 } 16088 16089 if (a->argc != 3) 16090 return CLI_SHOWUSAGE; 16091 ast_cli(a->fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs); 16092 ao2_t_callback(peers, OBJ_NODATA, peer_dump_func, a, "initiate ao2_callback to dump peers"); 16093 ast_cli(a->fd, "-= Registry objects: %d =-\n\n", regobjs); 16094 ASTOBJ_CONTAINER_DUMP(a->fd, tmp, sizeof(tmp), ®l); 16095 ast_cli(a->fd, "-= Dialog objects:\n\n"); 16096 ao2_t_callback(dialogs, OBJ_NODATA, dialog_dump_func, a, "initiate ao2_callback to dump dialogs"); 16097 return CLI_SUCCESS; 16098 }
| 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 16457 of file chan_sip.c.
References _sip_show_peer(), ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, complete_sip_show_peer(), ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.
16458 { 16459 switch (cmd) { 16460 case CLI_INIT: 16461 e->command = "sip show peer"; 16462 e->usage = 16463 "Usage: sip show peer <name> [load]\n" 16464 " Shows all details on one SIP peer and the current status.\n" 16465 " Option \"load\" forces lookup of peer in realtime storage.\n"; 16466 return NULL; 16467 case CLI_GENERATE: 16468 return complete_sip_show_peer(a->line, a->word, a->pos, a->n); 16469 } 16470 return _sip_show_peer(0, a->fd, NULL, NULL, a->argc, (const char **) a->argv); 16471 }
| 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 15849 of file chan_sip.c.
References _sip_show_peers(), ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.
15850 { 15851 switch (cmd) { 15852 case CLI_INIT: 15853 e->command = "sip show peers"; 15854 e->usage = 15855 "Usage: sip show peers [like <pattern>]\n" 15856 " Lists all known SIP peers.\n" 15857 " Optional regular expression pattern is used to filter the peer list.\n"; 15858 return NULL; 15859 case CLI_GENERATE: 15860 return NULL; 15861 } 15862 15863 return _sip_show_peers(a->fd, NULL, NULL, NULL, a->argc, (const char **) a->argv); 15864 }
| 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 16975 of file chan_sip.c.
References ast_cli_args::argc, ast_cli(), ast_localtime(), ast_strftime(), ast_strlen_zero(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, FORMAT, FORMAT2, regl, regstate2str(), and ast_cli_entry::usage.
16976 { 16977 #define FORMAT2 "%-39.39s %-6.6s %-12.12s %8.8s %-20.20s %-25.25s\n" 16978 #define FORMAT "%-39.39s %-6.6s %-12.12s %8d %-20.20s %-25.25s\n" 16979 char host[80]; 16980 char user[80]; 16981 char tmpdat[256]; 16982 struct ast_tm tm; 16983 int counter = 0; 16984 16985 switch (cmd) { 16986 case CLI_INIT: 16987 e->command = "sip show registry"; 16988 e->usage = 16989 "Usage: sip show registry\n" 16990 " Lists all registration requests and status.\n"; 16991 return NULL; 16992 case CLI_GENERATE: 16993 return NULL; 16994 } 16995 16996 if (a->argc != 3) 16997 return CLI_SHOWUSAGE; 16998 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Refresh", "State", "Reg.Time"); 16999 17000 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 17001 ASTOBJ_RDLOCK(iterator); 17002 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); 17003 snprintf(user, sizeof(user), "%s", iterator->username); 17004 if (!ast_strlen_zero(iterator->regdomain)) { 17005 snprintf(tmpdat, sizeof(tmpdat), "%s", user); 17006 snprintf(user, sizeof(user), "%s@%s", tmpdat, iterator->regdomain);} 17007 if (iterator->regdomainport) { 17008 snprintf(tmpdat, sizeof(tmpdat), "%s", user); 17009 snprintf(user, sizeof(user), "%s:%d", tmpdat, iterator->regdomainport);} 17010 if (iterator->regtime.tv_sec) { 17011 ast_localtime(&iterator->regtime, &tm, NULL); 17012 ast_strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm); 17013 } else 17014 tmpdat[0] = '\0'; 17015 ast_cli(a->fd, FORMAT, host, (iterator->dnsmgr) ? "Y" : "N", user, iterator->refresh, regstate2str(iterator->regstate), tmpdat); 17016 ASTOBJ_UNLOCK(iterator); 17017 counter++; 17018 } while(0)); 17019 ast_cli(a->fd, "%d SIP registrations.\n", counter); 17020 return CLI_SUCCESS; 17021 #undef FORMAT 17022 #undef FORMAT2 17023 }
| static char * sip_show_sched | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 16932 of file chan_sip.c.
References __sip_autodestruct(), ast_cli(), ast_sched_report(), ast_str_alloca, auto_congest(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, expire_register(), ast_cli_args::fd, retrans_pkt(), sip_poke_noanswer(), sip_poke_peer_s(), sip_reg_timeout(), sip_reinvite_retry(), sip_reregister(), and ast_cli_entry::usage.
16933 { 16934 struct ast_str *cbuf; 16935 struct ast_cb_names cbnames = {9, { "retrans_pkt", 16936 "__sip_autodestruct", 16937 "expire_register", 16938 "auto_congest", 16939 "sip_reg_timeout", 16940 "sip_poke_peer_s", 16941 "sip_poke_noanswer", 16942 "sip_reregister", 16943 "sip_reinvite_retry"}, 16944 { retrans_pkt, 16945 __sip_autodestruct, 16946 expire_register, 16947 auto_congest, 16948 sip_reg_timeout, 16949 sip_poke_peer_s, 16950 sip_poke_noanswer, 16951 sip_reregister, 16952 sip_reinvite_retry}}; 16953 16954 switch (cmd) { 16955 case CLI_INIT: 16956 e->command = "sip show sched"; 16957 e->usage = 16958 "Usage: sip show sched\n" 16959 " Shows stats on what's in the sched queue at the moment\n"; 16960 return NULL; 16961 case CLI_GENERATE: 16962 return NULL; 16963 } 16964 16965 cbuf = ast_str_alloca(2048); 16966 16967 ast_cli(a->fd, "\n"); 16968 ast_sched_report(sched, &cbuf, &cbnames); 16969 ast_cli(a->fd, "%s", cbuf->str); 16970 16971 return CLI_SUCCESS; 16972 }
| 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 17155 of file chan_sip.c.
References ast_ha::addr, ast_cli_args::argc, ast_check_realtime(), ast_cli(), AST_CLI_ONOFF, AST_CLI_YESNO, ast_getformatname_multiple(), AST_JB_ENABLED, AST_JB_FORCED, AST_JB_LOG, AST_LIST_EMPTY, ast_sockaddr_is_any(), ast_sockaddr_is_ipv6(), ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_tos2str(), authl, bindaddr, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, default_callerid, default_expiry, default_fromdomain, default_fromdomainport, default_language, default_maxcallbitrate, default_mohinterpret, default_mohsuggest, default_notifymime, default_prefs, default_primary_transport, default_qualify, default_tls_cfg, default_transports, default_vmexten, dtmfmode2str(), ast_tls_config::enabled, externaddr, externhost, externrefresh, FALSE, faxec2str(), ast_cli_args::fd, get_transport(), get_transport_list(), global_authfailureevents, global_autoframing, global_callcounter, global_cos_audio, global_cos_sip, global_cos_text, global_cos_video, global_flags, global_jbconf, global_match_auth_username, global_max_se, global_min_se, global_prematuremediafilter, global_qualifyfreq, 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_t1, global_t1min, global_t38_maxdatagram, global_timer_b, global_tos_audio, global_tos_sip, global_tos_text, global_tos_video, global_useragent, ast_jb_conf::impl, ast_tcptls_session_args::local_address, localaddr, max_expiry, ast_jb_conf::max_size, min_expiry, ast_ha::netmask, ast_ha::next, prefix, print_codec_to_cli(), recordhistory, ast_jb_conf::resync_threshold, S_OR, sip_cfg, sip_tcp_desc, sip_tls_desc, stmode2str(), strefresher2str(), transfermode2str(), and ast_cli_entry::usage.
17156 { 17157 int realtimepeers; 17158 int realtimeregs; 17159 char codec_buf[SIPBUFSIZE]; 17160 const char *msg; /* temporary msg pointer */ 17161 17162 switch (cmd) { 17163 case CLI_INIT: 17164 e->command = "sip show settings"; 17165 e->usage = 17166 "Usage: sip show settings\n" 17167 " Provides detailed list of the configuration of the SIP channel.\n"; 17168 return NULL; 17169 case CLI_GENERATE: 17170 return NULL; 17171 } 17172 17173 17174 realtimepeers = ast_check_realtime("sippeers"); 17175 realtimeregs = ast_check_realtime("sipregs"); 17176 17177 if (a->argc != 3) 17178 return CLI_SHOWUSAGE; 17179 ast_cli(a->fd, "\n\nGlobal Settings:\n"); 17180 ast_cli(a->fd, "----------------\n"); 17181 ast_cli(a->fd, " UDP Bindaddress: %s\n", ast_sockaddr_stringify(&bindaddr)); 17182 if (ast_sockaddr_is_ipv6(&bindaddr) && ast_sockaddr_is_any(&bindaddr)) { 17183 ast_cli(a->fd, " ** Additional Info:\n"); 17184 ast_cli(a->fd, " [::] may include IPv4 in addition to IPv6, if such a feature is enabled in the OS.\n"); 17185 } 17186 ast_cli(a->fd, " TCP SIP Bindaddress: %s\n", 17187 sip_cfg.tcp_enabled != FALSE ? 17188 ast_sockaddr_stringify(&sip_tcp_desc.local_address) : 17189 "Disabled"); 17190 ast_cli(a->fd, " TLS SIP Bindaddress: %s\n", 17191 default_tls_cfg.enabled != FALSE ? 17192 ast_sockaddr_stringify(&sip_tls_desc.local_address) : 17193 "Disabled"); 17194 ast_cli(a->fd, " Videosupport: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT))); 17195 ast_cli(a->fd, " Textsupport: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_TEXTSUPPORT))); 17196 ast_cli(a->fd, " Ignore SDP sess. ver.: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_IGNORESDPVERSION))); 17197 ast_cli(a->fd, " AutoCreate Peer: %s\n", AST_CLI_YESNO(sip_cfg.autocreatepeer)); 17198 ast_cli(a->fd, " Match Auth Username: %s\n", AST_CLI_YESNO(global_match_auth_username)); 17199 ast_cli(a->fd, " Allow unknown access: %s\n", AST_CLI_YESNO(sip_cfg.allowguest)); 17200 ast_cli(a->fd, " Allow subscriptions: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))); 17201 ast_cli(a->fd, " Allow overlap dialing: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP))); 17202 ast_cli(a->fd, " Allow promsic. redir: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_PROMISCREDIR))); 17203 ast_cli(a->fd, " Enable call counters: %s\n", AST_CLI_YESNO(global_callcounter)); 17204 ast_cli(a->fd, " SIP domain support: %s\n", AST_CLI_YESNO(!AST_LIST_EMPTY(&domain_list))); 17205 ast_cli(a->fd, " Realm. auth: %s\n", AST_CLI_YESNO(authl != NULL)); 17206 ast_cli(a->fd, " Our auth realm %s\n", sip_cfg.realm); 17207 ast_cli(a->fd, " Use domains as realms: %s\n", AST_CLI_YESNO(sip_cfg.domainsasrealm)); 17208 ast_cli(a->fd, " Call to non-local dom.: %s\n", AST_CLI_YESNO(sip_cfg.allow_external_domains)); 17209 ast_cli(a->fd, " URI user is phone no: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_USEREQPHONE))); 17210 ast_cli(a->fd, " Always auth rejects: %s\n", AST_CLI_YESNO(sip_cfg.alwaysauthreject)); 17211 ast_cli(a->fd, " Direct RTP setup: %s\n", AST_CLI_YESNO(sip_cfg.directrtpsetup)); 17212 ast_cli(a->fd, " User Agent: %s\n", global_useragent); 17213 ast_cli(a->fd, " SDP Session Name: %s\n", ast_strlen_zero(global_sdpsession) ? "-" : global_sdpsession); 17214 ast_cli(a->fd, " SDP Owner Name: %s\n", ast_strlen_zero(global_sdpowner) ? "-" : global_sdpowner); 17215 ast_cli(a->fd, " Reg. context: %s\n", S_OR(sip_cfg.regcontext, "(not set)")); 17216 ast_cli(a->fd, " Regexten on Qualify: %s\n", AST_CLI_YESNO(sip_cfg.regextenonqualify)); 17217 ast_cli(a->fd, " Caller ID: %s\n", default_callerid); 17218 if ((default_fromdomainport) && (default_fromdomainport != STANDARD_SIP_PORT)) { 17219 ast_cli(a->fd, " From: Domain: %s:%d\n", default_fromdomain, default_fromdomainport); 17220 } else { 17221 ast_cli(a->fd, " From: Domain: %s\n", default_fromdomain); 17222 } 17223 ast_cli(a->fd, " Record SIP history: %s\n", AST_CLI_ONOFF(recordhistory)); 17224 ast_cli(a->fd, " Call Events: %s\n", AST_CLI_ONOFF(sip_cfg.callevents)); 17225 ast_cli(a->fd, " Auth. Failure Events: %s\n", AST_CLI_ONOFF(global_authfailureevents)); 17226 17227 ast_cli(a->fd, " T.38 support: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT))); 17228 ast_cli(a->fd, " T.38 EC mode: %s\n", faxec2str(ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT))); 17229 ast_cli(a->fd, " T.38 MaxDtgrm: %d\n", global_t38_maxdatagram); 17230 if (!realtimepeers && !realtimeregs) 17231 ast_cli(a->fd, " SIP realtime: Disabled\n" ); 17232 else 17233 ast_cli(a->fd, " SIP realtime: Enabled\n" ); 17234 ast_cli(a->fd, " Qualify Freq : %d ms\n", global_qualifyfreq); 17235 ast_cli(a->fd, " Q.850 Reason header: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_Q850_REASON))); 17236 ast_cli(a->fd, "\nNetwork QoS Settings:\n"); 17237 ast_cli(a->fd, "---------------------------\n"); 17238 ast_cli(a->fd, " IP ToS SIP: %s\n", ast_tos2str(global_tos_sip)); 17239 ast_cli(a->fd, " IP ToS RTP audio: %s\n", ast_tos2str(global_tos_audio)); 17240 ast_cli(a->fd, " IP ToS RTP video: %s\n", ast_tos2str(global_tos_video)); 17241 ast_cli(a->fd, " IP ToS RTP text: %s\n", ast_tos2str(global_tos_text)); 17242 ast_cli(a->fd, " 802.1p CoS SIP: %d\n", global_cos_sip); 17243 ast_cli(a->fd, " 802.1p CoS RTP audio: %d\n", global_cos_audio); 17244 ast_cli(a->fd, " 802.1p CoS RTP video: %d\n", global_cos_video); 17245 ast_cli(a->fd, " 802.1p CoS RTP text: %d\n", global_cos_text); 17246 ast_cli(a->fd, " Jitterbuffer enabled: %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_ENABLED))); 17247 ast_cli(a->fd, " Jitterbuffer forced: %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_FORCED))); 17248 ast_cli(a->fd, " Jitterbuffer max size: %ld\n", global_jbconf.max_size); 17249 ast_cli(a->fd, " Jitterbuffer resync: %ld\n", global_jbconf.resync_threshold); 17250 ast_cli(a->fd, " Jitterbuffer impl: %s\n", global_jbconf.impl); 17251 ast_cli(a->fd, " Jitterbuffer log: %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_LOG))); 17252 17253 ast_cli(a->fd, "\nNetwork Settings:\n"); 17254 ast_cli(a->fd, "---------------------------\n"); 17255 /* determine if/how SIP address can be remapped */ 17256 if (localaddr == NULL) 17257 msg = "Disabled, no localnet list"; 17258 else if (ast_sockaddr_isnull(&externaddr)) 17259 msg = "Disabled"; 17260 else if (!ast_strlen_zero(externhost)) 17261 msg = "Enabled using externhost"; 17262 else 17263 msg = "Enabled using externaddr"; 17264 ast_cli(a->fd, " SIP address remapping: %s\n", msg); 17265 ast_cli(a->fd, " Externhost: %s\n", S_OR(externhost, "<none>")); 17266 ast_cli(a->fd, " externaddr: %s\n", ast_sockaddr_stringify(&externaddr)); 17267 ast_cli(a->fd, " Externrefresh: %d\n", externrefresh); 17268 { 17269 struct ast_ha *d; 17270 const char *prefix = "Localnet:"; 17271 17272 for (d = localaddr; d ; prefix = "", d = d->next) { 17273 const char *addr = ast_strdupa(ast_sockaddr_stringify_addr(&d->addr)); 17274 const char *mask = ast_strdupa(ast_sockaddr_stringify_addr(&d->netmask)); 17275 ast_cli(a->fd, " %-24s%s/%s\n", prefix, addr, mask); 17276 } 17277 } 17278 ast_cli(a->fd, "\nGlobal Signalling Settings:\n"); 17279 ast_cli(a->fd, "---------------------------\n"); 17280 ast_cli(a->fd, " Codecs: "); 17281 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, sip_cfg.capability); 17282 ast_cli(a->fd, "%s\n", codec_buf); 17283 ast_cli(a->fd, " Codec Order: "); 17284 print_codec_to_cli(a->fd, &default_prefs); 17285 ast_cli(a->fd, "\n"); 17286 ast_cli(a->fd, " Relax DTMF: %s\n", AST_CLI_YESNO(global_relaxdtmf)); 17287 ast_cli(a->fd, " RFC2833 Compensation: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE))); 17288 ast_cli(a->fd, " Symmetric RTP: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_SYMMETRICRTP))); 17289 ast_cli(a->fd, " Compact SIP headers: %s\n", AST_CLI_YESNO(sip_cfg.compactheaders)); 17290 ast_cli(a->fd, " RTP Keepalive: %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" ); 17291 ast_cli(a->fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" ); 17292 ast_cli(a->fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)"); 17293 ast_cli(a->fd, " MWI NOTIFY mime type: %s\n", default_notifymime); 17294 ast_cli(a->fd, " DNS SRV lookup: %s\n", AST_CLI_YESNO(sip_cfg.srvlookup)); 17295 ast_cli(a->fd, " Pedantic SIP support: %s\n", AST_CLI_YESNO(sip_cfg.pedanticsipchecking)); 17296 ast_cli(a->fd, " Reg. min duration %d secs\n", min_expiry); 17297 ast_cli(a->fd, " Reg. max duration: %d secs\n", max_expiry); 17298 ast_cli(a->fd, " Reg. default duration: %d secs\n", default_expiry); 17299 ast_cli(a->fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout); 17300 ast_cli(a->fd, " Outbound reg. attempts: %d\n", global_regattempts_max); 17301 ast_cli(a->fd, " Notify ringing state: %s\n", AST_CLI_YESNO(sip_cfg.notifyringing)); 17302 if (sip_cfg.notifyringing) { 17303 ast_cli(a->fd, " Include CID: %s%s\n", 17304 AST_CLI_YESNO(sip_cfg.notifycid), 17305 sip_cfg.notifycid == IGNORE_CONTEXT ? " (Ignoring context)" : ""); 17306 } 17307 ast_cli(a->fd, " Notify hold state: %s\n", AST_CLI_YESNO(sip_cfg.notifyhold)); 17308 ast_cli(a->fd, " SIP Transfer mode: %s\n", transfermode2str(sip_cfg.allowtransfer)); 17309 ast_cli(a->fd, " Max Call Bitrate: %d kbps\n", default_maxcallbitrate); 17310 ast_cli(a->fd, " Auto-Framing: %s\n", AST_CLI_YESNO(global_autoframing)); 17311 ast_cli(a->fd, " Outb. proxy: %s %s\n", ast_strlen_zero(sip_cfg.outboundproxy.name) ? "<not set>" : sip_cfg.outboundproxy.name, 17312 sip_cfg.outboundproxy.force ? "(forced)" : ""); 17313 ast_cli(a->fd, " Session Timers: %s\n", stmode2str(global_st_mode)); 17314 ast_cli(a->fd, " Session Refresher: %s\n", strefresher2str (global_st_refresher)); 17315 ast_cli(a->fd, " Session Expires: %d secs\n", global_max_se); 17316 ast_cli(a->fd, " Session Min-SE: %d secs\n", global_min_se); 17317 ast_cli(a->fd, " Timer T1: %d\n", global_t1); 17318 ast_cli(a->fd, " Timer T1 minimum: %d\n", global_t1min); 17319 ast_cli(a->fd, " Timer B: %d\n", global_timer_b); 17320 ast_cli(a->fd, " No premature media: %s\n", AST_CLI_YESNO(global_prematuremediafilter)); 17321 ast_cli(a->fd, " Max forwards: %d\n", sip_cfg.default_max_forwards); 17322 17323 ast_cli(a->fd, "\nDefault Settings:\n"); 17324 ast_cli(a->fd, "-----------------\n"); 17325 ast_cli(a->fd, " Allowed transports: %s\n", get_transport_list(default_transports)); 17326 ast_cli(a->fd, " Outbound transport: %s\n", get_transport(default_primary_transport)); 17327 ast_cli(a->fd, " Context: %s\n", sip_cfg.default_context); 17328 ast_cli(a->fd, " Force rport: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_NAT_FORCE_RPORT))); 17329 ast_cli(a->fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF))); 17330 ast_cli(a->fd, " Qualify: %d\n", default_qualify); 17331 ast_cli(a->fd, " Use ClientCode: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_USECLIENTCODE))); 17332 ast_cli(a->fd, " Progress inband: %s\n", (ast_test_flag(&global_flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER) ? "Never" : (AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_NO))); 17333 ast_cli(a->fd, " Language: %s\n", default_language); 17334 ast_cli(a->fd, " MOH Interpret: %s\n", default_mohinterpret); 17335 ast_cli(a->fd, " MOH Suggest: %s\n", default_mohsuggest); 17336 ast_cli(a->fd, " Voice Mail Extension: %s\n", default_vmexten); 17337 17338 17339 if (realtimepeers || realtimeregs) { 17340 ast_cli(a->fd, "\nRealtime SIP Settings:\n"); 17341 ast_cli(a->fd, "----------------------\n"); 17342 ast_cli(a->fd, " Realtime Peers: %s\n", AST_CLI_YESNO(realtimepeers)); 17343 ast_cli(a->fd, " Realtime Regs: %s\n", AST_CLI_YESNO(realtimeregs)); 17344 ast_cli(a->fd, " Cache Friends: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS))); 17345 ast_cli(a->fd, " Update: %s\n", AST_CLI_YESNO(sip_cfg.peer_rtupdate)); 17346 ast_cli(a->fd, " Ignore Reg. Expire: %s\n", AST_CLI_YESNO(sip_cfg.ignore_regexpire)); 17347 ast_cli(a->fd, " Save sys. name: %s\n", AST_CLI_YESNO(sip_cfg.rtsave_sysname)); 17348 ast_cli(a->fd, " Auto Clear: %d (%s)\n", sip_cfg.rtautoclear, ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR) ? "Enabled" : "Disabled"); 17349 } 17350 ast_cli(a->fd, "\n----\n"); 17351 return CLI_SUCCESS; 17352 }
| 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 15664 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ao2_t_ref, ast_cli_args::argc, ast_cli(), ast_sockaddr_stringify(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, FORMAT, FORMAT2, get_transport(), threadt, and ast_cli_entry::usage.
15665 { 15666 struct sip_threadinfo *th; 15667 struct ao2_iterator i; 15668 15669 #define FORMAT2 "%-47.47s %9.9s %6.6s\n" 15670 #define FORMAT "%-47.47s %-9.9s %-6.6s\n" 15671 15672 switch (cmd) { 15673 case CLI_INIT: 15674 e->command = "sip show tcp"; 15675 e->usage = 15676 "Usage: sip show tcp\n" 15677 " Lists all active TCP/TLS sessions.\n"; 15678 return NULL; 15679 case CLI_GENERATE: 15680 return NULL; 15681 } 15682 15683 if (a->argc != 3) 15684 return CLI_SHOWUSAGE; 15685 15686 ast_cli(a->fd, FORMAT2, "Address", "Transport", "Type"); 15687 15688 i = ao2_iterator_init(threadt, 0); 15689 while ((th = ao2_t_iterator_next(&i, "iterate through tcp threads for 'sip show tcp'"))) { 15690 ast_cli(a->fd, FORMAT, 15691 ast_sockaddr_stringify(&th->tcptls_session->remote_address), 15692 get_transport(th->type), 15693 (th->tcptls_session->client ? "Client" : "Server")); 15694 ao2_t_ref(th, -1, "decrement ref from iterator"); 15695 } 15696 ao2_iterator_destroy(&i); 15697 15698 return CLI_SUCCESS; 15699 #undef FORMAT 15700 #undef FORMAT2 15701 }
| 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 16856 of file chan_sip.c.
References ao2_lock, ao2_unlock, ast_cli_args::argc, ast_cli_args::argv, ast_callerid_merge(), ast_cdr_flags2str(), ast_cli(), AST_CLI_YESNO, ast_describe_caller_presentation(), ast_strlen_zero(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sip_show_user(), FALSE, ast_cli_args::fd, find_peer(), ast_cli_args::line, ast_cli_args::n, ast_variable::name, ast_variable::next, ast_cli_args::pos, print_codec_to_cli(), print_group(), stmode2str(), strefresher2str(), transfermode2str(), TRUE, unref_peer(), ast_cli_entry::usage, ast_variable::value, and ast_cli_args::word.
16857 { 16858 char cbuf[256]; 16859 struct sip_peer *user; 16860 struct ast_variable *v; 16861 int load_realtime; 16862 16863 switch (cmd) { 16864 case CLI_INIT: 16865 e->command = "sip show user"; 16866 e->usage = 16867 "Usage: sip show user <name> [load]\n" 16868 " Shows all details on one SIP user and the current status.\n" 16869 " Option \"load\" forces lookup of peer in realtime storage.\n"; 16870 return NULL; 16871 case CLI_GENERATE: 16872 return complete_sip_show_user(a->line, a->word, a->pos, a->n); 16873 } 16874 16875 if (a->argc < 4) 16876 return CLI_SHOWUSAGE; 16877 16878 /* Load from realtime storage? */ 16879 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? TRUE : FALSE; 16880 16881 if ((user = find_peer(a->argv[3], NULL, load_realtime, FINDUSERS, FALSE, 0))) { 16882 ao2_lock(user); 16883 ast_cli(a->fd, "\n\n"); 16884 ast_cli(a->fd, " * Name : %s\n", user->name); 16885 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>"); 16886 ast_cli(a->fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>"); 16887 ast_cli(a->fd, " Context : %s\n", user->context); 16888 ast_cli(a->fd, " Language : %s\n", user->language); 16889 if (!ast_strlen_zero(user->accountcode)) 16890 ast_cli(a->fd, " Accountcode : %s\n", user->accountcode); 16891 ast_cli(a->fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); 16892 ast_cli(a->fd, " Transfer mode: %s\n", transfermode2str(user->allowtransfer)); 16893 ast_cli(a->fd, " MaxCallBR : %d kbps\n", user->maxcallbitrate); 16894 ast_cli(a->fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); 16895 ast_cli(a->fd, " Call limit : %d\n", user->call_limit); 16896 ast_cli(a->fd, " Callgroup : "); 16897 print_group(a->fd, user->callgroup, 0); 16898 ast_cli(a->fd, " Pickupgroup : "); 16899 print_group(a->fd, user->pickupgroup, 0); 16900 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>")); 16901 ast_cli(a->fd, " ACL : %s\n", AST_CLI_YESNO(user->ha != NULL)); 16902 ast_cli(a->fd, " Sess-Timers : %s\n", stmode2str(user->stimer.st_mode_oper)); 16903 ast_cli(a->fd, " Sess-Refresh : %s\n", strefresher2str(user->stimer.st_ref)); 16904 ast_cli(a->fd, " Sess-Expires : %d secs\n", user->stimer.st_max_se); 16905 ast_cli(a->fd, " Sess-Min-SE : %d secs\n", user->stimer.st_min_se); 16906 ast_cli(a->fd, " RTP Engine : %s\n", user->engine); 16907 16908 ast_cli(a->fd, " Codec Order : ("); 16909 print_codec_to_cli(a->fd, &user->prefs); 16910 ast_cli(a->fd, ")\n"); 16911 16912 ast_cli(a->fd, " Auto-Framing: %s \n", AST_CLI_YESNO(user->autoframing)); 16913 if (user->chanvars) { 16914 ast_cli(a->fd, " Variables :\n"); 16915 for (v = user->chanvars ; v ; v = v->next) 16916 ast_cli(a->fd, " %s = %s\n", v->name, v->value); 16917 } 16918 16919 ast_cli(a->fd, "\n"); 16920 16921 ao2_unlock(user); 16922 unref_peer(user, "sip show user"); 16923 } else { 16924 ast_cli(a->fd, "User %s not found.\n", a->argv[3]); 16925 ast_cli(a->fd, "\n"); 16926 } 16927 16928 return CLI_SUCCESS; 16929 }
| 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 15704 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_unlock, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_CLI_YESNO, ast_test_flag, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, FALSE, ast_cli_args::fd, FORMAT, TRUE, unref_peer(), and ast_cli_entry::usage.
15705 { 15706 regex_t regexbuf; 15707 int havepattern = FALSE; 15708 struct ao2_iterator user_iter; 15709 struct sip_peer *user; 15710 15711 #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" 15712 15713 switch (cmd) { 15714 case CLI_INIT: 15715 e->command = "sip show users"; 15716 e->usage = 15717 "Usage: sip show users [like <pattern>]\n" 15718 " Lists all known SIP users.\n" 15719 " Optional regular expression pattern is used to filter the user list.\n"; 15720 return NULL; 15721 case CLI_GENERATE: 15722 return NULL; 15723 } 15724 15725 switch (a->argc) { 15726 case 5: 15727 if (!strcasecmp(a->argv[3], "like")) { 15728 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB)) 15729 return CLI_SHOWUSAGE; 15730 havepattern = TRUE; 15731 } else 15732 return CLI_SHOWUSAGE; 15733 case 3: 15734 break; 15735 default: 15736 return CLI_SHOWUSAGE; 15737 } 15738 15739 ast_cli(a->fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "ForcerPort"); 15740 15741 user_iter = ao2_iterator_init(peers, 0); 15742 while ((user = ao2_iterator_next(&user_iter))) { 15743 ao2_lock(user); 15744 if (!(user->type & SIP_TYPE_USER)) { 15745 ao2_unlock(user); 15746 unref_peer(user, "sip show users"); 15747 continue; 15748 } 15749 15750 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) { 15751 ao2_unlock(user); 15752 unref_peer(user, "sip show users"); 15753 continue; 15754 } 15755 15756 ast_cli(a->fd, FORMAT, user->name, 15757 user->secret, 15758 user->accountcode, 15759 user->context, 15760 AST_CLI_YESNO(user->ha != NULL), 15761 AST_CLI_YESNO(ast_test_flag(&user->flags[0], SIP_NAT_FORCE_RPORT))); 15762 ao2_unlock(user); 15763 unref_peer(user, "sip show users"); 15764 } 15765 ao2_iterator_destroy(&user_iter); 15766 15767 if (havepattern) 15768 regfree(®exbuf); 15769 15770 return CLI_SUCCESS; 15771 #undef FORMAT 15772 }
| static int sip_sipredirect | ( | struct sip_pvt * | p, | |
| const char * | dest | |||
| ) | [static] |
Transfer call before connect with a 302 redirect.
Definition at line 28177 of file chan_sip.c.
References AST_CONTROL_TRANSFER, ast_copy_string(), ast_log(), ast_queue_control_data(), ast_strdupa, ast_string_field_build, ast_strlen_zero(), AST_TRANSFER_SUCCESS, get_header(), LOG_ERROR, sip_alreadygone(), sip_scheddestroy(), strcasestr(), strsep(), and transmit_response_reliable().
Referenced by sip_transfer().
28178 { 28179 char *cdest; 28180 char *extension, *domain; 28181 28182 cdest = ast_strdupa(dest); 28183 28184 extension = strsep(&cdest, "@"); 28185 domain = strsep(&cdest, ":"); 28186 if (ast_strlen_zero(extension)) { 28187 ast_log(LOG_ERROR, "Missing mandatory argument: extension\n"); 28188 return 0; 28189 } 28190 28191 /* we'll issue the redirect message here */ 28192 if (!domain) { 28193 char *local_to_header; 28194 char to_header[256]; 28195 28196 ast_copy_string(to_header, get_header(&p->initreq, "To"), sizeof(to_header)); 28197 if (ast_strlen_zero(to_header)) { 28198 ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n"); 28199 return 0; 28200 } 28201 if (((local_to_header = strcasestr(to_header, "sip:")) || (local_to_header = strcasestr(to_header, "sips:"))) 28202 && (local_to_header = strchr(local_to_header, '@'))) { 28203 char ldomain[256]; 28204 28205 memset(ldomain, 0, sizeof(ldomain)); 28206 local_to_header++; 28207 /* This is okey because lhost and lport are as big as tmp */ 28208 sscanf(local_to_header, "%256[^<>; ]", ldomain); 28209 if (ast_strlen_zero(ldomain)) { 28210 ast_log(LOG_ERROR, "Can't find the host address\n"); 28211 return 0; 28212 } 28213 domain = ast_strdupa(ldomain); 28214 } 28215 } 28216 28217 ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s>", extension, domain); 28218 transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq); 28219 28220 sip_scheddestroy(p, SIP_TRANS_TIMEOUT); /* Make sure we stop send this reply. */ 28221 sip_alreadygone(p); 28222 28223 if (p->owner) { 28224 enum ast_control_transfer message = AST_TRANSFER_SUCCESS; 28225 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 28226 } 28227 /* hangup here */ 28228 return 0; 28229 }
| static struct sip_st_dlg * sip_st_alloc | ( | struct sip_pvt *const | p | ) | [static] |
Allocate Session-Timers struct w/in dialog.
Definition at line 7219 of file chan_sip.c.
References ast_calloc, ast_log(), and LOG_ERROR.
Referenced by handle_request_invite(), and st_get_mode().
07220 { 07221 struct sip_st_dlg *stp; 07222 07223 if (p->stimer) { 07224 ast_log(LOG_ERROR, "Session-Timer struct already allocated\n"); 07225 return p->stimer; 07226 } 07227 07228 if (!(stp = ast_calloc(1, sizeof(struct sip_st_dlg)))) 07229 return NULL; 07230 07231 p->stimer = stp; 07232 07233 stp->st_schedid = -1; /* Session-Timers ast_sched scheduler id */ 07234 07235 return p->stimer; 07236 }
| static int sip_standard_port | ( | enum sip_transport | type, | |
| int | port | |||
| ) | [static] |
Returns the port to use for this socket.
| type | The type of transport used | |
| port | Port we are checking to see if it's the standard port. |
Definition at line 24327 of file chan_sip.c.
Referenced by initreqprep(), and transmit_notify_with_mwi().
24328 { 24329 if (type & SIP_TRANSPORT_TLS) 24330 return port == STANDARD_TLS_PORT; 24331 else 24332 return port == STANDARD_SIP_PORT; 24333 }
| 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 7801 of file chan_sip.c.
References ast_calloc_with_stringfields, ast_copy_string(), ast_log(), ast_string_field_set, ast_strlen_zero(), ASTOBJ_CONTAINER_LINK, ASTOBJ_INIT, ASTOBJ_UNREF, hostname, LOG_WARNING, mailbox, secret, sip_subscribe_mwi_destroy(), and submwil.
07802 { 07803 struct sip_subscription_mwi *mwi; 07804 int portnum = 0; 07805 enum sip_transport transport = SIP_TRANSPORT_UDP; 07806 char buf[256] = ""; 07807 char *username = NULL, *hostname = NULL, *secret = NULL, *authuser = NULL, *porta = NULL, *mailbox = NULL, *at = NULL; 07808 07809 if (!value) { 07810 return -1; 07811 } 07812 07813 ast_copy_string(buf, value, sizeof(buf)); 07814 07815 if (!(at = strstr(buf, "@"))) { 07816 return -1; 07817 } 07818 07819 if ((hostname = strrchr(buf, '@'))) { 07820 *hostname++ = '\0'; 07821 username = buf; 07822 } 07823 07824 if ((secret = strchr(username, ':'))) { 07825 *secret++ = '\0'; 07826 if ((authuser = strchr(secret, ':'))) { 07827 *authuser++ = '\0'; 07828 } 07829 } 07830 07831 if ((mailbox = strchr(hostname, '/'))) { 07832 *mailbox++ = '\0'; 07833 } 07834 07835 if (ast_strlen_zero(username) || ast_strlen_zero(hostname) || ast_strlen_zero(mailbox)) { 07836 ast_log(LOG_WARNING, "Format for MWI subscription is user[:secret[:authuser]]@host[:port]/mailbox at line %d\n", lineno); 07837 return -1; 07838 } 07839 07840 if ((porta = strchr(hostname, ':'))) { 07841 *porta++ = '\0'; 07842 if (!(portnum = atoi(porta))) { 07843 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 07844 return -1; 07845 } 07846 } 07847 07848 if (!(mwi = ast_calloc_with_stringfields(1, struct sip_subscription_mwi, 256))) { 07849 return -1; 07850 } 07851 07852 ASTOBJ_INIT(mwi); 07853 ast_string_field_set(mwi, username, username); 07854 if (secret) { 07855 ast_string_field_set(mwi, secret, secret); 07856 } 07857 if (authuser) { 07858 ast_string_field_set(mwi, authuser, authuser); 07859 } 07860 ast_string_field_set(mwi, hostname, hostname); 07861 ast_string_field_set(mwi, mailbox, mailbox); 07862 mwi->resub = -1; 07863 mwi->portno = portnum; 07864 mwi->transport = transport; 07865 07866 ASTOBJ_CONTAINER_LINK(&submwil, mwi); 07867 ASTOBJ_UNREF(mwi, sip_subscribe_mwi_destroy); 07868 07869 return 0; 07870 }
| static void sip_subscribe_mwi_destroy | ( | struct sip_subscription_mwi * | mwi | ) | [static] |
Destroy MWI subscription object.
Definition at line 5439 of file chan_sip.c.
References ast_dnsmgr_release(), ast_free, AST_SCHED_DEL, ast_string_field_free_memory, and sip_destroy().
Referenced by handle_response_subscribe(), sip_send_all_mwi_subscriptions(), sip_subscribe_mwi(), sip_subscribe_mwi_do(), and unload_module().
05440 { 05441 if (mwi->call) { 05442 mwi->call->mwi = NULL; 05443 sip_destroy(mwi->call); 05444 } 05445 05446 AST_SCHED_DEL(sched, mwi->resub); 05447 ast_string_field_free_memory(mwi); 05448 ast_dnsmgr_release(mwi->dnsmgr); 05449 ast_free(mwi); 05450 }
| static int sip_subscribe_mwi_do | ( | const void * | data | ) | [static] |
Send a subscription or resubscription for MWI.
Definition at line 11747 of file chan_sip.c.
References __sip_subscribe_mwi_do(), ASTOBJ_UNREF, and sip_subscribe_mwi_destroy().
Referenced by handle_response_subscribe(), and sip_send_all_mwi_subscriptions().
11748 { 11749 struct sip_subscription_mwi *mwi = (struct sip_subscription_mwi*)data; 11750 11751 if (!mwi) { 11752 return -1; 11753 } 11754 11755 mwi->resub = -1; 11756 __sip_subscribe_mwi_do(mwi); 11757 ASTOBJ_UNREF(mwi, sip_subscribe_mwi_destroy); 11758 11759 return 0; 11760 }
| static int sip_t38_abort | ( | const void * | data | ) | [static] |
Called to deny a T38 reinvite if the core does not respond to our request.
Definition at line 21061 of file chan_sip.c.
References change_t38_state(), sip_pvt_lock, sip_pvt_unlock, and transmit_response_reliable().
Referenced by handle_request_invite().
21062 { 21063 struct sip_pvt *p = (struct sip_pvt *) data; 21064 21065 sip_pvt_lock(p); 21066 /* an application may have taken ownership of the T.38 negotiation on this 21067 * channel while we were waiting to grab the lock... if it did, the scheduler 21068 * id will have been reset to -1, which is our indication that we do *not* 21069 * want to abort the negotiation process 21070 */ 21071 if (p->t38id != -1) { 21072 change_t38_state(p, T38_DISABLED); 21073 transmit_response_reliable(p, "488 Not acceptable here", &p->initreq); 21074 p->t38id = -1; 21075 dialog_unref(p, "unref the dialog ptr from sip_t38_abort, because it held a dialog ptr"); 21076 } 21077 sip_pvt_unlock(p); 21078 return 0; 21079 }
| static struct ast_tcptls_session_instance* sip_tcp_locate | ( | struct ast_sockaddr * | s | ) | [static] |
Find thread for TCP/TLS session (based on IP/Port.
Definition at line 24352 of file chan_sip.c.
References ao2_callback, ao2_ref, ao2_t_ref, threadinfo_locate_cb(), and threadt.
Referenced by sip_prepare_socket().
24353 { 24354 struct sip_threadinfo *th; 24355 struct ast_tcptls_session_instance *tcptls_instance = NULL; 24356 24357 if ((th = ao2_callback(threadt, 0, threadinfo_locate_cb, s))) { 24358 tcptls_instance = (ao2_ref(th->tcptls_session, +1), th->tcptls_session); 24359 ao2_t_ref(th, -1, "decrement ref from callback"); 24360 } 24361 24362 return tcptls_instance; 24363 }
| static void * sip_tcp_worker_fn | ( | void * | ) | [static] |
SIP TCP connection handler.
Definition at line 2438 of file chan_sip.c.
References _sip_tcp_helper_thread().
Referenced by sip_prepare_socket().
02439 { 02440 struct ast_tcptls_session_instance *tcptls_session = data; 02441 02442 return _sip_tcp_helper_thread(NULL, tcptls_session); 02443 }
| static void sip_tcptls_client_args_destructor | ( | void * | obj | ) | [static] |
Definition at line 2320 of file chan_sip.c.
References args, and ast_free.
Referenced by sip_prepare_socket().
02321 { 02322 struct ast_tcptls_session_args *args = obj; 02323 if (args->tls_cfg) { 02324 ast_free(args->tls_cfg->certfile); 02325 ast_free(args->tls_cfg->pvtfile); 02326 ast_free(args->tls_cfg->cipher); 02327 ast_free(args->tls_cfg->cafile); 02328 ast_free(args->tls_cfg->capath); 02329 } 02330 ast_free(args->tls_cfg); 02331 ast_free((char *) args->name); 02332 }
| 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 2380 of file chan_sip.c.
References ao2_alloc, ao2_lock, ao2_t_find, ao2_t_ref, ao2_unlock, AST_LIST_INSERT_TAIL, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_str_create(), ast_str_set(), errno, ast_tcptls_session_instance::fd, ast_tcptls_session_instance::lock, LOG_ERROR, OBJ_POINTER, tcptls_packet_destructor(), and threadt.
Referenced by __sip_xmit().
02381 { 02382 int res = len; 02383 struct sip_threadinfo *th = NULL; 02384 struct tcptls_packet *packet = NULL; 02385 struct sip_threadinfo tmp = { 02386 .tcptls_session = tcptls_session, 02387 }; 02388 enum sip_tcptls_alert alert = TCPTLS_ALERT_DATA; 02389 02390 if (!tcptls_session) { 02391 return XMIT_ERROR; 02392 } 02393 02394 ast_mutex_lock(&tcptls_session->lock); 02395 02396 if ((tcptls_session->fd == -1) || 02397 !(th = ao2_t_find(threadt, &tmp, OBJ_POINTER, "ao2_find, getting sip_threadinfo in tcp helper thread")) || 02398 !(packet = ao2_alloc(sizeof(*packet), tcptls_packet_destructor)) || 02399 !(packet->data = ast_str_create(len))) { 02400 goto tcptls_write_setup_error; 02401 } 02402 02403 /* goto tcptls_write_error should _NOT_ be used beyond this point */ 02404 ast_str_set(&packet->data, 0, "%s", (char *) buf); 02405 packet->len = len; 02406 02407 /* alert tcptls thread handler that there is a packet to be sent. 02408 * must lock the thread info object to guarantee control of the 02409 * packet queue */ 02410 ao2_lock(th); 02411 if (write(th->alert_pipe[1], &alert, sizeof(alert)) == -1) { 02412 ast_log(LOG_ERROR, "write() to alert pipe failed: %s\n", strerror(errno)); 02413 ao2_t_ref(packet, -1, "could not write to alert pipe, remove packet"); 02414 packet = NULL; 02415 res = XMIT_ERROR; 02416 } else { /* it is safe to queue the frame after issuing the alert when we hold the threadinfo lock */ 02417 AST_LIST_INSERT_TAIL(&th->packet_q, packet, entry); 02418 } 02419 ao2_unlock(th); 02420 02421 ast_mutex_unlock(&tcptls_session->lock); 02422 ao2_t_ref(th, -1, "In sip_tcptls_write, unref threadinfo object after finding it"); 02423 return res; 02424 02425 tcptls_write_setup_error: 02426 if (th) { 02427 ao2_t_ref(th, -1, "In sip_tcptls_write, unref threadinfo obj, could not create packet"); 02428 } 02429 if (packet) { 02430 ao2_t_ref(packet, -1, "could not allocate packet's data"); 02431 } 02432 ast_mutex_unlock(&tcptls_session->lock); 02433 02434 return XMIT_ERROR; 02435 }
| 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 2356 of file chan_sip.c.
References ao2_alloc, ao2_t_link, ao2_t_ref, ast_log(), errno, LOG_ERROR, sip_threadinfo_destructor(), ast_tcptls_session_instance::ssl, and threadt.
Referenced by _sip_tcp_helper_thread(), and sip_prepare_socket().
02357 { 02358 struct sip_threadinfo *th; 02359 02360 if (!tcptls_session || !(th = ao2_alloc(sizeof(*th), sip_threadinfo_destructor))) { 02361 return NULL; 02362 } 02363 02364 th->alert_pipe[0] = th->alert_pipe[1] = -1; 02365 02366 if (pipe(th->alert_pipe) == -1) { 02367 ao2_t_ref(th, -1, "Failed to open alert pipe on sip_threadinfo"); 02368 ast_log(LOG_ERROR, "Could not create sip alert pipe in tcptls thread, error %s\n", strerror(errno)); 02369 return NULL; 02370 } 02371 ao2_t_ref(tcptls_session, +1, "tcptls_session ref for sip_threadinfo object"); 02372 th->tcptls_session = tcptls_session; 02373 th->type = transport ? transport : (tcptls_session->ssl ? SIP_TRANSPORT_TLS: SIP_TRANSPORT_TCP); 02374 ao2_t_link(threadt, th, "Adding new tcptls helper thread"); 02375 ao2_t_ref(th, -1, "Decrementing threadinfo ref from alloc, only table ref remains"); 02376 return th; 02377 }
| static void sip_threadinfo_destructor | ( | void * | obj | ) | [static] |
Definition at line 2334 of file chan_sip.c.
References ao2_t_ref, and AST_LIST_REMOVE_HEAD.
Referenced by sip_threadinfo_create().
02335 { 02336 struct sip_threadinfo *th = obj; 02337 struct tcptls_packet *packet; 02338 if (th->alert_pipe[1] > -1) { 02339 close(th->alert_pipe[0]); 02340 } 02341 if (th->alert_pipe[1] > -1) { 02342 close(th->alert_pipe[1]); 02343 } 02344 th->alert_pipe[0] = th->alert_pipe[1] = -1; 02345 02346 while ((packet = AST_LIST_REMOVE_HEAD(&th->packet_q, entry))) { 02347 ao2_t_ref(packet, -1, "thread destruction, removing packet from frame queue"); 02348 } 02349 02350 if (th->tcptls_session) { 02351 ao2_t_ref(th->tcptls_session, -1, "remove tcptls_session for sip_threadinfo object"); 02352 } 02353 }
| static int sip_transfer | ( | struct ast_channel * | ast, | |
| const char * | dest | |||
| ) | [static] |
Transfer SIP call.
Definition at line 6409 of file chan_sip.c.
References ast_channel::_state, AST_STATE_RING, sip_pvt_lock, sip_pvt_unlock, sip_sipredirect(), ast_channel::tech_pvt, and transmit_refer().
06410 { 06411 struct sip_pvt *p = ast->tech_pvt; 06412 int res; 06413 06414 if (dest == NULL) /* functions below do not take a NULL */ 06415 dest = ""; 06416 sip_pvt_lock(p); 06417 if (ast->_state == AST_STATE_RING) 06418 res = sip_sipredirect(p, dest); 06419 else 06420 res = transmit_refer(p, dest); 06421 sip_pvt_unlock(p); 06422 return res; 06423 }
| static char * sip_unregister | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Unregister (force expiration) a SIP peer in the registry via CLI.
Definition at line 17029 of file chan_sip.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_SCHED_DEL_UNREF, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sip_unregister(), expire_register(), ast_cli_args::fd, find_peer(), ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ref_peer(), TRUE, unref_peer(), ast_cli_entry::usage, and ast_cli_args::word.
17030 { 17031 struct sip_peer *peer; 17032 int load_realtime = 0; 17033 17034 switch (cmd) { 17035 case CLI_INIT: 17036 e->command = "sip unregister"; 17037 e->usage = 17038 "Usage: sip unregister <peer>\n" 17039 " Unregister (force expiration) a SIP peer from the registry\n"; 17040 return NULL; 17041 case CLI_GENERATE: 17042 return complete_sip_unregister(a->line, a->word, a->pos, a->n); 17043 } 17044 17045 if (a->argc != 3) 17046 return CLI_SHOWUSAGE; 17047 17048 if ((peer = find_peer(a->argv[2], NULL, load_realtime, FINDPEERS, TRUE, 0))) { 17049 if (peer->expire > 0) { 17050 AST_SCHED_DEL_UNREF(sched, peer->expire, 17051 unref_peer(peer, "remove register expire ref")); 17052 expire_register(ref_peer(peer, "ref for expire_register")); 17053 ast_cli(a->fd, "Unregistered peer \'%s\'\n\n", a->argv[2]); 17054 } else { 17055 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]); 17056 } 17057 unref_peer(peer, "sip_unregister: unref_peer via sip_unregister: done with peer from find_peer call"); 17058 } else { 17059 ast_cli(a->fd, "Peer unknown: \'%s\'. Not unregistered.\n", a->argv[2]); 17060 } 17061 17062 return CLI_SUCCESS; 17063 }
| static void sip_unregister_tests | ( | void | ) | [static] |
SIP test registration.
Definition at line 28625 of file chan_sip.c.
Referenced by unload_module().
28626 { 28627 sip_config_parser_unregister_tests(); 28628 sip_request_parser_unregister_tests(); 28629 sip_dialplan_function_unregister_tests(); 28630 }
| static int sip_write | ( | struct ast_channel * | ast, | |
| struct ast_frame * | frame | |||
| ) | [static] |
Send frame to media channel (rtp).
Definition at line 6204 of file chan_sip.c.
References ast_channel::_state, AST_FORMAT_AUDIO_MASK, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_rtp_instance_update_source(), ast_rtp_instance_write(), ast_rtp_red_buffer(), ast_set_flag, AST_STATE_UP, ast_test_flag, ast_udptl_write(), ast_frame_subclass::codec, ast_frame::frametype, global_prematuremediafilter, LOG_WARNING, ast_channel::nativeformats, ast_channel::readformat, sip_pvt_lock, sip_pvt_unlock, ast_frame::subclass, ast_channel::tech_pvt, transmit_provisional_response(), TRUE, and ast_channel::writeformat.
06205 { 06206 struct sip_pvt *p = ast->tech_pvt; 06207 int res = 0; 06208 06209 switch (frame->frametype) { 06210 case AST_FRAME_VOICE: 06211 if (!(frame->subclass.codec & ast->nativeformats)) { 06212 char s1[512], s2[512], s3[512]; 06213 ast_log(LOG_WARNING, "Asked to transmit frame type %s, while native formats is %s read/write = %s/%s\n", 06214 ast_getformatname(frame->subclass.codec), 06215 ast_getformatname_multiple(s1, sizeof(s1), ast->nativeformats & AST_FORMAT_AUDIO_MASK), 06216 ast_getformatname_multiple(s2, sizeof(s2), ast->readformat), 06217 ast_getformatname_multiple(s3, sizeof(s3), ast->writeformat)); 06218 return 0; 06219 } 06220 if (p) { 06221 sip_pvt_lock(p); 06222 if (p->rtp) { 06223 /* If channel is not up, activate early media session */ 06224 if ((ast->_state != AST_STATE_UP) && 06225 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 06226 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06227 ast_rtp_instance_update_source(p->rtp); 06228 if (!global_prematuremediafilter) { 06229 p->invitestate = INV_EARLY_MEDIA; 06230 transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE); 06231 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 06232 } 06233 } else if (p->t38.state == T38_ENABLED) { 06234 /* drop frame, can't sent VOICE frames while in T.38 mode */ 06235 } else { 06236 p->lastrtptx = time(NULL); 06237 res = ast_rtp_instance_write(p->rtp, frame); 06238 } 06239 } 06240 sip_pvt_unlock(p); 06241 } 06242 break; 06243 case AST_FRAME_VIDEO: 06244 if (p) { 06245 sip_pvt_lock(p); 06246 if (p->vrtp) { 06247 /* Activate video early media */ 06248 if ((ast->_state != AST_STATE_UP) && 06249 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 06250 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06251 p->invitestate = INV_EARLY_MEDIA; 06252 transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE); 06253 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 06254 } 06255 p->lastrtptx = time(NULL); 06256 res = ast_rtp_instance_write(p->vrtp, frame); 06257 } 06258 sip_pvt_unlock(p); 06259 } 06260 break; 06261 case AST_FRAME_TEXT: 06262 if (p) { 06263 sip_pvt_lock(p); 06264 if (p->red) { 06265 ast_rtp_red_buffer(p->trtp, frame); 06266 } else { 06267 if (p->trtp) { 06268 /* Activate text early media */ 06269 if ((ast->_state != AST_STATE_UP) && 06270 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 06271 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06272 p->invitestate = INV_EARLY_MEDIA; 06273 transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE); 06274 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 06275 } 06276 p->lastrtptx = time(NULL); 06277 res = ast_rtp_instance_write(p->trtp, frame); 06278 } 06279 } 06280 sip_pvt_unlock(p); 06281 } 06282 break; 06283 case AST_FRAME_IMAGE: 06284 return 0; 06285 break; 06286 case AST_FRAME_MODEM: 06287 if (p) { 06288 sip_pvt_lock(p); 06289 /* UDPTL requires two-way communication, so early media is not needed here. 06290 we simply forget the frames if we get modem frames before the bridge is up. 06291 Fax will re-transmit. 06292 */ 06293 if ((ast->_state == AST_STATE_UP) && 06294 p->udptl && 06295 (p->t38.state == T38_ENABLED)) { 06296 res = ast_udptl_write(p->udptl, frame); 06297 } 06298 sip_pvt_unlock(p); 06299 } 06300 break; 06301 default: 06302 ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype); 06303 return 0; 06304 } 06305 06306 return res; 06307 }
| static int sipsock_read | ( | int * | id, | |
| int | fd, | |||
| short | events, | |||
| void * | ignore | |||
| ) | [static] |
Read data from SIP UDP socket.
Definition at line 24161 of file chan_sip.c.
References AST_DYNSTR_BUILD_FAILED, ast_log(), ast_recvfrom(), ast_sockaddr_port, ast_str_create(), ast_str_set(), ast_str_strlen(), bindaddr, deinit_req(), errno, handle_request_do(), LOG_NOTICE, LOG_WARNING, set_socket_transport(), and sipsock.
Referenced by do_monitor().
24162 { 24163 struct sip_request req; 24164 struct ast_sockaddr addr; 24165 int res; 24166 static char readbuf[65535]; 24167 24168 memset(&req, 0, sizeof(req)); 24169 res = ast_recvfrom(fd, readbuf, sizeof(readbuf) - 1, 0, &addr); 24170 if (res < 0) { 24171 #if !defined(__FreeBSD__) 24172 if (errno == EAGAIN) 24173 ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n"); 24174 else 24175 #endif 24176 if (errno != ECONNREFUSED) 24177 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 24178 return 1; 24179 } 24180 24181 readbuf[res] = '\0'; 24182 24183 if (!(req.data = ast_str_create(SIP_MIN_PACKET))) { 24184 return 1; 24185 } 24186 24187 if (ast_str_set(&req.data, 0, "%s", readbuf) == AST_DYNSTR_BUILD_FAILED) { 24188 return -1; 24189 } 24190 24191 /* req.data will have the correct length in case of nulls */ 24192 req.len = ast_str_strlen(req.data); 24193 req.socket.fd = sipsock; 24194 set_socket_transport(&req.socket, SIP_TRANSPORT_UDP); 24195 req.socket.tcptls_session = NULL; 24196 req.socket.port = htons(ast_sockaddr_port(&bindaddr)); 24197 24198 handle_request_do(&req, &addr); 24199 deinit_req(&req); 24200 24201 return 1; 24202 }
| enum st_mode st_get_mode | ( | struct sip_pvt * | p | ) | [static] |
Get the session-timer mode.
| p | pointer to the SIP dialog |
Definition at line 25047 of file chan_sip.c.
References global_st_mode, and sip_st_alloc().
Referenced by add_supported_header(), handle_request_invite(), handle_response_invite(), and transmit_invite().
25048 { 25049 if (!p->stimer) 25050 sip_st_alloc(p); 25051 25052 if (p->stimer->st_cached_mode != SESSION_TIMER_MODE_INVALID) 25053 return p->stimer->st_cached_mode; 25054 25055 if (p->relatedpeer) { 25056 p->stimer->st_cached_mode = p->relatedpeer->stimer.st_mode_oper; 25057 return p->stimer->st_cached_mode; 25058 } 25059 25060 p->stimer->st_cached_mode = global_st_mode; 25061 return global_st_mode; 25062 }
| enum st_refresher st_get_refresher | ( | struct sip_pvt * | p | ) | [static] |
Get the entity (UAC or UAS) that's acting as the session-timer refresher.
| p | pointer to the SIP dialog |
Definition at line 25029 of file chan_sip.c.
References global_st_refresher.
Referenced by handle_request_invite().
25030 { 25031 if (p->stimer->st_cached_ref != SESSION_TIMER_REFRESHER_AUTO) 25032 return p->stimer->st_cached_ref; 25033 25034 if (p->relatedpeer) { 25035 p->stimer->st_cached_ref = p->relatedpeer->stimer.st_ref; 25036 return p->stimer->st_cached_ref; 25037 } 25038 25039 p->stimer->st_cached_ref = global_st_refresher; 25040 return global_st_refresher; 25041 }
| int st_get_se | ( | struct sip_pvt * | p, | |
| int | max | |||
| ) | [static] |
Get Max or Min SE (session timer expiry).
| p | pointer to the SIP dialog | |
| max | if true, get max se, otherwise min se |
Definition at line 25000 of file chan_sip.c.
References global_max_se, global_min_se, and TRUE.
Referenced by handle_request_invite(), reqprep(), and transmit_invite().
25001 { 25002 if (max == TRUE) { 25003 if (p->stimer->st_cached_max_se) { 25004 return p->stimer->st_cached_max_se; 25005 } 25006 if (p->relatedpeer) { 25007 p->stimer->st_cached_max_se = p->relatedpeer->stimer.st_max_se; 25008 return (p->stimer->st_cached_max_se); 25009 } 25010 p->stimer->st_cached_max_se = global_max_se; 25011 return (p->stimer->st_cached_max_se); 25012 } 25013 /* Find Min SE timer */ 25014 if (p->stimer->st_cached_min_se) { 25015 return p->stimer->st_cached_min_se; 25016 } 25017 if (p->relatedpeer) { 25018 p->stimer->st_cached_min_se = p->relatedpeer->stimer.st_min_se; 25019 return (p->stimer->st_cached_min_se); 25020 } 25021 p->stimer->st_cached_min_se = global_min_se; 25022 return (p->stimer->st_cached_min_se); 25023 }
| static void start_session_timer | ( | struct sip_pvt * | p | ) | [static] |
Session-Timers: Start session timer.
Definition at line 24797 of file chan_sip.c.
References ast_debug, ast_log(), ast_sched_add(), LOG_ERROR, LOG_WARNING, and proc_session_timer().
Referenced by handle_request_invite(), handle_response_invite(), and restart_session_timer().
24798 { 24799 if (!p->stimer) { 24800 ast_log(LOG_WARNING, "Null stimer in start_session_timer - %s\n", p->callid); 24801 return; 24802 } 24803 24804 p->stimer->st_schedid = ast_sched_add(sched, p->stimer->st_interval * 1000 / 2, proc_session_timer, 24805 dialog_ref(p, "adding session timer ref")); 24806 if (p->stimer->st_schedid < 0) { 24807 dialog_unref(p, "removing session timer ref"); 24808 ast_log(LOG_ERROR, "ast_sched_add failed.\n"); 24809 } 24810 ast_debug(2, "Session timer started: %d - %s\n", p->stimer->st_schedid, p->callid); 24811 }
| static void state_notify_build_xml | ( | int | state, | |
| int | full, | |||
| const char * | exten, | |||
| const char * | context, | |||
| struct ast_str ** | tmp, | |||
| struct sip_pvt * | p, | |||
| int | subscribed, | |||
| const char * | mfrom, | |||
| const char * | mto | |||
| ) | [static] |
Builds XML portion of NOTIFY messages for presence or dialog updates.
Definition at line 11859 of file chan_sip.c.
References ast_channel_callback(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_device_state(), AST_DEVICE_UNAVAILABLE, AST_EXTENSION_BUSY, AST_EXTENSION_INUSE, AST_EXTENSION_NOT_INUSE, AST_EXTENSION_ONHOLD, AST_EXTENSION_RINGING, AST_EXTENSION_UNAVAILABLE, ast_get_hint(), AST_MAX_EXTENSION, ast_str_append(), ast_strdupa, ast_channel::caller, cid_num, find_calling_channel(), ast_party_caller::id, ast_party_id::name, NONE, ast_party_id::number, S_COR, sip_cfg, ast_party_name::str, ast_party_number::str, strsep(), ast_party_name::valid, and ast_party_number::valid.
Referenced by transmit_state_notify().
11860 { 11861 enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN; 11862 const char *statestring = "terminated"; 11863 const char *pidfstate = "--"; 11864 const char *pidfnote= "Ready"; 11865 char hint[AST_MAX_EXTENSION]; 11866 11867 switch (state) { 11868 case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE): 11869 statestring = (sip_cfg.notifyringing) ? "early" : "confirmed"; 11870 local_state = NOTIFY_INUSE; 11871 pidfstate = "busy"; 11872 pidfnote = "Ringing"; 11873 break; 11874 case AST_EXTENSION_RINGING: 11875 statestring = "early"; 11876 local_state = NOTIFY_INUSE; 11877 pidfstate = "busy"; 11878 pidfnote = "Ringing"; 11879 break; 11880 case AST_EXTENSION_INUSE: 11881 statestring = "confirmed"; 11882 local_state = NOTIFY_INUSE; 11883 pidfstate = "busy"; 11884 pidfnote = "On the phone"; 11885 break; 11886 case AST_EXTENSION_BUSY: 11887 statestring = "confirmed"; 11888 local_state = NOTIFY_CLOSED; 11889 pidfstate = "busy"; 11890 pidfnote = "On the phone"; 11891 break; 11892 case AST_EXTENSION_UNAVAILABLE: 11893 statestring = "terminated"; 11894 local_state = NOTIFY_CLOSED; 11895 pidfstate = "away"; 11896 pidfnote = "Unavailable"; 11897 break; 11898 case AST_EXTENSION_ONHOLD: 11899 statestring = "confirmed"; 11900 local_state = NOTIFY_CLOSED; 11901 pidfstate = "busy"; 11902 pidfnote = "On hold"; 11903 break; 11904 case AST_EXTENSION_NOT_INUSE: 11905 default: 11906 /* Default setting */ 11907 break; 11908 } 11909 11910 /* Check which device/devices we are watching and if they are registered */ 11911 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten)) { 11912 char *hint2 = hint, *individual_hint = NULL; 11913 int hint_count = 0, unavailable_count = 0; 11914 11915 while ((individual_hint = strsep(&hint2, "&"))) { 11916 hint_count++; 11917 11918 if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE) 11919 unavailable_count++; 11920 } 11921 11922 /* If none of the hinted devices are registered, we will 11923 * override notification and show no availability. 11924 */ 11925 if (hint_count > 0 && hint_count == unavailable_count) { 11926 local_state = NOTIFY_CLOSED; 11927 pidfstate = "away"; 11928 pidfnote = "Not online"; 11929 } 11930 } 11931 11932 switch (subscribed) { 11933 case XPIDF_XML: 11934 case CPIM_PIDF_XML: 11935 ast_str_append(tmp, 0, 11936 "<?xml version=\"1.0\"?>\n" 11937 "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n" 11938 "<presence>\n"); 11939 ast_str_append(tmp, 0, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom); 11940 ast_str_append(tmp, 0, "<atom id=\"%s\">\n", exten); 11941 ast_str_append(tmp, 0, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto); 11942 ast_str_append(tmp, 0, "<status status=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed"); 11943 ast_str_append(tmp, 0, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline"); 11944 ast_str_append(tmp, 0, "</address>\n</atom>\n</presence>\n"); 11945 break; 11946 case PIDF_XML: /* Eyebeam supports this format */ 11947 ast_str_append(tmp, 0, 11948 "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n" 11949 "<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); 11950 ast_str_append(tmp, 0, "<pp:person><status>\n"); 11951 if (pidfstate[0] != '-') { 11952 ast_str_append(tmp, 0, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate); 11953 } 11954 ast_str_append(tmp, 0, "</status></pp:person>\n"); 11955 ast_str_append(tmp, 0, "<note>%s</note>\n", pidfnote); /* Note */ 11956 ast_str_append(tmp, 0, "<tuple id=\"%s\">\n", exten); /* Tuple start */ 11957 ast_str_append(tmp, 0, "<contact priority=\"1\">%s</contact>\n", mto); 11958 if (pidfstate[0] == 'b') /* Busy? Still open ... */ 11959 ast_str_append(tmp, 0, "<status><basic>open</basic></status>\n"); 11960 else 11961 ast_str_append(tmp, 0, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed"); 11962 ast_str_append(tmp, 0, "</tuple>\n</presence>\n"); 11963 break; 11964 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 11965 ast_str_append(tmp, 0, "<?xml version=\"1.0\"?>"); 11966 ast_str_append(tmp, 0, "<dialog-info xmlns=\"urn:ietf:params:xml:ns:dialog-info\" version=\"%d\" state=\"%s\" entity=\"%s\">", p->dialogver, full ? "full" : "partial", mto); 11967 if ((state & AST_EXTENSION_RINGING) && sip_cfg.notifyringing) { 11968 const char *local_display = exten; 11969 char *local_target = ast_strdupa(mto); 11970 11971 /* There are some limitations to how this works. The primary one is that the 11972 callee must be dialing the same extension that is being monitored. Simply dialing 11973 the hint'd device is not sufficient. */ 11974 if (sip_cfg.notifycid) { 11975 struct ast_channel *caller; 11976 11977 if ((caller = ast_channel_callback(find_calling_channel, NULL, p, 0))) { 11978 char *cid_num; 11979 int need; 11980 11981 ast_channel_lock(caller); 11982 cid_num = S_COR(caller->caller.id.number.valid, 11983 caller->caller.id.number.str, ""); 11984 need = strlen(cid_num) + strlen(p->fromdomain) + sizeof("sip:@"); 11985 local_target = alloca(need); 11986 snprintf(local_target, need, "sip:%s@%s", cid_num, p->fromdomain); 11987 local_display = ast_strdupa(S_COR(caller->caller.id.name.valid, 11988 caller->caller.id.name.str, "")); 11989 ast_channel_unlock(caller); 11990 caller = ast_channel_unref(caller); 11991 } 11992 11993 /* We create a fake call-id which the phone will send back in an INVITE 11994 Replaces header which we can grab and do some magic with. */ 11995 if (sip_cfg.pedanticsipchecking) { 11996 ast_str_append(tmp, 0, "<dialog id=\"%s\" call-id=\"pickup-%s\" local-tag=\"%s\" remote-tag=\"%s\" direction=\"recipient\">\n", 11997 exten, p->callid, p->theirtag, p->tag); 11998 } else { 11999 ast_str_append(tmp, 0, "<dialog id=\"%s\" call-id=\"pickup-%s\" direction=\"recipient\">\n", 12000 exten, p->callid); 12001 } 12002 ast_str_append(tmp, 0, 12003 "<remote>\n" 12004 /* See the limitations of this above. Luckily the phone seems to still be 12005 happy when these values are not correct. */ 12006 "<identity display=\"%s\">%s</identity>\n" 12007 "<target uri=\"%s\"/>\n" 12008 "</remote>\n" 12009 "<local>\n" 12010 "<identity>%s</identity>\n" 12011 "<target uri=\"%s\"/>\n" 12012 "</local>\n", 12013 local_display, local_target, local_target, mto, mto); 12014 } else { 12015 ast_str_append(tmp, 0, "<dialog id=\"%s\" direction=\"recipient\">\n", exten); 12016 } 12017 12018 } else { 12019 ast_str_append(tmp, 0, "<dialog id=\"%s\">", exten); 12020 } 12021 ast_str_append(tmp, 0, "<state>%s</state>\n", statestring); 12022 if (state == AST_EXTENSION_ONHOLD) { 12023 ast_str_append(tmp, 0, "<local>\n<target uri=\"%s\">\n" 12024 "<param pname=\"+sip.rendering\" pvalue=\"no\"/>\n" 12025 "</target>\n</local>\n", mto); 12026 } 12027 ast_str_append(tmp, 0, "</dialog>\n</dialog-info>\n"); 12028 break; 12029 case NONE: 12030 default: 12031 break; 12032 } 12033 }
| static const char* stmode2str | ( | enum st_mode | m | ) | [static] |
Definition at line 15611 of file chan_sip.c.
References map_x_s(), and stmodes.
Referenced by _sip_show_peer(), sip_show_channel(), sip_show_settings(), and sip_show_user().
| static void stop_media_flows | ( | struct sip_pvt * | p | ) | [static] |
Immediately stop RTP, VRTP and UDPTL as applicable.
Definition at line 19867 of file chan_sip.c.
References ast_rtp_instance_stop(), and ast_udptl_stop().
Referenced by handle_request_bye(), handle_request_cancel(), handle_response(), and sip_hangup().
19868 { 19869 /* Immediately stop RTP, VRTP and UDPTL as applicable */ 19870 if (p->rtp) 19871 ast_rtp_instance_stop(p->rtp); 19872 if (p->vrtp) 19873 ast_rtp_instance_stop(p->vrtp); 19874 if (p->trtp) 19875 ast_rtp_instance_stop(p->trtp); 19876 if (p->udptl) 19877 ast_udptl_stop(p->udptl); 19878 }
| static void stop_session_timer | ( | struct sip_pvt * | p | ) | [static] |
Session-Timers: Stop session timer.
Definition at line 24780 of file chan_sip.c.
References ast_debug, ast_log(), AST_SCHED_DEL_UNREF, FALSE, LOG_WARNING, and TRUE.
Referenced by handle_request_bye(), proc_session_timer(), sip_hangup(), and sip_scheddestroy().
24781 { 24782 if (!p->stimer) { 24783 ast_log(LOG_WARNING, "Null stimer in stop_session_timer - %s\n", p->callid); 24784 return; 24785 } 24786 24787 if (p->stimer->st_active == TRUE) { 24788 p->stimer->st_active = FALSE; 24789 AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid, 24790 dialog_unref(p, "removing session timer ref")); 24791 ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid); 24792 } 24793 }
| static int str2dtmfmode | ( | const char * | str | ) | [static] |
| static enum st_mode str2stmode | ( | const char * | s | ) | [static] |
Definition at line 15616 of file chan_sip.c.
References map_s_x(), and stmodes.
Referenced by build_peer().
| static enum st_refresher str2strefresher | ( | const char * | s | ) | [static] |
Definition at line 15634 of file chan_sip.c.
References map_s_x(), and strefreshers.
Referenced by build_peer().
15635 { 15636 return map_s_x(strefreshers, s, -1); 15637 }
| static const char * strefresher2str | ( | enum st_refresher | r | ) | [static] |
Definition at line 15629 of file chan_sip.c.
References map_x_s(), and strefreshers.
Referenced by _sip_show_peer(), reqprep(), respprep(), sip_show_channel(), sip_show_settings(), and sip_show_user().
15630 { 15631 return map_x_s(strefreshers, r, "Unknown"); 15632 }
| static const char * subscription_type2str | ( | enum subscriptiontype | subtype | ) | [static] |
Show subscription type in string format.
Definition at line 17385 of file chan_sip.c.
References ARRAY_LEN, subscription_types, cfsubscription_types::text, and type.
Referenced by show_channels_cb(), and sip_show_channel().
17386 { 17387 int i; 17388 17389 for (i = 1; i < ARRAY_LEN(subscription_types); i++) { 17390 if (subscription_types[i].type == subtype) { 17391 return subscription_types[i].text; 17392 } 17393 } 17394 return subscription_types[0].text; 17395 }
| 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 10534 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().
10535 { 10536 switch (rate) { 10537 case AST_T38_RATE_2400: 10538 return 2400; 10539 case AST_T38_RATE_4800: 10540 return 4800; 10541 case AST_T38_RATE_7200: 10542 return 7200; 10543 case AST_T38_RATE_9600: 10544 return 9600; 10545 case AST_T38_RATE_12000: 10546 return 12000; 10547 case AST_T38_RATE_14400: 10548 return 14400; 10549 default: 10550 return 0; 10551 } 10552 }
| static void tcptls_packet_destructor | ( | void * | obj | ) | [static] |
Definition at line 2313 of file chan_sip.c.
References ast_free.
Referenced by sip_tcptls_write().
02314 { 02315 struct tcptls_packet *packet = obj; 02316 02317 ast_free(packet->data); 02318 }
| static struct sip_peer * temp_peer | ( | const char * | name | ) | [static] |
Create temporary peer (used in autocreatepeer mode).
Definition at line 25948 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_string_field_init, default_prefs, reg_source_db(), set_peer_defaults(), sip_destroy_peer_fn(), and TRUE.
Referenced by register_verify().
25949 { 25950 struct sip_peer *peer; 25951 25952 if (!(peer = ao2_t_alloc(sizeof(*peer), sip_destroy_peer_fn, "allocate a peer struct"))) 25953 return NULL; 25954 25955 if (ast_string_field_init(peer, 512)) { 25956 ao2_t_ref(peer, -1, "failed to string_field_init, drop peer"); 25957 return NULL; 25958 } 25959 25960 if (!(peer->cc_params = ast_cc_config_params_init())) { 25961 ao2_t_ref(peer, -1, "failed to allocate cc_params for peer"); 25962 return NULL; 25963 } 25964 25965 ast_atomic_fetchadd_int(&apeerobjs, 1); 25966 set_peer_defaults(peer); 25967 25968 ast_copy_string(peer->name, name, sizeof(peer->name)); 25969 25970 peer->selfdestruct = TRUE; 25971 peer->host_dynamic = TRUE; 25972 peer->prefs = default_prefs; 25973 reg_source_db(peer); 25974 25975 return peer; 25976 }
| static void temp_pvt_cleanup | ( | void * | ) | [static] |
Definition at line 9996 of file chan_sip.c.
References ast_free, and ast_string_field_free_memory.
09997 { 09998 struct sip_pvt *p = data; 09999 10000 ast_string_field_free_memory(p); 10001 10002 ast_free(data); 10003 }
| static int temp_pvt_init | ( | void * | ) | [static] |
Definition at line 9988 of file chan_sip.c.
References ast_string_field_init.
09989 { 09990 struct sip_pvt *p = data; 09991 09992 p->do_history = 0; /* XXX do we need it ? isn't already all 0 ? */ 09993 return ast_string_field_init(p, 512); 09994 }
| static char* terminate_uri | ( | char * | uri | ) | [static] |
Terminate the uri at the first ';' or space. Technically we should ignore escaped space per RFC3261 (19.1.1 etc) but don't do it for the time being. Remember the uri format is: (User-parameters was added after RFC 3261)
* * sip:user:password;user-parameters@host:port;uri-parameters?headers * sips:user:password;user-parameters@host:port;uri-parameters?headers * *
Definition at line 13983 of file chan_sip.c.
Referenced by check_user_full(), and register_verify().
13984 { 13985 char *t = uri; 13986 while (*t && *t > ' ' && *t != ';') { 13987 t++; 13988 } 13989 *t = '\0'; 13990 return uri; 13991 }
| static int threadinfo_locate_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 24335 of file chan_sip.c.
References ast_sockaddr_cmp(), CMP_MATCH, and CMP_STOP.
Referenced by sip_tcp_locate().
24336 { 24337 struct sip_threadinfo *th = obj; 24338 struct ast_sockaddr *s = arg; 24339 24340 if (!ast_sockaddr_cmp(s, &th->tcptls_session->remote_address)) { 24341 return CMP_MATCH | CMP_STOP; 24342 } 24343 24344 return 0; 24345 }
| static int threadt_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 28552 of file chan_sip.c.
References CMP_MATCH, and CMP_STOP.
Referenced by load_module().
28553 { 28554 struct sip_threadinfo *th = obj, *th2 = arg; 28555 28556 return (th->tcptls_session == th2->tcptls_session) ? CMP_MATCH | CMP_STOP : 0; 28557 }
| static int threadt_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 28545 of file chan_sip.c.
References ast_sockaddr_hash().
Referenced by load_module().
28546 { 28547 const struct sip_threadinfo *th = obj; 28548 28549 return ast_sockaddr_hash(&th->tcptls_session->remote_address); 28550 }
| static char * transfermode2str | ( | enum transfermodes | mode | ) | const [static] |
Convert transfer mode to text string.
Definition at line 15589 of file chan_sip.c.
Referenced by _sip_show_peer(), peers_data_provider_get(), sip_show_channel(), sip_show_settings(), and sip_show_user().
15590 { 15591 if (mode == TRANSFER_OPENFORALL) 15592 return "open"; 15593 else if (mode == TRANSFER_CLOSED) 15594 return "closed"; 15595 return "strict"; 15596 }
| static int transmit_cc_notify | ( | struct ast_cc_agent * | agent, | |
| struct sip_pvt * | subscription, | |||
| enum sip_cc_notify_state | state | |||
| ) | [static] |
Definition at line 12035 of file chan_sip.c.
References add_content(), add_header(), ast_log(), generate_uri(), LOG_WARNING, ast_cc_agent::private_data, reqprep(), send_request(), sip_cc_notify_state_map, state_string, and TRUE.
Referenced by sip_cc_agent_recall(), and sip_cc_agent_respond().
12036 { 12037 struct sip_request req; 12038 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 12039 char uri[SIPBUFSIZE]; 12040 char state_str[64]; 12041 12042 if (state < CC_QUEUED || state > CC_READY) { 12043 ast_log(LOG_WARNING, "Invalid state provided for transmit_cc_notify (%d)\n", state); 12044 return -1; 12045 } 12046 12047 reqprep(&req, subscription, SIP_NOTIFY, 0, TRUE); 12048 snprintf(state_str, sizeof(state_str), "%s\r\n", sip_cc_notify_state_map[state].state_string); 12049 add_header(&req, "Event", "call-completion"); 12050 add_header(&req, "Content-Type", "application/call-completion"); 12051 if (state == CC_READY) { 12052 generate_uri(subscription, agent_pvt->notify_uri, sizeof(agent_pvt->notify_uri)); 12053 snprintf(uri, sizeof(uri) - 1, "cc-URI: %s\r\n", agent_pvt->notify_uri); 12054 } 12055 add_content(&req, state_str); 12056 if (state == CC_READY) { 12057 add_content(&req, uri); 12058 } 12059 return send_request(subscription, &req, XMIT_RELIABLE, subscription->ocseq); 12060 }
| static void transmit_fake_auth_response | ( | struct sip_pvt * | p, | |
| int | sipmethod, | |||
| 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 13877 of file chan_sip.c.
References AST_DYNSTR_BUILD_FAILED, ast_skip_blanks(), ast_str_set(), ast_str_thread_get(), ast_strlen_zero(), check_auth_buf, CHECK_AUTH_BUF_INITLEN, get_header(), set_nonce_randdata(), sip_scheddestroy(), strsep(), transmit_response(), and transmit_response_with_auth().
Referenced by handle_request_invite(), handle_request_options(), handle_request_publish(), handle_request_subscribe(), and register_verify().
13878 { 13879 /* We have to emulate EXACTLY what we'd get with a good peer 13880 * and a bad password, or else we leak information. */ 13881 const char *response = "407 Proxy Authentication Required"; 13882 const char *reqheader = "Proxy-Authorization"; 13883 const char *respheader = "Proxy-Authenticate"; 13884 const char *authtoken; 13885 struct ast_str *buf; 13886 char *c; 13887 13888 /* table of recognised keywords, and their value in the digest */ 13889 enum keys { K_NONCE, K_LAST }; 13890 struct x { 13891 const char *key; 13892 const char *s; 13893 } *i, keys[] = { 13894 [K_NONCE] = { "nonce=", "" }, 13895 [K_LAST] = { NULL, NULL} 13896 }; 13897 13898 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 13899 response = "401 Unauthorized"; 13900 reqheader = "Authorization"; 13901 respheader = "WWW-Authenticate"; 13902 } 13903 authtoken = get_header(req, reqheader); 13904 if (req->ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 13905 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 13906 * information */ 13907 transmit_response_with_auth(p, response, req, p->randdata, 0, respheader, 0); 13908 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 13909 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13910 return; 13911 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 13912 /* We have no auth, so issue challenge and request authentication */ 13913 set_nonce_randdata(p, 1); 13914 transmit_response_with_auth(p, response, req, p->randdata, 0, respheader, 0); 13915 /* Schedule auto destroy in 32 seconds */ 13916 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13917 return; 13918 } 13919 13920 if (!(buf = ast_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) { 13921 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 13922 return; 13923 } 13924 13925 /* Make a copy of the response and parse it */ 13926 if (ast_str_set(&buf, 0, "%s", authtoken) == AST_DYNSTR_BUILD_FAILED) { 13927 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 13928 return; 13929 } 13930 13931 c = buf->str; 13932 13933 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 13934 for (i = keys; i->key != NULL; i++) { 13935 const char *separator = ","; /* default */ 13936 13937 if (strncasecmp(c, i->key, strlen(i->key)) != 0) { 13938 continue; 13939 } 13940 /* Found. Skip keyword, take text in quotes or up to the separator. */ 13941 c += strlen(i->key); 13942 if (*c == '"') { /* in quotes. Skip first and look for last */ 13943 c++; 13944 separator = "\""; 13945 } 13946 i->s = c; 13947 strsep(&c, separator); 13948 break; 13949 } 13950 if (i->key == NULL) { /* not found, jump after space or comma */ 13951 strsep(&c, " ,"); 13952 } 13953 } 13954 13955 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 13956 if (strcasecmp(p->randdata, keys[K_NONCE].s)) { 13957 if (!req->ignore) { 13958 set_nonce_randdata(p, 1); 13959 } 13960 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 13961 13962 /* Schedule auto destroy in 32 seconds */ 13963 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13964 } else { 13965 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 13966 } 13967 }
| 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 12830 of file chan_sip.c.
References add_header(), ast_aoc_unit_entry::amount, AST_AOC_CHARGE_CURRENCY, AST_AOC_CHARGE_FREE, AST_AOC_CHARGE_UNIT, AST_AOC_D, AST_AOC_E, ast_aoc_get_charge_type(), ast_aoc_get_currency_amount(), ast_aoc_get_currency_multiplier_decimal(), ast_aoc_get_currency_name(), ast_aoc_get_msg_type(), ast_aoc_get_unit_info(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_strlen_zero(), reqprep(), send_request(), and str.
Referenced by sip_indicate().
12831 { 12832 struct sip_request req; 12833 struct ast_str *str = ast_str_alloca(512); 12834 const struct ast_aoc_unit_entry *unit_entry = ast_aoc_get_unit_info(decoded, 0); 12835 enum ast_aoc_charge_type charging = ast_aoc_get_charge_type(decoded); 12836 12837 reqprep(&req, p, SIP_INFO, 0, 1); 12838 12839 if (ast_aoc_get_msg_type(decoded) == AST_AOC_D) { 12840 ast_str_append(&str, 0, "type=active;"); 12841 } else if (ast_aoc_get_msg_type(decoded) == AST_AOC_E) { 12842 ast_str_append(&str, 0, "type=terminated;"); 12843 } else { 12844 /* unsupported message type */ 12845 return -1; 12846 } 12847 12848 switch (charging) { 12849 case AST_AOC_CHARGE_FREE: 12850 ast_str_append(&str, 0, "free-of-charge;"); 12851 break; 12852 case AST_AOC_CHARGE_CURRENCY: 12853 ast_str_append(&str, 0, "charging;"); 12854 ast_str_append(&str, 0, "charging-info=currency;"); 12855 ast_str_append(&str, 0, "amount=%u;", ast_aoc_get_currency_amount(decoded)); 12856 ast_str_append(&str, 0, "multiplier=%s;", ast_aoc_get_currency_multiplier_decimal(decoded)); 12857 if (!ast_strlen_zero(ast_aoc_get_currency_name(decoded))) { 12858 ast_str_append(&str, 0, "currency=%s;", ast_aoc_get_currency_name(decoded)); 12859 } 12860 break; 12861 case AST_AOC_CHARGE_UNIT: 12862 ast_str_append(&str, 0, "charging;"); 12863 ast_str_append(&str, 0, "charging-info=pulse;"); 12864 if (unit_entry) { 12865 ast_str_append(&str, 0, "recorded-units=%u;", unit_entry->amount); 12866 } 12867 break; 12868 default: 12869 ast_str_append(&str, 0, "not-available;"); 12870 }; 12871 12872 add_header(&req, "AOC", ast_str_buffer(str)); 12873 12874 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 12875 }
| 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 12878 of file chan_sip.c.
References add_digit(), ast_test_flag, reqprep(), and send_request().
Referenced by sip_senddigit_end().
12879 { 12880 struct sip_request req; 12881 12882 reqprep(&req, p, SIP_INFO, 0, 1); 12883 add_digit(&req, digit, duration, (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_SHORTINFO)); 12884 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 12885 }
| static int transmit_info_with_vidupdate | ( | struct sip_pvt * | p | ) | [static] |
Send SIP INFO with video update request.
Definition at line 12888 of file chan_sip.c.
References add_vidupdate(), reqprep(), and send_request().
Referenced by sip_indicate().
12889 { 12890 struct sip_request req; 12891 12892 reqprep(&req, p, SIP_INFO, 0, 1); 12893 add_vidupdate(&req); 12894 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 12895 }
| static int transmit_invite | ( | struct sip_pvt * | p, | |
| int | sipmethod, | |||
| int | sdp, | |||
| int | init, | |||
| const char *const | explicit_uri | |||
| ) | [static] |
Build REFER/INVITE/OPTIONS/SUBSCRIBE message and transmit it.
| p | sip_pvt structure | |
| sipmethod | ||
| sdp | unknown | |
| init | 0 = Prepare request within dialog, 1= prepare request, new branch, 2= prepare new request and new dialog. do_proxy_auth calls this with init!=2 | |
| explicit_uri |
Definition at line 11580 of file chan_sip.c.
References add_content(), add_diversion_header(), add_header(), add_rpid(), add_sdp(), add_supported_header(), append_date(), ast_channel_lock, ast_channel_unlock, ast_debug, AST_LIST_TRAVERSE, ast_log(), ast_random(), ast_skip_blanks(), ast_str_buffer(), ast_str_strlen(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_var_name(), ast_var_value(), build_via(), ast_var_t::entries, FALSE, initialize_initreq(), initreqprep(), LOG_WARNING, reqprep(), send_request(), st_get_mode(), st_get_se(), TRUE, try_suggested_sip_codec(), var, and ast_channel::varshead.
Referenced by __sip_subscribe_mwi_do(), cc_handle_publish_error(), do_proxy_auth(), proc_422_rsp(), sip_call(), sip_cc_monitor_request_cc(), sip_monitor_instance_destructor(), sip_poke_peer(), and transmit_publish().
11581 { 11582 struct sip_request req; 11583 struct ast_variable *var; 11584 11585 req.method = sipmethod; 11586 if (init) {/* Bump branch even on initial requests */ 11587 p->branch ^= ast_random(); 11588 p->invite_branch = p->branch; 11589 build_via(p); 11590 } 11591 if (init > 1) { 11592 initreqprep(&req, p, sipmethod, explicit_uri); 11593 } else { 11594 /* If init=1, we should not generate a new branch. If it's 0, we need a new branch. */ 11595 reqprep(&req, p, sipmethod, 0, init ? 0 : 1); 11596 } 11597 11598 if (p->options && p->options->auth) { 11599 add_header(&req, p->options->authheader, p->options->auth); 11600 } 11601 append_date(&req); 11602 if (sipmethod == SIP_REFER) { /* Call transfer */ 11603 if (p->refer) { 11604 char buf[SIPBUFSIZE]; 11605 if (!ast_strlen_zero(p->refer->refer_to)) { 11606 add_header(&req, "Refer-To", p->refer->refer_to); 11607 } 11608 if (!ast_strlen_zero(p->refer->referred_by)) { 11609 snprintf(buf, sizeof(buf), "%s <%s>", p->refer->referred_by_name, p->refer->referred_by); 11610 add_header(&req, "Referred-By", buf); 11611 } 11612 } 11613 } else if (sipmethod == SIP_SUBSCRIBE) { 11614 char buf[SIPBUFSIZE]; 11615 if (p->subscribed == MWI_NOTIFICATION) { 11616 add_header(&req, "Event", "message-summary"); 11617 add_header(&req, "Accept", "application/simple-message-summary"); 11618 } else if (p->subscribed == CALL_COMPLETION) { 11619 add_header(&req, "Event", "call-completion"); 11620 add_header(&req, "Accept", "application/call-completion"); 11621 } 11622 snprintf(buf, sizeof(buf), "%d", p->expiry); 11623 add_header(&req, "Expires", buf); 11624 } 11625 11626 /* This new INVITE is part of an attended transfer. Make sure that the 11627 other end knows and replace the current call with this new call */ 11628 if (p->options && !ast_strlen_zero(p->options->replaces)) { 11629 add_header(&req, "Replaces", p->options->replaces); 11630 add_header(&req, "Require", "replaces"); 11631 } 11632 11633 /* Add Session-Timers related headers */ 11634 if (st_get_mode(p) == SESSION_TIMER_MODE_ORIGINATE) { 11635 char i2astr[10]; 11636 11637 if (!p->stimer->st_interval) { 11638 p->stimer->st_interval = st_get_se(p, TRUE); 11639 } 11640 11641 p->stimer->st_active = TRUE; 11642 11643 snprintf(i2astr, sizeof(i2astr), "%d", p->stimer->st_interval); 11644 add_header(&req, "Session-Expires", i2astr); 11645 snprintf(i2astr, sizeof(i2astr), "%d", st_get_se(p, FALSE)); 11646 add_header(&req, "Min-SE", i2astr); 11647 } 11648 11649 add_header(&req, "Allow", ALLOWED_METHODS); 11650 add_supported_header(p, &req); 11651 11652 if (p->options && p->options->addsipheaders && p->owner) { 11653 struct ast_channel *chan = p->owner; /* The owner channel */ 11654 struct varshead *headp; 11655 11656 ast_channel_lock(chan); 11657 11658 headp = &chan->varshead; 11659 11660 if (!headp) { 11661 ast_log(LOG_WARNING, "No Headp for the channel...ooops!\n"); 11662 } else { 11663 const struct ast_var_t *current; 11664 AST_LIST_TRAVERSE(headp, current, entries) { 11665 /* SIPADDHEADER: Add SIP header to outgoing call */ 11666 if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 11667 char *content, *end; 11668 const char *header = ast_var_value(current); 11669 char *headdup = ast_strdupa(header); 11670 11671 /* Strip of the starting " (if it's there) */ 11672 if (*headdup == '"') { 11673 headdup++; 11674 } 11675 if ((content = strchr(headdup, ':'))) { 11676 *content++ = '\0'; 11677 content = ast_skip_blanks(content); /* Skip white space */ 11678 /* Strip the ending " (if it's there) */ 11679 end = content + strlen(content) -1; 11680 if (*end == '"') { 11681 *end = '\0'; 11682 } 11683 11684 add_header(&req, headdup, content); 11685 if (sipdebug) { 11686 ast_debug(1, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content); 11687 } 11688 } 11689 } 11690 } 11691 } 11692 11693 ast_channel_unlock(chan); 11694 } 11695 if ((sipmethod == SIP_INVITE || sipmethod == SIP_UPDATE) && ast_test_flag(&p->flags[0], SIP_SENDRPID)) 11696 add_rpid(&req, p); 11697 if (sipmethod == SIP_INVITE) { 11698 add_diversion_header(&req, p); 11699 } 11700 if (sdp) { 11701 memset(p->offered_media, 0, sizeof(p->offered_media)); 11702 if (p->udptl && p->t38.state == T38_LOCAL_REINVITE) { 11703 ast_debug(1, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 11704 add_sdp(&req, p, FALSE, FALSE, TRUE); 11705 } else if (p->rtp) { 11706 try_suggested_sip_codec(p); 11707 add_sdp(&req, p, FALSE, TRUE, FALSE); 11708 } 11709 } else if (p->notify) { 11710 for (var = p->notify->headers; var; var = var->next) { 11711 add_header(&req, var->name, var->value); 11712 } 11713 if (ast_str_strlen(p->notify->content)) { 11714 add_content(&req, ast_str_buffer(p->notify->content)); 11715 } 11716 } else if (sipmethod == SIP_PUBLISH) { 11717 char expires[SIPBUFSIZE]; 11718 11719 switch (p->epa_entry->static_data->event) { 11720 case CALL_COMPLETION: 11721 snprintf(expires, sizeof(expires), "%d", p->expiry); 11722 add_header(&req, "Event", "call-completion"); 11723 add_header(&req, "Expires", expires); 11724 if (p->epa_entry->publish_type != SIP_PUBLISH_INITIAL) { 11725 add_header(&req, "SIP-If-Match", p->epa_entry->entity_tag); 11726 } 11727 11728 if (!ast_strlen_zero(p->epa_entry->body)) { 11729 add_header(&req, "Content-Type", "application/pidf+xml"); 11730 add_content(&req, p->epa_entry->body); 11731 } 11732 default: 11733 break; 11734 } 11735 } 11736 11737 if (!p->initreq.headers || init > 2) { 11738 initialize_initreq(p, &req); 11739 } 11740 if (sipmethod == SIP_INVITE || sipmethod == SIP_SUBSCRIBE) { 11741 p->lastinvite = p->ocseq; 11742 } 11743 return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq); 11744 }
| static int transmit_message_with_text | ( | struct sip_pvt * | p, | |
| const char * | text | |||
| ) | [static] |
Transmit text with SIP MESSAGE method.
Definition at line 12720 of file chan_sip.c.
References add_text(), reqprep(), and send_request().
Referenced by sip_park_thread(), and sip_sendtext().
12721 { 12722 struct sip_request req; 12723 12724 reqprep(&req, p, SIP_MESSAGE, 0, 1); 12725 add_text(&req, text); 12726 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 12727 }
| static int transmit_notify_with_mwi | ( | struct sip_pvt * | p, | |
| int | newmsgs, | |||
| int | oldmsgs, | |||
| const char * | vmexten | |||
| ) | [static] |
Notify user of messages waiting in voicemail (RFC3842).
Definition at line 12152 of file chan_sip.c.
References add_content(), add_header(), ast_sockaddr_port, ast_sockaddr_stringify_host(), ast_str_alloca, ast_str_append(), ast_test_flag, default_notifymime, default_vmexten, exten, get_transport(), initialize_initreq(), initreqprep(), ourport, S_OR, send_request(), and sip_standard_port().
Referenced by sip_send_mwi_to_peer().
12153 { 12154 struct sip_request req; 12155 struct ast_str *out = ast_str_alloca(500); 12156 int ourport = (p->fromdomainport) ? p->fromdomainport : ast_sockaddr_port(&p->ourip); 12157 const char *domain = S_OR(p->fromdomain, ast_sockaddr_stringify_host(&p->ourip)); 12158 const char *exten = S_OR(vmexten, default_vmexten); 12159 12160 initreqprep(&req, p, SIP_NOTIFY, NULL); 12161 add_header(&req, "Event", "message-summary"); 12162 add_header(&req, "Content-Type", default_notifymime); 12163 ast_str_append(&out, 0, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no"); 12164 12165 12166 if (!sip_standard_port(p->socket.type, ourport)) { 12167 if (p->socket.type == SIP_TRANSPORT_UDP) { 12168 ast_str_append(&out, 0, "Message-Account: sip:%s@%s:%d\r\n", exten, domain, ourport); 12169 } else { 12170 ast_str_append(&out, 0, "Message-Account: sip:%s@%s:%d;transport=%s\r\n", exten, domain, ourport, get_transport(p->socket.type)); 12171 } 12172 } else { 12173 if (p->socket.type == SIP_TRANSPORT_UDP) { 12174 ast_str_append(&out, 0, "Message-Account: sip:%s@%s\r\n", exten, domain); 12175 } else { 12176 ast_str_append(&out, 0, "Message-Account: sip:%s@%s;transport=%s\r\n", exten, domain, get_transport(p->socket.type)); 12177 } 12178 } 12179 /* Cisco has a bug in the SIP stack where it can't accept the 12180 (0/0) notification. This can temporarily be disabled in 12181 sip.conf with the "buggymwi" option */ 12182 ast_str_append(&out, 0, "Voice-Message: %d/%d%s\r\n", 12183 newmsgs, oldmsgs, (ast_test_flag(&p->flags[1], SIP_PAGE2_BUGGY_MWI) ? "" : " (0/0)")); 12184 12185 if (p->subscribed) { 12186 if (p->expiry) { 12187 add_header(&req, "Subscription-State", "active"); 12188 } else { /* Expired */ 12189 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 12190 } 12191 } 12192 12193 add_content(&req, out->str); 12194 12195 if (!p->initreq.headers) { 12196 initialize_initreq(p, &req); 12197 } 12198 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 12199 }
| 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 12202 of file chan_sip.c.
References add_content(), add_header(), add_supported_header(), initialize_initreq(), reqprep(), and send_request().
Referenced by handle_request_refer(), local_attended_transfer(), and sip_park_thread().
12203 { 12204 struct sip_request req; 12205 char tmp[SIPBUFSIZE/2]; 12206 12207 reqprep(&req, p, SIP_NOTIFY, 0, 1); 12208 snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq); 12209 add_header(&req, "Event", tmp); 12210 add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active"); 12211 add_header(&req, "Content-Type", "message/sipfrag;version=2.0"); 12212 add_header(&req, "Allow", ALLOWED_METHODS); 12213 add_supported_header(p, &req); 12214 12215 snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message); 12216 add_content(&req, tmp); 12217 12218 if (!p->initreq.headers) { 12219 initialize_initreq(p, &req); 12220 } 12221 12222 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 12223 }
| static int transmit_provisional_response | ( | struct sip_pvt * | p, | |
| const char * | msg, | |||
| const struct sip_request * | req, | |||
| int | with_sdp | |||
| ) | [static] |
Definition at line 10256 of file chan_sip.c.
References FALSE, transmit_response(), transmit_response_with_sdp(), and update_provisional_keepalive().
Referenced by handle_request_invite(), sip_indicate(), and sip_write().
10257 { 10258 int res; 10259 10260 if (!(res = with_sdp ? transmit_response_with_sdp(p, msg, req, XMIT_UNRELIABLE, FALSE, FALSE) : transmit_response(p, msg, req))) { 10261 p->last_provisional = msg; 10262 update_provisional_keepalive(p, with_sdp); 10263 } 10264 10265 return res; 10266 }
| 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 11536 of file chan_sip.c.
References ao2_ref, ast_set_flag, ast_sip_ouraddrfor(), create_addr(), DEFAULT_PUBLISH_EXPIRES, dialog_unlink_all(), FALSE, sip_alloc(), sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), transmit_invite(), and TRUE.
Referenced by handle_cc_notify(), sip_cc_monitor_suspend(), sip_cc_monitor_unsuspend(), and sip_monitor_instance_destructor().
11537 { 11538 struct sip_pvt *pvt; 11539 int expires; 11540 11541 epa_entry->publish_type = publish_type; 11542 11543 if (!(pvt = sip_alloc(NULL, NULL, 0, SIP_PUBLISH, NULL))) { 11544 return -1; 11545 } 11546 11547 sip_pvt_lock(pvt); 11548 11549 if (create_addr(pvt, epa_entry->destination, NULL, TRUE, NULL)) { 11550 sip_pvt_unlock(pvt); 11551 dialog_unlink_all(pvt, TRUE, TRUE); 11552 dialog_unref(pvt, "create_addr failed in transmit_publish. Unref dialog"); 11553 return -1; 11554 } 11555 ast_sip_ouraddrfor(&pvt->sa, &pvt->ourip, pvt); 11556 ast_set_flag(&pvt->flags[0], SIP_OUTGOING); 11557 expires = (publish_type == SIP_PUBLISH_REMOVE) ? 0 : DEFAULT_PUBLISH_EXPIRES; 11558 pvt->expiry = expires; 11559 11560 /* Bump refcount for sip_pvt's reference */ 11561 ao2_ref(epa_entry, +1); 11562 pvt->epa_entry = epa_entry; 11563 11564 transmit_invite(pvt, SIP_PUBLISH, FALSE, 2, explicit_uri); 11565 sip_pvt_unlock(pvt); 11566 sip_scheddestroy(pvt, DEFAULT_TRANS_TIMEOUT); 11567 dialog_unref(pvt, "Done with the sip_pvt allocated for transmitting PUBLISH"); 11568 return 0; 11569 }
| static int transmit_refer | ( | struct sip_pvt * | p, | |
| const char * | dest | |||
| ) | [static] |
Transmit SIP REFER message (initiated by the transfer() dialplan application.
Definition at line 12751 of file chan_sip.c.
References add_header(), add_supported_header(), ast_copy_string(), ast_debug, ast_log(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, FALSE, get_header(), LOG_NOTICE, reqprep(), send_request(), sip_refer_allocate(), sipdebug, and TRUE.
Referenced by sip_transfer().
12752 { 12753 struct sip_request req = { 12754 .headers = 0, 12755 }; 12756 char from[256]; 12757 const char *of; 12758 char *c; 12759 char referto[256]; 12760 char *ttag, *ftag; 12761 char *theirtag = ast_strdupa(p->theirtag); 12762 int use_tls=FALSE; 12763 12764 if (sipdebug) { 12765 ast_debug(1, "SIP transfer of %s to %s\n", p->callid, dest); 12766 } 12767 12768 /* Are we transfering an inbound or outbound call ? */ 12769 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 12770 of = get_header(&p->initreq, "To"); 12771 ttag = theirtag; 12772 ftag = p->tag; 12773 } else { 12774 of = get_header(&p->initreq, "From"); 12775 ftag = theirtag; 12776 ttag = p->tag; 12777 } 12778 12779 ast_copy_string(from, of, sizeof(from)); 12780 of = get_in_brackets(from); 12781 ast_string_field_set(p, from, of); 12782 if (!strncasecmp(of, "sip:", 4)) { 12783 of += 4; 12784 } else if (!strncasecmp(of, "sips:", 5)) { 12785 of += 5; 12786 use_tls = TRUE; 12787 } else { 12788 ast_log(LOG_NOTICE, "From address missing 'sip(s):', assuming sip:\n"); 12789 } 12790 /* Get just the username part */ 12791 if ((c = strchr(dest, '@'))) { 12792 c = NULL; 12793 } else if ((c = strchr(of, '@'))) { 12794 *c++ = '\0'; 12795 } 12796 if (c) { 12797 snprintf(referto, sizeof(referto), "<sip%s:%s@%s>", use_tls ? "s" : "", dest, c); 12798 } else { 12799 snprintf(referto, sizeof(referto), "<sip%s:%s>", use_tls ? "s" : "", dest); 12800 } 12801 12802 /* save in case we get 407 challenge */ 12803 sip_refer_allocate(p); 12804 ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to)); 12805 ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by)); 12806 p->refer->status = REFER_SENT; /* Set refer status */ 12807 12808 reqprep(&req, p, SIP_REFER, 0, 1); 12809 12810 add_header(&req, "Refer-To", referto); 12811 add_header(&req, "Allow", ALLOWED_METHODS); 12812 add_supported_header(p, &req); 12813 if (!ast_strlen_zero(p->our_contact)) { 12814 add_header(&req, "Referred-By", p->our_contact); 12815 } 12816 12817 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 12818 12819 /* We should propably wait for a NOTIFY here until we ack the transfer */ 12820 /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */ 12821 12822 /*! \todo In theory, we should hang around and wait for a reply, before 12823 returning to the dial plan here. Don't know really how that would 12824 affect the transfer() app or the pbx, but, well, to make this 12825 useful we should have a STATUS code on transfer(). 12826 */ 12827 }
| 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 12490 of file chan_sip.c.
References add_header(), add_header_max_forwards(), append_history, ast_debug, ast_dnsmgr_lookup(), ast_log(), ast_random(), ast_sched_add(), AST_SCHED_REPLACE_UNREF, ast_set_flag, ast_sip_ouraddrfor(), ast_sockaddr_port, ast_sockaddr_set_port, ast_string_field_set, ast_strlen_zero(), ast_verbose, bindaddr, build_callid_registry(), build_contact(), build_reply_digest(), build_via(), create_addr(), default_fromdomain, dialog_unlink_all(), exten, FALSE, find_peer(), get_address_family_filter(), get_srv_protocol(), get_srv_service(), global_reg_timeout, global_useragent, init_req(), initialize_initreq(), internip, ast_tcptls_session_args::local_address, LOG_NOTICE, LOG_WARNING, make_our_tag(), MAXHOSTNAMELEN, REG_STATE_AUTHSENT, REG_STATE_REGSENT, registry_addref(), registry_unref(), S_OR, send_request(), set_socket_transport(), sip_alloc(), sip_cfg, sip_debug_test_pvt(), sip_methods, sip_reg_timeout(), sip_tcp_desc, sipdebug, cfsip_methods::text, TRUE, and unref_peer().
Referenced by __sip_do_register(), do_register_auth(), handle_response_register(), and sip_reg_timeout().
12491 { 12492 struct sip_request req; 12493 char from[256]; 12494 char to[256]; 12495 char tmp[80]; 12496 char addr[80]; 12497 struct sip_pvt *p; 12498 struct sip_peer *peer = NULL; 12499 int res; 12500 int portno = 0; 12501 12502 /* exit if we are already in process with this registrar ?*/ 12503 if (r == NULL || ((auth == NULL) && (r->regstate == REG_STATE_REGSENT || r->regstate == REG_STATE_AUTHSENT))) { 12504 if (r) { 12505 ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname); 12506 } 12507 return 0; 12508 } 12509 12510 if (r->dnsmgr == NULL) { 12511 char transport[MAXHOSTNAMELEN]; 12512 peer = find_peer(r->hostname, NULL, TRUE, FINDPEERS, FALSE, 0); 12513 snprintf(transport, sizeof(transport), "_%s._%s",get_srv_service(r->transport), get_srv_protocol(r->transport)); /* have to use static get_transport function */ 12514 r->us.ss.ss_family = get_address_family_filter(&bindaddr); /* Filter address family */ 12515 ast_dnsmgr_lookup(peer ? peer->tohost : r->hostname, &r->us, &r->dnsmgr, sip_cfg.srvlookup ? transport : NULL); 12516 if (peer) { 12517 peer = unref_peer(peer, "removing peer ref for dnsmgr_lookup"); 12518 } 12519 } 12520 12521 if (r->call) { /* We have a registration */ 12522 if (!auth) { 12523 ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname); 12524 return 0; 12525 } else { 12526 p = dialog_ref(r->call, "getting a copy of the r->call dialog in transmit_register"); 12527 make_our_tag(p->tag, sizeof(p->tag)); /* create a new local tag for every register attempt */ 12528 ast_string_field_set(p, theirtag, NULL); /* forget their old tag, so we don't match tags when getting response */ 12529 } 12530 } else { 12531 /* Build callid for registration if we haven't registered before */ 12532 if (!r->callid_valid) { 12533 build_callid_registry(r, &internip, default_fromdomain); 12534 r->callid_valid = TRUE; 12535 } 12536 /* Allocate SIP dialog for registration */ 12537 if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER, NULL))) { 12538 ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n"); 12539 return 0; 12540 } 12541 12542 if (p->do_history) { 12543 append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname); 12544 } 12545 12546 /* Use port number specified if no SRV record was found */ 12547 if (!ast_sockaddr_port(&r->us) && r->portno) { 12548 ast_sockaddr_set_port(&r->us, r->portno); 12549 } 12550 12551 /* Find address to hostname */ 12552 if (create_addr(p, S_OR(r->peername, r->hostname), &r->us, 0, NULL)) { 12553 /* we have what we hope is a temporary network error, 12554 * probably DNS. We need to reschedule a registration try */ 12555 dialog_unlink_all(p, TRUE, TRUE); 12556 p = dialog_unref(p, "unref dialog after unlink_all"); 12557 if (r->timeout > -1) { 12558 AST_SCHED_REPLACE_UNREF(r->timeout, sched, global_reg_timeout * 1000, sip_reg_timeout, r, 12559 registry_unref(_data, "del for REPLACE of registry ptr"), 12560 registry_unref(r, "object ptr dec when SCHED_REPLACE add failed"), 12561 registry_addref(r,"add for REPLACE registry ptr")); 12562 ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout); 12563 } else { 12564 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, registry_addref(r, "add for REPLACE registry ptr")); 12565 ast_log(LOG_WARNING, "Probably a DNS error for registration to %s@%s, trying REGISTER again (after %d seconds)\n", r->username, r->hostname, global_reg_timeout); 12566 } 12567 r->regattempts++; 12568 return 0; 12569 } 12570 12571 /* Copy back Call-ID in case create_addr changed it */ 12572 ast_string_field_set(r, callid, p->callid); 12573 12574 if (!r->dnsmgr && r->portno) { 12575 ast_sockaddr_set_port(&p->sa, r->portno); 12576 ast_sockaddr_set_port(&p->recv, r->portno); 12577 } 12578 if (!ast_strlen_zero(p->fromdomain)) { 12579 portno = (p->fromdomainport) ? p->fromdomainport : STANDARD_SIP_PORT; 12580 } else if (!ast_strlen_zero(r->regdomain)) { 12581 portno = (r->regdomainport) ? r->regdomainport : STANDARD_SIP_PORT; 12582 } else { 12583 portno = ast_sockaddr_port(&p->sa); 12584 } 12585 12586 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */ 12587 r->call = dialog_ref(p, "copying dialog into registry r->call"); /* Save pointer to SIP dialog */ 12588 p->registry = registry_addref(r, "transmit_register: addref to p->registry in transmit_register"); /* Add pointer to registry in packet */ 12589 if (!ast_strlen_zero(r->secret)) { /* Secret (password) */ 12590 ast_string_field_set(p, peersecret, r->secret); 12591 } 12592 if (!ast_strlen_zero(r->md5secret)) 12593 ast_string_field_set(p, peermd5secret, r->md5secret); 12594 /* User name in this realm 12595 - if authuser is set, use that, otherwise use username */ 12596 if (!ast_strlen_zero(r->authuser)) { 12597 ast_string_field_set(p, peername, r->authuser); 12598 ast_string_field_set(p, authname, r->authuser); 12599 } else if (!ast_strlen_zero(r->username)) { 12600 ast_string_field_set(p, peername, r->username); 12601 ast_string_field_set(p, authname, r->username); 12602 ast_string_field_set(p, fromuser, r->username); 12603 } 12604 if (!ast_strlen_zero(r->username)) { 12605 ast_string_field_set(p, username, r->username); 12606 } 12607 /* Save extension in packet */ 12608 if (!ast_strlen_zero(r->callback)) { 12609 ast_string_field_set(p, exten, r->callback); 12610 } 12611 12612 /* Set transport and port so the correct contact is built */ 12613 set_socket_transport(&p->socket, r->transport); 12614 if (r->transport == SIP_TRANSPORT_TLS || r->transport == SIP_TRANSPORT_TCP) { 12615 p->socket.port = 12616 htons(ast_sockaddr_port(&sip_tcp_desc.local_address)); 12617 } 12618 12619 /* 12620 check which address we should use in our contact header 12621 based on whether the remote host is on the external or 12622 internal network so we can register through nat 12623 */ 12624 ast_sip_ouraddrfor(&p->sa, &p->ourip, p); 12625 build_contact(p); 12626 } 12627 12628 /* set up a timeout */ 12629 if (auth == NULL) { 12630 if (r->timeout > -1) { 12631 ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout); 12632 } 12633 AST_SCHED_REPLACE_UNREF(r->timeout, sched, global_reg_timeout * 1000, sip_reg_timeout, r, 12634 registry_unref(_data,"reg ptr unrefed from del in SCHED_REPLACE"), 12635 registry_unref(r,"reg ptr unrefed from add failure in SCHED_REPLACE"), 12636 registry_addref(r,"reg ptr reffed from add in SCHED_REPLACE")); 12637 ast_debug(1, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); 12638 } 12639 12640 snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, S_OR(r->regdomain,p->tohost), p->tag); 12641 if (!ast_strlen_zero(p->theirtag)) { 12642 snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, S_OR(r->regdomain,p->tohost), p->theirtag); 12643 } else { 12644 snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, S_OR(r->regdomain,p->tohost)); 12645 } 12646 12647 /* Fromdomain is what we are registering to, regardless of actual 12648 host name from SRV */ 12649 if (portno && portno != STANDARD_SIP_PORT) { 12650 snprintf(addr, sizeof(addr), "sip:%s:%d", S_OR(p->fromdomain,S_OR(r->regdomain,r->hostname)), portno); 12651 } else { 12652 snprintf(addr, sizeof(addr), "sip:%s", S_OR(p->fromdomain,S_OR(r->regdomain,r->hostname))); 12653 } 12654 12655 ast_string_field_set(p, uri, addr); 12656 12657 p->branch ^= ast_random(); 12658 12659 init_req(&req, sipmethod, addr); 12660 12661 /* Add to CSEQ */ 12662 snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text); 12663 p->ocseq = r->ocseq; 12664 12665 build_via(p); 12666 add_header(&req, "Via", p->via); 12667 add_header_max_forwards(p, &req); 12668 add_header(&req, "From", from); 12669 add_header(&req, "To", to); 12670 add_header(&req, "Call-ID", p->callid); 12671 add_header(&req, "CSeq", tmp); 12672 if (!ast_strlen_zero(global_useragent)) 12673 add_header(&req, "User-Agent", global_useragent); 12674 12675 if (auth) { /* Add auth header */ 12676 add_header(&req, authheader, auth); 12677 } else if (!ast_strlen_zero(r->nonce)) { 12678 char digest[1024]; 12679 12680 /* We have auth data to reuse, build a digest header. 12681 * Note, this is not always useful because some parties do not 12682 * like nonces to be reused (for good reasons!) so they will 12683 * challenge us anyways. 12684 */ 12685 if (sipdebug) { 12686 ast_debug(1, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname); 12687 } 12688 ast_string_field_set(p, realm, r->realm); 12689 ast_string_field_set(p, nonce, r->nonce); 12690 ast_string_field_set(p, domain, r->authdomain); 12691 ast_string_field_set(p, opaque, r->opaque); 12692 ast_string_field_set(p, qop, r->qop); 12693 p->noncecount = ++r->noncecount; 12694 12695 memset(digest, 0, sizeof(digest)); 12696 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 12697 add_header(&req, "Authorization", digest); 12698 } else { 12699 ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname); 12700 } 12701 } 12702 12703 snprintf(tmp, sizeof(tmp), "%d", r->expiry); 12704 add_header(&req, "Expires", tmp); 12705 add_header(&req, "Contact", p->our_contact); 12706 12707 initialize_initreq(p, &req); 12708 if (sip_debug_test_pvt(p)) { 12709 ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 12710 } 12711 r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT; 12712 r->regattempts++; /* Another attempt */ 12713 ast_debug(4, "REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname); 12714 res = send_request(p, &req, XMIT_CRITICAL, p->ocseq); 12715 dialog_unref(p, "p is finished here at the end of transmit_register"); 12716 return res; 12717 }
| static int transmit_reinvite_with_sdp | ( | struct sip_pvt * | p, | |
| int | t38version, | |||
| int | oldsdp | |||
| ) | [static] |
Transmit reinvite with SDP.
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 11242 of file chan_sip.c.
References add_header(), add_rpid(), add_sdp(), add_supported_header(), append_history, ast_set_flag, ast_test_flag, FALSE, initialize_initreq(), reqprep(), send_request(), TRUE, and try_suggested_sip_codec().
Referenced by check_pendings(), handle_response_invite(), interpret_t38_parameters(), proc_session_timer(), sip_sendhtml(), sip_set_rtp_peer(), and sip_set_udptl_peer().
11243 { 11244 struct sip_request req; 11245 11246 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 11247 11248 add_header(&req, "Allow", ALLOWED_METHODS); 11249 add_supported_header(p, &req); 11250 if (sipdebug) { 11251 if (oldsdp == TRUE) 11252 add_header(&req, "X-asterisk-Info", "SIP re-invite (Session-Timers)"); 11253 else 11254 add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)"); 11255 } 11256 11257 if (ast_test_flag(&p->flags[0], SIP_SENDRPID)) 11258 add_rpid(&req, p); 11259 11260 if (p->do_history) { 11261 append_history(p, "ReInv", "Re-invite sent"); 11262 } 11263 memset(p->offered_media, 0, sizeof(p->offered_media)); 11264 11265 try_suggested_sip_codec(p); 11266 if (t38version) { 11267 add_sdp(&req, p, oldsdp, FALSE, TRUE); 11268 } else { 11269 add_sdp(&req, p, oldsdp, TRUE, FALSE); 11270 } 11271 11272 /* Use this as the basis */ 11273 initialize_initreq(p, &req); 11274 p->lastinvite = p->ocseq; 11275 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 11276 11277 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 11278 }
| static int transmit_request | ( | struct sip_pvt * | p, | |
| int | sipmethod, | |||
| int | inc, | |||
| 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 12900 of file chan_sip.c.
References add_header(), reqprep(), and send_request().
Referenced by check_pendings(), handle_response(), handle_response_invite(), and sip_hangup().
12901 { 12902 struct sip_request resp; 12903 12904 if (sipmethod == SIP_ACK) { 12905 p->invitestate = INV_CONFIRMED; 12906 } 12907 12908 reqprep(&resp, p, sipmethod, seqno, newbranch); 12909 if (sipmethod == SIP_CANCEL && p->answered_elsewhere) { 12910 add_header(&resp, "Reason", "SIP;cause=200;text=\"Call completed elsewhere\""); 12911 } 12912 12913 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 12914 }
| static int transmit_request_with_auth | ( | struct sip_pvt * | p, | |
| int | sipmethod, | |||
| int | seqno, | |||
| enum xmittype | reliable, | |||
| int | newbranch | |||
| ) | [static] |
Transmit SIP request, auth added.
Definition at line 12932 of file chan_sip.c.
References add_header(), ast_cause2str(), ast_log(), ast_strlen_zero(), ast_test_flag, auth_headers(), build_reply_digest(), dummy(), LOG_WARNING, reqprep(), and send_request().
Referenced by __sip_autodestruct(), check_pendings(), and sip_hangup().
12933 { 12934 struct sip_request resp; 12935 12936 reqprep(&resp, p, sipmethod, seqno, newbranch); 12937 if (!ast_strlen_zero(p->realm)) { 12938 char digest[1024]; 12939 12940 memset(digest, 0, sizeof(digest)); 12941 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 12942 char *dummy, *response; 12943 enum sip_auth_type code = p->options ? p->options->auth_type : PROXY_AUTH; /* XXX force 407 if unknown */ 12944 auth_headers(code, &dummy, &response); 12945 add_header(&resp, response, digest); 12946 } else { 12947 ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid); 12948 } 12949 } 12950 /* If we are hanging up and know a cause for that, send it in clear text to make 12951 debugging easier. */ 12952 if (sipmethod == SIP_BYE) { 12953 char buf[20]; 12954 12955 if (ast_test_flag(&p->flags[1], SIP_PAGE2_Q850_REASON) && p->hangupcause) { 12956 sprintf(buf, "Q.850;cause=%i", p->hangupcause & 0x7f); 12957 add_header(&resp, "Reason", buf); 12958 } 12959 12960 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->hangupcause)); 12961 snprintf(buf, sizeof(buf), "%d", p->hangupcause); 12962 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 12963 } 12964 12965 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 12966 }
| static int transmit_response | ( | struct sip_pvt * | p, | |
| const char * | msg, | |||
| const struct sip_request * | req | |||
| ) | [static] |
Transmit response, no retransmits.
Definition at line 10059 of file chan_sip.c.
References __transmit_response().
10060 { 10061 return __transmit_response(p, msg, req, XMIT_UNRELIABLE); 10062 }
| 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 10092 of file chan_sip.c.
References __transmit_response().
Referenced by handle_incoming(), handle_invite_replaces(), handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_publish(), handle_request_subscribe(), interpret_t38_parameters(), sip_hangup(), sip_indicate(), sip_sipredirect(), and sip_t38_abort().
10093 { 10094 return __transmit_response(p, msg, req, req->ignore ? XMIT_UNRELIABLE : XMIT_CRITICAL); 10095 }
| 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 10006 of file chan_sip.c.
References __transmit_response(), ast_copy_flags, ast_log(), ast_random(), ast_sip_ouraddrfor(), ast_sockaddr_copy(), ast_string_field_init, ast_string_field_set, ast_threadstorage_get(), build_via(), copy_socket_data(), default_fromdomain, default_fromdomainport, do_setnat(), global_flags, internip, LOG_ERROR, make_our_tag(), and ts_temp_pvt.
Referenced by find_call().
10007 { 10008 struct sip_pvt *p = NULL; 10009 10010 if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) { 10011 ast_log(LOG_ERROR, "Failed to get temporary pvt\n"); 10012 return -1; 10013 } 10014 10015 /* XXX the structure may be dirty from previous usage. 10016 * Here we should state clearly how we should reinitialize it 10017 * before using it. 10018 * E.g. certainly the threadstorage should be left alone, 10019 * but other thihngs such as flags etc. maybe need cleanup ? 10020 */ 10021 10022 /* Initialize the bare minimum */ 10023 p->method = intended_method; 10024 10025 if (!addr) { 10026 ast_sockaddr_copy(&p->ourip, &internip); 10027 } else { 10028 ast_sockaddr_copy(&p->sa, addr); 10029 ast_sip_ouraddrfor(&p->sa, &p->ourip, p); 10030 } 10031 10032 p->branch = ast_random(); 10033 make_our_tag(p->tag, sizeof(p->tag)); 10034 p->ocseq = INITIAL_CSEQ; 10035 10036 if (useglobal_nat && addr) { 10037 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT_FORCE_RPORT); 10038 ast_sockaddr_copy(&p->recv, addr); 10039 do_setnat(p); 10040 } 10041 10042 ast_string_field_set(p, fromdomain, default_fromdomain); 10043 p->fromdomainport = default_fromdomainport; 10044 build_via(p); 10045 ast_string_field_set(p, callid, callid); 10046 10047 copy_socket_data(&p->socket, &req->socket); 10048 10049 /* Use this temporary pvt structure to send the message */ 10050 __transmit_response(p, msg, req, XMIT_UNRELIABLE); 10051 10052 /* Free the string fields, but not the pool space */ 10053 ast_string_field_init(p, 0); 10054 10055 return 0; 10056 }
| 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 10128 of file chan_sip.c.
References add_header(), respprep(), and send_response().
Referenced by handle_incoming(), and handle_request_options().
10129 { 10130 struct sip_request resp; 10131 respprep(&resp, p, msg, req); 10132 add_header(&resp, "Accept", "application/sdp"); 10133 return send_response(p, &resp, reliable, 0); 10134 }
| 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 10149 of file chan_sip.c.
References add_header(), append_history, ast_log(), get_header(), get_realm(), LOG_WARNING, respprep(), and send_response().
Referenced by check_auth(), and transmit_fake_auth_response().
10150 { 10151 struct sip_request resp; 10152 char tmp[512]; 10153 int seqno = 0; 10154 10155 if (reliable && (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1)) { 10156 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 10157 return -1; 10158 } 10159 /* Choose Realm */ 10160 get_realm(p, req); 10161 10162 /* Stale means that they sent us correct authentication, but 10163 based it on an old challenge (nonce) */ 10164 snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", p->realm, randdata, stale ? ", stale=true" : ""); 10165 respprep(&resp, p, msg, req); 10166 add_header(&resp, header, tmp); 10167 append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount); 10168 return send_response(p, &resp, reliable, seqno); 10169 }
| static int transmit_response_with_date | ( | struct sip_pvt * | p, | |
| const char * | msg, | |||
| const struct sip_request * | req | |||
| ) | [static] |
Append date and content length before transmitting response.
Definition at line 10119 of file chan_sip.c.
References append_date(), respprep(), and send_response().
Referenced by handle_response_subscribe(), and register_verify().
10120 { 10121 struct sip_request resp; 10122 respprep(&resp, p, msg, req); 10123 append_date(&resp); 10124 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 10125 }
| static int transmit_response_with_minexpires | ( | struct sip_pvt * | p, | |
| const char * | msg, | |||
| const struct sip_request * | req | |||
| ) | [static] |
Append Min-Expires header, content length before transmitting response.
Definition at line 10137 of file chan_sip.c.
References add_header(), min_expiry, respprep(), and send_response().
Referenced by handle_request_subscribe().
10138 { 10139 struct sip_request resp; 10140 char tmp[32]; 10141 10142 snprintf(tmp, sizeof(tmp), "%d", min_expiry); 10143 respprep(&resp, p, msg, req); 10144 add_header(&resp, "Min-Expires", tmp); 10145 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 10146 }
| 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 10075 of file chan_sip.c.
References add_header(), append_date(), respprep(), and send_response().
Referenced by handle_request_invite().
10076 { 10077 struct sip_request resp; 10078 char minse_str[20]; 10079 10080 respprep(&resp, p, msg, req); 10081 append_date(&resp); 10082 10083 snprintf(minse_str, sizeof(minse_str), "%d", minse_int); 10084 add_header(&resp, "Min-SE", minse_str); 10085 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 10086 }
| 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 10110 of file chan_sip.c.
References add_header(), respprep(), and send_response().
Referenced by handle_incoming().
10111 { 10112 struct sip_request resp; 10113 respprep(&resp, p, msg, req); 10114 add_header(&resp, "Retry-After", seconds); 10115 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 10116 }
| static int transmit_response_with_sdp | ( | struct sip_pvt * | p, | |
| const char * | msg, | |||
| const struct sip_request * | req, | |||
| enum xmittype | reliable, | |||
| int | oldsdp, | |||
| int | rpid | |||
| ) | [static] |
Used for 200 OK and 183 early media.
Definition at line 11152 of file chan_sip.c.
References add_cc_call_info_to_response(), add_rpid(), add_sdp(), ast_debug, ast_log(), ast_rtp_codecs_packetization_set(), ast_rtp_instance_activate(), ast_rtp_instance_get_codecs(), ast_test_flag, FALSE, get_header(), LOG_ERROR, LOG_WARNING, respprep(), send_response(), TRUE, and try_suggested_sip_codec().
Referenced by handle_invite_replaces(), handle_request_invite(), send_provisional_keepalive_full(), sip_answer(), and transmit_provisional_response().
11153 { 11154 struct sip_request resp; 11155 int seqno; 11156 if (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1) { 11157 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 11158 return -1; 11159 } 11160 respprep(&resp, p, msg, req); 11161 if (rpid == TRUE) { 11162 add_rpid(&resp, p); 11163 } 11164 if (ast_test_flag(&p->flags[0], SIP_OFFER_CC)) { 11165 add_cc_call_info_to_response(p, &resp); 11166 } 11167 if (p->rtp) { 11168 if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 11169 ast_debug(1, "Setting framing from config on incoming call\n"); 11170 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &p->prefs); 11171 } 11172 ast_rtp_instance_activate(p->rtp); 11173 try_suggested_sip_codec(p); 11174 if (p->t38.state == T38_ENABLED) { 11175 add_sdp(&resp, p, oldsdp, TRUE, TRUE); 11176 } else { 11177 add_sdp(&resp, p, oldsdp, TRUE, FALSE); 11178 } 11179 } else 11180 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid); 11181 if (reliable && !p->pendinginvite) 11182 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 11183 return send_response(p, &resp, reliable, seqno); 11184 }
| 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 9975 of file chan_sip.c.
References add_header(), create_new_sip_etag(), respprep(), and send_response().
Referenced by handle_sip_publish_initial(), handle_sip_publish_modify(), handle_sip_publish_refresh(), and handle_sip_publish_remove().
09976 { 09977 struct sip_request resp; 09978 09979 if (need_new_etag) { 09980 create_new_sip_etag(esc_entry, 1); 09981 } 09982 respprep(&resp, p, msg, req); 09983 add_header(&resp, "SIP-ETag", esc_entry->entity_tag); 09984 09985 return send_response(p, &resp, 0, 0); 09986 }
| 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 11070 of file chan_sip.c.
References add_sdp(), ast_log(), get_header(), LOG_ERROR, LOG_WARNING, respprep(), and send_response().
Referenced by handle_request_invite(), and interpret_t38_parameters().
11071 { 11072 struct sip_request resp; 11073 int seqno; 11074 11075 if (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1) { 11076 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 11077 return -1; 11078 } 11079 respprep(&resp, p, msg, req); 11080 if (p->udptl) { 11081 add_sdp(&resp, p, 0, 0, 1); 11082 } else 11083 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid); 11084 if (retrans && !p->pendinginvite) 11085 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 11086 return send_response(p, &resp, retrans, seqno); 11087 }
| 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 10065 of file chan_sip.c.
References add_header(), append_date(), respprep(), and send_response().
Referenced by handle_request_bye(), and handle_request_invite().
10066 { 10067 struct sip_request resp; 10068 respprep(&resp, p, msg, req); 10069 append_date(&resp); 10070 add_header(&resp, "Unsupported", unsupported); 10071 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 10072 }
| static int transmit_state_notify | ( | struct sip_pvt * | p, | |
| int | state, | |||
| int | full, | |||
| int | timeout | |||
| ) | [static] |
Used in the SUBSCRIBE notification subsystem (RFC3265).
Definition at line 12063 of file chan_sip.c.
References add_content(), add_header(), ast_copy_string(), AST_EXTENSION_DEACTIVATED, AST_EXTENSION_REMOVED, ast_log(), ast_str_alloca, cfsubscription_types::event, find_subscription_type(), get_header(), LOG_WARNING, cfsubscription_types::mediatype, NONE, remove_uri_parameters(), reqprep(), send_request(), and state_notify_build_xml().
Referenced by __sip_autodestruct(), cb_extensionstate(), and handle_request_subscribe().
12064 { 12065 struct ast_str *tmp = ast_str_alloca(4000); 12066 char from[256], to[256]; 12067 char *c, *mfrom, *mto; 12068 struct sip_request req; 12069 const struct cfsubscription_types *subscriptiontype; 12070 12071 memset(from, 0, sizeof(from)); 12072 memset(to, 0, sizeof(to)); 12073 12074 subscriptiontype = find_subscription_type(p->subscribed); 12075 12076 ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from)); 12077 c = get_in_brackets(from); 12078 if (strncasecmp(c, "sip:", 4) && strncasecmp(c, "sips:", 5)) { 12079 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 12080 return -1; 12081 } 12082 12083 mfrom = remove_uri_parameters(c); 12084 12085 ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to)); 12086 c = get_in_brackets(to); 12087 if (strncasecmp(c, "sip:", 4) && strncasecmp(c, "sips:", 5)) { 12088 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 12089 return -1; 12090 } 12091 mto = remove_uri_parameters(c); 12092 12093 reqprep(&req, p, SIP_NOTIFY, 0, 1); 12094 12095 switch(state) { 12096 case AST_EXTENSION_DEACTIVATED: 12097 if (timeout) 12098 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 12099 else { 12100 add_header(&req, "Subscription-State", "terminated;reason=probation"); 12101 add_header(&req, "Retry-After", "60"); 12102 } 12103 break; 12104 case AST_EXTENSION_REMOVED: 12105 add_header(&req, "Subscription-State", "terminated;reason=noresource"); 12106 break; 12107 default: 12108 if (p->expiry) 12109 add_header(&req, "Subscription-State", "active"); 12110 else /* Expired */ 12111 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 12112 } 12113 12114 switch (p->subscribed) { 12115 case XPIDF_XML: 12116 case CPIM_PIDF_XML: 12117 add_header(&req, "Event", subscriptiontype->event); 12118 state_notify_build_xml(state, full, p->exten, p->context, &tmp, p, p->subscribed, mfrom, mto); 12119 add_header(&req, "Content-Type", subscriptiontype->mediatype); 12120 p->dialogver++; 12121 break; 12122 case PIDF_XML: /* Eyebeam supports this format */ 12123 add_header(&req, "Event", subscriptiontype->event); 12124 state_notify_build_xml(state, full, p->exten, p->context, &tmp, p, p->subscribed, mfrom, mto); 12125 add_header(&req, "Content-Type", subscriptiontype->mediatype); 12126 p->dialogver++; 12127 break; 12128 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 12129 add_header(&req, "Event", subscriptiontype->event); 12130 state_notify_build_xml(state, full, p->exten, p->context, &tmp, p, p->subscribed, mfrom, mto); 12131 add_header(&req, "Content-Type", subscriptiontype->mediatype); 12132 p->dialogver++; 12133 break; 12134 case NONE: 12135 default: 12136 break; 12137 } 12138 12139 add_content(&req, tmp->str); 12140 12141 p->pendinginvite = p->ocseq; /* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */ 12142 12143 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 12144 }
| static void try_suggested_sip_codec | ( | struct sip_pvt * | p | ) | [static] |
Try setting codec suggested by the SIP_CODEC channel variable.
Definition at line 6155 of file chan_sip.c.
References ast_getformatbyname(), ast_log(), LOG_NOTICE, and pbx_builtin_getvar_helper().
Referenced by sip_answer(), transmit_invite(), transmit_reinvite_with_sdp(), and transmit_response_with_sdp().
06156 { 06157 format_t fmt; 06158 const char *codec; 06159 06160 if (p->outgoing_call) { 06161 codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC_OUTBOUND"); 06162 } else if (!(codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC_INBOUND"))) { 06163 codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC"); 06164 } 06165 06166 if (!codec) 06167 return; 06168 06169 fmt = ast_getformatbyname(codec); 06170 if (fmt) { 06171 ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec); 06172 if (p->jointcapability & fmt) { 06173 p->jointcapability &= fmt; 06174 p->capability &= fmt; 06175 } else 06176 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n"); 06177 } else 06178 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec); 06179 return; 06180 }
| static void unlink_marked_peers_from_tables | ( | void | ) | [static] |
Definition at line 2803 of file chan_sip.c.
References ao2_t_callback, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, peer_is_marked(), and peers_by_ip.
Referenced by sip_do_reload(), and sip_prune_realtime().
02804 { 02805 ao2_t_callback(peers, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, peer_is_marked, NULL, 02806 "initiating callback to remove marked peers"); 02807 ao2_t_callback(peers_by_ip, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, peer_is_marked, NULL, 02808 "initiating callback to remove marked peers"); 02809 }
| static void unlink_peer_from_tables | ( | struct sip_peer * | peer | ) | [static] |
Definition at line 2812 of file chan_sip.c.
References ao2_t_unlink, ast_sockaddr_isnull(), and peers_by_ip.
Referenced by expire_register().
02813 { 02814 ao2_t_unlink(peers, peer, "ao2_unlink of peer from peers table"); 02815 if (!ast_sockaddr_isnull(&peer->addr)) { 02816 ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table"); 02817 } 02818 }
| static int unload_module | ( | void | ) | [static] |
PBX unload module API.
Definition at line 29144 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ao2_t_ref, ARRAY_LEN, ast_cc_agent_unregister(), ast_cc_monitor_unregister(), ast_channel_unregister(), ast_cli_unregister_multiple(), ast_context_destroy(), ast_context_find(), ast_custom_function_unregister(), ast_data_unregister, ast_free, ast_free_ha(), ast_manager_unregister(), ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_rtp_glue_unregister(), ast_sched_dump(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_tcptls_server_stop(), AST_TEST_UNREGISTER, ast_udptl_proto_unregister(), ast_unload_realtime(), ast_unregister_application(), ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, authl, ast_tls_config::cafile, ast_tls_config::capath, ast_tls_config::certfile, checksipdomain_function, ast_tls_config::cipher, clear_realm_authentication(), clear_sip_domains(), cli_sip, default_tls_cfg, destroy_escs(), dialog_unlink_all(), dialogs, localaddr, ast_tcptls_session_args::master, monitor_thread, monlock, network_change_event_unsubscribe(), peers_by_ip, ast_tls_config::pvtfile, regl, sched_context_destroy(), sip_cc_agent_callbacks, sip_cc_monitor_callbacks, sip_cfg, sip_header_function, sip_registry_destroy(), sip_rtp_glue, sip_subscribe_mwi_destroy(), sip_tcp_desc, sip_tech, sip_tls_desc, sip_udptl, sip_unregister_tests(), sipchaninfo_function, sippeer_function, sipsock, submwil, thread, threadt, TRUE, and used_context.
29145 { 29146 struct sip_pvt *p; 29147 struct sip_threadinfo *th; 29148 struct ast_context *con; 29149 struct ao2_iterator i; 29150 29151 network_change_event_unsubscribe(); 29152 29153 ast_sched_dump(sched); 29154 29155 /* First, take us out of the channel type list */ 29156 ast_channel_unregister(&sip_tech); 29157 29158 /* Unregister dial plan functions */ 29159 ast_custom_function_unregister(&sipchaninfo_function); 29160 ast_custom_function_unregister(&sippeer_function); 29161 ast_custom_function_unregister(&sip_header_function); 29162 ast_custom_function_unregister(&checksipdomain_function); 29163 29164 /* Unregister dial plan applications */ 29165 ast_unregister_application(app_dtmfmode); 29166 ast_unregister_application(app_sipaddheader); 29167 ast_unregister_application(app_sipremoveheader); 29168 29169 #ifdef TEST_FRAMEWORK 29170 AST_TEST_UNREGISTER(test_sip_peers_get); 29171 AST_TEST_UNREGISTER(test_sip_mwi_subscribe_parse); 29172 #endif 29173 /* Unregister all the AstData providers */ 29174 ast_data_unregister(NULL); 29175 29176 /* Unregister CLI commands */ 29177 ast_cli_unregister_multiple(cli_sip, ARRAY_LEN(cli_sip)); 29178 29179 /* Disconnect from UDPTL */ 29180 ast_udptl_proto_unregister(&sip_udptl); 29181 29182 /* Disconnect from RTP engine */ 29183 ast_rtp_glue_unregister(&sip_rtp_glue); 29184 29185 /* Unregister AMI actions */ 29186 ast_manager_unregister("SIPpeers"); 29187 ast_manager_unregister("SIPshowpeer"); 29188 ast_manager_unregister("SIPqualifypeer"); 29189 ast_manager_unregister("SIPshowregistry"); 29190 ast_manager_unregister("SIPnotify"); 29191 29192 /* Kill TCP/TLS server threads */ 29193 if (sip_tcp_desc.master) { 29194 ast_tcptls_server_stop(&sip_tcp_desc); 29195 } 29196 if (sip_tls_desc.master) { 29197 ast_tcptls_server_stop(&sip_tls_desc); 29198 } 29199 29200 /* Kill all existing TCP/TLS threads */ 29201 i = ao2_iterator_init(threadt, 0); 29202 while ((th = ao2_t_iterator_next(&i, "iterate through tcp threads for 'sip show tcp'"))) { 29203 pthread_t thread = th->threadid; 29204 th->stop = 1; 29205 pthread_kill(thread, SIGURG); 29206 pthread_join(thread, NULL); 29207 ao2_t_ref(th, -1, "decrement ref from iterator"); 29208 } 29209 ao2_iterator_destroy(&i); 29210 29211 /* Hangup all dialogs if they have an owner */ 29212 i = ao2_iterator_init(dialogs, 0); 29213 while ((p = ao2_t_iterator_next(&i, "iterate thru dialogs"))) { 29214 if (p->owner) 29215 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 29216 ao2_t_ref(p, -1, "toss dialog ptr from iterator_next"); 29217 } 29218 ao2_iterator_destroy(&i); 29219 29220 ast_mutex_lock(&monlock); 29221 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 29222 pthread_cancel(monitor_thread); 29223 pthread_kill(monitor_thread, SIGURG); 29224 pthread_join(monitor_thread, NULL); 29225 } 29226 monitor_thread = AST_PTHREADT_STOP; 29227 ast_mutex_unlock(&monlock); 29228 29229 /* Destroy all the dialogs and free their memory */ 29230 i = ao2_iterator_init(dialogs, 0); 29231 while ((p = ao2_t_iterator_next(&i, "iterate thru dialogs"))) { 29232 dialog_unlink_all(p, TRUE, TRUE); 29233 ao2_t_ref(p, -1, "throw away iterator result"); 29234 } 29235 ao2_iterator_destroy(&i); 29236 29237 /* Free memory for local network address mask */ 29238 ast_free_ha(localaddr); 29239 29240 clear_realm_authentication(authl); 29241 29242 destroy_escs(); 29243 29244 if (default_tls_cfg.certfile) { 29245 ast_free(default_tls_cfg.certfile); 29246 } 29247 if (default_tls_cfg.pvtfile) { 29248 ast_free(default_tls_cfg.pvtfile); 29249 } 29250 if (default_tls_cfg.cipher) { 29251 ast_free(default_tls_cfg.cipher); 29252 } 29253 if (default_tls_cfg.cafile) { 29254 ast_free(default_tls_cfg.cafile); 29255 } 29256 if (default_tls_cfg.capath) { 29257 ast_free(default_tls_cfg.capath); 29258 } 29259 29260 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 29261 ASTOBJ_CONTAINER_DESTROY(®l); 29262 ASTOBJ_CONTAINER_DESTROYALL(&submwil, sip_subscribe_mwi_destroy); 29263 ASTOBJ_CONTAINER_DESTROY(&submwil); 29264 29265 ao2_t_ref(peers, -1, "unref the peers table"); 29266 ao2_t_ref(peers_by_ip, -1, "unref the peers_by_ip table"); 29267 ao2_t_ref(dialogs, -1, "unref the dialogs table"); 29268 ao2_t_ref(threadt, -1, "unref the thread table"); 29269 29270 clear_sip_domains(); 29271 ast_free_ha(sip_cfg.contact_ha); 29272 close(sipsock); 29273 sched_context_destroy(sched); 29274 con = ast_context_find(used_context); 29275 if (con) { 29276 ast_context_destroy(con, "SIP"); 29277 } 29278 ast_unload_realtime("sipregs"); 29279 ast_unload_realtime("sippeers"); 29280 ast_cc_monitor_unregister(&sip_cc_monitor_callbacks); 29281 ast_cc_agent_unregister(&sip_cc_agent_callbacks); 29282 29283 sip_reqresp_parser_exit(); 29284 sip_unregister_tests(); 29285 29286 return 0; 29287 }
| static void* unref_peer | ( | struct sip_peer * | peer, | |
| char * | tag | |||
| ) | [static] |
helper functions to unreference various types of objects. By handling them this way, we don't have to declare the destructor on each call, which removes the chance of errors.
Definition at line 2825 of file chan_sip.c.
References ao2_t_ref.
Referenced by __sip_destroy(), _sip_qualify_peer(), _sip_show_peer(), _sip_show_peers(), build_peer(), check_peer_ok(), complete_sip_peer(), complete_sip_registered_peer(), complete_sip_user(), create_addr(), expire_register(), find_peer(), function_sippeer(), handle_request_invite(), handle_request_notify(), handle_request_subscribe(), handle_response_peerpoke(), parse_register_contact(), reg_source_db(), register_verify(), sip_devicestate(), sip_do_debug_peer(), sip_poke_all_peers(), sip_poke_noanswer(), sip_poke_peer(), sip_poke_peer_s(), sip_prune_realtime(), sip_show_inuse(), sip_show_user(), sip_show_users(), sip_unregister(), transmit_register(), and update_call_counter().
02826 { 02827 ao2_t_ref(peer, -1, tag); 02828 return NULL; 02829 }
| static int update_call_counter | ( | struct sip_pvt * | fup, | |
| int | event | |||
| ) | [static] |
update_call_counter: Handle call_limit for SIP devices Setting a call-limit will cause calls above the limit not to be accepted.
Remember that for a type=friend, there's one limit for the user and another for the peer, not a combined call limit. This will cause unexpected behaviour in subscriptions, since a "friend" is *two* devices in Asterisk, not one.
Thought: For realtime, we should probably update storage with inuse counter...
Definition at line 5613 of file chan_sip.c.
References ao2_lock, ao2_unlock, ast_clear_flag, ast_copy_string(), ast_debug, AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_log(), ast_set_flag, ast_test_flag, FALSE, LOG_ERROR, LOG_NOTICE, name, ref_peer(), sip_cfg, sip_peer_hold(), sip_pvt_lock, sip_pvt_unlock, sipdebug, and unref_peer().
Referenced by __sip_destroy(), handle_request_cancel(), handle_request_invite(), handle_response_invite(), sip_call(), and sip_hangup().
05614 { 05615 char name[256]; 05616 int *inuse = NULL, *call_limit = NULL, *inringing = NULL; 05617 int outgoing = fup->outgoing_call; 05618 struct sip_peer *p = NULL; 05619 05620 ast_debug(3, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming"); 05621 05622 05623 /* Test if we need to check call limits, in order to avoid 05624 realtime lookups if we do not need it */ 05625 if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT) && !ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD)) 05626 return 0; 05627 05628 ast_copy_string(name, fup->username, sizeof(name)); 05629 05630 /* Check the list of devices */ 05631 if (fup->relatedpeer) { 05632 p = ref_peer(fup->relatedpeer, "ref related peer for update_call_counter"); 05633 inuse = &p->inUse; 05634 call_limit = &p->call_limit; 05635 inringing = &p->inRinging; 05636 ast_copy_string(name, fup->peername, sizeof(name)); 05637 } 05638 if (!p) { 05639 ast_debug(2, "%s is not a local device, no call limit\n", name); 05640 return 0; 05641 } 05642 05643 switch(event) { 05644 /* incoming and outgoing affects the inUse counter */ 05645 case DEC_CALL_LIMIT: 05646 /* Decrement inuse count if applicable */ 05647 if (inuse) { 05648 sip_pvt_lock(fup); 05649 ao2_lock(p); 05650 if (*inuse > 0) { 05651 if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) { 05652 (*inuse)--; 05653 ast_clear_flag(&fup->flags[0], SIP_INC_COUNT); 05654 } 05655 } else { 05656 *inuse = 0; 05657 } 05658 ao2_unlock(p); 05659 sip_pvt_unlock(fup); 05660 } 05661 05662 /* Decrement ringing count if applicable */ 05663 if (inringing) { 05664 sip_pvt_lock(fup); 05665 ao2_lock(p); 05666 if (*inringing > 0) { 05667 if (ast_test_flag(&fup->flags[0], SIP_INC_RINGING)) { 05668 (*inringing)--; 05669 ast_clear_flag(&fup->flags[0], SIP_INC_RINGING); 05670 } 05671 } else { 05672 *inringing = 0; 05673 } 05674 ao2_unlock(p); 05675 sip_pvt_unlock(fup); 05676 } 05677 05678 /* Decrement onhold count if applicable */ 05679 sip_pvt_lock(fup); 05680 ao2_lock(p); 05681 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && sip_cfg.notifyhold) { 05682 ast_clear_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD); 05683 ao2_unlock(p); 05684 sip_pvt_unlock(fup); 05685 sip_peer_hold(fup, FALSE); 05686 } else { 05687 ao2_unlock(p); 05688 sip_pvt_unlock(fup); 05689 } 05690 if (sipdebug) 05691 ast_debug(2, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", "peer", name, *call_limit); 05692 break; 05693 05694 case INC_CALL_RINGING: 05695 case INC_CALL_LIMIT: 05696 /* If call limit is active and we have reached the limit, reject the call */ 05697 if (*call_limit > 0 ) { 05698 if (*inuse >= *call_limit) { 05699 ast_log(LOG_NOTICE, "Call %s %s '%s' rejected due to usage limit of %d\n", outgoing ? "to" : "from", "peer", name, *call_limit); 05700 unref_peer(p, "update_call_counter: unref peer p, call limit exceeded"); 05701 return -1; 05702 } 05703 } 05704 if (inringing && (event == INC_CALL_RINGING)) { 05705 sip_pvt_lock(fup); 05706 ao2_lock(p); 05707 if (!ast_test_flag(&fup->flags[0], SIP_INC_RINGING)) { 05708 (*inringing)++; 05709 ast_set_flag(&fup->flags[0], SIP_INC_RINGING); 05710 } 05711 ao2_unlock(p); 05712 sip_pvt_unlock(fup); 05713 } 05714 if (inuse) { 05715 sip_pvt_lock(fup); 05716 ao2_lock(p); 05717 if (!ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) { 05718 (*inuse)++; 05719 ast_set_flag(&fup->flags[0], SIP_INC_COUNT); 05720 } 05721 ao2_unlock(p); 05722 sip_pvt_unlock(fup); 05723 } 05724 if (sipdebug) { 05725 ast_debug(2, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", "peer", name, *inuse, *call_limit); 05726 } 05727 break; 05728 05729 case DEC_CALL_RINGING: 05730 if (inringing) { 05731 sip_pvt_lock(fup); 05732 ao2_lock(p); 05733 if (ast_test_flag(&fup->flags[0], SIP_INC_RINGING)) { 05734 if (*inringing > 0) { 05735 (*inringing)--; 05736 } 05737 ast_clear_flag(&fup->flags[0], SIP_INC_RINGING); 05738 } 05739 ao2_unlock(p); 05740 sip_pvt_unlock(fup); 05741 } 05742 break; 05743 05744 default: 05745 ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event); 05746 } 05747 05748 if (p) { 05749 ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", p->name); 05750 unref_peer(p, "update_call_counter: unref_peer from call counter"); 05751 } 05752 return 0; 05753 }
| 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 12299 of file chan_sip.c.
References add_header(), add_rpid(), add_sdp(), add_supported_header(), append_history, ast_debug, ast_set_flag, ast_state2str(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, FALSE, initialize_initreq(), is_method_allowed(), reqprep(), respprep(), S_COR, send_request(), send_response(), and TRUE.
Referenced by sip_indicate(), and skinny_indicate().
12300 { 12301 12302 if (!ast_test_flag(&p->flags[0], SIP_SENDRPID)) { 12303 return; 12304 } 12305 if (!p->owner->connected.id.number.valid 12306 || ast_strlen_zero(p->owner->connected.id.number.str)) { 12307 return; 12308 } 12309 12310 append_history(p, "ConnectedLine", "%s party is now %s <%s>", 12311 ast_test_flag(&p->flags[0], SIP_OUTGOING) ? "Calling" : "Called", 12312 S_COR(p->owner->connected.id.name.valid, p->owner->connected.id.name.str, ""), 12313 S_COR(p->owner->connected.id.number.valid, p->owner->connected.id.number.str, "")); 12314 12315 if (p->owner->_state == AST_STATE_UP || ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 12316 struct sip_request req; 12317 12318 if (p->invitestate == INV_CONFIRMED || p->invitestate == INV_TERMINATED) { 12319 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 12320 12321 add_header(&req, "Allow", ALLOWED_METHODS); 12322 add_supported_header(p, &req); 12323 add_rpid(&req, p); 12324 add_sdp(&req, p, FALSE, TRUE, FALSE); 12325 12326 initialize_initreq(p, &req); 12327 p->lastinvite = p->ocseq; 12328 ast_set_flag(&p->flags[0], SIP_OUTGOING); 12329 p->invitestate = INV_CALLING; 12330 send_request(p, &req, XMIT_CRITICAL, p->ocseq); 12331 } else if (is_method_allowed(&p->allowed_methods, SIP_UPDATE)) { 12332 reqprep(&req, p, SIP_UPDATE, 0, 1); 12333 add_rpid(&req, p); 12334 add_header(&req, "X-Asterisk-rpid-update", "Yes"); 12335 send_request(p, &req, XMIT_CRITICAL, p->ocseq); 12336 } else { 12337 /* We cannot send the update yet, so we have to wait until we can */ 12338 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 12339 } 12340 } else { 12341 if (ast_test_flag(&p->flags[1], SIP_PAGE2_RPID_IMMEDIATE)) { 12342 struct sip_request resp; 12343 12344 if ((p->owner->_state == AST_STATE_RING) && !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT)) { 12345 respprep(&resp, p, "180 Ringing", &p->initreq); 12346 add_rpid(&resp, p); 12347 send_response(p, &resp, XMIT_UNRELIABLE, 0); 12348 ast_set_flag(&p->flags[0], SIP_RINGING); 12349 } else if (p->owner->_state == AST_STATE_RINGING) { 12350 respprep(&resp, p, "183 Session Progress", &p->initreq); 12351 add_rpid(&resp, p); 12352 send_response(p, &resp, XMIT_UNRELIABLE, 0); 12353 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 12354 } else { 12355 ast_debug(1, "Unable able to send update to '%s' in state '%s'\n", p->owner->name, ast_state2str(p->owner->_state)); 12356 } 12357 } else { 12358 ast_set_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND); 12359 } 12360 } 12361 }
| static void update_peer | ( | struct sip_peer * | p, | |
| int | expire | |||
| ) | [static] |
Update peer data in database (if used).
Definition at line 4522 of file chan_sip.c.
References ast_test_flag, realtime_update_peer(), and sip_cfg.
Referenced by register_verify().
04523 { 04524 int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 04525 if (sip_cfg.peer_rtupdate && 04526 (p->is_realtime || rtcachefriends)) { 04527 realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, p->useragent, expire, p->deprecated_username, p->lastms); 04528 } 04529 }
| static void update_provisional_keepalive | ( | struct sip_pvt * | pvt, | |
| int | with_sdp | |||
| ) | [static] |
Definition at line 4041 of file chan_sip.c.
References ast_sched_add(), AST_SCHED_DEL_UNREF, send_provisional_keepalive(), and send_provisional_keepalive_with_sdp().
Referenced by transmit_provisional_response().
04042 { 04043 AST_SCHED_DEL_UNREF(sched, pvt->provisional_keepalive_sched_id, dialog_unref(pvt, "when you delete the provisional_keepalive_sched_id, you should dec the refcount for the stored dialog ptr")); 04044 04045 pvt->provisional_keepalive_sched_id = ast_sched_add(sched, PROVIS_KEEPALIVE_TIMEOUT, 04046 with_sdp ? send_provisional_keepalive_with_sdp : send_provisional_keepalive, dialog_ref(pvt, "Increment refcount to pass dialog pointer to sched callback")); 04047 }
| 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 12285 of file chan_sip.c.
References add_diversion_header(), AST_STATE_UP, ast_test_flag, respprep(), and send_response().
Referenced by change_redirecting_information(), handle_request_invite(), handle_response(), handle_response_invite(), misdn_copy_redirecting_to_ast(), and sip_indicate().
12286 { 12287 struct sip_request resp; 12288 12289 if (p->owner->_state == AST_STATE_UP || ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 12290 return; 12291 } 12292 12293 respprep(&resp, p, "181 Call is being forwarded", &p->initreq); 12294 add_diversion_header(&resp, p); 12295 send_response(p, &resp, XMIT_UNRELIABLE, 0); 12296 }
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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .nonoptreq = "res_crypto,chan_local", } [static] |
Definition at line 29295 of file chan_sip.c.
int apeerobjs = 0 [static] |
Autocreated peer objects
Definition at line 762 of file chan_sip.c.
Referenced by sip_destroy_peer(), sip_show_objects(), and temp_peer().
char* app_dtmfmode = "SIPDtmfMode" [static] |
Definition at line 28041 of file chan_sip.c.
char* app_sipaddheader = "SIPAddHeader" [static] |
Definition at line 28042 of file chan_sip.c.
char* app_sipremoveheader = "SIPRemoveHeader" [static] |
Definition at line 28043 of file chan_sip.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 29295 of file chan_sip.c.
struct sip_auth* authl = NULL [static] |
Authentication list for realm authentication.
Definition at line 1110 of file chan_sip.c.
Referenced by build_reply_digest(), reload_config(), sip_show_settings(), and unload_module().
int authlimit = DEFAULT_AUTHLIMIT [static] |
Definition at line 563 of file chan_sip.c.
Referenced by __init_manager(), _sip_tcp_helper_thread(), and session_do().
int authtimeout = DEFAULT_AUTHTIMEOUT [static] |
Definition at line 564 of file chan_sip.c.
Referenced by __init_manager(), do_message(), and sip_check_authtimeout().
| struct ast_sockaddr bindaddr |
UDP: The address we bind to
Definition at line 1130 of file chan_sip.c.
int can_parse_xml [static] |
We use libxml2 in order to parse XML that may appear in the body of a SIP message. Currently, the only usage is for parsing PIDF bodies of incoming PUBLISH requests in the call-completion event package. This variable is set at module load time and may be checked at runtime to determine if XML parsing support was found.
Definition at line 755 of file chan_sip.c.
Referenced by build_peer(), and load_module().
struct epa_static_data cc_epa_static_data [static] |
struct sip_esc_publish_callbacks cc_esc_publish_callbacks [static] |
Initial value:
{
.initial_handler = cc_esc_publish_handler,
.modify_handler = cc_esc_publish_handler,
}
Definition at line 931 of file chan_sip.c.
unsigned int chan_idx [static] |
struct ast_threadstorage check_auth_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_check_auth_buf , .custom_init = NULL , } [static] |
Definition at line 13584 of file chan_sip.c.
Referenced by check_auth(), and transmit_fake_auth_response().
struct ast_custom_function checksipdomain_function [static] |
Initial value:
{
.name = "CHECKSIPDOMAIN",
.read = func_check_sipdomain,
}
Definition at line 18502 of file chan_sip.c.
Referenced by load_module(), and unload_module().
struct ast_cli_entry cli_sip[] [static] |
SIP Cli commands definition.
Definition at line 28590 of file chan_sip.c.
Referenced by load_module(), and unload_module().
const char config[] = "sip.conf" [static] |
Main configuration file
Definition at line 577 of file chan_sip.c.
struct ast_sockaddr debugaddr [static] |
Definition at line 1174 of file chan_sip.c.
char default_callerid[AST_MAX_EXTENSION] [static] |
Default caller ID for sip messages
Definition at line 678 of file chan_sip.c.
Referenced by initreqprep(), and sip_show_settings().
char default_engine[256] [static] |
Default RTP engine
Definition at line 689 of file chan_sip.c.
Referenced by ast_speech_register(), ast_speech_unregister(), find_engine(), set_peer_defaults(), and sip_alloc().
int default_expiry = DEFAULT_DEFAULT_EXPIRY [static] |
Definition at line 559 of file chan_sip.c.
Referenced by handle_response_register(), parse_register_contact(), sip_register(), sip_send_all_registers(), and sip_show_settings().
char default_fromdomain[AST_MAX_EXTENSION] [static] |
Default domain on outound messages
Definition at line 680 of file chan_sip.c.
Referenced by sip_alloc(), sip_show_settings(), transmit_register(), and transmit_response_using_temp().
int default_fromdomainport [static] |
Default domain port on outbound messages
Definition at line 681 of file chan_sip.c.
Referenced by sip_alloc(), sip_show_settings(), and transmit_response_using_temp().
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled.
Definition at line 567 of file chan_sip.c.
char default_language[MAX_LANGUAGE] [static] |
Default language setting for new channels
Definition at line 677 of file chan_sip.c.
Referenced by set_peer_defaults(), and sip_show_settings().
int default_maxcallbitrate [static] |
Maximum bitrate for call
Definition at line 690 of file chan_sip.c.
Referenced by build_peer(), set_peer_defaults(), sip_alloc(), and sip_show_settings().
char default_mohinterpret[MAX_MUSICCLASS] [static] |
Global setting for moh class to use when put on hold
Definition at line 685 of file chan_sip.c.
Referenced by set_peer_defaults(), sip_alloc(), and sip_show_settings().
char default_mohsuggest[MAX_MUSICCLASS] [static] |
Global setting for moh class to suggest when putting a bridged channel on hold
Definition at line 686 of file chan_sip.c.
Referenced by set_peer_defaults(), sip_alloc(), and sip_show_settings().
char default_mwi_from[80] [static] |
Default caller ID for MWI updates
Definition at line 679 of file chan_sip.c.
Referenced by sip_send_mwi_to_peer().
char default_notifymime[AST_MAX_EXTENSION] [static] |
Default MIME media type for MWI notify messages
Definition at line 682 of file chan_sip.c.
Referenced by sip_show_settings(), and transmit_notify_with_mwi().
char default_parkinglot[AST_MAX_CONTEXT] [static] |
Parkinglot
Definition at line 688 of file chan_sip.c.
struct ast_codec_pref default_prefs [static] |
Default codec prefs
Definition at line 691 of file chan_sip.c.
Referenced by config_load(), config_parse_variables(), set_peer_defaults(), sip_alloc(), sip_show_settings(), and temp_peer().
unsigned int default_primary_transport [static] |
Default primary Transport (enum sip_transport) for outbound connections to devices
Definition at line 693 of file chan_sip.c.
Referenced by build_peer(), set_peer_defaults(), and sip_show_settings().
const int DEFAULT_PUBLISH_EXPIRES = 3600 [static] |
Definition at line 926 of file chan_sip.c.
Referenced by determine_sip_publish_type(), and transmit_publish().
int default_qualify [static] |
Default Qualify= setting
Definition at line 684 of file chan_sip.c.
Referenced by build_peer(), set_peer_defaults(), and sip_show_settings().
struct ast_tls_config default_tls_cfg [static] |
Default TLS connection configuration.
Definition at line 2164 of file chan_sip.c.
Referenced by reload_config(), sip_prepare_socket(), sip_show_settings(), and unload_module().
unsigned int default_transports [static] |
Default Transports (enum sip_transport) that are acceptable
Definition at line 692 of file chan_sip.c.
Referenced by build_peer(), set_peer_defaults(), and sip_show_settings().
char default_vmexten[AST_MAX_EXTENSION] [static] |
Default From Username on MWI updates
Definition at line 683 of file chan_sip.c.
Referenced by set_peer_defaults(), sip_show_settings(), and transmit_notify_with_mwi().
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 1080 of file chan_sip.c.
Referenced by complete_sipch(), create_addr_from_peer(), dialog_unlink_all(), do_monitor(), find_call(), get_sip_pvt_byid_locked(), load_module(), sip_alloc(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), sip_show_channel(), sip_show_channels(), sip_show_channelstats(), sip_show_history(), sip_show_objects(), and unload_module().
struct _map_x_s dtmfstr[] [static] |
mapping between dtmf flags and strings
Definition at line 16107 of file chan_sip.c.
Referenced by conf_run(), dtmfmode2str(), handle_link_data(), handle_remote_data(), send_dtmf(), and str2dtmfmode().
unsigned int dumphistory [static] |
Dump history to verbose before destroying SIP dialog
Definition at line 728 of file chan_sip.c.
Referenced by __sip_destroy(), and append_history_full().
int esc_etag_counter [static] |
Used to create new entity IDs by ESCs.
Definition at line 925 of file chan_sip.c.
const int ESC_MAX_BUCKETS = 37 [static] |
Definition at line 960 of file chan_sip.c.
struct event_state_compositor event_state_compositors[] [static] |
The Event State Compositors.
An Event State Compositor is an entity which accepts PUBLISH requests and acts appropriately based on these requests.
The actual event_state_compositor structure is simply an ao2_container of sip_esc_entrys. When an incoming PUBLISH is received, we can match the appropriate sip_esc_entry using the entity ID of the incoming PUBLISH.
Referenced by destroy_escs(), get_esc(), and initialize_escs().
struct ast_sockaddr externaddr [static] |
our external IP address/port for SIP sessions. externaddr.sin_addr is only set when we know we might be behind a NAT, and this is done using a variety of (mutually exclusive) ways from the config file:
+ with "externaddr = host[:port]" we specify the address/port explicitly. The address is looked up only once when (re)loading the config file;
+ with "externhost = host[:port]" we do a similar thing, but the hostname is stored in externhost, and the hostname->IP mapping is refreshed every 'externrefresh' seconds;
Other variables (externhost, externexpire, externrefresh) are used to support the above functions. External IP address if we are behind NAT
Definition at line 1155 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), and sip_show_settings().
time_t externexpire [static] |
Expiration counter for re-resolving external host name in dynamic DNS
Definition at line 1159 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor().
char externhost[MAXHOSTNAMELEN] [static] |
External host name
Definition at line 1158 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), and sip_show_settings().
int externrefresh = 10 [static] |
Refresh timer for DNS-based external address (dyndns)
Definition at line 1160 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), and sip_show_settings().
uint16_t externtcpport [static] |
uint16_t externtlsport [static] |
struct _map_x_s faxecmodes[] [static] |
int global_authfailureevents [static] |
Whether we send authentication failure manager events or not. Default no.
Definition at line 732 of file chan_sip.c.
Referenced by register_verify(), and sip_show_settings().
unsigned int global_autoframing [static] |
Turn autoframing on or off.
Definition at line 736 of file chan_sip.c.
Referenced by set_peer_defaults(), sip_alloc(), and sip_show_settings().
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 716 of file chan_sip.c.
Referenced by set_peer_defaults(), and sip_show_settings().
unsigned int global_cos_audio [static] |
802.1p class of service for audio RTP packets
Definition at line 724 of file chan_sip.c.
Referenced by dialog_initialize_rtp(), sip_alloc(), and sip_show_settings().
unsigned int global_cos_sip [static] |
802.1p class of service for SIP packets
Definition at line 723 of file chan_sip.c.
Referenced by sip_show_settings().
unsigned int global_cos_text [static] |
802.1p class of service for text RTP packets
Definition at line 726 of file chan_sip.c.
Referenced by sip_show_settings().
unsigned int global_cos_video [static] |
802.1p class of service for video RTP packets
Definition at line 725 of file chan_sip.c.
Referenced by sip_show_settings().
int global_dynamic_exclude_static = 0 [static] |
Exclude static peers from contact registrations
Definition at line 746 of file chan_sip.c.
Referenced by build_peer().
struct ast_flags global_flags[3] = {{0}} [static] |
global SIP_ flags
Definition at line 766 of file chan_sip.c.
struct ast_jb_conf global_jbconf [static] |
Global jitterbuffer configuration
Definition at line 575 of file chan_sip.c.
int global_match_auth_username [static] |
Match auth username if available instead of From: Default off.
Definition at line 706 of file chan_sip.c.
Referenced by check_user_full(), and sip_show_settings().
int global_max_se [static] |
Highest threshold for session refresh interval
Definition at line 744 of file chan_sip.c.
Referenced by build_peer(), handle_request_invite(), set_peer_defaults(), sip_show_settings(), and st_get_se().
int global_min_se [static] |
Lowest threshold for session refresh interval
Definition at line 743 of file chan_sip.c.
Referenced by build_peer(), set_peer_defaults(), sip_show_settings(), and st_get_se().
int global_prematuremediafilter [static] |
Enable/disable premature frames in a call (causing 183 early media)
Definition at line 709 of file chan_sip.c.
Referenced by sip_show_settings(), and sip_write().
int global_qualify_gap [static] |
Time between our group of peer pokes
Definition at line 738 of file chan_sip.c.
Referenced by sip_poke_all_peers().
int global_qualify_peers [static] |
Number of peers to poke at a given time
Definition at line 739 of file chan_sip.c.
Referenced by sip_poke_all_peers().
int global_qualifyfreq [static] |
Qualify frequency
Definition at line 737 of file chan_sip.c.
Referenced by build_peer(), set_peer_defaults(), and sip_show_settings().
int global_reg_timeout [static] |
Global time between attempts for outbound registrations
Definition at line 713 of file chan_sip.c.
Referenced by sip_show_settings(), and transmit_register().
int global_regattempts_max [static] |
Registration attempts before giving up
Definition at line 714 of file chan_sip.c.
Referenced by sip_reg_timeout(), and sip_show_settings().
int global_relaxdtmf [static] |
Relax DTMF
Definition at line 708 of file chan_sip.c.
Referenced by enable_dsp_detect(), and sip_show_settings().
int global_rtpholdtimeout [static] |
Time out call if no RTP during hold
Definition at line 711 of file chan_sip.c.
Referenced by build_peer(), dialog_initialize_rtp(), set_peer_defaults(), and sip_show_settings().
int global_rtpkeepalive [static] |
Send RTP keepalives
Definition at line 712 of file chan_sip.c.
Referenced by build_peer(), set_peer_defaults(), and sip_show_settings().
int global_rtptimeout [static] |
Time out call if no RTP
Definition at line 710 of file chan_sip.c.
Referenced by build_peer(), dialog_initialize_rtp(), set_peer_defaults(), and sip_show_settings().
char global_sdpowner[AST_MAX_EXTENSION] [static] |
SDP owner name for the SIP channel
Definition at line 731 of file chan_sip.c.
Referenced by add_sdp(), and sip_show_settings().
char global_sdpsession[AST_MAX_EXTENSION] [static] |
SDP session name for the SIP channel
Definition at line 730 of file chan_sip.c.
Referenced by add_sdp(), and sip_show_settings().
int global_shrinkcallerid [static] |
enable or disable shrinking of caller id
Definition at line 715 of file chan_sip.c.
Referenced by check_peer_ok(), check_user_full(), get_pai(), and get_rpid().
enum st_mode global_st_mode [static] |
Mode of operation for Session-Timers
Definition at line 741 of file chan_sip.c.
Referenced by build_peer(), set_peer_defaults(), sip_show_settings(), and st_get_mode().
enum st_refresher global_st_refresher [static] |
Session-Timer refresher
Definition at line 742 of file chan_sip.c.
Referenced by build_peer(), set_peer_defaults(), sip_show_settings(), and st_get_refresher().
int global_t1 [static] |
T1 time
Definition at line 733 of file chan_sip.c.
Referenced by create_addr(), set_peer_defaults(), sip_alloc(), sip_scheddestroy(), and sip_show_settings().
int global_t1min [static] |
T1 roundtrip time minimum
Definition at line 734 of file chan_sip.c.
Referenced by build_peer(), check_peer_ok(), create_addr_from_peer(), and sip_show_settings().
int global_t38_maxdatagram [static] |
global T.38 FaxMaxDatagram override
Definition at line 767 of file chan_sip.c.
Referenced by handle_request_invite(), handle_t38_options(), set_peer_defaults(), sip_alloc(), and sip_show_settings().
int global_timer_b [static] |
Timer B - RFC 3261 Section 17.1.1.2
Definition at line 735 of file chan_sip.c.
Referenced by build_peer(), create_addr(), set_peer_defaults(), sip_alloc(), sip_scheddestroy(), and sip_show_settings().
unsigned int global_tos_audio [static] |
IP type of service for audio RTP packets
Definition at line 720 of file chan_sip.c.
Referenced by dialog_initialize_rtp(), sip_alloc(), and sip_show_settings().
unsigned int global_tos_sip [static] |
IP type of service for SIP packets
Definition at line 719 of file chan_sip.c.
Referenced by sip_show_settings().
unsigned int global_tos_text [static] |
IP type of service for text RTP packets
Definition at line 722 of file chan_sip.c.
Referenced by sip_show_settings().
unsigned int global_tos_video [static] |
IP type of service for video RTP packets
Definition at line 721 of file chan_sip.c.
Referenced by sip_show_settings().
char global_useragent[AST_MAX_EXTENSION] [static] |
Useragent for the SIP channel
Definition at line 729 of file chan_sip.c.
Referenced by curl_instance_init(), initreqprep(), reqprep(), respprep(), sip_show_settings(), and transmit_register().
const int HASH_DIALOG_SIZE = 563 [static] |
const int HASH_PEER_SIZE = 563 [static] |
Size of peer hash table, prime number preferred!
Definition at line 823 of file chan_sip.c.
Referenced by load_module().
struct _map_x_s insecurestr[] [static] |
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 1138 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), sip_alloc(), transmit_register(), and transmit_response_using_temp().
struct invstate2stringtable invitestate2string[] [static] |
Readable descriptions of device states.
Referenced by show_chanstats_cb().
struct io_context* io [static] |
The IO context
Definition at line 790 of file chan_sip.c.
List of local networks We store "localnet" addresses from the config file into an access list, marked as 'DENY', so the call to ast_apply_ha() will return AST_SENSE_DENY for 'local' addresses, and AST_SENSE_ALLOW for 'non local' (i.e. presumably public) addresses.
List of local networks, on the same side of NAT as this Asterisk
Definition at line 1170 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), sip_show_settings(), and unload_module().
int max_expiry = DEFAULT_MAX_EXPIRY [static] |
Maximum accepted registration time
Definition at line 558 of file chan_sip.c.
Referenced by handle_request_subscribe(), handle_response_register(), parse_register_contact(), and sip_show_settings().
struct ast_sockaddr media_address [static] |
External RTP IP address if we are behind NAT
Definition at line 1156 of file chan_sip.c.
Referenced by get_our_media_address().
int min_expiry = DEFAULT_MIN_EXPIRY [static] |
Minimum accepted registration time
Definition at line 557 of file chan_sip.c.
Referenced by handle_request_subscribe(), parse_register_contact(), sip_show_settings(), and transmit_response_with_minexpires().
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 784 of file chan_sip.c.
ast_mutex_t monlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [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 778 of file chan_sip.c.
int mwi_expiry = DEFAULT_MWI_EXPIRY [static] |
Definition at line 560 of file chan_sip.c.
Referenced by __sip_subscribe_mwi_do(), and handle_response_subscribe().
ast_mutex_t netlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static] |
Definition at line 774 of file chan_sip.c.
int network_change_event_sched_id = -1 [static] |
Definition at line 770 of file chan_sip.c.
struct ast_event_sub* network_change_event_subscription [static] |
subscription id for network change events
Definition at line 769 of file chan_sip.c.
const char notify_config[] = "sip_notify.conf" [static] |
Configuration file for sending Notify with CLI commands to reconfigure or reboot phones
Definition at line 578 of file chan_sip.c.
Referenced by sip_cli_notify().
struct ast_config* notify_types = NULL [static] |
The list of manual NOTIFY types we know how to send
Definition at line 1176 of file chan_sip.c.
Referenced by complete_sipnotify(), and sip_cli_notify().
int ourport_tcp [static] |
The port used for TCP connections
Definition at line 1172 of file chan_sip.c.
int ourport_tls [static] |
The port used for TCP/TLS connections
Definition at line 1173 of file chan_sip.c.
struct ao2_container* peers [static] |
struct ao2_container* peers_by_ip [static] |
Definition at line 1090 of file chan_sip.c.
Referenced by find_peer(), load_module(), parse_register_contact(), register_verify(), sip_prune_realtime(), unlink_marked_peers_from_tables(), unlink_peer_from_tables(), and unload_module().
struct ast_data_handler peers_data_provider [static] |
Initial value:
{
.version = AST_DATA_HANDLER_VERSION,
.get = peers_data_provider_get
}
Definition at line 29002 of file chan_sip.c.
unsigned int recordhistory [static] |
Record SIP history. Off by default
Definition at line 727 of file chan_sip.c.
Referenced by append_history_full(), sip_alloc(), sip_set_history(), sip_show_history(), and sip_show_settings().
struct _map_x_s referstatusstrings[] [static] |
struct ast_register_list regl [static] |
The register list: Other SIP proxies we register with and receive calls from.
Referenced by load_module(), manager_show_registry(), reload_config(), sip_register(), sip_send_all_registers(), sip_show_objects(), sip_show_registry(), and unload_module().
int regobjs = 0 [static] |
Registry objects
Definition at line 763 of file chan_sip.c.
Referenced by sip_register(), sip_registry_destroy(), sip_send_all_registers(), and sip_show_objects().
struct _map_x_s regstatestrings[] [static] |
int rpeerobjs = 0 [static] |
Realtime peers
Definition at line 761 of file chan_sip.c.
Referenced by build_peer(), expire_register(), sip_destroy_peer(), and sip_show_objects().
| struct sched_context* sched |
The scheduling context
Definition at line 789 of file chan_sip.c.
Definition at line 828 of file chan_sip.c.
Referenced by cc_generic_monitor_request_cc(), create_addr(), launch_ha_netscript(), service_string_to_service_type(), and sip_cc_monitor_request_cc().
| const char* service_string |
Definition at line 829 of file chan_sip.c.
struct ast_cc_agent_callbacks sip_cc_agent_callbacks [static] |
struct ast_cc_monitor_callbacks sip_cc_monitor_callbacks [static] |
struct { ... } sip_cc_notify_state_map[] [static] |
Referenced by transmit_cc_notify().
struct { ... } sip_cc_service_map[] [static] |
Referenced by service_string_to_service_type().
struct sip_settings sip_cfg [static] |
SIP configuration data.
Definition at line 696 of file chan_sip.c.
Referenced by __get_header(), __sip_subscribe_mwi_do(), _sip_show_peer(), add_header(), ast_sip_ouraddrfor(), build_peer(), change_hold_state(), check_user_full(), create_addr(), destroy_association(), do_magic_pickup(), find_call(), find_calling_channel(), get_also_info(), get_destination(), get_realm(), get_refer_info(), get_sip_pvt_byid_locked(), handle_incoming(), handle_request_bye(), handle_request_do(), handle_request_invite(), handle_request_options(), handle_request_refer(), handle_request_subscribe(), handle_response_invite(), handle_response_peerpoke(), initreqprep(), obproxy_get(), parse_register_contact(), proxy_update(), realtime_update_peer(), ref_proxy(), register_peer_exten(), register_verify(), reload_config(), set_peer_defaults(), sip_alloc(), sip_new(), sip_poke_noanswer(), sip_request_call(), sip_set_rtp_peer(), sip_show_settings(), state_notify_build_xml(), transmit_register(), unload_module(), update_call_counter(), and update_peer().
struct ast_data_entry sip_data_providers[] [static] |
Initial value:
{
AST_DATA_ENTRY("asterisk/channel/sip/peers", &peers_data_provider),
}
Definition at line 29007 of file chan_sip.c.
Referenced by load_module().
struct ast_custom_function sip_header_function [static] |
Initial value:
{
.name = "SIP_HEADER",
.read = func_header_read,
}
Definition at line 18483 of file chan_sip.c.
Referenced by load_module(), and unload_module().
struct cfsip_methods sip_methods[] [static] |
The core structure to setup dialogs. We parse incoming messages by using structure and then route the messages according to the type.
Referenced by __sip_autodestruct(), __sip_destroy(), __sip_pretend_ack(), __sip_semi_ack(), build_reply_digest(), dialog_initialize_rtp(), dialog_needdestroy(), do_proxy_auth(), find_call(), find_sip_method(), get_destination(), handle_incoming(), handle_request_bye(), handle_request_invite(), handle_request_register(), handle_request_subscribe(), handle_response(), init_req(), initialize_initreq(), initreqprep(), method_match(), reqprep(), retrans_pkt(), send_request(), send_response(), sip_alloc(), sip_scheddestroy(), and transmit_register().
| struct ao2_container* sip_monitor_instances |
Definition at line 1808 of file chan_sip.c.
Referenced by cc_handle_publish_error(), handle_cc_notify(), handle_response(), load_module(), sip_cc_monitor_destructor(), and sip_monitor_instance_init().
struct sip_reasons sip_reason_table[] [static] |
Diversion header reasons.
The core defines a bunch of constants used to define redirecting reasons. This provides a translation table between those and the strings which may be present in a SIP Diversion header
Referenced by sip_reason_code_to_str(), and sip_reason_str_to_code().
ast_mutex_t sip_reload_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static] |
int sip_reloading = FALSE [static] |
Flag for avoiding multiple reloads at the same time
Definition at line 786 of file chan_sip.c.
Referenced by do_monitor(), and sip_reload().
enum channelreloadreason sip_reloadreason [static] |
Reason for last reload/load of configuration
Definition at line 787 of file chan_sip.c.
Referenced by do_monitor(), load_module(), and sip_reload().
struct ast_rtp_glue sip_rtp_glue [static] |
struct ast_tcptls_session_args sip_tcp_desc [static] |
The TCP server definition.
Definition at line 2167 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), sip_show_settings(), transmit_register(), and unload_module().
| struct ast_channel_tech sip_tech |
Definition of this channel for PBX channel registration.
Definition at line 1568 of file chan_sip.c.
Referenced by load_module(), sip_new(), and unload_module().
| 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 1603 of file chan_sip.c.
Referenced by load_module(), and sip_new().
struct ast_tls_config sip_tls_cfg [static] |
struct ast_tcptls_session_args sip_tls_desc [static] |
The TCP/TLS server definition.
Definition at line 2178 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), sip_show_settings(), and unload_module().
struct ast_udptl_protocol sip_udptl [static] |
Initial value:
{
type: "SIP",
get_udptl_info: sip_get_udptl_peer,
set_udptl_peer: sip_set_udptl_peer,
}
Definition at line 2955 of file chan_sip.c.
Referenced by load_module(), and unload_module().
struct ast_custom_function sipchaninfo_function [static] |
Initial value:
{
.name = "SIPCHANINFO",
.read = function_sipchaninfo_read,
}
Definition at line 18667 of file chan_sip.c.
Referenced by load_module(), and unload_module().
enum sip_debug_e sipdebug [static] |
Definition at line 797 of file chan_sip.c.
Referenced by __sip_ack(), __sip_reliable_xmit(), __sip_semi_ack(), obproxy_get(), parse_request(), retrans_pkt(), sip_call(), sip_debug_test_addr(), sip_debug_test_pvt(), sip_hangup(), sip_reregister(), transmit_refer(), transmit_register(), and update_call_counter().
int sipdebug_text [static] |
extra debugging for 'text' related events. At the moment this is set together with sip_debug_console.
Definition at line 803 of file chan_sip.c.
Referenced by add_sdp(), sip_do_debug(), and sip_rtp_read().
struct ast_custom_function sippeer_function [static] |
Initial value:
{
.name = "SIPPEER",
.read = function_sippeer,
}
Definition at line 18601 of file chan_sip.c.
Referenced by load_module(), and unload_module().
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 1128 of file chan_sip.c.
Referenced by do_monitor(), process_via(), reg_source_db(), sip_prepare_socket(), sipsock_read(), and unload_module().
int* sipsock_read_id [static] |
ID of IO entry for sipsock FD
Definition at line 791 of file chan_sip.c.
Referenced by do_monitor().
int speerobjs = 0 [static] |
Static peers
Definition at line 760 of file chan_sip.c.
Referenced by build_peer(), sip_destroy_peer(), sip_poke_all_peers(), and sip_show_objects().
| enum sip_cc_notify_state state |
Definition at line 849 of file chan_sip.c.
Referenced by adpcm(), adsi_process(), ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), ast_moh_files_next(), clearflag(), decode(), find_cache(), gen_alloc(), gen_closestream(), gen_generate(), gen_nextfile(), gen_readframe(), gen_release(), getdisplaybyname(), getflagbyname(), getkeybyname(), getstatebyname(), getsubbyname(), handle_characters(), handle_end_element(), handle_start_element(), iax2_write(), local_ast_moh_cleanup(), local_ast_moh_start(), moh_alloc(), moh_files_alloc(), moh_files_generator(), moh_files_release(), onevent(), parse_cdata(), parse_tag(), process_opcode(), process_returncode(), register_verify(), setflag(), showdisplay(), showkeys(), stun_process_attr(), subscript(), update_caldav(), update_exchangecal(), and update_registry().
| const char* state_string |
struct _map_x_s stmodes[] [static] |
Report Peer status in character string.
Definition at line 15604 of file chan_sip.c.
Referenced by stmode2str(), and str2stmode().
struct _map_x_s strefreshers[] [static] |
Definition at line 15622 of file chan_sip.c.
Referenced by str2strefresher(), and strefresher2str().
struct ast_subscription_mwi_list submwil [static] |
The MWI subscription list.
Referenced by load_module(), sip_send_all_mwi_subscriptions(), sip_show_mwi(), sip_subscribe_mwi(), and unload_module().
struct cfsubscription_types subscription_types[] [static] |
Subscription types that we support. We support
Referenced by find_subscription_type(), and subscription_type2str().
struct ao2_container* threadt [static] |
The table of TCP threads.
Definition at line 1086 of file chan_sip.c.
Referenced by _sip_tcp_helper_thread(), load_module(), sip_prepare_socket(), sip_show_tcp(), sip_tcp_locate(), sip_tcptls_write(), sip_threadinfo_create(), and unload_module().
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] |
Definition at line 562 of file chan_sip.c.
Referenced by _sip_tcp_helper_thread(), action_login(), and session_do().
char used_context[AST_MAX_CONTEXT] [static] |
name of automatically created context for unloading
Definition at line 772 of file chan_sip.c.
Referenced by unload_module().
1.4.7